source: protocols/yahoo/yahoo.c @ 3fa5a8c

Last change on this file since 3fa5a8c was c495217, checked in by Wilmer van der Gaast <wilmer@…>, at 2010-07-24T13:28:36Z

Inverting allow_reconnect logic on login failures. Automatic reconnects were
getting im.bitlbee.org IP-banned sometimes. This fix keeps it happy for
some time already.

  • Property mode set to 100644
File size: 24.7 KB
RevLine 
[b7d3cc34]1/*
2 * libyahoo2 wrapper to BitlBee
3 *
[9034ba0]4 * Mostly Copyright 2004-2010 Wilmer van der Gaast <wilmer@gaast.net>
[b7d3cc34]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;
[0da65d5]60        struct groupchat *c;
[b7d3cc34]61        int yid;
62        YList *members;
[0da65d5]63        struct im_connection *ic;
[b7d3cc34]64};
65
66static GSList *byahoo_inputs = NULL;
67static int byahoo_chat_id = 0;
68
[cfc8d58]69static char *byahoo_strip( const char *in )
[b7d3cc34]70{
71        int len;
72       
[717e3bf]73        /* This should get rid of the markup noise at the beginning of the string. */
[b7d3cc34]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                {
[cfc8d58]88                        const char *s;
[b7d3cc34]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       
[717e3bf]103        /* This is supposed to get rid of the noise at the end of the line. */
[b7d3cc34]104        len = strlen( in );
[717e3bf]105        while( len > 0 && ( in[len-1] == '>' || in[len-1] == 'm' ) )
[b7d3cc34]106        {
107                int blen = len;
[717e3bf]108                const char *search;
[b7d3cc34]109               
[717e3bf]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 )
[b7d3cc34]117                        len --;
118               
[717e3bf]119                if( len <= 0 && strncmp( in, search, 2 ) != 0 )
[b7d3cc34]120                {
121                        len = blen;
122                        break;
123                }
124        }
125       
126        return( g_strndup( in, len ) );
127}
128
[1febf5c]129static void byahoo_init( account_t *acc )
130{
131        set_add( &acc->set, "mail_notifications", "false", set_eval_bool, acc );
[4049061]132       
133        acc->flags |= ACC_FLAG_AWAY_MESSAGE | ACC_FLAG_STATUS_MESSAGE;
[1febf5c]134}
135
[0a3c243]136static void byahoo_login( account_t *acc )
[b7d3cc34]137{
[84b045d]138        struct im_connection *ic = imcb_new( acc );
[0da65d5]139        struct byahoo_data *yd = ic->proto_data = g_new0( struct byahoo_data, 1 );
[6e6b3d7]140        char *s;
[b7d3cc34]141       
142        yd->logged_in = FALSE;
143        yd->current_status = YAHOO_STATUS_AVAILABLE;
144       
[6e6b3d7]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       
[84b045d]149        imcb_log( ic, "Connecting" );
[0a3c243]150        yd->y2_id = yahoo_init( acc->user, acc->pass );
[b7d3cc34]151        yahoo_login( yd->y2_id, yd->current_status );
152}
153
[0da65d5]154static void byahoo_logout( struct im_connection *ic )
[b7d3cc34]155{
[0da65d5]156        struct byahoo_data *yd = (struct byahoo_data *) ic->proto_data;
[b7d3cc34]157        GSList *l;
158       
[e35d1a1]159        while( ic->groupchats )
[eaaa986]160                imcb_chat_free( ic->groupchats->data );
[b7d3cc34]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       
[dfbb056]172        yahoo_logoff( yd->y2_id );
[b7d3cc34]173       
174        g_free( yd );
175}
176
[0da65d5]177static void byahoo_get_info(struct im_connection *ic, char *who) 
[b7d3cc34]178{
179        /* Just make an URL and let the user fetch the info */
[84b045d]180        imcb_log(ic, "%s\n%s: %s%s", _("User Info"), 
[b7d3cc34]181                        _("For now, fetch yourself"), yahoo_get_profile_url(),
182                        who);
183}
184
[f6c963b]185static int byahoo_buddy_msg( struct im_connection *ic, char *who, char *what, int flags )
[b7d3cc34]186{
[0da65d5]187        struct byahoo_data *yd = ic->proto_data;
[b7d3cc34]188       
[cfc8d58]189        yahoo_send_im( yd->y2_id, NULL, who, what, 1, 0 );
[b7d3cc34]190       
191        return 1;
192}
193
[0da65d5]194static int byahoo_send_typing( struct im_connection *ic, char *who, int typing )
[b7d3cc34]195{
[0da65d5]196        struct byahoo_data *yd = ic->proto_data;
[b7d3cc34]197       
[df1fb67]198        yahoo_send_typing( yd->y2_id, NULL, who, ( typing & OPT_TYPING ) != 0 );
[b7d3cc34]199       
200        return 1;
201}
202
[0da65d5]203static void byahoo_set_away( struct im_connection *ic, char *state, char *msg )
[b7d3cc34]204{
[0da65d5]205        struct byahoo_data *yd = (struct byahoo_data *) ic->proto_data;
[d2cbe0a]206       
[be915f5]207        if( state && msg == NULL )
[b7d3cc34]208        {
[be915f5]209                /* Use these states only if msg doesn't contain additional
210                   info since away messages are only supported with CUSTOM. */
[4049061]211                if( g_strcasecmp( state, "Be Right Back" ) == 0 )
[b7d3cc34]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;
[4049061]231                else
232                        yd->current_status = YAHOO_STATUS_CUSTOM;
[b7d3cc34]233        }
[ec55a7d]234        else if( msg )
[be915f5]235                yd->current_status = YAHOO_STATUS_CUSTOM;
[b7d3cc34]236        else
237                yd->current_status = YAHOO_STATUS_AVAILABLE;
238       
[4049061]239        yahoo_set_away( yd->y2_id, yd->current_status, msg, state ? 2 : 0 );
[b7d3cc34]240}
241
[0da65d5]242static GList *byahoo_away_states( struct im_connection *ic )
[b7d3cc34]243{
[99c8f13]244        static GList *m = NULL;
[b7d3cc34]245
[99c8f13]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        }
[b7d3cc34]259       
260        return m;
261}
262
[0da65d5]263static void byahoo_keepalive( struct im_connection *ic )
[b7d3cc34]264{
[0da65d5]265        struct byahoo_data *yd = ic->proto_data;
[b7d3cc34]266       
267        yahoo_keepalive( yd->y2_id );
268}
269
[0da65d5]270static void byahoo_add_buddy( struct im_connection *ic, char *who, char *group )
[b7d3cc34]271{
[0da65d5]272        struct byahoo_data *yd = (struct byahoo_data *) ic->proto_data;
[ccc595b]273        bee_user_t *bu;
[b7d3cc34]274       
[ccc595b]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 );
[b7d3cc34]299}
300
[0da65d5]301static void byahoo_remove_buddy( struct im_connection *ic, char *who, char *group )
[b7d3cc34]302{
[0da65d5]303        struct byahoo_data *yd = (struct byahoo_data *) ic->proto_data;
[b7d3cc34]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
[f6c963b]317static void byahoo_chat_msg( struct groupchat *c, char *message, int flags )
[b7d3cc34]318{
[0da65d5]319        struct byahoo_data *yd = (struct byahoo_data *) c->ic->proto_data;
[b7d3cc34]320       
321        yahoo_conference_message( yd->y2_id, NULL, c->data, c->title, message, 1 );
322}
323
[c058ff9]324static void byahoo_chat_invite( struct groupchat *c, char *who, char *msg )
[b7d3cc34]325{
[0da65d5]326        struct byahoo_data *yd = (struct byahoo_data *) c->ic->proto_data;
[b7d3cc34]327       
[79eae4a]328        yahoo_conference_invite( yd->y2_id, NULL, c->data, c->title, msg ? msg : "" );
[b7d3cc34]329}
330
[0da65d5]331static void byahoo_chat_leave( struct groupchat *c )
[b7d3cc34]332{
[0da65d5]333        struct byahoo_data *yd = (struct byahoo_data *) c->ic->proto_data;
[b7d3cc34]334       
335        yahoo_conference_logoff( yd->y2_id, NULL, c->data, c->title );
[e35d1a1]336        imcb_chat_free( c );
[b7d3cc34]337}
338
[0da65d5]339static struct groupchat *byahoo_chat_with( struct im_connection *ic, char *who )
[b7d3cc34]340{
[0da65d5]341        struct byahoo_data *yd = (struct byahoo_data *) ic->proto_data;
342        struct groupchat *c;
[b7d3cc34]343        char *roomname;
344        YList *members;
345       
[c2fb3809]346        roomname = g_strdup_printf( "%s-Bee-%d", ic->acc->user, byahoo_chat_id );
[b7d3cc34]347       
[61ae52c]348        c = imcb_chat_new( ic, roomname );
349        imcb_chat_add_buddy( c, ic->acc->user );
[b7d3cc34]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       
[fa29d093]360        return c;
[b7d3cc34]361}
362
[ba16895]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       
[78e2eb7]367        yahoo_confirm_buddy( yd->y2_id, who, 0, "" );
[ba16895]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       
[78e2eb7]374        yahoo_confirm_buddy( yd->y2_id, who, 1, "" );
[ba16895]375}
376
[0da65d5]377void byahoo_initmodule( )
[b7d3cc34]378{
[7b23afd]379        struct prpl *ret = g_new0(struct prpl, 1);
380        ret->name = "yahoo";
[1febf5c]381        ret->init = byahoo_init;
[b7d3cc34]382       
383        ret->login = byahoo_login;
[0da65d5]384        ret->keepalive = byahoo_keepalive;
385        ret->logout = byahoo_logout;
386       
[f6c963b]387        ret->buddy_msg = byahoo_buddy_msg;
[b7d3cc34]388        ret->get_info = byahoo_get_info;
389        ret->away_states = byahoo_away_states;
390        ret->set_away = byahoo_set_away;
391        ret->add_buddy = byahoo_add_buddy;
392        ret->remove_buddy = byahoo_remove_buddy;
[7b23afd]393        ret->send_typing = byahoo_send_typing;
[b7d3cc34]394       
[f6c963b]395        ret->chat_msg = byahoo_chat_msg;
[b7d3cc34]396        ret->chat_invite = byahoo_chat_invite;
397        ret->chat_leave = byahoo_chat_leave;
[0da65d5]398        ret->chat_with = byahoo_chat_with;
[5b52a48]399
400        ret->handle_cmp = g_strcasecmp;
[b7d3cc34]401       
[ba16895]402        ret->auth_allow = byahoo_auth_allow;
403        ret->auth_deny = byahoo_auth_deny;
404       
[7b23afd]405        register_protocol(ret);
[b7d3cc34]406}
407
[0da65d5]408static struct im_connection *byahoo_get_ic_by_id( int id )
[b7d3cc34]409{
410        GSList *l;
[0da65d5]411        struct im_connection *ic;
[b7d3cc34]412        struct byahoo_data *yd;
413       
414        for( l = get_connections(); l; l = l->next )
415        {
[0da65d5]416                ic = l->data;
417                yd = ic->proto_data;
[b7d3cc34]418               
[0da65d5]419                if( strcmp( ic->acc->prpl->name, "yahoo" ) == 0 && yd->y2_id == id )
420                        return( ic );
[b7d3cc34]421        }
422       
423        return( NULL );
424}
425
426
427/* Now it's callback time! */
428
429struct byahoo_connect_callback_data
430{
431        int fd;
432        yahoo_connect_callback callback;
433        gpointer data;
434        int id;
435};
436
[ba9edaa]437void byahoo_connect_callback( gpointer data, gint source, b_input_condition cond )
[b7d3cc34]438{
439        struct byahoo_connect_callback_data *d = data;
440       
[0da65d5]441        if( !byahoo_get_ic_by_id( d->id ) )
[b7d3cc34]442        {
443                g_free( d );
444                return;
445        }
446       
[9034ba0]447        d->callback( NULL + d->fd, 0, d->data );
[b7d3cc34]448        g_free( d );
449}
450
451struct byahoo_read_ready_data
452{
453        int id;
454        int fd;
455        int tag;
456        gpointer data;
457};
458
[ba9edaa]459gboolean byahoo_read_ready_callback( gpointer data, gint source, b_input_condition cond )
[b7d3cc34]460{
461        struct byahoo_read_ready_data *d = data;
462       
[0da65d5]463        if( !byahoo_get_ic_by_id( d->id ) )
[b7d3cc34]464                /* WTF doesn't libyahoo clean this up? */
[ba9edaa]465                return FALSE;
[b7d3cc34]466       
[9034ba0]467        yahoo_read_ready( d->id, NULL + d->fd, d->data );
[7a685f1]468       
469        return TRUE;
[b7d3cc34]470}
471
472struct byahoo_write_ready_data
473{
474        int id;
475        int fd;
476        int tag;
477        gpointer data;
478};
479
[ba9edaa]480gboolean byahoo_write_ready_callback( gpointer data, gint source, b_input_condition cond )
[b7d3cc34]481{
482        struct byahoo_write_ready_data *d = data;
483       
[9034ba0]484        return yahoo_write_ready( d->id, NULL + d->fd, d->data );
[b7d3cc34]485}
486
[cfc8d58]487void ext_yahoo_login_response( int id, int succ, const char *url )
[b7d3cc34]488{
[0da65d5]489        struct im_connection *ic = byahoo_get_ic_by_id( id );
[b7d3cc34]490        struct byahoo_data *yd = NULL;
491       
[0da65d5]492        if( ic == NULL )
[b7d3cc34]493        {
494                /* libyahoo2 seems to call this one twice when something
495                   went wrong sometimes. Don't know why. Because we clean
496                   up the connection on the first failure, the second
497                   should be ignored. */
498               
499                return;
500        }
501       
[0da65d5]502        yd = (struct byahoo_data *) ic->proto_data;
[b7d3cc34]503       
504        if( succ == YAHOO_LOGIN_OK )
505        {
[84b045d]506                imcb_connected( ic );
[b7d3cc34]507               
508                yd->logged_in = TRUE;
509        }
510        else
511        {
512                char *errstr;
[c495217]513                int allow_reconnect = FALSE;
[b7d3cc34]514               
515                yd->logged_in = FALSE;
516               
517                if( succ == YAHOO_LOGIN_UNAME )
518                        errstr = "Incorrect Yahoo! username";
519                else if( succ == YAHOO_LOGIN_PASSWD )
520                        errstr = "Incorrect Yahoo! password";
521                else if( succ == YAHOO_LOGIN_LOCK )
522                        errstr = "Yahoo! account locked";
[c495217]523                else if( succ == 1236 )
524                        errstr = "Yahoo! account locked or machine temporarily banned";
[b7d3cc34]525                else if( succ == YAHOO_LOGIN_DUPL )
526                        errstr = "Logged in on a different machine or device";
527                else if( succ == YAHOO_LOGIN_SOCK )
[c495217]528                {
[b7d3cc34]529                        errstr = "Socket problem";
[c495217]530                        allow_reconnect = TRUE;
531                }
[b7d3cc34]532                else
533                        errstr = "Unknown error";
534               
535                if( url && *url )
[84b045d]536                        imcb_error( ic, "Error %d (%s). See %s for more information.", succ, errstr, url );
[b7d3cc34]537                else
[84b045d]538                        imcb_error( ic, "Error %d (%s)", succ, errstr );
[b7d3cc34]539               
[c2fb3809]540                imc_logout( ic, allow_reconnect );
[b7d3cc34]541        }
542}
543
544void ext_yahoo_got_buddies( int id, YList *buds )
545{
[0da65d5]546        struct im_connection *ic = byahoo_get_ic_by_id( id );
547        struct byahoo_data *yd = ic->proto_data;
[b7d3cc34]548        YList *bl = buds;
549       
550        while( bl )
551        {
552                struct yahoo_buddy *b = bl->data;
553                struct byahoo_buddygroups *bg;
554               
555                if( strcmp( b->group, BYAHOO_DEFAULT_GROUP ) != 0 )
556                {
557                        bg = g_new0( struct byahoo_buddygroups, 1 );
558                       
559                        bg->buddy = g_strdup( b->id );
560                        bg->group = g_strdup( b->group );
561                        yd->buddygroups = g_slist_append( yd->buddygroups, bg );
562                }
563               
[f0cb961]564                imcb_add_buddy( ic, b->id, b->group );
565                imcb_rename_buddy( ic, b->id, b->real_name );
566               
[b7d3cc34]567                bl = bl->next;
568        }
569}
570
571void ext_yahoo_got_ignore( int id, YList *igns )
572{
573}
574
575void ext_yahoo_got_identities( int id, YList *ids )
576{
577}
578
579void ext_yahoo_got_cookies( int id )
580{
581}
582
[cfc8d58]583void ext_yahoo_status_changed( int id, const char *who, int stat, const char *msg, int away, int idle, int mobile )
[b7d3cc34]584{
[0da65d5]585        struct im_connection *ic = byahoo_get_ic_by_id( id );
[6bbb939]586        char *state_string = NULL;
587        int flags = OPT_LOGGED_IN;
588       
589        if( away )
590                flags |= OPT_AWAY;
591       
592        switch (stat)
593        {
594        case YAHOO_STATUS_BRB:
595                state_string = "Be Right Back";
596                break;
597        case YAHOO_STATUS_BUSY:
598                state_string = "Busy";
599                break;
600        case YAHOO_STATUS_NOTATHOME:
601                state_string = "Not At Home";
602                break;
603        case YAHOO_STATUS_NOTATDESK:
604                state_string = "Not At Desk";
605                break;
606        case YAHOO_STATUS_NOTINOFFICE:
607                state_string = "Not In Office";
608                break;
609        case YAHOO_STATUS_ONPHONE:
610                state_string = "On Phone";
611                break;
612        case YAHOO_STATUS_ONVACATION:
613                state_string = "On Vacation";
614                break;
615        case YAHOO_STATUS_OUTTOLUNCH:
616                state_string = "Out To Lunch";
617                break;
618        case YAHOO_STATUS_STEPPEDOUT:
619                state_string = "Stepped Out";
620                break;
621        case YAHOO_STATUS_INVISIBLE:
622                state_string = "Invisible";
623                break;
624        case YAHOO_STATUS_CUSTOM:
625                state_string = "Away";
626                break;
627        case YAHOO_STATUS_IDLE:
628                state_string = "Idle";
629                break;
630        case YAHOO_STATUS_OFFLINE:
631                state_string = "Offline";
632                flags = 0;
633                break;
634        }
635       
636        imcb_buddy_status( ic, who, flags, state_string, msg );
[b7d3cc34]637       
[6bbb939]638        if( stat == YAHOO_STATUS_IDLE )
[56699f0]639                imcb_buddy_times( ic, who, 0, idle );
[b7d3cc34]640}
641
[9034ba0]642void ext_yahoo_got_buzz( int id, const char *me, const char *who, long tm )
643{
644}
645
[cfc8d58]646void ext_yahoo_got_im( int id, const char *me, const char *who, const char *msg, long tm, int stat, int utf8 )
[b7d3cc34]647{
[0da65d5]648        struct im_connection *ic = byahoo_get_ic_by_id( id );
[ac4adf9]649        char *m;
[b7d3cc34]650       
[ac4adf9]651        if( msg )
652        {
653                m = byahoo_strip( msg );
654                imcb_buddy_msg( ic, (char*) who, (char*) m, 0, 0 );
655                g_free( m );
656        }
[b7d3cc34]657}
658
[9034ba0]659void ext_yahoo_got_file( int id, const char *ignored, const char *who, const char *msg,
660                         const char *fname, unsigned long fesize, char *trid )
[b7d3cc34]661{
[0da65d5]662        struct im_connection *ic = byahoo_get_ic_by_id( id );
[b7d3cc34]663       
[84b045d]664        imcb_log( ic, "Got a file transfer (file = %s) from %s. Ignoring for now due to lack of support.", fname, who );
[b7d3cc34]665}
666
[9034ba0]667void ext_yahoo_got_ft_data( int id, const unsigned char *in, int len, void *data )
668{
669}
670
671void ext_yahoo_file_transfer_done( int id, int result, void *data )
672{
673}
674
[cfc8d58]675void ext_yahoo_typing_notify( int id, const char *ignored, const char *who, int stat )
[b7d3cc34]676{
[0da65d5]677        struct im_connection *ic = byahoo_get_ic_by_id( id );
[9624fdf]678       
679        if( stat == 1 )
680                imcb_buddy_typing( ic, (char*) who, OPT_TYPING );
681        else
682                imcb_buddy_typing( ic, (char*) who, 0 );
[b7d3cc34]683}
684
[9034ba0]685void ext_yahoo_system_message( int id, const char *me, const char *who, const char *msg )
[b7d3cc34]686{
[0da65d5]687        struct im_connection *ic = byahoo_get_ic_by_id( id );
[b7d3cc34]688       
[84b045d]689        imcb_log( ic, "Yahoo! system message: %s", msg );
[b7d3cc34]690}
691
[cfc8d58]692void ext_yahoo_webcam_invite( int id, const char *ignored, const char *from )
[b7d3cc34]693{
[0da65d5]694        struct im_connection *ic = byahoo_get_ic_by_id( id );
[b7d3cc34]695       
[84b045d]696        imcb_log( ic, "Got a webcam invitation from %s. IRC+webcams is a no-no though...", from );
[b7d3cc34]697}
698
[cfc8d58]699void ext_yahoo_error( int id, const char *err, int fatal, int num )
[b7d3cc34]700{
[0da65d5]701        struct im_connection *ic = byahoo_get_ic_by_id( id );
[b7d3cc34]702       
[84b045d]703        imcb_error( ic, "%s", err );
[b7d3cc34]704}
705
706/* TODO: Clear up the mess of inp and d structures */
[9034ba0]707int ext_yahoo_add_handler( int id, void *fd_, yahoo_input_condition cond, void *data )
[b7d3cc34]708{
709        struct byahoo_input_data *inp = g_new0( struct byahoo_input_data, 1 );
[9034ba0]710        int fd = (int) fd_;
[b7d3cc34]711       
712        if( cond == YAHOO_INPUT_READ )
713        {
714                struct byahoo_read_ready_data *d = g_new0( struct byahoo_read_ready_data, 1 );
715               
716                d->id = id;
717                d->fd = fd;
718                d->data = data;
719               
720                inp->d = d;
[e046390]721                d->tag = inp->h = b_input_add( fd, B_EV_IO_READ, (b_event_handler) byahoo_read_ready_callback, (gpointer) d );
[b7d3cc34]722        }
723        else if( cond == YAHOO_INPUT_WRITE )
724        {
725                struct byahoo_write_ready_data *d = g_new0( struct byahoo_write_ready_data, 1 );
726               
727                d->id = id;
728                d->fd = fd;
729                d->data = data;
730               
731                inp->d = d;
[e046390]732                d->tag = inp->h = b_input_add( fd, B_EV_IO_WRITE, (b_event_handler) byahoo_write_ready_callback, (gpointer) d );
[b7d3cc34]733        }
734        else
735        {
736                g_free( inp );
[9034ba0]737                return -1;
[b7d3cc34]738                /* Panic... */
739        }
740       
741        byahoo_inputs = g_slist_append( byahoo_inputs, inp );
[9034ba0]742        return inp->h;
[b7d3cc34]743}
744
745void ext_yahoo_remove_handler( int id, int tag )
746{
747        struct byahoo_input_data *inp;
748        GSList *l = byahoo_inputs;
749       
750        while( l )
751        {
752                inp = l->data;
753                if( inp->h == tag )
754                {
755                        g_free( inp->d );
756                        g_free( inp );
757                        byahoo_inputs = g_slist_remove( byahoo_inputs, inp );
758                        break;
759                }
760                l = l->next;
761        }
762       
[ba9edaa]763        b_event_remove( tag );
[b7d3cc34]764}
765
[9034ba0]766int ext_yahoo_connect_async( int id, const char *host, int port, yahoo_connect_callback callback, void *data, int use_ssl )
[b7d3cc34]767{
768        struct byahoo_connect_callback_data *d;
769        int fd;
770       
771        d = g_new0( struct byahoo_connect_callback_data, 1 );
[ba9edaa]772        if( ( fd = proxy_connect( host, port, (b_event_handler) byahoo_connect_callback, (gpointer) d ) ) < 0 )
[b7d3cc34]773        {
774                g_free( d );
775                return( fd );
776        }
777        d->fd = fd;
778        d->callback = callback;
779        d->data = data;
780        d->id = id;
781       
[9034ba0]782        return fd;
[b7d3cc34]783}
784
[9034ba0]785char *ext_yahoo_get_ip_addr( const char *domain )
[b7d3cc34]786{
[9034ba0]787        return NULL;
788}
[b7d3cc34]789
[9034ba0]790int ext_yahoo_write( void *fd, char *buf, int len )
791{
792        return write( (int) fd, buf, len );
793}
[b7d3cc34]794
[9034ba0]795int ext_yahoo_read( void *fd, char *buf, int len )
796{
797        return read( (int) fd, buf, len );
798}
[b7d3cc34]799
[9034ba0]800void ext_yahoo_close( void *fd )
801{
802        close( (int) fd );
803}
804
805void ext_yahoo_got_buddy_change_group( int id, const char *me, const char *who,
806                                       const char *old_group, const char *new_group )
807{
[ccc595b]808        struct im_connection *ic = byahoo_get_ic_by_id( id );
809       
810        imcb_add_buddy( ic, who, new_group );
811}
[b7d3cc34]812
[9034ba0]813/* Because we don't want asynchronous connects in BitlBee, and because
814   libyahoo doesn't seem to use this one anyway, this one is now defunct. */
815int ext_yahoo_connect(const char *host, int port)
816{
[b7d3cc34]817        return -1;
818}
819
[9143aeb]820static void byahoo_accept_conf( void *data )
[b7d3cc34]821{
[9143aeb]822        struct byahoo_conf_invitation *inv = data;
[2bebe15]823        struct groupchat *b;
[eaaa986]824        GSList *l;
[2bebe15]825       
[eaaa986]826        for( l = inv->ic->groupchats; l; l = l->next )
827        {
828                b = l->data;
[2bebe15]829                if( b == inv->c )
830                        break;
[eaaa986]831        }
[2bebe15]832       
833        if( b != NULL )
834        {
835                yahoo_conference_logon( inv->yid, NULL, inv->members, inv->name );
836                imcb_chat_add_buddy( inv->c, inv->ic->acc->user );
837        }
838        else
839        {
840                imcb_log( inv->ic, "Duplicate/corrupted invitation to `%s'.", inv->name );
841        }
[9143aeb]842       
[b7d3cc34]843        g_free( inv->name );
844        g_free( inv );
845}
846
[9143aeb]847static void byahoo_reject_conf( void *data )
[b7d3cc34]848{
[9143aeb]849        struct byahoo_conf_invitation *inv = data;
850       
[b7d3cc34]851        yahoo_conference_decline( inv->yid, NULL, inv->members, inv->name, "User rejected groupchat" );
[e35d1a1]852        imcb_chat_free( inv->c );
[b7d3cc34]853        g_free( inv->name );
854        g_free( inv );
855}
856
[cfc8d58]857void ext_yahoo_got_conf_invite( int id, const char *ignored,
858                                const char *who, const char *room, const char *msg, YList *members )
[b7d3cc34]859{
[0da65d5]860        struct im_connection *ic = byahoo_get_ic_by_id( id );
[b7d3cc34]861        struct byahoo_conf_invitation *inv;
862        char txt[1024];
863        YList *m;
864       
[aa7ce1b]865        if( g_strcasecmp( who, ic->acc->user ) == 0 )
866                /* WTF, Yahoo! seems to echo these now? */
867                return;
868       
[b7d3cc34]869        inv = g_malloc( sizeof( struct byahoo_conf_invitation ) );
870        memset( inv, 0, sizeof( struct byahoo_conf_invitation ) );
871        inv->name = g_strdup( room );
[61ae52c]872        inv->c = imcb_chat_new( ic, (char*) room );
[b7d3cc34]873        inv->c->data = members;
874        inv->yid = id;
875        inv->members = members;
[0da65d5]876        inv->ic = ic;
[b7d3cc34]877       
878        for( m = members; m; m = m->next )
[c2fb3809]879                if( g_strcasecmp( m->data, ic->acc->user ) != 0 )
[61ae52c]880                        imcb_chat_add_buddy( inv->c, m->data );
[b7d3cc34]881       
882        g_snprintf( txt, 1024, "Got an invitation to chatroom %s from %s: %s", room, who, msg );
883       
[84b045d]884        imcb_ask( ic, txt, inv, byahoo_accept_conf, byahoo_reject_conf );
[b7d3cc34]885}
886
[cfc8d58]887void ext_yahoo_conf_userdecline( int id, const char *ignored, const char *who, const char *room, const char *msg )
[b7d3cc34]888{
[0da65d5]889        struct im_connection *ic = byahoo_get_ic_by_id( id );
[b7d3cc34]890       
[84b045d]891        imcb_log( ic, "Invite to chatroom %s rejected by %s: %s", room, who, msg );
[b7d3cc34]892}
893
[cfc8d58]894void ext_yahoo_conf_userjoin( int id, const char *ignored, const char *who, const char *room )
[b7d3cc34]895{
[0da65d5]896        struct im_connection *ic = byahoo_get_ic_by_id( id );
[eaaa986]897        struct groupchat *c = bee_chat_by_title( ic->bee, ic, room );
[b7d3cc34]898       
899        if( c )
[61ae52c]900                imcb_chat_add_buddy( c, (char*) who );
[b7d3cc34]901}
902
[cfc8d58]903void ext_yahoo_conf_userleave( int id, const char *ignored, const char *who, const char *room )
904
[b7d3cc34]905{
[0da65d5]906        struct im_connection *ic = byahoo_get_ic_by_id( id );
[eaaa986]907        struct groupchat *c = bee_chat_by_title( ic->bee, ic, room );
[b7d3cc34]908       
909        if( c )
[61ae52c]910                imcb_chat_remove_buddy( c, (char*) who, "" );
[b7d3cc34]911}
912
[cfc8d58]913void ext_yahoo_conf_message( int id, const char *ignored, const char *who, const char *room, const char *msg, int utf8 )
[b7d3cc34]914{
[0da65d5]915        struct im_connection *ic = byahoo_get_ic_by_id( id );
[b7d3cc34]916        char *m = byahoo_strip( msg );
[eaaa986]917        struct groupchat *c = bee_chat_by_title( ic->bee, ic, room );
[b7d3cc34]918       
[fa29d093]919        if( c )
[61ae52c]920                imcb_chat_msg( c, (char*) who, (char*) m, 0, 0 );
[b7d3cc34]921        g_free( m );
922}
923
[cfc8d58]924void ext_yahoo_chat_cat_xml( int id, const char *xml )
[b7d3cc34]925{
926}
927
[9034ba0]928void ext_yahoo_chat_join( int id, const char *who, const char *room, const char *topic, YList *members, void *fd )
[b7d3cc34]929{
930}
931
[cfc8d58]932void ext_yahoo_chat_userjoin( int id, const char *me, const char *room, struct yahoo_chat_member *who )
[b7d3cc34]933{
[cfc8d58]934        free(who->id);
935        free(who->alias);
936        free(who->location);
937        free(who);
[b7d3cc34]938}
939
[cfc8d58]940void ext_yahoo_chat_userleave( int id, const char *me, const char *room, const char *who )
[b7d3cc34]941{
942}
943
[cfc8d58]944void ext_yahoo_chat_message( int id, const char *me, const char *who, const char *room, const char *msg, int msgtype, int utf8 )
[b7d3cc34]945{
946}
947
[cfc8d58]948void ext_yahoo_chat_yahoologout( int id, const char *me )
[b7d3cc34]949{
950}
951
[cfc8d58]952void ext_yahoo_chat_yahooerror( int id, const char *me )
[b7d3cc34]953{
954}
955
[cfc8d58]956void ext_yahoo_contact_added( int id, const char *myid, const char *who, const char *msg )
[b7d3cc34]957{
[ba16895]958        struct im_connection *ic = byahoo_get_ic_by_id( id );
959       
[78e2eb7]960        imcb_ask_auth( ic, who, msg );
[b7d3cc34]961}
962
[cfc8d58]963void ext_yahoo_rejected( int id, const char *who, const char *msg )
[b7d3cc34]964{
965}
966
[9034ba0]967void ext_yahoo_game_notify( int id, const char *me, const char *who, int stat, const char *msg )
[b7d3cc34]968{
969}
970
[cfc8d58]971void ext_yahoo_mail_notify( int id, const char *from, const char *subj, int cnt )
[b7d3cc34]972{
[0da65d5]973        struct im_connection *ic = byahoo_get_ic_by_id( id );
[b7d3cc34]974       
[1febf5c]975        if( !set_getbool( &ic->acc->set, "mail_notifications" ) )
976                ; /* The user doesn't care. */
977        else if( from && subj )
[84b045d]978                imcb_log( ic, "Received e-mail message from %s with subject `%s'", from, subj );
[b7d3cc34]979        else if( cnt > 0 )
[84b045d]980                imcb_log( ic, "Received %d new e-mails", cnt );
[b7d3cc34]981}
982
[cfc8d58]983void ext_yahoo_webcam_invite_reply( int id, const char *me, const char *from, int accept )
[b7d3cc34]984{
985}
986
[cfc8d58]987void ext_yahoo_webcam_closed( int id, const char *who, int reason )
[b7d3cc34]988{
989}
990
991void ext_yahoo_got_search_result( int id, int found, int start, int total, YList *contacts )
992{
993}
994
[cfc8d58]995void ext_yahoo_webcam_viewer( int id, const char *who, int connect )
[b7d3cc34]996{
997}
998
999void ext_yahoo_webcam_data_request( int id, int send )
1000{
1001}
1002
[cfc8d58]1003int ext_yahoo_log( const char *fmt, ... )
[b7d3cc34]1004{
1005        return( 0 );
1006}
1007
1008void 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 )
1009{
1010}
[cfc8d58]1011
[ccc595b]1012void ext_yahoo_got_ping( int id, const char *msg )
[cfc8d58]1013{
1014}
1015
1016void ext_yahoo_got_buddyicon (int id, const char *me, const char *who, const char *url, int checksum) {}
1017void ext_yahoo_got_buddyicon_checksum (int id, const char *me,const char *who, int checksum) {}
1018
1019void ext_yahoo_got_buddyicon_request(int id, const char *me, const char *who){}
1020void ext_yahoo_buddyicon_uploaded(int id, const char *url){}
Note: See TracBrowser for help on using the repository browser.