source: protocols/yahoo/yahoo.c @ d179921d

Last change on this file since d179921d was 79eae4a, checked in by Wilmer van der Gaast <wilmer@…>, at 2008-03-15T21:05:39Z

Inviting someone to a Yahoo! chatroom with msg=NULL is bad. I wonder if
/invite ever worked in the Yahoo! module...

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