Mercurial > pidgin
annotate src/protocols/yahoo/ycht.c @ 13253:87a7c3077c19
[gaim-migrate @ 15619]
More cleaning up of oscar. Renamed some functions to be more clear.
Got rid of some stuff that wasn't used. Inlined some small things
in conn.c that were only used once.
The goals of all this are
1. Non-blocking I/O for all connections
2. p2p stuff won't use the same struct as oscar connections, because
that's stupid
3. The oscar PRPL should be less scary
committer: Tailor Script <tailor@pidgin.im>
| author | Mark Doliner <mark@kingant.net> |
|---|---|
| date | Sun, 12 Feb 2006 21:27:04 +0000 |
| parents | 33bef17125c2 |
| children | 10e8eb6a4910 |
| rev | line source |
|---|---|
| 9376 | 1 /** |
| 2 * @file ycht.c The Yahoo! protocol plugin, YCHT protocol stuff. | |
| 3 * | |
| 4 * gaim | |
| 5 * | |
| 6 * Copyright (C) 2004 Timothy Ringenbach <omarvo@hotmail.com> | |
| 7 * Liberal amounts of code borrowed from the rest of the Yahoo! prpl. | |
| 8 * | |
| 9 * Gaim is the legal property of its developers, whose names are too numerous | |
| 10 * to list here. Please refer to the COPYRIGHT file distributed with this | |
| 11 * source distribution. | |
| 12 * | |
| 13 * This program is free software; you can redistribute it and/or modify | |
| 14 * it under the terms of the GNU General Public License as published by | |
| 15 * the Free Software Foundation; either version 2 of the License, or | |
| 16 * (at your option) any later version. | |
| 17 * | |
| 18 * This program is distributed in the hope that it will be useful, | |
| 19 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 21 * GNU General Public License for more details. | |
| 22 * | |
| 23 * You should have received a copy of the GNU General Public License | |
| 24 * along with this program; if not, write to the Free Software | |
| 25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
| 26 */ | |
| 27 | |
| 28 #include <string.h> | |
| 29 | |
| 30 #include "internal.h" | |
| 31 #include "prpl.h" | |
| 32 #include "notify.h" | |
| 33 #include "account.h" | |
| 34 #include "proxy.h" | |
| 35 #include "debug.h" | |
| 36 #include "conversation.h" | |
| 37 #include "util.h" | |
| 38 | |
| 39 #include "yahoo.h" | |
| 10392 | 40 #include "yahoo_packet.h" |
| 9376 | 41 #include "ycht.h" |
| 42 #include "yahoochat.h" | |
| 43 | |
| 44 /* | |
| 45 * dword: YCHT | |
| 46 * dword: 0x000000AE | |
| 47 * dword: service | |
| 48 * word: status | |
| 49 * word: size | |
| 50 */ | |
| 51 #define YAHOO_CHAT_ID (1) | |
| 52 /************************************************************************************ | |
| 53 * Functions to process various kinds of packets. | |
| 54 ************************************************************************************/ | |
| 55 static void ycht_process_login(YchtConn *ycht, YchtPkt *pkt) | |
| 56 { | |
| 57 GaimConnection *gc = ycht->gc; | |
| 58 struct yahoo_data *yd = gc->proto_data; | |
| 59 | |
| 60 if (ycht->logged_in) | |
| 61 return; | |
| 62 | |
| 63 yd->chat_online = TRUE; | |
| 64 ycht->logged_in = TRUE; | |
| 65 | |
| 66 if (ycht->room) | |
| 67 ycht_chat_join(ycht, ycht->room); | |
| 68 } | |
| 69 | |
| 70 static void ycht_process_logout(YchtConn *ycht, YchtPkt *pkt) | |
| 71 { | |
| 72 GaimConnection *gc = ycht->gc; | |
| 73 struct yahoo_data *yd = gc->proto_data; | |
| 74 | |
| 75 yd->chat_online = FALSE; | |
| 76 ycht->logged_in = FALSE; | |
| 77 } | |
| 78 | |
| 79 static void ycht_process_chatjoin(YchtConn *ycht, YchtPkt *pkt) | |
| 80 { | |
| 81 char *room, *topic; | |
| 82 GaimConnection *gc = ycht->gc; | |
| 83 GaimConversation *c = NULL; | |
| 84 gboolean new_room = FALSE; | |
| 85 char **members; | |
| 86 int i; | |
| 87 | |
| 88 room = g_list_nth_data(pkt->data, 0); | |
| 89 topic = g_list_nth_data(pkt->data, 1); | |
| 90 if (!g_list_nth_data(pkt->data, 4)) | |
| 91 return; | |
| 92 if (!room) | |
| 93 return; | |
| 94 | |
| 95 members = g_strsplit(g_list_nth_data(pkt->data, 4), "\001", 0); | |
| 96 for (i = 0; members[i]; i++) { | |
| 97 char *tmp = strchr(members[i], '\002'); | |
| 98 if (tmp) | |
| 99 *tmp = '\0'; | |
| 100 } | |
| 101 | |
| 102 if (g_list_length(pkt->data) > 5) | |
| 103 new_room = TRUE; | |
| 104 | |
| 105 if (new_room && ycht->changing_rooms) { | |
| 106 serv_got_chat_left(gc, YAHOO_CHAT_ID); | |
| 107 ycht->changing_rooms = FALSE; | |
| 108 c = serv_got_joined_chat(gc, YAHOO_CHAT_ID, room); | |
| 109 } else { | |
| 110 c = gaim_find_chat(gc, YAHOO_CHAT_ID); | |
| 111 } | |
| 112 | |
| 113 if (topic) | |
| 114 gaim_conv_chat_set_topic(GAIM_CONV_CHAT(c), NULL, topic); | |
| 115 | |
| 116 for (i = 0; members[i]; i++) { | |
| 117 if (new_room) { | |
| 118 /*if (!strcmp(members[i], gaim_connection_get_display_name(ycht->gc))) | |
| 119 continue;*/ | |
| 9846 | 120 gaim_conv_chat_add_user(GAIM_CONV_CHAT(c), members[i], NULL, GAIM_CBFLAGS_NONE, TRUE); |
| 9376 | 121 } else { |
| 122 yahoo_chat_add_user(GAIM_CONV_CHAT(c), members[i], NULL); | |
| 123 } | |
| 124 } | |
| 125 | |
| 126 g_strfreev(members); | |
| 127 } | |
| 128 | |
| 129 static void ycht_process_chatpart(YchtConn *ycht, YchtPkt *pkt) | |
| 130 { | |
| 131 char *room, *who; | |
| 132 | |
| 133 room = g_list_nth_data(pkt->data, 0); | |
| 134 who = g_list_nth_data(pkt->data, 1); | |
| 135 | |
| 136 if (who && room) { | |
| 137 GaimConversation *c = gaim_find_chat(ycht->gc, YAHOO_CHAT_ID); | |
| 138 if (c && !gaim_utf8_strcasecmp(gaim_conversation_get_name(c), room)) | |
| 139 gaim_conv_chat_remove_user(GAIM_CONV_CHAT(c), who, NULL); | |
| 140 | |
| 141 } | |
| 142 } | |
| 143 | |
| 144 static void ycht_progress_chatmsg(YchtConn *ycht, YchtPkt *pkt) | |
| 145 { | |
| 146 char *who, *what, *msg; | |
| 147 GaimConversation *c; | |
| 148 GaimConnection *gc = ycht->gc; | |
| 149 | |
| 150 who = g_list_nth_data(pkt->data, 1); | |
| 151 what = g_list_nth_data(pkt->data, 2); | |
| 152 | |
| 153 if (!who || !what) | |
| 154 return; | |
| 155 | |
| 156 c = gaim_find_chat(gc, YAHOO_CHAT_ID); | |
| 157 if (!c) | |
| 158 return; | |
| 159 | |
| 160 msg = yahoo_string_decode(gc, what, 1); | |
| 161 what = yahoo_codes_to_html(msg); | |
| 162 g_free(msg); | |
| 163 | |
| 164 if (pkt->service == YCHT_SERVICE_CHATMSG_EMOTE) { | |
| 165 char *tmp = g_strdup_printf("/me %s", what); | |
| 166 g_free(what); | |
| 167 what = tmp; | |
| 168 } | |
| 169 | |
| 170 serv_got_chat_in(gc, YAHOO_CHAT_ID, who, 0, what, time(NULL)); | |
| 171 g_free(what); | |
| 172 } | |
| 173 | |
| 174 static void ycht_progress_online_friends(YchtConn *ycht, YchtPkt *pkt) | |
| 175 { | |
| 176 #if 0 | |
| 177 GaimConnection *gc = ycht->gc; | |
| 178 struct yahoo_data *yd = gc->proto_data; | |
| 179 | |
| 180 if (ycht->logged_in) | |
| 181 return; | |
| 182 | |
| 183 yd->chat_online = TRUE; | |
| 184 ycht->logged_in = TRUE; | |
| 185 | |
| 186 if (ycht->room) | |
| 187 ycht_chat_join(ycht, ycht->room); | |
| 188 #endif | |
| 189 } | |
| 190 | |
| 191 /***************************************************************************** | |
| 192 * Functions dealing with YCHT packets and their contents directly. | |
| 193 *****************************************************************************/ | |
| 11318 | 194 static void ycht_packet_dump(const guchar *data, int len) |
| 9376 | 195 { |
| 196 #ifdef YAHOO_YCHT_DEBUG | |
| 197 int i; | |
| 198 | |
| 199 gaim_debug(GAIM_DEBUG_MISC, "yahoo", ""); | |
| 200 | |
| 201 for (i = 0; i + 1 < len; i += 2) { | |
| 202 if ((i % 16 == 0) && i) { | |
| 203 gaim_debug(GAIM_DEBUG_MISC, NULL, "\n"); | |
| 204 gaim_debug(GAIM_DEBUG_MISC, "yahoo", ""); | |
| 205 } | |
| 206 | |
| 207 gaim_debug(GAIM_DEBUG_MISC, NULL, "%02hhx%02hhx ", data[i], data[i + 1]); | |
| 208 } | |
| 209 if (i < len) | |
| 210 gaim_debug(GAIM_DEBUG_MISC, NULL, "%02hhx", data[i]); | |
| 211 | |
| 212 gaim_debug(GAIM_DEBUG_MISC, NULL, "\n"); | |
| 213 gaim_debug(GAIM_DEBUG_MISC, "yahoo", ""); | |
| 214 | |
| 215 for (i = 0; i < len; i++) { | |
| 216 if ((i % 16 == 0) && i) { | |
| 217 gaim_debug(GAIM_DEBUG_MISC, NULL, "\n"); | |
| 218 gaim_debug(GAIM_DEBUG_MISC, "yahoo", ""); | |
| 219 } | |
| 220 | |
| 221 if (g_ascii_isprint(data[i])) | |
| 222 gaim_debug(GAIM_DEBUG_MISC, NULL, "%c ", data[i]); | |
| 223 else | |
| 224 gaim_debug(GAIM_DEBUG_MISC, NULL, ". "); | |
| 225 } | |
| 226 | |
| 227 gaim_debug(GAIM_DEBUG_MISC, NULL, "\n"); | |
| 228 #endif | |
| 229 } | |
| 230 | |
| 231 static YchtPkt *ycht_packet_new(guint version, guint service, int status) | |
| 232 { | |
| 233 YchtPkt *ret; | |
| 234 | |
| 235 ret = g_new0(YchtPkt, 1); | |
| 236 | |
| 237 ret->version = version; | |
| 238 ret->service = service; | |
| 239 ret->status = status; | |
| 240 | |
| 241 return ret; | |
| 242 } | |
| 243 | |
| 244 static void ycht_packet_append(YchtPkt *pkt, const char *str) | |
| 245 { | |
| 246 g_return_if_fail(pkt != NULL); | |
| 247 g_return_if_fail(str != NULL); | |
| 248 | |
| 249 pkt->data = g_list_append(pkt->data, g_strdup(str)); | |
| 250 } | |
| 251 | |
| 252 static int ycht_packet_length(YchtPkt *pkt) | |
| 253 { | |
| 254 int ret; | |
| 255 GList *l; | |
| 256 | |
| 257 ret = YCHT_HEADER_LEN; | |
| 258 | |
| 259 for (l = pkt->data; l; l = l->next) { | |
| 260 ret += strlen(l->data); | |
| 261 if (l->next) | |
| 262 ret += strlen(YCHT_SEP); | |
| 263 } | |
| 264 | |
| 265 return ret; | |
| 266 } | |
| 267 | |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11644
diff
changeset
|
268 static void ycht_packet_send_write_cb(gpointer data, gint source, GaimInputCondition cond) |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11644
diff
changeset
|
269 { |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11644
diff
changeset
|
270 YchtConn *ycht = data; |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11644
diff
changeset
|
271 int ret, writelen; |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11644
diff
changeset
|
272 |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11644
diff
changeset
|
273 writelen = gaim_circ_buffer_get_max_read(ycht->txbuf); |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11644
diff
changeset
|
274 |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11644
diff
changeset
|
275 if (writelen == 0) { |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11644
diff
changeset
|
276 gaim_input_remove(ycht->tx_handler); |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11644
diff
changeset
|
277 ycht->tx_handler = 0; |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11644
diff
changeset
|
278 return; |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11644
diff
changeset
|
279 } |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11644
diff
changeset
|
280 |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11644
diff
changeset
|
281 ret = write(ycht->fd, ycht->txbuf->outptr, writelen); |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11644
diff
changeset
|
282 |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11644
diff
changeset
|
283 if (ret < 0 && errno == EAGAIN) |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11644
diff
changeset
|
284 return; |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11644
diff
changeset
|
285 else if (ret <= 0) { |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11644
diff
changeset
|
286 /* TODO: error handling */ |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11644
diff
changeset
|
287 /* |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11644
diff
changeset
|
288 gaim_connection_error(gaim_account_get_connection(irc->account), |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11644
diff
changeset
|
289 _("Server has disconnected")); |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11644
diff
changeset
|
290 */ |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11644
diff
changeset
|
291 return; |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11644
diff
changeset
|
292 } |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11644
diff
changeset
|
293 |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11644
diff
changeset
|
294 gaim_circ_buffer_mark_read(ycht->txbuf, ret); |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11644
diff
changeset
|
295 |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11644
diff
changeset
|
296 } |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11644
diff
changeset
|
297 |
| 9376 | 298 static void ycht_packet_send(YchtConn *ycht, YchtPkt *pkt) |
| 299 { | |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11644
diff
changeset
|
300 int len, pos, written; |
| 9376 | 301 char *buf; |
| 302 GList *l; | |
| 303 | |
| 304 g_return_if_fail(ycht != NULL); | |
| 305 g_return_if_fail(pkt != NULL); | |
| 306 g_return_if_fail(ycht->fd != -1); | |
| 307 | |
| 308 pos = 0; | |
| 309 len = ycht_packet_length(pkt); | |
| 310 buf = g_malloc(len); | |
| 311 | |
| 312 memcpy(buf + pos, "YCHT", 4); pos += 4; | |
| 313 pos += yahoo_put32(buf + pos, pkt->version); | |
| 314 pos += yahoo_put32(buf + pos, pkt->service); | |
| 315 pos += yahoo_put16(buf + pos, pkt->status); | |
| 316 pos += yahoo_put16(buf + pos, len - YCHT_HEADER_LEN); | |
| 317 | |
| 318 for (l = pkt->data; l; l = l->next) { | |
| 319 int slen = strlen(l->data); | |
| 320 memcpy(buf + pos, l->data, slen); pos += slen; | |
| 321 | |
| 322 if (l->next) { | |
| 323 memcpy(buf + pos, YCHT_SEP, strlen(YCHT_SEP)); | |
| 324 pos += strlen(YCHT_SEP); | |
| 325 } | |
| 326 } | |
| 327 | |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11644
diff
changeset
|
328 if (!ycht->tx_handler) |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11644
diff
changeset
|
329 written = write(ycht->fd, buf, len); |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11644
diff
changeset
|
330 else { |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11644
diff
changeset
|
331 written = -1; |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11644
diff
changeset
|
332 errno = EAGAIN; |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11644
diff
changeset
|
333 } |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11644
diff
changeset
|
334 |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11644
diff
changeset
|
335 if (written < 0 && errno == EAGAIN) |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11644
diff
changeset
|
336 written = 0; |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11644
diff
changeset
|
337 else if (written <= 0) { |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11644
diff
changeset
|
338 /* TODO: Error handling (was none before NBIO changes) */ |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11644
diff
changeset
|
339 written = 0; |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11644
diff
changeset
|
340 } |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11644
diff
changeset
|
341 |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11644
diff
changeset
|
342 if (written < len) { |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11644
diff
changeset
|
343 if (!ycht->tx_handler) |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11644
diff
changeset
|
344 ycht->tx_handler = gaim_input_add(ycht->fd, |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11644
diff
changeset
|
345 GAIM_INPUT_WRITE, ycht_packet_send_write_cb, |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11644
diff
changeset
|
346 ycht); |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11644
diff
changeset
|
347 gaim_circ_buffer_append(ycht->txbuf, buf + written, |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11644
diff
changeset
|
348 len - written); |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11644
diff
changeset
|
349 } |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11644
diff
changeset
|
350 |
| 9376 | 351 g_free(buf); |
| 352 } | |
| 353 | |
| 354 static void ycht_packet_read(YchtPkt *pkt, const char *buf, int len) | |
| 355 { | |
| 356 const char *pos = buf; | |
| 357 const char *needle; | |
| 358 char *tmp, *tmp2; | |
| 359 int i = 0; | |
| 360 | |
| 361 while (len > 0 && (needle = g_strstr_len(pos, len, YCHT_SEP))) { | |
| 362 tmp = g_strndup(pos, needle - pos); | |
| 363 pkt->data = g_list_append(pkt->data, tmp); | |
| 364 len -= needle - pos + strlen(YCHT_SEP); | |
| 365 pos = needle + strlen(YCHT_SEP); | |
| 366 tmp2 = g_strescape(tmp, NULL); | |
| 367 gaim_debug_misc("yahoo", "Data[%d]:\t%s\n", i++, tmp2); | |
| 368 g_free(tmp2); | |
| 369 } | |
| 370 | |
| 371 if (len) { | |
| 372 tmp = g_strndup(pos, len); | |
| 373 pkt->data = g_list_append(pkt->data, tmp); | |
| 374 tmp2 = g_strescape(tmp, NULL); | |
| 375 gaim_debug_misc("yahoo", "Data[%d]:\t%s\n", i, tmp2); | |
| 376 g_free(tmp2); | |
| 377 }; | |
| 378 | |
| 379 gaim_debug_misc("yahoo", "--==End of incoming YCHT packet==--\n"); | |
| 380 } | |
| 381 | |
| 382 static void ycht_packet_process(YchtConn *ycht, YchtPkt *pkt) | |
| 383 { | |
| 384 if (pkt->data && !strncmp(pkt->data->data, "*** Danger Will Robinson!!!", strlen("*** Danger Will Robinson!!!"))) | |
| 385 return; | |
| 386 | |
| 387 switch (pkt->service) { | |
| 388 case YCHT_SERVICE_LOGIN: | |
| 389 ycht_process_login(ycht, pkt); | |
| 390 break; | |
| 391 case YCHT_SERVICE_LOGOUT: | |
| 392 ycht_process_logout(ycht, pkt); | |
| 393 break; | |
| 394 case YCHT_SERVICE_CHATJOIN: | |
| 395 ycht_process_chatjoin(ycht, pkt); | |
| 396 break; | |
| 397 case YCHT_SERVICE_CHATPART: | |
| 398 ycht_process_chatpart(ycht, pkt); | |
| 399 break; | |
| 400 case YCHT_SERVICE_CHATMSG: | |
| 401 case YCHT_SERVICE_CHATMSG_EMOTE: | |
| 402 ycht_progress_chatmsg(ycht, pkt); | |
| 403 break; | |
| 404 case YCHT_SERVICE_ONLINE_FRIENDS: | |
| 405 ycht_progress_online_friends(ycht, pkt); | |
| 406 break; | |
| 407 default: | |
| 408 gaim_debug_warning("yahoo", "YCHT: warning, unhandled service 0x%02x\n", pkt->service); | |
| 409 } | |
| 410 } | |
| 411 | |
| 412 static void ycht_packet_free(YchtPkt *pkt) | |
| 413 { | |
| 414 GList *l; | |
| 415 | |
| 416 g_return_if_fail(pkt != NULL); | |
| 417 | |
| 418 for (l = pkt->data; l; l = l->next) | |
| 419 g_free(l->data); | |
| 420 g_list_free(pkt->data); | |
| 421 g_free(pkt); | |
| 422 } | |
| 423 | |
| 424 /************************************************************************************ | |
| 425 * Functions dealing with connecting and disconnecting and reading data into YchtPkt | |
| 426 * structs, and all that stuff. | |
| 427 ************************************************************************************/ | |
| 428 | |
| 429 void ycht_connection_close(YchtConn *ycht) | |
| 430 { | |
| 431 struct yahoo_data *yd = ycht->gc->proto_data; | |
| 432 | |
| 433 if (yd) { | |
| 434 yd->ycht = NULL; | |
| 435 yd->chat_online = FALSE; | |
| 436 } | |
| 437 | |
| 438 if (ycht->fd > 0) | |
| 439 close(ycht->fd); | |
| 440 if (ycht->inpa) | |
| 441 gaim_input_remove(ycht->inpa); | |
| 442 | |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11644
diff
changeset
|
443 if (ycht->tx_handler) |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11644
diff
changeset
|
444 gaim_input_remove(ycht->tx_handler); |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11644
diff
changeset
|
445 |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11644
diff
changeset
|
446 gaim_circ_buffer_destroy(ycht->txbuf); |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11644
diff
changeset
|
447 |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11644
diff
changeset
|
448 g_free(ycht->rxqueue); |
| 9376 | 449 |
| 450 g_free(ycht); | |
| 451 } | |
| 452 | |
| 453 static void ycht_connection_error(YchtConn *ycht, const gchar *error) | |
| 454 { | |
| 9397 | 455 |
| 9376 | 456 gaim_notify_info(ycht->gc, NULL, _("Connection problem with the YCHT server."), error); |
| 457 ycht_connection_close(ycht); | |
| 458 } | |
| 459 | |
| 460 static void ycht_pending(gpointer data, gint source, GaimInputCondition cond) | |
| 461 { | |
| 462 YchtConn *ycht = data; | |
| 463 char buf[1024]; | |
| 464 int len; | |
| 465 | |
| 466 len = read(ycht->fd, buf, sizeof(buf)); | |
| 467 | |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11644
diff
changeset
|
468 if (len < 0 && errno == EAGAIN) |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11644
diff
changeset
|
469 return; |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11644
diff
changeset
|
470 |
| 9376 | 471 if (len <= 0) { |
| 9397 | 472 ycht_connection_error(ycht, _("Unable to read")); |
| 9376 | 473 return; |
| 474 } | |
| 475 | |
| 476 ycht->rxqueue = g_realloc(ycht->rxqueue, len + ycht->rxlen); | |
| 477 memcpy(ycht->rxqueue + ycht->rxlen, buf, len); | |
| 478 ycht->rxlen += len; | |
| 479 | |
| 480 while (1) { | |
| 481 YchtPkt *pkt; | |
| 482 int pos = 0; | |
| 483 int pktlen; | |
| 484 guint service; | |
| 485 guint version; | |
| 486 gint status; | |
| 487 | |
| 488 if (ycht->rxlen < YCHT_HEADER_LEN) | |
| 489 return; | |
| 490 | |
| 11318 | 491 if (strncmp("YCHT", (char *)ycht->rxqueue, 4) != 0) |
| 9376 | 492 gaim_debug_error("yahoo", "YCHT: protocol error.\n"); |
| 493 | |
| 494 pos += 4; /* YCHT */ | |
| 495 | |
| 496 version = yahoo_get32(ycht->rxqueue + pos); pos += 4; | |
| 497 service = yahoo_get32(ycht->rxqueue + pos); pos += 4; | |
| 498 status = yahoo_get16(ycht->rxqueue + pos); pos += 2; | |
| 499 pktlen = yahoo_get16(ycht->rxqueue + pos); pos += 2; | |
| 500 gaim_debug(GAIM_DEBUG_MISC, "yahoo", | |
| 501 "ycht: %d bytes to read, rxlen is %d\n", pktlen, ycht->rxlen); | |
| 502 | |
| 503 if (ycht->rxlen < (YCHT_HEADER_LEN + pktlen)) | |
| 504 return; | |
| 505 | |
| 506 gaim_debug_misc("yahoo", "--==Incoming YCHT packet==--\n"); | |
| 507 gaim_debug(GAIM_DEBUG_MISC, "yahoo", | |
| 508 "YCHT Service: 0x%02x Version: 0x%02x Status: 0x%02x\n", | |
| 509 service, version, status); | |
| 510 ycht_packet_dump(ycht->rxqueue, YCHT_HEADER_LEN + pktlen); | |
| 511 | |
| 512 pkt = ycht_packet_new(version, service, status); | |
| 11318 | 513 ycht_packet_read(pkt, (char *)ycht->rxqueue + pos, pktlen); |
| 9376 | 514 |
| 515 ycht->rxlen -= YCHT_HEADER_LEN + pktlen; | |
| 516 if (ycht->rxlen) { | |
| 11318 | 517 guchar *tmp = g_memdup(ycht->rxqueue + YCHT_HEADER_LEN + pktlen, ycht->rxlen); |
| 9376 | 518 g_free(ycht->rxqueue); |
| 519 ycht->rxqueue = tmp; | |
| 520 } else { | |
| 521 g_free(ycht->rxqueue); | |
| 522 ycht->rxqueue = NULL; | |
| 523 } | |
| 524 | |
| 525 ycht_packet_process(ycht, pkt); | |
| 526 | |
| 527 ycht_packet_free(pkt); | |
| 528 } | |
| 529 } | |
| 530 | |
| 531 static void ycht_got_connected(gpointer data, gint source, GaimInputCondition cond) | |
| 532 { | |
| 533 YchtConn *ycht = data; | |
| 534 GaimConnection *gc = ycht->gc; | |
| 535 struct yahoo_data *yd = gc->proto_data; | |
| 536 YchtPkt *pkt; | |
| 537 char *buf; | |
| 538 | |
| 539 if (source < 0) { | |
| 9397 | 540 ycht_connection_error(ycht, _("Unable to connect.")); |
| 9376 | 541 return; |
| 542 } | |
| 543 | |
| 544 ycht->fd = source; | |
| 545 | |
| 546 pkt = ycht_packet_new(YCHT_VERSION, YCHT_SERVICE_LOGIN, 0); | |
| 547 | |
| 548 buf = g_strdup_printf("%s\001Y=%s; T=%s", gaim_connection_get_display_name(gc), yd->cookie_y, yd->cookie_t); | |
| 549 ycht_packet_append(pkt, buf); | |
| 550 g_free(buf); | |
| 551 | |
| 552 ycht_packet_send(ycht, pkt); | |
| 553 | |
| 554 ycht_packet_free(pkt); | |
| 555 | |
| 556 ycht->inpa = gaim_input_add(ycht->fd, GAIM_INPUT_READ, ycht_pending, ycht); | |
| 557 } | |
| 558 | |
| 559 void ycht_connection_open(GaimConnection *gc) | |
| 560 { | |
| 561 YchtConn *ycht; | |
| 562 struct yahoo_data *yd = gc->proto_data; | |
| 563 GaimAccount *account = gaim_connection_get_account(gc); | |
| 564 | |
| 565 ycht = g_new0(YchtConn, 1); | |
| 566 ycht->gc = gc; | |
| 567 ycht->fd = -1; | |
| 568 | |
| 569 yd->ycht = ycht; | |
| 570 | |
| 571 if (gaim_proxy_connect(account, | |
| 572 gaim_account_get_string(account, "ycht-server", YAHOO_YCHT_HOST), | |
| 573 gaim_account_get_int(account, "ycht-port", YAHOO_YCHT_PORT), | |
| 574 ycht_got_connected, ycht) != 0) | |
| 575 { | |
| 9397 | 576 ycht_connection_error(ycht, _("Connection problem")); |
| 9376 | 577 return; |
| 578 } | |
| 579 } | |
| 580 | |
| 581 /******************************************************************************************* | |
| 582 * These are functions called because the user did something. | |
| 583 *******************************************************************************************/ | |
| 584 | |
| 585 void ycht_chat_join(YchtConn *ycht, const char *room) | |
| 586 { | |
| 587 YchtPkt *pkt; | |
| 588 char *tmp; | |
| 589 | |
| 590 tmp = g_strdup(room); | |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11644
diff
changeset
|
591 g_free(ycht->room); |
| 9376 | 592 ycht->room = tmp; |
| 593 | |
| 594 if (!ycht->logged_in) | |
| 595 return; | |
| 596 | |
| 597 ycht->changing_rooms = TRUE; | |
| 598 pkt = ycht_packet_new(YCHT_VERSION, YCHT_SERVICE_CHATJOIN, 0); | |
| 599 ycht_packet_append(pkt, ycht->room); | |
| 600 ycht_packet_send(ycht, pkt); | |
| 601 ycht_packet_free(pkt); | |
| 602 } | |
| 603 | |
| 604 int ycht_chat_send(YchtConn *ycht, const char *room, const char *what) | |
| 605 { | |
| 606 YchtPkt *pkt; | |
| 607 char *msg1, *msg2, *buf; | |
| 608 | |
| 609 if (strcmp(room, ycht->room)) | |
| 610 gaim_debug_warning("yahoo", "uhoh, sending to the wrong room!\n"); | |
| 611 | |
| 612 pkt = ycht_packet_new(YCHT_VERSION, YCHT_SERVICE_CHATMSG, 0); | |
| 613 | |
| 614 msg1 = yahoo_html_to_codes(what); | |
| 615 msg2 = yahoo_string_encode(ycht->gc, msg1, NULL); | |
| 616 g_free(msg1); | |
| 617 | |
| 618 buf = g_strdup_printf("%s\001%s", ycht->room, msg2); | |
| 619 ycht_packet_append(pkt, buf); | |
| 620 g_free(msg2); | |
| 621 g_free(buf); | |
| 622 | |
| 623 ycht_packet_send(ycht, pkt); | |
| 624 ycht_packet_free(pkt); | |
| 625 return 1; | |
| 626 } | |
| 627 | |
| 628 void ycht_chat_leave(YchtConn *ycht, const char *room, gboolean logout) | |
| 629 { | |
| 630 if (logout) | |
| 631 ycht_connection_close(ycht); | |
| 632 } | |
| 633 | |
| 634 void ycht_chat_send_invite(YchtConn *ycht, const char *room, const char *buddy, const char *msg) | |
| 635 { | |
| 636 } | |
| 637 | |
| 638 void ycht_chat_goto_user(YchtConn *ycht, const char *name) | |
| 639 { | |
| 640 } | |
| 641 | |
| 642 void ycht_chat_send_keepalive(YchtConn *ycht) | |
| 643 { | |
| 644 YchtPkt *pkt; | |
| 645 | |
| 646 pkt = ycht_packet_new(YCHT_VERSION, YCHT_SERVICE_PING, 0); | |
| 647 ycht_packet_send(ycht, pkt); | |
| 648 ycht_packet_free(pkt); | |
| 649 } |
