# HG changeset patch # User Tim Ringenbach # Date 1088060913 0 # Node ID 3aa848ccf986ca691bd068fc9cc36a4ab5c716ee # Parent 49b7b30f6e4e8d4b43a7b1ff991c50af3e4c5b29 [gaim-migrate @ 10184] *** Danger Will Robinson!!! committer: Tailor Script diff -r 49b7b30f6e4e -r 3aa848ccf986 ChangeLog --- a/ChangeLog Thu Jun 24 05:01:50 2004 +0000 +++ b/ChangeLog Thu Jun 24 07:08:33 2004 +0000 @@ -30,6 +30,8 @@ installed. (Stu Tomlinson) * Headers for gaim-remote now reside in gaim/ instead of gaim-include/. + * Basic YCHT support, which allows joining Yahoo! Chats when + logged in using the web messenger method Bug Fixes: * Switched Yahoo! (not Japan) over to using Web Messenger auth diff -r 49b7b30f6e4e -r 3aa848ccf986 src/protocols/yahoo/Makefile.am --- a/src/protocols/yahoo/Makefile.am Thu Jun 24 05:01:50 2004 +0000 +++ b/src/protocols/yahoo/Makefile.am Thu Jun 24 07:08:33 2004 +0000 @@ -18,7 +18,9 @@ yahoo_friend.c \ yahoo_picture.c \ yahoo_picture.h \ - yahoo_profile.c + yahoo_profile.c \ + ycht.c \ + ycht.h AM_CFLAGS = $(st) diff -r 49b7b30f6e4e -r 3aa848ccf986 src/protocols/yahoo/Makefile.mingw --- a/src/protocols/yahoo/Makefile.mingw Thu Jun 24 05:01:50 2004 +0000 +++ b/src/protocols/yahoo/Makefile.mingw Thu Jun 24 07:08:33 2004 +0000 @@ -75,6 +75,7 @@ yahoo_profile.c \ yahoo_picture.c \ yahoo_friend.c \ + ycht.c \ crypt.c \ util.c diff -r 49b7b30f6e4e -r 3aa848ccf986 src/protocols/yahoo/yahoo.c --- a/src/protocols/yahoo/yahoo.c Thu Jun 24 05:01:50 2004 +0000 +++ b/src/protocols/yahoo/yahoo.c Thu Jun 24 07:08:33 2004 +0000 @@ -39,6 +39,7 @@ #include "yahoo.h" #include "yahoo_friend.h" #include "yahoochat.h" +#include "ycht.h" #include "yahoo_auth.h" #include "yahoo_filexfer.h" #include "yahoo_picture.h" @@ -2417,6 +2418,8 @@ g_free(yd->picture_url); if (yd->picture_upload_todo) yahoo_buddy_icon_upload_data_free(yd->picture_upload_todo); + if (yd->ycht) + ycht_connection_close(yd->ycht); if (gc->inpa) gaim_input_remove(gc->inpa); g_free(yd); @@ -2991,6 +2994,11 @@ if (!yd->chat_online) return; + if (yd->wm) { + ycht_chat_send_keepalive(yd->ycht); + return; + } + pkt = yahoo_packet_new(YAHOO_SERVICE_CHATPING, YAHOO_STATUS_AVAILABLE, 0); yahoo_packet_hash(pkt, 109, gaim_connection_get_display_name(gc)); yahoo_send_packet(yd, pkt); @@ -3336,7 +3344,14 @@ option = gaim_account_option_string_new(_("Chat Room List Url"), "room_list", YAHOO_ROOMLIST_URL); prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); - +#if 0 + option = gaim_account_option_string_new(_("YCHT Host"), "ycht-server", YAHOO_YCHT_HOST); + prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); + + option = gaim_account_option_int_new(_("YCHT Port"), "ycht-port", YAHOO_YCHT_PORT); + prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); +#endif + my_protocol = plugin; yahoo_init_colorht(); diff -r 49b7b30f6e4e -r 3aa848ccf986 src/protocols/yahoo/yahoo.h --- a/src/protocols/yahoo/yahoo.h Thu Jun 24 05:01:50 2004 +0000 +++ b/src/protocols/yahoo/yahoo.h Thu Jun 24 07:08:33 2004 +0000 @@ -150,6 +150,8 @@ guint watcher; }; +struct _YchtConn; + struct yahoo_data { int fd; guchar *rxqueue; @@ -176,6 +178,8 @@ /* ew. we have to check the icon before we connect, * but can't upload it til we're connected. */ struct yahoo_buddy_icon_upload_data *picture_upload_todo; + + struct _YchtConn *ycht; }; struct yahoo_pair { diff -r 49b7b30f6e4e -r 3aa848ccf986 src/protocols/yahoo/yahoochat.c --- a/src/protocols/yahoo/yahoochat.c Thu Jun 24 05:01:50 2004 +0000 +++ b/src/protocols/yahoo/yahoochat.c Thu Jun 24 07:08:33 2004 +0000 @@ -41,6 +41,7 @@ #include "yahoo.h" #include "yahoochat.h" +#include "ycht.h" #define YAHOO_CHAT_ID (1) @@ -53,6 +54,10 @@ struct yahoo_data *yd = gc->proto_data; struct yahoo_packet *pkt; + if (yd->wm) { + ycht_connection_open(gc); + return; + } pkt = yahoo_packet_new(YAHOO_SERVICE_CHATONLINE, YAHOO_STATUS_AVAILABLE,0); yahoo_packet_hash(pkt, 1, gaim_connection_get_display_name(gc)); @@ -70,7 +75,7 @@ } /* this is slow, and different from the gaim_* version in that it (hopefully) won't add a user twice */ -static void yahoo_chat_add_users(GaimConvChat *chat, GList *newusers) +void yahoo_chat_add_users(GaimConvChat *chat, GList *newusers) { GList *users, *i, *j; @@ -84,7 +89,7 @@ } } -static void yahoo_chat_add_user(GaimConvChat *chat, const char *user, const char *reason) +void yahoo_chat_add_user(GaimConvChat *chat, const char *user, const char *reason) { GList *users; @@ -714,6 +719,13 @@ char *eroom; gboolean utf8 = 1; + if (yd->wm) { + g_return_if_fail(yd->ycht != NULL); + + ycht_chat_leave(yd->ycht, room, logout); + return; + } + eroom = yahoo_string_encode(gc, room, &utf8); pkt = yahoo_packet_new(YAHOO_SERVICE_CHATEXIT, YAHOO_STATUS_AVAILABLE, 0); @@ -796,6 +808,12 @@ char *msg1, *msg2, *room2; gboolean utf8 = TRUE; + if (yd->wm) { + g_return_val_if_fail(yd->ycht != NULL, 1); + + return ycht_chat_send(yd->ycht, room, what); + } + msg1 = g_strdup(what); if (meify(msg1, -1)) @@ -835,6 +853,13 @@ char *room2; gboolean utf8 = TRUE; + if (yd->wm) { + g_return_if_fail(yd->ycht != NULL); + + ycht_chat_join(yd->ycht, room); + return; + } + /* apparently room names are always utf8, or else always not utf8, * so we don't have to actually pass the flag in the packet. Or something. */ room2 = yahoo_string_encode(gc, room, &utf8); @@ -860,6 +885,13 @@ char *room2, *msg2 = NULL; gboolean utf8 = TRUE; + if (yd->wm) { + g_return_if_fail(yd->ycht != NULL); + + ycht_chat_send_invite(yd->ycht, room, buddy, msg); + return; + } + room2 = yahoo_string_encode(gc, room, &utf8); if (msg) msg2 = yahoo_string_encode(gc, msg, NULL); @@ -886,6 +918,13 @@ yd = gc->proto_data; + if (yd->wm) { + g_return_if_fail(yd->ycht != NULL); + + ycht_chat_goto_user(yd->ycht, name); + return; + } + if (!yd->chat_online) yahoo_chat_online(gc); diff -r 49b7b30f6e4e -r 3aa848ccf986 src/protocols/yahoo/yahoochat.h --- a/src/protocols/yahoo/yahoochat.h Thu Jun 24 05:01:50 2004 +0000 +++ b/src/protocols/yahoo/yahoochat.h Thu Jun 24 07:08:33 2004 +0000 @@ -54,4 +54,8 @@ void yahoo_roomlist_cancel(GaimRoomlist *list); void yahoo_roomlist_expand_category(GaimRoomlist *list, GaimRoomlistRoom *category); +/* util */ +void yahoo_chat_add_users(GaimConvChat *chat, GList *newusers); +void yahoo_chat_add_user(GaimConvChat *chat, const char *user, const char *reason); + #endif /* _YAHOO_CHAT_H_ */ diff -r 49b7b30f6e4e -r 3aa848ccf986 src/protocols/yahoo/ycht.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/protocols/yahoo/ycht.c Thu Jun 24 07:08:33 2004 +0000 @@ -0,0 +1,600 @@ +/** + * @file ycht.c The Yahoo! protocol plugin, YCHT protocol stuff. + * + * gaim + * + * Copyright (C) 2004 Timothy Ringenbach + * Liberal amounts of code borrowed from the rest of the Yahoo! prpl. + * + * Gaim is the legal property of its developers, whose names are too numerous + * to list here. Please refer to the COPYRIGHT file distributed with this + * source distribution. + * + * 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" +#include "prpl.h" +#include "notify.h" +#include "account.h" +#include "proxy.h" +#include "debug.h" +#include "conversation.h" +#include "util.h" + +#include "yahoo.h" +#include "ycht.h" +#include "yahoochat.h" + +/* + * dword: YCHT + * dword: 0x000000AE + * dword: service + * word: status + * word: size + */ +#define YAHOO_CHAT_ID (1) +/************************************************************************************ + * Functions to process various kinds of packets. + ************************************************************************************/ +static void ycht_process_login(YchtConn *ycht, YchtPkt *pkt) +{ + GaimConnection *gc = ycht->gc; + struct yahoo_data *yd = gc->proto_data; + + if (ycht->logged_in) + return; + + yd->chat_online = TRUE; + ycht->logged_in = TRUE; + + if (ycht->room) + ycht_chat_join(ycht, ycht->room); +} + +static void ycht_process_logout(YchtConn *ycht, YchtPkt *pkt) +{ + GaimConnection *gc = ycht->gc; + struct yahoo_data *yd = gc->proto_data; + + yd->chat_online = FALSE; + ycht->logged_in = FALSE; +} + +static void ycht_process_chatjoin(YchtConn *ycht, YchtPkt *pkt) +{ + char *room, *topic; + GaimConnection *gc = ycht->gc; + GaimConversation *c = NULL; + gboolean new_room = FALSE; + char **members; + int i; + + room = g_list_nth_data(pkt->data, 0); + topic = g_list_nth_data(pkt->data, 1); + if (!g_list_nth_data(pkt->data, 4)) + return; + if (!room) + return; + + members = g_strsplit(g_list_nth_data(pkt->data, 4), "\001", 0); + for (i = 0; members[i]; i++) { + char *tmp = strchr(members[i], '\002'); + if (tmp) + *tmp = '\0'; + } + + + if (g_list_length(pkt->data) > 5) + new_room = TRUE; + + if (new_room && ycht->changing_rooms) { + serv_got_chat_left(gc, YAHOO_CHAT_ID); + ycht->changing_rooms = FALSE; + c = serv_got_joined_chat(gc, YAHOO_CHAT_ID, room); + } else { + c = gaim_find_chat(gc, YAHOO_CHAT_ID); + } + + + if (topic) + gaim_conv_chat_set_topic(GAIM_CONV_CHAT(c), NULL, topic); + + for (i = 0; members[i]; i++) { + if (new_room) { + GList l; + /*if (!strcmp(members[i], gaim_connection_get_display_name(ycht->gc))) + continue;*/ + l.data = members[i]; + l.next = l.prev = NULL; + gaim_conv_chat_add_users(GAIM_CONV_CHAT(c), &l); + } else { + yahoo_chat_add_user(GAIM_CONV_CHAT(c), members[i], NULL); + } + } + + g_strfreev(members); +} + +static void ycht_process_chatpart(YchtConn *ycht, YchtPkt *pkt) +{ + char *room, *who; + + room = g_list_nth_data(pkt->data, 0); + who = g_list_nth_data(pkt->data, 1); + + if (who && room) { + GaimConversation *c = gaim_find_chat(ycht->gc, YAHOO_CHAT_ID); + if (c && !gaim_utf8_strcasecmp(gaim_conversation_get_name(c), room)) + gaim_conv_chat_remove_user(GAIM_CONV_CHAT(c), who, NULL); + + } +} + +static void ycht_progress_chatmsg(YchtConn *ycht, YchtPkt *pkt) +{ + char *who, *what, *msg; + GaimConversation *c; + GaimConnection *gc = ycht->gc; + + who = g_list_nth_data(pkt->data, 1); + what = g_list_nth_data(pkt->data, 2); + + if (!who || !what) + return; + + c = gaim_find_chat(gc, YAHOO_CHAT_ID); + if (!c) + return; + + msg = yahoo_string_decode(gc, what, 1); + what = yahoo_codes_to_html(msg); + g_free(msg); + + if (pkt->service == YCHT_SERVICE_CHATMSG_EMOTE) { + char *tmp = g_strdup_printf("/me %s", what); + g_free(what); + what = tmp; + } + + serv_got_chat_in(gc, YAHOO_CHAT_ID, who, 0, what, time(NULL)); + g_free(what); +} + +static void ycht_progress_online_friends(YchtConn *ycht, YchtPkt *pkt) +{ +#if 0 + GaimConnection *gc = ycht->gc; + struct yahoo_data *yd = gc->proto_data; + + if (ycht->logged_in) + return; + + yd->chat_online = TRUE; + ycht->logged_in = TRUE; + + if (ycht->room) + ycht_chat_join(ycht, ycht->room); +#endif +} + +/***************************************************************************** + * Functions dealing with YCHT packets and their contents directly. + *****************************************************************************/ +static void ycht_packet_dump(const char *data, int len) +{ +#ifdef YAHOO_YCHT_DEBUG + int i; + + gaim_debug(GAIM_DEBUG_MISC, "yahoo", ""); + + for (i = 0; i + 1 < len; i += 2) { + if ((i % 16 == 0) && i) { + gaim_debug(GAIM_DEBUG_MISC, NULL, "\n"); + gaim_debug(GAIM_DEBUG_MISC, "yahoo", ""); + } + + gaim_debug(GAIM_DEBUG_MISC, NULL, "%02hhx%02hhx ", data[i], data[i + 1]); + } + if (i < len) + gaim_debug(GAIM_DEBUG_MISC, NULL, "%02hhx", data[i]); + + gaim_debug(GAIM_DEBUG_MISC, NULL, "\n"); + gaim_debug(GAIM_DEBUG_MISC, "yahoo", ""); + + for (i = 0; i < len; i++) { + if ((i % 16 == 0) && i) { + gaim_debug(GAIM_DEBUG_MISC, NULL, "\n"); + gaim_debug(GAIM_DEBUG_MISC, "yahoo", ""); + } + + if (g_ascii_isprint(data[i])) + gaim_debug(GAIM_DEBUG_MISC, NULL, "%c ", data[i]); + else + gaim_debug(GAIM_DEBUG_MISC, NULL, ". "); + } + + gaim_debug(GAIM_DEBUG_MISC, NULL, "\n"); +#endif +} + +static YchtPkt *ycht_packet_new(guint version, guint service, int status) +{ + YchtPkt *ret; + + ret = g_new0(YchtPkt, 1); + + ret->version = version; + ret->service = service; + ret->status = status; + + return ret; +} + +static void ycht_packet_append(YchtPkt *pkt, const char *str) +{ + g_return_if_fail(pkt != NULL); + g_return_if_fail(str != NULL); + + pkt->data = g_list_append(pkt->data, g_strdup(str)); +} + +static int ycht_packet_length(YchtPkt *pkt) +{ + int ret; + GList *l; + + ret = YCHT_HEADER_LEN; + + for (l = pkt->data; l; l = l->next) { + ret += strlen(l->data); + if (l->next) + ret += strlen(YCHT_SEP); + } + + return ret; +} + +static void ycht_packet_send(YchtConn *ycht, YchtPkt *pkt) +{ + int len, pos; + char *buf; + GList *l; + + g_return_if_fail(ycht != NULL); + g_return_if_fail(pkt != NULL); + g_return_if_fail(ycht->fd != -1); + + pos = 0; + len = ycht_packet_length(pkt); + buf = g_malloc(len); + + memcpy(buf + pos, "YCHT", 4); pos += 4; + pos += yahoo_put32(buf + pos, pkt->version); + pos += yahoo_put32(buf + pos, pkt->service); + pos += yahoo_put16(buf + pos, pkt->status); + pos += yahoo_put16(buf + pos, len - YCHT_HEADER_LEN); + + for (l = pkt->data; l; l = l->next) { + int slen = strlen(l->data); + memcpy(buf + pos, l->data, slen); pos += slen; + + if (l->next) { + memcpy(buf + pos, YCHT_SEP, strlen(YCHT_SEP)); + pos += strlen(YCHT_SEP); + } + } + + write(ycht->fd, buf, len); + g_free(buf); +} + +static void ycht_packet_read(YchtPkt *pkt, const char *buf, int len) +{ + const char *pos = buf; + const char *needle; + char *tmp, *tmp2; + int i = 0; + + while (len > 0 && (needle = g_strstr_len(pos, len, YCHT_SEP))) { + tmp = g_strndup(pos, needle - pos); + pkt->data = g_list_append(pkt->data, tmp); + len -= needle - pos + strlen(YCHT_SEP); + pos = needle + strlen(YCHT_SEP); + tmp2 = g_strescape(tmp, NULL); + gaim_debug_misc("yahoo", "Data[%d]:\t%s\n", i++, tmp2); + g_free(tmp2); + } + + if (len) { + tmp = g_strndup(pos, len); + pkt->data = g_list_append(pkt->data, tmp); + tmp2 = g_strescape(tmp, NULL); + gaim_debug_misc("yahoo", "Data[%d]:\t%s\n", i, tmp2); + g_free(tmp2); + }; + + gaim_debug_misc("yahoo", "--==End of incoming YCHT packet==--\n"); +} + +static void ycht_packet_process(YchtConn *ycht, YchtPkt *pkt) +{ + if (pkt->data && !strncmp(pkt->data->data, "*** Danger Will Robinson!!!", strlen("*** Danger Will Robinson!!!"))) + return; + + switch (pkt->service) { + case YCHT_SERVICE_LOGIN: + ycht_process_login(ycht, pkt); + break; + case YCHT_SERVICE_LOGOUT: + ycht_process_logout(ycht, pkt); + break; + case YCHT_SERVICE_CHATJOIN: + ycht_process_chatjoin(ycht, pkt); + break; + case YCHT_SERVICE_CHATPART: + ycht_process_chatpart(ycht, pkt); + break; + case YCHT_SERVICE_CHATMSG: + case YCHT_SERVICE_CHATMSG_EMOTE: + ycht_progress_chatmsg(ycht, pkt); + break; + case YCHT_SERVICE_ONLINE_FRIENDS: + ycht_progress_online_friends(ycht, pkt); + break; + default: + gaim_debug_warning("yahoo", "YCHT: warning, unhandled service 0x%02x\n", pkt->service); + } +} + +static void ycht_packet_free(YchtPkt *pkt) +{ + GList *l; + + g_return_if_fail(pkt != NULL); + + for (l = pkt->data; l; l = l->next) + g_free(l->data); + g_list_free(pkt->data); + g_free(pkt); +} + +/************************************************************************************ + * Functions dealing with connecting and disconnecting and reading data into YchtPkt + * structs, and all that stuff. + ************************************************************************************/ + +void ycht_connection_close(YchtConn *ycht) +{ + struct yahoo_data *yd = ycht->gc->proto_data; + + if (yd) { + yd->ycht = NULL; + yd->chat_online = FALSE; + } + + if (ycht->fd > 0) + close(ycht->fd); + if (ycht->inpa) + gaim_input_remove(ycht->inpa); + + if (ycht->rxqueue) + g_free(ycht->rxqueue); + + g_free(ycht); +} + +static void ycht_connection_error(YchtConn *ycht, const gchar *error) +{ +#if 0 +/* string freeze */ + gaim_notify_info(ycht->gc, NULL, _("Connection problem with the YCHT server."), error); +#endif + ycht_connection_close(ycht); +} + +static void ycht_pending(gpointer data, gint source, GaimInputCondition cond) +{ + YchtConn *ycht = data; + char buf[1024]; + int len; + + len = read(ycht->fd, buf, sizeof(buf)); + + if (len <= 0) { + /*ycht_connection_error(ycht, _("Unable to read"));*/ + ycht_connection_error(ycht, NULL); + return; + } + + ycht->rxqueue = g_realloc(ycht->rxqueue, len + ycht->rxlen); + memcpy(ycht->rxqueue + ycht->rxlen, buf, len); + ycht->rxlen += len; + + while (1) { + YchtPkt *pkt; + int pos = 0; + int pktlen; + guint service; + guint version; + gint status; + + if (ycht->rxlen < YCHT_HEADER_LEN) + return; + + if (strncmp("YCHT", ycht->rxqueue, 4) != 0) + gaim_debug_error("yahoo", "YCHT: protocol error.\n"); + + pos += 4; /* YCHT */ + + version = yahoo_get32(ycht->rxqueue + pos); pos += 4; + service = yahoo_get32(ycht->rxqueue + pos); pos += 4; + status = yahoo_get16(ycht->rxqueue + pos); pos += 2; + pktlen = yahoo_get16(ycht->rxqueue + pos); pos += 2; + gaim_debug(GAIM_DEBUG_MISC, "yahoo", + "ycht: %d bytes to read, rxlen is %d\n", pktlen, ycht->rxlen); + + if (ycht->rxlen < (YCHT_HEADER_LEN + pktlen)) + return; + + gaim_debug_misc("yahoo", "--==Incoming YCHT packet==--\n"); + gaim_debug(GAIM_DEBUG_MISC, "yahoo", + "YCHT Service: 0x%02x Version: 0x%02x Status: 0x%02x\n", + service, version, status); + ycht_packet_dump(ycht->rxqueue, YCHT_HEADER_LEN + pktlen); + + pkt = ycht_packet_new(version, service, status); + ycht_packet_read(pkt, ycht->rxqueue + pos, pktlen); + + ycht->rxlen -= YCHT_HEADER_LEN + pktlen; + if (ycht->rxlen) { + char *tmp = g_memdup(ycht->rxqueue + YCHT_HEADER_LEN + pktlen, ycht->rxlen); + g_free(ycht->rxqueue); + ycht->rxqueue = tmp; + } else { + g_free(ycht->rxqueue); + ycht->rxqueue = NULL; + } + + ycht_packet_process(ycht, pkt); + + ycht_packet_free(pkt); + } +} + +static void ycht_got_connected(gpointer data, gint source, GaimInputCondition cond) +{ + YchtConn *ycht = data; + GaimConnection *gc = ycht->gc; + struct yahoo_data *yd = gc->proto_data; + YchtPkt *pkt; + char *buf; + + if (source < 0) { + /*ycht_connection_error(ycht, _("Unable to connect."));*/ + ycht_connection_error(ycht, NULL); + return; + } + + ycht->fd = source; + + pkt = ycht_packet_new(YCHT_VERSION, YCHT_SERVICE_LOGIN, 0); + + buf = g_strdup_printf("%s\001Y=%s; T=%s", gaim_connection_get_display_name(gc), yd->cookie_y, yd->cookie_t); + ycht_packet_append(pkt, buf); + g_free(buf); + + ycht_packet_send(ycht, pkt); + + ycht_packet_free(pkt); + + ycht->inpa = gaim_input_add(ycht->fd, GAIM_INPUT_READ, ycht_pending, ycht); +} + +void ycht_connection_open(GaimConnection *gc) +{ + YchtConn *ycht; + struct yahoo_data *yd = gc->proto_data; + GaimAccount *account = gaim_connection_get_account(gc); + + ycht = g_new0(YchtConn, 1); + ycht->gc = gc; + ycht->fd = -1; + + yd->ycht = ycht; + + if (gaim_proxy_connect(account, + gaim_account_get_string(account, "ycht-server", YAHOO_YCHT_HOST), + gaim_account_get_int(account, "ycht-port", YAHOO_YCHT_PORT), + ycht_got_connected, ycht) != 0) + { + /*ycht_connection_error(ycht, _("Connection problem"));*/ + ycht_connection_error(ycht, NULL); + return; + } +} + +/******************************************************************************************* + * These are functions called because the user did something. + *******************************************************************************************/ + +void ycht_chat_join(YchtConn *ycht, const char *room) +{ + YchtPkt *pkt; + char *tmp; + + tmp = g_strdup(room); + if (ycht->room) + g_free(ycht->room); + ycht->room = tmp; + + if (!ycht->logged_in) + return; + + ycht->changing_rooms = TRUE; + pkt = ycht_packet_new(YCHT_VERSION, YCHT_SERVICE_CHATJOIN, 0); + ycht_packet_append(pkt, ycht->room); + ycht_packet_send(ycht, pkt); + ycht_packet_free(pkt); +} + +int ycht_chat_send(YchtConn *ycht, const char *room, const char *what) +{ + YchtPkt *pkt; + char *msg1, *msg2, *buf; + + if (strcmp(room, ycht->room)) + gaim_debug_warning("yahoo", "uhoh, sending to the wrong room!\n"); + + pkt = ycht_packet_new(YCHT_VERSION, YCHT_SERVICE_CHATMSG, 0); + + msg1 = yahoo_html_to_codes(what); + msg2 = yahoo_string_encode(ycht->gc, msg1, NULL); + g_free(msg1); + + buf = g_strdup_printf("%s\001%s", ycht->room, msg2); + ycht_packet_append(pkt, buf); + g_free(msg2); + g_free(buf); + + ycht_packet_send(ycht, pkt); + ycht_packet_free(pkt); + return 1; +} + +void ycht_chat_leave(YchtConn *ycht, const char *room, gboolean logout) +{ + if (logout) + ycht_connection_close(ycht); +} + +void ycht_chat_send_invite(YchtConn *ycht, const char *room, const char *buddy, const char *msg) +{ +} + +void ycht_chat_goto_user(YchtConn *ycht, const char *name) +{ +} + +void ycht_chat_send_keepalive(YchtConn *ycht) +{ + YchtPkt *pkt; + + pkt = ycht_packet_new(YCHT_VERSION, YCHT_SERVICE_PING, 0); + ycht_packet_send(ycht, pkt); + ycht_packet_free(pkt); +} diff -r 49b7b30f6e4e -r 3aa848ccf986 src/protocols/yahoo/ycht.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/protocols/yahoo/ycht.h Thu Jun 24 07:08:33 2004 +0000 @@ -0,0 +1,96 @@ +/** + * @file ycht.h The Yahoo! protocol plugin, YCHT protocol stuff. + * + * gaim + * + * Copyright (C) 2004 Timothy Ringenbach + * + * Gaim is the legal property of its developers, whose names are too numerous + * to list here. Please refer to the COPYRIGHT file distributed with this + * source distribution. + * + * 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 _GAIM_YCHT_H_ +#define _GAIM_YCHT_H_ + +/* #define YAHOO_YCHT_DEBUG */ + +#define YAHOO_YCHT_HOST "jcs3.chat.dcn.yahoo.com" +#define YAHOO_YCHT_PORT 8002 + +#define YCHT_VERSION (0xae) +#define YCHT_HEADER_LEN (0x10) + +typedef enum { + YCHT_SERVICE_LOGIN = 0x01, + YCHT_SERVICE_LOGOUT = 0x02, + YCHT_SERVICE_CHATJOIN = 0x11, + YCHT_SERVICE_CHATPART = 0x12, + YCHT_SERVICE_CHATMSG = 0x41, + YCHT_SERVICE_CHATMSG_EMOTE = 0x43, + YCHT_SERVICE_PING = 0x62, + YCHT_SERVICE_ONLINE_FRIENDS = 0x68, +} ycht_service; +/* +yahoo: YCHT Service: 0x11 Version: 0x100 +yahoo: Data[0]: Linux, FreeBSD, Solaris:1 +yahoo: Data[1]: Questions, problems and discussions about all flavors of Unix. +yahoo: Data[2]: +yahoo: Data[3]: 0 +yahoo: Data[4]: sgooki888\0020\002 \0022769036\00258936\002 +yahoo: --==End of incoming YCHT packet==-- + +yahoo: --==Incoming YCHT packet==-- +yahoo: YCHT Service: 0x12 Version: 0x100 +yahoo: Data[0]: Linux, FreeBSD, Solaris:1 +yahoo: Data[1]: cccc4cccc +yahoo: --==End of incoming YCHT packet==-- + +*/ +#define YCHT_SEP "\xc0\x80" + +typedef struct _YchtConn { + GaimConnection *gc; + gchar *room; + int room_id; + gint fd; + gint inpa; + gboolean logged_in; + gboolean changing_rooms; + guchar *rxqueue; + guint rxlen; +} YchtConn; + +typedef struct { + guint version; + guint service; + gint status; + GList *data; +} YchtPkt; + + +void ycht_connection_open(GaimConnection *gc); +void ycht_connection_close(YchtConn *ycht); + +void ycht_chat_join(YchtConn *ycht, const char *room); +int ycht_chat_send(YchtConn *ycht, const char *room, const char *what); +void ycht_chat_leave(YchtConn *ycht, const char *room, gboolean logout); +void ycht_chat_send_invite(YchtConn *ycht, const char *room, const char *buddy, const char *msg); +void ycht_chat_goto_user(YchtConn *ycht, const char *name); +void ycht_chat_send_keepalive(YchtConn *ycht); + +#endif /* _GAIM_YCHT_H_ */