source: protocols/yahoo/yahoo.c @ 71dc854

Last change on this file since 71dc854 was c058ff9, checked in by Wilmer van der Gaast <wilmer@…>, at 2007-12-09T23:19:35Z

Added /invite support for Jabber chatrooms (and fixed the argument order
to chat_invite).

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