source: protocols/yahoo/yahoo.c @ e7f8838

Last change on this file since e7f8838 was 1febf5c, checked in by Wilmer van der Gaast <wilmer@…>, at 2008-01-05T21:15:32Z

Added "mail_notifications" setting. Who needs those notifications anyway?
Closes: #338.

  • 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       
317        yahoo_conference_invite( yd->y2_id, NULL, c->data, c->title, msg );
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 );
[b7d3cc34]626        char *m = byahoo_strip( msg );
627       
[9624fdf]628        imcb_buddy_msg( ic, (char*) who, (char*) m, 0, 0 );
[b7d3cc34]629        g_free( m );
630}
631
[cfc8d58]632void ext_yahoo_got_file( int id,
633                         const char *ignored,
634                         const char *who, const char *url, long expires, const char *msg, const char *fname, unsigned long fesize )
[b7d3cc34]635{
[0da65d5]636        struct im_connection *ic = byahoo_get_ic_by_id( id );
[b7d3cc34]637       
[84b045d]638        imcb_log( ic, "Got a file transfer (file = %s) from %s. Ignoring for now due to lack of support.", fname, who );
[b7d3cc34]639}
640
[cfc8d58]641void ext_yahoo_typing_notify( int id, const char *ignored, const char *who, int stat )
[b7d3cc34]642{
[0da65d5]643        struct im_connection *ic = byahoo_get_ic_by_id( id );
[9624fdf]644       
645        if( stat == 1 )
646                imcb_buddy_typing( ic, (char*) who, OPT_TYPING );
647        else
648                imcb_buddy_typing( ic, (char*) who, 0 );
[b7d3cc34]649}
650
[cfc8d58]651void ext_yahoo_system_message( int id, const char *msg )
[b7d3cc34]652{
[0da65d5]653        struct im_connection *ic = byahoo_get_ic_by_id( id );
[b7d3cc34]654       
[84b045d]655        imcb_log( ic, "Yahoo! system message: %s", msg );
[b7d3cc34]656}
657
[cfc8d58]658void ext_yahoo_webcam_invite( int id, const char *ignored, const char *from )
[b7d3cc34]659{
[0da65d5]660        struct im_connection *ic = byahoo_get_ic_by_id( id );
[b7d3cc34]661       
[84b045d]662        imcb_log( ic, "Got a webcam invitation from %s. IRC+webcams is a no-no though...", from );
[b7d3cc34]663}
664
[cfc8d58]665void ext_yahoo_error( int id, const char *err, int fatal, int num )
[b7d3cc34]666{
[0da65d5]667        struct im_connection *ic = byahoo_get_ic_by_id( id );
[b7d3cc34]668       
[84b045d]669        imcb_error( ic, "%s", err );
[aef4828]670       
[b7d3cc34]671        if( fatal )
[c2fb3809]672                imc_logout( ic, TRUE );
[b7d3cc34]673}
674
675/* TODO: Clear up the mess of inp and d structures */
676int ext_yahoo_add_handler( int id, int fd, yahoo_input_condition cond, void *data )
677{
678        struct byahoo_input_data *inp = g_new0( struct byahoo_input_data, 1 );
679       
680        if( cond == YAHOO_INPUT_READ )
681        {
682                struct byahoo_read_ready_data *d = g_new0( struct byahoo_read_ready_data, 1 );
683               
684                d->id = id;
685                d->fd = fd;
686                d->data = data;
687               
688                inp->d = d;
[ba9edaa]689                d->tag = inp->h = b_input_add( fd, GAIM_INPUT_READ, (b_event_handler) byahoo_read_ready_callback, (gpointer) d );
[b7d3cc34]690        }
691        else if( cond == YAHOO_INPUT_WRITE )
692        {
693                struct byahoo_write_ready_data *d = g_new0( struct byahoo_write_ready_data, 1 );
694               
695                d->id = id;
696                d->fd = fd;
697                d->data = data;
698               
699                inp->d = d;
[ba9edaa]700                d->tag = inp->h = b_input_add( fd, GAIM_INPUT_WRITE, (b_event_handler) byahoo_write_ready_callback, (gpointer) d );
[b7d3cc34]701        }
702        else
703        {
704                g_free( inp );
705                return( -1 );
706                /* Panic... */
707        }
708       
709        byahoo_inputs = g_slist_append( byahoo_inputs, inp );
710        return( inp->h );
711}
712
713void ext_yahoo_remove_handler( int id, int tag )
714{
715        struct byahoo_input_data *inp;
716        GSList *l = byahoo_inputs;
717       
718        while( l )
719        {
720                inp = l->data;
721                if( inp->h == tag )
722                {
723                        g_free( inp->d );
724                        g_free( inp );
725                        byahoo_inputs = g_slist_remove( byahoo_inputs, inp );
726                        break;
727                }
728                l = l->next;
729        }
730       
[ba9edaa]731        b_event_remove( tag );
[b7d3cc34]732}
733
[cfc8d58]734int ext_yahoo_connect_async( int id, const char *host, int port, yahoo_connect_callback callback, void *data )
[b7d3cc34]735{
736        struct byahoo_connect_callback_data *d;
737        int fd;
738       
739        d = g_new0( struct byahoo_connect_callback_data, 1 );
[ba9edaa]740        if( ( fd = proxy_connect( host, port, (b_event_handler) byahoo_connect_callback, (gpointer) d ) ) < 0 )
[b7d3cc34]741        {
742                g_free( d );
743                return( fd );
744        }
745        d->fd = fd;
746        d->callback = callback;
747        d->data = data;
748        d->id = id;
749       
750        return( fd );
751}
752
753/* Because we don't want asynchronous connects in BitlBee, and because
754   libyahoo doesn't seem to use this one anyway, this one is now defunct. */
[cfc8d58]755int ext_yahoo_connect(const char *host, int port)
[b7d3cc34]756{
757#if 0
758        struct sockaddr_in serv_addr;
759        static struct hostent *server;
760        static char last_host[256];
761        int servfd;
762        char **p;
763
764        if(last_host[0] || g_strcasecmp(last_host, host)!=0) {
765                if(!(server = gethostbyname(host))) {
766                        return -1;
767                }
768                strncpy(last_host, host, 255);
769        }
770
771        if((servfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
772                return -1;
773        }
774
775        for (p = server->h_addr_list; *p; p++)
776        {
777                memset(&serv_addr, 0, sizeof(serv_addr));
778                serv_addr.sin_family = AF_INET;
779                memcpy(&serv_addr.sin_addr.s_addr, *p, server->h_length);
780                serv_addr.sin_port = htons(port);
781
782                if(connect(servfd, (struct sockaddr *) &serv_addr,
783                                        sizeof(serv_addr)) == -1) {
784                        return -1;
785                } else {
786                        return servfd;
787                }
788        }
789
790        closesocket(servfd);
791#endif
792        return -1;
793}
794
795static void byahoo_accept_conf( gpointer w, struct byahoo_conf_invitation *inv )
796{
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
803static void byahoo_reject_conf( gpointer w, struct byahoo_conf_invitation *inv )
804{
805        yahoo_conference_decline( inv->yid, NULL, inv->members, inv->name, "User rejected groupchat" );
[e35d1a1]806        imcb_chat_free( inv->c );
[b7d3cc34]807        g_free( inv->name );
808        g_free( inv );
809}
810
[cfc8d58]811void ext_yahoo_got_conf_invite( int id, const char *ignored,
812                                const char *who, const char *room, const char *msg, YList *members )
[b7d3cc34]813{
[0da65d5]814        struct im_connection *ic = byahoo_get_ic_by_id( id );
[b7d3cc34]815        struct byahoo_conf_invitation *inv;
816        char txt[1024];
817        YList *m;
818       
819        inv = g_malloc( sizeof( struct byahoo_conf_invitation ) );
820        memset( inv, 0, sizeof( struct byahoo_conf_invitation ) );
821        inv->name = g_strdup( room );
[61ae52c]822        inv->c = imcb_chat_new( ic, (char*) room );
[b7d3cc34]823        inv->c->data = members;
824        inv->yid = id;
825        inv->members = members;
[0da65d5]826        inv->ic = ic;
[b7d3cc34]827       
828        for( m = members; m; m = m->next )
[c2fb3809]829                if( g_strcasecmp( m->data, ic->acc->user ) != 0 )
[61ae52c]830                        imcb_chat_add_buddy( inv->c, m->data );
[b7d3cc34]831       
832        g_snprintf( txt, 1024, "Got an invitation to chatroom %s from %s: %s", room, who, msg );
833       
[84b045d]834        imcb_ask( ic, txt, inv, byahoo_accept_conf, byahoo_reject_conf );
[b7d3cc34]835}
836
[cfc8d58]837void ext_yahoo_conf_userdecline( int id, const char *ignored, const char *who, const char *room, const char *msg )
[b7d3cc34]838{
[0da65d5]839        struct im_connection *ic = byahoo_get_ic_by_id( id );
[b7d3cc34]840       
[84b045d]841        imcb_log( ic, "Invite to chatroom %s rejected by %s: %s", room, who, msg );
[b7d3cc34]842}
843
[cfc8d58]844void ext_yahoo_conf_userjoin( int id, const char *ignored, const char *who, const char *room )
[b7d3cc34]845{
[0da65d5]846        struct im_connection *ic = byahoo_get_ic_by_id( id );
847        struct groupchat *c;
[b7d3cc34]848       
[e35d1a1]849        for( c = ic->groupchats; c && strcmp( c->title, room ) != 0; c = c->next );
[b7d3cc34]850       
851        if( c )
[61ae52c]852                imcb_chat_add_buddy( c, (char*) who );
[b7d3cc34]853}
854
[cfc8d58]855void ext_yahoo_conf_userleave( int id, const char *ignored, const char *who, const char *room )
856
[b7d3cc34]857{
[0da65d5]858        struct im_connection *ic = byahoo_get_ic_by_id( id );
859        struct groupchat *c;
[b7d3cc34]860       
[e35d1a1]861        for( c = ic->groupchats; c && strcmp( c->title, room ) != 0; c = c->next );
[b7d3cc34]862       
863        if( c )
[61ae52c]864                imcb_chat_remove_buddy( c, (char*) who, "" );
[b7d3cc34]865}
866
[cfc8d58]867void ext_yahoo_conf_message( int id, const char *ignored, const char *who, const char *room, const char *msg, int utf8 )
[b7d3cc34]868{
[0da65d5]869        struct im_connection *ic = byahoo_get_ic_by_id( id );
[b7d3cc34]870        char *m = byahoo_strip( msg );
[0da65d5]871        struct groupchat *c;
[b7d3cc34]872       
[e35d1a1]873        for( c = ic->groupchats; c && strcmp( c->title, room ) != 0; c = c->next );
[b7d3cc34]874       
[fa29d093]875        if( c )
[61ae52c]876                imcb_chat_msg( c, (char*) who, (char*) m, 0, 0 );
[b7d3cc34]877        g_free( m );
878}
879
[cfc8d58]880void ext_yahoo_chat_cat_xml( int id, const char *xml )
[b7d3cc34]881{
882}
883
[cfc8d58]884void ext_yahoo_chat_join( int id, const char *who, const char *room, const char *topic, YList *members, int fd )
[b7d3cc34]885{
886}
887
[cfc8d58]888void ext_yahoo_chat_userjoin( int id, const char *me, const char *room, struct yahoo_chat_member *who )
[b7d3cc34]889{
[cfc8d58]890        free(who->id);
891        free(who->alias);
892        free(who->location);
893        free(who);
[b7d3cc34]894}
895
[cfc8d58]896void ext_yahoo_chat_userleave( int id, const char *me, const char *room, const char *who )
[b7d3cc34]897{
898}
899
[cfc8d58]900void ext_yahoo_chat_message( int id, const char *me, const char *who, const char *room, const char *msg, int msgtype, int utf8 )
[b7d3cc34]901{
902}
903
[cfc8d58]904void ext_yahoo_chat_yahoologout( int id, const char *me )
[b7d3cc34]905{
906}
907
[cfc8d58]908void ext_yahoo_chat_yahooerror( int id, const char *me )
[b7d3cc34]909{
910}
911
[cfc8d58]912void ext_yahoo_contact_added( int id, const char *myid, const char *who, const char *msg )
[b7d3cc34]913{
[f0cb961]914        /* Groups schmoups. If I want to handle groups properly I can get the
915           buddy data from some internal libyahoo2 structure. */
916        imcb_add_buddy( byahoo_get_ic_by_id( id ), (char*) who, NULL );
[b7d3cc34]917}
918
[cfc8d58]919void ext_yahoo_rejected( int id, const char *who, const char *msg )
[b7d3cc34]920{
921}
922
[cfc8d58]923void ext_yahoo_game_notify( int id, const char *me, const char *who, int stat )
[b7d3cc34]924{
925}
926
[cfc8d58]927void ext_yahoo_mail_notify( int id, const char *from, const char *subj, int cnt )
[b7d3cc34]928{
[0da65d5]929        struct im_connection *ic = byahoo_get_ic_by_id( id );
[b7d3cc34]930       
[1febf5c]931        if( !set_getbool( &ic->acc->set, "mail_notifications" ) )
932                ; /* The user doesn't care. */
933        else if( from && subj )
[84b045d]934                imcb_log( ic, "Received e-mail message from %s with subject `%s'", from, subj );
[b7d3cc34]935        else if( cnt > 0 )
[84b045d]936                imcb_log( ic, "Received %d new e-mails", cnt );
[b7d3cc34]937}
938
[cfc8d58]939void ext_yahoo_webcam_invite_reply( int id, const char *me, const char *from, int accept )
[b7d3cc34]940{
941}
942
[cfc8d58]943void ext_yahoo_webcam_closed( int id, const char *who, int reason )
[b7d3cc34]944{
945}
946
947void ext_yahoo_got_search_result( int id, int found, int start, int total, YList *contacts )
948{
949}
950
[cfc8d58]951void ext_yahoo_webcam_viewer( int id, const char *who, int connect )
[b7d3cc34]952{
953}
954
955void ext_yahoo_webcam_data_request( int id, int send )
956{
957}
958
[cfc8d58]959int ext_yahoo_log( const char *fmt, ... )
[b7d3cc34]960{
961        return( 0 );
962}
963
964void 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 )
965{
966}
[cfc8d58]967
968void ext_yahoo_got_ping( int id, const char *msg)
969{
970}
971
972void ext_yahoo_got_buddyicon (int id, const char *me, const char *who, const char *url, int checksum) {}
973void ext_yahoo_got_buddyicon_checksum (int id, const char *me,const char *who, int checksum) {}
974
975void ext_yahoo_got_buddyicon_request(int id, const char *me, const char *who){}
976void ext_yahoo_buddyicon_uploaded(int id, const char *url){}
Note: See TracBrowser for help on using the repository browser.