source: protocols/yahoo/yahoo.c @ 99c8f13

Last change on this file since 99c8f13 was 99c8f13, checked in by Wilmer van der Gaast <wilmer@…>, at 2009-10-17T14:48:21Z

Valgrind pointed me at some memory leaks in the Yahoo! codek, including one
that existed for a while already. Fixed.

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