source: protocols/yahoo/yahoo.c @ ba16895

Last change on this file since ba16895 was ba16895, checked in by Wilmer van der Gaast <wilmer@…>, at 2009-10-10T13:48:44Z

More Yahoo! fixes: Adding and removing buddies works, and for the first
time buddy add requests are actually handled; from what I can see this
simply didn't exist in libyahoo2 yet so far. :-(

I melded pieces of changes from http://geny.sf.net/ to make this stuff
work.

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