source: protocols/yahoo/yahoo.c @ b308cf9

Last change on this file since b308cf9 was ec86b22, checked in by Wilmer van der Gaast <wilmer@…>, at 2010-05-15T23:28:16Z

Mainline merge. (Probably mostly irrelevant for this branch, oh well.)

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