source: protocols/yahoo/yahoo.c @ 4049061

Last change on this file since 4049061 was 4049061, checked in by Wilmer van der Gaast <wilmer@…>, at 2010-03-06T17:10:32Z

Fixed up Yahoo! I'll have to do some more thorough testing of this code
since I may have broken something.

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