source: protocols/yahoo/yahoo.c @ 9b55485

Last change on this file since 9b55485 was 6738a67, checked in by Sven Moritz Hallberg <pesco@…>, at 2008-07-16T23:22:52Z

merge in latest trunk

  • 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       
[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";
[5a71d9c]353    ret->mms = 832;           /* this guess taken from libotr UPGRADING file */
[1febf5c]354        ret->init = byahoo_init;
[b7d3cc34]355       
356        ret->login = byahoo_login;
[0da65d5]357        ret->keepalive = byahoo_keepalive;
358        ret->logout = byahoo_logout;
359       
[f6c963b]360        ret->buddy_msg = byahoo_buddy_msg;
[b7d3cc34]361        ret->get_info = byahoo_get_info;
362        ret->away_states = byahoo_away_states;
363        ret->set_away = byahoo_set_away;
364        ret->add_buddy = byahoo_add_buddy;
365        ret->remove_buddy = byahoo_remove_buddy;
[7b23afd]366        ret->send_typing = byahoo_send_typing;
[b7d3cc34]367       
[f6c963b]368        ret->chat_msg = byahoo_chat_msg;
[b7d3cc34]369        ret->chat_invite = byahoo_chat_invite;
370        ret->chat_leave = byahoo_chat_leave;
[0da65d5]371        ret->chat_with = byahoo_chat_with;
[5b52a48]372
373        ret->handle_cmp = g_strcasecmp;
[b7d3cc34]374       
[7b23afd]375        register_protocol(ret);
[b7d3cc34]376}
377
[0da65d5]378static struct im_connection *byahoo_get_ic_by_id( int id )
[b7d3cc34]379{
380        GSList *l;
[0da65d5]381        struct im_connection *ic;
[b7d3cc34]382        struct byahoo_data *yd;
383       
384        for( l = get_connections(); l; l = l->next )
385        {
[0da65d5]386                ic = l->data;
387                yd = ic->proto_data;
[b7d3cc34]388               
[0da65d5]389                if( strcmp( ic->acc->prpl->name, "yahoo" ) == 0 && yd->y2_id == id )
390                        return( ic );
[b7d3cc34]391        }
392       
393        return( NULL );
394}
395
396
397/* Now it's callback time! */
398
399struct byahoo_connect_callback_data
400{
401        int fd;
402        yahoo_connect_callback callback;
403        gpointer data;
404        int id;
405};
406
[ba9edaa]407void byahoo_connect_callback( gpointer data, gint source, b_input_condition cond )
[b7d3cc34]408{
409        struct byahoo_connect_callback_data *d = data;
410       
[0da65d5]411        if( !byahoo_get_ic_by_id( d->id ) )
[b7d3cc34]412        {
413                g_free( d );
414                return;
415        }
416       
417        d->callback( d->fd, 0, d->data );
418        g_free( d );
419}
420
421struct byahoo_read_ready_data
422{
423        int id;
424        int fd;
425        int tag;
426        gpointer data;
427};
428
[ba9edaa]429gboolean byahoo_read_ready_callback( gpointer data, gint source, b_input_condition cond )
[b7d3cc34]430{
431        struct byahoo_read_ready_data *d = data;
432       
[0da65d5]433        if( !byahoo_get_ic_by_id( d->id ) )
[b7d3cc34]434                /* WTF doesn't libyahoo clean this up? */
[ba9edaa]435                return FALSE;
[b7d3cc34]436       
437        yahoo_read_ready( d->id, d->fd, d->data );
[7a685f1]438       
439        return TRUE;
[b7d3cc34]440}
441
442struct byahoo_write_ready_data
443{
444        int id;
445        int fd;
446        int tag;
447        gpointer data;
448};
449
[ba9edaa]450gboolean byahoo_write_ready_callback( gpointer data, gint source, b_input_condition cond )
[b7d3cc34]451{
452        struct byahoo_write_ready_data *d = data;
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 );
[ac4adf9]620        char *m;
[b7d3cc34]621       
[ac4adf9]622        if( msg )
623        {
624                m = byahoo_strip( msg );
625                imcb_buddy_msg( ic, (char*) who, (char*) m, 0, 0 );
626                g_free( m );
627        }
[b7d3cc34]628}
629
[cfc8d58]630void ext_yahoo_got_file( int id,
631                         const char *ignored,
632                         const char *who, const char *url, long expires, const char *msg, const char *fname, unsigned long fesize )
[b7d3cc34]633{
[0da65d5]634        struct im_connection *ic = byahoo_get_ic_by_id( id );
[b7d3cc34]635       
[84b045d]636        imcb_log( ic, "Got a file transfer (file = %s) from %s. Ignoring for now due to lack of support.", fname, who );
[b7d3cc34]637}
638
[cfc8d58]639void ext_yahoo_typing_notify( int id, const char *ignored, const char *who, int stat )
[b7d3cc34]640{
[0da65d5]641        struct im_connection *ic = byahoo_get_ic_by_id( id );
[9624fdf]642       
643        if( stat == 1 )
644                imcb_buddy_typing( ic, (char*) who, OPT_TYPING );
645        else
646                imcb_buddy_typing( ic, (char*) who, 0 );
[b7d3cc34]647}
648
[cfc8d58]649void ext_yahoo_system_message( int id, const char *msg )
[b7d3cc34]650{
[0da65d5]651        struct im_connection *ic = byahoo_get_ic_by_id( id );
[b7d3cc34]652       
[84b045d]653        imcb_log( ic, "Yahoo! system message: %s", msg );
[b7d3cc34]654}
655
[cfc8d58]656void ext_yahoo_webcam_invite( int id, const char *ignored, const char *from )
[b7d3cc34]657{
[0da65d5]658        struct im_connection *ic = byahoo_get_ic_by_id( id );
[b7d3cc34]659       
[84b045d]660        imcb_log( ic, "Got a webcam invitation from %s. IRC+webcams is a no-no though...", from );
[b7d3cc34]661}
662
[cfc8d58]663void ext_yahoo_error( int id, const char *err, int fatal, int num )
[b7d3cc34]664{
[0da65d5]665        struct im_connection *ic = byahoo_get_ic_by_id( id );
[b7d3cc34]666       
[84b045d]667        imcb_error( ic, "%s", err );
[aef4828]668       
[b7d3cc34]669        if( fatal )
[c2fb3809]670                imc_logout( ic, TRUE );
[b7d3cc34]671}
672
673/* TODO: Clear up the mess of inp and d structures */
674int ext_yahoo_add_handler( int id, int fd, yahoo_input_condition cond, void *data )
675{
676        struct byahoo_input_data *inp = g_new0( struct byahoo_input_data, 1 );
677       
678        if( cond == YAHOO_INPUT_READ )
679        {
680                struct byahoo_read_ready_data *d = g_new0( struct byahoo_read_ready_data, 1 );
681               
682                d->id = id;
683                d->fd = fd;
684                d->data = data;
685               
686                inp->d = d;
[ba9edaa]687                d->tag = inp->h = b_input_add( fd, GAIM_INPUT_READ, (b_event_handler) byahoo_read_ready_callback, (gpointer) d );
[b7d3cc34]688        }
689        else if( cond == YAHOO_INPUT_WRITE )
690        {
691                struct byahoo_write_ready_data *d = g_new0( struct byahoo_write_ready_data, 1 );
692               
693                d->id = id;
694                d->fd = fd;
695                d->data = data;
696               
697                inp->d = d;
[ba9edaa]698                d->tag = inp->h = b_input_add( fd, GAIM_INPUT_WRITE, (b_event_handler) byahoo_write_ready_callback, (gpointer) d );
[b7d3cc34]699        }
700        else
701        {
702                g_free( inp );
703                return( -1 );
704                /* Panic... */
705        }
706       
707        byahoo_inputs = g_slist_append( byahoo_inputs, inp );
708        return( inp->h );
709}
710
711void ext_yahoo_remove_handler( int id, int tag )
712{
713        struct byahoo_input_data *inp;
714        GSList *l = byahoo_inputs;
715       
716        while( l )
717        {
718                inp = l->data;
719                if( inp->h == tag )
720                {
721                        g_free( inp->d );
722                        g_free( inp );
723                        byahoo_inputs = g_slist_remove( byahoo_inputs, inp );
724                        break;
725                }
726                l = l->next;
727        }
728       
[ba9edaa]729        b_event_remove( tag );
[b7d3cc34]730}
731
[cfc8d58]732int ext_yahoo_connect_async( int id, const char *host, int port, yahoo_connect_callback callback, void *data )
[b7d3cc34]733{
734        struct byahoo_connect_callback_data *d;
735        int fd;
736       
737        d = g_new0( struct byahoo_connect_callback_data, 1 );
[ba9edaa]738        if( ( fd = proxy_connect( host, port, (b_event_handler) byahoo_connect_callback, (gpointer) d ) ) < 0 )
[b7d3cc34]739        {
740                g_free( d );
741                return( fd );
742        }
743        d->fd = fd;
744        d->callback = callback;
745        d->data = data;
746        d->id = id;
747       
748        return( fd );
749}
750
751/* Because we don't want asynchronous connects in BitlBee, and because
752   libyahoo doesn't seem to use this one anyway, this one is now defunct. */
[cfc8d58]753int ext_yahoo_connect(const char *host, int port)
[b7d3cc34]754{
755#if 0
756        struct sockaddr_in serv_addr;
757        static struct hostent *server;
758        static char last_host[256];
759        int servfd;
760        char **p;
761
762        if(last_host[0] || g_strcasecmp(last_host, host)!=0) {
763                if(!(server = gethostbyname(host))) {
764                        return -1;
765                }
766                strncpy(last_host, host, 255);
767        }
768
769        if((servfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
770                return -1;
771        }
772
773        for (p = server->h_addr_list; *p; p++)
774        {
775                memset(&serv_addr, 0, sizeof(serv_addr));
776                serv_addr.sin_family = AF_INET;
777                memcpy(&serv_addr.sin_addr.s_addr, *p, server->h_length);
778                serv_addr.sin_port = htons(port);
779
780                if(connect(servfd, (struct sockaddr *) &serv_addr,
781                                        sizeof(serv_addr)) == -1) {
782                        return -1;
783                } else {
784                        return servfd;
785                }
786        }
787
788        closesocket(servfd);
789#endif
790        return -1;
791}
792
[9143aeb]793static void byahoo_accept_conf( void *data )
[b7d3cc34]794{
[9143aeb]795        struct byahoo_conf_invitation *inv = data;
796       
[b7d3cc34]797        yahoo_conference_logon( inv->yid, NULL, inv->members, inv->name );
[61ae52c]798        imcb_chat_add_buddy( inv->c, inv->ic->acc->user );
[b7d3cc34]799        g_free( inv->name );
800        g_free( inv );
801}
802
[9143aeb]803static void byahoo_reject_conf( void *data )
[b7d3cc34]804{
[9143aeb]805        struct byahoo_conf_invitation *inv = data;
806       
[b7d3cc34]807        yahoo_conference_decline( inv->yid, NULL, inv->members, inv->name, "User rejected groupchat" );
[e35d1a1]808        imcb_chat_free( inv->c );
[b7d3cc34]809        g_free( inv->name );
810        g_free( inv );
811}
812
[cfc8d58]813void ext_yahoo_got_conf_invite( int id, const char *ignored,
814                                const char *who, const char *room, const char *msg, YList *members )
[b7d3cc34]815{
[0da65d5]816        struct im_connection *ic = byahoo_get_ic_by_id( id );
[b7d3cc34]817        struct byahoo_conf_invitation *inv;
818        char txt[1024];
819        YList *m;
820       
821        inv = g_malloc( sizeof( struct byahoo_conf_invitation ) );
822        memset( inv, 0, sizeof( struct byahoo_conf_invitation ) );
823        inv->name = g_strdup( room );
[61ae52c]824        inv->c = imcb_chat_new( ic, (char*) room );
[b7d3cc34]825        inv->c->data = members;
826        inv->yid = id;
827        inv->members = members;
[0da65d5]828        inv->ic = ic;
[b7d3cc34]829       
830        for( m = members; m; m = m->next )
[c2fb3809]831                if( g_strcasecmp( m->data, ic->acc->user ) != 0 )
[61ae52c]832                        imcb_chat_add_buddy( inv->c, m->data );
[b7d3cc34]833       
834        g_snprintf( txt, 1024, "Got an invitation to chatroom %s from %s: %s", room, who, msg );
835       
[84b045d]836        imcb_ask( ic, txt, inv, byahoo_accept_conf, byahoo_reject_conf );
[b7d3cc34]837}
838
[cfc8d58]839void ext_yahoo_conf_userdecline( int id, const char *ignored, const char *who, const char *room, const char *msg )
[b7d3cc34]840{
[0da65d5]841        struct im_connection *ic = byahoo_get_ic_by_id( id );
[b7d3cc34]842       
[84b045d]843        imcb_log( ic, "Invite to chatroom %s rejected by %s: %s", room, who, msg );
[b7d3cc34]844}
845
[cfc8d58]846void ext_yahoo_conf_userjoin( int id, const char *ignored, const char *who, const char *room )
[b7d3cc34]847{
[0da65d5]848        struct im_connection *ic = byahoo_get_ic_by_id( id );
849        struct groupchat *c;
[b7d3cc34]850       
[e35d1a1]851        for( c = ic->groupchats; c && strcmp( c->title, room ) != 0; c = c->next );
[b7d3cc34]852       
853        if( c )
[61ae52c]854                imcb_chat_add_buddy( c, (char*) who );
[b7d3cc34]855}
856
[cfc8d58]857void ext_yahoo_conf_userleave( int id, const char *ignored, const char *who, const char *room )
858
[b7d3cc34]859{
[0da65d5]860        struct im_connection *ic = byahoo_get_ic_by_id( id );
861        struct groupchat *c;
[b7d3cc34]862       
[e35d1a1]863        for( c = ic->groupchats; c && strcmp( c->title, room ) != 0; c = c->next );
[b7d3cc34]864       
865        if( c )
[61ae52c]866                imcb_chat_remove_buddy( c, (char*) who, "" );
[b7d3cc34]867}
868
[cfc8d58]869void ext_yahoo_conf_message( int id, const char *ignored, const char *who, const char *room, const char *msg, int utf8 )
[b7d3cc34]870{
[0da65d5]871        struct im_connection *ic = byahoo_get_ic_by_id( id );
[b7d3cc34]872        char *m = byahoo_strip( msg );
[0da65d5]873        struct groupchat *c;
[b7d3cc34]874       
[e35d1a1]875        for( c = ic->groupchats; c && strcmp( c->title, room ) != 0; c = c->next );
[b7d3cc34]876       
[fa29d093]877        if( c )
[61ae52c]878                imcb_chat_msg( c, (char*) who, (char*) m, 0, 0 );
[b7d3cc34]879        g_free( m );
880}
881
[cfc8d58]882void ext_yahoo_chat_cat_xml( int id, const char *xml )
[b7d3cc34]883{
884}
885
[cfc8d58]886void ext_yahoo_chat_join( int id, const char *who, const char *room, const char *topic, YList *members, int fd )
[b7d3cc34]887{
888}
889
[cfc8d58]890void ext_yahoo_chat_userjoin( int id, const char *me, const char *room, struct yahoo_chat_member *who )
[b7d3cc34]891{
[cfc8d58]892        free(who->id);
893        free(who->alias);
894        free(who->location);
895        free(who);
[b7d3cc34]896}
897
[cfc8d58]898void ext_yahoo_chat_userleave( int id, const char *me, const char *room, const char *who )
[b7d3cc34]899{
900}
901
[cfc8d58]902void ext_yahoo_chat_message( int id, const char *me, const char *who, const char *room, const char *msg, int msgtype, int utf8 )
[b7d3cc34]903{
904}
905
[cfc8d58]906void ext_yahoo_chat_yahoologout( int id, const char *me )
[b7d3cc34]907{
908}
909
[cfc8d58]910void ext_yahoo_chat_yahooerror( int id, const char *me )
[b7d3cc34]911{
912}
913
[cfc8d58]914void ext_yahoo_contact_added( int id, const char *myid, const char *who, const char *msg )
[b7d3cc34]915{
[f0cb961]916        /* Groups schmoups. If I want to handle groups properly I can get the
917           buddy data from some internal libyahoo2 structure. */
918        imcb_add_buddy( byahoo_get_ic_by_id( id ), (char*) who, NULL );
[b7d3cc34]919}
920
[cfc8d58]921void ext_yahoo_rejected( int id, const char *who, const char *msg )
[b7d3cc34]922{
923}
924
[cfc8d58]925void ext_yahoo_game_notify( int id, const char *me, const char *who, int stat )
[b7d3cc34]926{
927}
928
[cfc8d58]929void ext_yahoo_mail_notify( int id, const char *from, const char *subj, int cnt )
[b7d3cc34]930{
[0da65d5]931        struct im_connection *ic = byahoo_get_ic_by_id( id );
[b7d3cc34]932       
[1febf5c]933        if( !set_getbool( &ic->acc->set, "mail_notifications" ) )
934                ; /* The user doesn't care. */
935        else if( from && subj )
[84b045d]936                imcb_log( ic, "Received e-mail message from %s with subject `%s'", from, subj );
[b7d3cc34]937        else if( cnt > 0 )
[84b045d]938                imcb_log( ic, "Received %d new e-mails", cnt );
[b7d3cc34]939}
940
[cfc8d58]941void ext_yahoo_webcam_invite_reply( int id, const char *me, const char *from, int accept )
[b7d3cc34]942{
943}
944
[cfc8d58]945void ext_yahoo_webcam_closed( int id, const char *who, int reason )
[b7d3cc34]946{
947}
948
949void ext_yahoo_got_search_result( int id, int found, int start, int total, YList *contacts )
950{
951}
952
[cfc8d58]953void ext_yahoo_webcam_viewer( int id, const char *who, int connect )
[b7d3cc34]954{
955}
956
957void ext_yahoo_webcam_data_request( int id, int send )
958{
959}
960
[cfc8d58]961int ext_yahoo_log( const char *fmt, ... )
[b7d3cc34]962{
963        return( 0 );
964}
965
966void 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 )
967{
968}
[cfc8d58]969
970void ext_yahoo_got_ping( int id, const char *msg)
971{
972}
973
974void ext_yahoo_got_buddyicon (int id, const char *me, const char *who, const char *url, int checksum) {}
975void ext_yahoo_got_buddyicon_checksum (int id, const char *me,const char *who, int checksum) {}
976
977void ext_yahoo_got_buddyicon_request(int id, const char *me, const char *who){}
978void ext_yahoo_buddyicon_uploaded(int id, const char *url){}
Note: See TracBrowser for help on using the repository browser.