source: protocols/yahoo/yahoo.c @ 8ba511d

Last change on this file since 8ba511d was d2cbe0a, checked in by Wilmer van der Gaast <wilmer@…>, at 2006-01-14T17:10:15Z

Fixed Yahoo! invisible status. (Thanks to a patch someone posted on FreshMeat some time ago.)

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