# HG changeset patch # User Eric Warmenhoven # Date 1005091104 0 # Node ID 37d80035e77fac8c11bcc08e91378e55dff58e11 # Parent ab2ca2770d2e9765f9a230bac17c126881191cdc [gaim-migrate @ 2694] don't ask. committer: Tailor Script diff -r ab2ca2770d2e -r 37d80035e77f ChangeLog --- a/ChangeLog Tue Nov 06 21:30:31 2001 +0000 +++ b/ChangeLog Tue Nov 06 23:58:24 2001 +0000 @@ -2,6 +2,7 @@ version 0.48: * Right-click on links to open/copy URL + * Yahoo changes version 0.47 (11/01/2001): * Better font loading (pays attention to charset now) diff -r ab2ca2770d2e -r 37d80035e77f src/buddy.c --- a/src/buddy.c Tue Nov 06 21:30:31 2001 +0000 +++ b/src/buddy.c Tue Nov 06 23:58:24 2001 +0000 @@ -999,6 +999,7 @@ * we change the group that the buddy is in */ struct group *old_g, *new_g = (struct group *)ptype; struct buddy *s = NULL, *buddy = (struct buddy *)ctype; + gboolean add = FALSE; int pos; if (buddy->gc != new_g->gc) { @@ -1015,7 +1016,7 @@ og->members = g_slist_remove(og->members, a); } else { /* we don't have this buddy yet; let's add him */ - serv_add_buddy(new_g->gc, buddy->name); + add = TRUE; } } @@ -1035,6 +1036,10 @@ } else new_g->members = g_slist_append(new_g->members, buddy); + /* we do the add after it's added locally so that prpls can find it if necessary */ + if (add) + serv_add_buddy(new_g->gc, buddy->name); + do_export(buddy->gc); if (buddy->gc != new_g->gc) { do_export(new_g->gc); @@ -1245,7 +1250,7 @@ b = (struct buddy *)type; g = find_group_by_buddy(b->gc, b->name); gct = b->gc; - serv_remove_buddy(b->gc, b->name); + serv_remove_buddy(b->gc, b->name, g->name); remove_buddy(b->gc, g, b); gtk_ctree_remove_node(GTK_CTREE(edittree), node); do_export(gct); diff -r ab2ca2770d2e -r 37d80035e77f src/conversation.c --- a/src/conversation.c Tue Nov 06 21:30:31 2001 +0000 +++ b/src/conversation.c Tue Nov 06 23:58:24 2001 +0000 @@ -538,17 +538,17 @@ void add_callback(GtkWidget *widget, struct conversation *c) { - if (c->gc && find_buddy(c->gc, c->name) != NULL) { + struct buddy *b = find_buddy(c->gc, c->name); + if (b) { + struct group *g = find_group_by_buddy(c->gc, c->name); debug_printf(_("Removing '%s' from buddylist.\n"), c->name); - serv_remove_buddy(c->gc, c->name); - remove_buddy(c->gc, find_group_by_buddy(c->gc, c->name), find_buddy(c->gc, c->name)); + serv_remove_buddy(c->gc, c->name, g->name); + remove_buddy(c->gc, g, b); do_export(c->gc); build_edit_tree(); update_convo_add_button(c); - } else { - if (c->gc) - show_add_buddy(c->gc, c->name, NULL, NULL); - } + } else if (c->gc) + show_add_buddy(c->gc, c->name, NULL, NULL); gtk_widget_grab_focus(c->entry); } diff -r ab2ca2770d2e -r 37d80035e77f src/dialogs.c --- a/src/dialogs.c Tue Nov 06 21:30:31 2001 +0000 +++ b/src/dialogs.c Tue Nov 06 23:58:24 2001 +0000 @@ -3767,13 +3767,32 @@ { char *new_name; struct buddy *b; + GSList *gr; new_name = gtk_entry_get_text(GTK_ENTRY(entry)); b = gtk_object_get_user_data(obj); + if (!g_slist_find(connections, b->gc)) { + destroy_dialog(rename_bud_dialog, rename_bud_dialog); + return; + } + + gr = b->gc->groups; + while (gr) { + if (g_slist_find(((struct group *)gr->data)->members, b)) + break; + gr = gr->next; + } + if (!gr) { + destroy_dialog(rename_bud_dialog, rename_bud_dialog); + return; + } + if (new_name && (strlen(new_name) != 0) && strcmp(new_name, b->name)) { + struct group *g = find_group_by_buddy(b->gc, b->name); char *prevname = g_strdup(b->name); - serv_remove_buddy(b->gc, b->name); + if (g) + serv_remove_buddy(b->gc, b->name, g->name); if (!strcmp(b->name, b->show)) g_snprintf(b->show, sizeof(b->show), "%s", new_name); g_snprintf(b->name, sizeof(b->name), "%s", new_name); diff -r ab2ca2770d2e -r 37d80035e77f src/gaim.h --- a/src/gaim.h Tue Nov 06 21:30:31 2001 +0000 +++ b/src/gaim.h Tue Nov 06 23:58:24 2001 +0000 @@ -362,8 +362,8 @@ extern void serv_change_passwd(struct gaim_connection *, char *, char *); extern void serv_add_buddy(struct gaim_connection *, char *); extern void serv_add_buddies(struct gaim_connection *, GList *); -extern void serv_remove_buddy(struct gaim_connection *, char *); -extern void serv_remove_buddies(struct gaim_connection *, GList *); +extern void serv_remove_buddy(struct gaim_connection *, char *, char *); +extern void serv_remove_buddies(struct gaim_connection *, GList *, char *); extern void serv_add_permit(struct gaim_connection *, char *); extern void serv_add_deny(struct gaim_connection *, char *); extern void serv_rem_permit(struct gaim_connection *, char *); diff -r ab2ca2770d2e -r 37d80035e77f src/list.c --- a/src/list.c Tue Nov 06 21:30:31 2001 +0000 +++ b/src/list.c Tue Nov 06 23:58:24 2001 +0000 @@ -86,7 +86,7 @@ gc->groups = g_slist_remove(gc->groups, delg); - serv_remove_buddies(gc, tmp); + serv_remove_buddies(gc, tmp, rem_g->name); while (tmp) { g_free(tmp->data); tmp = g_list_remove(tmp, tmp->data); diff -r ab2ca2770d2e -r 37d80035e77f src/protocols/gg/gg.c --- a/src/protocols/gg/gg.c Tue Nov 06 21:30:31 2001 +0000 +++ b/src/protocols/gg/gg.c Tue Nov 06 23:58:24 2001 +0000 @@ -1,6 +1,6 @@ /* * gaim - Gadu-Gadu Protocol Plugin - * $Id: gg.c 2576 2001-10-21 00:14:41Z robflynn $ + * $Id: gg.c 2694 2001-11-06 23:58:24Z warmenhoven $ * * Copyright (C) 2001, Arkadiusz Mi¶kiewicz * @@ -616,7 +616,7 @@ gg_add_notify(gd->sess, strtol(who, (char **)NULL, 10)); } -static void agg_rem_buddy(struct gaim_connection *gc, char *who) +static void agg_rem_buddy(struct gaim_connection *gc, char *who, char *group) { struct agg_data *gd = (struct agg_data *)gc->proto_data; if (invalid_uin(who)) diff -r ab2ca2770d2e -r 37d80035e77f src/protocols/icq/gaim_icq.c --- a/src/protocols/icq/gaim_icq.c Tue Nov 06 21:30:31 2001 +0000 +++ b/src/protocols/icq/gaim_icq.c Tue Nov 06 23:58:24 2001 +0000 @@ -386,7 +386,7 @@ } } -static void icq_rem_buddy(struct gaim_connection *gc, char *who) { +static void icq_rem_buddy(struct gaim_connection *gc, char *who, char *group) { struct icq_data *id = (struct icq_data *)gc->proto_data; icq_ContactRemove(id->link, atol(who)); } diff -r ab2ca2770d2e -r 37d80035e77f src/protocols/irc/irc.c --- a/src/protocols/irc/irc.c Tue Nov 06 21:30:31 2001 +0000 +++ b/src/protocols/irc/irc.c Tue Nov 06 23:58:24 2001 +0000 @@ -1338,7 +1338,8 @@ } /* IRC doesn't have a buddy list, but we can still figure out who's online with ISON */ -static void irc_fake_buddy(struct gaim_connection *gc, char *who) {} +static void irc_add_buddy(struct gaim_connection *gc, char *who) {} +static void irc_remove_buddy(struct gaim_connection *gc, char *who, char *group) {} static GList *irc_chat_info(struct gaim_connection *gc) { @@ -1461,8 +1462,8 @@ ret->login = irc_login; ret->close = irc_close; ret->send_im = irc_send_im; - ret->add_buddy = irc_fake_buddy; - ret->remove_buddy = irc_fake_buddy; + ret->add_buddy = irc_add_buddy; + ret->remove_buddy = irc_remove_buddy; ret->chat_info = irc_chat_info; ret->join_chat = irc_join_chat; ret->chat_leave = irc_chat_leave; diff -r ab2ca2770d2e -r 37d80035e77f src/protocols/jabber/jabber.c --- a/src/protocols/jabber/jabber.c Tue Nov 06 21:30:31 2001 +0000 +++ b/src/protocols/jabber/jabber.c Tue Nov 06 23:58:24 2001 +0000 @@ -1301,7 +1301,7 @@ g_free(realwho); } -static void jabber_remove_buddy(struct gaim_connection *gc, char *name) +static void jabber_remove_buddy(struct gaim_connection *gc, char *name, char *group) { xmlnode x, y; char *realwho; diff -r ab2ca2770d2e -r 37d80035e77f src/protocols/msn/msn.c --- a/src/protocols/msn/msn.c Tue Nov 06 21:30:31 2001 +0000 +++ b/src/protocols/msn/msn.c Tue Nov 06 23:58:24 2001 +0000 @@ -1511,7 +1511,7 @@ } } -static void msn_rem_buddy(struct gaim_connection *gc, char *who) +static void msn_rem_buddy(struct gaim_connection *gc, char *who, char *group) { struct msn_data *md = gc->proto_data; char buf[MSN_BUF_LEN]; diff -r ab2ca2770d2e -r 37d80035e77f src/protocols/napster/napster.c --- a/src/protocols/napster/napster.c Tue Nov 06 21:30:31 2001 +0000 +++ b/src/protocols/napster/napster.c Tue Nov 06 23:58:24 2001 +0000 @@ -506,7 +506,7 @@ nap_write_packet(gc, 0xCF, name); } -static void nap_remove_buddy(struct gaim_connection *gc, char *name) +static void nap_remove_buddy(struct gaim_connection *gc, char *name, char *group) { nap_write_packet(gc, 0x12F, name); } diff -r ab2ca2770d2e -r 37d80035e77f src/protocols/oscar/oscar.c --- a/src/protocols/oscar/oscar.c Tue Nov 06 21:30:31 2001 +0000 +++ b/src/protocols/oscar/oscar.c Tue Nov 06 23:58:24 2001 +0000 @@ -2291,7 +2291,7 @@ aim_bos_setbuddylist(odata->sess, odata->conn, buf); } -static void oscar_remove_buddy(struct gaim_connection *g, char *name) { +static void oscar_remove_buddy(struct gaim_connection *g, char *name, char *group) { struct oscar_data *odata = (struct oscar_data *)g->proto_data; aim_remove_buddy(odata->sess, odata->conn, name); } diff -r ab2ca2770d2e -r 37d80035e77f src/protocols/toc/toc.c --- a/src/protocols/toc/toc.c Tue Nov 06 21:30:31 2001 +0000 +++ b/src/protocols/toc/toc.c Tue Nov 06 23:58:24 2001 +0000 @@ -1037,7 +1037,7 @@ sflap_send(g, buf, -1, TYPE_DATA); } -static void toc_remove_buddy(struct gaim_connection *g, char *name) +static void toc_remove_buddy(struct gaim_connection *g, char *name, char *group) { char buf[BUF_LEN * 2]; g_snprintf(buf, sizeof(buf), "toc_remove_buddy %s", normalize(name)); @@ -1045,7 +1045,7 @@ toc_set_config(g); } -static void toc_remove_buddies(struct gaim_connection *g, GList *buddies) +static void toc_remove_buddies(struct gaim_connection *g, GList *buddies, char *group) { char buf[BUF_LEN * 2]; int n; diff -r ab2ca2770d2e -r 37d80035e77f src/protocols/yahoo/.cvsignore --- a/src/protocols/yahoo/.cvsignore Tue Nov 06 21:30:31 2001 +0000 +++ b/src/protocols/yahoo/.cvsignore Tue Nov 06 23:58:24 2001 +0000 @@ -10,3 +10,4 @@ outgoing.lo rxhandlers.lo yay.lo +yahoo.lo diff -r ab2ca2770d2e -r 37d80035e77f src/protocols/yahoo/AUTHORS --- a/src/protocols/yahoo/AUTHORS Tue Nov 06 21:30:31 2001 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,9 +0,0 @@ -Eric Warmenhoven - -Most of this code is either based off of or taken from: -libfaim by Adam Fritzler, et al., http://sourceforge.net/projects/libfaim/ -icqlib by Bill Soudan et al., http://sourceforge.net/projects/icqlib/ -libyahoo by Nathan Neulinger et al., http://sourceforge.net/projects/libyahoo/ - -I did not reverse engineer the protocol at all. All of that work was done by -everyone who has worked on libyahoo. diff -r ab2ca2770d2e -r 37d80035e77f src/protocols/yahoo/Makefile.am --- a/src/protocols/yahoo/Makefile.am Tue Nov 06 21:30:31 2001 +0000 +++ b/src/protocols/yahoo/Makefile.am Tue Nov 06 23:58:24 2001 +0000 @@ -11,8 +11,7 @@ pkg_LTLIBRARIES = noinst_LIBRARIES = libyahoo.a -libyahoo_a_SOURCES = \ - buddy.c conn.c internal.h login.c misc.c outgoing.c rxhandlers.c yay.c yay.h +libyahoo_a_SOURCES = yahoo.c else @@ -20,7 +19,6 @@ pkg_LTLIBRARIES = libyahoo.la noinst_LIBRARIES = -libyahoo_la_SOURCES = \ - buddy.c conn.c internal.h login.c misc.c outgoing.c rxhandlers.c yay.c yay.h +libyahoo_la_SOURCES = yahoo.c endif diff -r ab2ca2770d2e -r 37d80035e77f src/protocols/yahoo/buddy.c --- a/src/protocols/yahoo/buddy.c Tue Nov 06 21:30:31 2001 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,157 +0,0 @@ -/* - * libyay - * - * Copyright (C) 2001 Eric Warmenhoven - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include "internal.h" -#include - -int yahoo_add_buddy(struct yahoo_session *session, const char *active_id, - const char *group, const char *buddy, const char *message) -{ - struct yahoo_conn *conn; - char *send; - char *grp, *bdy, *id, *msg = "", *usr; - - if (!session || !active_id || !group || !buddy) - return 0; - - if (!(grp = yahoo_urlencode(group))) - return 0; - if (!(bdy = yahoo_urlencode(buddy))) { - g_free(grp); - return 0; - } - if (!(id = yahoo_urlencode(active_id))) { - g_free(grp); - g_free(bdy); - return 0; - } - if (!(usr = yahoo_urlencode(session->name))) { - g_free(grp); - g_free(bdy); - g_free(id); - return 0; - } - if (message && strlen(message) && !(msg = yahoo_urlencode(message))) { - g_free(grp); - g_free(bdy); - g_free(id); - g_free(usr); - return 0; - } - - send = g_strconcat("GET ", - session->proxy_type ? "http://" : "", - session->proxy_type ? session->auth_host : "", - "/config/set_buddygrp?.bg=", grp, - "&.src=bl&.cmd=a&.bdl=", bdy, - "&.id=", id, - "&.l=", usr, - "&.amsg=", msg, - " HTTP/1.0\r\n", - "User-Agent: " YAHOO_USER_AGENT "\r\n" - "Host: ", session->auth_host, "\r\n" - "Cookie: ", session->cookie, - "\r\n\r\n", NULL); - g_free(grp); - g_free(bdy); - g_free(id); - g_free(usr); - if (message && strlen(message)) - g_free(msg); - - if (!send) - return 0; - - if (!(conn = yahoo_new_conn(session, YAHOO_CONN_TYPE_DUMB, session->auth_host, - session->auth_port))) - return 0; - - conn->txqueue = send; - - return 1; -} - -int yahoo_remove_buddy(struct yahoo_session *session, const char *active_id, - const char *group, const char *buddy, const char *message) -{ - struct yahoo_conn *conn; - char *send; - char *grp, *bdy, *id, *msg = "", *usr; - - if (!session || !active_id || !group || !buddy) - return 0; - - if (!(grp = yahoo_urlencode(group))) - return 0; - if (!(bdy = yahoo_urlencode(buddy))) { - g_free(grp); - return 0; - } - if (!(id = yahoo_urlencode(active_id))) { - g_free(grp); - g_free(bdy); - return 0; - } - if (!(usr = yahoo_urlencode(session->name))) { - g_free(grp); - g_free(bdy); - g_free(id); - return 0; - } - if (message && strlen(message) && !(msg = yahoo_urlencode(message))) { - g_free(grp); - g_free(bdy); - g_free(id); - g_free(usr); - return 0; - } - - send = g_strconcat("GET ", - session->proxy_type ? "http://" : "", - session->proxy_type ? session->auth_host : "", - "/config/set_buddygrp?.bg=", grp, - "&.src=bl&.cmd=d&.bdl=", bdy, - "&.id=", id, - "&.l=", usr, - "&.amsg=", msg, - " HTTP/1.0\r\n", - "User-Agent: " YAHOO_USER_AGENT "\r\n" - "Host: ", session->auth_host, "\r\n" - "Cookie: ", session->cookie, - "\r\n\r\n", NULL); - g_free(grp); - g_free(bdy); - g_free(id); - g_free(usr); - if (message && strlen(message)) - g_free(msg); - - if (!send) - return 0; - - if (!(conn = yahoo_new_conn(session, YAHOO_CONN_TYPE_DUMB, session->auth_host, - session->auth_port))) - return 0; - - conn->txqueue = send; - - return 1; -} diff -r ab2ca2770d2e -r 37d80035e77f src/protocols/yahoo/conn.c --- a/src/protocols/yahoo/conn.c Tue Nov 06 21:30:31 2001 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,321 +0,0 @@ -/* - * libyay - * - * Copyright (C) 2001 Eric Warmenhoven - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include -#include "internal.h" - -void (*yahoo_socket_notify)(struct yahoo_session *, int, int, gboolean) = NULL; -void (*yahoo_print)(struct yahoo_session *, int, const char *) = NULL; -int (*yahoo_connector)(struct yahoo_session *, const char *, int, gpointer) = NULL; - -struct yahoo_session *yahoo_new() -{ - struct yahoo_session *sess; - - if (!(sess = g_new0(struct yahoo_session, 1))) - return NULL; - - return sess; -} - -void yahoo_set_proxy(struct yahoo_session *session, int proxy_type, char *proxy_host, int proxy_port) -{ - if (!session || !proxy_type || !proxy_host) - return; - - session->proxy_type = proxy_type; - session->proxy_host = g_strdup(proxy_host); - session->proxy_port = proxy_port; -} - -static int yahoo_connect_host(struct yahoo_session *sess, const char *host, int port, int *statusret) -{ - struct sockaddr_in sa; - struct hostent *hp; - int fd; - - if (!(hp = gethostbyname(host))) { - YAHOO_PRINT(sess, YAHOO_LOG_WARNING, "Resolve error"); - if (statusret) - *statusret = (h_errno | YAHOO_CONN_STATUS_RESOLVERR); - return -1; - } - - memset(&sa, 0, sizeof(struct sockaddr_in)); - sa.sin_port = htons(port); - memcpy(&sa.sin_addr, hp->h_addr, hp->h_length); - sa.sin_family = hp->h_addrtype; - - fd = socket(hp->h_addrtype, SOCK_STREAM, 0); - - fcntl(fd, F_SETFL, O_NONBLOCK); - - if (connect(fd, (struct sockaddr *)&sa, sizeof(struct sockaddr_in)) < 0) { - if ((errno == EINPROGRESS) || (errno == EINTR)) { - YAHOO_PRINT(sess, YAHOO_LOG_NOTICE, "Connect would block"); - if (statusret) - *statusret |= YAHOO_CONN_STATUS_INPROGRESS; - return fd; - } - close(fd); - fd = -1; - } - - return fd; -} - -int yahoo_connected(struct yahoo_session *session, gpointer data, int fd) -{ - struct yahoo_conn *conn = data; - - if (fd < 0) { - YAHOO_PRINT(session, YAHOO_LOG_WARNING, "connect failed"); - session->connlist = g_list_remove(session->connlist, conn); - g_free(conn); - return 0; - } - - YAHOO_PRINT(session, YAHOO_LOG_NOTICE, "connect succeeded"); - conn->socket = fd; - conn->connected = TRUE; - if (conn->type == YAHOO_CONN_TYPE_AUTH) { - if (session->callbacks[YAHOO_HANDLE_AUTHCONNECT].function) - if (!(*session->callbacks[YAHOO_HANDLE_AUTHCONNECT].function)(session)) - return 0; - } else if (conn->type == YAHOO_CONN_TYPE_MAIN) { - if (session->callbacks[YAHOO_HANDLE_MAINCONNECT].function) - if (!(*session->callbacks[YAHOO_HANDLE_MAINCONNECT].function)(session)) - return 0; - } else if (conn->type == YAHOO_CONN_TYPE_DUMB) { - YAHOO_PRINT(session, YAHOO_LOG_DEBUG, "sending to buddy list host"); - yahoo_write(session, conn, conn->txqueue, strlen(conn->txqueue)); - g_free(conn->txqueue); - conn->txqueue = NULL; - } - - if (yahoo_socket_notify) - (*yahoo_socket_notify)(session, conn->socket, YAHOO_SOCKET_READ, TRUE); - else - YAHOO_PRINT(session, YAHOO_LOG_CRITICAL, "yahoo_socket_notify not set up"); - - return 1; -} - -struct yahoo_conn *yahoo_new_conn(struct yahoo_session *session, int type, const char *host, int port) -{ - struct yahoo_conn *conn; - int status; - - if (!session) - return NULL; - - conn = g_new0(struct yahoo_conn, 1); - conn->type = type; - - if (yahoo_connector) { - YAHOO_PRINT(session, YAHOO_LOG_DEBUG, "Connecting using user-specified connect routine"); - if ((*yahoo_connector)(session, host, port, conn) < 0) { - YAHOO_PRINT(session, YAHOO_LOG_CRITICAL, "connect failed"); - g_free(conn); - return NULL; - } - session->connlist = g_list_append(session->connlist, conn); - return conn; - } - - if (session->proxy_type) { - YAHOO_PRINT(session, YAHOO_LOG_DEBUG, "connecting to proxy"); - conn->socket = yahoo_connect_host(session, session->proxy_host, - session->proxy_port, &status); - if (type == YAHOO_CONN_TYPE_MAIN) - conn->type = YAHOO_CONN_TYPE_PROXY; - } else - conn->socket = yahoo_connect_host(session, host, port, &status); - - if (conn->socket < 0) { - g_free(conn); - return NULL; - } - - if (yahoo_socket_notify) - (*yahoo_socket_notify)(session, conn->socket, YAHOO_SOCKET_WRITE, TRUE); - else - YAHOO_PRINT(session, YAHOO_LOG_CRITICAL, "yahoo_socket_notify not set up"); - - session->connlist = g_list_append(session->connlist, conn); - - return conn; -} - -struct yahoo_conn *yahoo_getconn_type(struct yahoo_session *sess, int type) -{ - GList *c; - struct yahoo_conn *conn; - - if (!sess) - return NULL; - - c = sess->connlist; - while (c) { - conn = c->data; - if (conn->type == type) - return conn; - c = g_list_next(c); - } - - return NULL; -} - -struct yahoo_conn *yahoo_find_conn(struct yahoo_session *sess, int socket) -{ - GList *c; - struct yahoo_conn *conn; - - c = sess->connlist; - while (c) { - conn = c->data; - if (conn->socket == socket) - return conn; - c = g_list_next(c); - } - - return NULL; -} - -int yahoo_connect(struct yahoo_session *session, const char *host, int port) -{ - if (!session) - return 0; - - if (session->auth_host) - g_free(session->auth_host); - if (host && *host) - session->auth_host = g_strdup(host); - else - session->auth_host = g_strdup(YAHOO_AUTH_HOST); - - if (port) - session->auth_port = port; - else - session->auth_port = YAHOO_AUTH_PORT; - - if (!yahoo_new_conn(session, YAHOO_CONN_TYPE_AUTH, session->auth_host, session->auth_port)) - return 0; - - return 1; -} - -int yahoo_major_connect(struct yahoo_session *session, const char *host, int port) -{ - if (!session) - return 0; - - if (session->pager_host) - g_free(session->pager_host); - if (host && *host) - session->pager_host = g_strdup(host); - else - session->pager_host = g_strdup(YAHOO_PAGER_HOST); - - if (port) - session->pager_port = port; - else - session->pager_port = YAHOO_AUTH_PORT; - - if (!yahoo_new_conn(session, YAHOO_CONN_TYPE_MAIN, session->pager_host, session->pager_port)) - return 0; - - return 1; -} - -void yahoo_close(struct yahoo_session *session, struct yahoo_conn *conn) -{ - if (!session || !conn) - return; - - if (!g_list_find(session->connlist, conn)) - return; - - if (yahoo_socket_notify) { - if (conn->connected) - (*yahoo_socket_notify)(session, conn->socket, YAHOO_SOCKET_READ, FALSE); - else - (*yahoo_socket_notify)(session, conn->socket, YAHOO_SOCKET_WRITE, FALSE); - } - close(conn->socket); - - session->connlist = g_list_remove(session->connlist, conn); - if (conn->txqueue) - g_free(conn->txqueue); - g_free(conn); -} - -int yahoo_disconnect(struct yahoo_session *session) -{ - if (!session) - return 0; - yahoo_logoff(session); - if (session->name) - g_free(session->name); - session->name = NULL; - while (session->connlist) - yahoo_close(session, session->connlist->data); - if (session->cookie) - g_free(session->cookie); - session->cookie = NULL; - if (session->login_cookie) - g_free(session->login_cookie); - session->login_cookie = NULL; - while (session->ignored) { - g_free(session->ignored->data); - session->ignored = g_list_remove(session->ignored, session->ignored->data); - } - if (session->identities) - g_strfreev(session->identities); - session->identities = NULL; - if (session->login) - g_free(session->login); - session->login = NULL; - while (session->groups) { - struct yahoo_group *grp = session->groups->data; - g_strfreev(grp->buddies); - g_free(grp->name); - g_free(grp); - session->groups = g_list_remove(session->groups, grp); - } - if (session->auth_host) - g_free(session->auth_host); - session->auth_host = NULL; - if (session->pager_host) - g_free(session->pager_host); - session->pager_host = NULL; - return 0; -} - -int yahoo_delete(struct yahoo_session *session) -{ - if (!session) - return 0; - if (session->proxy_host) - g_free(session->proxy_host); - g_free(session); - return 0; -} diff -r ab2ca2770d2e -r 37d80035e77f src/protocols/yahoo/internal.h --- a/src/protocols/yahoo/internal.h Tue Nov 06 21:30:31 2001 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,95 +0,0 @@ -/* - * libyay - * - * Copyright (C) 2001 Eric Warmenhoven - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifndef _LIBYAY_INTERNAL_H -#define _LIBYAY_INTERNAL_H - -#include "yay.h" - -#define YAHOO_CONN_STATUS_RESOLVERR 0x0040 -#define YAHOO_CONN_STATUS_INPROGRESS 0x0100 - -#define YAHOO_USER_AGENT "Mozilla/4.6 (libyay/1.0)" - -#define YAHOO_PRINT(x, y, z) if (yahoo_print) (*yahoo_print)(x, y, z) - -struct yahoo_conn { - int type; - int socket; - int magic_id; - gboolean connected; - char *txqueue; -}; - -#define YAHOO_CONN_TYPE_AUTH 1 -#define YAHOO_CONN_TYPE_MAIN 2 -#define YAHOO_CONN_TYPE_DUMB 3 -#define YAHOO_CONN_TYPE_PROXY 4 - -#define HTTP_GOODSTRING1 "HTTP/1.0 200 Connection established" -#define HTTP_GOODSTRING2 "HTTP/1.1 200 Connection established" - -char *yahoo_urlencode(const char *); -struct yahoo_conn *yahoo_new_conn(struct yahoo_session *, int, const char *, int); -struct yahoo_conn *yahoo_getconn_type(struct yahoo_session *, int); -struct yahoo_conn *yahoo_find_conn(struct yahoo_session *, int); -int yahoo_write(struct yahoo_session *, struct yahoo_conn *, void *, int); -int yahoo_write_cmd(struct yahoo_session *, struct yahoo_conn *, int, const char *, void *, guint); -void yahoo_close(struct yahoo_session *, struct yahoo_conn *); - -#define YAHOO_SERVICE_LOGON 1 -#define YAHOO_SERVICE_LOGOFF 2 -#define YAHOO_SERVICE_ISAWAY 3 -#define YAHOO_SERVICE_ISBACK 4 -#define YAHOO_SERVICE_IDLE 5 -#define YAHOO_SERVICE_MESSAGE 6 -#define YAHOO_SERVICE_IDACT 7 -#define YAHOO_SERVICE_IDDEACT 8 -#define YAHOO_SERVICE_NEWMAIL 11 -#define YAHOO_SERVICE_NEWPERSONALMAIL 14 -#define YAHOO_SERVICE_NEWCONTACT 15 -#define YAHOO_SERVICE_PING 18 - -#define YAHOO_MESSAGE_NORMAL 1 -#define YAHOO_MESSAGE_BOUNCE 2 -#define YAHOO_MESSAGE_OFFLINE 5 -#define YAHOO_MESSAGE_SEND 1515563606 - -void yahoo_storeint(guchar *, guint); -int yahoo_makeint(guchar *); - -struct yahoo_packet { - char version[8]; - guchar len[4]; - guchar service[4]; - - guchar conn_id[4]; - guchar magic_id[4]; - guchar address[4]; - guchar msgtype[4]; - - char nick1[36]; - char nick2[36]; - - char content[1024]; -}; - -#endif diff -r ab2ca2770d2e -r 37d80035e77f src/protocols/yahoo/login.c --- a/src/protocols/yahoo/login.c Tue Nov 06 21:30:31 2001 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,95 +0,0 @@ -/* - * libyay - * - * Copyright (C) 2001 Eric Warmenhoven - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include "internal.h" -#include - -int yahoo_send_login(struct yahoo_session *session, const char *name, const char *password) -{ - char *buf = g_malloc(1024 + strlen(name) + strlen(password)); - char *a, *b; - int at; - struct yahoo_conn *conn; - - if (!buf) - return 0; - - if (!(conn = yahoo_getconn_type(session, YAHOO_CONN_TYPE_AUTH))) - return 0; - - if (!(a = yahoo_urlencode(name))) - return 0; - if (!(b = yahoo_urlencode(password))) { - g_free(a); - return 0; - } - - at = g_snprintf(buf, 1024 + strlen(name) + strlen(password), - "GET %s%s/config/ncclogin?login=%s&passwd=%s&n=1 HTTP/1.0\r\n" - "User-Agent: " YAHOO_USER_AGENT "\r\n" - "Host: %s\r\n\r\n", - session->proxy_type ? "http://" : "", - session->proxy_type ? session->auth_host : "", - a, b, session->auth_host); - - g_free(a); - g_free(b); - - if (yahoo_write(session, conn, buf, at) != at) { - g_free(buf); - return 0; - } - - g_free(buf); - session->name = g_strdup(name); - return at; -} - -int yahoo_finish_logon(struct yahoo_session *session, enum yahoo_status status) -{ - char *buf = NULL, *tmp = NULL; - int ret; - struct yahoo_conn *conn; - - if (!session || !session->login_cookie) - return 0; - - if (!(conn = yahoo_getconn_type(session, YAHOO_CONN_TYPE_MAIN))) - return 0; - - if (session->identities) { - if (!(tmp = g_strjoinv(",", session->identities))) - return 0; - } else - tmp = ""; - - if (!(buf = g_strconcat(session->login_cookie, "\001", session->name, tmp, NULL))) { - g_free(tmp); - return 0; - } - - ret = yahoo_write_cmd(session, conn, YAHOO_SERVICE_LOGON, session->name, buf, status); - g_free(buf); - if (session->identities) - g_free(tmp); - - return ret; -} diff -r ab2ca2770d2e -r 37d80035e77f src/protocols/yahoo/misc.c --- a/src/protocols/yahoo/misc.c Tue Nov 06 21:30:31 2001 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,69 +0,0 @@ -/* - * libyay - * - * Copyright (C) 2001 Eric Warmenhoven - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include "internal.h" -#include -#include - -char *yahoo_urlencode(const char *str) -{ - int len; - char *ret; - const char *s; - char *r; - - if ((len = strlen(str)) == 0) - return NULL; - - ret = g_malloc(len * 3 + 1); - if (!ret) - return NULL; - - for (s = str, r = ret; *s; s++) { - if (isdigit(*s) || isalpha(*s) || *s == '_') - *r++ = *s; - else { - int tmp = *s / 16; - *r++ = '%'; - *r++ = (tmp < 10) ? (tmp + '0') : (tmp - 10 + 'A'); - tmp = *s % 16; - *r++ = (tmp < 10) ? (tmp + '0') : (tmp - 10 + 'A'); - } - } - - *r = '\0'; - - return ret; -} - -int yahoo_makeint(guchar *buf) -{ - return ((buf[3] << 24) + (buf[2] << 16) + (buf[1] << 8) + buf[0]); -} - -void yahoo_storeint(guchar *buf, guint data) -{ - int i; - for (i = 0; i < 4; i++) { - buf[i] = data % 256; - data >>= 8; - } -} diff -r ab2ca2770d2e -r 37d80035e77f src/protocols/yahoo/outgoing.c --- a/src/protocols/yahoo/outgoing.c Tue Nov 06 21:30:31 2001 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,206 +0,0 @@ -/* - * libyay - * - * Copyright (C) 2001 Eric Warmenhoven - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include "internal.h" -#include - -int yahoo_write(struct yahoo_session *session, struct yahoo_conn *conn, void *buf, int len) -{ - if (!session || !conn) - return 0; - - if (!g_list_find(session->connlist, conn)) - return 0; - - if (send(conn->socket, buf, len, 0) != len) { - int type = conn->type; - yahoo_close(session, conn); - YAHOO_PRINT(session, YAHOO_LOG_CRITICAL, "error sending"); - if (type == YAHOO_CONN_TYPE_DUMB) - if (session->callbacks[YAHOO_HANDLE_DISCONNECT].function) - (*session->callbacks[YAHOO_HANDLE_DISCONNECT].function)(session); - return 0; - } - - return len; -} - -int yahoo_write_cmd(struct yahoo_session *session, struct yahoo_conn *conn, - int service, const char *active_id, void *buf, guint msgtype) -{ - struct yahoo_packet *pkt; - int ret; - - if (!session || !session->login || !conn || !active_id) - return 0; - - if (!(pkt = g_new0(struct yahoo_packet, 1))) - return 0; - - strcpy(pkt->version, "YPNS2.0"); - yahoo_storeint(pkt->len, sizeof(struct yahoo_packet)); - yahoo_storeint(pkt->service, service); - - yahoo_storeint(pkt->magic_id, conn->magic_id); - yahoo_storeint(pkt->msgtype, msgtype); - - strcpy(pkt->nick1, session->login); - strcpy(pkt->nick2, active_id); - - strncpy(pkt->content, buf, 1024); - - ret = yahoo_write(session, conn, pkt, sizeof(struct yahoo_packet)); - g_free(pkt); - return ret; -} - -int yahoo_activate_id(struct yahoo_session *session, char *id) -{ - struct yahoo_conn *conn; - - if (!session || !id) - return 0; - - if (!(conn = yahoo_getconn_type(session, YAHOO_CONN_TYPE_MAIN))) - return 0; - - return yahoo_write_cmd(session, conn, YAHOO_SERVICE_IDACT, id, id, 0); -} - -int yahoo_deactivate_id(struct yahoo_session *session, char *id) -{ - struct yahoo_conn *conn; - - if (!session || !id) - return 0; - - if (!(conn = yahoo_getconn_type(session, YAHOO_CONN_TYPE_MAIN))) - return 0; - - return yahoo_write_cmd(session, conn, YAHOO_SERVICE_IDDEACT, id, id, 0); -} - -int yahoo_send_message(struct yahoo_session *session, const char *active_id, - const char *user, const char *msg) -{ - struct yahoo_conn *conn; - char *buf; - int ret; - - if (!session || !user || !msg) - return 0; - - if (!(conn = yahoo_getconn_type(session, YAHOO_CONN_TYPE_MAIN))) - return 0; - - if (!(buf = g_strconcat(user, ",", msg, NULL))) - return 0; - - ret = yahoo_write_cmd(session, conn, YAHOO_SERVICE_MESSAGE, - active_id ? active_id : session->name, buf, 0); - g_free(buf); - - return ret; -} - -int yahoo_send_message_offline(struct yahoo_session *session, const char *active_id, - const char *user, const char *msg) -{ - struct yahoo_conn *conn; - char *buf; - int ret; - - if (!session || !user || !msg) - return 0; - - if (!(conn = yahoo_getconn_type(session, YAHOO_CONN_TYPE_MAIN))) - return 0; - - if (!(buf = g_strconcat(user, ",", msg, NULL))) - return 0; - - ret = yahoo_write_cmd(session, conn, YAHOO_SERVICE_MESSAGE, - active_id ? active_id : session->name, buf, YAHOO_MESSAGE_SEND); - g_free(buf); - - return ret; -} - -int yahoo_logoff(struct yahoo_session *session) -{ - struct yahoo_conn *conn; - - if (!session) - return 0; - - if (!session->login) - return 0; - - if (!(conn = yahoo_getconn_type(session, YAHOO_CONN_TYPE_MAIN))) - return 0; - - return yahoo_write_cmd(session, conn, YAHOO_SERVICE_LOGOFF, session->name, session->name, 0); -} - -int yahoo_ping(struct yahoo_session *session) -{ - struct yahoo_conn *conn; - - if (!session) - return 0; - - if (!(conn = yahoo_getconn_type(session, YAHOO_CONN_TYPE_MAIN))) - return 0; - - return yahoo_write_cmd(session, conn, YAHOO_SERVICE_PING, session->name, "", 0); -} - -int yahoo_away(struct yahoo_session *session, enum yahoo_status status, char *msg) -{ - struct yahoo_conn *conn; - char buf[1024]; - - if (!session) - return 0; - - if (!(conn = yahoo_getconn_type(session, YAHOO_CONN_TYPE_MAIN))) - return 0; - - g_snprintf(buf, sizeof(buf), "%d%c%s", status, 1, msg ? msg : "---"); - - return yahoo_write_cmd(session, conn, YAHOO_SERVICE_ISAWAY, session->name, buf, 0); -} - -int yahoo_back(struct yahoo_session *session, enum yahoo_status status, char *msg) -{ - struct yahoo_conn *conn; - char buf[1024]; - - if (!session) - return 0; - - if (!(conn = yahoo_getconn_type(session, YAHOO_CONN_TYPE_MAIN))) - return 0; - - g_snprintf(buf, sizeof(buf), "%d%c%s", status, 1, msg ? msg : "---"); - - return yahoo_write_cmd(session, conn, YAHOO_SERVICE_ISBACK, session->name, buf, 0); -} diff -r ab2ca2770d2e -r 37d80035e77f src/protocols/yahoo/rxhandlers.c --- a/src/protocols/yahoo/rxhandlers.c Tue Nov 06 21:30:31 2001 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,472 +0,0 @@ -/* - * libyay - * - * Copyright (C) 2001 Eric Warmenhoven - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include "internal.h" -#include -#include -#include - -static void yahoo_parse_config(struct yahoo_session *session, struct yahoo_conn *conn, char *buf) -{ - char **str_array = g_strsplit(buf, "\n", 1024); - char **it; - int state = 0; - - for (it = str_array; *it; it++) { - if (!**it) continue; - if (!strncmp(*it, "ERROR", strlen("ERROR"))) { - yahoo_close(session, conn); - if (session->callbacks[YAHOO_HANDLE_BADPASSWORD].function) - (*session->callbacks[YAHOO_HANDLE_BADPASSWORD].function)(session); - return; - } else if (!strncmp(*it, "Set-Cookie: Y=", strlen("Set-Cookie: Y="))) { - char **sa; - char **m; - - char *end = strchr(*it, ';'); - if (session->cookie) - g_free(session->cookie); - session->cookie = g_strndup(*it + strlen("Set-Cookie: "), - end - *it - strlen("Set-Cookie: ")); - YAHOO_PRINT(session, YAHOO_LOG_DEBUG, session->cookie); - if (!session->cookie) { - yahoo_close(session, conn); - YAHOO_PRINT(session, YAHOO_LOG_ERROR, "did not get cookie"); - if (session->callbacks[YAHOO_HANDLE_DISCONNECT].function) - (*session->callbacks[YAHOO_HANDLE_DISCONNECT].function)(session); - return; - } - - sa = g_strsplit(session->cookie, "&", 8); - for (m = sa; *m; m++) { - if (!strncmp(*m, "n=", 2)) { - if (session->login_cookie) - g_free(session->login_cookie); - session->login_cookie = g_strdup(*m + 2); - YAHOO_PRINT(session, YAHOO_LOG_DEBUG, session->login_cookie); - } - } - g_strfreev(sa); - } else if (!strncmp(*it, "BEGIN BUDDYLIST", strlen("BEGIN BUDDYLIST"))) { - state = 1; - } else if (!strncmp(*it, "END BUDDYLIST", strlen("END BUDDYLIST"))) { - state = 0; - } else if (!strncmp(*it, "BEGIN IGNORELIST", strlen("BEGIN IGNORELIST"))) { - state = 2; - } else if (!strncmp(*it, "END IGNORELIST", strlen("END IGNORELIST"))) { - state = 0; - } else if (!strncmp(*it, "BEGIN IDENTITIES", strlen("BEGIN IDENTITIES"))) { - state = 3; - } else if (!strncmp(*it, "END IDENTITIES", strlen("END IDENTITIES"))) { - state = 0; - } else if (!strncmp(*it, "Mail=", strlen("Mail="))) { - session->mail = atoi(*it + strlen("Mail=")); - } else if (!strncmp(*it, "Login=", strlen("Login="))) { - if (session->login) - g_free(session->login); - session->login = g_strdup(*it + strlen("Login=")); - } else { - if (state == 1) { - struct yahoo_group *grp = g_new0(struct yahoo_group, 1); - char *end = strchr(*it, ':'); - if (end) { - grp->name = g_strndup(*it, end - *it); - end++; - grp->buddies = g_strsplit(end, ",", 1024); - session->groups = g_list_append(session->groups, grp); - } - } else if (state == 2) { - session->ignored = g_list_append(session->ignored, g_strdup(*it)); - } else if (state == 3) { - session->identities = g_strsplit(*it, ",", 6); - } - } - } - - g_strfreev(str_array); - yahoo_close(session, conn); - if (session->callbacks[YAHOO_HANDLE_LOGINCOOKIE].function) - (*session->callbacks[YAHOO_HANDLE_LOGINCOOKIE].function)(session); -} - -static void yahoo_parse_status(struct yahoo_session *sess, struct yahoo_packet *pkt) -{ - /* OK, I'm going to comment it this time. We either get: - * warmenhoven(99,(test)\001,6634CD3,0,1,0,0) - * or - * 2,smarterchild(0,6634CD3,0,1,0,0),warmenhoven(0,6C8C0C48,0,1,0,0) - * - * in the first case, we only get one person, and we get a bunch of fields. - * in the second case, the number is how many people we got, and then the - * names followed by a bunch of fields, separated by commas. - * - * the fields are: (status, [optional: custom message \001,] session id, ?, pager, chat, game) - * - * the custom message may contain any characters (none are escaped) so we can't split on - * anything in particular. this is what we fucked up with the first time - */ - char *tmp = pkt->content; - int count = 0; - int i; - - if (strstr(pkt->content, "was not AWAY")) - return; - - /* count is the first number, if we got it. */ - while (*tmp && isdigit((int)*tmp)) - count = count * 10 + *tmp++ - '0'; - count = count ? count : 1; - - for (i = 0; i < count && *tmp; i++) { - int status, in_pager, in_chat, in_game; - char *p, *who, *msg = NULL; - - if (*tmp == ',') - tmp++; - - /* who is the person we're getting an update for. there will always be a paren - * after this so we should be OK. if we don't get a paren, we'll just break. */ - who = tmp; - if ((tmp = strchr(who, '(')) == NULL) - break; - *tmp++ = '\0'; - - /* tmp now points to the start of the fields. we'll get the status first. it - * should always be followed by a comma, and if it isn't, we'll just break. */ - if ((p = strchr(tmp, ',')) == NULL) - break; - *p++ = '\0'; - status = atoi(tmp); - tmp = p; - - if (status == YAHOO_STATUS_CUSTOM) { - /* tmp now points to the away message. it should end with "\001,". */ - msg = tmp; - if ((tmp = strstr(msg, "\001,")) == NULL) - break; - *tmp = '\0'; - tmp += 2; - } - - /* tmp now points to the session id. we don't need it. */ - if ((tmp = strchr(tmp, ',')) == NULL) - break; - tmp++; - - /* tmp is at the unknown value. we don't need it. */ - if ((tmp = strchr(tmp, ',')) == NULL) - break; - tmp++; - - /* tmp is at the in_pager value */ - if ((p = strchr(tmp, ',')) == NULL) - break; - *p++ = '\0'; - in_pager = atoi(tmp); - tmp = p; - - /* tmp is at the in_chat value */ - if ((p = strchr(tmp, ',')) == NULL) - break; - *p++ = '\0'; - in_chat = atoi(tmp); - tmp = p; - - /* tmp is at the in_game value. this is the last value, so it should end with - * a parenthesis. */ - if ((p = strchr(tmp, ')')) == NULL) - break; - *p++ = '\0'; - in_game = atoi(tmp); - tmp = p; - - if (sess->callbacks[YAHOO_HANDLE_STATUS].function) - (*sess->callbacks[YAHOO_HANDLE_STATUS].function)(sess, who, status, msg, - in_pager, in_chat, in_game); - } -} - -static void yahoo_parse_message(struct yahoo_session *sess, struct yahoo_packet *pkt) -{ - char buf[256]; - int type = yahoo_makeint(pkt->msgtype); - char *str_array[4]; - char *tmp; - - switch(type) { - case YAHOO_MESSAGE_NORMAL: - str_array[0] = pkt->content; - if ((tmp = strchr(str_array[0], ',')) == NULL) - break; - *tmp++ = '\0'; - str_array[1] = tmp; - if ((tmp = strchr(str_array[1], ',')) == NULL) - break; - *tmp++ = '\0'; - str_array[2] = tmp; - str_array[2][strlen(str_array[2]) - 1] = 0; - if (sess->callbacks[YAHOO_HANDLE_MESSAGE].function) - (*sess->callbacks[YAHOO_HANDLE_MESSAGE].function)(sess, pkt->nick2, - str_array[0], - atol(str_array[1]), - str_array[2]); - break; - case YAHOO_MESSAGE_BOUNCE: - if (sess->callbacks[YAHOO_HANDLE_BOUNCE].function) - (*sess->callbacks[YAHOO_HANDLE_BOUNCE].function)(sess); - break; - case YAHOO_MESSAGE_OFFLINE: - tmp = pkt->content; - if ((tmp = strchr(tmp, ',')) == NULL) - break; - ++tmp; - if ((tmp = strchr(tmp, ',')) == NULL) - break; - str_array[0] = ++tmp; - if ((tmp = strchr(tmp, ',')) == NULL) - break; - *tmp++ = '\0'; - str_array[1] = tmp; - if ((tmp = strchr(tmp, ',')) == NULL) - break; - *tmp++ = '\0'; - str_array[2] = tmp; - if ((tmp = strchr(tmp, ',')) == NULL) - break; - *tmp++ = '\0'; - str_array[3] = tmp; - if (sess->callbacks[YAHOO_HANDLE_MESSAGE].function) - (*sess->callbacks[YAHOO_HANDLE_MESSAGE].function)(sess, str_array[0], - str_array[1], - atol(str_array[2]), - str_array[3]); - break; - default: - g_snprintf(buf, sizeof(buf), "unhandled message type %d", type); - YAHOO_PRINT(sess, YAHOO_LOG_WARNING, buf); - break; - } -} - -static void yahoo_parse_packet(struct yahoo_session *sess, - struct yahoo_conn *conn, struct yahoo_packet *pkt) -{ - char buf[256]; - int service = yahoo_makeint(pkt->service); - conn->magic_id = yahoo_makeint(pkt->magic_id); - g_snprintf(buf, sizeof(buf), "Service %d (msgtype %d): %s", service, - yahoo_makeint(pkt->msgtype), pkt->content); - YAHOO_PRINT(sess, YAHOO_LOG_DEBUG, buf); - switch(service) { - case YAHOO_SERVICE_LOGON: - if (yahoo_makeint(pkt->msgtype) == 0) - if (sess->callbacks[YAHOO_HANDLE_ONLINE].function) - (*sess->callbacks[YAHOO_HANDLE_ONLINE].function)(sess); - case YAHOO_SERVICE_LOGOFF: - case YAHOO_SERVICE_ISAWAY: - case YAHOO_SERVICE_ISBACK: - yahoo_parse_status(sess, pkt); - break; - case YAHOO_SERVICE_NEWCONTACT: - if (yahoo_makeint(pkt->msgtype) == 3) { - char **str_array = g_strsplit(pkt->content, ",", 3); - if (sess->callbacks[YAHOO_HANDLE_BUDDYADDED].function) - (*sess->callbacks[YAHOO_HANDLE_BUDDYADDED].function)(sess, - pkt->nick2, - str_array[0], - atol(str_array[1]), - str_array[2]); - g_strfreev(str_array); - } else - yahoo_parse_status(sess, pkt); - break; - case YAHOO_SERVICE_IDACT: - if (sess->callbacks[YAHOO_HANDLE_ACTIVATE].function) - (*sess->callbacks[YAHOO_HANDLE_ACTIVATE].function)(sess); - break; - case YAHOO_SERVICE_MESSAGE: - yahoo_parse_message(sess, pkt); - break; - case YAHOO_SERVICE_NEWMAIL: - if (sess->callbacks[YAHOO_HANDLE_NEWMAIL].function) - (*sess->callbacks[YAHOO_HANDLE_NEWMAIL].function)(sess, strlen(pkt->content) ? - atoi(pkt->content) : 0); - break; - default: - g_snprintf(buf, sizeof(buf), "unhandled service type %d", service); - YAHOO_PRINT(sess, YAHOO_LOG_WARNING, buf); - break; - } -} - -void yahoo_socket_handler(struct yahoo_session *session, int socket, int type) -{ - int pos = 0; - struct yahoo_conn *conn; - - if (!session) - return; - - if (!(conn = yahoo_find_conn(session, socket))) - return; - - if (type == YAHOO_SOCKET_WRITE) { - int error = ETIMEDOUT, len = sizeof(error); - - if (getsockopt(socket, SOL_SOCKET, SO_ERROR, &error, &len) < 0) - error = errno; - if (error) { - yahoo_close(session, conn); - YAHOO_PRINT(session, YAHOO_LOG_CRITICAL, "unable to connect"); - if (session->callbacks[YAHOO_HANDLE_DISCONNECT].function) - (*session->callbacks[YAHOO_HANDLE_DISCONNECT].function)(session); - return; - } - - fcntl(socket, F_SETFL, 0); - - YAHOO_PRINT(session, YAHOO_LOG_NOTICE, "connected"); - - conn->connected = TRUE; - if (yahoo_socket_notify) - (*yahoo_socket_notify)(session, socket, YAHOO_SOCKET_WRITE, FALSE); - if (yahoo_socket_notify) - (*yahoo_socket_notify)(session, socket, YAHOO_SOCKET_READ, TRUE); - - if (conn->type == YAHOO_CONN_TYPE_AUTH) { - if (session->callbacks[YAHOO_HANDLE_AUTHCONNECT].function) - (*session->callbacks[YAHOO_HANDLE_AUTHCONNECT].function)(session); - } else if (conn->type == YAHOO_CONN_TYPE_MAIN) { - if (session->callbacks[YAHOO_HANDLE_MAINCONNECT].function) - (*session->callbacks[YAHOO_HANDLE_MAINCONNECT].function)(session); - } else if (conn->type == YAHOO_CONN_TYPE_DUMB) { - YAHOO_PRINT(session, YAHOO_LOG_DEBUG, "sending to buddy list host"); - yahoo_write(session, conn, conn->txqueue, strlen(conn->txqueue)); - g_free(conn->txqueue); - conn->txqueue = NULL; - } else if (conn->type == YAHOO_CONN_TYPE_PROXY) { - char buf[1024]; - g_snprintf(buf, sizeof(buf), "CONNECT %s:%d HTTP/1.1\r\n\r\n", - session->pager_host, session->pager_port); - YAHOO_PRINT(session, YAHOO_LOG_DEBUG, buf); - yahoo_write(session, conn, buf, strlen(buf)); - } - - return; - } - - if (conn->type == YAHOO_CONN_TYPE_AUTH) { - char *buf = g_malloc0(5000); - while (read(socket, &buf[pos++], 1) == 1); - if (pos == 1) { - g_free(buf); - yahoo_close(session, conn); - YAHOO_PRINT(session, YAHOO_LOG_CRITICAL, "could not read auth response"); - if (session->callbacks[YAHOO_HANDLE_DISCONNECT].function) - (*session->callbacks[YAHOO_HANDLE_DISCONNECT].function)(session); - return; - } - YAHOO_PRINT(session, YAHOO_LOG_DEBUG, buf); - yahoo_parse_config(session, conn, buf); - g_free(buf); - } else if (conn->type == YAHOO_CONN_TYPE_MAIN) { - struct yahoo_packet pkt; - int len; - - if ((read(socket, &pkt, 8) != 8) || strcmp(pkt.version, "YHOO1.0")) { - yahoo_close(session, conn); - YAHOO_PRINT(session, YAHOO_LOG_CRITICAL, "invalid version type"); - if (session->callbacks[YAHOO_HANDLE_DISCONNECT].function) - (*session->callbacks[YAHOO_HANDLE_DISCONNECT].function)(session); - return; - } - - if (read(socket, &pkt.len, 4) != 4) { - yahoo_close(session, conn); - YAHOO_PRINT(session, YAHOO_LOG_CRITICAL, "could not read length"); - if (session->callbacks[YAHOO_HANDLE_DISCONNECT].function) - (*session->callbacks[YAHOO_HANDLE_DISCONNECT].function)(session); - return; - } - len = yahoo_makeint(pkt.len); - - if (read(socket, &pkt.service, len - 12) != len - 12) { - yahoo_close(session, conn); - YAHOO_PRINT(session, YAHOO_LOG_CRITICAL, "could not read data"); - if (session->callbacks[YAHOO_HANDLE_DISCONNECT].function) - (*session->callbacks[YAHOO_HANDLE_DISCONNECT].function)(session); - return; - } - yahoo_parse_packet(session, conn, &pkt); - } else if (conn->type == YAHOO_CONN_TYPE_DUMB) { - char *buf = g_malloc0(5000); - while (read(socket, &buf[pos++], 1) == 1); - if (pos == 1) { - g_free(buf); - yahoo_close(session, conn); - YAHOO_PRINT(session, YAHOO_LOG_WARNING, "error reading from listserv"); - return; - } - YAHOO_PRINT(session, YAHOO_LOG_DEBUG, buf); - YAHOO_PRINT(session, YAHOO_LOG_NOTICE, "closing buddy list host connnection"); - yahoo_close(session, conn); - g_free(buf); - } else if (conn->type == YAHOO_CONN_TYPE_PROXY) { - char *buf = g_malloc0(5000); - int nlc = 0; - while ((nlc != 2) && (read(socket, &buf[pos++], 1) == 1)) { - if (buf[pos-1] == '\n') - nlc++; - else if (buf[pos-1] != '\r') - nlc = 0; - } - if (pos == 1) { - g_free(buf); - yahoo_close(session, conn); - YAHOO_PRINT(session, YAHOO_LOG_ERROR, "error reading from proxy"); - if (session->callbacks[YAHOO_HANDLE_DISCONNECT].function) - (*session->callbacks[YAHOO_HANDLE_DISCONNECT].function)(session); - return; - } - YAHOO_PRINT(session, YAHOO_LOG_DEBUG, buf); - if (!strncasecmp(buf, HTTP_GOODSTRING1, strlen(HTTP_GOODSTRING1)) || - !strncasecmp(buf, HTTP_GOODSTRING2, strlen(HTTP_GOODSTRING2))) { - conn->type = YAHOO_CONN_TYPE_MAIN; - YAHOO_PRINT(session, YAHOO_LOG_NOTICE, "proxy connected successfully"); - if (session->callbacks[YAHOO_HANDLE_MAINCONNECT].function) - (*session->callbacks[YAHOO_HANDLE_MAINCONNECT].function)(session); - } else { - yahoo_close(session, conn); - YAHOO_PRINT(session, YAHOO_LOG_ERROR, "proxy could not connect"); - if (session->callbacks[YAHOO_HANDLE_DISCONNECT].function) - (*session->callbacks[YAHOO_HANDLE_DISCONNECT].function)(session); - } - g_free(buf); - } -} - -void yahoo_add_handler(struct yahoo_session *session, int type, yahoo_callback function) -{ - if (!session) - return; - - session->callbacks[type].function = function; -} diff -r ab2ca2770d2e -r 37d80035e77f src/protocols/yahoo/yahoo.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/protocols/yahoo/yahoo.c Tue Nov 06 23:58:24 2001 +0000 @@ -0,0 +1,1074 @@ +/* + * gaim + * + * Some code copyright (C) 1998-1999, Mark Spencer + * libfaim code copyright 1998, 1999 Adam Fritzler + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "multi.h" +#include "prpl.h" +#include "gaim.h" +#include "proxy.h" + +#include "pixmaps/status-away.xpm" +#include "pixmaps/status-here.xpm" +#include "pixmaps/status-idle.xpm" + +#define YAHOO_DEBUG + +#define USEROPT_MAIL 0 + +#define USEROPT_PAGERHOST 3 +#define YAHOO_PAGER_HOST "scs.yahoo.com" +#define USEROPT_PAGERPORT 4 +#define YAHOO_PAGER_PORT 5050 + +enum yahoo_service { + YAHOO_SERVICE_LOGON = 1, + YAHOO_SERVICE_LOGOFF, + YAHOO_SERVICE_ISAWAY, + YAHOO_SERVICE_ISBACK, + YAHOO_SERVICE_IDLE, + YAHOO_SERVICE_MESSAGE, + YAHOO_SERVICE_IDACT, + YAHOO_SERVICE_IDDEACT, + YAHOO_SERVICE_MAILSTAT, + YAHOO_SERVICE_USERSTAT, + YAHOO_SERVICE_NEWMAIL, + YAHOO_SERVICE_CHATINVITE, + YAHOO_SERVICE_CALENDAR, + YAHOO_SERVICE_NEWPERSONALMAIL, + YAHOO_SERVICE_NEWCONTACT, + YAHOO_SERVICE_ADDIDENT, + YAHOO_SERVICE_ADDIGNORE, + YAHOO_SERVICE_PING, + YAHOO_SERVICE_GROUPRENAME, + YAHOO_SERVICE_SYSMESSAGE = 20, + YAHOO_SERVICE_PASSTHROUGH2 = 22, + YAHOO_SERVICE_CONFINVITE = 24, + YAHOO_SERVICE_CONFLOGON, + YAHOO_SERVICE_CONFDECLINE, + YAHOO_SERVICE_CONFLOGOFF, + YAHOO_SERVICE_CONFADDINVITE, + YAHOO_SERVICE_CONFMSG, + YAHOO_SERVICE_CHATLOGON, + YAHOO_SERVICE_CHATLOGOFF, + YAHOO_SERVICE_CHATMSG = 32, + YAHOO_SERVICE_GAMELOGON = 40, + YAHOO_SERVICE_GAMELOGOFF = 41, + YAHOO_SERVICE_FILETRANSFER = 70, + YAHOO_SERVICE_LIST = 85, + YAHOO_SERVICE_ADDBUDDY = 131, + YAHOO_SERVICE_REMBUDDY = 132 +}; + +enum yahoo_status { + YAHOO_STATUS_AVAILABLE, + YAHOO_STATUS_BRB, + YAHOO_STATUS_BUSY, + YAHOO_STATUS_NOTATHOME, + YAHOO_STATUS_NOTATDESK, + YAHOO_STATUS_NOTINOFFICE, + YAHOO_STATUS_ONPHONE, + YAHOO_STATUS_ONVACATION, + YAHOO_STATUS_OUTTOLUNCH, + YAHOO_STATUS_STEPPEDOUT, + YAHOO_STATUS_INVISIBLE = 12, + YAHOO_STATUS_CUSTOM = 99, + YAHOO_STATUS_IDLE = 999, + YAHOO_STATUS_OFFLINE = 0x5a55aa56 +}; + +struct yahoo_data { + int fd; + guchar *rxqueue; + int rxlen; + GHashTable *hash; + GSList *login; + int current_status; + gboolean logged_in; +}; + +struct yahoo_pair { + int key; + char *value; +}; + +struct yahoo_packet { + guint16 service; + guint32 status; + guint32 id; + GSList *hash; +}; + +struct yahoo_buddy { + char *name; + int state; + char *msg; +}; + +static char *yahoo_name() { + return "Yahoo"; +} + +#define YAHOO_PACKET_HDRLEN (4 + 2 + 2 + 2 + 2 + 4 + 4) + +static struct yahoo_packet *yahoo_packet_new(enum yahoo_service service, enum yahoo_status status, int id) +{ + struct yahoo_packet *pkt = g_new0(struct yahoo_packet, 1); + + pkt->service = service; + pkt->status = status; + pkt->id = id; + + return pkt; +} + +static void yahoo_packet_hash(struct yahoo_packet *pkt, int key, char *value) +{ + struct yahoo_pair *pair = g_new0(struct yahoo_pair, 1); + pair->key = key; + pair->value = g_strdup(value); + pkt->hash = g_slist_append(pkt->hash, pair); +} + +static int yahoo_packet_length(struct yahoo_packet *pkt) +{ + GSList *l; + + int len = 0; + + l = pkt->hash; + while (l) { + struct yahoo_pair *pair = l->data; + int tmp = pair->key; + do { + tmp /= 10; + len++; + } while (tmp); + len += 2; + len += strlen(pair->value); + len += 2; + l = l->next; + } + + return len; +} + +/* sometimes i wish prpls could #include things from other prpls. then i could just + * use the routines from libfaim and not have to admit to knowing how they work. */ +#define yahoo_put16(buf, data) ( \ + (*(buf) = (u_char)((data)>>8)&0xff), \ + (*((buf)+1) = (u_char)(data)&0xff), \ + 2) +#define yahoo_get16(buf) ((((*(buf))<<8)&0xff00) + ((*((buf)+1)) & 0xff)) +#define yahoo_put32(buf, data) ( \ + (*((buf)) = (u_char)((data)>>24)&0xff), \ + (*((buf)+1) = (u_char)((data)>>16)&0xff), \ + (*((buf)+2) = (u_char)((data)>>8)&0xff), \ + (*((buf)+3) = (u_char)(data)&0xff), \ + 4) +#define yahoo_get32(buf) ((((*(buf))<<24)&0xff000000) + \ + (((*((buf)+1))<<16)&0x00ff0000) + \ + (((*((buf)+2))<< 8)&0x0000ff00) + \ + (((*((buf)+3) )&0x000000ff))) + +static void yahoo_packet_read(struct yahoo_packet *pkt, guchar *data, int len) +{ + int pos = 0; + + while (pos + 1 < len) { + char key[64], *value; + int x; + + struct yahoo_pair *pair = g_new0(struct yahoo_pair, 1); + pkt->hash = g_slist_append(pkt->hash, pair); + + x = 0; + while (pos + 1 < len) { + if (data[pos] == 0xc0 && data[pos + 1] == 0x80) + break; + key[x++] = data[pos++]; + } + key[x] = 0; + pos += 2; + pair->key = strtol(key, NULL, 10); + + value = g_malloc(len - pos); + x = 0; + while (pos + 1 < len) { + if (data[pos] == 0xc0 && data[pos + 1] == 0x80) + break; + value[x++] = data[pos++]; + } + value[x] = 0; + pos += 2; + pair->value = g_strdup(value); + g_free(value); + debug_printf("Key: %d \tValue: %s\n", pair->key, pair->value); + } +} + +static void yahoo_packet_write(struct yahoo_packet *pkt, guchar *data) +{ + GSList *l = pkt->hash; + int pos = 0; + + while (l) { + struct yahoo_pair *pair = l->data; + guchar buf[100]; + + g_snprintf(buf, sizeof(buf), "%d", pair->key); + strcpy(data + pos, buf); + pos += strlen(buf); + data[pos++] = 0xc0; + data[pos++] = 0x80; + + strcpy(data + pos, pair->value); + pos += strlen(pair->value); + data[pos++] = 0xc0; + data[pos++] = 0x80; + + l = l->next; + } +} + +static void yahoo_packet_dump(guchar *data, int len) +{ +#ifdef YAHOO_DEBUG + int i; + for (i = 0; i + 1 < len; i += 2) { + if ((i % 16 == 0) && i) + debug_printf("\n"); + debug_printf("%02x", data[i]); + debug_printf("%02x ", data[i+1]); + } + if (i < len) + debug_printf("%02x", data[i]); + debug_printf("\n"); + for (i = 0; i < len; i++) { + if ((i % 16 == 0) && i) + debug_printf("\n"); + if (isprint(data[i])) + debug_printf("%c ", data[i]); + else + debug_printf(". "); + } + debug_printf("\n"); +#endif +} + +static int yahoo_send_packet(struct yahoo_data *yd, struct yahoo_packet *pkt) +{ + int pktlen = yahoo_packet_length(pkt); + int len = YAHOO_PACKET_HDRLEN + pktlen; + int ret; + + guchar *data; + int pos = 0; + + if (yd->fd < 0) + return -1; + + data = g_malloc0(len + 1); + + memcpy(data + pos, "YMSG", 4); pos += 4; + pos += yahoo_put16(data + pos, 0x0600); + pos += yahoo_put16(data + pos, 0x0000); + pos += yahoo_put16(data + pos, pktlen); + pos += yahoo_put16(data + pos, pkt->service); + pos += yahoo_put32(data + pos, pkt->status); + pos += yahoo_put32(data + pos, pkt->id); + + yahoo_packet_write(pkt, data + pos); + + yahoo_packet_dump(data, len); + ret = write(yd->fd, data, len); + + g_free(data); + + return ret; +} + +static void yahoo_packet_free(struct yahoo_packet *pkt) +{ + while (pkt->hash) { + struct yahoo_pair *pair = pkt->hash->data; + g_free(pair->value); + g_free(pair); + pkt->hash = g_slist_remove(pkt->hash, pair); + } + g_free(pkt); +} + +static void yahoo_process_logon(struct gaim_connection *gc, struct yahoo_packet *pkt) +{ + struct yahoo_data *yd = gc->proto_data; + GSList *l = pkt->hash; + struct yahoo_buddy *buddy = NULL; + struct yahoo_packet *newpkt; + char *name = NULL; + int state = 0; + char *msg = NULL; + + while (l) { + struct yahoo_pair *pair = l->data; + + switch (pair->key) { + case 0: /* we won't actually do anything with this */ + break; + case 1: /* we don't get the full buddy list here. */ + account_online(gc); + serv_finish_login(gc); + g_snprintf(gc->displayname, sizeof(gc->displayname), "%s", pair->value); + do_import(gc, NULL); + yd->logged_in = TRUE; + + /* this requests the list. i have a feeling that this is very evil */ + newpkt = yahoo_packet_new(YAHOO_SERVICE_LIST, YAHOO_STATUS_OFFLINE, 0); + yahoo_send_packet(yd, newpkt); + yahoo_packet_free(newpkt); + + break; + case 8: /* how many online buddies we have */ + break; + case 7: /* the current buddy */ + name = pair->value; + break; + case 10: /* state */ + state = strtol(pair->value, NULL, 10); + break; + case 19: /* custom message */ + msg = pair->value; + break; + case 11: /* i didn't know what this was in the old protocol either */ + break; + case 17: /* in chat? */ + break; + case 13: /* in pager, i think this should always be 1 */ + /* we don't actually give notification here. we wait until after we've + * gotten the list, so that they get added to the right group */ + buddy = g_new0(struct yahoo_buddy, 1); + buddy->name = g_strdup(name); + buddy->state = state; + buddy->msg = msg ? g_strdup(msg) : NULL; + yd->login = g_slist_append(yd->login, buddy); + break; + default: + debug_printf("unknown login key %d\n", pair->key); + break; + } + + l = l->next; + } +} + +static void yahoo_process_list(struct gaim_connection *gc, struct yahoo_packet *pkt) +{ + struct yahoo_data *yd = gc->proto_data; + GSList *l = pkt->hash; + gboolean export = FALSE; + + while (l) { + char **lines; + char **split; + char **buddies; + char **tmp, **bud; + + struct yahoo_pair *pair = l->data; + l = l->next; + + if (pair->key != 87) + continue; + + lines = g_strsplit(pair->value, "\n", -1); + for (tmp = lines; *tmp; tmp++) { + split = g_strsplit(*tmp, ":", 2); + buddies = g_strsplit(split[1], ",", -1); + for (bud = buddies; *bud; bud++) + if (!find_buddy(gc, *bud)) { + add_buddy(gc, split[0], *bud, *bud); + export = TRUE; + } + g_strfreev(buddies); + g_strfreev(split); + } + g_strfreev(lines); + } + + if (export) + do_export(gc); + + while (yd->login) { + struct yahoo_buddy *buddy = yd->login->data; + int status = buddy->state; + yd->login = g_slist_remove(yd->login, buddy); + if (status == YAHOO_STATUS_AVAILABLE) + serv_got_update(gc, buddy->name, 1, 0, 0, 0, 0, 0); + else if (status == YAHOO_STATUS_IDLE) + serv_got_update(gc, buddy->name, 1, 0, 0, time(NULL) - 600, (status << 1), 0); + else + serv_got_update(gc, buddy->name, 1, 0, 0, 0, (status << 1) | UC_UNAVAILABLE, 0); + if (status == YAHOO_STATUS_CUSTOM) { + gpointer val = g_hash_table_lookup(yd->hash, buddy->name); + if (val) { + g_free(val); + g_hash_table_insert(yd->hash, buddy->name, g_strdup(buddy->msg)); + } else + g_hash_table_insert(yd->hash, g_strdup(buddy->name), g_strdup(buddy->msg)); + } + g_free(buddy->msg); + g_free(buddy->name); + g_free(buddy); + } +} + +static void yahoo_process_message(struct gaim_connection *gc, struct yahoo_packet *pkt) +{ + char *msg = NULL; + char *from = NULL; + time_t tm = time(NULL); + GSList *l = pkt->hash; + + while (l) { + struct yahoo_pair *pair = l->data; + if (pair->key == 4) + from = pair->value; + if (pair->key == 14) + msg = pair->value; + if (pair->key == 15) + tm = strtol(pair->value, NULL, 10); + l = l->next; + } + + if (pkt->status == 1) { + strip_linefeed(msg); + serv_got_im(gc, from, msg, 0, tm); + } else if (pkt->status == 2) { + do_error_dialog(_("Your message did not get sent."), _("Gaim - Error")); + } +} + +static void yahoo_process_status(struct gaim_connection *gc, struct yahoo_packet *pkt) +{ + struct yahoo_data *yd = gc->proto_data; + GSList *l = pkt->hash; + char *name = NULL; + int state = 0; + char *msg = NULL; + + while (l) { + struct yahoo_pair *pair = l->data; + + switch (pair->key) { + case 7: + name = pair->value; + break; + case 10: + state = strtol(pair->value, NULL, 10); + break; + case 19: + msg = pair->value; + break; + case 11: /* i didn't know what this was in the old protocol either */ + break; + case 17: /* in chat? */ + break; + case 13: + if (strtol(pair->value, NULL, 10) != 1) { + serv_got_update(gc, name, 0, 0, 0, 0, 0, 0); + break; + } + if (state == YAHOO_STATUS_AVAILABLE) + serv_got_update(gc, name, 1, 0, 0, 0, 0, 0); + else if (state == YAHOO_STATUS_IDLE) + serv_got_update(gc, name, 1, 0, 0, time(NULL) - 600, (state << 1), 0); + else + serv_got_update(gc, name, 1, 0, 0, 0, (state << 1) | UC_UNAVAILABLE, 0); + if (state == YAHOO_STATUS_CUSTOM) { + gpointer val = g_hash_table_lookup(yd->hash, name); + if (val) { + g_free(val); + g_hash_table_insert(yd->hash, name, g_strdup(msg)); + } else + g_hash_table_insert(yd->hash, g_strdup(name), g_strdup(msg)); + } + break; + } + + l = l->next; + } +} + +static void yahoo_process_contact(struct gaim_connection *gc, struct yahoo_packet *pkt) +{ + char *id = NULL; + char *who = NULL; + char *msg = NULL; + GSList *l = pkt->hash; + + while (l) { + struct yahoo_pair *pair = l->data; + if (pair->key == 1) + id = pair->value; + else if (pair->key == 3) + who = pair->value; + else if (pair->key == 14) + msg = pair->value; + l = l->next; + } + + show_got_added(gc, id, who, NULL, msg); +} + +static void yahoo_process_mail(struct gaim_connection *gc, struct yahoo_packet *pkt) +{ + char *who = NULL; + char *email = NULL; + char *subj = NULL; + int count = 0; + GSList *l = pkt->hash; + + while (l) { + struct yahoo_pair *pair = l->data; + if (pair->key == 9) + count = strtol(pair->value, NULL, 10); + else if (pair->key == 43) + who = pair->value; + else if (pair->key == 42) + email = pair->value; + else if (pair->key == 18) + subj = pair->value; + l = l->next; + } + + connection_has_mail(gc, count, NULL, NULL, "http://mail.yahoo.com/"); +} + +static void yahoo_packet_process(struct gaim_connection *gc, struct yahoo_packet *pkt) +{ + switch (pkt->service) + { + case YAHOO_SERVICE_LOGON: + yahoo_process_logon(gc, pkt); + break; + case YAHOO_SERVICE_ISAWAY: + yahoo_process_status(gc, pkt); + break; + case YAHOO_SERVICE_MESSAGE: + yahoo_process_message(gc, pkt); + break; + case YAHOO_SERVICE_NEWMAIL: + yahoo_process_mail(gc, pkt); + break; + case YAHOO_SERVICE_NEWCONTACT: + yahoo_process_contact(gc, pkt); + break; + case YAHOO_SERVICE_LIST: + yahoo_process_list(gc, pkt); + break; + default: + debug_printf("unhandled service %d\n", pkt->service); + break; + } +} + +static void yahoo_pending(gpointer data, gint source, GaimInputCondition cond) +{ + struct gaim_connection *gc = data; + struct yahoo_data *yd = gc->proto_data; + char buf[1024]; + int len; + + len = read(yd->fd, buf, sizeof(buf)); + + if (len <= 0) { + hide_login_progress(gc, "Unable to read"); + signoff(gc); + return; + } + + yd->rxqueue = g_realloc(yd->rxqueue, len + yd->rxlen); + memcpy(yd->rxqueue + yd->rxlen, buf, len); + yd->rxlen += len; + + while (1) { + struct yahoo_packet *pkt; + int pos = 0; + int pktlen; + + if (yd->rxlen < YAHOO_PACKET_HDRLEN) + return; + + pos += 4; /* YMSG */ + pos += 2; + pos += 2; + + pktlen = yahoo_get16(yd->rxqueue + pos); pos += 2; + debug_printf("%d bytes to read, rxlen is %d\n", pktlen, yd->rxlen); + + if (yd->rxlen < (YAHOO_PACKET_HDRLEN + pktlen)) + return; + + yahoo_packet_dump(yd->rxqueue, YAHOO_PACKET_HDRLEN + pktlen); + + pkt = yahoo_packet_new(0, 0, 0); + + pkt->service = yahoo_get16(yd->rxqueue + pos); pos += 2; + debug_printf("Yahoo Service: %d Status: %d\n", pkt->service, pkt->status); + pkt->status = yahoo_get32(yd->rxqueue + pos); pos += 4; + pkt->id = yahoo_get32(yd->rxqueue + pos); pos += 4; + + yahoo_packet_read(pkt, yd->rxqueue + pos, pktlen); + + yd->rxlen -= YAHOO_PACKET_HDRLEN + pktlen; + if (yd->rxlen) { + char *tmp = g_memdup(yd->rxqueue + YAHOO_PACKET_HDRLEN + pktlen, yd->rxlen); + g_free(yd->rxqueue); + yd->rxqueue = tmp; + } else { + g_free(yd->rxqueue); + yd->rxqueue = NULL; + } + + yahoo_packet_process(gc, pkt); + + yahoo_packet_free(pkt); + } +} + +static void yahoo_got_connected(gpointer data, gint source, GaimInputCondition cond) +{ + struct gaim_connection *gc = data; + struct yahoo_data *yd; + struct yahoo_packet *pkt; + + if (!g_slist_find(connections, gc)) { + close(source); + return; + } + + if (source < 0) { + hide_login_progress(gc, "Unable to connect"); + signoff(gc); + return; + } + + yd = gc->proto_data; + yd->fd = source; + + pkt = yahoo_packet_new(YAHOO_SERVICE_LOGON, YAHOO_STATUS_AVAILABLE, 0); + + yahoo_packet_hash(pkt, 0, gc->username); + yahoo_packet_hash(pkt, 1, gc->username); + yahoo_packet_hash(pkt, 6, crypt(gc->password, "$1$_2S43d5f$")); + + yahoo_send_packet(yd, pkt); + + yahoo_packet_free(pkt); + + gc->inpa = gaim_input_add(yd->fd, GAIM_INPUT_READ, yahoo_pending, gc); +} + +static void yahoo_login(struct aim_user *user) { + struct gaim_connection *gc = new_gaim_conn(user); + struct yahoo_data *yd = gc->proto_data = g_new0(struct yahoo_data, 1); + + set_login_progress(gc, 1, "Connecting"); + + yd->fd = -1; + yd->hash = g_hash_table_new(g_str_hash, g_str_equal); + + if (!proxy_connect(user->proto_opt[USEROPT_PAGERHOST][0] ? + user->proto_opt[USEROPT_PAGERHOST] : YAHOO_PAGER_HOST, + user->proto_opt[USEROPT_PAGERPORT][0] ? + atoi(user->proto_opt[USEROPT_PAGERPORT]) : YAHOO_PAGER_PORT, + yahoo_got_connected, gc)) { + hide_login_progress(gc, "Connection problem"); + signoff(gc); + return; + } + +} + +static gboolean yahoo_destroy_hash(gpointer key, gpointer val, gpointer data) +{ + g_free(key); + g_free(val); + return TRUE; +} + +static void yahoo_close(struct gaim_connection *gc) { + struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; + g_hash_table_foreach_remove(yd->hash, yahoo_destroy_hash, NULL); + g_hash_table_destroy(yd->hash); + if (yd->fd >= 0) + close(yd->fd); + if (yd->rxqueue) + g_free(yd->rxqueue); + while (yd->login) { + struct yahoo_buddy *buddy = yd->login->data; + yd->login = g_slist_remove(yd->login, buddy); + g_free(buddy->msg); + g_free(buddy->name); + g_free(buddy); + } + if (gc->inpa) + gaim_input_remove(gc->inpa); + g_free(yd); +} + +static char **yahoo_list_icon(int uc) +{ + if ((uc >> 1) == YAHOO_STATUS_IDLE) + return status_idle_xpm; + else if (uc == 0) + return status_here_xpm; + return status_away_xpm; +} + +static char *yahoo_get_status_string(enum yahoo_status a) +{ + switch (a) { + case YAHOO_STATUS_BRB: + return "Be Right Back"; + case YAHOO_STATUS_BUSY: + return "Busy"; + case YAHOO_STATUS_NOTATHOME: + return "Not At Home"; + case YAHOO_STATUS_NOTATDESK: + return "Not At Desk"; + case YAHOO_STATUS_NOTINOFFICE: + return "Not In Office"; + case YAHOO_STATUS_ONPHONE: + return "On Phone"; + case YAHOO_STATUS_ONVACATION: + return "On Vacation"; + case YAHOO_STATUS_OUTTOLUNCH: + return "Out To Lunch"; + case YAHOO_STATUS_STEPPEDOUT: + return "Stepped Out"; + default: + return NULL; + } +} + +static GList *yahoo_buddy_menu(struct gaim_connection *gc, char *who) +{ + GList *m = NULL; + struct proto_buddy_menu *pbm; + struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; + struct buddy *b = find_buddy(gc, who); /* this should never be null. if it is, + segfault and get the bug report. */ + static char buf[1024]; + + if (!(b->uc & UC_UNAVAILABLE)) + return NULL; + + pbm = g_new0(struct proto_buddy_menu, 1); + if ((b->uc >> 1) != YAHOO_STATUS_CUSTOM) + g_snprintf(buf, sizeof buf, "Status: %s", yahoo_get_status_string(b->uc >> 1)); + else + g_snprintf(buf, sizeof buf, "Custom Status: %s", + (char *)g_hash_table_lookup(yd->hash, b->name)); + pbm->label = buf; + pbm->callback = NULL; + pbm->gc = gc; + m = g_list_append(m, pbm); + + return m; +} + +static GList *yahoo_user_opts() +{ + GList *m = NULL; + struct proto_user_opt *puo; + + puo = g_new0(struct proto_user_opt, 1); + puo->label = "Pager Host:"; + puo->def = YAHOO_PAGER_HOST; + puo->pos = USEROPT_PAGERHOST; + m = g_list_append(m, puo); + + puo = g_new0(struct proto_user_opt, 1); + puo->label = "Pager Port:"; + puo->def = "5050"; + puo->pos = USEROPT_PAGERPORT; + m = g_list_append(m, puo); + + return m; +} + +static void yahoo_act_id(gpointer data, char *entry) +{ + struct gaim_connection *gc = data; + struct yahoo_data *yd = gc->proto_data; + + struct yahoo_packet *pkt = yahoo_packet_new(YAHOO_SERVICE_IDACT, YAHOO_STATUS_AVAILABLE, 0); + yahoo_packet_hash(pkt, 3, entry); + yahoo_send_packet(yd, pkt); + yahoo_packet_free(pkt); + + g_snprintf(gc->displayname, sizeof(gc->displayname), "%s", entry); +} + +static void yahoo_do_action(struct gaim_connection *gc, char *act) +{ + if (!strcmp(act, "Activate ID")) { + do_prompt_dialog("Activate which ID:", gc->displayname, gc, yahoo_act_id, NULL); + } +} + +static GList *yahoo_actions() { + GList *m = NULL; + + m = g_list_append(m, "Activate ID"); + + return m; +} + +static int yahoo_send_im(struct gaim_connection *gc, char *who, char *what, int flags) +{ + struct yahoo_data *yd = gc->proto_data; + struct yahoo_packet *pkt = yahoo_packet_new(YAHOO_SERVICE_MESSAGE, YAHOO_STATUS_OFFLINE, 0); + + yahoo_packet_hash(pkt, 1, gc->displayname); + yahoo_packet_hash(pkt, 5, who); + yahoo_packet_hash(pkt, 14, what); + + yahoo_send_packet(yd, pkt); + + yahoo_packet_free(pkt); + + return 1; +} + +static void yahoo_set_away(struct gaim_connection *gc, char *state, char *msg) +{ + struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; + struct yahoo_packet *pkt; + char s[4]; + + gc->away = NULL; + + if (msg) { + yd->current_status = YAHOO_STATUS_CUSTOM; + gc->away = ""; + } else if (state) { + gc->away = ""; + if (!strcmp(state, "Available")) { + yd->current_status = YAHOO_STATUS_AVAILABLE; + gc->away = NULL; + } else if (!strcmp(state, "Be Right Back")) { + yd->current_status = YAHOO_STATUS_BRB; + } else if (!strcmp(state, "Busy")) { + yd->current_status = YAHOO_STATUS_BUSY; + } else if (!strcmp(state, "Not At Home")) { + yd->current_status = YAHOO_STATUS_NOTATHOME; + } else if (!strcmp(state, "Not At Desk")) { + yd->current_status = YAHOO_STATUS_NOTATDESK; + } else if (!strcmp(state, "Not In Office")) { + yd->current_status = YAHOO_STATUS_NOTINOFFICE; + } else if (!strcmp(state, "On Phone")) { + yd->current_status = YAHOO_STATUS_ONPHONE; + } else if (!strcmp(state, "On Vacation")) { + yd->current_status = YAHOO_STATUS_ONVACATION; + } else if (!strcmp(state, "Out To Lunch")) { + yd->current_status = YAHOO_STATUS_OUTTOLUNCH; + } else if (!strcmp(state, "Stepped Out")) { + yd->current_status = YAHOO_STATUS_STEPPEDOUT; + } else if (!strcmp(state, "Invisible")) { + yd->current_status = YAHOO_STATUS_INVISIBLE; + } else if (!strcmp(state, GAIM_AWAY_CUSTOM)) { + if (gc->is_idle) { + yd->current_status = YAHOO_STATUS_IDLE; + } else { + yd->current_status = YAHOO_STATUS_AVAILABLE; + } + gc->away = NULL; + } + } else if (gc->is_idle) { + yd->current_status = YAHOO_STATUS_IDLE; + } else { + yd->current_status = YAHOO_STATUS_AVAILABLE; + } + + pkt = yahoo_packet_new(YAHOO_SERVICE_ISAWAY, yd->current_status, 0); + g_snprintf(s, sizeof(s), "%d", yd->current_status); + yahoo_packet_hash(pkt, 10, s); + if (yd->current_status == YAHOO_STATUS_CUSTOM) + yahoo_packet_hash(pkt, 19, msg); + + yahoo_send_packet(yd, pkt); + yahoo_packet_free(pkt); +} + +static void yahoo_set_idle(struct gaim_connection *gc, int idle) +{ + struct yahoo_data *yd = gc->proto_data; + struct yahoo_packet *pkt = NULL; + + if (idle && yd->current_status == YAHOO_STATUS_AVAILABLE) { + pkt = yahoo_packet_new(YAHOO_SERVICE_ISAWAY, YAHOO_STATUS_IDLE, 0); + yd->current_status = YAHOO_STATUS_IDLE; + } else if (!idle && yd->current_status == YAHOO_STATUS_IDLE) { + pkt = yahoo_packet_new(YAHOO_SERVICE_ISAWAY, YAHOO_STATUS_AVAILABLE, 0); + yd->current_status = YAHOO_STATUS_AVAILABLE; + } + + if (pkt) { + char buf[4]; + g_snprintf(buf, sizeof(buf), "%d", yd->current_status); + yahoo_packet_hash(pkt, 10, buf); + yahoo_send_packet(yd, pkt); + yahoo_packet_free(pkt); + } +} + +static GList *yahoo_away_states(struct gaim_connection *gc) +{ + GList *m = NULL; + + m = g_list_append(m, "Available"); + m = g_list_append(m, "Be Right Back"); + m = g_list_append(m, "Busy"); + m = g_list_append(m, "Not At Home"); + m = g_list_append(m, "Not At Desk"); + m = g_list_append(m, "Not In Office"); + m = g_list_append(m, "On Phone"); + m = g_list_append(m, "On Vacation"); + m = g_list_append(m, "Out To Lunch"); + m = g_list_append(m, "Stepped Out"); + m = g_list_append(m, "Invisible"); + m = g_list_append(m, GAIM_AWAY_CUSTOM); + + return m; +} + +static void yahoo_keepalive(struct gaim_connection *gc) +{ + struct yahoo_data *yd = gc->proto_data; + struct yahoo_packet *pkt = yahoo_packet_new(YAHOO_SERVICE_PING, YAHOO_STATUS_AVAILABLE, 0); + yahoo_send_packet(yd, pkt); + yahoo_packet_free(pkt); +} + +static void yahoo_add_buddy(struct gaim_connection *gc, char *who) +{ + struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; + struct yahoo_packet *pkt; + struct group *g; + char *group = NULL; + + if (!yd->logged_in) + return; + + g = find_group_by_buddy(gc, who); + if (g) + group = g->name; + else + group = "Buddies"; + + pkt = yahoo_packet_new(YAHOO_SERVICE_ADDBUDDY, YAHOO_STATUS_AVAILABLE, 0); + yahoo_packet_hash(pkt, 1, gc->displayname); + yahoo_packet_hash(pkt, 7, who); + yahoo_packet_hash(pkt, 65, group); + yahoo_send_packet(yd, pkt); + yahoo_packet_free(pkt); +} + +static void yahoo_remove_buddy(struct gaim_connection *gc, char *who, char *group) +{ + struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; + + struct yahoo_packet *pkt = yahoo_packet_new(YAHOO_SERVICE_REMBUDDY, YAHOO_STATUS_AVAILABLE, 0); + yahoo_packet_hash(pkt, 1, gc->displayname); + yahoo_packet_hash(pkt, 7, who); + yahoo_packet_hash(pkt, 65, group); + yahoo_send_packet(yd, pkt); + yahoo_packet_free(pkt); +} + +static struct prpl *my_protocol = NULL; + +void yahoo_init(struct prpl *ret) { + ret->protocol = PROTO_YAHOO; + ret->options = OPT_PROTO_MAIL_CHECK; + ret->name = yahoo_name; + ret->user_opts = yahoo_user_opts; + ret->login = yahoo_login; + ret->close = yahoo_close; + ret->buddy_menu = yahoo_buddy_menu; + ret->list_icon = yahoo_list_icon; + ret->actions = yahoo_actions; + ret->do_action = yahoo_do_action; + ret->send_im = yahoo_send_im; + ret->away_states = yahoo_away_states; + ret->set_away = yahoo_set_away; + ret->set_idle = yahoo_set_idle; + ret->keepalive = yahoo_keepalive; + ret->add_buddy = yahoo_add_buddy; + ret->remove_buddy = yahoo_remove_buddy; + + my_protocol = ret; +} + +#ifndef STATIC + +char *gaim_plugin_init(GModule *handle) +{ + load_protocol(yahoo_init, sizeof(struct prpl)); + return NULL; +} + +void gaim_plugin_remove() +{ + struct prpl *p = find_prpl(PROTO_YAHOO); + if (p == my_protocol) + unload_protocol(p); +} + +char *name() +{ + return "Yahoo"; +} + +char *description() +{ + return PRPL_DESC("Yahoo"); +} + +#endif diff -r ab2ca2770d2e -r 37d80035e77f src/protocols/yahoo/yay.c --- a/src/protocols/yahoo/yay.c Tue Nov 06 21:30:31 2001 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,762 +0,0 @@ -/* - * gaim - * - * Some code copyright (C) 1998-1999, Mark Spencer - * libfaim code copyright 1998, 1999 Adam Fritzler - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "multi.h" -#include "prpl.h" -#include "gaim.h" -#include "yay.h" -#include "proxy.h" - -#include "pixmaps/status-away.xpm" -#include "pixmaps/status-here.xpm" -#include "pixmaps/status-idle.xpm" - -#define USEROPT_MAIL 0 - -#define USEROPT_AUTHHOST 1 -#define USEROPT_AUTHPORT 2 -#define USEROPT_PAGERHOST 3 -#define USEROPT_PAGERPORT 4 - -struct conn { - int socket; - int type; - int inpa; -}; - -struct connect { - struct yahoo_session *sess; - gpointer data; -}; - -struct yahoo_data { - struct yahoo_session *sess; - int current_status; - GHashTable *hash; - char *active_id; - GList *conns; - gboolean logged_in; -}; - -static char *yahoo_name() { - return "Yahoo"; -} - -static int yahoo_status(struct yahoo_session *sess, ...) { - struct gaim_connection *gc = sess->user_data; - struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; - time_t tmptime; - struct buddy *b; - gboolean online; - - va_list ap; - char *who; - int status; - char *msg; - int in_pager, in_chat, in_game; - - va_start(ap, sess); - who = va_arg(ap, char *); - status = va_arg(ap, int); - msg = va_arg(ap, char *); - in_pager = va_arg(ap, int); - in_chat = va_arg(ap, int); - in_game = va_arg(ap, int); - va_end(ap); - - online = in_pager || in_chat || in_game; - - b = find_buddy(gc, who); - if (!b) return 0; - if (!online) - serv_got_update(gc, b->name, 0, 0, 0, 0, 0, 0); - else { - if (status == YAHOO_STATUS_AVAILABLE) - serv_got_update(gc, b->name, 1, 0, 0, 0, 0, 0); - else if (status == YAHOO_STATUS_IDLE) { - time(&tmptime); - serv_got_update(gc, b->name, 1, 0, 0, tmptime - 600, (status << 1), 0); - } else - serv_got_update(gc, b->name, 1, 0, 0, 0, (status << 1) | UC_UNAVAILABLE, 0); - if (status == YAHOO_STATUS_CUSTOM) { - gpointer val = g_hash_table_lookup(yd->hash, b->name); - if (val) - g_free(val); - g_hash_table_insert(yd->hash, g_strdup(b->name), g_strdup(msg)); - } - } - - return 1; -} - -static int yahoo_message(struct yahoo_session *sess, ...) { - struct gaim_connection *gc = sess->user_data; - char buf[BUF_LEN * 4]; - char *tmp, *c, *e; - time_t tm; - int at = 0; - - va_list ap; - char *id, *nick, *msg; - - va_start(ap, sess); - id = va_arg(ap, char *); - nick = va_arg(ap, char *); - tm = va_arg(ap, time_t); - msg = va_arg(ap, char *); - va_end(ap); - - if (msg) - e = tmp = g_strdup(msg); - else - return 1; - - while ((c = strchr(e, '\033')) != NULL) { - *c++ = '\0'; - at += g_snprintf(buf + at, sizeof(buf) - at, "%s", e); - e = ++c; - while (*e && (*e++ != 'm')); - } - - if (*e) - g_snprintf(buf + at, sizeof(buf) - at, "%s", e); - - g_free(tmp); - - strip_linefeed(buf); - serv_got_im(gc, nick, buf, 0, tm ? tm : time((time_t)NULL)); - - return 1; -} - -static int yahoo_bounce(struct yahoo_session *sess, ...) { - do_error_dialog(_("Your message did not get sent."), _("Gaim - Error")); - - return 1; -} - -static int yahoo_buddyadded(struct yahoo_session *sess, ...) { - va_list ap; - char *id; - time_t t; - char *who; - char *msg; - - va_start(ap, sess); - id = va_arg(ap, char *); - who = va_arg(ap, char *); - t = va_arg(ap, time_t); - msg = va_arg(ap, char *); - va_end(ap); - - show_got_added(sess->user_data, id, who, NULL, msg); - - return 1; -} - -static int yahoo_newmail(struct yahoo_session *sess, ...) { - struct gaim_connection *gc = sess->user_data; - - va_list ap; - int count; - - va_start(ap, sess); - count = va_arg(ap, int); - va_end(ap); - - connection_has_mail(gc, count, NULL, NULL, "http://mail.yahoo.com/"); - - return 1; -} - -static int yahoo_disconn(struct yahoo_session *sess, ...) { - struct gaim_connection *gc = sess->user_data; - hide_login_progress(gc, "Disconnected"); - signoff(gc); - return 1; -} - -static int yahoo_authconnect(struct yahoo_session *sess, ...) { - struct gaim_connection *gc = sess->user_data; - - set_login_progress(gc, 2, "Connected to Auth"); - if (yahoo_send_login(sess, gc->username, gc->password) < 1) { - hide_login_progress(gc, "Authorizer error"); - signoff(gc); - return 0; - } - - return 1; -} - -static int yahoo_badpassword(struct yahoo_session *sess, ...) { - struct gaim_connection *gc = sess->user_data; - hide_login_progress(gc, "Bad Password"); - signoff(gc); - return 1; -} - -static int yahoo_logincookie(struct yahoo_session *sess, ...) { - struct gaim_connection *gc = sess->user_data; - - set_login_progress(gc, 3, "Got login cookie"); - if (yahoo_major_connect(sess, gc->user->proto_opt[USEROPT_PAGERHOST], - atoi(gc->user->proto_opt[USEROPT_PAGERPORT])) < 1) { - hide_login_progress(gc, "Login error"); - signoff(gc); - } - - return 1; -} - -static int yahoo_mainconnect(struct yahoo_session *sess, ...) { - struct gaim_connection *gc = sess->user_data; - struct yahoo_data *yd = gc->proto_data; - GList *grps; - - set_login_progress(gc, 4, "Connected to service"); - if (yahoo_finish_logon(sess, YAHOO_STATUS_AVAILABLE) < 1) { - hide_login_progress(gc, "Login error"); - signoff(gc); - return 0; - } - - if (bud_list_cache_exists(gc)) - do_import(gc, NULL); - - grps = yd->sess->groups; - while (grps) { - struct yahoo_group *grp = grps->data; - int i; - - for (i = 0; grp->buddies[i]; i++) - add_buddy(gc, grp->name, grp->buddies[i], NULL); - - grps = grps->next; - } - - return 1; -} - -static int yahoo_online(struct yahoo_session *sess, ...) { - struct gaim_connection *gc = sess->user_data; - struct yahoo_data *yd = gc->proto_data; - - account_online(gc); - serv_finish_login(gc); - if (yd->active_id) - g_free(yd->active_id); - yd->active_id = g_strdup(gc->username); - yd->logged_in = TRUE; - - return 1; -} - -static void yahoo_pending(gpointer data, gint source, GaimInputCondition condition) { - struct gaim_connection *gc = (struct gaim_connection *)data; - struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; - - yahoo_socket_handler(yd->sess, source, condition); -} - -static void yahoo_notify(struct yahoo_session *sess, int socket, int type, int cont) { - struct gaim_connection *gc = sess->user_data; - struct yahoo_data *yd; - - if (!g_slist_find(connections, gc)) - return; - - yd = gc->proto_data; - - if (cont) { - struct conn *c = g_new0(struct conn, 1); - c->socket = socket; - c->type = type; - c->inpa = gaim_input_add(socket, type, yahoo_pending, gc); - yd->conns = g_list_append(yd->conns, c); - } else { - GList *c = yd->conns; - while (c) { - struct conn *m = c->data; - if ((m->socket == socket) && (m->type == type)) { - yd->conns = g_list_remove(yd->conns, m); - gaim_input_remove(m->inpa); - g_free(m); - return; - } - c = g_list_next(c); - } - } -} - -static void yahoo_got_connected(gpointer data, gint source, GaimInputCondition cond) { - struct connect *con = data; - struct gaim_connection *gc = con->sess->user_data; - - if (!g_slist_find(connections, gc)) { - close(source); - g_free(con); - return; - } - - debug_printf("got connected (possibly)\n"); - yahoo_connected(con->sess, con->data, source); - - g_free(con); -} - -static int yahoo_connect_to(struct yahoo_session *sess, const char *host, int port, gpointer data) { - struct connect *con = g_new0(struct connect, 1); - int fd; - - con->sess = sess; - con->data = data; - fd = proxy_connect((char *)host, port, yahoo_got_connected, con); - if (fd < 0) { - g_free(con); - return -1; - } - - return fd; -} - -static void yahoo_debug(struct yahoo_session *sess, int level, const char *string) { - debug_printf("Level %d: %s\n", level, string); -} - -static void yahoo_login(struct aim_user *user) { - struct gaim_connection *gc = new_gaim_conn(user); - struct yahoo_data *yd = gc->proto_data = g_new0(struct yahoo_data, 1); - - yd->sess = yahoo_new(); - yd->sess->user_data = gc; - yd->current_status = YAHOO_STATUS_AVAILABLE; - yd->hash = g_hash_table_new(g_str_hash, g_str_equal); - - set_login_progress(gc, 1, "Connecting"); - - if (!yahoo_connect(yd->sess, user->proto_opt[USEROPT_AUTHHOST], - atoi(user->proto_opt[USEROPT_AUTHPORT]))) { - hide_login_progress(gc, "Connection problem"); - signoff(gc); - return; - } - - yahoo_add_handler(yd->sess, YAHOO_HANDLE_DISCONNECT, yahoo_disconn); - yahoo_add_handler(yd->sess, YAHOO_HANDLE_AUTHCONNECT, yahoo_authconnect); - yahoo_add_handler(yd->sess, YAHOO_HANDLE_BADPASSWORD, yahoo_badpassword); - yahoo_add_handler(yd->sess, YAHOO_HANDLE_LOGINCOOKIE, yahoo_logincookie); - yahoo_add_handler(yd->sess, YAHOO_HANDLE_MAINCONNECT, yahoo_mainconnect); - yahoo_add_handler(yd->sess, YAHOO_HANDLE_ONLINE, yahoo_online); - yahoo_add_handler(yd->sess, YAHOO_HANDLE_NEWMAIL, yahoo_newmail); - yahoo_add_handler(yd->sess, YAHOO_HANDLE_MESSAGE, yahoo_message); - yahoo_add_handler(yd->sess, YAHOO_HANDLE_BOUNCE, yahoo_bounce); - yahoo_add_handler(yd->sess, YAHOO_HANDLE_STATUS, yahoo_status); - yahoo_add_handler(yd->sess, YAHOO_HANDLE_BUDDYADDED, yahoo_buddyadded); -} - -static gboolean yahoo_destroy_hash(gpointer key, gpointer val, gpointer data) { - g_free(key); - g_free(val); - return TRUE; -} - -static void yahoo_close(struct gaim_connection *gc) { - struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; - g_hash_table_foreach_remove(yd->hash, yahoo_destroy_hash, NULL); - g_hash_table_destroy(yd->hash); - yahoo_disconnect(yd->sess); - yahoo_delete(yd->sess); - g_free(yd->active_id); - g_free(yd); -} - -static int yahoo_send_im(struct gaim_connection *gc, char *who, char *message, int flags) { - struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; - - if ((flags & IM_FLAG_AWAY)|| !strlen(message)) return 0; - - if (flags & IM_FLAG_CHECKBOX) - yahoo_send_message_offline(yd->sess, yd->active_id, who, message); - else - yahoo_send_message(yd->sess, yd->active_id, who, message); - return 1; -} - -static void yahoo_set_away(struct gaim_connection *gc, char *state, char *msg) { - struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; - - gc->away = NULL; - - if (msg) { - yahoo_away(yd->sess, YAHOO_STATUS_CUSTOM, msg); - yd->current_status = YAHOO_STATUS_CUSTOM; - gc->away = ""; - } else if (state) { - gc->away = ""; - if (!strcmp(state, "Available")) { - yahoo_away(yd->sess, YAHOO_STATUS_AVAILABLE, msg); - yd->current_status = YAHOO_STATUS_AVAILABLE; - } else if (!strcmp(state, "Be Right Back")) { - yahoo_away(yd->sess, YAHOO_STATUS_BRB, msg); - yd->current_status = YAHOO_STATUS_BRB; - } else if (!strcmp(state, "Busy")) { - yahoo_away(yd->sess, YAHOO_STATUS_BUSY, msg); - yd->current_status = YAHOO_STATUS_BUSY; - } else if (!strcmp(state, "Not At Home")) { - yahoo_away(yd->sess, YAHOO_STATUS_NOTATHOME, msg); - yd->current_status = YAHOO_STATUS_NOTATHOME; - } else if (!strcmp(state, "Not At Desk")) { - yahoo_away(yd->sess, YAHOO_STATUS_NOTATDESK, msg); - yd->current_status = YAHOO_STATUS_NOTATDESK; - } else if (!strcmp(state, "Not In Office")) { - yahoo_away(yd->sess, YAHOO_STATUS_NOTINOFFICE, msg); - yd->current_status = YAHOO_STATUS_NOTINOFFICE; - } else if (!strcmp(state, "On Phone")) { - yahoo_away(yd->sess, YAHOO_STATUS_ONPHONE, msg); - yd->current_status = YAHOO_STATUS_ONPHONE; - } else if (!strcmp(state, "On Vacation")) { - yahoo_away(yd->sess, YAHOO_STATUS_ONVACATION, msg); - yd->current_status = YAHOO_STATUS_ONVACATION; - } else if (!strcmp(state, "Out To Lunch")) { - yahoo_away(yd->sess, YAHOO_STATUS_OUTTOLUNCH, msg); - yd->current_status = YAHOO_STATUS_OUTTOLUNCH; - } else if (!strcmp(state, "Stepped Out")) { - yahoo_away(yd->sess, YAHOO_STATUS_STEPPEDOUT, msg); - yd->current_status = YAHOO_STATUS_STEPPEDOUT; - } else if (!strcmp(state, "Invisible")) { - yahoo_away(yd->sess, YAHOO_STATUS_INVISIBLE, msg); - yd->current_status = YAHOO_STATUS_INVISIBLE; - } else if (!strcmp(state, GAIM_AWAY_CUSTOM)) { - if (gc->is_idle) { - yahoo_away(yd->sess, YAHOO_STATUS_IDLE, NULL); - yd->current_status = YAHOO_STATUS_IDLE; - } else { - yahoo_away(yd->sess, YAHOO_STATUS_AVAILABLE, NULL); - yd->current_status = YAHOO_STATUS_AVAILABLE; - } - gc->away = NULL; - } - } else if (gc->is_idle) { - yahoo_away(yd->sess, YAHOO_STATUS_IDLE, NULL); - yd->current_status = YAHOO_STATUS_IDLE; - } else { - yahoo_away(yd->sess, YAHOO_STATUS_AVAILABLE, NULL); - yd->current_status = YAHOO_STATUS_AVAILABLE; - } -} - -static void yahoo_set_idle(struct gaim_connection *gc, int idle) { - struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; - - if (idle && yd->current_status == YAHOO_STATUS_AVAILABLE) { - yahoo_away(yd->sess, YAHOO_STATUS_IDLE, NULL); - yd->current_status = YAHOO_STATUS_IDLE; - } else if (!idle && yd->current_status == YAHOO_STATUS_IDLE) { - yahoo_back(yd->sess, YAHOO_STATUS_AVAILABLE, NULL); - yd->current_status = YAHOO_STATUS_AVAILABLE; - } -} - -static void yahoo_keepalive(struct gaim_connection *gc) { - yahoo_ping(((struct yahoo_data *)gc->proto_data)->sess); -} - -static void gyahoo_add_buddy(struct gaim_connection *gc, char *name) { - struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; - struct yahoo_group *tmpgroup; - struct group *g = find_group_by_buddy(gc, name); - char *group = NULL; - - if (!yd->logged_in) - return; - - if (g) { - group = g->name; - } else if (yd->sess && yd->sess->groups) { - tmpgroup = yd->sess->groups->data; - group = tmpgroup->name; - } else { - group = "Buddies"; - } - - if (group) - yahoo_add_buddy(yd->sess, yd->active_id, group, normalize(name), ""); -} - -static void yahoo_add_buddies(struct gaim_connection *gc, GList *buddies) { - while (buddies) { - gyahoo_add_buddy(gc, buddies->data); - buddies = buddies->next; - } -} - -static void gyahoo_remove_buddy(struct gaim_connection *gc, char *name) { - struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; - struct group *g = find_group_by_buddy(gc, name); - char *group = NULL; - - if (g) { - group = g->name; - } else if (yd->sess && yd->sess->groups) { - GList *x = yd->sess->groups; - while (x) { - struct yahoo_group *tmpgroup = x->data; - char **bds = tmpgroup->buddies; - while (*bds) { - if (!strcmp(*bds, name)) - break; - bds++; - } - if (*bds) { - group = tmpgroup->name; - break; - } - x = x->next; - } - } else { - group = "Buddies"; - } - - if (group) - yahoo_remove_buddy(yd->sess, yd->active_id, group, name, ""); -} - -static char **yahoo_list_icon(int uc) { - if ((uc >> 1) == YAHOO_STATUS_IDLE) - return status_idle_xpm; - else if (uc == 0) - return status_here_xpm; - return status_away_xpm; -} - -static char *yahoo_get_status_string(enum yahoo_status a) { - switch (a) { - case YAHOO_STATUS_BRB: - return "Be Right Back"; - case YAHOO_STATUS_BUSY: - return "Busy"; - case YAHOO_STATUS_NOTATHOME: - return "Not At Home"; - case YAHOO_STATUS_NOTATDESK: - return "Not At Desk"; - case YAHOO_STATUS_NOTINOFFICE: - return "Not In Office"; - case YAHOO_STATUS_ONPHONE: - return "On Phone"; - case YAHOO_STATUS_ONVACATION: - return "On Vacation"; - case YAHOO_STATUS_OUTTOLUNCH: - return "Out To Lunch"; - case YAHOO_STATUS_STEPPEDOUT: - return "Stepped Out"; - default: - return NULL; - } -} - -static GList *yahoo_buddy_menu(struct gaim_connection *gc, char *who) { - GList *m = NULL; - struct proto_buddy_menu *pbm; - struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; - struct buddy *b = find_buddy(gc, who); /* this should never be null. if it is, - segfault and get the bug report. */ - static char buf[1024]; - - if (!(b->uc & UC_UNAVAILABLE)) - return NULL; - - pbm = g_new0(struct proto_buddy_menu, 1); - if ((b->uc >> 1) != YAHOO_STATUS_CUSTOM) - g_snprintf(buf, sizeof buf, "Status: %s", yahoo_get_status_string(b->uc >> 1)); - else - g_snprintf(buf, sizeof buf, "Custom Status: %s", - (char *)g_hash_table_lookup(yd->hash, b->name)); - pbm->label = buf; - pbm->callback = NULL; - pbm->gc = gc; - m = g_list_append(m, pbm); - - return m; -} - -static GList *yahoo_away_states(struct gaim_connection *gc) { - GList *m = NULL; - - m = g_list_append(m, "Available"); - m = g_list_append(m, "Be Right Back"); - m = g_list_append(m, "Busy"); - m = g_list_append(m, "Not At Home"); - m = g_list_append(m, "Not At Desk"); - m = g_list_append(m, "Not In Office"); - m = g_list_append(m, "On Phone"); - m = g_list_append(m, "On Vacation"); - m = g_list_append(m, "Out To Lunch"); - m = g_list_append(m, "Stepped Out"); - m = g_list_append(m, "Invisible"); - m = g_list_append(m, GAIM_AWAY_CUSTOM); - - return m; -} - -static void yahoo_act_id(gpointer data, char *entry) { - struct gaim_connection *gc = data; - struct yahoo_data *yd = gc->proto_data; - - yahoo_activate_id(yd->sess, entry); - if (yd->active_id) - g_free(yd->active_id); - yd->active_id = g_strdup(entry); - g_snprintf(gc->displayname, sizeof(gc->displayname), "%s", yd->active_id); -} - -static void yahoo_do_action(struct gaim_connection *gc, char *act) { - if (!strcmp(act, "Activate ID")) { - do_prompt_dialog("Activate which ID:", gc->displayname, gc, yahoo_act_id, NULL); - } -} - -static GList *yahoo_actions() { - GList *m = NULL; - - m = g_list_append(m, "Activate ID"); - - return m; -} - -static GList *yahoo_user_opts() -{ - GList *m = NULL; - struct proto_user_opt *puo; - - puo = g_new0(struct proto_user_opt, 1); - puo->label = "Auth Host:"; - puo->def = YAHOO_AUTH_HOST; - puo->pos = USEROPT_AUTHHOST; - m = g_list_append(m, puo); - - puo = g_new0(struct proto_user_opt, 1); - puo->label = "Auth Port:"; - puo->def = "80"; - puo->pos = USEROPT_AUTHPORT; - m = g_list_append(m, puo); - - puo = g_new0(struct proto_user_opt, 1); - puo->label = "Pager Host:"; - puo->def = YAHOO_PAGER_HOST; - puo->pos = USEROPT_PAGERHOST; - m = g_list_append(m, puo); - - puo = g_new0(struct proto_user_opt, 1); - puo->label = "Pager Port:"; - puo->def = "5050"; - puo->pos = USEROPT_PAGERPORT; - m = g_list_append(m, puo); - - return m; -} - -static struct prpl *my_protocol = NULL; - -void yahoo_init(struct prpl *ret) { - /* the NULL's aren't required but they're nice to have */ - ret->protocol = PROTO_YAHOO; - ret->options = OPT_PROTO_MAIL_CHECK; - ret->checkbox = _("Send offline message"); - ret->name = yahoo_name; - ret->list_icon = yahoo_list_icon; - ret->away_states = yahoo_away_states; - ret->actions = yahoo_actions; - ret->do_action = yahoo_do_action; - ret->buddy_menu = yahoo_buddy_menu; - ret->user_opts = yahoo_user_opts; - ret->login = yahoo_login; - ret->close = yahoo_close; - ret->send_im = yahoo_send_im; - ret->set_info = NULL; - ret->get_info = NULL; - ret->set_away = yahoo_set_away; - ret->set_dir = NULL; - ret->get_dir = NULL; - ret->dir_search = NULL; - ret->set_idle = yahoo_set_idle; - ret->change_passwd = NULL; - ret->add_buddy = gyahoo_add_buddy; - ret->add_buddies = yahoo_add_buddies; - ret->remove_buddy = gyahoo_remove_buddy; - ret->add_permit = NULL; - ret->add_deny = NULL; - ret->rem_permit = NULL; - ret->rem_deny = NULL; - ret->set_permit_deny = NULL; - ret->warn = NULL; - ret->keepalive = yahoo_keepalive; - - my_protocol = ret; - - yahoo_socket_notify = yahoo_notify; - yahoo_print = yahoo_debug; - yahoo_connector = yahoo_connect_to; -} - -#ifndef STATIC - -char *gaim_plugin_init(GModule *handle) -{ - load_protocol(yahoo_init, sizeof(struct prpl)); - return NULL; -} - -void gaim_plugin_remove() -{ - struct prpl *p = find_prpl(PROTO_YAHOO); - if (p == my_protocol) - unload_protocol(p); -} - -char *name() -{ - return "Yahoo"; -} - -char *description() -{ - return PRPL_DESC("Yahoo"); -} - -#endif diff -r ab2ca2770d2e -r 37d80035e77f src/protocols/yahoo/yay.h --- a/src/protocols/yahoo/yay.h Tue Nov 06 21:30:31 2001 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,153 +0,0 @@ -/* - * libyay - * - * Copyright (C) 2001 Eric Warmenhoven - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifndef _LIBYAY_H -#define _LIBYAY_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -struct yahoo_session; - -#define YAHOO_PROXY_NONE 0 -#define YAHOO_PROXY_HTTP 1 - -#define YAHOO_AUTH_HOST "msg.edit.yahoo.com" -#define YAHOO_AUTH_PORT 80 -#define YAHOO_PAGER_HOST "cs.yahoo.com" -#define YAHOO_PAGER_PORT 5050 - -enum yahoo_status { - YAHOO_STATUS_AVAILABLE, - YAHOO_STATUS_BRB, - YAHOO_STATUS_BUSY, - YAHOO_STATUS_NOTATHOME, - YAHOO_STATUS_NOTATDESK, - YAHOO_STATUS_NOTINOFFICE, - YAHOO_STATUS_ONPHONE, - YAHOO_STATUS_ONVACATION, - YAHOO_STATUS_OUTTOLUNCH, - YAHOO_STATUS_STEPPEDOUT, - YAHOO_STATUS_INVISIBLE = 12, - YAHOO_STATUS_CUSTOM = 99, - YAHOO_STATUS_IDLE = 999 -}; - -struct yahoo_session *yahoo_new(); -void yahoo_set_proxy(struct yahoo_session *session, int proxy_type, char *proxy_host, int proxy_port); -int yahoo_connect(struct yahoo_session *session, const char *host, int port); -int yahoo_send_login(struct yahoo_session *session, const char *name, const char *password); -int yahoo_major_connect(struct yahoo_session *session, const char *host, int port); -int yahoo_finish_logon(struct yahoo_session *session, enum yahoo_status status); -int yahoo_logoff(struct yahoo_session *session); -int yahoo_disconnect(struct yahoo_session *session); -int yahoo_delete(struct yahoo_session *session); - -int yahoo_activate_id(struct yahoo_session *session, char *id); -int yahoo_deactivate_id(struct yahoo_session *session, char *id); -int yahoo_send_message(struct yahoo_session *session, const char *id, const char *user, const char *msg); -int yahoo_send_message_offline(struct yahoo_session *session, const char *id, - const char *user, const char *msg); -int yahoo_away(struct yahoo_session *session, enum yahoo_status stats, char *msg); -int yahoo_back(struct yahoo_session *session, enum yahoo_status stats, char *msg); -int yahoo_ping(struct yahoo_session *session); - -int yahoo_add_buddy(struct yahoo_session *session, const char *active_id, - const char *group, const char *buddy, const char *message); -int yahoo_remove_buddy(struct yahoo_session *session, const char *active_id, - const char *group, const char *buddy, const char *message); - -extern void (*yahoo_socket_notify)(struct yahoo_session *session, int socket, int type, gboolean status); -#define YAHOO_SOCKET_READ 1 -#define YAHOO_SOCKET_WRITE 2 -void yahoo_socket_handler(struct yahoo_session *session, int socket, int type); - -extern void (*yahoo_print)(struct yahoo_session *session, int level, const char *log); -#define YAHOO_LOG_DEBUG 4 -#define YAHOO_LOG_NOTICE 3 -#define YAHOO_LOG_WARNING 2 -#define YAHOO_LOG_ERROR 1 -#define YAHOO_LOG_CRITICAL 0 - -extern int (*yahoo_connector)(struct yahoo_session *session, const char *host, int port, gpointer data); -int yahoo_connected(struct yahoo_session *session, gpointer data, int fd); - -typedef int (*yahoo_callback)(struct yahoo_session *session, ...); -void yahoo_add_handler(struct yahoo_session *session, int type, yahoo_callback function); -#define YAHOO_HANDLE_DISCONNECT 0 -#define YAHOO_HANDLE_AUTHCONNECT 1 -#define YAHOO_HANDLE_BADPASSWORD 2 -#define YAHOO_HANDLE_LOGINCOOKIE 3 -#define YAHOO_HANDLE_MAINCONNECT 4 -#define YAHOO_HANDLE_ONLINE 5 -#define YAHOO_HANDLE_NEWMAIL 6 -#define YAHOO_HANDLE_MESSAGE 7 -#define YAHOO_HANDLE_BOUNCE 8 -#define YAHOO_HANDLE_STATUS 9 -#define YAHOO_HANDLE_ACTIVATE 10 -#define YAHOO_HANDLE_BUDDYADDED 11 -#define YAHOO_HANDLE_MAX 12 - -struct callback { - yahoo_callback function; - void *data; -}; - -struct yahoo_group { - char *name; - char **buddies; -}; - -struct yahoo_session { - void *user_data; - struct callback callbacks[YAHOO_HANDLE_MAX]; - - int proxy_type; - char *proxy_host; - int proxy_port; - - char *auth_host; - int auth_port; - char *pager_host; - int pager_port; - - char *name; - - char *cookie; - char *login_cookie; - GList *connlist; - - GList *groups; - GList *ignored; - - char **identities; - int mail; - char *login; -}; - -#endif diff -r ab2ca2770d2e -r 37d80035e77f src/protocols/zephyr/zephyr.c --- a/src/protocols/zephyr/zephyr.c Tue Nov 06 21:30:31 2001 +0000 +++ b/src/protocols/zephyr/zephyr.c Tue Nov 06 23:58:24 2001 +0000 @@ -670,7 +670,7 @@ } static void zephyr_add_buddy(struct gaim_connection *gc, char *buddy) { } -static void zephyr_remove_buddy(struct gaim_connection *gc, char *buddy) { } +static void zephyr_remove_buddy(struct gaim_connection *gc, char *buddy, char *group) { } static int zephyr_chat_send(struct gaim_connection *gc, int id, char *im) { diff -r ab2ca2770d2e -r 37d80035e77f src/prpl.h --- a/src/prpl.h Tue Nov 06 21:30:31 2001 +0000 +++ b/src/prpl.h Tue Nov 06 23:58:24 2001 +0000 @@ -127,8 +127,8 @@ void (* change_passwd) (struct gaim_connection *, char *old, char *new); void (* add_buddy) (struct gaim_connection *, char *name); void (* add_buddies) (struct gaim_connection *, GList *buddies); - void (* remove_buddy) (struct gaim_connection *, char *name); - void (* remove_buddies) (struct gaim_connection *, GList *buddies); + void (* remove_buddy) (struct gaim_connection *, char *name, char *group); + void (* remove_buddies) (struct gaim_connection *, GList *buddies, char *group); void (* add_permit) (struct gaim_connection *, char *name); void (* add_deny) (struct gaim_connection *, char *name); void (* rem_permit) (struct gaim_connection *, char *name); diff -r ab2ca2770d2e -r 37d80035e77f src/server.c --- a/src/server.c Tue Nov 06 21:30:31 2001 +0000 +++ b/src/server.c Tue Nov 06 23:58:24 2001 +0000 @@ -250,23 +250,23 @@ } -void serv_remove_buddy(struct gaim_connection *g, char *name) +void serv_remove_buddy(struct gaim_connection *g, char *name, char *group) { if (g && g_slist_find(connections, g) && g->prpl && g->prpl->remove_buddy) - g->prpl->remove_buddy(g, name); + g->prpl->remove_buddy(g, name, group); } -void serv_remove_buddies(struct gaim_connection *gc, GList *g) +void serv_remove_buddies(struct gaim_connection *gc, GList *g, char *group) { if (!g_slist_find(connections, gc)) return; if (!gc->prpl) return; /* how the hell did that happen? */ if (gc->prpl->remove_buddies) - gc->prpl->remove_buddies(gc, g); + gc->prpl->remove_buddies(gc, g, group); else { while (g) { - serv_remove_buddy(gc, g->data); + serv_remove_buddy(gc, g->data, group); g = g->next; } }