source: protocols/yahoo/yahoo.c @ eb6df6a

Last change on this file since eb6df6a was bb09b3c, checked in by Sven Moritz Hallberg <pesco@…>, at 2010-06-03T21:13:57Z

merge in bitlbee 1.2.7

  • Property mode set to 100644
File size: 24.2 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        acc->flags |= ACC_FLAG_AWAY_MESSAGE | ACC_FLAG_STATUS_MESSAGE;
134}
135
136static void byahoo_login( account_t *acc )
137{
138        struct im_connection *ic = imcb_new( acc );
139        struct byahoo_data *yd = ic->proto_data = g_new0( struct byahoo_data, 1 );
140        char *s;
141       
142        yd->logged_in = FALSE;
143        yd->current_status = YAHOO_STATUS_AVAILABLE;
144       
145        if( ( s = strchr( acc->user, '@' ) ) && g_strcasecmp( s, "@yahoo.com" ) == 0 )
146                imcb_error( ic, "Your Yahoo! username should just be a username. "
147                                "Do not include any @domain part." );
148       
149        imcb_log( ic, "Connecting" );
150        yd->y2_id = yahoo_init( acc->user, acc->pass );
151        yahoo_login( yd->y2_id, yd->current_status );
152}
153
154static void byahoo_logout( struct im_connection *ic )
155{
156        struct byahoo_data *yd = (struct byahoo_data *) ic->proto_data;
157        GSList *l;
158       
159        while( ic->groupchats )
160                imcb_chat_free( ic->groupchats );
161       
162        for( l = yd->buddygroups; l; l = l->next )
163        {
164                struct byahoo_buddygroups *bg = l->data;
165               
166                g_free( bg->buddy );
167                g_free( bg->group );
168                g_free( bg );
169        }
170        g_slist_free( yd->buddygroups );
171       
172        yahoo_logoff( yd->y2_id );
173       
174        g_free( yd );
175}
176
177static void byahoo_get_info(struct im_connection *ic, char *who) 
178{
179        /* Just make an URL and let the user fetch the info */
180        imcb_log(ic, "%s\n%s: %s%s", _("User Info"), 
181                        _("For now, fetch yourself"), yahoo_get_profile_url(),
182                        who);
183}
184
185static int byahoo_buddy_msg( struct im_connection *ic, char *who, char *what, int flags )
186{
187        struct byahoo_data *yd = ic->proto_data;
188       
189        yahoo_send_im( yd->y2_id, NULL, who, what, 1, 0 );
190       
191        return 1;
192}
193
194static int byahoo_send_typing( struct im_connection *ic, char *who, int typing )
195{
196        struct byahoo_data *yd = ic->proto_data;
197       
198        yahoo_send_typing( yd->y2_id, NULL, who, ( typing & OPT_TYPING ) != 0 );
199       
200        return 1;
201}
202
203static void byahoo_set_away( struct im_connection *ic, char *state, char *msg )
204{
205        struct byahoo_data *yd = (struct byahoo_data *) ic->proto_data;
206       
207        if( state && msg == NULL )
208        {
209                /* Use these states only if msg doesn't contain additional
210                   info since away messages are only supported with CUSTOM. */
211                if( g_strcasecmp( state, "Be Right Back" ) == 0 )
212                        yd->current_status = YAHOO_STATUS_BRB;
213                else if( g_strcasecmp( state, "Busy" ) == 0 )
214                        yd->current_status = YAHOO_STATUS_BUSY;
215                else if( g_strcasecmp( state, "Not At Home" ) == 0 )
216                        yd->current_status = YAHOO_STATUS_NOTATHOME;
217                else if( g_strcasecmp( state, "Not At Desk" ) == 0 )
218                        yd->current_status = YAHOO_STATUS_NOTATDESK;
219                else if( g_strcasecmp( state, "Not In Office" ) == 0 )
220                        yd->current_status = YAHOO_STATUS_NOTINOFFICE;
221                else if( g_strcasecmp( state, "On Phone" ) == 0 )
222                        yd->current_status = YAHOO_STATUS_ONPHONE;
223                else if( g_strcasecmp( state, "On Vacation" ) == 0 )
224                        yd->current_status = YAHOO_STATUS_ONVACATION;
225                else if( g_strcasecmp( state, "Out To Lunch" ) == 0 )
226                        yd->current_status = YAHOO_STATUS_OUTTOLUNCH;
227                else if( g_strcasecmp( state, "Stepped Out" ) == 0 )
228                        yd->current_status = YAHOO_STATUS_STEPPEDOUT;
229                else if( g_strcasecmp( state, "Invisible" ) == 0 )
230                        yd->current_status = YAHOO_STATUS_INVISIBLE;
231                else
232                        yd->current_status = YAHOO_STATUS_CUSTOM;
233        }
234        else if( msg )
235                yd->current_status = YAHOO_STATUS_CUSTOM;
236        else
237                yd->current_status = YAHOO_STATUS_AVAILABLE;
238       
239        yahoo_set_away( yd->y2_id, yd->current_status, msg, state ? 2 : 0 );
240}
241
242static GList *byahoo_away_states( struct im_connection *ic )
243{
244        static GList *m = NULL;
245
246        if( m == NULL )
247        {
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        }
259       
260        return m;
261}
262
263static void byahoo_keepalive( struct im_connection *ic )
264{
265        struct byahoo_data *yd = ic->proto_data;
266       
267        yahoo_keepalive( yd->y2_id );
268}
269
270static void byahoo_add_buddy( struct im_connection *ic, char *who, char *group )
271{
272        struct byahoo_data *yd = (struct byahoo_data *) ic->proto_data;
273       
274        yahoo_add_buddy( yd->y2_id, who, group ? group : BYAHOO_DEFAULT_GROUP, NULL );
275}
276
277static void byahoo_remove_buddy( struct im_connection *ic, char *who, char *group )
278{
279        struct byahoo_data *yd = (struct byahoo_data *) ic->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 void byahoo_chat_msg( struct groupchat *c, char *message, int flags )
294{
295        struct byahoo_data *yd = (struct byahoo_data *) c->ic->proto_data;
296       
297        yahoo_conference_message( yd->y2_id, NULL, c->data, c->title, message, 1 );
298}
299
300static void byahoo_chat_invite( struct groupchat *c, char *who, char *msg )
301{
302        struct byahoo_data *yd = (struct byahoo_data *) c->ic->proto_data;
303       
304        yahoo_conference_invite( yd->y2_id, NULL, c->data, c->title, msg ? msg : "" );
305}
306
307static void byahoo_chat_leave( struct groupchat *c )
308{
309        struct byahoo_data *yd = (struct byahoo_data *) c->ic->proto_data;
310       
311        yahoo_conference_logoff( yd->y2_id, NULL, c->data, c->title );
312        imcb_chat_free( c );
313}
314
315static struct groupchat *byahoo_chat_with( struct im_connection *ic, char *who )
316{
317        struct byahoo_data *yd = (struct byahoo_data *) ic->proto_data;
318        struct groupchat *c;
319        char *roomname;
320        YList *members;
321       
322        roomname = g_strdup_printf( "%s-Bee-%d", ic->acc->user, byahoo_chat_id );
323       
324        c = imcb_chat_new( ic, roomname );
325        imcb_chat_add_buddy( c, ic->acc->user );
326       
327        /* FIXME: Free this thing when the chat's destroyed. We can't *always*
328                  do this because it's not always created here. */
329        c->data = members = g_new0( YList, 1 );
330        members->data = g_strdup( who );
331       
332        yahoo_conference_invite( yd->y2_id, NULL, members, roomname, "Please join my groupchat..." );
333       
334        g_free( roomname );
335       
336        return c;
337}
338
339static void byahoo_auth_allow( struct im_connection *ic, const char *who )
340{
341        struct byahoo_data *yd = (struct byahoo_data *) ic->proto_data;
342       
343        yahoo_accept_buddy_ymsg13( yd->y2_id, NULL, who );
344}
345
346static void byahoo_auth_deny( struct im_connection *ic, const char *who )
347{
348        struct byahoo_data *yd = (struct byahoo_data *) ic->proto_data;
349       
350        yahoo_reject_buddy_ymsg13( yd->y2_id, NULL, who, NULL );
351}
352
353void byahoo_initmodule( )
354{
355        struct prpl *ret = g_new0(struct prpl, 1);
356        ret->name = "yahoo";
357    ret->mms = 832;           /* this guess taken from libotr UPGRADING file */
358        ret->init = byahoo_init;
359       
360        ret->login = byahoo_login;
361        ret->keepalive = byahoo_keepalive;
362        ret->logout = byahoo_logout;
363       
364        ret->buddy_msg = byahoo_buddy_msg;
365        ret->get_info = byahoo_get_info;
366        ret->away_states = byahoo_away_states;
367        ret->set_away = byahoo_set_away;
368        ret->add_buddy = byahoo_add_buddy;
369        ret->remove_buddy = byahoo_remove_buddy;
370        ret->send_typing = byahoo_send_typing;
371       
372        ret->chat_msg = byahoo_chat_msg;
373        ret->chat_invite = byahoo_chat_invite;
374        ret->chat_leave = byahoo_chat_leave;
375        ret->chat_with = byahoo_chat_with;
376
377        ret->handle_cmp = g_strcasecmp;
378       
379        ret->auth_allow = byahoo_auth_allow;
380        ret->auth_deny = byahoo_auth_deny;
381       
382        register_protocol(ret);
383}
384
385static struct im_connection *byahoo_get_ic_by_id( int id )
386{
387        GSList *l;
388        struct im_connection *ic;
389        struct byahoo_data *yd;
390       
391        for( l = get_connections(); l; l = l->next )
392        {
393                ic = l->data;
394                yd = ic->proto_data;
395               
396                if( strcmp( ic->acc->prpl->name, "yahoo" ) == 0 && yd->y2_id == id )
397                        return( ic );
398        }
399       
400        return( NULL );
401}
402
403
404/* Now it's callback time! */
405
406struct byahoo_connect_callback_data
407{
408        int fd;
409        yahoo_connect_callback callback;
410        gpointer data;
411        int id;
412};
413
414void byahoo_connect_callback( gpointer data, gint source, b_input_condition cond )
415{
416        struct byahoo_connect_callback_data *d = data;
417       
418        if( !byahoo_get_ic_by_id( d->id ) )
419        {
420                g_free( d );
421                return;
422        }
423       
424        d->callback( d->fd, 0, d->data );
425        g_free( d );
426}
427
428struct byahoo_read_ready_data
429{
430        int id;
431        int fd;
432        int tag;
433        gpointer data;
434};
435
436gboolean byahoo_read_ready_callback( gpointer data, gint source, b_input_condition cond )
437{
438        struct byahoo_read_ready_data *d = data;
439       
440        if( !byahoo_get_ic_by_id( d->id ) )
441                /* WTF doesn't libyahoo clean this up? */
442                return FALSE;
443       
444        yahoo_read_ready( d->id, d->fd, d->data );
445       
446        return TRUE;
447}
448
449struct byahoo_write_ready_data
450{
451        int id;
452        int fd;
453        int tag;
454        gpointer data;
455};
456
457gboolean byahoo_write_ready_callback( gpointer data, gint source, b_input_condition cond )
458{
459        struct byahoo_write_ready_data *d = data;
460       
461        return yahoo_write_ready( d->id, d->fd, d->data );
462}
463
464void ext_yahoo_login_response( int id, int succ, const char *url )
465{
466        struct im_connection *ic = byahoo_get_ic_by_id( id );
467        struct byahoo_data *yd = NULL;
468       
469        if( ic == NULL )
470        {
471                /* libyahoo2 seems to call this one twice when something
472                   went wrong sometimes. Don't know why. Because we clean
473                   up the connection on the first failure, the second
474                   should be ignored. */
475               
476                return;
477        }
478       
479        yd = (struct byahoo_data *) ic->proto_data;
480       
481        if( succ == YAHOO_LOGIN_OK )
482        {
483                imcb_connected( ic );
484               
485                yd->logged_in = TRUE;
486        }
487        else
488        {
489                char *errstr;
490                int allow_reconnect = TRUE;
491               
492                yd->logged_in = FALSE;
493               
494                if( succ == YAHOO_LOGIN_UNAME )
495                        errstr = "Incorrect Yahoo! username";
496                else if( succ == YAHOO_LOGIN_PASSWD )
497                        errstr = "Incorrect Yahoo! password";
498                else if( succ == YAHOO_LOGIN_LOCK )
499                        errstr = "Yahoo! account locked";
500                else if( succ == YAHOO_LOGIN_DUPL )
501                {
502                        errstr = "Logged in on a different machine or device";
503                        allow_reconnect = FALSE;
504                }
505                else if( succ == YAHOO_LOGIN_SOCK )
506                        errstr = "Socket problem";
507                else
508                        errstr = "Unknown error";
509               
510                if( url && *url )
511                        imcb_error( ic, "Error %d (%s). See %s for more information.", succ, errstr, url );
512                else
513                        imcb_error( ic, "Error %d (%s)", succ, errstr );
514               
515                imc_logout( ic, allow_reconnect );
516        }
517}
518
519void ext_yahoo_got_buddies( int id, YList *buds )
520{
521        struct im_connection *ic = byahoo_get_ic_by_id( id );
522        struct byahoo_data *yd = ic->proto_data;
523        YList *bl = buds;
524       
525        while( bl )
526        {
527                struct yahoo_buddy *b = bl->data;
528                struct byahoo_buddygroups *bg;
529               
530                if( strcmp( b->group, BYAHOO_DEFAULT_GROUP ) != 0 )
531                {
532                        bg = g_new0( struct byahoo_buddygroups, 1 );
533                       
534                        bg->buddy = g_strdup( b->id );
535                        bg->group = g_strdup( b->group );
536                        yd->buddygroups = g_slist_append( yd->buddygroups, bg );
537                }
538               
539                imcb_add_buddy( ic, b->id, b->group );
540                imcb_rename_buddy( ic, b->id, b->real_name );
541               
542                bl = bl->next;
543        }
544}
545
546void ext_yahoo_got_ignore( int id, YList *igns )
547{
548}
549
550void ext_yahoo_got_identities( int id, YList *ids )
551{
552}
553
554void ext_yahoo_got_cookies( int id )
555{
556}
557
558void ext_yahoo_status_changed( int id, const char *who, int stat, const char *msg, int away, int idle, int mobile )
559{
560        struct im_connection *ic = byahoo_get_ic_by_id( id );
561        char *state_string = NULL;
562        int flags = OPT_LOGGED_IN;
563       
564        if( away )
565                flags |= OPT_AWAY;
566       
567        switch (stat)
568        {
569        case YAHOO_STATUS_BRB:
570                state_string = "Be Right Back";
571                break;
572        case YAHOO_STATUS_BUSY:
573                state_string = "Busy";
574                break;
575        case YAHOO_STATUS_NOTATHOME:
576                state_string = "Not At Home";
577                break;
578        case YAHOO_STATUS_NOTATDESK:
579                state_string = "Not At Desk";
580                break;
581        case YAHOO_STATUS_NOTINOFFICE:
582                state_string = "Not In Office";
583                break;
584        case YAHOO_STATUS_ONPHONE:
585                state_string = "On Phone";
586                break;
587        case YAHOO_STATUS_ONVACATION:
588                state_string = "On Vacation";
589                break;
590        case YAHOO_STATUS_OUTTOLUNCH:
591                state_string = "Out To Lunch";
592                break;
593        case YAHOO_STATUS_STEPPEDOUT:
594                state_string = "Stepped Out";
595                break;
596        case YAHOO_STATUS_INVISIBLE:
597                state_string = "Invisible";
598                break;
599        case YAHOO_STATUS_CUSTOM:
600                state_string = "Away";
601                break;
602        case YAHOO_STATUS_IDLE:
603                state_string = "Idle";
604                break;
605        case YAHOO_STATUS_OFFLINE:
606                state_string = "Offline";
607                flags = 0;
608                break;
609        case YAHOO_STATUS_NOTIFY:
610                state_string = "Notify";
611                break;
612        }
613       
614        imcb_buddy_status( ic, who, flags, state_string, msg );
615       
616        /* Not implemented yet...
617        if( stat == YAHOO_STATUS_IDLE )
618                imcb_buddy_times( ic, who, 0, away );
619        */
620}
621
622void ext_yahoo_got_im( int id, const char *me, const char *who, const char *msg, long tm, int stat, int utf8 )
623{
624        struct im_connection *ic = byahoo_get_ic_by_id( id );
625        char *m;
626       
627        if( msg )
628        {
629                m = byahoo_strip( msg );
630                imcb_buddy_msg( ic, (char*) who, (char*) m, 0, 0 );
631                g_free( m );
632        }
633}
634
635void ext_yahoo_got_file( int id,
636                         const char *ignored,
637                         const char *who, const char *url, long expires, const char *msg, const char *fname, unsigned long fesize )
638{
639        struct im_connection *ic = byahoo_get_ic_by_id( id );
640       
641        imcb_log( ic, "Got a file transfer (file = %s) from %s. Ignoring for now due to lack of support.", fname, who );
642}
643
644void ext_yahoo_typing_notify( int id, const char *ignored, const char *who, int stat )
645{
646        struct im_connection *ic = byahoo_get_ic_by_id( id );
647       
648        if( stat == 1 )
649                imcb_buddy_typing( ic, (char*) who, OPT_TYPING );
650        else
651                imcb_buddy_typing( ic, (char*) who, 0 );
652}
653
654void ext_yahoo_system_message( int id, const char *msg )
655{
656        struct im_connection *ic = byahoo_get_ic_by_id( id );
657       
658        imcb_log( ic, "Yahoo! system message: %s", msg );
659}
660
661void ext_yahoo_webcam_invite( int id, const char *ignored, const char *from )
662{
663        struct im_connection *ic = byahoo_get_ic_by_id( id );
664       
665        imcb_log( ic, "Got a webcam invitation from %s. IRC+webcams is a no-no though...", from );
666}
667
668void ext_yahoo_error( int id, const char *err, int fatal, int num )
669{
670        struct im_connection *ic = byahoo_get_ic_by_id( id );
671       
672        imcb_error( ic, "%s", err );
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        struct groupchat *b;
799       
800        for( b = inv->ic->groupchats; b; b = b->next )
801                if( b == inv->c )
802                        break;
803       
804        if( b != NULL )
805        {
806                yahoo_conference_logon( inv->yid, NULL, inv->members, inv->name );
807                imcb_chat_add_buddy( inv->c, inv->ic->acc->user );
808        }
809        else
810        {
811                imcb_log( inv->ic, "Duplicate/corrupted invitation to `%s'.", inv->name );
812        }
813       
814        g_free( inv->name );
815        g_free( inv );
816}
817
818static void byahoo_reject_conf( void *data )
819{
820        struct byahoo_conf_invitation *inv = data;
821       
822        yahoo_conference_decline( inv->yid, NULL, inv->members, inv->name, "User rejected groupchat" );
823        imcb_chat_free( inv->c );
824        g_free( inv->name );
825        g_free( inv );
826}
827
828void ext_yahoo_got_conf_invite( int id, const char *ignored,
829                                const char *who, const char *room, const char *msg, YList *members )
830{
831        struct im_connection *ic = byahoo_get_ic_by_id( id );
832        struct byahoo_conf_invitation *inv;
833        char txt[1024];
834        YList *m;
835       
836        if( g_strcasecmp( who, ic->acc->user ) == 0 )
837                /* WTF, Yahoo! seems to echo these now? */
838                return;
839       
840        inv = g_malloc( sizeof( struct byahoo_conf_invitation ) );
841        memset( inv, 0, sizeof( struct byahoo_conf_invitation ) );
842        inv->name = g_strdup( room );
843        inv->c = imcb_chat_new( ic, (char*) room );
844        inv->c->data = members;
845        inv->yid = id;
846        inv->members = members;
847        inv->ic = ic;
848       
849        for( m = members; m; m = m->next )
850                if( g_strcasecmp( m->data, ic->acc->user ) != 0 )
851                        imcb_chat_add_buddy( inv->c, m->data );
852       
853        g_snprintf( txt, 1024, "Got an invitation to chatroom %s from %s: %s", room, who, msg );
854       
855        imcb_ask( ic, txt, inv, byahoo_accept_conf, byahoo_reject_conf );
856}
857
858void ext_yahoo_conf_userdecline( int id, const char *ignored, const char *who, const char *room, const char *msg )
859{
860        struct im_connection *ic = byahoo_get_ic_by_id( id );
861       
862        imcb_log( ic, "Invite to chatroom %s rejected by %s: %s", room, who, msg );
863}
864
865void ext_yahoo_conf_userjoin( int id, const char *ignored, const char *who, const char *room )
866{
867        struct im_connection *ic = byahoo_get_ic_by_id( id );
868        struct groupchat *c;
869       
870        for( c = ic->groupchats; c && strcmp( c->title, room ) != 0; c = c->next );
871       
872        if( c )
873                imcb_chat_add_buddy( c, (char*) who );
874}
875
876void ext_yahoo_conf_userleave( int id, const char *ignored, const char *who, const char *room )
877
878{
879        struct im_connection *ic = byahoo_get_ic_by_id( id );
880        struct groupchat *c;
881       
882        for( c = ic->groupchats; c && strcmp( c->title, room ) != 0; c = c->next );
883       
884        if( c )
885                imcb_chat_remove_buddy( c, (char*) who, "" );
886}
887
888void ext_yahoo_conf_message( int id, const char *ignored, const char *who, const char *room, const char *msg, int utf8 )
889{
890        struct im_connection *ic = byahoo_get_ic_by_id( id );
891        char *m = byahoo_strip( msg );
892        struct groupchat *c;
893       
894        for( c = ic->groupchats; c && strcmp( c->title, room ) != 0; c = c->next );
895       
896        if( c )
897                imcb_chat_msg( c, (char*) who, (char*) m, 0, 0 );
898        g_free( m );
899}
900
901void ext_yahoo_chat_cat_xml( int id, const char *xml )
902{
903}
904
905void ext_yahoo_chat_join( int id, const char *who, const char *room, const char *topic, YList *members, int fd )
906{
907}
908
909void ext_yahoo_chat_userjoin( int id, const char *me, const char *room, struct yahoo_chat_member *who )
910{
911        free(who->id);
912        free(who->alias);
913        free(who->location);
914        free(who);
915}
916
917void ext_yahoo_chat_userleave( int id, const char *me, const char *room, const char *who )
918{
919}
920
921void ext_yahoo_chat_message( int id, const char *me, const char *who, const char *room, const char *msg, int msgtype, int utf8 )
922{
923}
924
925void ext_yahoo_chat_yahoologout( int id, const char *me )
926{
927}
928
929void ext_yahoo_chat_yahooerror( int id, const char *me )
930{
931}
932
933void ext_yahoo_contact_auth_request( int id, const char *myid, const char *who, const char *msg )
934{
935        struct im_connection *ic = byahoo_get_ic_by_id( id );
936       
937        imcb_ask_auth( ic, who, NULL );
938}
939
940void ext_yahoo_contact_added( int id, const char *myid, const char *who, const char *msg )
941{
942        struct im_connection *ic = byahoo_get_ic_by_id( id );
943       
944        imcb_add_buddy( ic, (char*) who, NULL );
945}
946
947void ext_yahoo_rejected( int id, const char *who, const char *msg )
948{
949}
950
951void ext_yahoo_game_notify( int id, const char *me, const char *who, int stat )
952{
953}
954
955void ext_yahoo_mail_notify( int id, const char *from, const char *subj, int cnt )
956{
957        struct im_connection *ic = byahoo_get_ic_by_id( id );
958       
959        if( !set_getbool( &ic->acc->set, "mail_notifications" ) )
960                ; /* The user doesn't care. */
961        else if( from && subj )
962                imcb_log( ic, "Received e-mail message from %s with subject `%s'", from, subj );
963        else if( cnt > 0 )
964                imcb_log( ic, "Received %d new e-mails", cnt );
965}
966
967void ext_yahoo_webcam_invite_reply( int id, const char *me, const char *from, int accept )
968{
969}
970
971void ext_yahoo_webcam_closed( int id, const char *who, int reason )
972{
973}
974
975void ext_yahoo_got_search_result( int id, int found, int start, int total, YList *contacts )
976{
977}
978
979void ext_yahoo_webcam_viewer( int id, const char *who, int connect )
980{
981}
982
983void ext_yahoo_webcam_data_request( int id, int send )
984{
985}
986
987int ext_yahoo_log( const char *fmt, ... )
988{
989        return( 0 );
990}
991
992void 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 )
993{
994}
995
996void ext_yahoo_got_ping( int id, const char *msg)
997{
998}
999
1000void ext_yahoo_got_buddyicon (int id, const char *me, const char *who, const char *url, int checksum) {}
1001void ext_yahoo_got_buddyicon_checksum (int id, const char *me,const char *who, int checksum) {}
1002
1003void ext_yahoo_got_buddyicon_request(int id, const char *me, const char *who){}
1004void ext_yahoo_buddyicon_uploaded(int id, const char *url){}
Note: See TracBrowser for help on using the repository browser.