source: protocols/yahoo/yahoo.c @ 98de2cc

Last change on this file since 98de2cc was 52df5df, checked in by Wilmer van der Gaast <wilmer@…>, at 2008-06-14T01:19:12Z

This seems to fix the Yahoo! logoff code. I have no idea why this was broken
(on purpose) in libyahoo2, but this fix seems to work and at least Valgrind
is still happy. And I actually see myself log off now, and the fd is actually
cleaned up properly.

  • Property mode set to 100644
File size: 23.4 KB
Line 
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 groupchat *c;
61        int yid;
62        YList *members;
63        struct im_connection *ic;
64};
65
66static GSList *byahoo_inputs = NULL;
67static int byahoo_chat_id = 0;
68
69static char *byahoo_strip( const char *in )
70{
71        int len;
72       
73        /* This should get rid of the markup noise 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                        const 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 noise at the end of the line. */
104        len = strlen( in );
105        while( len > 0 && ( in[len-1] == '>' || in[len-1] == 'm' ) )
106        {
107                int blen = len;
108                const char *search;
109               
110                if( in[len-1] == '>' )
111                        search = "</";
112                else
113                        search = "\e[";
114               
115                len -= 3;
116                while( len > 0 && strncmp( in + len, search, 2 ) != 0 )
117                        len --;
118               
119                if( len <= 0 && strncmp( in, search, 2 ) != 0 )
120                {
121                        len = blen;
122                        break;
123                }
124        }
125       
126        return( g_strndup( in, len ) );
127}
128
129static void byahoo_init( account_t *acc )
130{
131        set_add( &acc->set, "mail_notifications", "false", set_eval_bool, acc );
132}
133
134static void byahoo_login( account_t *acc )
135{
136        struct im_connection *ic = imcb_new( acc );
137        struct byahoo_data *yd = ic->proto_data = g_new0( struct byahoo_data, 1 );
138       
139        yd->logged_in = FALSE;
140        yd->current_status = YAHOO_STATUS_AVAILABLE;
141       
142        imcb_log( ic, "Connecting" );
143        yd->y2_id = yahoo_init( acc->user, acc->pass );
144        yahoo_login( yd->y2_id, yd->current_status );
145}
146
147static void byahoo_logout( struct im_connection *ic )
148{
149        struct byahoo_data *yd = (struct byahoo_data *) ic->proto_data;
150        GSList *l;
151       
152        while( ic->groupchats )
153                imcb_chat_free( ic->groupchats );
154       
155        for( l = yd->buddygroups; l; l = l->next )
156        {
157                struct byahoo_buddygroups *bg = l->data;
158               
159                g_free( bg->buddy );
160                g_free( bg->group );
161                g_free( bg );
162        }
163        g_slist_free( yd->buddygroups );
164       
165        if( yd->logged_in )
166                yahoo_logoff( yd->y2_id );
167        else
168                yahoo_close( yd->y2_id );
169       
170        g_free( yd );
171}
172
173static void byahoo_get_info(struct im_connection *ic, char *who) 
174{
175        /* Just make an URL and let the user fetch the info */
176        imcb_log(ic, "%s\n%s: %s%s", _("User Info"), 
177                        _("For now, fetch yourself"), yahoo_get_profile_url(),
178                        who);
179}
180
181static int byahoo_buddy_msg( struct im_connection *ic, char *who, char *what, int flags )
182{
183        struct byahoo_data *yd = ic->proto_data;
184       
185        yahoo_send_im( yd->y2_id, NULL, who, what, 1, 0 );
186       
187        return 1;
188}
189
190static int byahoo_send_typing( struct im_connection *ic, char *who, int typing )
191{
192        struct byahoo_data *yd = ic->proto_data;
193       
194        yahoo_send_typing( yd->y2_id, NULL, who, ( typing & OPT_TYPING ) != 0 );
195       
196        return 1;
197}
198
199static void byahoo_set_away( struct im_connection *ic, char *state, char *msg )
200{
201        struct byahoo_data *yd = (struct byahoo_data *) ic->proto_data;
202       
203        ic->away = NULL;
204       
205        if( state && msg && g_strcasecmp( state, msg ) != 0 )
206        {
207                yd->current_status = YAHOO_STATUS_CUSTOM;
208                ic->away = "";
209        }
210        else if( state )
211        {
212                /* Set msg to NULL since (if it isn't NULL already) it's equal
213                   to state. msg must be empty if we want to use an existing
214                   away state. */
215                msg = NULL;
216               
217                ic->away = "";
218                if( g_strcasecmp( state, "Available" ) == 0 )
219                {
220                        yd->current_status = YAHOO_STATUS_AVAILABLE;
221                        ic->away = NULL;
222                }
223                else if( g_strcasecmp( state, "Be Right Back" ) == 0 )
224                        yd->current_status = YAHOO_STATUS_BRB;
225                else if( g_strcasecmp( state, "Busy" ) == 0 )
226                        yd->current_status = YAHOO_STATUS_BUSY;
227                else if( g_strcasecmp( state, "Not At Home" ) == 0 )
228                        yd->current_status = YAHOO_STATUS_NOTATHOME;
229                else if( g_strcasecmp( state, "Not At Desk" ) == 0 )
230                        yd->current_status = YAHOO_STATUS_NOTATDESK;
231                else if( g_strcasecmp( state, "Not In Office" ) == 0 )
232                        yd->current_status = YAHOO_STATUS_NOTINOFFICE;
233                else if( g_strcasecmp( state, "On Phone" ) == 0 )
234                        yd->current_status = YAHOO_STATUS_ONPHONE;
235                else if( g_strcasecmp( state, "On Vacation" ) == 0 )
236                        yd->current_status = YAHOO_STATUS_ONVACATION;
237                else if( g_strcasecmp( state, "Out To Lunch" ) == 0 )
238                        yd->current_status = YAHOO_STATUS_OUTTOLUNCH;
239                else if( g_strcasecmp( state, "Stepped Out" ) == 0 )
240                        yd->current_status = YAHOO_STATUS_STEPPEDOUT;
241                else if( g_strcasecmp( state, "Invisible" ) == 0 )
242                        yd->current_status = YAHOO_STATUS_INVISIBLE;
243                else if( g_strcasecmp( state, GAIM_AWAY_CUSTOM ) == 0 )
244                {
245                        yd->current_status = YAHOO_STATUS_AVAILABLE;
246                       
247                        ic->away = NULL;
248                }
249        }
250        else
251                yd->current_status = YAHOO_STATUS_AVAILABLE;
252       
253        yahoo_set_away( yd->y2_id, yd->current_status, msg, ic->away != NULL ? 2 : 0 );
254}
255
256static GList *byahoo_away_states( struct im_connection *ic )
257{
258        GList *m = NULL;
259
260        m = g_list_append( m, "Available" );
261        m = g_list_append( m, "Be Right Back" );
262        m = g_list_append( m, "Busy" );
263        m = g_list_append( m, "Not At Home" );
264        m = g_list_append( m, "Not At Desk" );
265        m = g_list_append( m, "Not In Office" );
266        m = g_list_append( m, "On Phone" );
267        m = g_list_append( m, "On Vacation" );
268        m = g_list_append( m, "Out To Lunch" );
269        m = g_list_append( m, "Stepped Out" );
270        m = g_list_append( m, "Invisible" );
271        m = g_list_append( m, GAIM_AWAY_CUSTOM );
272       
273        return m;
274}
275
276static void byahoo_keepalive( struct im_connection *ic )
277{
278        struct byahoo_data *yd = ic->proto_data;
279       
280        yahoo_keepalive( yd->y2_id );
281}
282
283static void byahoo_add_buddy( struct im_connection *ic, char *who, char *group )
284{
285        struct byahoo_data *yd = (struct byahoo_data *) ic->proto_data;
286       
287        yahoo_add_buddy( yd->y2_id, who, group ? group : BYAHOO_DEFAULT_GROUP, NULL );
288}
289
290static void byahoo_remove_buddy( struct im_connection *ic, char *who, char *group )
291{
292        struct byahoo_data *yd = (struct byahoo_data *) ic->proto_data;
293        GSList *bgl;
294       
295        yahoo_remove_buddy( yd->y2_id, who, BYAHOO_DEFAULT_GROUP );
296       
297        for( bgl = yd->buddygroups; bgl; bgl = bgl->next )
298        {
299                struct byahoo_buddygroups *bg = bgl->data;
300               
301                if( g_strcasecmp( bg->buddy, who ) == 0 )
302                        yahoo_remove_buddy( yd->y2_id, who, bg->group );
303        }
304}
305
306static void byahoo_chat_msg( struct groupchat *c, char *message, int flags )
307{
308        struct byahoo_data *yd = (struct byahoo_data *) c->ic->proto_data;
309       
310        yahoo_conference_message( yd->y2_id, NULL, c->data, c->title, message, 1 );
311}
312
313static void byahoo_chat_invite( struct groupchat *c, char *who, char *msg )
314{
315        struct byahoo_data *yd = (struct byahoo_data *) c->ic->proto_data;
316       
317        yahoo_conference_invite( yd->y2_id, NULL, c->data, c->title, msg ? msg : "" );
318}
319
320static void byahoo_chat_leave( struct groupchat *c )
321{
322        struct byahoo_data *yd = (struct byahoo_data *) c->ic->proto_data;
323       
324        yahoo_conference_logoff( yd->y2_id, NULL, c->data, c->title );
325        imcb_chat_free( c );
326}
327
328static struct groupchat *byahoo_chat_with( struct im_connection *ic, char *who )
329{
330        struct byahoo_data *yd = (struct byahoo_data *) ic->proto_data;
331        struct groupchat *c;
332        char *roomname;
333        YList *members;
334       
335        roomname = g_strdup_printf( "%s-Bee-%d", ic->acc->user, byahoo_chat_id );
336       
337        c = imcb_chat_new( ic, roomname );
338        imcb_chat_add_buddy( c, ic->acc->user );
339       
340        /* FIXME: Free this thing when the chat's destroyed. We can't *always*
341                  do this because it's not always created here. */
342        c->data = members = g_new0( YList, 1 );
343        members->data = g_strdup( who );
344       
345        yahoo_conference_invite( yd->y2_id, NULL, members, roomname, "Please join my groupchat..." );
346       
347        g_free( roomname );
348       
349        return c;
350}
351
352void byahoo_initmodule( )
353{
354        struct prpl *ret = g_new0(struct prpl, 1);
355        ret->name = "yahoo";
356        ret->init = byahoo_init;
357       
358        ret->login = byahoo_login;
359        ret->keepalive = byahoo_keepalive;
360        ret->logout = byahoo_logout;
361       
362        ret->buddy_msg = byahoo_buddy_msg;
363        ret->get_info = byahoo_get_info;
364        ret->away_states = byahoo_away_states;
365        ret->set_away = byahoo_set_away;
366        ret->add_buddy = byahoo_add_buddy;
367        ret->remove_buddy = byahoo_remove_buddy;
368        ret->send_typing = byahoo_send_typing;
369       
370        ret->chat_msg = byahoo_chat_msg;
371        ret->chat_invite = byahoo_chat_invite;
372        ret->chat_leave = byahoo_chat_leave;
373        ret->chat_with = byahoo_chat_with;
374
375        ret->handle_cmp = g_strcasecmp;
376       
377        register_protocol(ret);
378}
379
380static struct im_connection *byahoo_get_ic_by_id( int id )
381{
382        GSList *l;
383        struct im_connection *ic;
384        struct byahoo_data *yd;
385       
386        for( l = get_connections(); l; l = l->next )
387        {
388                ic = l->data;
389                yd = ic->proto_data;
390               
391                if( strcmp( ic->acc->prpl->name, "yahoo" ) == 0 && yd->y2_id == id )
392                        return( ic );
393        }
394       
395        return( NULL );
396}
397
398
399/* Now it's callback time! */
400
401struct byahoo_connect_callback_data
402{
403        int fd;
404        yahoo_connect_callback callback;
405        gpointer data;
406        int id;
407};
408
409void byahoo_connect_callback( gpointer data, gint source, b_input_condition cond )
410{
411        struct byahoo_connect_callback_data *d = data;
412       
413        if( !byahoo_get_ic_by_id( d->id ) )
414        {
415                g_free( d );
416                return;
417        }
418       
419        d->callback( d->fd, 0, d->data );
420        g_free( d );
421}
422
423struct byahoo_read_ready_data
424{
425        int id;
426        int fd;
427        int tag;
428        gpointer data;
429};
430
431gboolean byahoo_read_ready_callback( gpointer data, gint source, b_input_condition cond )
432{
433        struct byahoo_read_ready_data *d = data;
434       
435        if( !byahoo_get_ic_by_id( d->id ) )
436                /* WTF doesn't libyahoo clean this up? */
437                return FALSE;
438       
439        yahoo_read_ready( d->id, d->fd, d->data );
440       
441        return TRUE;
442}
443
444struct byahoo_write_ready_data
445{
446        int id;
447        int fd;
448        int tag;
449        gpointer data;
450};
451
452gboolean byahoo_write_ready_callback( gpointer data, gint source, b_input_condition cond )
453{
454        struct byahoo_write_ready_data *d = data;
455       
456        yahoo_write_ready( d->id, d->fd, d->data );
457       
458        return FALSE;
459}
460
461void ext_yahoo_login_response( int id, int succ, const char *url )
462{
463        struct im_connection *ic = byahoo_get_ic_by_id( id );
464        struct byahoo_data *yd = NULL;
465       
466        if( ic == NULL )
467        {
468                /* libyahoo2 seems to call this one twice when something
469                   went wrong sometimes. Don't know why. Because we clean
470                   up the connection on the first failure, the second
471                   should be ignored. */
472               
473                return;
474        }
475       
476        yd = (struct byahoo_data *) ic->proto_data;
477       
478        if( succ == YAHOO_LOGIN_OK )
479        {
480                imcb_connected( ic );
481               
482                yd->logged_in = TRUE;
483        }
484        else
485        {
486                char *errstr;
487                int allow_reconnect = TRUE;
488               
489                yd->logged_in = FALSE;
490               
491                if( succ == YAHOO_LOGIN_UNAME )
492                        errstr = "Incorrect Yahoo! username";
493                else if( succ == YAHOO_LOGIN_PASSWD )
494                        errstr = "Incorrect Yahoo! password";
495                else if( succ == YAHOO_LOGIN_LOCK )
496                        errstr = "Yahoo! account locked";
497                else if( succ == YAHOO_LOGIN_DUPL )
498                {
499                        errstr = "Logged in on a different machine or device";
500                        allow_reconnect = FALSE;
501                }
502                else if( succ == YAHOO_LOGIN_SOCK )
503                        errstr = "Socket problem";
504                else
505                        errstr = "Unknown error";
506               
507                if( url && *url )
508                        imcb_error( ic, "Error %d (%s). See %s for more information.", succ, errstr, url );
509                else
510                        imcb_error( ic, "Error %d (%s)", succ, errstr );
511               
512                imc_logout( ic, allow_reconnect );
513        }
514}
515
516void ext_yahoo_got_buddies( int id, YList *buds )
517{
518        struct im_connection *ic = byahoo_get_ic_by_id( id );
519        struct byahoo_data *yd = ic->proto_data;
520        YList *bl = buds;
521       
522        while( bl )
523        {
524                struct yahoo_buddy *b = bl->data;
525                struct byahoo_buddygroups *bg;
526               
527                if( strcmp( b->group, BYAHOO_DEFAULT_GROUP ) != 0 )
528                {
529                        bg = g_new0( struct byahoo_buddygroups, 1 );
530                       
531                        bg->buddy = g_strdup( b->id );
532                        bg->group = g_strdup( b->group );
533                        yd->buddygroups = g_slist_append( yd->buddygroups, bg );
534                }
535               
536                imcb_add_buddy( ic, b->id, b->group );
537                imcb_rename_buddy( ic, b->id, b->real_name );
538               
539                bl = bl->next;
540        }
541}
542
543void ext_yahoo_got_ignore( int id, YList *igns )
544{
545}
546
547void ext_yahoo_got_identities( int id, YList *ids )
548{
549}
550
551void ext_yahoo_got_cookies( int id )
552{
553}
554
555void ext_yahoo_status_changed( int id, const char *who, int stat, const char *msg, int away, int idle, int mobile )
556{
557        struct im_connection *ic = byahoo_get_ic_by_id( id );
558        char *state_string = NULL;
559        int flags = OPT_LOGGED_IN;
560       
561        if( away )
562                flags |= OPT_AWAY;
563       
564        switch (stat)
565        {
566        case YAHOO_STATUS_BRB:
567                state_string = "Be Right Back";
568                break;
569        case YAHOO_STATUS_BUSY:
570                state_string = "Busy";
571                break;
572        case YAHOO_STATUS_NOTATHOME:
573                state_string = "Not At Home";
574                break;
575        case YAHOO_STATUS_NOTATDESK:
576                state_string = "Not At Desk";
577                break;
578        case YAHOO_STATUS_NOTINOFFICE:
579                state_string = "Not In Office";
580                break;
581        case YAHOO_STATUS_ONPHONE:
582                state_string = "On Phone";
583                break;
584        case YAHOO_STATUS_ONVACATION:
585                state_string = "On Vacation";
586                break;
587        case YAHOO_STATUS_OUTTOLUNCH:
588                state_string = "Out To Lunch";
589                break;
590        case YAHOO_STATUS_STEPPEDOUT:
591                state_string = "Stepped Out";
592                break;
593        case YAHOO_STATUS_INVISIBLE:
594                state_string = "Invisible";
595                break;
596        case YAHOO_STATUS_CUSTOM:
597                state_string = "Away";
598                break;
599        case YAHOO_STATUS_IDLE:
600                state_string = "Idle";
601                break;
602        case YAHOO_STATUS_OFFLINE:
603                state_string = "Offline";
604                flags = 0;
605                break;
606        case YAHOO_STATUS_NOTIFY:
607                state_string = "Notify";
608                break;
609        }
610       
611        imcb_buddy_status( ic, who, flags, state_string, msg );
612       
613        /* Not implemented yet...
614        if( stat == YAHOO_STATUS_IDLE )
615                imcb_buddy_times( ic, who, 0, away );
616        */
617}
618
619void ext_yahoo_got_im( int id, const char *me, const char *who, const char *msg, long tm, int stat, int utf8 )
620{
621        struct im_connection *ic = byahoo_get_ic_by_id( id );
622        char *m;
623       
624        if( msg )
625        {
626                m = byahoo_strip( msg );
627                imcb_buddy_msg( ic, (char*) who, (char*) m, 0, 0 );
628                g_free( m );
629        }
630}
631
632void ext_yahoo_got_file( int id,
633                         const char *ignored,
634                         const char *who, const char *url, long expires, const char *msg, const char *fname, unsigned long fesize )
635{
636        struct im_connection *ic = byahoo_get_ic_by_id( id );
637       
638        imcb_log( ic, "Got a file transfer (file = %s) from %s. Ignoring for now due to lack of support.", fname, who );
639}
640
641void ext_yahoo_typing_notify( int id, const char *ignored, const char *who, int stat )
642{
643        struct im_connection *ic = byahoo_get_ic_by_id( id );
644       
645        if( stat == 1 )
646                imcb_buddy_typing( ic, (char*) who, OPT_TYPING );
647        else
648                imcb_buddy_typing( ic, (char*) who, 0 );
649}
650
651void ext_yahoo_system_message( int id, const char *msg )
652{
653        struct im_connection *ic = byahoo_get_ic_by_id( id );
654       
655        imcb_log( ic, "Yahoo! system message: %s", msg );
656}
657
658void ext_yahoo_webcam_invite( int id, const char *ignored, const char *from )
659{
660        struct im_connection *ic = byahoo_get_ic_by_id( id );
661       
662        imcb_log( ic, "Got a webcam invitation from %s. IRC+webcams is a no-no though...", from );
663}
664
665void ext_yahoo_error( int id, const char *err, int fatal, int num )
666{
667        struct im_connection *ic = byahoo_get_ic_by_id( id );
668       
669        imcb_error( ic, "%s", err );
670       
671        if( fatal )
672                imc_logout( ic, TRUE );
673}
674
675/* TODO: Clear up the mess of inp and d structures */
676int ext_yahoo_add_handler( int id, int fd, yahoo_input_condition cond, void *data )
677{
678        struct byahoo_input_data *inp = g_new0( struct byahoo_input_data, 1 );
679       
680        if( cond == YAHOO_INPUT_READ )
681        {
682                struct byahoo_read_ready_data *d = g_new0( struct byahoo_read_ready_data, 1 );
683               
684                d->id = id;
685                d->fd = fd;
686                d->data = data;
687               
688                inp->d = d;
689                d->tag = inp->h = b_input_add( fd, GAIM_INPUT_READ, (b_event_handler) byahoo_read_ready_callback, (gpointer) d );
690        }
691        else if( cond == YAHOO_INPUT_WRITE )
692        {
693                struct byahoo_write_ready_data *d = g_new0( struct byahoo_write_ready_data, 1 );
694               
695                d->id = id;
696                d->fd = fd;
697                d->data = data;
698               
699                inp->d = d;
700                d->tag = inp->h = b_input_add( fd, GAIM_INPUT_WRITE, (b_event_handler) byahoo_write_ready_callback, (gpointer) d );
701        }
702        else
703        {
704                g_free( inp );
705                return( -1 );
706                /* Panic... */
707        }
708       
709        byahoo_inputs = g_slist_append( byahoo_inputs, inp );
710        return( inp->h );
711}
712
713void ext_yahoo_remove_handler( int id, int tag )
714{
715        struct byahoo_input_data *inp;
716        GSList *l = byahoo_inputs;
717       
718        while( l )
719        {
720                inp = l->data;
721                if( inp->h == tag )
722                {
723                        g_free( inp->d );
724                        g_free( inp );
725                        byahoo_inputs = g_slist_remove( byahoo_inputs, inp );
726                        break;
727                }
728                l = l->next;
729        }
730       
731        b_event_remove( tag );
732}
733
734int ext_yahoo_connect_async( int id, const char *host, int port, yahoo_connect_callback callback, void *data )
735{
736        struct byahoo_connect_callback_data *d;
737        int fd;
738       
739        d = g_new0( struct byahoo_connect_callback_data, 1 );
740        if( ( fd = proxy_connect( host, port, (b_event_handler) byahoo_connect_callback, (gpointer) d ) ) < 0 )
741        {
742                g_free( d );
743                return( fd );
744        }
745        d->fd = fd;
746        d->callback = callback;
747        d->data = data;
748        d->id = id;
749       
750        return( fd );
751}
752
753/* Because we don't want asynchronous connects in BitlBee, and because
754   libyahoo doesn't seem to use this one anyway, this one is now defunct. */
755int ext_yahoo_connect(const char *host, int port)
756{
757#if 0
758        struct sockaddr_in serv_addr;
759        static struct hostent *server;
760        static char last_host[256];
761        int servfd;
762        char **p;
763
764        if(last_host[0] || g_strcasecmp(last_host, host)!=0) {
765                if(!(server = gethostbyname(host))) {
766                        return -1;
767                }
768                strncpy(last_host, host, 255);
769        }
770
771        if((servfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
772                return -1;
773        }
774
775        for (p = server->h_addr_list; *p; p++)
776        {
777                memset(&serv_addr, 0, sizeof(serv_addr));
778                serv_addr.sin_family = AF_INET;
779                memcpy(&serv_addr.sin_addr.s_addr, *p, server->h_length);
780                serv_addr.sin_port = htons(port);
781
782                if(connect(servfd, (struct sockaddr *) &serv_addr,
783                                        sizeof(serv_addr)) == -1) {
784                        return -1;
785                } else {
786                        return servfd;
787                }
788        }
789
790        closesocket(servfd);
791#endif
792        return -1;
793}
794
795static void byahoo_accept_conf( void *data )
796{
797        struct byahoo_conf_invitation *inv = data;
798       
799        yahoo_conference_logon( inv->yid, NULL, inv->members, inv->name );
800        imcb_chat_add_buddy( inv->c, inv->ic->acc->user );
801        g_free( inv->name );
802        g_free( inv );
803}
804
805static void byahoo_reject_conf( void *data )
806{
807        struct byahoo_conf_invitation *inv = data;
808       
809        yahoo_conference_decline( inv->yid, NULL, inv->members, inv->name, "User rejected groupchat" );
810        imcb_chat_free( inv->c );
811        g_free( inv->name );
812        g_free( inv );
813}
814
815void ext_yahoo_got_conf_invite( int id, const char *ignored,
816                                const char *who, const char *room, const char *msg, YList *members )
817{
818        struct im_connection *ic = byahoo_get_ic_by_id( id );
819        struct byahoo_conf_invitation *inv;
820        char txt[1024];
821        YList *m;
822       
823        inv = g_malloc( sizeof( struct byahoo_conf_invitation ) );
824        memset( inv, 0, sizeof( struct byahoo_conf_invitation ) );
825        inv->name = g_strdup( room );
826        inv->c = imcb_chat_new( ic, (char*) room );
827        inv->c->data = members;
828        inv->yid = id;
829        inv->members = members;
830        inv->ic = ic;
831       
832        for( m = members; m; m = m->next )
833                if( g_strcasecmp( m->data, ic->acc->user ) != 0 )
834                        imcb_chat_add_buddy( inv->c, m->data );
835       
836        g_snprintf( txt, 1024, "Got an invitation to chatroom %s from %s: %s", room, who, msg );
837       
838        imcb_ask( ic, txt, inv, byahoo_accept_conf, byahoo_reject_conf );
839}
840
841void ext_yahoo_conf_userdecline( int id, const char *ignored, const char *who, const char *room, const char *msg )
842{
843        struct im_connection *ic = byahoo_get_ic_by_id( id );
844       
845        imcb_log( ic, "Invite to chatroom %s rejected by %s: %s", room, who, msg );
846}
847
848void ext_yahoo_conf_userjoin( int id, const char *ignored, const char *who, const char *room )
849{
850        struct im_connection *ic = byahoo_get_ic_by_id( id );
851        struct groupchat *c;
852       
853        for( c = ic->groupchats; c && strcmp( c->title, room ) != 0; c = c->next );
854       
855        if( c )
856                imcb_chat_add_buddy( c, (char*) who );
857}
858
859void ext_yahoo_conf_userleave( int id, const char *ignored, const char *who, const char *room )
860
861{
862        struct im_connection *ic = byahoo_get_ic_by_id( id );
863        struct groupchat *c;
864       
865        for( c = ic->groupchats; c && strcmp( c->title, room ) != 0; c = c->next );
866       
867        if( c )
868                imcb_chat_remove_buddy( c, (char*) who, "" );
869}
870
871void ext_yahoo_conf_message( int id, const char *ignored, const char *who, const char *room, const char *msg, int utf8 )
872{
873        struct im_connection *ic = byahoo_get_ic_by_id( id );
874        char *m = byahoo_strip( msg );
875        struct groupchat *c;
876       
877        for( c = ic->groupchats; c && strcmp( c->title, room ) != 0; c = c->next );
878       
879        if( c )
880                imcb_chat_msg( c, (char*) who, (char*) m, 0, 0 );
881        g_free( m );
882}
883
884void ext_yahoo_chat_cat_xml( int id, const char *xml )
885{
886}
887
888void ext_yahoo_chat_join( int id, const char *who, const char *room, const char *topic, YList *members, int fd )
889{
890}
891
892void ext_yahoo_chat_userjoin( int id, const char *me, const char *room, struct yahoo_chat_member *who )
893{
894        free(who->id);
895        free(who->alias);
896        free(who->location);
897        free(who);
898}
899
900void ext_yahoo_chat_userleave( int id, const char *me, const char *room, const char *who )
901{
902}
903
904void ext_yahoo_chat_message( int id, const char *me, const char *who, const char *room, const char *msg, int msgtype, int utf8 )
905{
906}
907
908void ext_yahoo_chat_yahoologout( int id, const char *me )
909{
910}
911
912void ext_yahoo_chat_yahooerror( int id, const char *me )
913{
914}
915
916void ext_yahoo_contact_added( int id, const char *myid, const char *who, const char *msg )
917{
918        /* Groups schmoups. If I want to handle groups properly I can get the
919           buddy data from some internal libyahoo2 structure. */
920        imcb_add_buddy( byahoo_get_ic_by_id( id ), (char*) who, NULL );
921}
922
923void ext_yahoo_rejected( int id, const char *who, const char *msg )
924{
925}
926
927void ext_yahoo_game_notify( int id, const char *me, const char *who, int stat )
928{
929}
930
931void ext_yahoo_mail_notify( int id, const char *from, const char *subj, int cnt )
932{
933        struct im_connection *ic = byahoo_get_ic_by_id( id );
934       
935        if( !set_getbool( &ic->acc->set, "mail_notifications" ) )
936                ; /* The user doesn't care. */
937        else if( from && subj )
938                imcb_log( ic, "Received e-mail message from %s with subject `%s'", from, subj );
939        else if( cnt > 0 )
940                imcb_log( ic, "Received %d new e-mails", cnt );
941}
942
943void ext_yahoo_webcam_invite_reply( int id, const char *me, const char *from, int accept )
944{
945}
946
947void ext_yahoo_webcam_closed( int id, const char *who, int reason )
948{
949}
950
951void ext_yahoo_got_search_result( int id, int found, int start, int total, YList *contacts )
952{
953}
954
955void ext_yahoo_webcam_viewer( int id, const char *who, int connect )
956{
957}
958
959void ext_yahoo_webcam_data_request( int id, int send )
960{
961}
962
963int ext_yahoo_log( const char *fmt, ... )
964{
965        return( 0 );
966}
967
968void 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 )
969{
970}
971
972void ext_yahoo_got_ping( int id, const char *msg)
973{
974}
975
976void ext_yahoo_got_buddyicon (int id, const char *me, const char *who, const char *url, int checksum) {}
977void ext_yahoo_got_buddyicon_checksum (int id, const char *me,const char *who, int checksum) {}
978
979void ext_yahoo_got_buddyicon_request(int id, const char *me, const char *who){}
980void ext_yahoo_buddyicon_uploaded(int id, const char *url){}
Note: See TracBrowser for help on using the repository browser.