source: protocols/yahoo/yahoo.c @ 94e7eb3

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