source: protocols/yahoo/yahoo.c @ 172a73f1

Last change on this file since 172a73f1 was 5b52a48, checked in by Wilmer van der Gaast <wilmer@…>, at 2006-07-03T21:22:45Z

Implemented per-account nick lists instead of per-protocol nick lists.
nick_t is dead, instead nicks are just saves in a per-account_t GLib
hash table. While doing this, the import_buddies command finally died
and text_save() disappeared, because the old file format can't handle
most of the new features in this branch anyway.

Still have to implement support for the new nick lists in text_load()!

  • Property mode set to 100644
File size: 22.4 KB
RevLine 
[b7d3cc34]1/*
2 * libyahoo2 wrapper to BitlBee
3 *
4 * Mostly Copyright 2004 Wilmer van der Gaast <wilmer@gaast.net>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 *
20 */
21
22
23#include <errno.h>
24#include <string.h>
25#include <stdlib.h>
26#include <stdio.h>
27#include <time.h>
28#include <sys/stat.h>
29#include <ctype.h>
30#include "nogaim.h"
31#include "yahoo2.h"
32#include "yahoo2_callbacks.h"
33
34#define BYAHOO_DEFAULT_GROUP "Buddies"
35
36/* A hack to handle removal of buddies not in the group "Buddies" correctly */
37struct byahoo_buddygroups
38{
39        char *buddy;
40        char *group;
41};
42
43struct byahoo_data
44{
45        int y2_id;
46        int current_status;
47        gboolean logged_in;
48        GSList *buddygroups;
49};
50
51struct byahoo_input_data
52{
53        int h;
54        void *d;
55};
56
57struct byahoo_conf_invitation
58{
59        char *name;
60        struct conversation *c;
61        int yid;
62        YList *members;
63        struct gaim_connection *gc;
64};
65
66static GSList *byahoo_inputs = NULL;
67static int byahoo_chat_id = 0;
68
69static char *byahoo_strip( char *in )
70{
71        int len;
72       
73        /* This should get rid of HTML tags at the beginning of the string. */
74        while( *in )
75        {
76                if( g_strncasecmp( in, "<font", 5 ) == 0 ||
77                    g_strncasecmp( in, "<fade", 5 ) == 0 ||
78                    g_strncasecmp( in, "<alt", 4 ) == 0 )
79                {
80                        char *s = strchr( in, '>' );
81                        if( !s )
82                                break;
83                       
84                        in = s + 1;
85                }
86                else if( strncmp( in, "\e[", 2 ) == 0 )
87                {
88                        char *s;
89                       
90                        for( s = in + 2; *s && *s != 'm'; s ++ );
91                       
92                        if( *s != 'm' )
93                                break;
94                       
95                        in = s + 1;
96                }
97                else
98                {
99                        break;
100                }
101        }
102       
103        /* This is supposed to get rid of the closing HTML tags at the end of the line. */
104        len = strlen( in );
105        while( len > 0 && in[len-1] == '>' )
106        {
107                int blen = len;
108               
109                len --;
110                while( len > 0 && ( in[len] != '<' || in[len+1] != '/' ) )
111                        len --;
112               
113                if( len == 0 && ( in[len] != '<' || in[len+1] != '/' ) )
114                {
115                        len = blen;
116                        break;
117                }
118        }
119       
120        return( g_strndup( in, len ) );
121}
122
[0a3c243]123static void byahoo_login( account_t *acc )
[b7d3cc34]124{
[0a3c243]125        struct gaim_connection *gc = new_gaim_conn( acc );
[b7d3cc34]126        struct byahoo_data *yd = gc->proto_data = g_new0( struct byahoo_data, 1 );
127       
128        yd->logged_in = FALSE;
129        yd->current_status = YAHOO_STATUS_AVAILABLE;
130       
131        set_login_progress( gc, 1, "Connecting" );
[0a3c243]132        yd->y2_id = yahoo_init( acc->user, acc->pass );
[b7d3cc34]133        yahoo_login( yd->y2_id, yd->current_status );
134}
135
136static void byahoo_close( struct gaim_connection *gc )
137{
138        struct byahoo_data *yd = (struct byahoo_data *) gc->proto_data;
139        GSList *l;
140       
141        while( gc->conversations )
142                serv_got_chat_left( gc, gc->conversations->id );
143       
144        for( l = yd->buddygroups; l; l = l->next )
145        {
146                struct byahoo_buddygroups *bg = l->data;
147               
148                g_free( bg->buddy );
149                g_free( bg->group );
150                g_free( bg );
151        }
152        g_slist_free( yd->buddygroups );
153       
154        if( yd->logged_in )
155                yahoo_logoff( yd->y2_id );
156        else
157                yahoo_close( yd->y2_id );
158       
159        g_free( yd );
160}
161
162static void byahoo_get_info(struct gaim_connection *gc, char *who) 
163{
164        /* Just make an URL and let the user fetch the info */
165        serv_got_crap(gc, "%s\n%s: %s%s", _("User Info"), 
166                        _("For now, fetch yourself"), yahoo_get_profile_url(),
167                        who);
168}
169
170static int byahoo_send_im( struct gaim_connection *gc, char *who, char *what, int len, int flags )
171{
172        struct byahoo_data *yd = gc->proto_data;
173       
174        yahoo_send_im( yd->y2_id, NULL, who, what, 1 );
175       
176        return 1;
177}
178
179static int byahoo_send_typing( struct gaim_connection *gc, char *who, int typing )
180{
181        struct byahoo_data *yd = gc->proto_data;
182       
183        yahoo_send_typing( yd->y2_id, NULL, who, typing );
184       
185        return 1;
186}
187
188static void byahoo_set_away( struct gaim_connection *gc, char *state, char *msg )
189{
190        struct byahoo_data *yd = (struct byahoo_data *) gc->proto_data;
[d2cbe0a]191       
[b7d3cc34]192        gc->away = NULL;
[d2cbe0a]193       
194        if( msg )
[b7d3cc34]195        {
196                yd->current_status = YAHOO_STATUS_CUSTOM;
197                gc->away = "";
198        }
[d2cbe0a]199        if( state )
[b7d3cc34]200        {
201                gc->away = "";
[d2cbe0a]202                if( g_strcasecmp( state, "Available" ) == 0 )
[b7d3cc34]203                {
204                        yd->current_status = YAHOO_STATUS_AVAILABLE;
205                        gc->away = NULL;
206                }
207                else if( g_strcasecmp( state, "Be Right Back" ) == 0 )
208                        yd->current_status = YAHOO_STATUS_BRB;
209                else if( g_strcasecmp( state, "Busy" ) == 0 )
210                        yd->current_status = YAHOO_STATUS_BUSY;
211                else if( g_strcasecmp( state, "Not At Home" ) == 0 )
212                        yd->current_status = YAHOO_STATUS_NOTATHOME;
213                else if( g_strcasecmp( state, "Not At Desk" ) == 0 )
214                        yd->current_status = YAHOO_STATUS_NOTATDESK;
215                else if( g_strcasecmp( state, "Not In Office" ) == 0 )
216                        yd->current_status = YAHOO_STATUS_NOTINOFFICE;
217                else if( g_strcasecmp( state, "On Phone" ) == 0 )
218                        yd->current_status = YAHOO_STATUS_ONPHONE;
219                else if( g_strcasecmp( state, "On Vacation" ) == 0 )
220                        yd->current_status = YAHOO_STATUS_ONVACATION;
221                else if( g_strcasecmp( state, "Out To Lunch" ) == 0 )
222                        yd->current_status = YAHOO_STATUS_OUTTOLUNCH;
223                else if( g_strcasecmp( state, "Stepped Out" ) == 0 )
224                        yd->current_status = YAHOO_STATUS_STEPPEDOUT;
225                else if( g_strcasecmp( state, "Invisible" ) == 0 )
226                        yd->current_status = YAHOO_STATUS_INVISIBLE;
227                else if( g_strcasecmp( state, GAIM_AWAY_CUSTOM ) == 0 )
228                {
[192b80a]229                        yd->current_status = YAHOO_STATUS_AVAILABLE;
[b7d3cc34]230                       
231                        gc->away = NULL;
232                }
233        }
234        else
235                yd->current_status = YAHOO_STATUS_AVAILABLE;
236       
[d2cbe0a]237        if( yd->current_status == YAHOO_STATUS_INVISIBLE )
238                yahoo_set_away( yd->y2_id, yd->current_status, NULL, gc->away != NULL );
239        else
240                yahoo_set_away( yd->y2_id, yd->current_status, msg, gc->away != NULL );
[b7d3cc34]241}
242
243static GList *byahoo_away_states( struct gaim_connection *gc )
244{
245        GList *m = NULL;
246
247        m = g_list_append( m, "Available" );
248        m = g_list_append( m, "Be Right Back" );
249        m = g_list_append( m, "Busy" );
250        m = g_list_append( m, "Not At Home" );
251        m = g_list_append( m, "Not At Desk" );
252        m = g_list_append( m, "Not In Office" );
253        m = g_list_append( m, "On Phone" );
254        m = g_list_append( m, "On Vacation" );
255        m = g_list_append( m, "Out To Lunch" );
256        m = g_list_append( m, "Stepped Out" );
257        m = g_list_append( m, "Invisible" );
258        m = g_list_append( m, GAIM_AWAY_CUSTOM );
259       
260        return m;
261}
262
263static void byahoo_keepalive( struct gaim_connection *gc )
264{
265        struct byahoo_data *yd = gc->proto_data;
266       
267        yahoo_keepalive( yd->y2_id );
268}
269
270static void byahoo_add_buddy( struct gaim_connection *gc, char *who )
271{
272        struct byahoo_data *yd = (struct byahoo_data *) gc->proto_data;
273       
274        yahoo_add_buddy( yd->y2_id, who, BYAHOO_DEFAULT_GROUP );
275}
276
277static void byahoo_remove_buddy( struct gaim_connection *gc, char *who, char *group )
278{
279        struct byahoo_data *yd = (struct byahoo_data *) gc->proto_data;
280        GSList *bgl;
281       
282        yahoo_remove_buddy( yd->y2_id, who, BYAHOO_DEFAULT_GROUP );
283       
284        for( bgl = yd->buddygroups; bgl; bgl = bgl->next )
285        {
286                struct byahoo_buddygroups *bg = bgl->data;
287               
288                if( g_strcasecmp( bg->buddy, who ) == 0 )
289                        yahoo_remove_buddy( yd->y2_id, who, bg->group );
290        }
291}
292
293static char *byahoo_get_status_string( struct gaim_connection *gc, int stat )
294{
295        enum yahoo_status a = stat >> 1;
296       
297        switch (a)
298        {
299        case YAHOO_STATUS_BRB:
300                return "Be Right Back";
301        case YAHOO_STATUS_BUSY:
302                return "Busy";
303        case YAHOO_STATUS_NOTATHOME:
304                return "Not At Home";
305        case YAHOO_STATUS_NOTATDESK:
306                return "Not At Desk";
307        case YAHOO_STATUS_NOTINOFFICE:
308                return "Not In Office";
309        case YAHOO_STATUS_ONPHONE:
310                return "On Phone";
311        case YAHOO_STATUS_ONVACATION:
312                return "On Vacation";
313        case YAHOO_STATUS_OUTTOLUNCH:
314                return "Out To Lunch";
315        case YAHOO_STATUS_STEPPEDOUT:
316                return "Stepped Out";
317        case YAHOO_STATUS_INVISIBLE:
318                return "Invisible";
319        case YAHOO_STATUS_CUSTOM:
320                return "Away";
321        case YAHOO_STATUS_IDLE:
322                return "Idle";
323        case YAHOO_STATUS_OFFLINE:
324                return "Offline";
325        case YAHOO_STATUS_NOTIFY:
326                return "Notify";
327        default:
328                return "Away";
329        }
330}
331
332static int byahoo_chat_send( struct gaim_connection *gc, int id, char *message )
333{
334        struct byahoo_data *yd = (struct byahoo_data *) gc->proto_data;
335        struct conversation *c;
336       
337        for( c = gc->conversations; c && c->id != id; c = c->next );
338
339        yahoo_conference_message( yd->y2_id, NULL, c->data, c->title, message, 1 );
340       
341        return( 0 );
342}
343
344static void byahoo_chat_invite( struct gaim_connection *gc, int id, char *msg, char *who )
345{
346        struct byahoo_data *yd = (struct byahoo_data *) gc->proto_data;
347        struct conversation *c;
348       
349        for( c = gc->conversations; c && c->id != id; c = c->next );
350       
351        yahoo_conference_invite( yd->y2_id, NULL, c->data, c->title, msg );
352}
353
354static void byahoo_chat_leave( struct gaim_connection *gc, int id )
355{
356        struct byahoo_data *yd = (struct byahoo_data *) gc->proto_data;
357        struct conversation *c;
358       
359        for( c = gc->conversations; c && c->id != id; c = c->next );
360       
361        yahoo_conference_logoff( yd->y2_id, NULL, c->data, c->title );
362        serv_got_chat_left( gc, c->id );
363}
364
365static int byahoo_chat_open( struct gaim_connection *gc, char *who )
366{
367        struct byahoo_data *yd = (struct byahoo_data *) gc->proto_data;
368        struct conversation *c;
369        char *roomname;
370        YList *members;
371       
372        roomname = g_new0( char, strlen( gc->username ) + 16 );
373        g_snprintf( roomname, strlen( gc->username ) + 16, "%s-Bee-%d", gc->username, byahoo_chat_id );
374       
375        c = serv_got_joined_chat( gc, ++byahoo_chat_id, roomname );
376        add_chat_buddy( c, gc->username );
377       
378        /* FIXME: Free this thing when the chat's destroyed. We can't *always*
379                  do this because it's not always created here. */
380        c->data = members = g_new0( YList, 1 );
381        members->data = g_strdup( who );
382       
383        yahoo_conference_invite( yd->y2_id, NULL, members, roomname, "Please join my groupchat..." );
384       
385        g_free( roomname );
386       
387        return( 1 );
388}
389
[7b23afd]390void byahoo_init( )
[b7d3cc34]391{
[7b23afd]392        struct prpl *ret = g_new0(struct prpl, 1);
393        ret->name = "yahoo";
[b7d3cc34]394       
395        ret->login = byahoo_login;
396        ret->close = byahoo_close;
397        ret->send_im = byahoo_send_im;
398        ret->get_info = byahoo_get_info;
399        ret->away_states = byahoo_away_states;
400        ret->set_away = byahoo_set_away;
401        ret->keepalive = byahoo_keepalive;
402        ret->add_buddy = byahoo_add_buddy;
403        ret->remove_buddy = byahoo_remove_buddy;
404        ret->get_status_string = byahoo_get_status_string;
[7b23afd]405        ret->send_typing = byahoo_send_typing;
[b7d3cc34]406       
407        ret->chat_send = byahoo_chat_send;
408        ret->chat_invite = byahoo_chat_invite;
409        ret->chat_leave = byahoo_chat_leave;
410        ret->chat_open = byahoo_chat_open;
[5b52a48]411
412        ret->handle_cmp = g_strcasecmp;
[b7d3cc34]413       
[7b23afd]414        register_protocol(ret);
[b7d3cc34]415}
416
417static struct gaim_connection *byahoo_get_gc_by_id( int id )
418{
419        GSList *l;
420        struct gaim_connection *gc;
421        struct byahoo_data *yd;
422       
423        for( l = get_connections(); l; l = l->next )
424        {
425                gc = l->data;
426                yd = gc->proto_data;
427               
[0a3c243]428                if( strcmp( gc->acc->prpl->name, "yahoo" ) == 0 && yd->y2_id == id )
[b7d3cc34]429                        return( gc );
430        }
431       
432        return( NULL );
433}
434
435
436/* Now it's callback time! */
437
438struct byahoo_connect_callback_data
439{
440        int fd;
441        yahoo_connect_callback callback;
442        gpointer data;
443        int id;
444};
445
[ba9edaa]446void byahoo_connect_callback( gpointer data, gint source, b_input_condition cond )
[b7d3cc34]447{
448        struct byahoo_connect_callback_data *d = data;
449       
450        if( !byahoo_get_gc_by_id( d->id ) )
451        {
452                g_free( d );
453                return;
454        }
455       
456        d->callback( d->fd, 0, d->data );
457        g_free( d );
458}
459
460struct byahoo_read_ready_data
461{
462        int id;
463        int fd;
464        int tag;
465        gpointer data;
466};
467
[ba9edaa]468gboolean byahoo_read_ready_callback( gpointer data, gint source, b_input_condition cond )
[b7d3cc34]469{
470        struct byahoo_read_ready_data *d = data;
471       
472        if( !byahoo_get_gc_by_id( d->id ) )
473                /* WTF doesn't libyahoo clean this up? */
[ba9edaa]474                return FALSE;
[b7d3cc34]475       
476        yahoo_read_ready( d->id, d->fd, d->data );
[7a685f1]477       
478        return TRUE;
[b7d3cc34]479}
480
481struct byahoo_write_ready_data
482{
483        int id;
484        int fd;
485        int tag;
486        gpointer data;
487};
488
[ba9edaa]489gboolean byahoo_write_ready_callback( gpointer data, gint source, b_input_condition cond )
[b7d3cc34]490{
491        struct byahoo_write_ready_data *d = data;
492       
493        if( !byahoo_get_gc_by_id( d->id ) )
494                /* WTF doesn't libyahoo clean this up? */
[ba9edaa]495                return FALSE;
[b7d3cc34]496       
497        yahoo_write_ready( d->id, d->fd, d->data );
[7a685f1]498       
499        return FALSE;
[b7d3cc34]500}
501
502void ext_yahoo_login_response( int id, int succ, char *url )
503{
504        struct gaim_connection *gc = byahoo_get_gc_by_id( id );
505        struct byahoo_data *yd = NULL;
506       
507        if( gc == NULL )
508        {
509                /* libyahoo2 seems to call this one twice when something
510                   went wrong sometimes. Don't know why. Because we clean
511                   up the connection on the first failure, the second
512                   should be ignored. */
513               
514                return;
515        }
516       
517        yd = (struct byahoo_data *) gc->proto_data;
518       
519        if( succ == YAHOO_LOGIN_OK )
520        {
521                account_online( gc );
522               
523                yd->logged_in = TRUE;
524        }
525        else
526        {
527                char *errstr;
528                char *s;
529               
530                yd->logged_in = FALSE;
531               
532                if( succ == YAHOO_LOGIN_UNAME )
533                        errstr = "Incorrect Yahoo! username";
534                else if( succ == YAHOO_LOGIN_PASSWD )
535                        errstr = "Incorrect Yahoo! password";
536                else if( succ == YAHOO_LOGIN_LOCK )
537                        errstr = "Yahoo! account locked";
538                else if( succ == YAHOO_LOGIN_DUPL )
539                {
540                        errstr = "Logged in on a different machine or device";
541                        gc->wants_to_die = TRUE;
542                }
543                else if( succ == YAHOO_LOGIN_SOCK )
544                        errstr = "Socket problem";
545                else
546                        errstr = "Unknown error";
547               
548                if( url && *url )
549                {
550                        s = g_malloc( strlen( "Error %d (%s). See %s for more information." ) + strlen( url ) + strlen( errstr ) + 16 );
551                        sprintf( s, "Error %d (%s). See %s for more information.", succ, errstr, url );
552                }
553                else
554                {
555                        s = g_malloc( strlen( "Error %d (%s)" ) + strlen( errstr ) + 16 );
556                        sprintf( s, "Error %d (%s)", succ, errstr );
557                }
558               
559                if( yd->logged_in )
560                        hide_login_progress_error( gc, s );
561                else
562                        hide_login_progress( gc, s );
563               
564                g_free( s );
565               
566                signoff( gc );
567        }
568}
569
570void ext_yahoo_got_buddies( int id, YList *buds )
571{
572        struct gaim_connection *gc = byahoo_get_gc_by_id( id );
573        struct byahoo_data *yd = gc->proto_data;
574        YList *bl = buds;
575       
576        while( bl )
577        {
578                struct yahoo_buddy *b = bl->data;
579                struct byahoo_buddygroups *bg;
580               
581                if( strcmp( b->group, BYAHOO_DEFAULT_GROUP ) != 0 )
582                {
583                        bg = g_new0( struct byahoo_buddygroups, 1 );
584                       
585                        bg->buddy = g_strdup( b->id );
586                        bg->group = g_strdup( b->group );
587                        yd->buddygroups = g_slist_append( yd->buddygroups, bg );
588                }
589               
590                add_buddy( gc, b->group, b->id, b->real_name );
591                bl = bl->next;
592        }
593}
594
595void ext_yahoo_got_ignore( int id, YList *igns )
596{
597}
598
599void ext_yahoo_got_identities( int id, YList *ids )
600{
601}
602
603void ext_yahoo_got_cookies( int id )
604{
605}
606
607void ext_yahoo_status_changed( int id, char *who, int stat, char *msg, int away )
608{
609        struct gaim_connection *gc = byahoo_get_gc_by_id( id );
610       
[5a348c3]611        serv_got_update( gc, who, stat != YAHOO_STATUS_OFFLINE, 0, 0,
612                         ( stat == YAHOO_STATUS_IDLE ) ? away : 0,
[b7d3cc34]613                         ( stat != YAHOO_STATUS_AVAILABLE ) | ( stat << 1 ), 0 );
614}
615
616void ext_yahoo_got_im( int id, char *who, char *msg, long tm, int stat, int utf8 )
617{
618        struct gaim_connection *gc = byahoo_get_gc_by_id( id );
619        char *m = byahoo_strip( msg );
620       
621        serv_got_im( gc, who, m, 0, 0, strlen( m ) );
622        g_free( m );
623}
624
625void ext_yahoo_got_file( int id, char *who, char *url, long expires, char *msg, char *fname, unsigned long fesize )
626{
627        struct gaim_connection *gc = byahoo_get_gc_by_id( id );
628       
629        serv_got_crap( gc, "Got a file transfer (file = %s) from %s. Ignoring for now due to lack of support.", fname, who );
630}
631
632void ext_yahoo_typing_notify( int id, char *who, int stat )
633{
634        struct gaim_connection *gc = byahoo_get_gc_by_id( id );
[e7f46c5]635        if (stat == 1) {
636                /* User is typing */
637                serv_got_typing( gc, who, 1, 1 );
638        }
639        else {
640                /* User stopped typing */
641                serv_got_typing( gc, who, 1, 0 );
642        }
[b7d3cc34]643}
644
645void ext_yahoo_system_message( int id, char *msg )
646{
647        struct gaim_connection *gc = byahoo_get_gc_by_id( id );
648       
649        serv_got_crap( gc, "Yahoo! system message: %s", msg );
650}
651
652void ext_yahoo_webcam_invite( int id, char *from )
653{
654        struct gaim_connection *gc = byahoo_get_gc_by_id( id );
655       
656        serv_got_crap( gc, "Got a webcam invitation from %s. IRC+webcams is a no-no though...", from );
657}
658
659void ext_yahoo_error( int id, char *err, int fatal )
660{
661        struct gaim_connection *gc = byahoo_get_gc_by_id( id );
662       
663        if( fatal )
664        {
665                hide_login_progress_error( gc, err );
666                signoff( gc );
667        }
668        else
669        {
670                do_error_dialog( gc, err, "Yahoo! error" );
671        }
672}
673
674/* TODO: Clear up the mess of inp and d structures */
675int ext_yahoo_add_handler( int id, int fd, yahoo_input_condition cond, void *data )
676{
677        struct byahoo_input_data *inp = g_new0( struct byahoo_input_data, 1 );
678       
679        if( cond == YAHOO_INPUT_READ )
680        {
681                struct byahoo_read_ready_data *d = g_new0( struct byahoo_read_ready_data, 1 );
682               
683                d->id = id;
684                d->fd = fd;
685                d->data = data;
686               
687                inp->d = d;
[ba9edaa]688                d->tag = inp->h = b_input_add( fd, GAIM_INPUT_READ, (b_event_handler) byahoo_read_ready_callback, (gpointer) d );
[b7d3cc34]689        }
690        else if( cond == YAHOO_INPUT_WRITE )
691        {
692                struct byahoo_write_ready_data *d = g_new0( struct byahoo_write_ready_data, 1 );
693               
694                d->id = id;
695                d->fd = fd;
696                d->data = data;
697               
698                inp->d = d;
[ba9edaa]699                d->tag = inp->h = b_input_add( fd, GAIM_INPUT_WRITE, (b_event_handler) byahoo_write_ready_callback, (gpointer) d );
[b7d3cc34]700        }
701        else
702        {
703                g_free( inp );
704                return( -1 );
705                /* Panic... */
706        }
707       
708        byahoo_inputs = g_slist_append( byahoo_inputs, inp );
709        return( inp->h );
710}
711
712void ext_yahoo_remove_handler( int id, int tag )
713{
714        struct byahoo_input_data *inp;
715        GSList *l = byahoo_inputs;
716       
717        while( l )
718        {
719                inp = l->data;
720                if( inp->h == tag )
721                {
722                        g_free( inp->d );
723                        g_free( inp );
724                        byahoo_inputs = g_slist_remove( byahoo_inputs, inp );
725                        break;
726                }
727                l = l->next;
728        }
729       
[ba9edaa]730        b_event_remove( tag );
[b7d3cc34]731}
732
733int ext_yahoo_connect_async( int id, char *host, int port, yahoo_connect_callback callback, void *data )
734{
735        struct byahoo_connect_callback_data *d;
736        int fd;
737       
738        d = g_new0( struct byahoo_connect_callback_data, 1 );
[ba9edaa]739        if( ( fd = proxy_connect( host, port, (b_event_handler) byahoo_connect_callback, (gpointer) d ) ) < 0 )
[b7d3cc34]740        {
741                g_free( d );
742                return( fd );
743        }
744        d->fd = fd;
745        d->callback = callback;
746        d->data = data;
747        d->id = id;
748       
749        return( fd );
750}
751
752/* Because we don't want asynchronous connects in BitlBee, and because
753   libyahoo doesn't seem to use this one anyway, this one is now defunct. */
754int ext_yahoo_connect(char *host, int port)
755{
756#if 0
757        struct sockaddr_in serv_addr;
758        static struct hostent *server;
759        static char last_host[256];
760        int servfd;
761        char **p;
762
763        if(last_host[0] || g_strcasecmp(last_host, host)!=0) {
764                if(!(server = gethostbyname(host))) {
765                        return -1;
766                }
767                strncpy(last_host, host, 255);
768        }
769
770        if((servfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
771                return -1;
772        }
773
774        for (p = server->h_addr_list; *p; p++)
775        {
776                memset(&serv_addr, 0, sizeof(serv_addr));
777                serv_addr.sin_family = AF_INET;
778                memcpy(&serv_addr.sin_addr.s_addr, *p, server->h_length);
779                serv_addr.sin_port = htons(port);
780
781                if(connect(servfd, (struct sockaddr *) &serv_addr,
782                                        sizeof(serv_addr)) == -1) {
783                        return -1;
784                } else {
785                        return servfd;
786                }
787        }
788
789        closesocket(servfd);
790#endif
791        return -1;
792}
793
794static void byahoo_accept_conf( gpointer w, struct byahoo_conf_invitation *inv )
795{
796        yahoo_conference_logon( inv->yid, NULL, inv->members, inv->name );
797        add_chat_buddy( inv->c, inv->gc->username );
798        g_free( inv->name );
799        g_free( inv );
800}
801
802static void byahoo_reject_conf( gpointer w, struct byahoo_conf_invitation *inv )
803{
804        yahoo_conference_decline( inv->yid, NULL, inv->members, inv->name, "User rejected groupchat" );
805        serv_got_chat_left( inv->gc, inv->c->id );
806        g_free( inv->name );
807        g_free( inv );
808}
809
810void ext_yahoo_got_conf_invite( int id, char *who, char *room, char *msg, YList *members )
811{
812        struct gaim_connection *gc = byahoo_get_gc_by_id( id );
813        struct byahoo_conf_invitation *inv;
814        char txt[1024];
815        YList *m;
816       
817        inv = g_malloc( sizeof( struct byahoo_conf_invitation ) );
818        memset( inv, 0, sizeof( struct byahoo_conf_invitation ) );
819        inv->name = g_strdup( room );
820        inv->c = serv_got_joined_chat( gc, ++byahoo_chat_id, room );
821        inv->c->data = members;
822        inv->yid = id;
823        inv->members = members;
824        inv->gc = gc;
825       
826        for( m = members; m; m = m->next )
827                if( g_strcasecmp( m->data, gc->username ) != 0 )
828                        add_chat_buddy( inv->c, m->data );
829       
830        g_snprintf( txt, 1024, "Got an invitation to chatroom %s from %s: %s", room, who, msg );
831       
832        do_ask_dialog( gc, txt, inv, byahoo_accept_conf, byahoo_reject_conf );
833}
834
835void ext_yahoo_conf_userdecline( int id, char *who, char *room, char *msg )
836{
837        struct gaim_connection *gc = byahoo_get_gc_by_id( id );
838       
839        serv_got_crap( gc, "Invite to chatroom %s rejected by %s: %s", room, who, msg );
840}
841
842void ext_yahoo_conf_userjoin( int id, char *who, char *room )
843{
844        struct gaim_connection *gc = byahoo_get_gc_by_id( id );
845        struct conversation *c;
846       
847        for( c = gc->conversations; c && strcmp( c->title, room ) != 0; c = c->next );
848       
849        if( c )
850                add_chat_buddy( c, who );
851}
852
853void ext_yahoo_conf_userleave( int id, char *who, char *room )
854{
855        struct gaim_connection *gc = byahoo_get_gc_by_id( id );
856        struct conversation *c;
857       
858        for( c = gc->conversations; c && strcmp( c->title, room ) != 0; c = c->next );
859       
860        if( c )
861                remove_chat_buddy( c, who, "" );
862}
863
864void ext_yahoo_conf_message( int id, char *who, char *room, char *msg, int utf8 )
865{
866        struct gaim_connection *gc = byahoo_get_gc_by_id( id );
867        char *m = byahoo_strip( msg );
868        struct conversation *c;
869       
870        for( c = gc->conversations; c && strcmp( c->title, room ) != 0; c = c->next );
871       
872        serv_got_chat_in( gc, c ? c->id : 0, who, 0, m, 0 );
873        g_free( m );
874}
875
876void ext_yahoo_chat_cat_xml( int id, char *xml )
877{
878}
879
880void ext_yahoo_chat_join( int id, char *room, char *topic, YList *members, int fd )
881{
882}
883
884void ext_yahoo_chat_userjoin( int id, char *room, struct yahoo_chat_member *who )
885{
886}
887
888void ext_yahoo_chat_userleave( int id, char *room, char *who )
889{
890}
891
892void ext_yahoo_chat_message( int id, char *who, char *room, char *msg, int msgtype, int utf8 )
893{
894}
895
896void ext_yahoo_chat_yahoologout( int id )
897{
898}
899
900void ext_yahoo_chat_yahooerror( int id )
901{
902}
903
904void ext_yahoo_contact_added( int id, char *myid, char *who, char *msg )
905{
906}
907
908void ext_yahoo_rejected( int id, char *who, char *msg )
909{
910}
911
912void ext_yahoo_game_notify( int id, char *who, int stat )
913{
914}
915
916void ext_yahoo_mail_notify( int id, char *from, char *subj, int cnt )
917{
918        struct gaim_connection *gc = byahoo_get_gc_by_id( id );
919       
920        if( from && subj )
921                serv_got_crap( gc, "Received e-mail message from %s with subject `%s'", from, subj );
922        else if( cnt > 0 )
923                serv_got_crap( gc, "Received %d new e-mails", cnt );
924}
925
926void ext_yahoo_webcam_invite_reply( int id, char *from, int accept )
927{
928}
929
930void ext_yahoo_webcam_closed( int id, char *who, int reason )
931{
932}
933
934void ext_yahoo_got_search_result( int id, int found, int start, int total, YList *contacts )
935{
936}
937
938void ext_yahoo_webcam_viewer( int id, char *who, int connect )
939{
940}
941
942void ext_yahoo_webcam_data_request( int id, int send )
943{
944}
945
946int ext_yahoo_log( char *fmt, ... )
947{
948        return( 0 );
949}
950
951void ext_yahoo_got_webcam_image( int id, const char * who, const unsigned char *image, unsigned int image_size, unsigned int real_size, unsigned int timestamp )
952{
953}
Note: See TracBrowser for help on using the repository browser.