source: protocols/yahoo/yahoo.c @ cfc8d58

Last change on this file since cfc8d58 was cfc8d58, checked in by Wilmer van der Gaast <wilmer@…>, at 2007-04-16T04:31:52Z

Updating the Yahoo! module. This seems to fix handling of incoming away
states/messages, should fix some issues with group chats, and unfortunately
also adds some crap which I don't want to clean up for now.

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