source: protocols/yahoo/yahoo.c @ 5a71d9c

Last change on this file since 5a71d9c was 5a71d9c, checked in by Sven Moritz Hallberg <sm@…>, at 2008-02-09T17:58:13Z
  • add support for setting ops/voice according to OTR msgstate
  • add 'otr trust' user command
  • support non-otr messages during keygen
  • run otr messages through strip_html
  • interpret <b> and <i> tags in html messages
  • record max message size in prpl
  • add 'encrypted' flag to user_t
  • cosmetics
  • Property mode set to 100644
File size: 23.6 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";
[5a71d9c]356    ret->mms = 832;           /* this guess taken from libotr UPGRADING file */
[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       
[7b23afd]378        register_protocol(ret);
[b7d3cc34]379}
380
[0da65d5]381static struct im_connection *byahoo_get_ic_by_id( int id )
[b7d3cc34]382{
383        GSList *l;
[0da65d5]384        struct im_connection *ic;
[b7d3cc34]385        struct byahoo_data *yd;
386       
387        for( l = get_connections(); l; l = l->next )
388        {
[0da65d5]389                ic = l->data;
390                yd = ic->proto_data;
[b7d3cc34]391               
[0da65d5]392                if( strcmp( ic->acc->prpl->name, "yahoo" ) == 0 && yd->y2_id == id )
393                        return( ic );
[b7d3cc34]394        }
395       
396        return( NULL );
397}
398
399
400/* Now it's callback time! */
401
402struct byahoo_connect_callback_data
403{
404        int fd;
405        yahoo_connect_callback callback;
406        gpointer data;
407        int id;
408};
409
[ba9edaa]410void byahoo_connect_callback( gpointer data, gint source, b_input_condition cond )
[b7d3cc34]411{
412        struct byahoo_connect_callback_data *d = data;
413       
[0da65d5]414        if( !byahoo_get_ic_by_id( d->id ) )
[b7d3cc34]415        {
416                g_free( d );
417                return;
418        }
419       
420        d->callback( d->fd, 0, d->data );
421        g_free( d );
422}
423
424struct byahoo_read_ready_data
425{
426        int id;
427        int fd;
428        int tag;
429        gpointer data;
430};
431
[ba9edaa]432gboolean byahoo_read_ready_callback( gpointer data, gint source, b_input_condition cond )
[b7d3cc34]433{
434        struct byahoo_read_ready_data *d = data;
435       
[0da65d5]436        if( !byahoo_get_ic_by_id( d->id ) )
[b7d3cc34]437                /* WTF doesn't libyahoo clean this up? */
[ba9edaa]438                return FALSE;
[b7d3cc34]439       
440        yahoo_read_ready( d->id, d->fd, d->data );
[7a685f1]441       
442        return TRUE;
[b7d3cc34]443}
444
445struct byahoo_write_ready_data
446{
447        int id;
448        int fd;
449        int tag;
450        gpointer data;
451};
452
[ba9edaa]453gboolean byahoo_write_ready_callback( gpointer data, gint source, b_input_condition cond )
[b7d3cc34]454{
455        struct byahoo_write_ready_data *d = data;
456       
[0da65d5]457        if( !byahoo_get_ic_by_id( d->id ) )
[b7d3cc34]458                /* WTF doesn't libyahoo clean this up? */
[ba9edaa]459                return FALSE;
[b7d3cc34]460       
461        yahoo_write_ready( d->id, d->fd, d->data );
[7a685f1]462       
463        return FALSE;
[b7d3cc34]464}
465
[cfc8d58]466void ext_yahoo_login_response( int id, int succ, const char *url )
[b7d3cc34]467{
[0da65d5]468        struct im_connection *ic = byahoo_get_ic_by_id( id );
[b7d3cc34]469        struct byahoo_data *yd = NULL;
470       
[0da65d5]471        if( ic == NULL )
[b7d3cc34]472        {
473                /* libyahoo2 seems to call this one twice when something
474                   went wrong sometimes. Don't know why. Because we clean
475                   up the connection on the first failure, the second
476                   should be ignored. */
477               
478                return;
479        }
480       
[0da65d5]481        yd = (struct byahoo_data *) ic->proto_data;
[b7d3cc34]482       
483        if( succ == YAHOO_LOGIN_OK )
484        {
[84b045d]485                imcb_connected( ic );
[b7d3cc34]486               
487                yd->logged_in = TRUE;
488        }
489        else
490        {
491                char *errstr;
[c2fb3809]492                int allow_reconnect = TRUE;
[b7d3cc34]493               
494                yd->logged_in = FALSE;
495               
496                if( succ == YAHOO_LOGIN_UNAME )
497                        errstr = "Incorrect Yahoo! username";
498                else if( succ == YAHOO_LOGIN_PASSWD )
499                        errstr = "Incorrect Yahoo! password";
500                else if( succ == YAHOO_LOGIN_LOCK )
501                        errstr = "Yahoo! account locked";
502                else if( succ == YAHOO_LOGIN_DUPL )
503                {
504                        errstr = "Logged in on a different machine or device";
[c2fb3809]505                        allow_reconnect = FALSE;
[b7d3cc34]506                }
507                else if( succ == YAHOO_LOGIN_SOCK )
508                        errstr = "Socket problem";
509                else
510                        errstr = "Unknown error";
511               
512                if( url && *url )
[84b045d]513                        imcb_error( ic, "Error %d (%s). See %s for more information.", succ, errstr, url );
[b7d3cc34]514                else
[84b045d]515                        imcb_error( ic, "Error %d (%s)", succ, errstr );
[b7d3cc34]516               
[c2fb3809]517                imc_logout( ic, allow_reconnect );
[b7d3cc34]518        }
519}
520
521void ext_yahoo_got_buddies( int id, YList *buds )
522{
[0da65d5]523        struct im_connection *ic = byahoo_get_ic_by_id( id );
524        struct byahoo_data *yd = ic->proto_data;
[b7d3cc34]525        YList *bl = buds;
526       
527        while( bl )
528        {
529                struct yahoo_buddy *b = bl->data;
530                struct byahoo_buddygroups *bg;
531               
532                if( strcmp( b->group, BYAHOO_DEFAULT_GROUP ) != 0 )
533                {
534                        bg = g_new0( struct byahoo_buddygroups, 1 );
535                       
536                        bg->buddy = g_strdup( b->id );
537                        bg->group = g_strdup( b->group );
538                        yd->buddygroups = g_slist_append( yd->buddygroups, bg );
539                }
540               
[f0cb961]541                imcb_add_buddy( ic, b->id, b->group );
542                imcb_rename_buddy( ic, b->id, b->real_name );
543               
[b7d3cc34]544                bl = bl->next;
545        }
546}
547
548void ext_yahoo_got_ignore( int id, YList *igns )
549{
550}
551
552void ext_yahoo_got_identities( int id, YList *ids )
553{
554}
555
556void ext_yahoo_got_cookies( int id )
557{
558}
559
[cfc8d58]560void ext_yahoo_status_changed( int id, const char *who, int stat, const char *msg, int away, int idle, int mobile )
[b7d3cc34]561{
[0da65d5]562        struct im_connection *ic = byahoo_get_ic_by_id( id );
[6bbb939]563        char *state_string = NULL;
564        int flags = OPT_LOGGED_IN;
565       
566        if( away )
567                flags |= OPT_AWAY;
568       
569        switch (stat)
570        {
571        case YAHOO_STATUS_BRB:
572                state_string = "Be Right Back";
573                break;
574        case YAHOO_STATUS_BUSY:
575                state_string = "Busy";
576                break;
577        case YAHOO_STATUS_NOTATHOME:
578                state_string = "Not At Home";
579                break;
580        case YAHOO_STATUS_NOTATDESK:
581                state_string = "Not At Desk";
582                break;
583        case YAHOO_STATUS_NOTINOFFICE:
584                state_string = "Not In Office";
585                break;
586        case YAHOO_STATUS_ONPHONE:
587                state_string = "On Phone";
588                break;
589        case YAHOO_STATUS_ONVACATION:
590                state_string = "On Vacation";
591                break;
592        case YAHOO_STATUS_OUTTOLUNCH:
593                state_string = "Out To Lunch";
594                break;
595        case YAHOO_STATUS_STEPPEDOUT:
596                state_string = "Stepped Out";
597                break;
598        case YAHOO_STATUS_INVISIBLE:
599                state_string = "Invisible";
600                break;
601        case YAHOO_STATUS_CUSTOM:
602                state_string = "Away";
603                break;
604        case YAHOO_STATUS_IDLE:
605                state_string = "Idle";
606                break;
607        case YAHOO_STATUS_OFFLINE:
608                state_string = "Offline";
609                flags = 0;
610                break;
611        case YAHOO_STATUS_NOTIFY:
612                state_string = "Notify";
613                break;
614        }
615       
616        imcb_buddy_status( ic, who, flags, state_string, msg );
[b7d3cc34]617       
[6bbb939]618        /* Not implemented yet...
619        if( stat == YAHOO_STATUS_IDLE )
620                imcb_buddy_times( ic, who, 0, away );
621        */
[b7d3cc34]622}
623
[cfc8d58]624void ext_yahoo_got_im( int id, const char *me, const char *who, const char *msg, long tm, int stat, int utf8 )
[b7d3cc34]625{
[0da65d5]626        struct im_connection *ic = byahoo_get_ic_by_id( id );
[ac4adf9]627        char *m;
[b7d3cc34]628       
[ac4adf9]629        if( msg )
630        {
631                m = byahoo_strip( msg );
632                imcb_buddy_msg( ic, (char*) who, (char*) m, 0, 0 );
633                g_free( m );
634        }
[b7d3cc34]635}
636
[cfc8d58]637void ext_yahoo_got_file( int id,
638                         const char *ignored,
639                         const char *who, const char *url, long expires, const char *msg, const char *fname, unsigned long fesize )
[b7d3cc34]640{
[0da65d5]641        struct im_connection *ic = byahoo_get_ic_by_id( id );
[b7d3cc34]642       
[84b045d]643        imcb_log( ic, "Got a file transfer (file = %s) from %s. Ignoring for now due to lack of support.", fname, who );
[b7d3cc34]644}
645
[cfc8d58]646void ext_yahoo_typing_notify( int id, const char *ignored, const char *who, int stat )
[b7d3cc34]647{
[0da65d5]648        struct im_connection *ic = byahoo_get_ic_by_id( id );
[9624fdf]649       
650        if( stat == 1 )
651                imcb_buddy_typing( ic, (char*) who, OPT_TYPING );
652        else
653                imcb_buddy_typing( ic, (char*) who, 0 );
[b7d3cc34]654}
655
[cfc8d58]656void ext_yahoo_system_message( int id, const char *msg )
[b7d3cc34]657{
[0da65d5]658        struct im_connection *ic = byahoo_get_ic_by_id( id );
[b7d3cc34]659       
[84b045d]660        imcb_log( ic, "Yahoo! system message: %s", msg );
[b7d3cc34]661}
662
[cfc8d58]663void ext_yahoo_webcam_invite( int id, const char *ignored, const char *from )
[b7d3cc34]664{
[0da65d5]665        struct im_connection *ic = byahoo_get_ic_by_id( id );
[b7d3cc34]666       
[84b045d]667        imcb_log( ic, "Got a webcam invitation from %s. IRC+webcams is a no-no though...", from );
[b7d3cc34]668}
669
[cfc8d58]670void ext_yahoo_error( int id, const char *err, int fatal, int num )
[b7d3cc34]671{
[0da65d5]672        struct im_connection *ic = byahoo_get_ic_by_id( id );
[b7d3cc34]673       
[84b045d]674        imcb_error( ic, "%s", err );
[aef4828]675       
[b7d3cc34]676        if( fatal )
[c2fb3809]677                imc_logout( ic, TRUE );
[b7d3cc34]678}
679
680/* TODO: Clear up the mess of inp and d structures */
681int ext_yahoo_add_handler( int id, int fd, yahoo_input_condition cond, void *data )
682{
683        struct byahoo_input_data *inp = g_new0( struct byahoo_input_data, 1 );
684       
685        if( cond == YAHOO_INPUT_READ )
686        {
687                struct byahoo_read_ready_data *d = g_new0( struct byahoo_read_ready_data, 1 );
688               
689                d->id = id;
690                d->fd = fd;
691                d->data = data;
692               
693                inp->d = d;
[ba9edaa]694                d->tag = inp->h = b_input_add( fd, GAIM_INPUT_READ, (b_event_handler) byahoo_read_ready_callback, (gpointer) d );
[b7d3cc34]695        }
696        else if( cond == YAHOO_INPUT_WRITE )
697        {
698                struct byahoo_write_ready_data *d = g_new0( struct byahoo_write_ready_data, 1 );
699               
700                d->id = id;
701                d->fd = fd;
702                d->data = data;
703               
704                inp->d = d;
[ba9edaa]705                d->tag = inp->h = b_input_add( fd, GAIM_INPUT_WRITE, (b_event_handler) byahoo_write_ready_callback, (gpointer) d );
[b7d3cc34]706        }
707        else
708        {
709                g_free( inp );
710                return( -1 );
711                /* Panic... */
712        }
713       
714        byahoo_inputs = g_slist_append( byahoo_inputs, inp );
715        return( inp->h );
716}
717
718void ext_yahoo_remove_handler( int id, int tag )
719{
720        struct byahoo_input_data *inp;
721        GSList *l = byahoo_inputs;
722       
723        while( l )
724        {
725                inp = l->data;
726                if( inp->h == tag )
727                {
728                        g_free( inp->d );
729                        g_free( inp );
730                        byahoo_inputs = g_slist_remove( byahoo_inputs, inp );
731                        break;
732                }
733                l = l->next;
734        }
735       
[ba9edaa]736        b_event_remove( tag );
[b7d3cc34]737}
738
[cfc8d58]739int ext_yahoo_connect_async( int id, const char *host, int port, yahoo_connect_callback callback, void *data )
[b7d3cc34]740{
741        struct byahoo_connect_callback_data *d;
742        int fd;
743       
744        d = g_new0( struct byahoo_connect_callback_data, 1 );
[ba9edaa]745        if( ( fd = proxy_connect( host, port, (b_event_handler) byahoo_connect_callback, (gpointer) d ) ) < 0 )
[b7d3cc34]746        {
747                g_free( d );
748                return( fd );
749        }
750        d->fd = fd;
751        d->callback = callback;
752        d->data = data;
753        d->id = id;
754       
755        return( fd );
756}
757
758/* Because we don't want asynchronous connects in BitlBee, and because
759   libyahoo doesn't seem to use this one anyway, this one is now defunct. */
[cfc8d58]760int ext_yahoo_connect(const char *host, int port)
[b7d3cc34]761{
762#if 0
763        struct sockaddr_in serv_addr;
764        static struct hostent *server;
765        static char last_host[256];
766        int servfd;
767        char **p;
768
769        if(last_host[0] || g_strcasecmp(last_host, host)!=0) {
770                if(!(server = gethostbyname(host))) {
771                        return -1;
772                }
773                strncpy(last_host, host, 255);
774        }
775
776        if((servfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
777                return -1;
778        }
779
780        for (p = server->h_addr_list; *p; p++)
781        {
782                memset(&serv_addr, 0, sizeof(serv_addr));
783                serv_addr.sin_family = AF_INET;
784                memcpy(&serv_addr.sin_addr.s_addr, *p, server->h_length);
785                serv_addr.sin_port = htons(port);
786
787                if(connect(servfd, (struct sockaddr *) &serv_addr,
788                                        sizeof(serv_addr)) == -1) {
789                        return -1;
790                } else {
791                        return servfd;
792                }
793        }
794
795        closesocket(servfd);
796#endif
797        return -1;
798}
799
800static void byahoo_accept_conf( gpointer w, struct byahoo_conf_invitation *inv )
801{
802        yahoo_conference_logon( inv->yid, NULL, inv->members, inv->name );
[61ae52c]803        imcb_chat_add_buddy( inv->c, inv->ic->acc->user );
[b7d3cc34]804        g_free( inv->name );
805        g_free( inv );
806}
807
808static void byahoo_reject_conf( gpointer w, struct byahoo_conf_invitation *inv )
809{
810        yahoo_conference_decline( inv->yid, NULL, inv->members, inv->name, "User rejected groupchat" );
[e35d1a1]811        imcb_chat_free( inv->c );
[b7d3cc34]812        g_free( inv->name );
813        g_free( inv );
814}
815
[cfc8d58]816void ext_yahoo_got_conf_invite( int id, const char *ignored,
817                                const char *who, const char *room, const char *msg, YList *members )
[b7d3cc34]818{
[0da65d5]819        struct im_connection *ic = byahoo_get_ic_by_id( id );
[b7d3cc34]820        struct byahoo_conf_invitation *inv;
821        char txt[1024];
822        YList *m;
823       
824        inv = g_malloc( sizeof( struct byahoo_conf_invitation ) );
825        memset( inv, 0, sizeof( struct byahoo_conf_invitation ) );
826        inv->name = g_strdup( room );
[61ae52c]827        inv->c = imcb_chat_new( ic, (char*) room );
[b7d3cc34]828        inv->c->data = members;
829        inv->yid = id;
830        inv->members = members;
[0da65d5]831        inv->ic = ic;
[b7d3cc34]832       
833        for( m = members; m; m = m->next )
[c2fb3809]834                if( g_strcasecmp( m->data, ic->acc->user ) != 0 )
[61ae52c]835                        imcb_chat_add_buddy( inv->c, m->data );
[b7d3cc34]836       
837        g_snprintf( txt, 1024, "Got an invitation to chatroom %s from %s: %s", room, who, msg );
838       
[84b045d]839        imcb_ask( ic, txt, inv, byahoo_accept_conf, byahoo_reject_conf );
[b7d3cc34]840}
841
[cfc8d58]842void ext_yahoo_conf_userdecline( int id, const char *ignored, const char *who, const char *room, const char *msg )
[b7d3cc34]843{
[0da65d5]844        struct im_connection *ic = byahoo_get_ic_by_id( id );
[b7d3cc34]845       
[84b045d]846        imcb_log( ic, "Invite to chatroom %s rejected by %s: %s", room, who, msg );
[b7d3cc34]847}
848
[cfc8d58]849void ext_yahoo_conf_userjoin( int id, const char *ignored, const char *who, const char *room )
[b7d3cc34]850{
[0da65d5]851        struct im_connection *ic = byahoo_get_ic_by_id( id );
852        struct groupchat *c;
[b7d3cc34]853       
[e35d1a1]854        for( c = ic->groupchats; c && strcmp( c->title, room ) != 0; c = c->next );
[b7d3cc34]855       
856        if( c )
[61ae52c]857                imcb_chat_add_buddy( c, (char*) who );
[b7d3cc34]858}
859
[cfc8d58]860void ext_yahoo_conf_userleave( int id, const char *ignored, const char *who, const char *room )
861
[b7d3cc34]862{
[0da65d5]863        struct im_connection *ic = byahoo_get_ic_by_id( id );
864        struct groupchat *c;
[b7d3cc34]865       
[e35d1a1]866        for( c = ic->groupchats; c && strcmp( c->title, room ) != 0; c = c->next );
[b7d3cc34]867       
868        if( c )
[61ae52c]869                imcb_chat_remove_buddy( c, (char*) who, "" );
[b7d3cc34]870}
871
[cfc8d58]872void ext_yahoo_conf_message( int id, const char *ignored, const char *who, const char *room, const char *msg, int utf8 )
[b7d3cc34]873{
[0da65d5]874        struct im_connection *ic = byahoo_get_ic_by_id( id );
[b7d3cc34]875        char *m = byahoo_strip( msg );
[0da65d5]876        struct groupchat *c;
[b7d3cc34]877       
[e35d1a1]878        for( c = ic->groupchats; c && strcmp( c->title, room ) != 0; c = c->next );
[b7d3cc34]879       
[fa29d093]880        if( c )
[61ae52c]881                imcb_chat_msg( c, (char*) who, (char*) m, 0, 0 );
[b7d3cc34]882        g_free( m );
883}
884
[cfc8d58]885void ext_yahoo_chat_cat_xml( int id, const char *xml )
[b7d3cc34]886{
887}
888
[cfc8d58]889void ext_yahoo_chat_join( int id, const char *who, const char *room, const char *topic, YList *members, int fd )
[b7d3cc34]890{
891}
892
[cfc8d58]893void ext_yahoo_chat_userjoin( int id, const char *me, const char *room, struct yahoo_chat_member *who )
[b7d3cc34]894{
[cfc8d58]895        free(who->id);
896        free(who->alias);
897        free(who->location);
898        free(who);
[b7d3cc34]899}
900
[cfc8d58]901void ext_yahoo_chat_userleave( int id, const char *me, const char *room, const char *who )
[b7d3cc34]902{
903}
904
[cfc8d58]905void ext_yahoo_chat_message( int id, const char *me, const char *who, const char *room, const char *msg, int msgtype, int utf8 )
[b7d3cc34]906{
907}
908
[cfc8d58]909void ext_yahoo_chat_yahoologout( int id, const char *me )
[b7d3cc34]910{
911}
912
[cfc8d58]913void ext_yahoo_chat_yahooerror( int id, const char *me )
[b7d3cc34]914{
915}
916
[cfc8d58]917void ext_yahoo_contact_added( int id, const char *myid, const char *who, const char *msg )
[b7d3cc34]918{
[f0cb961]919        /* Groups schmoups. If I want to handle groups properly I can get the
920           buddy data from some internal libyahoo2 structure. */
921        imcb_add_buddy( byahoo_get_ic_by_id( id ), (char*) who, NULL );
[b7d3cc34]922}
923
[cfc8d58]924void ext_yahoo_rejected( int id, const char *who, const char *msg )
[b7d3cc34]925{
926}
927
[cfc8d58]928void ext_yahoo_game_notify( int id, const char *me, const char *who, int stat )
[b7d3cc34]929{
930}
931
[cfc8d58]932void ext_yahoo_mail_notify( int id, const char *from, const char *subj, int cnt )
[b7d3cc34]933{
[0da65d5]934        struct im_connection *ic = byahoo_get_ic_by_id( id );
[b7d3cc34]935       
[1febf5c]936        if( !set_getbool( &ic->acc->set, "mail_notifications" ) )
937                ; /* The user doesn't care. */
938        else if( from && subj )
[84b045d]939                imcb_log( ic, "Received e-mail message from %s with subject `%s'", from, subj );
[b7d3cc34]940        else if( cnt > 0 )
[84b045d]941                imcb_log( ic, "Received %d new e-mails", cnt );
[b7d3cc34]942}
943
[cfc8d58]944void ext_yahoo_webcam_invite_reply( int id, const char *me, const char *from, int accept )
[b7d3cc34]945{
946}
947
[cfc8d58]948void ext_yahoo_webcam_closed( int id, const char *who, int reason )
[b7d3cc34]949{
950}
951
952void ext_yahoo_got_search_result( int id, int found, int start, int total, YList *contacts )
953{
954}
955
[cfc8d58]956void ext_yahoo_webcam_viewer( int id, const char *who, int connect )
[b7d3cc34]957{
958}
959
960void ext_yahoo_webcam_data_request( int id, int send )
961{
962}
963
[cfc8d58]964int ext_yahoo_log( const char *fmt, ... )
[b7d3cc34]965{
966        return( 0 );
967}
968
969void 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 )
970{
971}
[cfc8d58]972
973void ext_yahoo_got_ping( int id, const char *msg)
974{
975}
976
977void ext_yahoo_got_buddyicon (int id, const char *me, const char *who, const char *url, int checksum) {}
978void ext_yahoo_got_buddyicon_checksum (int id, const char *me,const char *who, int checksum) {}
979
980void ext_yahoo_got_buddyicon_request(int id, const char *me, const char *who){}
981void ext_yahoo_buddyicon_uploaded(int id, const char *url){}
Note: See TracBrowser for help on using the repository browser.