source: protocols/yahoo/yahoo.c @ 0714d51

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

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

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