source: protocols/yahoo/yahoo.c @ 9034ba0

Last change on this file since 9034ba0 was 9034ba0, checked in by Wilmer van der Gaast <wilmer@…>, at 2010-07-24T10:57:08Z

Merge complete. It still logs in...

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