source: protocols/yahoo/yahoo.c @ fc34fb5

Last change on this file since fc34fb5 was 673a54c, checked in by Sven Moritz Hallberg <pesco@…>, at 2009-03-12T19:33:28Z

pretty blind try at merging in the latest trunk

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