source: protocols/yahoo/yahoo.c @ 0c78bb7

Last change on this file since 0c78bb7 was b38f655, checked in by dequis <dx@…>, at 2015-05-28T05:26:30Z

Rename mail notification related settings for consistency

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