Mercurial > pidgin
annotate src/protocols/yahoo/yahoochat.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 | aaeb6ea63c56 |
| rev | line source |
|---|---|
| 6729 | 1 /* |
| 2 * gaim | |
| 3 * | |
| 8046 | 4 * Gaim is the legal property of its developers, whose names are too numerous |
| 5 * to list here. Please refer to the COPYRIGHT file distributed with this | |
| 6 * source distribution. | |
| 7 * | |
| 6729 | 8 * Some code copyright 2003 Tim Ringenbach <omarvo@hotmail.com> |
| 9 * (marv on irc.freenode.net) | |
| 10 * Some code borrowed from libyahoo2, copyright (C) 2002, Philip | |
| 11 * S Tellis <philip . tellis AT gmx . net> | |
| 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 | |
| 29 #ifdef HAVE_CONFIG_H | |
| 30 #include "config.h" | |
| 31 #endif | |
| 32 | |
| 33 #include "debug.h" | |
| 10937 | 34 #include "privacy.h" |
| 6729 | 35 #include "prpl.h" |
| 36 | |
| 37 #include "conversation.h" | |
| 38 #include "notify.h" | |
| 39 #include "util.h" | |
| 40 #include "internal.h" | |
| 41 | |
| 42 #include "yahoo.h" | |
| 10392 | 43 #include "yahoo_packet.h" |
| 6729 | 44 #include "yahoochat.h" |
| 9376 | 45 #include "ycht.h" |
| 6729 | 46 |
| 47 #define YAHOO_CHAT_ID (1) | |
| 48 | |
| 7186 | 49 /* prototype(s) */ |
| 50 static void yahoo_chat_leave(GaimConnection *gc, const char *room, const char *dn, gboolean logout); | |
| 51 | |
| 6729 | 52 /* special function to log us on to the yahoo chat service */ |
| 53 static void yahoo_chat_online(GaimConnection *gc) | |
| 54 { | |
| 55 struct yahoo_data *yd = gc->proto_data; | |
| 56 struct yahoo_packet *pkt; | |
| 57 | |
| 9376 | 58 if (yd->wm) { |
| 59 ycht_connection_open(gc); | |
| 60 return; | |
| 61 } | |
| 6729 | 62 |
| 63 pkt = yahoo_packet_new(YAHOO_SERVICE_CHATONLINE, YAHOO_STATUS_AVAILABLE,0); | |
| 10394 | 64 yahoo_packet_hash(pkt, "sss", 1, gaim_connection_get_display_name(gc), |
| 65 109, gaim_connection_get_display_name(gc), 6, "abcde"); | |
| 10392 | 66 yahoo_packet_send_and_free(pkt, yd); |
| 6729 | 67 } |
| 68 | |
| 69 /* this is slow, and different from the gaim_* version in that it (hopefully) won't add a user twice */ | |
| 9376 | 70 void yahoo_chat_add_users(GaimConvChat *chat, GList *newusers) |
| 6729 | 71 { |
| 9554 | 72 GList *i; |
| 6729 | 73 |
| 74 for (i = newusers; i; i = i->next) { | |
| 9554 | 75 if (gaim_conv_chat_find_user(chat, i->data)) |
| 6729 | 76 continue; |
| 9846 | 77 gaim_conv_chat_add_user(chat, i->data, NULL, GAIM_CBFLAGS_NONE, TRUE); |
| 6729 | 78 } |
| 79 } | |
| 80 | |
| 9376 | 81 void yahoo_chat_add_user(GaimConvChat *chat, const char *user, const char *reason) |
| 6729 | 82 { |
| 9554 | 83 if (gaim_conv_chat_find_user(chat, user)) |
| 6729 | 84 return; |
| 85 | |
| 9846 | 86 gaim_conv_chat_add_user(chat, user, reason, GAIM_CBFLAGS_NONE, TRUE); |
| 6729 | 87 } |
| 88 | |
| 89 static GaimConversation *yahoo_find_conference(GaimConnection *gc, const char *name) | |
| 90 { | |
| 91 struct yahoo_data *yd; | |
| 92 GSList *l; | |
| 93 | |
| 94 yd = gc->proto_data; | |
| 95 | |
| 96 for (l = yd->confs; l; l = l->next) { | |
| 97 GaimConversation *c = l->data; | |
| 98 if (!gaim_utf8_strcasecmp(gaim_conversation_get_name(c), name)) | |
| 99 return c; | |
| 100 } | |
| 101 return NULL; | |
| 102 } | |
| 103 | |
| 104 | |
| 105 void yahoo_process_conference_invite(GaimConnection *gc, struct yahoo_packet *pkt) | |
| 106 { | |
| 107 GSList *l; | |
| 108 char *room = NULL; | |
| 109 char *who = NULL; | |
| 110 char *msg = NULL; | |
| 111 GString *members = NULL; | |
| 112 GHashTable *components; | |
| 113 | |
| 114 if (pkt->status == 2) | |
| 115 return; /* XXX */ | |
| 116 | |
| 117 members = g_string_sized_new(512); | |
| 118 | |
| 119 for (l = pkt->hash; l; l = l->next) { | |
| 120 struct yahoo_pair *pair = l->data; | |
| 121 | |
| 122 switch (pair->key) { | |
| 123 case 1: /* us, but we already know who we are */ | |
| 124 break; | |
| 125 case 57: | |
| 7827 | 126 room = yahoo_string_decode(gc, pair->value, FALSE); |
| 6729 | 127 break; |
| 128 case 50: /* inviter */ | |
| 129 who = pair->value; | |
| 130 g_string_append_printf(members, "%s\n", who); | |
| 131 break; | |
| 9780 | 132 case 52: /* invitee (me) */ |
| 133 case 53: /* members */ | |
| 6729 | 134 g_string_append_printf(members, "%s\n", pair->value); |
| 135 break; | |
| 136 case 58: | |
| 7827 | 137 msg = yahoo_string_decode(gc, pair->value, FALSE); |
| 6729 | 138 break; |
| 139 case 13: /* ? */ | |
| 140 break; | |
| 141 } | |
| 142 } | |
| 143 | |
| 144 if (!room) { | |
| 145 g_string_free(members, TRUE); | |
| 146 return; | |
| 147 } | |
| 148 | |
| 149 components = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); | |
| 7827 | 150 g_hash_table_replace(components, g_strdup("room"), room); |
| 6729 | 151 if (msg) |
| 7827 | 152 g_hash_table_replace(components, g_strdup("topic"), msg); |
| 6729 | 153 g_hash_table_replace(components, g_strdup("type"), g_strdup("Conference")); |
| 154 if (members) { | |
| 155 g_hash_table_replace(components, g_strdup("members"), g_strdup(members->str)); | |
| 156 } | |
|
12999
68db2c40efb2
[gaim-migrate @ 15352]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12998
diff
changeset
|
157 if (!yahoo_privacy_check(gc, who) || |
|
68db2c40efb2
[gaim-migrate @ 15352]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12998
diff
changeset
|
158 (gaim_account_get_bool(gaim_connection_get_account(gc), "ignore_invites", FALSE))) { |
| 10937 | 159 gaim_debug_info("yahoo", |
| 160 "Invite to conference %s from %s has been dropped.\n", room, who); | |
|
11044
8bf376579177
[gaim-migrate @ 12958]
Richard Laager <rlaager@wiktel.com>
parents:
11043
diff
changeset
|
161 g_string_free(members, TRUE); |
| 10937 | 162 return; |
| 163 } | |
| 6729 | 164 serv_got_chat_invite(gc, room, who, msg, components); |
| 165 | |
| 166 g_string_free(members, TRUE); | |
| 167 } | |
| 168 | |
| 169 void yahoo_process_conference_decline(GaimConnection *gc, struct yahoo_packet *pkt) | |
| 170 { | |
| 171 GSList *l; | |
| 172 char *room = NULL; | |
| 173 char *who = NULL; | |
| 174 char *msg = NULL; | |
| 175 | |
| 176 for (l = pkt->hash; l; l = l->next) { | |
| 177 struct yahoo_pair *pair = l->data; | |
| 178 | |
| 179 switch (pair->key) { | |
| 180 case 57: | |
| 7827 | 181 room = yahoo_string_decode(gc, pair->value, FALSE); |
| 6729 | 182 break; |
| 183 case 54: | |
| 184 who = pair->value; | |
| 185 break; | |
| 186 case 14: | |
| 7827 | 187 msg = yahoo_string_decode(gc, pair->value, FALSE); |
| 6729 | 188 break; |
| 189 } | |
| 190 } | |
|
11044
8bf376579177
[gaim-migrate @ 12958]
Richard Laager <rlaager@wiktel.com>
parents:
11043
diff
changeset
|
191 if (!yahoo_privacy_check(gc, who)) { |
|
8bf376579177
[gaim-migrate @ 12958]
Richard Laager <rlaager@wiktel.com>
parents:
11043
diff
changeset
|
192 g_free(room); |
|
8bf376579177
[gaim-migrate @ 12958]
Richard Laager <rlaager@wiktel.com>
parents:
11043
diff
changeset
|
193 if (msg != NULL) |
|
8bf376579177
[gaim-migrate @ 12958]
Richard Laager <rlaager@wiktel.com>
parents:
11043
diff
changeset
|
194 g_free(msg); |
|
8bf376579177
[gaim-migrate @ 12958]
Richard Laager <rlaager@wiktel.com>
parents:
11043
diff
changeset
|
195 return; |
|
8bf376579177
[gaim-migrate @ 12958]
Richard Laager <rlaager@wiktel.com>
parents:
11043
diff
changeset
|
196 } |
| 6729 | 197 |
| 198 if (who && room) { | |
| 9575 | 199 /* make sure we're in the room before we process a decline message for it */ |
| 9576 | 200 if(yahoo_find_conference(gc, room)) { |
| 9575 | 201 char *tmp; |
| 6729 | 202 |
| 9575 | 203 tmp = g_strdup_printf(_("%s declined your conference invitation to room \"%s\" because \"%s\"."), |
| 204 who, room, msg?msg:""); | |
| 205 gaim_notify_info(gc, NULL, _("Invitation Rejected"), tmp); | |
| 206 g_free(tmp); | |
| 207 } | |
| 208 | |
| 7827 | 209 g_free(room); |
| 210 if (msg) | |
| 211 g_free(msg); | |
| 6729 | 212 } |
| 213 } | |
| 214 | |
| 215 void yahoo_process_conference_logon(GaimConnection *gc, struct yahoo_packet *pkt) | |
| 216 { | |
| 217 GSList *l; | |
| 218 char *room = NULL; | |
| 219 char *who = NULL; | |
| 220 GaimConversation *c; | |
| 221 | |
| 222 for (l = pkt->hash; l; l = l->next) { | |
| 223 struct yahoo_pair *pair = l->data; | |
| 224 | |
| 225 switch (pair->key) { | |
| 226 case 57: | |
| 7827 | 227 room = yahoo_string_decode(gc, pair->value, FALSE); |
| 6729 | 228 break; |
| 229 case 53: | |
| 230 who = pair->value; | |
| 231 break; | |
| 232 } | |
| 233 } | |
| 234 | |
| 235 if (who && room) { | |
| 236 c = yahoo_find_conference(gc, room); | |
| 237 if (c) | |
|
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
6804
diff
changeset
|
238 yahoo_chat_add_user(GAIM_CONV_CHAT(c), who, NULL); |
| 7827 | 239 g_free(room); |
| 6729 | 240 } |
| 241 } | |
| 242 | |
| 243 void yahoo_process_conference_logoff(GaimConnection *gc, struct yahoo_packet *pkt) | |
| 244 { | |
| 245 GSList *l; | |
| 246 char *room = NULL; | |
| 247 char *who = NULL; | |
| 248 GaimConversation *c; | |
| 249 | |
| 250 for (l = pkt->hash; l; l = l->next) { | |
| 251 struct yahoo_pair *pair = l->data; | |
| 252 | |
| 253 switch (pair->key) { | |
| 254 case 57: | |
| 7827 | 255 room = yahoo_string_decode(gc, pair->value, FALSE); |
| 6729 | 256 break; |
| 257 case 56: | |
| 258 who = pair->value; | |
| 259 break; | |
| 260 } | |
| 261 } | |
| 262 | |
| 263 if (who && room) { | |
| 264 c = yahoo_find_conference(gc, room); | |
| 265 if (c) | |
|
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
6804
diff
changeset
|
266 gaim_conv_chat_remove_user(GAIM_CONV_CHAT(c), who, NULL); |
| 7827 | 267 g_free(room); |
| 6729 | 268 } |
| 269 } | |
| 270 | |
| 271 void yahoo_process_conference_message(GaimConnection *gc, struct yahoo_packet *pkt) | |
| 272 { | |
| 273 GSList *l; | |
| 274 char *room = NULL; | |
| 275 char *who = NULL; | |
| 276 char *msg = NULL; | |
| 7827 | 277 char *msg2; |
| 278 int utf8 = 0; | |
| 6729 | 279 GaimConversation *c; |
| 280 | |
| 281 for (l = pkt->hash; l; l = l->next) { | |
| 282 struct yahoo_pair *pair = l->data; | |
| 283 | |
| 284 switch (pair->key) { | |
| 285 case 57: | |
| 7827 | 286 room = yahoo_string_decode(gc, pair->value, FALSE); |
| 6729 | 287 break; |
| 288 case 3: | |
| 289 who = pair->value; | |
| 290 break; | |
| 291 case 14: | |
| 292 msg = pair->value; | |
| 293 break; | |
| 7827 | 294 case 97: |
| 295 utf8 = strtol(pair->value, NULL, 10); | |
| 296 break; | |
| 6729 | 297 } |
| 298 } | |
| 299 | |
| 300 if (room && who && msg) { | |
| 7827 | 301 msg2 = yahoo_string_decode(gc, msg, utf8); |
| 6729 | 302 c = yahoo_find_conference(gc, room); |
| 303 if (!c) | |
| 304 return; | |
| 7827 | 305 msg = yahoo_codes_to_html(msg2); |
|
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
6804
diff
changeset
|
306 serv_got_chat_in(gc, gaim_conv_chat_get_id(GAIM_CONV_CHAT(c)), who, 0, msg, time(NULL)); |
| 6729 | 307 g_free(msg); |
| 7827 | 308 g_free(msg2); |
| 6729 | 309 } |
| 7827 | 310 if (room) |
| 311 g_free(room); | |
| 6729 | 312 } |
| 313 | |
| 314 | |
|
8735
92cbf9713795
[gaim-migrate @ 9490]
Christian Hammond <chipx86@chipx86.com>
parents:
8584
diff
changeset
|
315 /* this is a confirmation of yahoo_chat_online(); */ |
| 6729 | 316 void yahoo_process_chat_online(GaimConnection *gc, struct yahoo_packet *pkt) |
| 317 { | |
| 318 struct yahoo_data *yd = (struct yahoo_data *) gc->proto_data; | |
| 319 | |
| 320 if (pkt->status == 1) | |
| 321 yd->chat_online = 1; | |
| 322 } | |
| 323 | |
| 324 /* this is basicly the opposite of chat_online */ | |
| 325 void yahoo_process_chat_logout(GaimConnection *gc, struct yahoo_packet *pkt) | |
| 326 { | |
| 327 struct yahoo_data *yd = (struct yahoo_data *) gc->proto_data; | |
| 7186 | 328 GSList *l; |
| 7827 | 329 |
| 7186 | 330 for (l = pkt->hash; l; l = l->next) { |
| 331 struct yahoo_pair *pair = l->data; | |
| 6729 | 332 |
| 7186 | 333 if (pair->key == 1) |
| 334 if (g_ascii_strcasecmp(pair->value, | |
| 335 gaim_connection_get_display_name(gc))) | |
| 336 return; | |
| 337 } | |
| 7827 | 338 |
| 7186 | 339 if (pkt->status == 1) { |
| 6729 | 340 yd->chat_online = 0; |
| 7186 | 341 if (yd->in_chat) |
| 342 yahoo_c_leave(gc, YAHOO_CHAT_ID); | |
| 343 } | |
| 6729 | 344 } |
| 345 | |
| 346 void yahoo_process_chat_join(GaimConnection *gc, struct yahoo_packet *pkt) | |
| 347 { | |
| 10937 | 348 GaimAccount *account = gaim_connection_get_account(gc); |
| 6729 | 349 struct yahoo_data *yd = (struct yahoo_data *) gc->proto_data; |
| 350 GaimConversation *c = NULL; | |
| 351 GSList *l; | |
| 352 GList *members = NULL; | |
| 10937 | 353 GList *roomies = NULL; |
| 6729 | 354 char *room = NULL; |
| 355 char *topic = NULL; | |
| 356 char *someid, *someotherid, *somebase64orhashosomething, *somenegativenumber; | |
| 357 | |
| 358 if (pkt->status == -1) { | |
|
12998
a2096c8978b2
[gaim-migrate @ 15351]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12865
diff
changeset
|
359 /* We can't join */ |
|
a2096c8978b2
[gaim-migrate @ 15351]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12865
diff
changeset
|
360 struct yahoo_pair *pair = pkt->hash->data; |
|
a2096c8978b2
[gaim-migrate @ 15351]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12865
diff
changeset
|
361 gchar const *failed_to_join = _("Failed to join chat"); |
|
a2096c8978b2
[gaim-migrate @ 15351]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12865
diff
changeset
|
362 switch (atoi(pair->value)) { |
|
a2096c8978b2
[gaim-migrate @ 15351]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12865
diff
changeset
|
363 case 0xFFFFFFFA: /* -6 */ |
|
a2096c8978b2
[gaim-migrate @ 15351]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12865
diff
changeset
|
364 gaim_notify_error(gc, NULL, failed_to_join, _("Unknown room")); |
|
a2096c8978b2
[gaim-migrate @ 15351]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12865
diff
changeset
|
365 break; |
|
a2096c8978b2
[gaim-migrate @ 15351]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12865
diff
changeset
|
366 case 0xFFFFFFF1: /* -15 */ |
|
a2096c8978b2
[gaim-migrate @ 15351]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12865
diff
changeset
|
367 gaim_notify_error(gc, NULL, failed_to_join, _("Maybe the room is full")); |
|
a2096c8978b2
[gaim-migrate @ 15351]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12865
diff
changeset
|
368 break; |
|
a2096c8978b2
[gaim-migrate @ 15351]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12865
diff
changeset
|
369 case 0xFFFFFFDD: /* -35 */ |
|
a2096c8978b2
[gaim-migrate @ 15351]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12865
diff
changeset
|
370 gaim_notify_error(gc, NULL, failed_to_join, _("Not available")); |
|
a2096c8978b2
[gaim-migrate @ 15351]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12865
diff
changeset
|
371 break; |
|
a2096c8978b2
[gaim-migrate @ 15351]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12865
diff
changeset
|
372 default: |
|
a2096c8978b2
[gaim-migrate @ 15351]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12865
diff
changeset
|
373 gaim_notify_error(gc, NULL, failed_to_join, |
|
a2096c8978b2
[gaim-migrate @ 15351]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12865
diff
changeset
|
374 _("Unknown error. You may need to logout and wait five minutes before being able to rejoin a chatroom")); |
|
a2096c8978b2
[gaim-migrate @ 15351]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12865
diff
changeset
|
375 } |
| 6729 | 376 return; |
| 377 } | |
| 378 | |
| 379 for (l = pkt->hash; l; l = l->next) { | |
| 380 struct yahoo_pair *pair = l->data; | |
| 381 | |
| 382 switch (pair->key) { | |
| 383 | |
| 384 case 104: | |
| 8410 | 385 room = yahoo_string_decode(gc, pair->value, TRUE); |
| 6729 | 386 break; |
| 387 case 105: | |
| 8410 | 388 topic = yahoo_string_decode(gc, pair->value, TRUE); |
| 6729 | 389 break; |
| 390 case 128: | |
| 391 someid = pair->value; | |
| 392 break; | |
| 393 case 108: /* number of joiners */ | |
| 394 break; | |
| 395 case 129: | |
| 396 someotherid = pair->value; | |
| 397 break; | |
| 398 case 130: | |
| 399 somebase64orhashosomething = pair->value; | |
| 400 break; | |
| 401 case 126: | |
| 402 somenegativenumber = pair->value; | |
| 403 break; | |
| 404 case 13: /* this is 1. maybe its the type of room? (normal, user created, private, etc?) */ | |
| 405 break; | |
|
8735
92cbf9713795
[gaim-migrate @ 9490]
Christian Hammond <chipx86@chipx86.com>
parents:
8584
diff
changeset
|
406 case 61: /*this looks similar to 130 */ |
| 6729 | 407 break; |
| 408 | |
| 409 /* the previous section was just room info. this next section is | |
| 410 info about individual room members, (including us) */ | |
| 411 | |
| 412 case 109: /* the yahoo id */ | |
| 413 members = g_list_append(members, pair->value); | |
| 414 break; | |
| 415 case 110: /* age */ | |
| 416 break; | |
| 417 case 141: /* nickname */ | |
| 418 break; | |
| 419 case 142: /* location */ | |
| 420 break; | |
| 421 case 113: /* bitmask */ | |
| 422 break; | |
| 423 } | |
| 424 } | |
| 425 | |
| 9329 | 426 if (room && yd->chat_name && gaim_utf8_strcasecmp(room, yd->chat_name)) |
| 7186 | 427 yahoo_chat_leave(gc, room, |
| 428 gaim_connection_get_display_name(gc), FALSE); | |
| 6729 | 429 |
| 430 c = gaim_find_chat(gc, YAHOO_CHAT_ID); | |
| 431 | |
| 9329 | 432 if (room && (!c || gaim_conv_chat_has_left(GAIM_CONV_CHAT(c))) && members && |
| 8357 | 433 ((g_list_length(members) > 1) || |
| 434 !g_ascii_strcasecmp(members->data, gaim_connection_get_display_name(gc)))) { | |
| 9554 | 435 int i; |
| 436 GList *flags = NULL; | |
| 437 for (i = 0; i < g_list_length(members); i++) | |
| 438 flags = g_list_append(flags, GINT_TO_POINTER(GAIM_CBFLAGS_NONE)); | |
| 8357 | 439 if (c && gaim_conv_chat_has_left(GAIM_CONV_CHAT(c))) { |
| 440 /* this might be a hack, but oh well, it should nicely */ | |
| 441 char *tmpmsg; | |
| 442 | |
| 443 gaim_conversation_set_name(c, room); | |
| 444 | |
| 445 c = serv_got_joined_chat(gc, YAHOO_CHAT_ID, room); | |
| 446 if (topic) | |
| 447 gaim_conv_chat_set_topic(GAIM_CONV_CHAT(c), NULL, topic); | |
| 448 yd->in_chat = 1; | |
| 449 yd->chat_name = g_strdup(room); | |
|
11454
201617d49573
[gaim-migrate @ 13693]
Richard Laager <rlaager@wiktel.com>
parents:
11318
diff
changeset
|
450 gaim_conv_chat_add_users(GAIM_CONV_CHAT(c), members, NULL, flags, FALSE); |
| 8357 | 451 |
| 452 tmpmsg = g_strdup_printf(_("You are now chatting in %s."), room); | |
| 453 gaim_conv_chat_write(GAIM_CONV_CHAT(c), "", tmpmsg, GAIM_MESSAGE_SYSTEM, time(NULL)); | |
| 454 g_free(tmpmsg); | |
| 455 } else { | |
| 456 c = serv_got_joined_chat(gc, YAHOO_CHAT_ID, room); | |
| 457 if (topic) | |
| 458 gaim_conv_chat_set_topic(GAIM_CONV_CHAT(c), NULL, topic); | |
| 459 yd->in_chat = 1; | |
| 460 yd->chat_name = g_strdup(room); | |
|
11454
201617d49573
[gaim-migrate @ 13693]
Richard Laager <rlaager@wiktel.com>
parents:
11318
diff
changeset
|
461 gaim_conv_chat_add_users(GAIM_CONV_CHAT(c), members, NULL, flags, FALSE); |
| 8357 | 462 } |
| 7186 | 463 } else if (c) { |
|
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
6804
diff
changeset
|
464 yahoo_chat_add_users(GAIM_CONV_CHAT(c), members); |
| 6729 | 465 } |
| 466 | |
|
11527
b1f8151e6ae5
[gaim-migrate @ 13776]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11454
diff
changeset
|
467 if (account->deny && c) { |
|
b1f8151e6ae5
[gaim-migrate @ 13776]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11454
diff
changeset
|
468 GaimConversationUiOps *ops = gaim_conversation_get_ui_ops(c); |
|
b1f8151e6ae5
[gaim-migrate @ 13776]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11454
diff
changeset
|
469 for (l = account->deny; l != NULL; l = l->next) { |
|
b1f8151e6ae5
[gaim-migrate @ 13776]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11454
diff
changeset
|
470 for (roomies = members; roomies; roomies = roomies->next) { |
|
b1f8151e6ae5
[gaim-migrate @ 13776]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11454
diff
changeset
|
471 if (!gaim_utf8_strcasecmp((char *)l->data, roomies->data)) { |
|
b1f8151e6ae5
[gaim-migrate @ 13776]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11454
diff
changeset
|
472 gaim_debug_info("yahoo", "Ignoring room member %s in room %s\n" , roomies->data, room ? room : ""); |
|
b1f8151e6ae5
[gaim-migrate @ 13776]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11454
diff
changeset
|
473 gaim_conv_chat_ignore(GAIM_CONV_CHAT(c),roomies->data); |
|
b1f8151e6ae5
[gaim-migrate @ 13776]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11454
diff
changeset
|
474 ops->chat_update_user(c, roomies->data); |
|
b1f8151e6ae5
[gaim-migrate @ 13776]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11454
diff
changeset
|
475 } |
| 10937 | 476 } |
| 477 } | |
| 478 } | |
| 479 g_list_free(roomies); | |
| 6729 | 480 g_list_free(members); |
| 7827 | 481 g_free(room); |
|
11527
b1f8151e6ae5
[gaim-migrate @ 13776]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11454
diff
changeset
|
482 g_free(topic); |
| 6729 | 483 } |
| 484 | |
| 485 void yahoo_process_chat_exit(GaimConnection *gc, struct yahoo_packet *pkt) | |
| 486 { | |
| 487 char *who = NULL; | |
| 7186 | 488 char *room = NULL; |
| 6729 | 489 GSList *l; |
| 490 struct yahoo_data *yd; | |
| 491 | |
| 492 yd = gc->proto_data; | |
| 493 | |
| 494 for (l = pkt->hash; l; l = l->next) { | |
| 495 struct yahoo_pair *pair = l->data; | |
| 496 | |
| 7186 | 497 if (pair->key == 104) |
| 8410 | 498 room = yahoo_string_decode(gc, pair->value, TRUE); |
| 6729 | 499 if (pair->key == 109) |
| 500 who = pair->value; | |
| 501 } | |
| 502 | |
| 7186 | 503 if (who && room) { |
| 6729 | 504 GaimConversation *c = gaim_find_chat(gc, YAHOO_CHAT_ID); |
| 7186 | 505 if (c && !gaim_utf8_strcasecmp(gaim_conversation_get_name(c), room)) |
|
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
6804
diff
changeset
|
506 gaim_conv_chat_remove_user(GAIM_CONV_CHAT(c), who, NULL); |
| 6729 | 507 |
| 508 } | |
| 7827 | 509 if (room) |
| 510 g_free(room); | |
| 6729 | 511 } |
| 512 | |
| 513 void yahoo_process_chat_message(GaimConnection *gc, struct yahoo_packet *pkt) | |
| 514 { | |
| 7827 | 515 char *room = NULL, *who = NULL, *msg = NULL, *msg2; |
| 8410 | 516 int msgtype = 1, utf8 = 1; /* default to utf8 */ |
| 6729 | 517 GaimConversation *c = NULL; |
| 518 GSList *l; | |
| 519 | |
| 520 for (l = pkt->hash; l; l = l->next) { | |
| 521 struct yahoo_pair *pair = l->data; | |
| 522 | |
| 523 switch (pair->key) { | |
| 524 | |
| 7827 | 525 case 97: |
| 526 utf8 = strtol(pair->value, NULL, 10); | |
| 527 break; | |
| 6729 | 528 case 104: |
| 8410 | 529 room = yahoo_string_decode(gc, pair->value, TRUE); |
| 6729 | 530 break; |
| 531 case 109: | |
| 532 who = pair->value; | |
| 533 break; | |
| 534 case 117: | |
| 535 msg = pair->value; | |
| 536 break; | |
| 537 case 124: | |
| 538 msgtype = strtol(pair->value, NULL, 10); | |
| 539 break; | |
| 540 } | |
| 541 } | |
| 542 | |
| 543 c = gaim_find_chat(gc, YAHOO_CHAT_ID); | |
| 7827 | 544 if (!who || !c) { |
| 545 if (room) | |
| 546 g_free(room); | |
| 6729 | 547 /* we still get messages after we part, funny that */ |
| 548 return; | |
| 549 } | |
| 550 | |
| 551 if (!msg) { | |
| 552 gaim_debug(GAIM_DEBUG_MISC, "yahoo", "Got a message packet with no message.\nThis probably means something important, but we're ignoring it.\n"); | |
| 553 return; | |
| 554 } | |
| 7827 | 555 msg2 = yahoo_string_decode(gc, msg, utf8); |
| 556 msg = yahoo_codes_to_html(msg2); | |
| 557 g_free(msg2); | |
| 6729 | 558 |
| 559 if (msgtype == 2 || msgtype == 3) { | |
| 560 char *tmp; | |
| 561 tmp = g_strdup_printf("/me %s", msg); | |
| 562 g_free(msg); | |
| 563 msg = tmp; | |
| 564 } | |
| 565 | |
| 566 serv_got_chat_in(gc, YAHOO_CHAT_ID, who, 0, msg, time(NULL)); | |
| 567 g_free(msg); | |
|
11593
4b7fb30b8926
[gaim-migrate @ 13863]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11527
diff
changeset
|
568 g_free(room); |
| 6729 | 569 } |
| 570 | |
| 571 void yahoo_process_chat_addinvite(GaimConnection *gc, struct yahoo_packet *pkt) | |
| 572 { | |
| 573 GSList *l; | |
| 574 char *room = NULL; | |
| 575 char *msg = NULL; | |
| 576 char *who = NULL; | |
| 577 | |
| 578 for (l = pkt->hash; l; l = l->next) { | |
| 579 struct yahoo_pair *pair = l->data; | |
| 580 | |
| 581 switch (pair->key) { | |
| 582 case 104: | |
| 8410 | 583 room = yahoo_string_decode(gc, pair->value, TRUE); |
| 6729 | 584 break; |
| 585 case 129: /* room id? */ | |
| 586 break; | |
| 587 case 126: /* ??? */ | |
| 588 break; | |
| 589 case 117: | |
| 7827 | 590 msg = yahoo_string_decode(gc, pair->value, FALSE); |
| 6729 | 591 break; |
| 592 case 119: | |
| 593 who = pair->value; | |
| 594 break; | |
| 595 case 118: /* us */ | |
| 596 break; | |
| 597 } | |
| 598 } | |
| 599 | |
| 600 if (room && who) { | |
| 601 GHashTable *components; | |
| 602 | |
| 603 components = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); | |
| 604 g_hash_table_replace(components, g_strdup("room"), g_strdup(room)); | |
|
12999
68db2c40efb2
[gaim-migrate @ 15352]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12998
diff
changeset
|
605 if (!yahoo_privacy_check(gc, who) || |
|
68db2c40efb2
[gaim-migrate @ 15352]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12998
diff
changeset
|
606 (gaim_account_get_bool(gaim_connection_get_account(gc), "ignore_invites", FALSE))) { |
| 10937 | 607 gaim_debug_info("yahoo", |
| 608 "Invite to room %s from %s has been dropped.\n", room, who); | |
|
11044
8bf376579177
[gaim-migrate @ 12958]
Richard Laager <rlaager@wiktel.com>
parents:
11043
diff
changeset
|
609 if (room != NULL) |
|
8bf376579177
[gaim-migrate @ 12958]
Richard Laager <rlaager@wiktel.com>
parents:
11043
diff
changeset
|
610 g_free(room); |
|
8bf376579177
[gaim-migrate @ 12958]
Richard Laager <rlaager@wiktel.com>
parents:
11043
diff
changeset
|
611 if (msg != NULL) |
|
8bf376579177
[gaim-migrate @ 12958]
Richard Laager <rlaager@wiktel.com>
parents:
11043
diff
changeset
|
612 g_free(msg); |
| 10937 | 613 return; |
| 614 } | |
| 6729 | 615 serv_got_chat_invite(gc, room, who, msg, components); |
| 616 } | |
| 7827 | 617 if (room) |
| 618 g_free(room); | |
| 619 if (msg) | |
| 620 g_free(msg); | |
| 6729 | 621 } |
| 622 | |
| 623 void yahoo_process_chat_goto(GaimConnection *gc, struct yahoo_packet *pkt) | |
| 624 { | |
| 625 if (pkt->status == -1) | |
| 626 gaim_notify_error(gc, NULL, _("Failed to join buddy in chat"), | |
| 627 _("Maybe they're not in a chat?")); | |
| 628 } | |
| 629 | |
| 630 /* | |
| 631 * Functions dealing with conferences | |
| 7827 | 632 * I think conference names are always ascii. |
| 6729 | 633 */ |
| 634 | |
| 9782 | 635 void yahoo_conf_leave(struct yahoo_data *yd, const char *room, const char *dn, GList *who) |
| 6729 | 636 { |
| 637 struct yahoo_packet *pkt; | |
| 638 GList *w; | |
| 639 | |
| 9782 | 640 gaim_debug_misc("yahoo", "leaving conference %s\n", room); |
| 641 | |
| 6729 | 642 pkt = yahoo_packet_new(YAHOO_SERVICE_CONFLOGOFF, YAHOO_STATUS_AVAILABLE, 0); |
| 643 | |
| 10394 | 644 yahoo_packet_hash_str(pkt, 1, dn); |
| 6729 | 645 for (w = who; w; w = w->next) { |
| 9554 | 646 const char *name = gaim_conv_chat_cb_get_name(w->data); |
| 10394 | 647 yahoo_packet_hash_str(pkt, 3, name); |
| 6729 | 648 } |
| 649 | |
| 10394 | 650 yahoo_packet_hash_str(pkt, 57, room); |
| 10392 | 651 yahoo_packet_send_and_free(pkt, yd); |
| 6729 | 652 } |
| 653 | |
| 7827 | 654 static int yahoo_conf_send(GaimConnection *gc, const char *dn, const char *room, |
| 6729 | 655 GList *members, const char *what) |
| 656 { | |
| 7827 | 657 struct yahoo_data *yd = gc->proto_data; |
| 6729 | 658 struct yahoo_packet *pkt; |
| 659 GList *who; | |
| 7827 | 660 char *msg, *msg2; |
| 661 int utf8 = 1; | |
| 6804 | 662 |
| 663 msg = yahoo_html_to_codes(what); | |
| 7827 | 664 msg2 = yahoo_string_encode(gc, msg, &utf8); |
| 665 | |
| 6729 | 666 pkt = yahoo_packet_new(YAHOO_SERVICE_CONFMSG, YAHOO_STATUS_AVAILABLE, 0); |
| 667 | |
| 10394 | 668 yahoo_packet_hash_str(pkt, 1, dn); |
| 9554 | 669 for (who = members; who; who = who->next) { |
| 670 const char *name = gaim_conv_chat_cb_get_name(who->data); | |
| 10394 | 671 yahoo_packet_hash_str(pkt, 53, name); |
| 9554 | 672 } |
| 10394 | 673 yahoo_packet_hash(pkt, "ss", 57, room, 14, msg2); |
| 7827 | 674 if (utf8) |
| 10394 | 675 yahoo_packet_hash_str(pkt, 97, "1"); /* utf-8 */ |
| 6729 | 676 |
| 10392 | 677 yahoo_packet_send_and_free(pkt, yd); |
| 6804 | 678 g_free(msg); |
| 7827 | 679 g_free(msg2); |
| 6729 | 680 |
| 681 return 0; | |
| 682 } | |
| 683 | |
| 684 static void yahoo_conf_join(struct yahoo_data *yd, GaimConversation *c, const char *dn, const char *room, | |
| 685 const char *topic, const char *members) | |
| 686 { | |
| 687 struct yahoo_packet *pkt; | |
| 688 char **memarr = NULL; | |
| 689 int i; | |
| 690 | |
| 691 if (members) | |
| 692 memarr = g_strsplit(members, "\n", 0); | |
| 693 | |
| 694 pkt = yahoo_packet_new(YAHOO_SERVICE_CONFLOGON, YAHOO_STATUS_AVAILABLE, 0); | |
| 695 | |
| 10394 | 696 yahoo_packet_hash(pkt, "sss", 1, dn, 3, dn, 57, room); |
| 6729 | 697 if (memarr) { |
| 698 for(i = 0 ; memarr[i]; i++) { | |
| 699 if (!strcmp(memarr[i], "") || !strcmp(memarr[i], dn)) | |
| 700 continue; | |
| 10394 | 701 yahoo_packet_hash_str(pkt, 3, memarr[i]); |
| 9846 | 702 gaim_conv_chat_add_user(GAIM_CONV_CHAT(c), memarr[i], NULL, GAIM_CBFLAGS_NONE, TRUE); |
| 6729 | 703 } |
| 704 } | |
| 10392 | 705 yahoo_packet_send_and_free(pkt, yd); |
| 6729 | 706 |
| 707 if (memarr) | |
| 708 g_strfreev(memarr); | |
| 709 } | |
| 710 | |
| 7827 | 711 static void yahoo_conf_invite(GaimConnection *gc, GaimConversation *c, |
| 6729 | 712 const char *dn, const char *buddy, const char *room, const char *msg) |
| 713 { | |
| 7827 | 714 struct yahoo_data *yd = gc->proto_data; |
| 6729 | 715 struct yahoo_packet *pkt; |
| 716 GList *members; | |
| 7827 | 717 char *msg2 = NULL; |
| 718 | |
| 719 if (msg) | |
| 720 msg2 = yahoo_string_encode(gc, msg, NULL); | |
| 6729 | 721 |
|
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
6804
diff
changeset
|
722 members = gaim_conv_chat_get_users(GAIM_CONV_CHAT(c)); |
| 6729 | 723 |
| 724 pkt = yahoo_packet_new(YAHOO_SERVICE_CONFADDINVITE, YAHOO_STATUS_AVAILABLE, 0); | |
| 725 | |
| 10394 | 726 yahoo_packet_hash(pkt, "sssss", 1, dn, 51, buddy, 57, room, 58, msg?msg2:"", 13, "0"); |
| 6729 | 727 for(; members; members = members->next) { |
| 9554 | 728 const char *name = gaim_conv_chat_cb_get_name(members->data); |
| 729 if (!strcmp(name, dn)) | |
| 6729 | 730 continue; |
| 10394 | 731 yahoo_packet_hash(pkt, "ss", 52, name, 53, name); |
| 6729 | 732 } |
| 10392 | 733 |
| 734 yahoo_packet_send_and_free(pkt, yd); | |
| 735 g_free(msg2); | |
| 6729 | 736 } |
| 737 | |
| 738 /* | |
| 739 * Functions dealing with chats | |
| 740 */ | |
| 741 | |
| 7186 | 742 static void yahoo_chat_leave(GaimConnection *gc, const char *room, const char *dn, gboolean logout) |
| 6729 | 743 { |
| 7186 | 744 struct yahoo_data *yd = gc->proto_data; |
| 6729 | 745 struct yahoo_packet *pkt; |
| 7186 | 746 GaimConversation *c; |
|
12865
27c4145c6daa
[gaim-migrate @ 15216]
Richard Laager <rlaager@wiktel.com>
parents:
12216
diff
changeset
|
747 |
| 7827 | 748 char *eroom; |
| 8410 | 749 gboolean utf8 = 1; |
| 7827 | 750 |
| 9376 | 751 if (yd->wm) { |
| 752 g_return_if_fail(yd->ycht != NULL); | |
| 753 | |
| 754 ycht_chat_leave(yd->ycht, room, logout); | |
| 755 return; | |
| 756 } | |
| 757 | |
| 8410 | 758 eroom = yahoo_string_encode(gc, room, &utf8); |
| 6729 | 759 |
| 760 pkt = yahoo_packet_new(YAHOO_SERVICE_CHATEXIT, YAHOO_STATUS_AVAILABLE, 0); | |
| 10394 | 761 yahoo_packet_hash(pkt, "sss", 104, eroom, 109, dn, 108, "1"); |
| 762 yahoo_packet_hash_str(pkt, 112, "0"); /* what does this one mean? */ | |
| 10392 | 763 yahoo_packet_send_and_free(pkt, yd); |
| 6729 | 764 |
| 765 yd->in_chat = 0; | |
| 766 if (yd->chat_name) { | |
| 767 g_free(yd->chat_name); | |
| 768 yd->chat_name = NULL; | |
| 769 } | |
| 770 | |
| 7186 | 771 if ((c = gaim_find_chat(gc, YAHOO_CHAT_ID))) |
| 772 serv_got_chat_left(gc, YAHOO_CHAT_ID); | |
| 773 | |
| 774 if (!logout) | |
| 775 return; | |
| 11644 | 776 |
| 7186 | 777 pkt = yahoo_packet_new(YAHOO_SERVICE_CHATLOGOUT, |
| 778 YAHOO_STATUS_AVAILABLE, 0); | |
| 10394 | 779 yahoo_packet_hash_str(pkt, 1, dn); |
| 10392 | 780 yahoo_packet_send_and_free(pkt, yd); |
| 7186 | 781 |
| 782 yd->chat_online = 0; | |
| 7827 | 783 g_free(eroom); |
| 6729 | 784 } |
| 785 | |
| 6804 | 786 /* borrowed from gtkconv.c */ |
| 787 static gboolean | |
| 788 meify(char *message, size_t len) | |
| 789 { | |
| 790 /* | |
| 791 * Read /me-ify: If the message (post-HTML) starts with /me, | |
| 792 * remove the "/me " part of it (including that space) and return TRUE. | |
| 793 */ | |
| 794 char *c; | |
| 795 gboolean inside_html = 0; | |
| 796 | |
| 797 /* Umm.. this would be very bad if this happens. */ | |
| 798 g_return_val_if_fail(message != NULL, FALSE); | |
| 799 | |
| 800 if (len == -1) | |
| 801 len = strlen(message); | |
| 802 | |
| 803 for (c = message; *c != '\0'; c++, len--) { | |
| 804 if (inside_html) { | |
| 805 if (*c == '>') | |
| 806 inside_html = FALSE; | |
| 807 } | |
| 808 else { | |
| 809 if (*c == '<') | |
| 810 inside_html = TRUE; | |
| 811 else | |
| 812 break; | |
| 813 } | |
| 814 } | |
| 815 | |
| 816 if (*c != '\0' && !g_ascii_strncasecmp(c, "/me ", 4)) { | |
| 817 memmove(c, c + 4, len - 3); | |
| 818 return TRUE; | |
| 819 } | |
| 820 | |
| 821 return FALSE; | |
| 822 } | |
| 823 | |
| 12216 | 824 static int yahoo_chat_send(GaimConnection *gc, const char *dn, const char *room, const char *what, GaimMessageFlags flags) |
| 6729 | 825 { |
| 7827 | 826 struct yahoo_data *yd = gc->proto_data; |
| 6729 | 827 struct yahoo_packet *pkt; |
| 828 int me = 0; | |
| 7827 | 829 char *msg1, *msg2, *room2; |
| 830 gboolean utf8 = TRUE; | |
| 6804 | 831 |
| 9376 | 832 if (yd->wm) { |
| 833 g_return_val_if_fail(yd->ycht != NULL, 1); | |
| 834 | |
| 835 return ycht_chat_send(yd->ycht, room, what); | |
| 836 } | |
| 837 | |
| 6804 | 838 msg1 = g_strdup(what); |
| 6729 | 839 |
| 6804 | 840 if (meify(msg1, -1)) |
| 6729 | 841 me = 1; |
| 6804 | 842 |
| 843 msg2 = yahoo_html_to_codes(msg1); | |
| 844 g_free(msg1); | |
| 7827 | 845 msg1 = yahoo_string_encode(gc, msg2, &utf8); |
| 846 g_free(msg2); | |
| 847 room2 = yahoo_string_encode(gc, room, NULL); | |
| 6729 | 848 |
| 849 pkt = yahoo_packet_new(YAHOO_SERVICE_COMMENT, YAHOO_STATUS_AVAILABLE, 0); | |
| 850 | |
| 10394 | 851 yahoo_packet_hash(pkt, "sss", 1, dn, 104, room2, 117, msg1); |
| 6729 | 852 if (me) |
| 10394 | 853 yahoo_packet_hash_str(pkt, 124, "2"); |
| 6729 | 854 else |
| 10394 | 855 yahoo_packet_hash_str(pkt, 124, "1"); |
| 6729 | 856 /* fixme: what about /think? (124=3) */ |
| 7827 | 857 if (utf8) |
| 10394 | 858 yahoo_packet_hash_str(pkt, 97, "1"); |
| 6729 | 859 |
| 10392 | 860 yahoo_packet_send_and_free(pkt, yd); |
| 7827 | 861 g_free(msg1); |
| 862 g_free(room2); | |
| 6729 | 863 |
| 864 return 0; | |
| 865 } | |
| 866 | |
| 7827 | 867 static void yahoo_chat_join(GaimConnection *gc, const char *dn, const char *room, const char *topic) |
| 6729 | 868 { |
| 7827 | 869 struct yahoo_data *yd = gc->proto_data; |
| 6729 | 870 struct yahoo_packet *pkt; |
| 7827 | 871 char *room2; |
| 8410 | 872 gboolean utf8 = TRUE; |
| 7827 | 873 |
| 9376 | 874 if (yd->wm) { |
| 875 g_return_if_fail(yd->ycht != NULL); | |
| 876 ycht_chat_join(yd->ycht, room); | |
| 877 return; | |
| 878 } | |
| 879 | |
| 8410 | 880 /* apparently room names are always utf8, or else always not utf8, |
| 881 * so we don't have to actually pass the flag in the packet. Or something. */ | |
| 882 room2 = yahoo_string_encode(gc, room, &utf8); | |
| 6729 | 883 |
| 884 pkt = yahoo_packet_new(YAHOO_SERVICE_CHATJOIN, YAHOO_STATUS_AVAILABLE, 0); | |
| 10394 | 885 yahoo_packet_hash(pkt, "ssss", 1, gaim_connection_get_display_name(gc), |
| 886 62, "2", 104, room2, 129, "0"); | |
| 10392 | 887 yahoo_packet_send_and_free(pkt, yd); |
| 7827 | 888 g_free(room2); |
| 6729 | 889 } |
| 890 | |
| 7827 | 891 static void yahoo_chat_invite(GaimConnection *gc, const char *dn, const char *buddy, |
| 6729 | 892 const char *room, const char *msg) |
| 893 { | |
| 7827 | 894 struct yahoo_data *yd = gc->proto_data; |
| 6729 | 895 struct yahoo_packet *pkt; |
| 7827 | 896 char *room2, *msg2 = NULL; |
| 8410 | 897 gboolean utf8 = TRUE; |
| 6729 | 898 |
| 9376 | 899 if (yd->wm) { |
| 900 g_return_if_fail(yd->ycht != NULL); | |
| 901 ycht_chat_send_invite(yd->ycht, room, buddy, msg); | |
| 902 return; | |
| 903 } | |
| 904 | |
| 8410 | 905 room2 = yahoo_string_encode(gc, room, &utf8); |
| 7827 | 906 if (msg) |
| 907 msg2 = yahoo_string_encode(gc, msg, NULL); | |
| 11644 | 908 |
| 6729 | 909 pkt = yahoo_packet_new(YAHOO_SERVICE_CHATADDINVITE, YAHOO_STATUS_AVAILABLE, 0); |
| 10394 | 910 yahoo_packet_hash(pkt, "sssss", 1, dn, 118, buddy, 104, room2, 117, (msg2?msg2:""), 129, "0"); |
| 10392 | 911 yahoo_packet_send_and_free(pkt, yd); |
| 7827 | 912 |
| 913 g_free(room2); | |
| 10392 | 914 g_free(msg2); |
| 6729 | 915 } |
| 916 | |
| 917 void yahoo_chat_goto(GaimConnection *gc, const char *name) | |
| 918 { | |
| 919 struct yahoo_data *yd; | |
| 920 struct yahoo_packet *pkt; | |
| 921 | |
| 922 yd = gc->proto_data; | |
| 923 | |
| 9376 | 924 if (yd->wm) { |
| 925 g_return_if_fail(yd->ycht != NULL); | |
| 926 ycht_chat_goto_user(yd->ycht, name); | |
| 927 return; | |
| 928 } | |
| 929 | |
| 6729 | 930 if (!yd->chat_online) |
| 931 yahoo_chat_online(gc); | |
| 932 | |
| 933 pkt = yahoo_packet_new(YAHOO_SERVICE_CHATGOTO, YAHOO_STATUS_AVAILABLE, 0); | |
| 10394 | 934 yahoo_packet_hash(pkt, "sss", 109, name, 1, gaim_connection_get_display_name(gc), 62, "2"); |
| 10392 | 935 yahoo_packet_send_and_free(pkt, yd); |
| 6729 | 936 } |
| 937 /* | |
| 938 * These are the functions registered with the core | |
| 939 * which get called for both chats and conferences. | |
| 940 */ | |
| 941 | |
| 942 void yahoo_c_leave(GaimConnection *gc, int id) | |
| 943 { | |
| 944 struct yahoo_data *yd = (struct yahoo_data *) gc->proto_data; | |
| 945 GaimConversation *c; | |
| 946 | |
| 947 if (!yd) | |
| 948 return; | |
| 949 | |
| 950 c = gaim_find_chat(gc, id); | |
| 951 if (!c) | |
| 952 return; | |
| 953 | |
| 954 if (id != YAHOO_CHAT_ID) { | |
| 955 yahoo_conf_leave(yd, gaim_conversation_get_name(c), | |
|
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
6804
diff
changeset
|
956 gaim_connection_get_display_name(gc), gaim_conv_chat_get_users(GAIM_CONV_CHAT(c))); |
| 6729 | 957 yd->confs = g_slist_remove(yd->confs, c); |
| 958 } else { | |
| 7186 | 959 yahoo_chat_leave(gc, gaim_conversation_get_name(c), gaim_connection_get_display_name(gc), TRUE); |
| 6729 | 960 } |
| 961 | |
| 962 serv_got_chat_left(gc, id); | |
| 963 } | |
| 964 | |
| 12216 | 965 int yahoo_c_send(GaimConnection *gc, int id, const char *what, GaimMessageFlags flags) |
| 6729 | 966 { |
| 967 GaimConversation *c; | |
| 968 int ret; | |
| 969 struct yahoo_data *yd; | |
| 970 | |
| 971 yd = (struct yahoo_data *) gc->proto_data; | |
| 972 if (!yd) | |
| 973 return -1; | |
| 974 | |
| 975 c = gaim_find_chat(gc, id); | |
| 976 if (!c) | |
| 977 return -1; | |
| 978 | |
| 979 if (id != YAHOO_CHAT_ID) { | |
| 7827 | 980 ret = yahoo_conf_send(gc, gaim_connection_get_display_name(gc), |
|
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
6804
diff
changeset
|
981 gaim_conversation_get_name(c), gaim_conv_chat_get_users(GAIM_CONV_CHAT(c)), what); |
| 6729 | 982 } else { |
| 7827 | 983 ret = yahoo_chat_send(gc, gaim_connection_get_display_name(gc), |
| 12216 | 984 gaim_conversation_get_name(c), what, flags); |
| 6729 | 985 if (!ret) |
|
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
6804
diff
changeset
|
986 serv_got_chat_in(gc, gaim_conv_chat_get_id(GAIM_CONV_CHAT(c)), |
| 6729 | 987 gaim_connection_get_display_name(gc), 0, what, time(NULL)); |
| 988 } | |
| 989 return ret; | |
| 990 } | |
| 991 | |
| 992 GList *yahoo_c_info(GaimConnection *gc) | |
| 993 { | |
| 994 GList *m = NULL; | |
| 995 struct proto_chat_entry *pce; | |
| 996 | |
| 997 pce = g_new0(struct proto_chat_entry, 1); | |
| 7841 | 998 pce->label = _("_Room:"); |
| 6729 | 999 pce->identifier = "room"; |
| 10954 | 1000 pce->required = TRUE; |
| 6729 | 1001 m = g_list_append(m, pce); |
| 1002 | |
| 1003 return m; | |
| 1004 } | |
| 1005 | |
| 9768 | 1006 GHashTable *yahoo_c_info_defaults(GaimConnection *gc, const char *chat_name) |
| 1007 { | |
| 1008 GHashTable *defaults; | |
| 1009 | |
| 1010 defaults = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, g_free); | |
| 1011 | |
| 1012 if (chat_name != NULL) | |
| 1013 g_hash_table_insert(defaults, "room", g_strdup(chat_name)); | |
| 1014 | |
| 1015 return defaults; | |
| 1016 } | |
| 1017 | |
| 9917 | 1018 char *yahoo_get_chat_name(GHashTable *data) |
| 1019 { | |
| 1020 return g_strdup(g_hash_table_lookup(data, "room")); | |
| 1021 } | |
| 1022 | |
| 6729 | 1023 void yahoo_c_join(GaimConnection *gc, GHashTable *data) |
| 1024 { | |
| 1025 struct yahoo_data *yd; | |
| 1026 char *room, *topic, *members, *type; | |
| 1027 int id; | |
| 1028 GaimConversation *c; | |
| 1029 | |
| 1030 yd = (struct yahoo_data *) gc->proto_data; | |
| 1031 if (!yd) | |
| 1032 return; | |
| 1033 | |
| 1034 room = g_hash_table_lookup(data, "room"); | |
| 1035 if (!room) | |
| 1036 return; | |
| 1037 | |
| 1038 topic = g_hash_table_lookup(data, "topic"); | |
| 1039 if (!topic) | |
| 1040 topic = ""; | |
| 1041 | |
| 1042 members = g_hash_table_lookup(data, "members"); | |
| 1043 | |
| 1044 if ((type = g_hash_table_lookup(data, "type")) && !strcmp(type, "Conference")) { | |
| 1045 id = yd->conf_id++; | |
| 1046 c = serv_got_joined_chat(gc, id, room); | |
| 1047 yd->confs = g_slist_prepend(yd->confs, c); | |
|
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
6804
diff
changeset
|
1048 gaim_conv_chat_set_topic(GAIM_CONV_CHAT(c), gaim_connection_get_display_name(gc), topic); |
| 6729 | 1049 yahoo_conf_join(yd, c, gaim_connection_get_display_name(gc), room, topic, members); |
| 1050 return; | |
| 1051 } else { | |
| 1052 if (yd->in_chat) | |
| 7186 | 1053 yahoo_chat_leave(gc, room, |
| 1054 gaim_connection_get_display_name(gc), | |
| 1055 FALSE); | |
| 6729 | 1056 if (!yd->chat_online) |
| 1057 yahoo_chat_online(gc); | |
| 7827 | 1058 yahoo_chat_join(gc, gaim_connection_get_display_name(gc), room, topic); |
| 6729 | 1059 return; |
| 1060 } | |
| 1061 } | |
| 1062 | |
| 1063 void yahoo_c_invite(GaimConnection *gc, int id, const char *msg, const char *name) | |
| 1064 { | |
| 1065 GaimConversation *c; | |
| 1066 | |
| 1067 c = gaim_find_chat(gc, id); | |
| 1068 if (!c || !c->name) | |
| 1069 return; | |
| 1070 | |
| 1071 if (id != YAHOO_CHAT_ID) { | |
| 7827 | 1072 yahoo_conf_invite(gc, c, gaim_connection_get_display_name(gc), name, |
| 6729 | 1073 gaim_conversation_get_name(c), msg); |
| 1074 } else { | |
| 7827 | 1075 yahoo_chat_invite(gc, gaim_connection_get_display_name(gc), name, |
| 6729 | 1076 gaim_conversation_get_name(c), msg); |
| 1077 } | |
| 1078 } | |
| 1079 | |
| 8113 | 1080 struct yahoo_roomlist { |
| 1081 int fd; | |
| 1082 int inpa; | |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13000
diff
changeset
|
1083 guchar *txbuf; |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13000
diff
changeset
|
1084 gsize tx_written; |
| 8113 | 1085 guchar *rxqueue; |
| 1086 int rxlen; | |
| 1087 gboolean started; | |
| 1088 char *path; | |
| 1089 char *host; | |
| 1090 GaimRoomlist *list; | |
| 1091 GaimRoomlistRoom *cat; | |
| 1092 GaimRoomlistRoom *ucat; | |
| 1093 GMarkupParseContext *parse; | |
| 1094 }; | |
| 1095 | |
| 1096 static void yahoo_roomlist_destroy(struct yahoo_roomlist *yrl) | |
| 1097 { | |
| 1098 if (yrl->inpa) | |
| 1099 gaim_input_remove(yrl->inpa); | |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13000
diff
changeset
|
1100 g_free(yrl->txbuf); |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13000
diff
changeset
|
1101 g_free(yrl->rxqueue); |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13000
diff
changeset
|
1102 g_free(yrl->path); |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13000
diff
changeset
|
1103 g_free(yrl->host); |
| 8113 | 1104 if (yrl->parse) |
| 1105 g_markup_parse_context_free(yrl->parse); | |
| 10504 | 1106 g_free(yrl); |
| 8113 | 1107 } |
| 1108 | |
| 1109 enum yahoo_room_type { | |
| 1110 yrt_yahoo, | |
| 1111 yrt_user, | |
| 1112 }; | |
| 1113 | |
| 1114 struct yahoo_chatxml_state { | |
| 1115 GaimRoomlist *list; | |
| 1116 struct yahoo_roomlist *yrl; | |
| 1117 GQueue *q; | |
| 1118 struct { | |
| 1119 enum yahoo_room_type type; | |
| 1120 char *name; | |
| 1121 char *topic; | |
| 1122 char *id; | |
| 1123 int users, voices, webcams; | |
| 1124 } room; | |
| 1125 }; | |
| 1126 | |
| 1127 struct yahoo_lobby { | |
| 1128 int count, users, voices, webcams; | |
| 1129 }; | |
| 1130 | |
| 1131 static struct yahoo_chatxml_state *yahoo_chatxml_state_new(GaimRoomlist *list, struct yahoo_roomlist *yrl) | |
| 1132 { | |
| 1133 struct yahoo_chatxml_state *s; | |
| 1134 | |
| 1135 s = g_new0(struct yahoo_chatxml_state, 1); | |
| 1136 s->list = list; | |
| 1137 s->yrl = yrl; | |
| 1138 s->q = g_queue_new(); | |
| 1139 | |
| 1140 return s; | |
| 1141 } | |
| 1142 | |
| 1143 static void yahoo_chatxml_state_destroy(struct yahoo_chatxml_state *s) | |
| 1144 { | |
| 1145 g_queue_free(s->q); | |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13000
diff
changeset
|
1146 g_free(s->room.name); |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13000
diff
changeset
|
1147 g_free(s->room.topic); |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13000
diff
changeset
|
1148 g_free(s->room.id); |
| 8113 | 1149 g_free(s); |
| 1150 } | |
| 1151 | |
| 11644 | 1152 static void yahoo_chatlist_start_element(GMarkupParseContext *context, |
| 1153 const gchar *ename, const gchar **anames, | |
| 1154 const gchar **avalues, gpointer user_data, | |
| 1155 GError **error) | |
| 8113 | 1156 { |
| 1157 struct yahoo_chatxml_state *s = user_data; | |
| 1158 GaimRoomlist *list = s->list; | |
| 1159 GaimRoomlistRoom *r; | |
| 1160 GaimRoomlistRoom *parent; | |
| 1161 int i; | |
| 1162 | |
| 1163 if (!strcmp(ename, "category")) { | |
| 1164 const gchar *name = NULL, *id = NULL; | |
| 1165 | |
| 1166 for (i = 0; anames[i]; i++) { | |
| 1167 if (!strcmp(anames[i], "id")) | |
| 1168 id = avalues[i]; | |
| 1169 if (!strcmp(anames[i], "name")) | |
| 1170 name = avalues[i]; | |
| 1171 } | |
| 1172 if (!name || !id) | |
| 1173 return; | |
| 1174 | |
| 1175 parent = g_queue_peek_head(s->q); | |
| 8584 | 1176 r = gaim_roomlist_room_new(GAIM_ROOMLIST_ROOMTYPE_CATEGORY, name, parent); |
| 8113 | 1177 gaim_roomlist_room_add_field(list, r, (gpointer)name); |
| 1178 gaim_roomlist_room_add_field(list, r, (gpointer)id); | |
| 1179 gaim_roomlist_room_add(list, r); | |
| 1180 g_queue_push_head(s->q, r); | |
| 1181 } else if (!strcmp(ename, "room")) { | |
| 1182 s->room.users = s->room.voices = s->room.webcams = 0; | |
| 1183 | |
| 1184 for (i = 0; anames[i]; i++) { | |
| 1185 if (!strcmp(anames[i], "id")) { | |
| 1186 if (s->room.id) | |
| 1187 g_free(s->room.id); | |
| 1188 s->room.id = g_strdup(avalues[i]); | |
| 1189 } else if (!strcmp(anames[i], "name")) { | |
| 1190 if (s->room.name) | |
| 1191 g_free(s->room.name); | |
| 1192 s->room.name = g_strdup(avalues[i]); | |
| 1193 } else if (!strcmp(anames[i], "topic")) { | |
| 1194 if (s->room.topic) | |
| 1195 g_free(s->room.topic); | |
| 1196 s->room.topic = g_strdup(avalues[i]); | |
| 1197 } else if (!strcmp(anames[i], "type")) { | |
| 1198 if (!strcmp("yahoo", avalues[i])) | |
| 1199 s->room.type = yrt_yahoo; | |
| 1200 else | |
| 1201 s->room.type = yrt_user; | |
| 1202 } | |
| 1203 } | |
| 1204 | |
| 1205 } else if (!strcmp(ename, "lobby")) { | |
| 1206 struct yahoo_lobby *lob = g_new0(struct yahoo_lobby, 1); | |
| 1207 | |
| 1208 for (i = 0; anames[i]; i++) { | |
| 1209 if (!strcmp(anames[i], "count")) { | |
| 1210 lob->count = strtol(avalues[i], NULL, 10); | |
| 1211 } else if (!strcmp(anames[i], "users")) { | |
| 1212 s->room.users += lob->users = strtol(avalues[i], NULL, 10); | |
| 1213 } else if (!strcmp(anames[i], "voices")) { | |
| 1214 s->room.voices += lob->voices = strtol(avalues[i], NULL, 10); | |
| 1215 } else if (!strcmp(anames[i], "webcams")) { | |
| 1216 s->room.webcams += lob->webcams = strtol(avalues[i], NULL, 10); | |
| 1217 } | |
| 1218 } | |
| 1219 g_queue_push_head(s->q, lob); | |
| 1220 } | |
| 1221 } | |
| 1222 | |
| 1223 static void yahoo_chatlist_end_element(GMarkupParseContext *context, const gchar *ename, | |
| 1224 gpointer user_data, GError **error) | |
| 1225 { | |
| 1226 struct yahoo_chatxml_state *s = user_data; | |
| 1227 | |
| 1228 if (!strcmp(ename, "category")) { | |
| 1229 g_queue_pop_head(s->q); | |
| 1230 } else if (!strcmp(ename, "room")) { | |
| 1231 struct yahoo_lobby *lob; | |
| 1232 GaimRoomlistRoom *r, *l; | |
| 1233 | |
| 1234 if (s->room.type == yrt_yahoo) | |
| 8584 | 1235 r = gaim_roomlist_room_new(GAIM_ROOMLIST_ROOMTYPE_CATEGORY|GAIM_ROOMLIST_ROOMTYPE_ROOM, |
| 8113 | 1236 s->room.name, s->yrl->cat); |
| 1237 else | |
| 8584 | 1238 r = gaim_roomlist_room_new(GAIM_ROOMLIST_ROOMTYPE_CATEGORY|GAIM_ROOMLIST_ROOMTYPE_ROOM, |
| 8113 | 1239 s->room.name, s->yrl->ucat); |
| 1240 | |
| 1241 gaim_roomlist_room_add_field(s->list, r, s->room.name); | |
| 1242 gaim_roomlist_room_add_field(s->list, r, s->room.id); | |
| 1243 gaim_roomlist_room_add_field(s->list, r, GINT_TO_POINTER(s->room.users)); | |
| 1244 gaim_roomlist_room_add_field(s->list, r, GINT_TO_POINTER(s->room.voices)); | |
| 1245 gaim_roomlist_room_add_field(s->list, r, GINT_TO_POINTER(s->room.webcams)); | |
| 1246 gaim_roomlist_room_add_field(s->list, r, s->room.topic); | |
| 1247 gaim_roomlist_room_add(s->list, r); | |
| 1248 | |
| 1249 while ((lob = g_queue_pop_head(s->q))) { | |
| 1250 char *name = g_strdup_printf("%s:%d", s->room.name, lob->count); | |
| 1251 l = gaim_roomlist_room_new(GAIM_ROOMLIST_ROOMTYPE_ROOM, name, r); | |
| 1252 | |
| 1253 gaim_roomlist_room_add_field(s->list, l, name); | |
| 1254 gaim_roomlist_room_add_field(s->list, l, s->room.id); | |
| 1255 gaim_roomlist_room_add_field(s->list, l, GINT_TO_POINTER(lob->users)); | |
| 1256 gaim_roomlist_room_add_field(s->list, l, GINT_TO_POINTER(lob->voices)); | |
| 1257 gaim_roomlist_room_add_field(s->list, l, GINT_TO_POINTER(lob->webcams)); | |
| 1258 gaim_roomlist_room_add_field(s->list, l, s->room.topic); | |
| 1259 gaim_roomlist_room_add(s->list, l); | |
| 1260 | |
| 1261 g_free(name); | |
| 1262 g_free(lob); | |
| 1263 } | |
| 1264 } | |
| 1265 } | |
| 1266 | |
| 1267 static GMarkupParser parser = { | |
| 1268 yahoo_chatlist_start_element, | |
| 1269 yahoo_chatlist_end_element, | |
| 1270 NULL, | |
| 1271 NULL, | |
| 1272 NULL | |
| 1273 }; | |
| 1274 | |
| 1275 static void yahoo_roomlist_cleanup(GaimRoomlist *list, struct yahoo_roomlist *yrl) | |
| 1276 { | |
| 1277 gaim_roomlist_set_in_progress(list, FALSE); | |
| 1278 | |
| 1279 if (yrl) { | |
| 1280 list->proto_data = g_list_remove(list->proto_data, yrl); | |
| 1281 yahoo_roomlist_destroy(yrl); | |
| 1282 } | |
| 1283 | |
| 1284 gaim_roomlist_unref(list); | |
| 1285 } | |
| 1286 | |
| 1287 static void yahoo_roomlist_pending(gpointer data, gint source, GaimInputCondition cond) | |
| 1288 { | |
| 1289 struct yahoo_roomlist *yrl = data; | |
| 1290 GaimRoomlist *list = yrl->list; | |
| 1291 char buf[1024]; | |
| 1292 int len; | |
| 1293 guchar *start; | |
| 1294 struct yahoo_chatxml_state *s; | |
| 1295 | |
| 1296 len = read(yrl->fd, buf, sizeof(buf)); | |
| 1297 | |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13000
diff
changeset
|
1298 if (len < 0 && errno == EAGAIN) |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13000
diff
changeset
|
1299 return; |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13000
diff
changeset
|
1300 |
| 8113 | 1301 if (len <= 0) { |
| 1302 if (yrl->parse) | |
| 1303 g_markup_parse_context_end_parse(yrl->parse, NULL); | |
| 1304 yahoo_roomlist_cleanup(list, yrl); | |
| 1305 return; | |
| 1306 } | |
| 1307 | |
| 1308 yrl->rxqueue = g_realloc(yrl->rxqueue, len + yrl->rxlen); | |
| 1309 memcpy(yrl->rxqueue + yrl->rxlen, buf, len); | |
| 1310 yrl->rxlen += len; | |
| 1311 | |
| 1312 if (!yrl->started) { | |
| 1313 yrl->started = TRUE; | |
| 11318 | 1314 start = (guchar *)g_strstr_len((char *)yrl->rxqueue, yrl->rxlen, "\r\n\r\n"); |
| 8113 | 1315 if (!start || (start - yrl->rxqueue + 4) >= yrl->rxlen) |
| 1316 return; | |
| 1317 start += 4; | |
| 1318 } else { | |
| 1319 start = yrl->rxqueue; | |
| 1320 } | |
| 1321 | |
| 1322 if (yrl->parse == NULL) { | |
| 1323 s = yahoo_chatxml_state_new(list, yrl); | |
| 1324 yrl->parse = g_markup_parse_context_new(&parser, 0, s, | |
| 1325 (GDestroyNotify)yahoo_chatxml_state_destroy); | |
| 1326 } | |
| 1327 | |
| 11318 | 1328 if (!g_markup_parse_context_parse(yrl->parse, (char *)start, (yrl->rxlen - (start - yrl->rxqueue)), NULL)) { |
| 8113 | 1329 |
| 1330 yahoo_roomlist_cleanup(list, yrl); | |
| 1331 return; | |
| 1332 } | |
| 1333 | |
| 1334 yrl->rxlen = 0; | |
| 1335 } | |
| 1336 | |
| 1337 static void yahoo_roomlist_got_connected(gpointer data, gint source, GaimInputCondition cond) | |
| 1338 { | |
| 1339 struct yahoo_roomlist *yrl = data; | |
| 1340 GaimRoomlist *list = yrl->list; | |
| 1341 struct yahoo_data *yd = gaim_account_get_connection(list->account)->proto_data; | |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13000
diff
changeset
|
1342 int written, total_len; |
| 8113 | 1343 |
| 1344 if (source < 0) { | |
| 1345 gaim_notify_error(gaim_account_get_connection(list->account), NULL, _("Unable to connect"), _("Fetching the room list failed.")); | |
| 1346 yahoo_roomlist_cleanup(list, yrl); | |
| 1347 return; | |
| 1348 } | |
| 1349 | |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13000
diff
changeset
|
1350 if (yrl->txbuf == NULL) { |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13000
diff
changeset
|
1351 yrl->fd = source; |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13000
diff
changeset
|
1352 |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13000
diff
changeset
|
1353 yrl->txbuf = g_strdup_printf( |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13000
diff
changeset
|
1354 "GET http://%s/%s HTTP/1.0\r\n" |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13000
diff
changeset
|
1355 "Host: %s\r\n" |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13000
diff
changeset
|
1356 "Cookie: Y=%s; T=%s\r\n\r\n", |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13000
diff
changeset
|
1357 yrl->host, yrl->path, yrl->host, yd->cookie_y, |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13000
diff
changeset
|
1358 yd->cookie_t); |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13000
diff
changeset
|
1359 } |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13000
diff
changeset
|
1360 |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13000
diff
changeset
|
1361 total_len = strlen(yrl->txbuf) - yrl->tx_written; |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13000
diff
changeset
|
1362 written = write(yrl->fd, yrl->txbuf + yrl->tx_written, total_len); |
| 8113 | 1363 |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13000
diff
changeset
|
1364 if (written < 0 && errno == EAGAIN) |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13000
diff
changeset
|
1365 written = 0; |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13000
diff
changeset
|
1366 else if (written <= 0) { |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13000
diff
changeset
|
1367 if (yrl->inpa) |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13000
diff
changeset
|
1368 gaim_input_remove(yrl->inpa); |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13000
diff
changeset
|
1369 yrl->inpa = 0; |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13000
diff
changeset
|
1370 g_free(yrl->txbuf); |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13000
diff
changeset
|
1371 yrl->txbuf = NULL; |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13000
diff
changeset
|
1372 gaim_notify_error(gaim_account_get_connection(list->account), NULL, _("Unable to connect"), _("Fetching the room list failed.")); |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13000
diff
changeset
|
1373 yahoo_roomlist_cleanup(list, yrl); |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13000
diff
changeset
|
1374 return; |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13000
diff
changeset
|
1375 } |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13000
diff
changeset
|
1376 |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13000
diff
changeset
|
1377 if (written < total_len) { |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13000
diff
changeset
|
1378 if (!yrl->inpa) |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13000
diff
changeset
|
1379 yrl->inpa = gaim_input_add(yrl->fd, |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13000
diff
changeset
|
1380 GAIM_INPUT_WRITE, yahoo_roomlist_got_connected, |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13000
diff
changeset
|
1381 yrl); |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13000
diff
changeset
|
1382 yrl->tx_written += written; |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13000
diff
changeset
|
1383 return; |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13000
diff
changeset
|
1384 } |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13000
diff
changeset
|
1385 |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13000
diff
changeset
|
1386 g_free(yrl->txbuf); |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13000
diff
changeset
|
1387 yrl->txbuf = NULL; |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13000
diff
changeset
|
1388 if (yrl->inpa) |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13000
diff
changeset
|
1389 gaim_input_remove(yrl->inpa); |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13000
diff
changeset
|
1390 yrl->inpa = gaim_input_add(yrl->fd, GAIM_INPUT_READ, |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13000
diff
changeset
|
1391 yahoo_roomlist_pending, yrl); |
| 8113 | 1392 |
| 1393 } | |
| 1394 | |
| 1395 GaimRoomlist *yahoo_roomlist_get_list(GaimConnection *gc) | |
| 1396 { | |
| 1397 struct yahoo_roomlist *yrl; | |
| 1398 GaimRoomlist *rl; | |
| 12212 | 1399 const char *rll; |
| 8113 | 1400 char *url; |
| 1401 GList *fields = NULL; | |
| 1402 GaimRoomlistField *f; | |
| 1403 | |
| 12212 | 1404 rll = gaim_account_get_string(gaim_connection_get_account(gc), |
| 1405 "room_list_locale", YAHOO_ROOMLIST_LOCALE); | |
| 1406 | |
| 1407 if (rll != NULL && *rll != '\0') { | |
|
11043
629cbfd1ed6d
[gaim-migrate @ 12957]
Richard Laager <rlaager@wiktel.com>
parents:
10954
diff
changeset
|
1408 url = g_strdup_printf("%s?chatcat=0&intl=%s", |
|
629cbfd1ed6d
[gaim-migrate @ 12957]
Richard Laager <rlaager@wiktel.com>
parents:
10954
diff
changeset
|
1409 gaim_account_get_string(gaim_connection_get_account(gc), |
| 12212 | 1410 "room_list", YAHOO_ROOMLIST_URL), rll); |
|
11043
629cbfd1ed6d
[gaim-migrate @ 12957]
Richard Laager <rlaager@wiktel.com>
parents:
10954
diff
changeset
|
1411 } else { |
|
629cbfd1ed6d
[gaim-migrate @ 12957]
Richard Laager <rlaager@wiktel.com>
parents:
10954
diff
changeset
|
1412 url = g_strdup_printf("%s?chatcat=0", |
|
629cbfd1ed6d
[gaim-migrate @ 12957]
Richard Laager <rlaager@wiktel.com>
parents:
10954
diff
changeset
|
1413 gaim_account_get_string(gaim_connection_get_account(gc), |
|
629cbfd1ed6d
[gaim-migrate @ 12957]
Richard Laager <rlaager@wiktel.com>
parents:
10954
diff
changeset
|
1414 "room_list", YAHOO_ROOMLIST_URL)); |
|
629cbfd1ed6d
[gaim-migrate @ 12957]
Richard Laager <rlaager@wiktel.com>
parents:
10954
diff
changeset
|
1415 } |
| 8113 | 1416 |
| 1417 yrl = g_new0(struct yahoo_roomlist, 1); | |
| 1418 rl = gaim_roomlist_new(gaim_connection_get_account(gc)); | |
| 1419 yrl->list = rl; | |
| 1420 | |
|
9227
9171e528d7e5
[gaim-migrate @ 10023]
Christian Hammond <chipx86@chipx86.com>
parents:
8735
diff
changeset
|
1421 gaim_url_parse(url, &(yrl->host), NULL, &(yrl->path), NULL, NULL); |
| 8113 | 1422 g_free(url); |
| 1423 | |
| 1424 f = gaim_roomlist_field_new(GAIM_ROOMLIST_FIELD_STRING, "", "room", TRUE); | |
| 1425 fields = g_list_append(fields, f); | |
| 1426 | |
| 1427 f = gaim_roomlist_field_new(GAIM_ROOMLIST_FIELD_STRING, "", "id", TRUE); | |
| 1428 fields = g_list_append(fields, f); | |
| 1429 | |
| 1430 f = gaim_roomlist_field_new(GAIM_ROOMLIST_FIELD_INT, _("Users"), "users", FALSE); | |
| 1431 fields = g_list_append(fields, f); | |
| 1432 | |
| 1433 f = gaim_roomlist_field_new(GAIM_ROOMLIST_FIELD_INT, _("Voices"), "voices", FALSE); | |
| 1434 fields = g_list_append(fields, f); | |
| 1435 | |
| 1436 f = gaim_roomlist_field_new(GAIM_ROOMLIST_FIELD_INT, _("Webcams"), "webcams", FALSE); | |
| 1437 fields = g_list_append(fields, f); | |
| 1438 | |
| 1439 f = gaim_roomlist_field_new(GAIM_ROOMLIST_FIELD_STRING, _("Topic"), "topic", FALSE); | |
| 1440 fields = g_list_append(fields, f); | |
| 1441 | |
| 1442 gaim_roomlist_set_fields(rl, fields); | |
| 1443 | |
| 1444 if (gaim_proxy_connect(gaim_connection_get_account(gc), | |
| 1445 yrl->host, 80, yahoo_roomlist_got_connected, yrl) != 0) | |
| 1446 { | |
| 1447 gaim_notify_error(gc, NULL, _("Connection problem"), _("Unable to fetch room list.")); | |
| 1448 yahoo_roomlist_cleanup(rl, yrl); | |
| 1449 return NULL; | |
| 1450 } | |
| 1451 | |
| 1452 rl->proto_data = g_list_append(rl->proto_data, yrl); | |
| 1453 | |
| 1454 gaim_roomlist_set_in_progress(rl, TRUE); | |
| 1455 return rl; | |
| 1456 } | |
| 1457 | |
| 1458 void yahoo_roomlist_cancel(GaimRoomlist *list) | |
| 1459 { | |
| 1460 GList *l, *k; | |
| 1461 | |
| 1462 k = l = list->proto_data; | |
| 1463 list->proto_data = NULL; | |
| 1464 | |
| 1465 gaim_roomlist_set_in_progress(list, FALSE); | |
| 1466 | |
| 1467 for (; l; l = l->next) { | |
| 1468 yahoo_roomlist_destroy(l->data); | |
|
10647
7d13c04387ad
[gaim-migrate @ 12163]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10575
diff
changeset
|
1469 gaim_roomlist_unref(list); |
| 8113 | 1470 } |
| 1471 g_list_free(k); | |
| 1472 } | |
| 1473 | |
| 8584 | 1474 void yahoo_roomlist_expand_category(GaimRoomlist *list, GaimRoomlistRoom *category) |
| 8113 | 1475 { |
| 1476 struct yahoo_roomlist *yrl; | |
| 1477 char *url; | |
| 1478 char *id; | |
| 12212 | 1479 const char *rll; |
| 8113 | 1480 |
| 8584 | 1481 if (category->type != GAIM_ROOMLIST_ROOMTYPE_CATEGORY) |
| 8113 | 1482 return; |
| 1483 | |
| 8584 | 1484 if (!(id = g_list_nth_data(category->fields, 1))) { |
| 8113 | 1485 gaim_roomlist_set_in_progress(list, FALSE); |
| 1486 return; | |
| 1487 } | |
| 1488 | |
| 12212 | 1489 rll = gaim_account_get_string(list->account, "room_list_locale", |
| 1490 YAHOO_ROOMLIST_LOCALE); | |
| 1491 | |
| 1492 if (rll != NULL && *rll != '\0') { | |
|
11043
629cbfd1ed6d
[gaim-migrate @ 12957]
Richard Laager <rlaager@wiktel.com>
parents:
10954
diff
changeset
|
1493 url = g_strdup_printf("%s?chatroom_%s=0&intl=%s", |
| 12212 | 1494 gaim_account_get_string(list->account,"room_list", |
| 1495 YAHOO_ROOMLIST_URL), id, rll); | |
|
11043
629cbfd1ed6d
[gaim-migrate @ 12957]
Richard Laager <rlaager@wiktel.com>
parents:
10954
diff
changeset
|
1496 } else { |
|
629cbfd1ed6d
[gaim-migrate @ 12957]
Richard Laager <rlaager@wiktel.com>
parents:
10954
diff
changeset
|
1497 url = g_strdup_printf("%s?chatroom_%s=0", |
|
629cbfd1ed6d
[gaim-migrate @ 12957]
Richard Laager <rlaager@wiktel.com>
parents:
10954
diff
changeset
|
1498 gaim_account_get_string(list->account,"room_list", |
|
629cbfd1ed6d
[gaim-migrate @ 12957]
Richard Laager <rlaager@wiktel.com>
parents:
10954
diff
changeset
|
1499 YAHOO_ROOMLIST_URL), id); |
|
629cbfd1ed6d
[gaim-migrate @ 12957]
Richard Laager <rlaager@wiktel.com>
parents:
10954
diff
changeset
|
1500 } |
| 8113 | 1501 |
| 1502 yrl = g_new0(struct yahoo_roomlist, 1); | |
| 1503 yrl->list = list; | |
| 8584 | 1504 yrl->cat = category; |
| 8113 | 1505 list->proto_data = g_list_append(list->proto_data, yrl); |
| 1506 | |
|
9227
9171e528d7e5
[gaim-migrate @ 10023]
Christian Hammond <chipx86@chipx86.com>
parents:
8735
diff
changeset
|
1507 gaim_url_parse(url, &(yrl->host), NULL, &(yrl->path), NULL, NULL); |
| 8113 | 1508 g_free(url); |
| 1509 | |
| 8584 | 1510 yrl->ucat = gaim_roomlist_room_new(GAIM_ROOMLIST_ROOMTYPE_CATEGORY, _("User Rooms"), yrl->cat); |
| 8113 | 1511 gaim_roomlist_room_add(list, yrl->ucat); |
| 1512 | |
| 1513 if (gaim_proxy_connect(list->account, | |
| 1514 yrl->host, 80, yahoo_roomlist_got_connected, yrl) != 0) | |
| 1515 { | |
| 1516 gaim_notify_error(gaim_account_get_connection(list->account), | |
| 1517 NULL, _("Connection problem"), _("Unable to fetch room list.")); | |
|
10647
7d13c04387ad
[gaim-migrate @ 12163]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10575
diff
changeset
|
1518 gaim_roomlist_ref(list); |
| 8113 | 1519 yahoo_roomlist_cleanup(list, yrl); |
| 1520 return; | |
| 1521 } | |
| 1522 | |
| 1523 gaim_roomlist_set_in_progress(list, TRUE); | |
| 1524 gaim_roomlist_ref(list); | |
| 1525 } |
