source: protocols/yahoo/yahoo.c @ 4bc66ae

Last change on this file since 4bc66ae was be999a5, checked in by Wilmer van der Gaast <wilmer@…>, at 2010-08-23T23:12:24Z

First step in this merge. Mostly a bzr merge and then a cleanup of conflicts
and parts I want to/have to redo (because of ui-fix).

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