source: protocols/yahoo/yahoo.c @ 47fae0f

Last change on this file since 47fae0f was bd5eee3, checked in by Wilmer van der Gaast <wilmer@…>, at 2010-05-09T09:48:56Z

Merging mainline, mostly for chatroom fixes I implemented there.

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