source: protocols/yahoo/yahoo.c @ dfbb056

Last change on this file since dfbb056 was dfbb056, checked in by Wilmer van der Gaast <wilmer@…>, at 2008-06-24T09:01:29Z

Never use yahoo_close() directly, always use yahoo_logoff().

  • Property mode set to 100644
File size: 23.4 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;
[d2cbe0a]199       
[0da65d5]200        ic->away = NULL;
[d2cbe0a]201       
[a36b030]202        if( state && msg && g_strcasecmp( state, msg ) != 0 )
[b7d3cc34]203        {
204                yd->current_status = YAHOO_STATUS_CUSTOM;
[0da65d5]205                ic->away = "";
[b7d3cc34]206        }
[a36b030]207        else if( state )
[b7d3cc34]208        {
[a36b030]209                /* Set msg to NULL since (if it isn't NULL already) it's equal
210                   to state. msg must be empty if we want to use an existing
211                   away state. */
212                msg = NULL;
213               
[0da65d5]214                ic->away = "";
[d2cbe0a]215                if( g_strcasecmp( state, "Available" ) == 0 )
[b7d3cc34]216                {
217                        yd->current_status = YAHOO_STATUS_AVAILABLE;
[0da65d5]218                        ic->away = NULL;
[b7d3cc34]219                }
220                else if( g_strcasecmp( state, "Be Right Back" ) == 0 )
221                        yd->current_status = YAHOO_STATUS_BRB;
222                else if( g_strcasecmp( state, "Busy" ) == 0 )
223                        yd->current_status = YAHOO_STATUS_BUSY;
224                else if( g_strcasecmp( state, "Not At Home" ) == 0 )
225                        yd->current_status = YAHOO_STATUS_NOTATHOME;
226                else if( g_strcasecmp( state, "Not At Desk" ) == 0 )
227                        yd->current_status = YAHOO_STATUS_NOTATDESK;
228                else if( g_strcasecmp( state, "Not In Office" ) == 0 )
229                        yd->current_status = YAHOO_STATUS_NOTINOFFICE;
230                else if( g_strcasecmp( state, "On Phone" ) == 0 )
231                        yd->current_status = YAHOO_STATUS_ONPHONE;
232                else if( g_strcasecmp( state, "On Vacation" ) == 0 )
233                        yd->current_status = YAHOO_STATUS_ONVACATION;
234                else if( g_strcasecmp( state, "Out To Lunch" ) == 0 )
235                        yd->current_status = YAHOO_STATUS_OUTTOLUNCH;
236                else if( g_strcasecmp( state, "Stepped Out" ) == 0 )
237                        yd->current_status = YAHOO_STATUS_STEPPEDOUT;
238                else if( g_strcasecmp( state, "Invisible" ) == 0 )
239                        yd->current_status = YAHOO_STATUS_INVISIBLE;
240                else if( g_strcasecmp( state, GAIM_AWAY_CUSTOM ) == 0 )
241                {
[192b80a]242                        yd->current_status = YAHOO_STATUS_AVAILABLE;
[b7d3cc34]243                       
[0da65d5]244                        ic->away = NULL;
[b7d3cc34]245                }
246        }
247        else
248                yd->current_status = YAHOO_STATUS_AVAILABLE;
249       
[cfc8d58]250        yahoo_set_away( yd->y2_id, yd->current_status, msg, ic->away != NULL ? 2 : 0 );
[b7d3cc34]251}
252
[0da65d5]253static GList *byahoo_away_states( struct im_connection *ic )
[b7d3cc34]254{
255        GList *m = NULL;
256
257        m = g_list_append( m, "Available" );
258        m = g_list_append( m, "Be Right Back" );
259        m = g_list_append( m, "Busy" );
260        m = g_list_append( m, "Not At Home" );
261        m = g_list_append( m, "Not At Desk" );
262        m = g_list_append( m, "Not In Office" );
263        m = g_list_append( m, "On Phone" );
264        m = g_list_append( m, "On Vacation" );
265        m = g_list_append( m, "Out To Lunch" );
266        m = g_list_append( m, "Stepped Out" );
267        m = g_list_append( m, "Invisible" );
268        m = g_list_append( m, GAIM_AWAY_CUSTOM );
269       
270        return m;
271}
272
[0da65d5]273static void byahoo_keepalive( struct im_connection *ic )
[b7d3cc34]274{
[0da65d5]275        struct byahoo_data *yd = ic->proto_data;
[b7d3cc34]276       
277        yahoo_keepalive( yd->y2_id );
278}
279
[0da65d5]280static void byahoo_add_buddy( struct im_connection *ic, char *who, char *group )
[b7d3cc34]281{
[0da65d5]282        struct byahoo_data *yd = (struct byahoo_data *) ic->proto_data;
[b7d3cc34]283       
[cfc8d58]284        yahoo_add_buddy( yd->y2_id, who, group ? group : BYAHOO_DEFAULT_GROUP, NULL );
[b7d3cc34]285}
286
[0da65d5]287static void byahoo_remove_buddy( struct im_connection *ic, char *who, char *group )
[b7d3cc34]288{
[0da65d5]289        struct byahoo_data *yd = (struct byahoo_data *) ic->proto_data;
[b7d3cc34]290        GSList *bgl;
291       
292        yahoo_remove_buddy( yd->y2_id, who, BYAHOO_DEFAULT_GROUP );
293       
294        for( bgl = yd->buddygroups; bgl; bgl = bgl->next )
295        {
296                struct byahoo_buddygroups *bg = bgl->data;
297               
298                if( g_strcasecmp( bg->buddy, who ) == 0 )
299                        yahoo_remove_buddy( yd->y2_id, who, bg->group );
300        }
301}
302
[f6c963b]303static void byahoo_chat_msg( struct groupchat *c, char *message, int flags )
[b7d3cc34]304{
[0da65d5]305        struct byahoo_data *yd = (struct byahoo_data *) c->ic->proto_data;
[b7d3cc34]306       
307        yahoo_conference_message( yd->y2_id, NULL, c->data, c->title, message, 1 );
308}
309
[c058ff9]310static void byahoo_chat_invite( struct groupchat *c, char *who, char *msg )
[b7d3cc34]311{
[0da65d5]312        struct byahoo_data *yd = (struct byahoo_data *) c->ic->proto_data;
[b7d3cc34]313       
[79eae4a]314        yahoo_conference_invite( yd->y2_id, NULL, c->data, c->title, msg ? msg : "" );
[b7d3cc34]315}
316
[0da65d5]317static void byahoo_chat_leave( struct groupchat *c )
[b7d3cc34]318{
[0da65d5]319        struct byahoo_data *yd = (struct byahoo_data *) c->ic->proto_data;
[b7d3cc34]320       
321        yahoo_conference_logoff( yd->y2_id, NULL, c->data, c->title );
[e35d1a1]322        imcb_chat_free( c );
[b7d3cc34]323}
324
[0da65d5]325static struct groupchat *byahoo_chat_with( struct im_connection *ic, char *who )
[b7d3cc34]326{
[0da65d5]327        struct byahoo_data *yd = (struct byahoo_data *) ic->proto_data;
328        struct groupchat *c;
[b7d3cc34]329        char *roomname;
330        YList *members;
331       
[c2fb3809]332        roomname = g_strdup_printf( "%s-Bee-%d", ic->acc->user, byahoo_chat_id );
[b7d3cc34]333       
[61ae52c]334        c = imcb_chat_new( ic, roomname );
335        imcb_chat_add_buddy( c, ic->acc->user );
[b7d3cc34]336       
337        /* FIXME: Free this thing when the chat's destroyed. We can't *always*
338                  do this because it's not always created here. */
339        c->data = members = g_new0( YList, 1 );
340        members->data = g_strdup( who );
341       
342        yahoo_conference_invite( yd->y2_id, NULL, members, roomname, "Please join my groupchat..." );
343       
344        g_free( roomname );
345       
[fa29d093]346        return c;
[b7d3cc34]347}
348
[0da65d5]349void byahoo_initmodule( )
[b7d3cc34]350{
[7b23afd]351        struct prpl *ret = g_new0(struct prpl, 1);
352        ret->name = "yahoo";
[1febf5c]353        ret->init = byahoo_init;
[b7d3cc34]354       
355        ret->login = byahoo_login;
[0da65d5]356        ret->keepalive = byahoo_keepalive;
357        ret->logout = byahoo_logout;
358       
[f6c963b]359        ret->buddy_msg = byahoo_buddy_msg;
[b7d3cc34]360        ret->get_info = byahoo_get_info;
361        ret->away_states = byahoo_away_states;
362        ret->set_away = byahoo_set_away;
363        ret->add_buddy = byahoo_add_buddy;
364        ret->remove_buddy = byahoo_remove_buddy;
[7b23afd]365        ret->send_typing = byahoo_send_typing;
[b7d3cc34]366       
[f6c963b]367        ret->chat_msg = byahoo_chat_msg;
[b7d3cc34]368        ret->chat_invite = byahoo_chat_invite;
369        ret->chat_leave = byahoo_chat_leave;
[0da65d5]370        ret->chat_with = byahoo_chat_with;
[5b52a48]371
372        ret->handle_cmp = g_strcasecmp;
[b7d3cc34]373       
[7b23afd]374        register_protocol(ret);
[b7d3cc34]375}
376
[0da65d5]377static struct im_connection *byahoo_get_ic_by_id( int id )
[b7d3cc34]378{
379        GSList *l;
[0da65d5]380        struct im_connection *ic;
[b7d3cc34]381        struct byahoo_data *yd;
382       
383        for( l = get_connections(); l; l = l->next )
384        {
[0da65d5]385                ic = l->data;
386                yd = ic->proto_data;
[b7d3cc34]387               
[0da65d5]388                if( strcmp( ic->acc->prpl->name, "yahoo" ) == 0 && yd->y2_id == id )
389                        return( ic );
[b7d3cc34]390        }
391       
392        return( NULL );
393}
394
395
396/* Now it's callback time! */
397
398struct byahoo_connect_callback_data
399{
400        int fd;
401        yahoo_connect_callback callback;
402        gpointer data;
403        int id;
404};
405
[ba9edaa]406void byahoo_connect_callback( gpointer data, gint source, b_input_condition cond )
[b7d3cc34]407{
408        struct byahoo_connect_callback_data *d = data;
409       
[0da65d5]410        if( !byahoo_get_ic_by_id( d->id ) )
[b7d3cc34]411        {
412                g_free( d );
413                return;
414        }
415       
416        d->callback( d->fd, 0, d->data );
417        g_free( d );
418}
419
420struct byahoo_read_ready_data
421{
422        int id;
423        int fd;
424        int tag;
425        gpointer data;
426};
427
[ba9edaa]428gboolean byahoo_read_ready_callback( gpointer data, gint source, b_input_condition cond )
[b7d3cc34]429{
430        struct byahoo_read_ready_data *d = data;
431       
[0da65d5]432        if( !byahoo_get_ic_by_id( d->id ) )
[b7d3cc34]433                /* WTF doesn't libyahoo clean this up? */
[ba9edaa]434                return FALSE;
[b7d3cc34]435       
436        yahoo_read_ready( d->id, d->fd, d->data );
[7a685f1]437       
438        return TRUE;
[b7d3cc34]439}
440
441struct byahoo_write_ready_data
442{
443        int id;
444        int fd;
445        int tag;
446        gpointer data;
447};
448
[ba9edaa]449gboolean byahoo_write_ready_callback( gpointer data, gint source, b_input_condition cond )
[b7d3cc34]450{
451        struct byahoo_write_ready_data *d = data;
452       
453        yahoo_write_ready( d->id, d->fd, d->data );
[7a685f1]454       
455        return FALSE;
[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 );
[aef4828]667       
[b7d3cc34]668        if( fatal )
[c2fb3809]669                imc_logout( ic, TRUE );
[b7d3cc34]670}
671
672/* TODO: Clear up the mess of inp and d structures */
673int ext_yahoo_add_handler( int id, int fd, yahoo_input_condition cond, void *data )
674{
675        struct byahoo_input_data *inp = g_new0( struct byahoo_input_data, 1 );
676       
677        if( cond == YAHOO_INPUT_READ )
678        {
679                struct byahoo_read_ready_data *d = g_new0( struct byahoo_read_ready_data, 1 );
680               
681                d->id = id;
682                d->fd = fd;
683                d->data = data;
684               
685                inp->d = d;
[ba9edaa]686                d->tag = inp->h = b_input_add( fd, GAIM_INPUT_READ, (b_event_handler) byahoo_read_ready_callback, (gpointer) d );
[b7d3cc34]687        }
688        else if( cond == YAHOO_INPUT_WRITE )
689        {
690                struct byahoo_write_ready_data *d = g_new0( struct byahoo_write_ready_data, 1 );
691               
692                d->id = id;
693                d->fd = fd;
694                d->data = data;
695               
696                inp->d = d;
[ba9edaa]697                d->tag = inp->h = b_input_add( fd, GAIM_INPUT_WRITE, (b_event_handler) byahoo_write_ready_callback, (gpointer) d );
[b7d3cc34]698        }
699        else
700        {
701                g_free( inp );
702                return( -1 );
703                /* Panic... */
704        }
705       
706        byahoo_inputs = g_slist_append( byahoo_inputs, inp );
707        return( inp->h );
708}
709
710void ext_yahoo_remove_handler( int id, int tag )
711{
712        struct byahoo_input_data *inp;
713        GSList *l = byahoo_inputs;
714       
715        while( l )
716        {
717                inp = l->data;
718                if( inp->h == tag )
719                {
720                        g_free( inp->d );
721                        g_free( inp );
722                        byahoo_inputs = g_slist_remove( byahoo_inputs, inp );
723                        break;
724                }
725                l = l->next;
726        }
727       
[ba9edaa]728        b_event_remove( tag );
[b7d3cc34]729}
730
[cfc8d58]731int ext_yahoo_connect_async( int id, const char *host, int port, yahoo_connect_callback callback, void *data )
[b7d3cc34]732{
733        struct byahoo_connect_callback_data *d;
734        int fd;
735       
736        d = g_new0( struct byahoo_connect_callback_data, 1 );
[ba9edaa]737        if( ( fd = proxy_connect( host, port, (b_event_handler) byahoo_connect_callback, (gpointer) d ) ) < 0 )
[b7d3cc34]738        {
739                g_free( d );
740                return( fd );
741        }
742        d->fd = fd;
743        d->callback = callback;
744        d->data = data;
745        d->id = id;
746       
747        return( fd );
748}
749
750/* Because we don't want asynchronous connects in BitlBee, and because
751   libyahoo doesn't seem to use this one anyway, this one is now defunct. */
[cfc8d58]752int ext_yahoo_connect(const char *host, int port)
[b7d3cc34]753{
754#if 0
755        struct sockaddr_in serv_addr;
756        static struct hostent *server;
757        static char last_host[256];
758        int servfd;
759        char **p;
760
761        if(last_host[0] || g_strcasecmp(last_host, host)!=0) {
762                if(!(server = gethostbyname(host))) {
763                        return -1;
764                }
765                strncpy(last_host, host, 255);
766        }
767
768        if((servfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
769                return -1;
770        }
771
772        for (p = server->h_addr_list; *p; p++)
773        {
774                memset(&serv_addr, 0, sizeof(serv_addr));
775                serv_addr.sin_family = AF_INET;
776                memcpy(&serv_addr.sin_addr.s_addr, *p, server->h_length);
777                serv_addr.sin_port = htons(port);
778
779                if(connect(servfd, (struct sockaddr *) &serv_addr,
780                                        sizeof(serv_addr)) == -1) {
781                        return -1;
782                } else {
783                        return servfd;
784                }
785        }
786
787        closesocket(servfd);
788#endif
789        return -1;
790}
791
[9143aeb]792static void byahoo_accept_conf( void *data )
[b7d3cc34]793{
[9143aeb]794        struct byahoo_conf_invitation *inv = data;
795       
[b7d3cc34]796        yahoo_conference_logon( inv->yid, NULL, inv->members, inv->name );
[61ae52c]797        imcb_chat_add_buddy( inv->c, inv->ic->acc->user );
[b7d3cc34]798        g_free( inv->name );
799        g_free( inv );
800}
801
[9143aeb]802static void byahoo_reject_conf( void *data )
[b7d3cc34]803{
[9143aeb]804        struct byahoo_conf_invitation *inv = data;
805       
[b7d3cc34]806        yahoo_conference_decline( inv->yid, NULL, inv->members, inv->name, "User rejected groupchat" );
[e35d1a1]807        imcb_chat_free( inv->c );
[b7d3cc34]808        g_free( inv->name );
809        g_free( inv );
810}
811
[cfc8d58]812void ext_yahoo_got_conf_invite( int id, const char *ignored,
813                                const char *who, const char *room, const char *msg, YList *members )
[b7d3cc34]814{
[0da65d5]815        struct im_connection *ic = byahoo_get_ic_by_id( id );
[b7d3cc34]816        struct byahoo_conf_invitation *inv;
817        char txt[1024];
818        YList *m;
819       
820        inv = g_malloc( sizeof( struct byahoo_conf_invitation ) );
821        memset( inv, 0, sizeof( struct byahoo_conf_invitation ) );
822        inv->name = g_strdup( room );
[61ae52c]823        inv->c = imcb_chat_new( ic, (char*) room );
[b7d3cc34]824        inv->c->data = members;
825        inv->yid = id;
826        inv->members = members;
[0da65d5]827        inv->ic = ic;
[b7d3cc34]828       
829        for( m = members; m; m = m->next )
[c2fb3809]830                if( g_strcasecmp( m->data, ic->acc->user ) != 0 )
[61ae52c]831                        imcb_chat_add_buddy( inv->c, m->data );
[b7d3cc34]832       
833        g_snprintf( txt, 1024, "Got an invitation to chatroom %s from %s: %s", room, who, msg );
834       
[84b045d]835        imcb_ask( ic, txt, inv, byahoo_accept_conf, byahoo_reject_conf );
[b7d3cc34]836}
837
[cfc8d58]838void ext_yahoo_conf_userdecline( int id, const char *ignored, const char *who, const char *room, const char *msg )
[b7d3cc34]839{
[0da65d5]840        struct im_connection *ic = byahoo_get_ic_by_id( id );
[b7d3cc34]841       
[84b045d]842        imcb_log( ic, "Invite to chatroom %s rejected by %s: %s", room, who, msg );
[b7d3cc34]843}
844
[cfc8d58]845void ext_yahoo_conf_userjoin( int id, const char *ignored, const char *who, const char *room )
[b7d3cc34]846{
[0da65d5]847        struct im_connection *ic = byahoo_get_ic_by_id( id );
848        struct groupchat *c;
[b7d3cc34]849       
[e35d1a1]850        for( c = ic->groupchats; c && strcmp( c->title, room ) != 0; c = c->next );
[b7d3cc34]851       
852        if( c )
[61ae52c]853                imcb_chat_add_buddy( c, (char*) who );
[b7d3cc34]854}
855
[cfc8d58]856void ext_yahoo_conf_userleave( int id, const char *ignored, const char *who, const char *room )
857
[b7d3cc34]858{
[0da65d5]859        struct im_connection *ic = byahoo_get_ic_by_id( id );
860        struct groupchat *c;
[b7d3cc34]861       
[e35d1a1]862        for( c = ic->groupchats; c && strcmp( c->title, room ) != 0; c = c->next );
[b7d3cc34]863       
864        if( c )
[61ae52c]865                imcb_chat_remove_buddy( c, (char*) who, "" );
[b7d3cc34]866}
867
[cfc8d58]868void ext_yahoo_conf_message( int id, const char *ignored, const char *who, const char *room, const char *msg, int utf8 )
[b7d3cc34]869{
[0da65d5]870        struct im_connection *ic = byahoo_get_ic_by_id( id );
[b7d3cc34]871        char *m = byahoo_strip( msg );
[0da65d5]872        struct groupchat *c;
[b7d3cc34]873       
[e35d1a1]874        for( c = ic->groupchats; c && strcmp( c->title, room ) != 0; c = c->next );
[b7d3cc34]875       
[fa29d093]876        if( c )
[61ae52c]877                imcb_chat_msg( c, (char*) who, (char*) m, 0, 0 );
[b7d3cc34]878        g_free( m );
879}
880
[cfc8d58]881void ext_yahoo_chat_cat_xml( int id, const char *xml )
[b7d3cc34]882{
883}
884
[cfc8d58]885void ext_yahoo_chat_join( int id, const char *who, const char *room, const char *topic, YList *members, int fd )
[b7d3cc34]886{
887}
888
[cfc8d58]889void ext_yahoo_chat_userjoin( int id, const char *me, const char *room, struct yahoo_chat_member *who )
[b7d3cc34]890{
[cfc8d58]891        free(who->id);
892        free(who->alias);
893        free(who->location);
894        free(who);
[b7d3cc34]895}
896
[cfc8d58]897void ext_yahoo_chat_userleave( int id, const char *me, const char *room, const char *who )
[b7d3cc34]898{
899}
900
[cfc8d58]901void ext_yahoo_chat_message( int id, const char *me, const char *who, const char *room, const char *msg, int msgtype, int utf8 )
[b7d3cc34]902{
903}
904
[cfc8d58]905void ext_yahoo_chat_yahoologout( int id, const char *me )
[b7d3cc34]906{
907}
908
[cfc8d58]909void ext_yahoo_chat_yahooerror( int id, const char *me )
[b7d3cc34]910{
911}
912
[cfc8d58]913void ext_yahoo_contact_added( int id, const char *myid, const char *who, const char *msg )
[b7d3cc34]914{
[f0cb961]915        /* Groups schmoups. If I want to handle groups properly I can get the
916           buddy data from some internal libyahoo2 structure. */
917        imcb_add_buddy( byahoo_get_ic_by_id( id ), (char*) who, NULL );
[b7d3cc34]918}
919
[cfc8d58]920void ext_yahoo_rejected( int id, const char *who, const char *msg )
[b7d3cc34]921{
922}
923
[cfc8d58]924void ext_yahoo_game_notify( int id, const char *me, const char *who, int stat )
[b7d3cc34]925{
926}
927
[cfc8d58]928void ext_yahoo_mail_notify( int id, const char *from, const char *subj, int cnt )
[b7d3cc34]929{
[0da65d5]930        struct im_connection *ic = byahoo_get_ic_by_id( id );
[b7d3cc34]931       
[1febf5c]932        if( !set_getbool( &ic->acc->set, "mail_notifications" ) )
933                ; /* The user doesn't care. */
934        else if( from && subj )
[84b045d]935                imcb_log( ic, "Received e-mail message from %s with subject `%s'", from, subj );
[b7d3cc34]936        else if( cnt > 0 )
[84b045d]937                imcb_log( ic, "Received %d new e-mails", cnt );
[b7d3cc34]938}
939
[cfc8d58]940void ext_yahoo_webcam_invite_reply( int id, const char *me, const char *from, int accept )
[b7d3cc34]941{
942}
943
[cfc8d58]944void ext_yahoo_webcam_closed( int id, const char *who, int reason )
[b7d3cc34]945{
946}
947
948void ext_yahoo_got_search_result( int id, int found, int start, int total, YList *contacts )
949{
950}
951
[cfc8d58]952void ext_yahoo_webcam_viewer( int id, const char *who, int connect )
[b7d3cc34]953{
954}
955
956void ext_yahoo_webcam_data_request( int id, int send )
957{
958}
959
[cfc8d58]960int ext_yahoo_log( const char *fmt, ... )
[b7d3cc34]961{
962        return( 0 );
963}
964
965void 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 )
966{
967}
[cfc8d58]968
969void ext_yahoo_got_ping( int id, const char *msg)
970{
971}
972
973void ext_yahoo_got_buddyicon (int id, const char *me, const char *who, const char *url, int checksum) {}
974void ext_yahoo_got_buddyicon_checksum (int id, const char *me,const char *who, int checksum) {}
975
976void ext_yahoo_got_buddyicon_request(int id, const char *me, const char *who){}
977void ext_yahoo_buddyicon_uploaded(int id, const char *url){}
Note: See TracBrowser for help on using the repository browser.