Mercurial > pidgin
annotate src/protocols/yahoo/yahoo.c @ 10394:45a0a07e8b25
[gaim-migrate @ 11623]
Renamed yahoo_packet_hash to yahoo_packet_hash_str, added
yahoo_packet_hash_int, and a new variable arg yahoo_packet_hash that calls
either of them.
I was going to add some more format chars to yahoo_packet_hash, and may
yet. Stuff like automaticly converting strings' character sets or html
to yahoo codes, etc. But first I want to look at how yahoo 6 handles
character sets and see if it's any different.
Feel free to give opinions on if these changes are actually better,
assuming you actually look at them, as opposed to running away like a girly
man when you see yahoo protocol code.
committer: Tailor Script <tailor@pidgin.im>
author | Tim Ringenbach <marv@pidgin.im> |
---|---|
date | Fri, 17 Dec 2004 00:05:32 +0000 |
parents | a8f9e5ce4f92 |
children | 6a043ae92db6 |
rev | line source |
---|---|
2681 | 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. | |
2681 | 7 * |
8 * This program is free software; you can redistribute it and/or modify | |
9 * it under the terms of the GNU General Public License as published by | |
10 * the Free Software Foundation; either version 2 of the License, or | |
11 * (at your option) any later version. | |
12 * | |
13 * This program is distributed in the hope that it will be useful, | |
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 * GNU General Public License for more details. | |
17 * | |
18 * You should have received a copy of the GNU General Public License | |
19 * along with this program; if not, write to the Free Software | |
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
21 * | |
22 */ | |
9369 | 23 |
5872
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5685
diff
changeset
|
24 #include "internal.h" |
2681 | 25 |
5872
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5685
diff
changeset
|
26 #include "account.h" |
5638
0bdfa28c678e
[gaim-migrate @ 6047]
Christian Hammond <chipx86@chipx86.com>
parents:
5590
diff
changeset
|
27 #include "accountopt.h" |
6760 | 28 #include "blist.h" |
10119 | 29 #include "cmds.h" |
5872
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5685
diff
changeset
|
30 #include "debug.h" |
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5685
diff
changeset
|
31 #include "notify.h" |
6760 | 32 #include "privacy.h" |
2681 | 33 #include "prpl.h" |
34 #include "proxy.h" | |
5872
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5685
diff
changeset
|
35 #include "request.h" |
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5685
diff
changeset
|
36 #include "server.h" |
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5685
diff
changeset
|
37 #include "util.h" |
9943 | 38 #include "version.h" |
5872
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5685
diff
changeset
|
39 |
6986 | 40 #include "sha.h" |
6513 | 41 #include "yahoo.h" |
10392 | 42 #include "yahoo_packet.h" |
9278 | 43 #include "yahoo_friend.h" |
6729 | 44 #include "yahoochat.h" |
9376 | 45 #include "ycht.h" |
8349 | 46 #include "yahoo_auth.h" |
7651 | 47 #include "yahoo_filexfer.h" |
9306 | 48 #include "yahoo_picture.h" |
3147 | 49 #include "md5.h" |
2681 | 50 |
5583 | 51 extern char *yahoo_crypt(const char *, const char *); |
2795
536bb833fdeb
[gaim-migrate @ 2808]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2786
diff
changeset
|
52 |
5493
3e8487580024
[gaim-migrate @ 5889]
Christian Hammond <chipx86@chipx86.com>
parents:
5436
diff
changeset
|
53 /* #define YAHOO_DEBUG */ |
2681 | 54 |
9285 | 55 static void yahoo_add_buddy(GaimConnection *gc, GaimBuddy *, GaimGroup *); |
9410 | 56 static void yahoo_login_page_cb(void *user_data, const char *buf, size_t len); |
9306 | 57 |
6784 | 58 |
9278 | 59 static void yahoo_update_status(GaimConnection *gc, const char *name, YahooFriend *f) |
6784 | 60 { |
9927 | 61 gboolean online = TRUE; |
9983 | 62 char *status = NULL; |
6840 | 63 |
6784 | 64 if (!gc || !name || !f || !gaim_find_buddy(gaim_connection_get_account(gc), name)) |
65 return; | |
66 | |
6840 | 67 if (f->status == YAHOO_STATUS_OFFLINE) |
9927 | 68 online = FALSE; |
6840 | 69 |
9983 | 70 switch (f->status) { |
71 case YAHOO_STATUS_AVAILABLE: | |
10373 | 72 status = YAHOO_STATUS_TYPE_AVAILABLE; |
9983 | 73 break; |
74 case YAHOO_STATUS_BRB: | |
10373 | 75 status = YAHOO_STATUS_TYPE_BRB; |
9983 | 76 break; |
77 case YAHOO_STATUS_BUSY: | |
10373 | 78 status = YAHOO_STATUS_TYPE_BUSY; |
9983 | 79 break; |
80 case YAHOO_STATUS_NOTATHOME: | |
10373 | 81 status = YAHOO_STATUS_TYPE_NOTATHOME; |
9983 | 82 break; |
83 case YAHOO_STATUS_NOTATDESK: | |
10373 | 84 status = YAHOO_STATUS_TYPE_NOTATDESK; |
9983 | 85 break; |
86 case YAHOO_STATUS_NOTINOFFICE: | |
10373 | 87 status = YAHOO_STATUS_TYPE_NOTINOFFICE; |
9983 | 88 break; |
89 case YAHOO_STATUS_ONPHONE: | |
10373 | 90 status = YAHOO_STATUS_TYPE_ONPHONE; |
9983 | 91 break; |
92 case YAHOO_STATUS_ONVACATION: | |
10373 | 93 status = YAHOO_STATUS_TYPE_ONVACATION; |
9983 | 94 break; |
95 case YAHOO_STATUS_OUTTOLUNCH: | |
10373 | 96 status = YAHOO_STATUS_TYPE_OUTTOLUNCH; |
9983 | 97 break; |
98 case YAHOO_STATUS_STEPPEDOUT: | |
10373 | 99 status = YAHOO_STATUS_TYPE_STEPPEDOUT; |
9983 | 100 break; |
101 case YAHOO_STATUS_INVISIBLE: /* this should never happen? */ | |
10373 | 102 status = YAHOO_STATUS_TYPE_INVISIBLE; |
9983 | 103 break; |
104 case YAHOO_STATUS_CUSTOM: | |
105 if (!f->away) | |
10373 | 106 status = YAHOO_STATUS_TYPE_AVAILABLE_WM; |
9983 | 107 else |
10373 | 108 status = YAHOO_STATUS_TYPE_AWAY; |
9983 | 109 break; |
10141 | 110 case YAHOO_STATUS_IDLE: |
9983 | 111 break; |
112 default: | |
113 gaim_debug_warning("yahoo", "Warning, unknown status %d\n", f->status); | |
114 break; | |
115 } | |
116 | |
117 if (status) { | |
118 if (f->status == YAHOO_STATUS_CUSTOM) | |
119 gaim_prpl_got_user_status(gaim_connection_get_account(gc), name, status, "message", | |
120 yahoo_friend_get_status_message(f), NULL); | |
121 else | |
122 gaim_prpl_got_user_status(gaim_connection_get_account(gc), name, status, NULL); | |
123 } | |
124 | |
10141 | 125 if (f->idle != 0) |
126 gaim_prpl_got_user_idle(gaim_connection_get_account(gc), name, TRUE, f->idle); | |
127 else | |
128 gaim_prpl_got_user_idle(gaim_connection_get_account(gc), name, FALSE, 0); | |
6784 | 129 } |
130 | |
5583 | 131 static void yahoo_process_status(GaimConnection *gc, struct yahoo_packet *pkt) |
2681 | 132 { |
9983 | 133 GaimAccount *account = gaim_connection_get_account(gc); |
2681 | 134 struct yahoo_data *yd = gc->proto_data; |
135 GSList *l = pkt->hash; | |
9278 | 136 YahooFriend *f = NULL; |
2681 | 137 char *name = NULL; |
6784 | 138 |
7892 | 139 if (pkt->service == YAHOO_SERVICE_LOGOFF && pkt->status == -1) { |
8383 | 140 gc->wants_to_die = TRUE; |
7892 | 141 gaim_connection_error(gc, _("You have been logged off as you have logged in on a different machine or device.")); |
142 return; | |
143 } | |
6686 | 144 |
2681 | 145 while (l) { |
146 struct yahoo_pair *pair = l->data; | |
147 | |
148 switch (pair->key) { | |
149 case 0: /* we won't actually do anything with this */ | |
150 break; | |
151 case 1: /* we don't get the full buddy list here. */ | |
2805
9b3c7d2a6e9a
[gaim-migrate @ 2818]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2795
diff
changeset
|
152 if (!yd->logged_in) { |
7664 | 153 gaim_connection_set_display_name(gc, pair->value); |
5583 | 154 gaim_connection_set_state(gc, GAIM_CONNECTED); |
2805
9b3c7d2a6e9a
[gaim-migrate @ 2818]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2795
diff
changeset
|
155 serv_finish_login(gc); |
9b3c7d2a6e9a
[gaim-migrate @ 2818]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2795
diff
changeset
|
156 yd->logged_in = TRUE; |
9306 | 157 if (yd->picture_upload_todo) { |
158 yahoo_buddy_icon_upload(gc, yd->picture_upload_todo); | |
159 yd->picture_upload_todo = NULL; | |
160 } | |
2681 | 161 |
3147 | 162 /* this requests the list. i have a feeling that this is very evil |
163 * | |
6686 | 164 * scs.yahoo.com sends you the list before this packet without it being |
3147 | 165 * requested |
166 * | |
167 * do_import(gc, NULL); | |
168 * newpkt = yahoo_packet_new(YAHOO_SERVICE_LIST, YAHOO_STATUS_OFFLINE, 0); | |
10392 | 169 * yahoo_packet_send_and_free(newpkt, yd); |
3147 | 170 */ |
171 | |
172 } | |
2681 | 173 break; |
174 case 8: /* how many online buddies we have */ | |
175 break; | |
176 case 7: /* the current buddy */ | |
177 name = pair->value; | |
9886 | 178 if (name && g_utf8_validate(name, -1, NULL)) |
179 f = yahoo_friend_find_or_new(gc, name); | |
9888 | 180 else { |
181 f = NULL; | |
182 name = NULL; | |
183 } | |
2681 | 184 break; |
185 case 10: /* state */ | |
6784 | 186 if (!f) |
187 break; | |
188 | |
189 f->status = strtol(pair->value, NULL, 10); | |
190 if ((f->status >= YAHOO_STATUS_BRB) && (f->status <= YAHOO_STATUS_STEPPEDOUT)) | |
191 f->away = 1; | |
192 else | |
193 f->away = 0; | |
10141 | 194 |
195 if (f->status == YAHOO_STATUS_IDLE) { | |
196 /* Idle may have already been set in a more precise way in case 137 */ | |
197 if (f->idle == 0) | |
198 f->idle = time(NULL); | |
199 } else | |
6804 | 200 f->idle = 0; |
10141 | 201 |
9283 | 202 if (f->status != YAHOO_STATUS_CUSTOM) |
203 yahoo_friend_set_status_message(f, NULL); | |
6847 | 204 |
205 f->sms = 0; | |
2681 | 206 break; |
207 case 19: /* custom message */ | |
9283 | 208 if (f) |
209 yahoo_friend_set_status_message(f, yahoo_string_decode(gc, pair->value, FALSE)); | |
2681 | 210 break; |
6686 | 211 case 11: /* this is the buddy's session id */ |
2681 | 212 break; |
213 case 17: /* in chat? */ | |
214 break; | |
6784 | 215 case 47: /* is custom status away or not? 2=idle*/ |
216 if (!f) | |
217 break; | |
8441 | 218 |
219 /* I have no idea what it means when this is | |
220 * set when someone's available, but it doesn't | |
221 * mean idle. */ | |
222 if (f->status == YAHOO_STATUS_AVAILABLE) | |
223 break; | |
10141 | 224 |
6784 | 225 f->away = strtol(pair->value, NULL, 10); |
10141 | 226 if (f->away == 2) { |
227 /* Idle may have already been set in a more precise way in case 137 */ | |
228 if (f->idle == 0) | |
229 f->idle = time(NULL); | |
230 } | |
231 | |
6686 | 232 break; |
6784 | 233 case 138: /* either we're not idle, or we are but won't say how long */ |
234 if (!f) | |
235 break; | |
236 | |
237 if (f->idle) | |
238 f->idle = -1; | |
239 break; | |
240 case 137: /* usually idle time in seconds, sometimes login time */ | |
241 if (!f) | |
242 break; | |
243 | |
244 if (f->status != YAHOO_STATUS_AVAILABLE) | |
245 f->idle = time(NULL) - strtol(pair->value, NULL, 10); | |
6686 | 246 break; |
247 case 13: /* bitmask, bit 0 = pager, bit 1 = chat, bit 2 = game */ | |
6784 | 248 if (strtol(pair->value, NULL, 10) == 0) { |
249 if (f) | |
250 f->status = YAHOO_STATUS_OFFLINE; | |
9983 | 251 gaim_prpl_got_user_status(account, name, "offline", NULL); |
2807
f01e6a425136
[gaim-migrate @ 2820]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2805
diff
changeset
|
252 break; |
2805
9b3c7d2a6e9a
[gaim-migrate @ 2818]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2795
diff
changeset
|
253 } |
6784 | 254 |
255 if (f) | |
256 yahoo_update_status(gc, name, f); | |
257 break; | |
258 case 60: /* SMS */ | |
259 if (f) { | |
260 f->sms = strtol(pair->value, NULL, 10); | |
261 yahoo_update_status(gc, name, f); | |
2771
450f4f9d2f23
[gaim-migrate @ 2784]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2741
diff
changeset
|
262 } |
450f4f9d2f23
[gaim-migrate @ 2784]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2741
diff
changeset
|
263 break; |
9292 | 264 case 197: /* Avatars */ |
9277 | 265 { |
266 char *decoded, *tmp; | |
267 guint len; | |
268 | |
269 if (pair->value) { | |
270 gaim_base64_decode(pair->value, &decoded, &len); | |
271 if (len) { | |
272 tmp = gaim_str_binary_to_ascii(decoded, len); | |
273 gaim_debug_info("yahoo", "Got key 197, value = %s\n", tmp); | |
274 g_free(tmp); | |
275 } | |
276 g_free(decoded); | |
277 } | |
278 break; | |
279 } | |
9292 | 280 case 192: /* Pictures, aka Buddy Icons, checksum */ |
281 { | |
282 int cksum = strtol(pair->value, NULL, 10); | |
283 GaimBuddy *b; | |
284 | |
285 if (!name) | |
286 break; | |
287 | |
9325 | 288 b = gaim_find_buddy(gc->account, name); |
289 | |
9292 | 290 if (!cksum || (cksum == -1)) { |
9325 | 291 if (f) |
292 yahoo_friend_set_buddy_icon_need_request(f, TRUE); | |
9292 | 293 gaim_buddy_icons_set_for_user(gc->account, name, NULL, 0); |
9325 | 294 if (b) |
295 gaim_blist_node_remove_setting((GaimBlistNode *)b, YAHOO_ICON_CHECKSUM_KEY); | |
9292 | 296 break; |
297 } | |
298 | |
299 if (!f) | |
300 break; | |
9325 | 301 |
9292 | 302 yahoo_friend_set_buddy_icon_need_request(f, FALSE); |
303 if (cksum != gaim_blist_node_get_int((GaimBlistNode*)b, YAHOO_ICON_CHECKSUM_KEY)) | |
9310 | 304 yahoo_send_picture_request(gc, name); |
9292 | 305 |
306 break; | |
307 } | |
2979 | 308 case 16: /* Custom error message */ |
7827 | 309 { |
310 char *tmp = yahoo_string_decode(gc, pair->value, TRUE); | |
311 gaim_notify_error(gc, NULL, tmp, NULL); | |
312 g_free(tmp); | |
313 } | |
2951 | 314 break; |
2681 | 315 default: |
5220
7b9d78fa051e
[gaim-migrate @ 5590]
Christian Hammond <chipx86@chipx86.com>
parents:
5216
diff
changeset
|
316 gaim_debug(GAIM_DEBUG_ERROR, "yahoo", |
5216
00bd3019749e
[gaim-migrate @ 5586]
Christian Hammond <chipx86@chipx86.com>
parents:
5205
diff
changeset
|
317 "Unknown status key %d\n", pair->key); |
2681 | 318 break; |
319 } | |
320 | |
321 l = l->next; | |
322 } | |
323 } | |
324 | |
9285 | 325 static void yahoo_do_group_check(GaimAccount *account, GHashTable *ht, const char *name, const char *group) |
6820 | 326 { |
327 GaimBuddy *b; | |
328 GaimGroup *g; | |
329 GSList *list, *i; | |
330 gboolean onlist = 0; | |
331 char *oname = NULL; | |
332 | |
9015 | 333 char **oname_p = &oname; |
334 GSList **list_p = &list; | |
335 | |
336 if (!g_hash_table_lookup_extended(ht, gaim_normalize(account, name), (gpointer *) oname_p, (gpointer *) list_p)) | |
6820 | 337 list = gaim_find_buddies(account, name); |
338 else | |
339 g_hash_table_steal(ht, name); | |
340 | |
341 for (i = list; i; i = i->next) { | |
342 b = i->data; | |
343 g = gaim_find_buddys_group(b); | |
344 if (!gaim_utf8_strcasecmp(group, g->name)) { | |
345 gaim_debug(GAIM_DEBUG_MISC, "yahoo", | |
346 "Oh good, %s is in the right group (%s).\n", name, group); | |
347 list = g_slist_delete_link(list, i); | |
348 onlist = 1; | |
349 break; | |
350 } | |
351 } | |
352 | |
353 if (!onlist) { | |
354 gaim_debug(GAIM_DEBUG_MISC, "yahoo", | |
355 "Uhoh, %s isn't on the list (or not in this group), adding him to group %s.\n", name, group); | |
356 if (!(g = gaim_find_group(group))) { | |
357 g = gaim_group_new(group); | |
358 gaim_blist_add_group(g, NULL); | |
359 } | |
360 b = gaim_buddy_new(account, name, NULL); | |
361 gaim_blist_add_buddy(b, NULL, g, NULL); | |
362 } | |
363 | |
364 if (list) { | |
365 if (!oname) | |
7823 | 366 oname = g_strdup(gaim_normalize(account, name)); |
6820 | 367 g_hash_table_insert(ht, oname, list); |
368 } else if (oname) | |
369 g_free(oname); | |
370 } | |
371 | |
372 static void yahoo_do_group_cleanup(gpointer key, gpointer value, gpointer user_data) | |
373 { | |
374 char *name = key; | |
375 GSList *list = value, *i; | |
376 GaimBuddy *b; | |
377 GaimGroup *g; | |
378 | |
379 for (i = list; i; i = i->next) { | |
380 b = i->data; | |
381 g = gaim_find_buddys_group(b); | |
382 gaim_debug(GAIM_DEBUG_MISC, "yahoo", "Deleting Buddy %s from group %s.\n", name, g->name); | |
383 gaim_blist_remove_buddy(b); | |
384 } | |
385 } | |
386 | |
7651 | 387 static char *_getcookie(char *rawcookie) |
388 { | |
389 char *cookie = NULL; | |
390 char *tmpcookie; | |
391 char *cookieend; | |
392 | |
393 if (strlen(rawcookie) < 2) | |
394 return NULL; | |
395 tmpcookie = g_strdup(rawcookie+2); | |
396 cookieend = strchr(tmpcookie, ';'); | |
397 | |
398 if (cookieend) | |
399 *cookieend = '\0'; | |
400 | |
401 cookie = g_strdup(tmpcookie); | |
402 g_free(tmpcookie); | |
403 | |
404 return cookie; | |
405 } | |
406 | |
407 static void yahoo_process_cookie(struct yahoo_data *yd, char *c) | |
408 { | |
409 if (c[0] == 'Y') { | |
410 if (yd->cookie_y) | |
411 g_free(yd->cookie_y); | |
412 yd->cookie_y = _getcookie(c); | |
413 } else if (c[0] == 'T') { | |
414 if (yd->cookie_t) | |
415 g_free(yd->cookie_t); | |
416 yd->cookie_t = _getcookie(c); | |
417 } | |
418 } | |
419 | |
5583 | 420 static void yahoo_process_list(GaimConnection *gc, struct yahoo_packet *pkt) |
2681 | 421 { |
422 GSList *l = pkt->hash; | |
423 gboolean export = FALSE; | |
6760 | 424 gboolean got_serv_list = FALSE; |
6695 | 425 GaimBuddy *b; |
426 GaimGroup *g; | |
9278 | 427 YahooFriend *f = NULL; |
6820 | 428 GaimAccount *account = gaim_connection_get_account(gc); |
6784 | 429 struct yahoo_data *yd = gc->proto_data; |
6820 | 430 GHashTable *ht; |
6784 | 431 |
432 char **lines; | |
433 char **split; | |
434 char **buddies; | |
7823 | 435 char **tmp, **bud, *norm_bud; |
7827 | 436 char *grp = NULL; |
2681 | 437 |
7651 | 438 if (pkt->id) |
439 yd->session_id = pkt->id; | |
440 | |
6691
306790891ce7
[gaim-migrate @ 7217]
Christian Hammond <chipx86@chipx86.com>
parents:
6687
diff
changeset
|
441 while (l) { |
306790891ce7
[gaim-migrate @ 7217]
Christian Hammond <chipx86@chipx86.com>
parents:
6687
diff
changeset
|
442 struct yahoo_pair *pair = l->data; |
306790891ce7
[gaim-migrate @ 7217]
Christian Hammond <chipx86@chipx86.com>
parents:
6687
diff
changeset
|
443 l = l->next; |
306790891ce7
[gaim-migrate @ 7217]
Christian Hammond <chipx86@chipx86.com>
parents:
6687
diff
changeset
|
444 |
6760 | 445 switch (pair->key) { |
446 case 87: | |
6784 | 447 if (!yd->tmp_serv_blist) |
448 yd->tmp_serv_blist = g_string_new(pair->value); | |
449 else | |
450 g_string_append(yd->tmp_serv_blist, pair->value); | |
6760 | 451 break; |
452 case 88: | |
6784 | 453 if (!yd->tmp_serv_ilist) |
454 yd->tmp_serv_ilist = g_string_new(pair->value); | |
455 else | |
456 g_string_append(yd->tmp_serv_ilist, pair->value); | |
6760 | 457 break; |
7651 | 458 case 59: /* cookies, yum */ |
459 yahoo_process_cookie(yd, pair->value); | |
460 break; | |
6691
306790891ce7
[gaim-migrate @ 7217]
Christian Hammond <chipx86@chipx86.com>
parents:
6687
diff
changeset
|
461 } |
306790891ce7
[gaim-migrate @ 7217]
Christian Hammond <chipx86@chipx86.com>
parents:
6687
diff
changeset
|
462 } |
2681 | 463 |
6784 | 464 if (pkt->status != 0) |
465 return; | |
466 | |
467 if (yd->tmp_serv_blist) { | |
6820 | 468 ht = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_slist_free); |
469 | |
6784 | 470 lines = g_strsplit(yd->tmp_serv_blist->str, "\n", -1); |
471 for (tmp = lines; *tmp; tmp++) { | |
472 split = g_strsplit(*tmp, ":", 2); | |
473 if (!split) | |
474 continue; | |
475 if (!split[0] || !split[1]) { | |
476 g_strfreev(split); | |
477 continue; | |
478 } | |
7827 | 479 grp = yahoo_string_decode(gc, split[0], FALSE); |
6784 | 480 buddies = g_strsplit(split[1], ",", -1); |
481 for (bud = buddies; bud && *bud; bud++) { | |
7823 | 482 norm_bud = g_strdup(gaim_normalize(account, *bud)); |
9279 | 483 f = yahoo_friend_find_or_new(gc, norm_bud); |
484 | |
7827 | 485 if (!(b = gaim_find_buddy(account, norm_bud))) { |
486 if (!(g = gaim_find_group(grp))) { | |
487 g = gaim_group_new(grp); | |
6784 | 488 gaim_blist_add_group(g, NULL); |
489 } | |
7823 | 490 b = gaim_buddy_new(account, norm_bud, NULL); |
6784 | 491 gaim_blist_add_buddy(b, NULL, g, NULL); |
492 export = TRUE; | |
6820 | 493 } |
6784 | 494 |
9285 | 495 yahoo_do_group_check(account, ht, norm_bud, grp); |
7823 | 496 g_free(norm_bud); |
6784 | 497 } |
498 g_strfreev(buddies); | |
499 g_strfreev(split); | |
7827 | 500 g_free(grp); |
6784 | 501 } |
502 g_strfreev(lines); | |
503 | |
504 g_string_free(yd->tmp_serv_blist, TRUE); | |
505 yd->tmp_serv_blist = NULL; | |
9285 | 506 g_hash_table_foreach(ht, yahoo_do_group_cleanup, NULL); |
6820 | 507 g_hash_table_destroy(ht); |
6784 | 508 } |
509 | |
510 | |
511 if (yd->tmp_serv_ilist) { | |
512 buddies = g_strsplit(yd->tmp_serv_ilist->str, ",", -1); | |
513 for (bud = buddies; bud && *bud; bud++) { | |
514 /* The server is already ignoring the user */ | |
515 got_serv_list = TRUE; | |
516 gaim_privacy_deny_add(gc->account, *bud, 1); | |
517 } | |
518 g_strfreev(buddies); | |
519 | |
520 g_string_free(yd->tmp_serv_ilist, TRUE); | |
521 yd->tmp_serv_ilist = NULL; | |
522 } | |
523 | |
524 if (got_serv_list) { | |
525 gc->account->perm_deny = 4; | |
526 serv_set_permit_deny(gc); | |
527 } | |
2681 | 528 } |
529 | |
5583 | 530 static void yahoo_process_notify(GaimConnection *gc, struct yahoo_packet *pkt) |
2993 | 531 { |
532 char *msg = NULL; | |
533 char *from = NULL; | |
3019 | 534 char *stat = NULL; |
535 char *game = NULL; | |
9278 | 536 YahooFriend *f = NULL; |
2993 | 537 GSList *l = pkt->hash; |
6784 | 538 |
2993 | 539 while (l) { |
540 struct yahoo_pair *pair = l->data; | |
541 if (pair->key == 4) | |
542 from = pair->value; | |
543 if (pair->key == 49) | |
544 msg = pair->value; | |
3001 | 545 if (pair->key == 13) |
3019 | 546 stat = pair->value; |
547 if (pair->key == 14) | |
548 game = pair->value; | |
2993 | 549 l = l->next; |
550 } | |
3640 | 551 |
6784 | 552 if (!from || !msg) |
3640 | 553 return; |
6686 | 554 |
4793 | 555 if (!g_ascii_strncasecmp(msg, "TYPING", strlen("TYPING"))) { |
3019 | 556 if (*stat == '1') |
5872
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5685
diff
changeset
|
557 serv_got_typing(gc, from, 0, GAIM_TYPING); |
3019 | 558 else |
559 serv_got_typing_stopped(gc, from); | |
4793 | 560 } else if (!g_ascii_strncasecmp(msg, "GAME", strlen("GAME"))) { |
6695 | 561 GaimBuddy *bud = gaim_find_buddy(gc->account, from); |
6784 | 562 |
5216
00bd3019749e
[gaim-migrate @ 5586]
Christian Hammond <chipx86@chipx86.com>
parents:
5205
diff
changeset
|
563 if (!bud) { |
5220
7b9d78fa051e
[gaim-migrate @ 5590]
Christian Hammond <chipx86@chipx86.com>
parents:
5216
diff
changeset
|
564 gaim_debug(GAIM_DEBUG_WARNING, "yahoo", |
5216
00bd3019749e
[gaim-migrate @ 5586]
Christian Hammond <chipx86@chipx86.com>
parents:
5205
diff
changeset
|
565 "%s is playing a game, and doesn't want " |
00bd3019749e
[gaim-migrate @ 5586]
Christian Hammond <chipx86@chipx86.com>
parents:
5205
diff
changeset
|
566 "you to know.\n", from); |
00bd3019749e
[gaim-migrate @ 5586]
Christian Hammond <chipx86@chipx86.com>
parents:
5205
diff
changeset
|
567 } |
00bd3019749e
[gaim-migrate @ 5586]
Christian Hammond <chipx86@chipx86.com>
parents:
5205
diff
changeset
|
568 |
9279 | 569 f = yahoo_friend_find(gc, from); |
6784 | 570 if (!f) |
571 return; /* if they're not on the list, don't bother */ | |
572 | |
9283 | 573 yahoo_friend_set_game(f, NULL); |
6784 | 574 |
3019 | 575 if (*stat == '1') { |
9283 | 576 yahoo_friend_set_game(f, game); |
3020 | 577 if (bud) |
6784 | 578 yahoo_update_status(gc, from, f); |
3019 | 579 } |
580 } | |
2993 | 581 } |
582 | |
7827 | 583 |
584 struct _yahoo_im { | |
585 char *from; | |
586 int time; | |
587 int utf8; | |
9284 | 588 int buddy_icon; |
7827 | 589 char *msg; |
590 }; | |
591 | |
5583 | 592 static void yahoo_process_message(GaimConnection *gc, struct yahoo_packet *pkt) |
2681 | 593 { |
6691
306790891ce7
[gaim-migrate @ 7217]
Christian Hammond <chipx86@chipx86.com>
parents:
6687
diff
changeset
|
594 GSList *l = pkt->hash; |
7827 | 595 GSList *list = NULL; |
596 struct _yahoo_im *im = NULL; | |
6069 | 597 |
6691
306790891ce7
[gaim-migrate @ 7217]
Christian Hammond <chipx86@chipx86.com>
parents:
6687
diff
changeset
|
598 if (pkt->status <= 1 || pkt->status == 5) { |
306790891ce7
[gaim-migrate @ 7217]
Christian Hammond <chipx86@chipx86.com>
parents:
6687
diff
changeset
|
599 while (l) { |
306790891ce7
[gaim-migrate @ 7217]
Christian Hammond <chipx86@chipx86.com>
parents:
6687
diff
changeset
|
600 struct yahoo_pair *pair = l->data; |
7827 | 601 if (pair->key == 4) { |
602 im = g_new0(struct _yahoo_im, 1); | |
603 list = g_slist_append(list, im); | |
604 im->from = pair->value; | |
605 im->time = time(NULL); | |
606 } | |
607 if (pair->key == 97) | |
608 if (im) | |
609 im->utf8 = strtol(pair->value, NULL, 10); | |
6691
306790891ce7
[gaim-migrate @ 7217]
Christian Hammond <chipx86@chipx86.com>
parents:
6687
diff
changeset
|
610 if (pair->key == 15) |
7827 | 611 if (im) |
612 im->time = strtol(pair->value, NULL, 10); | |
9284 | 613 if (pair->key == 206) |
614 if (im) | |
615 im->buddy_icon = strtol(pair->value, NULL, 10); | |
6691
306790891ce7
[gaim-migrate @ 7217]
Christian Hammond <chipx86@chipx86.com>
parents:
6687
diff
changeset
|
616 if (pair->key == 14) { |
7827 | 617 if (im) |
618 im->msg = pair->value; | |
6687 | 619 } |
6691
306790891ce7
[gaim-migrate @ 7217]
Christian Hammond <chipx86@chipx86.com>
parents:
6687
diff
changeset
|
620 l = l->next; |
6687 | 621 } |
2681 | 622 } else if (pkt->status == 2) { |
5436
ad445074d239
[gaim-migrate @ 5818]
Christian Hammond <chipx86@chipx86.com>
parents:
5367
diff
changeset
|
623 gaim_notify_error(gc, NULL, |
10386 | 624 _("Your Yahoo! message did not get sent."), NULL); |
2681 | 625 } |
7827 | 626 |
627 for (l = list; l; l = l->next) { | |
9306 | 628 YahooFriend *f; |
7827 | 629 char *m, *m2; |
630 im = l->data; | |
631 | |
632 if (!im->from || !im->msg) { | |
633 g_free(im); | |
634 continue; | |
635 } | |
636 | |
637 m = yahoo_string_decode(gc, im->msg, im->utf8); | |
638 gaim_str_strip_cr(m); | |
8375 | 639 |
640 if (!strcmp(m, "<ding>")) { | |
641 GaimConversation *c = gaim_conversation_new(GAIM_CONV_IM, | |
642 gaim_connection_get_account(gc), im->from); | |
643 gaim_conv_im_write(GAIM_CONV_IM(c), "", _("Buzz!!"), GAIM_MESSAGE_NICK|GAIM_MESSAGE_RECV, | |
644 im->time); | |
645 g_free(m); | |
646 g_free(im); | |
647 continue; | |
648 } | |
649 | |
7827 | 650 m2 = yahoo_codes_to_html(m); |
651 g_free(m); | |
652 serv_got_im(gc, im->from, m2, 0, im->time); | |
653 g_free(m2); | |
9284 | 654 |
655 if ((f = yahoo_friend_find(gc, im->from)) && im->buddy_icon == 2) { | |
656 if (yahoo_friend_get_buddy_icon_need_request(f)) { | |
9310 | 657 yahoo_send_picture_request(gc, im->from); |
9284 | 658 yahoo_friend_set_buddy_icon_need_request(f, FALSE); |
659 } | |
660 } | |
661 | |
7827 | 662 g_free(im); |
663 } | |
664 g_slist_free(list); | |
2681 | 665 } |
666 | |
7865 | 667 static void yahoo_process_sysmessage(GaimConnection *gc, struct yahoo_packet *pkt) |
668 { | |
669 GSList *l = pkt->hash; | |
10070 | 670 char *prim, *me = NULL, *msg = NULL, *escmsg = NULL; |
7865 | 671 |
672 while (l) { | |
673 struct yahoo_pair *pair = l->data; | |
674 | |
675 if (pair->key == 5) | |
676 me = pair->value; | |
677 if (pair->key == 14) | |
678 msg = pair->value; | |
679 | |
680 l = l->next; | |
681 } | |
682 | |
10070 | 683 if (!msg || !g_utf8_validate(msg, -1, NULL)) |
7865 | 684 return; |
685 | |
10070 | 686 escmsg = gaim_escape_html(msg); |
687 | |
7865 | 688 prim = g_strdup_printf(_("Yahoo! system message for %s:"), |
689 me?me:gaim_connection_get_display_name(gc)); | |
10070 | 690 gaim_notify_info(NULL, NULL, prim, escmsg); |
7865 | 691 g_free(prim); |
10070 | 692 g_free(escmsg); |
7865 | 693 } |
694 | |
6686 | 695 static void yahoo_buddy_added_us(GaimConnection *gc, struct yahoo_packet *pkt) { |
2681 | 696 char *id = NULL; |
697 char *who = NULL; | |
7827 | 698 char *msg = NULL, *tmpmsg = NULL; |
2681 | 699 GSList *l = pkt->hash; |
700 | |
701 while (l) { | |
702 struct yahoo_pair *pair = l->data; | |
6686 | 703 |
704 switch (pair->key) { | |
705 case 1: | |
2681 | 706 id = pair->value; |
6686 | 707 break; |
708 case 3: | |
2681 | 709 who = pair->value; |
6686 | 710 break; |
711 case 15: /* time, for when they add us and we're offline */ | |
712 break; | |
713 case 14: | |
2681 | 714 msg = pair->value; |
6686 | 715 break; |
716 } | |
2681 | 717 l = l->next; |
718 } | |
719 | |
7827 | 720 if (id) { |
721 if (msg) | |
722 tmpmsg = yahoo_string_decode(gc, msg, FALSE); | |
723 gaim_account_notify_added(gc->account, id, who, NULL, tmpmsg); | |
724 if (tmpmsg) | |
725 g_free(tmpmsg); | |
726 } | |
6686 | 727 } |
728 | |
729 static void yahoo_buddy_denied_our_add(GaimConnection *gc, struct yahoo_packet *pkt) | |
730 { | |
731 char *who = NULL; | |
732 char *msg = NULL; | |
733 GSList *l = pkt->hash; | |
734 GString *buf = NULL; | |
6784 | 735 struct yahoo_data *yd = gc->proto_data; |
6686 | 736 |
737 while (l) { | |
738 struct yahoo_pair *pair = l->data; | |
739 | |
740 switch (pair->key) { | |
741 case 3: | |
742 who = pair->value; | |
743 break; | |
744 case 14: | |
745 msg = pair->value; | |
746 break; | |
747 } | |
748 l = l->next; | |
749 } | |
750 | |
751 if (who) { | |
7827 | 752 char *msg2; |
6686 | 753 buf = g_string_sized_new(0); |
7827 | 754 if (!msg) { |
6686 | 755 g_string_printf(buf, _("%s has (retroactively) denied your request to add them to your list."), who); |
7827 | 756 } else { |
757 msg2 = yahoo_string_decode(gc, msg, FALSE); | |
758 g_string_printf(buf, _("%s has (retroactively) denied your request to add them to your list for the following reason: %s."), who, msg2); | |
759 g_free(msg2); | |
760 } | |
6840 | 761 gaim_notify_info(gc, NULL, _("Add buddy rejected"), buf->str); |
6686 | 762 g_string_free(buf, TRUE); |
6784 | 763 g_hash_table_remove(yd->friends, who); |
9983 | 764 gaim_prpl_got_user_status(gaim_connection_get_account(gc), who, "offline", NULL); /* FIXME: make this set not on list status instead */ |
6686 | 765 } |
766 } | |
767 | |
768 static void yahoo_process_contact(GaimConnection *gc, struct yahoo_packet *pkt) | |
769 { | |
770 | |
771 | |
772 switch (pkt->status) { | |
773 case 1: | |
774 yahoo_process_status(gc, pkt); | |
775 return; | |
776 case 3: | |
777 yahoo_buddy_added_us(gc, pkt); | |
778 break; | |
779 case 7: | |
780 yahoo_buddy_denied_our_add(gc, pkt); | |
781 break; | |
782 default: | |
783 break; | |
2683
4836eae8dd8c
[gaim-migrate @ 2696]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2682
diff
changeset
|
784 } |
2681 | 785 } |
786 | |
7747 | 787 #define OUT_CHARSET "utf-8" |
788 | |
789 static char *yahoo_decode(const char *text) | |
790 { | |
9221 | 791 char *converted = NULL; |
8125 | 792 char *n, *new; |
793 const char *end, *p; | |
8616 | 794 int i, k; |
8125 | 795 |
7771 | 796 n = new = g_malloc(strlen (text) + 1); |
8118 | 797 end = text + strlen(text); |
798 | |
8125 | 799 for (p = text; p < end; p++, n++) { |
7747 | 800 if (*p == '\\') { |
9064 | 801 if (p[1] >= '0' && p[1] <= '7') { |
802 p += 1; | |
803 for (i = 0, k = 0; k < 3; k += 1) { | |
804 char c = p[k]; | |
9065 | 805 if (c < '0' || c > '7') break; |
9064 | 806 i *= 8; |
807 i += c - '0'; | |
808 } | |
809 *n = i; | |
810 p += k - 1; | |
811 } else { /* bug 959248 */ | |
812 /* If we see a \ not followed by an octal number, | |
813 * it means that it is actually a \\ with one \ | |
814 * already eaten by some unknown function. | |
815 * This is arguably broken. | |
816 * | |
817 * I think wing is wrong here, there is no function | |
818 * called that I see that could have done it. I guess | |
819 * it is just really sending single \'s. That's yahoo | |
820 * for you. | |
821 */ | |
822 *n = *p; | |
823 } | |
7747 | 824 } |
825 else | |
826 *n = *p; | |
827 } | |
828 | |
829 *n = '\0'; | |
8125 | 830 |
9221 | 831 if (strstr(text, "\033$B")) |
832 converted = g_convert(new, n - new, OUT_CHARSET, "iso-2022-jp", NULL, NULL, NULL); | |
833 if (!converted) | |
834 converted = g_convert(new, n - new, OUT_CHARSET, "iso-8859-1", NULL, NULL, NULL); | |
7747 | 835 g_free(new); |
836 | |
837 return converted; | |
838 } | |
839 | |
5583 | 840 static void yahoo_process_mail(GaimConnection *gc, struct yahoo_packet *pkt) |
2681 | 841 { |
5583 | 842 GaimAccount *account = gaim_connection_get_account(gc); |
9221 | 843 struct yahoo_data *yd = gc->proto_data; |
2681 | 844 char *who = NULL; |
845 char *email = NULL; | |
846 char *subj = NULL; | |
9221 | 847 char *yahoo_mail_url = (yd->jp? YAHOOJP_MAIL_URL: YAHOO_MAIL_URL); |
2681 | 848 int count = 0; |
849 GSList *l = pkt->hash; | |
850 | |
5583 | 851 if (!gaim_account_get_check_mail(account)) |
5521
76ec14ba51d7
[gaim-migrate @ 5921]
Christian Hammond <chipx86@chipx86.com>
parents:
5498
diff
changeset
|
852 return; |
76ec14ba51d7
[gaim-migrate @ 5921]
Christian Hammond <chipx86@chipx86.com>
parents:
5498
diff
changeset
|
853 |
2681 | 854 while (l) { |
855 struct yahoo_pair *pair = l->data; | |
856 if (pair->key == 9) | |
857 count = strtol(pair->value, NULL, 10); | |
858 else if (pair->key == 43) | |
859 who = pair->value; | |
860 else if (pair->key == 42) | |
861 email = pair->value; | |
862 else if (pair->key == 18) | |
863 subj = pair->value; | |
864 l = l->next; | |
865 } | |
866 | |
4001 | 867 if (who && subj && email && *email) { |
7747 | 868 char *dec_who = yahoo_decode(who); |
869 char *dec_subj = yahoo_decode(subj); | |
870 char *from = g_strdup_printf("%s (%s)", dec_who, email); | |
871 | |
872 gaim_notify_email(gc, dec_subj, from, gaim_account_get_username(account), | |
9221 | 873 yahoo_mail_url, NULL, NULL); |
5521
76ec14ba51d7
[gaim-migrate @ 5921]
Christian Hammond <chipx86@chipx86.com>
parents:
5498
diff
changeset
|
874 |
7747 | 875 g_free(dec_who); |
876 g_free(dec_subj); | |
2850
cbe6a1e63a72
[gaim-migrate @ 2863]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2813
diff
changeset
|
877 g_free(from); |
5521
76ec14ba51d7
[gaim-migrate @ 5921]
Christian Hammond <chipx86@chipx86.com>
parents:
5498
diff
changeset
|
878 } else if (count > 0) { |
5583 | 879 const char *to = gaim_account_get_username(account); |
9221 | 880 const char *url = yahoo_mail_url; |
5521
76ec14ba51d7
[gaim-migrate @ 5921]
Christian Hammond <chipx86@chipx86.com>
parents:
5498
diff
changeset
|
881 |
76ec14ba51d7
[gaim-migrate @ 5921]
Christian Hammond <chipx86@chipx86.com>
parents:
5498
diff
changeset
|
882 gaim_notify_emails(gc, count, FALSE, NULL, NULL, &to, &url, |
76ec14ba51d7
[gaim-migrate @ 5921]
Christian Hammond <chipx86@chipx86.com>
parents:
5498
diff
changeset
|
883 NULL, NULL); |
76ec14ba51d7
[gaim-migrate @ 5921]
Christian Hammond <chipx86@chipx86.com>
parents:
5498
diff
changeset
|
884 } |
2681 | 885 } |
3147 | 886 /* This is the y64 alphabet... it's like base64, but has a . and a _ */ |
887 char base64digits[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789._"; | |
888 | |
889 /* This is taken from Sylpheed by Hiroyuki Yamamoto. We have our own tobase64 function | |
890 * in util.c, but it has a bug I don't feel like finding right now ;) */ | |
891 void to_y64(unsigned char *out, const unsigned char *in, int inlen) | |
892 /* raw bytes in quasi-big-endian order to base 64 string (NUL-terminated) */ | |
893 { | |
894 for (; inlen >= 3; inlen -= 3) | |
895 { | |
896 *out++ = base64digits[in[0] >> 2]; | |
897 *out++ = base64digits[((in[0] << 4) & 0x30) | (in[1] >> 4)]; | |
898 *out++ = base64digits[((in[1] << 2) & 0x3c) | (in[2] >> 6)]; | |
899 *out++ = base64digits[in[2] & 0x3f]; | |
900 in += 3; | |
901 } | |
902 if (inlen > 0) | |
903 { | |
904 unsigned char fragment; | |
905 | |
906 *out++ = base64digits[in[0] >> 2]; | |
907 fragment = (in[0] << 4) & 0x30; | |
908 if (inlen > 1) | |
909 fragment |= in[1] >> 4; | |
910 *out++ = base64digits[fragment]; | |
911 *out++ = (inlen < 2) ? '-' : base64digits[(in[1] << 2) & 0x3c]; | |
912 *out++ = '-'; | |
913 } | |
914 *out = '\0'; | |
915 } | |
916 | |
6986 | 917 static void yahoo_process_auth_old(GaimConnection *gc, const char *seed) |
918 { | |
919 struct yahoo_packet *pack; | |
920 GaimAccount *account = gaim_connection_get_account(gc); | |
7261 | 921 const char *name = gaim_normalize(account, gaim_account_get_username(account)); |
6986 | 922 const char *pass = gaim_account_get_password(account); |
923 struct yahoo_data *yd = gc->proto_data; | |
924 | |
925 /* So, Yahoo has stopped supporting its older clients in India, and undoubtedly | |
926 * will soon do so in the rest of the world. | |
927 * | |
928 * The new clients use this authentication method. I warn you in advance, it's | |
8735
92cbf9713795
[gaim-migrate @ 9490]
Christian Hammond <chipx86@chipx86.com>
parents:
8713
diff
changeset
|
929 * bizarre, convoluted, inordinately complicated. It's also no more secure than |
6986 | 930 * crypt() was. The only purpose this scheme could serve is to prevent third |
931 * part clients from connecting to their servers. | |
932 * | |
933 * Sorry, Yahoo. | |
934 */ | |
9277 | 935 |
6986 | 936 md5_byte_t result[16]; |
937 md5_state_t ctx; | |
9277 | 938 |
6986 | 939 char *crypt_result; |
940 char password_hash[25]; | |
941 char crypt_hash[25]; | |
942 char *hash_string_p = g_malloc(50 + strlen(name)); | |
943 char *hash_string_c = g_malloc(50 + strlen(name)); | |
9277 | 944 |
6986 | 945 char checksum; |
9277 | 946 |
6986 | 947 int sv; |
9277 | 948 |
6986 | 949 char result6[25]; |
950 char result96[25]; | |
951 | |
952 sv = seed[15]; | |
953 sv = sv % 8; | |
954 | |
955 md5_init(&ctx); | |
956 md5_append(&ctx, pass, strlen(pass)); | |
957 md5_finish(&ctx, result); | |
958 to_y64(password_hash, result, 16); | |
9277 | 959 |
6986 | 960 md5_init(&ctx); |
9277 | 961 crypt_result = yahoo_crypt(pass, "$1$_2S43d5f$"); |
6986 | 962 md5_append(&ctx, crypt_result, strlen(crypt_result)); |
963 md5_finish(&ctx, result); | |
964 to_y64(crypt_hash, result, 16); | |
965 | |
966 switch (sv) { | |
967 case 1: | |
968 case 6: | |
969 checksum = seed[seed[9] % 16]; | |
970 g_snprintf(hash_string_p, strlen(name) + 50, | |
971 "%c%s%s%s", checksum, name, seed, password_hash); | |
972 g_snprintf(hash_string_c, strlen(name) + 50, | |
973 "%c%s%s%s", checksum, name, seed, crypt_hash); | |
974 break; | |
975 case 2: | |
976 case 7: | |
977 checksum = seed[seed[15] % 16]; | |
978 g_snprintf(hash_string_p, strlen(name) + 50, | |
979 "%c%s%s%s", checksum, seed, password_hash, name); | |
980 g_snprintf(hash_string_c, strlen(name) + 50, | |
981 "%c%s%s%s", checksum, seed, crypt_hash, name); | |
982 break; | |
983 case 3: | |
984 checksum = seed[seed[1] % 16]; | |
985 g_snprintf(hash_string_p, strlen(name) + 50, | |
986 "%c%s%s%s", checksum, name, password_hash, seed); | |
987 g_snprintf(hash_string_c, strlen(name) + 50, | |
988 "%c%s%s%s", checksum, name, crypt_hash, seed); | |
989 break; | |
990 case 4: | |
991 checksum = seed[seed[3] % 16]; | |
992 g_snprintf(hash_string_p, strlen(name) + 50, | |
993 "%c%s%s%s", checksum, password_hash, seed, name); | |
994 g_snprintf(hash_string_c, strlen(name) + 50, | |
995 "%c%s%s%s", checksum, crypt_hash, seed, name); | |
996 break; | |
997 case 0: | |
998 case 5: | |
999 checksum = seed[seed[7] % 16]; | |
1000 g_snprintf(hash_string_p, strlen(name) + 50, | |
1001 "%c%s%s%s", checksum, password_hash, name, seed); | |
1002 g_snprintf(hash_string_c, strlen(name) + 50, | |
1003 "%c%s%s%s", checksum, crypt_hash, name, seed); | |
1004 break; | |
1005 } | |
9277 | 1006 |
1007 md5_init(&ctx); | |
6986 | 1008 md5_append(&ctx, hash_string_p, strlen(hash_string_p)); |
1009 md5_finish(&ctx, result); | |
1010 to_y64(result6, result, 16); | |
9277 | 1011 |
1012 md5_init(&ctx); | |
6986 | 1013 md5_append(&ctx, hash_string_c, strlen(hash_string_c)); |
1014 md5_finish(&ctx, result); | |
1015 to_y64(result96, result, 16); | |
1016 | |
1017 pack = yahoo_packet_new(YAHOO_SERVICE_AUTHRESP, YAHOO_STATUS_AVAILABLE, 0); | |
10394 | 1018 yahoo_packet_hash(pack, "ssss", 0, name, 6, result6, 96, result96, 1, name); |
10392 | 1019 yahoo_packet_send_and_free(pack, yd); |
9277 | 1020 |
6986 | 1021 g_free(hash_string_p); |
1022 g_free(hash_string_c); | |
1023 } | |
1024 | |
6998 | 1025 /* I'm dishing out some uber-mad props to Cerulean Studios for cracking this |
1026 * and sending the fix! Thanks guys. */ | |
1027 | |
6986 | 1028 static void yahoo_process_auth_new(GaimConnection *gc, const char *seed) |
1029 { | |
1030 struct yahoo_packet *pack = NULL; | |
1031 GaimAccount *account = gaim_connection_get_account(gc); | |
7261 | 1032 const char *name = gaim_normalize(account, gaim_account_get_username(account)); |
6986 | 1033 const char *pass = gaim_account_get_password(account); |
1034 struct yahoo_data *yd = gc->proto_data; | |
9277 | 1035 |
8349 | 1036 md5_byte_t result[16]; |
1037 md5_state_t ctx; | |
9277 | 1038 |
8349 | 1039 SHA_CTX ctx1; |
1040 SHA_CTX ctx2; | |
9277 | 1041 |
8349 | 1042 char *alphabet1 = "FBZDWAGHrJTLMNOPpRSKUVEXYChImkwQ"; |
1043 char *alphabet2 = "F0E1D2C3B4A59687abcdefghijklmnop"; | |
1044 | |
1045 char *challenge_lookup = "qzec2tb3um1olpar8whx4dfgijknsvy5"; | |
1046 char *operand_lookup = "+|&%/*^-"; | |
1047 char *delimit_lookup = ",;"; | |
1048 | |
1049 char *password_hash = (char *)g_malloc(25); | |
1050 char *crypt_hash = (char *)g_malloc(25); | |
1051 char *crypt_result = NULL; | |
1052 | |
1053 char pass_hash_xor1[64]; | |
1054 char pass_hash_xor2[64]; | |
1055 char crypt_hash_xor1[64]; | |
1056 char crypt_hash_xor2[64]; | |
1057 char resp_6[100]; | |
1058 char resp_96[100]; | |
1059 | |
1060 unsigned char digest1[20]; | |
1061 unsigned char digest2[20]; | |
1062 unsigned char comparison_src[20]; | |
1063 unsigned char magic_key_char[4]; | |
8375 | 1064 const unsigned char *magic_ptr; |
8349 | 1065 |
1066 unsigned int magic[64]; | |
1067 unsigned int magic_work = 0; | |
1068 unsigned int magic_4 = 0; | |
1069 | |
1070 int x; | |
1071 int y; | |
1072 int cnt = 0; | |
1073 int magic_cnt = 0; | |
1074 int magic_len; | |
1075 | |
1076 memset(password_hash, 0, 25); | |
1077 memset(crypt_hash, 0, 25); | |
6986 | 1078 memset(&pass_hash_xor1, 0, 64); |
1079 memset(&pass_hash_xor2, 0, 64); | |
1080 memset(&crypt_hash_xor1, 0, 64); | |
1081 memset(&crypt_hash_xor2, 0, 64); | |
1082 memset(&digest1, 0, 20); | |
1083 memset(&digest2, 0, 20); | |
1084 memset(&magic, 0, 64); | |
1085 memset(&resp_6, 0, 100); | |
1086 memset(&resp_96, 0, 100); | |
1087 memset(&magic_key_char, 0, 4); | |
8349 | 1088 memset(&comparison_src, 0, 20); |
6986 | 1089 |
1090 /* | |
8349 | 1091 * Magic: Phase 1. Generate what seems to be a 30 byte value (could change if base64 |
1092 * ends up differently? I don't remember and I'm tired, so use a 64 byte buffer. | |
6986 | 1093 */ |
9277 | 1094 |
6986 | 1095 magic_ptr = seed; |
8375 | 1096 |
6986 | 1097 while (*magic_ptr != (int)NULL) { |
8349 | 1098 char *loc; |
6986 | 1099 |
8349 | 1100 /* Ignore parentheses. |
1101 */ | |
6986 | 1102 |
1103 if (*magic_ptr == '(' || *magic_ptr == ')') { | |
1104 magic_ptr++; | |
1105 continue; | |
1106 } | |
1107 | |
8349 | 1108 /* Characters and digits verify against the challenge lookup. |
1109 */ | |
6986 | 1110 |
1111 if (isalpha(*magic_ptr) || isdigit(*magic_ptr)) { | |
1112 loc = strchr(challenge_lookup, *magic_ptr); | |
1113 if (!loc) { | |
8349 | 1114 /* SME XXX Error - disconnect here */ |
6986 | 1115 } |
1116 | |
8349 | 1117 /* Get offset into lookup table and shl 3. |
1118 */ | |
6986 | 1119 |
1120 magic_work = loc - challenge_lookup; | |
1121 magic_work <<= 3; | |
1122 | |
1123 magic_ptr++; | |
1124 continue; | |
1125 } else { | |
8349 | 1126 unsigned int local_store; |
6986 | 1127 |
1128 loc = strchr(operand_lookup, *magic_ptr); | |
1129 if (!loc) { | |
8349 | 1130 /* SME XXX Disconnect */ |
6986 | 1131 } |
1132 | |
1133 local_store = loc - operand_lookup; | |
8349 | 1134 |
1135 /* Oops; how did this happen? | |
1136 */ | |
1137 | |
6986 | 1138 if (magic_cnt >= 64) |
1139 break; | |
8349 | 1140 |
6986 | 1141 magic[magic_cnt++] = magic_work | local_store; |
1142 magic_ptr++; | |
1143 continue; | |
1144 } | |
8349 | 1145 } |
6986 | 1146 |
1147 magic_len = magic_cnt; | |
1148 magic_cnt = 0; | |
1149 | |
8349 | 1150 /* Magic: Phase 2. Take generated magic value and sprinkle fairy dust on the values. |
1151 */ | |
1152 | |
6986 | 1153 for (magic_cnt = magic_len-2; magic_cnt >= 0; magic_cnt--) { |
8349 | 1154 unsigned char byte1; |
1155 unsigned char byte2; | |
6986 | 1156 |
1157 /* Bad. Abort. | |
1158 */ | |
8349 | 1159 |
1160 if ((magic_cnt + 1 > magic_len) || (magic_cnt > magic_len)) | |
6986 | 1161 break; |
1162 | |
1163 byte1 = magic[magic_cnt]; | |
1164 byte2 = magic[magic_cnt+1]; | |
8349 | 1165 |
6986 | 1166 byte1 *= 0xcd; |
1167 byte1 ^= byte2; | |
1168 | |
1169 magic[magic_cnt+1] = byte1; | |
8349 | 1170 } |
1171 | |
1172 /* | |
1173 * Magic: Phase 3. This computes 20 bytes. The first 4 bytes are used as our magic | |
1174 * key (and may be changed later); the next 16 bytes are an MD5 sum of the magic key | |
1175 * plus 3 bytes. The 3 bytes are found by looping, and they represent the offsets | |
1176 * into particular functions we'll later call to potentially alter the magic key. | |
1177 * | |
1178 * %-) | |
1179 */ | |
1180 | |
1181 magic_cnt = 1; | |
1182 x = 0; | |
1183 | |
1184 do { | |
1185 unsigned int bl = 0; | |
1186 unsigned int cl = magic[magic_cnt++]; | |
1187 | |
1188 if (magic_cnt >= magic_len) | |
1189 break; | |
1190 | |
1191 if (cl > 0x7F) { | |
1192 if (cl < 0xe0) | |
1193 bl = cl = (cl & 0x1f) << 6; | |
1194 else { | |
1195 bl = magic[magic_cnt++]; | |
1196 cl = (cl & 0x0f) << 6; | |
1197 bl = ((bl & 0x3f) + cl) << 6; | |
1198 } | |
9277 | 1199 |
8349 | 1200 cl = magic[magic_cnt++]; |
1201 bl = (cl & 0x3f) + bl; | |
1202 } else | |
1203 bl = cl; | |
1204 | |
1205 comparison_src[x++] = (bl & 0xff00) >> 8; | |
1206 comparison_src[x++] = bl & 0xff; | |
1207 } while (x < 20); | |
1208 | |
1209 /* First four bytes are magic key. | |
1210 */ | |
1211 | |
1212 memcpy(&magic_key_char[0], comparison_src, 4); | |
8482 | 1213 magic_4 = magic_key_char[0] | (magic_key_char[1]<<8) | (magic_key_char[2]<<16) | (magic_key_char[3]<<24); |
8349 | 1214 |
1215 /* | |
1216 * Magic: Phase 4. Determine what function to use later by getting outside/inside | |
1217 * loop values until we match our previous buffer. | |
1218 */ | |
1219 | |
1220 for (x = 0; x < 65535; x++) { | |
1221 int leave = 0; | |
1222 | |
1223 for (y = 0; y < 5; y++) { | |
1224 md5_byte_t result[16]; | |
1225 md5_state_t ctx; | |
1226 | |
1227 unsigned char test[3]; | |
1228 | |
1229 memset(&result, 0, 16); | |
1230 memset(&test, 0, 3); | |
1231 | |
1232 /* Calculate buffer. | |
1233 */ | |
1234 | |
1235 test[0] = x; | |
1236 test[1] = x >> 8; | |
1237 test[2] = y; | |
1238 | |
1239 md5_init(&ctx); | |
1240 md5_append(&ctx, magic_key_char, 4); | |
1241 md5_append(&ctx, test, 3); | |
1242 md5_finish(&ctx, result); | |
1243 | |
1244 if (!memcmp(result, comparison_src+4, 16)) { | |
1245 leave = 1; | |
1246 break; | |
1247 } | |
1248 } | |
1249 | |
1250 if (leave == 1) | |
1251 break; | |
6986 | 1252 } |
1253 | |
8349 | 1254 /* If y != 0, we need some help. |
1255 */ | |
6986 | 1256 |
8349 | 1257 if (y != 0) { |
1258 unsigned int updated_key; | |
6986 | 1259 |
8349 | 1260 /* Update magic stuff. Call it twice because Yahoo's encryption is super bad ass. |
1261 */ | |
7127 | 1262 |
8349 | 1263 updated_key = yahoo_auth_finalCountdown(magic_4, 0x60, y, x); |
1264 updated_key = yahoo_auth_finalCountdown(updated_key, 0x60, y, x); | |
6986 | 1265 |
8482 | 1266 magic_key_char[0] = updated_key & 0xff; |
1267 magic_key_char[1] = (updated_key >> 8) & 0xff; | |
1268 magic_key_char[2] = (updated_key >> 16) & 0xff; | |
1269 magic_key_char[3] = (updated_key >> 24) & 0xff; | |
8349 | 1270 } |
7127 | 1271 |
8349 | 1272 /* Get password and crypt hashes as per usual. |
1273 */ | |
1274 | |
6986 | 1275 md5_init(&ctx); |
8349 | 1276 md5_append(&ctx, pass, strlen(pass)); |
6986 | 1277 md5_finish(&ctx, result); |
1278 to_y64(password_hash, result, 16); | |
1279 | |
1280 md5_init(&ctx); | |
1281 crypt_result = yahoo_crypt(pass, "$1$_2S43d5f$"); | |
1282 md5_append(&ctx, crypt_result, strlen(crypt_result)); | |
1283 md5_finish(&ctx, result); | |
1284 to_y64(crypt_hash, result, 16); | |
8349 | 1285 |
1286 /* Our first authentication response is based off of the password hash. | |
1287 */ | |
6986 | 1288 |
1289 for (x = 0; x < (int)strlen(password_hash); x++) | |
1290 pass_hash_xor1[cnt++] = password_hash[x] ^ 0x36; | |
1291 | |
1292 if (cnt < 64) | |
1293 memset(&(pass_hash_xor1[cnt]), 0x36, 64-cnt); | |
8349 | 1294 |
6986 | 1295 cnt = 0; |
1296 | |
1297 for (x = 0; x < (int)strlen(password_hash); x++) | |
1298 pass_hash_xor2[cnt++] = password_hash[x] ^ 0x5c; | |
1299 | |
1300 if (cnt < 64) | |
1301 memset(&(pass_hash_xor2[cnt]), 0x5c, 64-cnt); | |
1302 | |
1303 shaInit(&ctx1); | |
1304 shaInit(&ctx2); | |
1305 | |
8349 | 1306 /* |
1307 * The first context gets the password hash XORed with 0x36 plus a magic value | |
1308 * which we previously extrapolated from our challenge. | |
1309 */ | |
6986 | 1310 |
1311 shaUpdate(&ctx1, pass_hash_xor1, 64); | |
9382 | 1312 if (y >= 3) |
1313 ctx1.sizeLo = 0x1ff; | |
6986 | 1314 shaUpdate(&ctx1, magic_key_char, 4); |
1315 shaFinal(&ctx1, digest1); | |
1316 | |
8349 | 1317 /* |
1318 * The second context gets the password hash XORed with 0x5c plus the SHA-1 digest | |
1319 * of the first context. | |
1320 */ | |
6986 | 1321 |
1322 shaUpdate(&ctx2, pass_hash_xor2, 64); | |
1323 shaUpdate(&ctx2, digest1, 20); | |
1324 shaFinal(&ctx2, digest2); | |
1325 | |
8349 | 1326 /* |
1327 * Now that we have digest2, use it to fetch characters from an alphabet to construct | |
1328 * our first authentication response. | |
1329 */ | |
1330 | |
6986 | 1331 for (x = 0; x < 20; x += 2) { |
8349 | 1332 unsigned int val = 0; |
1333 unsigned int lookup = 0; | |
6986 | 1334 |
8349 | 1335 char byte[6]; |
1336 | |
6986 | 1337 memset(&byte, 0, 6); |
8349 | 1338 |
1339 /* First two bytes of digest stuffed together. | |
6986 | 1340 */ |
9277 | 1341 |
6986 | 1342 val = digest2[x]; |
1343 val <<= 8; | |
1344 val += digest2[x+1]; | |
1345 | |
1346 lookup = (val >> 0x0b); | |
1347 lookup &= 0x1f; | |
1348 if (lookup >= strlen(alphabet1)) | |
1349 break; | |
1350 sprintf(byte, "%c", alphabet1[lookup]); | |
1351 strcat(resp_6, byte); | |
1352 strcat(resp_6, "="); | |
8349 | 1353 |
6986 | 1354 lookup = (val >> 0x06); |
1355 lookup &= 0x1f; | |
1356 if (lookup >= strlen(alphabet2)) | |
1357 break; | |
1358 sprintf(byte, "%c", alphabet2[lookup]); | |
1359 strcat(resp_6, byte); | |
1360 | |
1361 lookup = (val >> 0x01); | |
1362 lookup &= 0x1f; | |
1363 if (lookup >= strlen(alphabet2)) | |
1364 break; | |
1365 sprintf(byte, "%c", alphabet2[lookup]); | |
1366 strcat(resp_6, byte); | |
8349 | 1367 |
6986 | 1368 lookup = (val & 0x01); |
1369 if (lookup >= strlen(delimit_lookup)) | |
1370 break; | |
1371 sprintf(byte, "%c", delimit_lookup[lookup]); | |
1372 strcat(resp_6, byte); | |
1373 } | |
1374 | |
8349 | 1375 /* Our second authentication response is based off of the crypto hash. |
1376 */ | |
6986 | 1377 |
1378 cnt = 0; | |
1379 memset(&digest1, 0, 20); | |
1380 memset(&digest2, 0, 20); | |
1381 | |
1382 for (x = 0; x < (int)strlen(crypt_hash); x++) | |
1383 crypt_hash_xor1[cnt++] = crypt_hash[x] ^ 0x36; | |
1384 | |
1385 if (cnt < 64) | |
1386 memset(&(crypt_hash_xor1[cnt]), 0x36, 64-cnt); | |
8349 | 1387 |
6986 | 1388 cnt = 0; |
1389 | |
1390 for (x = 0; x < (int)strlen(crypt_hash); x++) | |
1391 crypt_hash_xor2[cnt++] = crypt_hash[x] ^ 0x5c; | |
1392 | |
1393 if (cnt < 64) | |
1394 memset(&(crypt_hash_xor2[cnt]), 0x5c, 64-cnt); | |
1395 | |
1396 shaInit(&ctx1); | |
1397 shaInit(&ctx2); | |
1398 | |
8349 | 1399 /* |
1400 * The first context gets the password hash XORed with 0x36 plus a magic value | |
1401 * which we previously extrapolated from our challenge. | |
1402 */ | |
6986 | 1403 |
1404 shaUpdate(&ctx1, crypt_hash_xor1, 64); | |
9382 | 1405 if (y >= 3) |
1406 ctx1.sizeLo = 0x1ff; | |
6986 | 1407 shaUpdate(&ctx1, magic_key_char, 4); |
1408 shaFinal(&ctx1, digest1); | |
1409 | |
8349 | 1410 /* |
1411 * The second context gets the password hash XORed with 0x5c plus the SHA-1 digest | |
1412 * of the first context. | |
1413 */ | |
6986 | 1414 |
1415 shaUpdate(&ctx2, crypt_hash_xor2, 64); | |
1416 shaUpdate(&ctx2, digest1, 20); | |
1417 shaFinal(&ctx2, digest2); | |
1418 | |
8349 | 1419 /* |
1420 * Now that we have digest2, use it to fetch characters from an alphabet to construct | |
1421 * our first authentication response. | |
1422 */ | |
6986 | 1423 |
1424 for (x = 0; x < 20; x += 2) { | |
8349 | 1425 unsigned int val = 0; |
1426 unsigned int lookup = 0; | |
6986 | 1427 |
8349 | 1428 char byte[6]; |
6986 | 1429 |
1430 memset(&byte, 0, 6); | |
1431 | |
8349 | 1432 /* First two bytes of digest stuffed together. |
1433 */ | |
6986 | 1434 |
1435 val = digest2[x]; | |
1436 val <<= 8; | |
1437 val += digest2[x+1]; | |
8349 | 1438 |
6986 | 1439 lookup = (val >> 0x0b); |
1440 lookup &= 0x1f; | |
1441 if (lookup >= strlen(alphabet1)) | |
1442 break; | |
1443 sprintf(byte, "%c", alphabet1[lookup]); | |
1444 strcat(resp_96, byte); | |
1445 strcat(resp_96, "="); | |
1446 | |
1447 lookup = (val >> 0x06); | |
1448 lookup &= 0x1f; | |
1449 if (lookup >= strlen(alphabet2)) | |
1450 break; | |
1451 sprintf(byte, "%c", alphabet2[lookup]); | |
1452 strcat(resp_96, byte); | |
1453 | |
1454 lookup = (val >> 0x01); | |
1455 lookup &= 0x1f; | |
1456 if (lookup >= strlen(alphabet2)) | |
1457 break; | |
1458 sprintf(byte, "%c", alphabet2[lookup]); | |
1459 strcat(resp_96, byte); | |
1460 | |
1461 lookup = (val & 0x01); | |
1462 if (lookup >= strlen(delimit_lookup)) | |
1463 break; | |
1464 sprintf(byte, "%c", delimit_lookup[lookup]); | |
1465 strcat(resp_96, byte); | |
1466 } | |
1467 | |
1468 pack = yahoo_packet_new(YAHOO_SERVICE_AUTHRESP, YAHOO_STATUS_AVAILABLE, 0); | |
10394 | 1469 yahoo_packet_hash(pack, "sssss", 0, name, 6, resp_6, 96, resp_96, 1, |
1470 name, 135, "6,0,0,1710"); | |
1471 if (yd->picture_checksum) | |
1472 yahoo_packet_hash_int(pack, 192, yd->picture_checksum); | |
1473 | |
10392 | 1474 yahoo_packet_send_and_free(pack, yd); |
6986 | 1475 |
7424 | 1476 g_free(password_hash); |
1477 g_free(crypt_hash); | |
6986 | 1478 } |
1479 | |
5583 | 1480 static void yahoo_process_auth(GaimConnection *gc, struct yahoo_packet *pkt) |
3147 | 1481 { |
1482 char *seed = NULL; | |
1483 char *sn = NULL; | |
1484 GSList *l = pkt->hash; | |
7010 | 1485 int m = 0; |
9277 | 1486 gchar *buf; |
1487 | |
1488 | |
3147 | 1489 while (l) { |
1490 struct yahoo_pair *pair = l->data; | |
1491 if (pair->key == 94) | |
1492 seed = pair->value; | |
1493 if (pair->key == 1) | |
1494 sn = pair->value; | |
6986 | 1495 if (pair->key == 13) |
1496 m = atoi(pair->value); | |
3147 | 1497 l = l->next; |
1498 } | |
9277 | 1499 |
3147 | 1500 if (seed) { |
6986 | 1501 switch (m) { |
1502 case 0: | |
1503 yahoo_process_auth_old(gc, seed); | |
1504 break; | |
3147 | 1505 case 1: |
6986 | 1506 yahoo_process_auth_new(gc, seed); |
3147 | 1507 break; |
6986 | 1508 default: |
7043 | 1509 buf = g_strdup_printf(_("The Yahoo server has requested the use of an unrecognized " |
7129 | 1510 "authentication method. This version of Gaim will likely not be able " |
7043 | 1511 "to successfully sign on to Yahoo. Check %s for updates."), GAIM_WEBSITE); |
6986 | 1512 gaim_notify_error(gc, "", _("Failed Yahoo! Authentication"), |
7043 | 1513 buf); |
1514 g_free(buf); | |
6986 | 1515 yahoo_process_auth_new(gc, seed); /* Can't hurt to try it anyway. */ |
3147 | 1516 } |
1517 } | |
1518 } | |
2681 | 1519 |
9285 | 1520 static void ignore_buddy(GaimBuddy *buddy) { |
1521 GaimGroup *group; | |
1522 GaimConversation *conv; | |
6760 | 1523 GaimAccount *account; |
1524 gchar *name; | |
1525 | |
9285 | 1526 if (!buddy) |
6792 | 1527 return; |
6760 | 1528 |
9285 | 1529 group = gaim_find_buddys_group(buddy); |
1530 name = g_strdup(buddy->name); | |
1531 account = buddy->account; | |
6760 | 1532 |
6792 | 1533 gaim_debug(GAIM_DEBUG_INFO, "blist", |
9285 | 1534 "Removing '%s' from buddy list.\n", buddy->name); |
1535 serv_remove_buddy(account->gc, buddy, group); | |
1536 gaim_blist_remove_buddy(buddy); | |
6760 | 1537 |
6792 | 1538 serv_add_deny(account->gc, name); |
9285 | 1539 |
10246 | 1540 /* The follow should really be done by the core... */ |
1541 conv = gaim_find_conversation_with_account(GAIM_CONV_IM, name, account); | |
9285 | 1542 |
1543 if (conv != NULL) | |
1544 gaim_conversation_update(conv, GAIM_CONV_UPDATE_REMOVE); | |
6760 | 1545 |
1546 g_free(name); | |
1547 } | |
1548 | |
1549 static void keep_buddy(GaimBuddy *b) { | |
1550 gaim_privacy_deny_remove(b->account, b->name, 1); | |
1551 } | |
1552 | |
1553 static void yahoo_process_ignore(GaimConnection *gc, struct yahoo_packet *pkt) { | |
1554 GaimBuddy *b; | |
1555 GSList *l; | |
1556 gchar *who = NULL; | |
1557 gchar *sn = NULL; | |
1558 gchar buf[BUF_LONG]; | |
1559 gint ignore = 0; | |
1560 gint status = 0; | |
1561 | |
1562 for (l = pkt->hash; l; l = l->next) { | |
1563 struct yahoo_pair *pair = l->data; | |
1564 switch (pair->key) { | |
1565 case 0: | |
1566 who = pair->value; | |
1567 break; | |
1568 case 1: | |
1569 sn = pair->value; | |
1570 break; | |
1571 case 13: | |
1572 ignore = strtol(pair->value, NULL, 10); | |
1573 break; | |
1574 case 66: | |
1575 status = strtol(pair->value, NULL, 10); | |
1576 break; | |
1577 default: | |
1578 break; | |
1579 } | |
1580 } | |
1581 | |
1582 switch (status) { | |
1583 case 12: | |
1584 b = gaim_find_buddy(gc->account, who); | |
1585 g_snprintf(buf, sizeof(buf), _("You have tried to ignore %s, but the " | |
1586 "user is on your buddy list. Clicking \"Yes\" " | |
1587 "will remove and ignore the buddy."), who); | |
1588 gaim_request_yes_no(gc, NULL, _("Ignore buddy?"), buf, 0, b, | |
1589 G_CALLBACK(ignore_buddy), | |
1590 G_CALLBACK(keep_buddy)); | |
1591 break; | |
1592 case 2: | |
1593 case 3: | |
1594 case 0: | |
1595 default: | |
1596 break; | |
1597 } | |
1598 } | |
1599 | |
6761 | 1600 static void yahoo_process_authresp(GaimConnection *gc, struct yahoo_packet *pkt) |
1601 { | |
9410 | 1602 struct yahoo_data *yd = gc->proto_data; |
6761 | 1603 GSList *l = pkt->hash; |
1604 int err = 0; | |
1605 char *msg; | |
7865 | 1606 char *url = NULL; |
1607 char *fullmsg; | |
6761 | 1608 |
1609 while (l) { | |
1610 struct yahoo_pair *pair = l->data; | |
1611 | |
1612 if (pair->key == 66) | |
1613 err = strtol(pair->value, NULL, 10); | |
7865 | 1614 if (pair->key == 20) |
1615 url = pair->value; | |
6761 | 1616 |
1617 l = l->next; | |
1618 } | |
1619 | |
1620 switch (err) { | |
1621 case 3: | |
7865 | 1622 msg = g_strdup(_("Invalid username.")); |
6761 | 1623 break; |
1624 case 13: | |
9410 | 1625 if (!yd->wm) { |
1626 yd->wm = TRUE; | |
1627 if (yd->fd >= 0) | |
1628 close(yd->fd); | |
1629 if (gc->inpa) | |
1630 gaim_input_remove(gc->inpa); | |
1631 gaim_url_fetch(WEBMESSENGER_URL, TRUE, "Gaim/" VERSION, FALSE, | |
1632 yahoo_login_page_cb, gc); | |
9835 | 1633 gaim_notify_warning(gc, NULL, _("Normal authentication failed!"), |
1634 _("The normal authentication method has failed. " | |
9410 | 1635 "This means either your password is incorrect, " |
9835 | 1636 "or Yahoo!'s authentication scheme has changed. " |
9410 | 1637 "Gaim will now attempt to log in using Web " |
9835 | 1638 "Messenger authentication, which will result " |
9410 | 1639 "in reduced functionality and features.")); |
1640 return; | |
1641 } | |
7865 | 1642 msg = g_strdup(_("Incorrect password.")); |
1643 break; | |
1644 case 14: | |
9280 | 1645 msg = g_strdup(_("Your account is locked, please log in to the Yahoo! website.")); |
6761 | 1646 break; |
1647 default: | |
9280 | 1648 msg = g_strdup_printf(_("Unknown error number %d. Logging into the Yahoo! website may fix this."), err); |
6761 | 1649 } |
7865 | 1650 |
1651 if (url) | |
1652 fullmsg = g_strdup_printf("%s\n%s", msg, url); | |
1653 else | |
1654 fullmsg = g_strdup(msg); | |
1655 | |
9280 | 1656 gc->wants_to_die = TRUE; |
7865 | 1657 gaim_connection_error(gc, fullmsg); |
1658 g_free(msg); | |
1659 g_free(fullmsg); | |
6761 | 1660 } |
1661 | |
6840 | 1662 static void yahoo_process_addbuddy(GaimConnection *gc, struct yahoo_packet *pkt) |
1663 { | |
1664 int err = 0; | |
1665 char *who = NULL; | |
1666 char *group = NULL; | |
7827 | 1667 char *decoded_group; |
6840 | 1668 char *buf; |
9278 | 1669 YahooFriend *f; |
6840 | 1670 GSList *l = pkt->hash; |
1671 | |
1672 while (l) { | |
1673 struct yahoo_pair *pair = l->data; | |
1674 | |
1675 switch (pair->key) { | |
1676 case 66: | |
1677 err = strtol(pair->value, NULL, 10); | |
1678 break; | |
1679 case 7: | |
1680 who = pair->value; | |
1681 break; | |
1682 case 65: | |
1683 group = pair->value; | |
1684 break; | |
1685 } | |
1686 | |
1687 l = l->next; | |
1688 } | |
1689 | |
1690 if (!who) | |
1691 return; | |
1692 if (!group) | |
1693 group = ""; | |
1694 | |
1695 if (!err || (err == 2)) { /* 0 = ok, 2 = already on serv list */ | |
9279 | 1696 f = yahoo_friend_find_or_new(gc, who); |
1697 yahoo_update_status(gc, who, f); | |
6840 | 1698 return; |
1699 } | |
1700 | |
7827 | 1701 decoded_group = yahoo_string_decode(gc, group, FALSE); |
6840 | 1702 buf = g_strdup_printf(_("Could not add buddy %s to group %s to the server list on account %s."), |
7827 | 1703 who, decoded_group, gaim_connection_get_display_name(gc)); |
9637 | 1704 if (!gaim_conv_present_error(who, gaim_connection_get_account(gc), buf)) |
1705 gaim_notify_error(gc, NULL, _("Could not add buddy to server list"), buf); | |
6840 | 1706 g_free(buf); |
7827 | 1707 g_free(decoded_group); |
6840 | 1708 } |
1709 | |
9062 | 1710 static void yahoo_process_p2p(GaimConnection *gc, struct yahoo_packet *pkt) |
1711 { | |
1712 GSList *l = pkt->hash; | |
1713 char *who = NULL; | |
1714 char *base64 = NULL; | |
9277 | 1715 char *decoded; |
9062 | 1716 int len; |
1717 | |
1718 while (l) { | |
1719 struct yahoo_pair *pair = l->data; | |
1720 | |
1721 switch (pair->key) { | |
1722 case 5: | |
1723 /* our identity */ | |
1724 break; | |
1725 case 4: | |
1726 who = pair->value; | |
1727 break; | |
1728 case 1: | |
1729 /* who again, the master identity this time? */ | |
1730 break; | |
1731 case 12: | |
1732 base64 = pair->value; | |
1733 /* so, this is an ip address. in base64. decoded it's in ascii. | |
1734 after strtol, it's in reversed byte order. Who thought this up?*/ | |
1735 break; | |
1736 /* | |
1737 TODO: figure these out | |
1738 yahoo: Key: 61 Value: 0 | |
1739 yahoo: Key: 2 Value: | |
1740 yahoo: Key: 13 Value: 0 | |
1741 yahoo: Key: 49 Value: PEERTOPEER | |
1742 yahoo: Key: 140 Value: 1 | |
1743 yahoo: Key: 11 Value: -1786225828 | |
1744 */ | |
1745 | |
1746 } | |
1747 | |
1748 l = l->next; | |
1749 } | |
1750 | |
9277 | 1751 if (base64) { |
9281 | 1752 guint32 ip; |
1753 char *tmp2; | |
1754 YahooFriend *f; | |
1755 | |
9062 | 1756 gaim_base64_decode(base64, &decoded, &len); |
9277 | 1757 if (len) { |
1758 char *tmp = gaim_str_binary_to_ascii(decoded, len); | |
1759 gaim_debug_info("yahoo", "Got P2P service packet (from server): who = %s, ip = %s\n", who, tmp); | |
1760 g_free(tmp); | |
1761 } | |
9281 | 1762 |
1763 tmp2 = g_strndup(decoded, len); /* so its \0 terminated...*/ | |
1764 ip = strtol(tmp2, NULL, 10); | |
1765 g_free(tmp2); | |
9062 | 1766 g_free(decoded); |
9281 | 1767 tmp2 = g_strdup_printf("%u.%u.%u.%u", ip & 0xff, (ip >> 8) & 0xff, (ip >> 16) & 0xff, |
1768 (ip >> 24) & 0xff); | |
1769 f = yahoo_friend_find(gc, who); | |
1770 if (f) | |
1771 yahoo_friend_set_ip(f, tmp2); | |
1772 g_free(tmp2); | |
9062 | 1773 } |
1774 } | |
1775 | |
9604 | 1776 static void yahoo_process_audible(GaimConnection *gc, struct yahoo_packet *pkt) |
1777 { | |
1778 char *who = NULL, *msg = NULL; | |
1779 GSList *l = pkt->hash; | |
1780 | |
1781 while (l) { | |
1782 struct yahoo_pair *pair = l->data; | |
1783 | |
1784 switch (pair->key) { | |
1785 case 4: | |
1786 who = pair->value; | |
1787 break; | |
1788 case 5: | |
1789 /* us */ | |
1790 break; | |
1791 case 230: | |
1792 /* the audible, in foo.bar.baz format */ | |
1793 break; | |
1794 case 231: | |
1795 /* the text of the audible */ | |
1796 msg = pair->value; | |
1797 break; | |
1798 case 232: | |
1799 /* weird number (md5 hash?), like 8ebab9094156135f5dcbaccbeee662a5c5fd1420 */ | |
1800 break; | |
1801 } | |
1802 | |
1803 l = l->next; | |
1804 } | |
1805 | |
1806 if (!who || !msg) | |
1807 return; | |
1808 if (!g_utf8_validate(msg, -1, NULL)) { | |
1809 gaim_debug_misc("yahoo", "Warning, nonutf8 audible, ignoring!\n"); | |
1810 return; | |
1811 } | |
1812 | |
1813 serv_got_im(gc, who, msg, 0, time(NULL)); | |
1814 } | |
1815 | |
5583 | 1816 static void yahoo_packet_process(GaimConnection *gc, struct yahoo_packet *pkt) |
2681 | 1817 { |
6760 | 1818 switch (pkt->service) { |
2681 | 1819 case YAHOO_SERVICE_LOGON: |
2771
450f4f9d2f23
[gaim-migrate @ 2784]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2741
diff
changeset
|
1820 case YAHOO_SERVICE_LOGOFF: |
2681 | 1821 case YAHOO_SERVICE_ISAWAY: |
2737
f61c1f3a6afa
[gaim-migrate @ 2750]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2724
diff
changeset
|
1822 case YAHOO_SERVICE_ISBACK: |
3019 | 1823 case YAHOO_SERVICE_GAMELOGON: |
1824 case YAHOO_SERVICE_GAMELOGOFF: | |
6686 | 1825 case YAHOO_SERVICE_CHATLOGON: |
1826 case YAHOO_SERVICE_CHATLOGOFF: | |
10373 | 1827 case YAHOO_SERVICE_Y6_STATUS_UPDATE: |
2681 | 1828 yahoo_process_status(gc, pkt); |
1829 break; | |
3019 | 1830 case YAHOO_SERVICE_NOTIFY: |
1831 yahoo_process_notify(gc, pkt); | |
2993 | 1832 break; |
2681 | 1833 case YAHOO_SERVICE_MESSAGE: |
2786
318f846120e2
[gaim-migrate @ 2799]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2772
diff
changeset
|
1834 case YAHOO_SERVICE_GAMEMSG: |
5939 | 1835 case YAHOO_SERVICE_CHATMSG: |
2681 | 1836 yahoo_process_message(gc, pkt); |
1837 break; | |
7865 | 1838 case YAHOO_SERVICE_SYSMESSAGE: |
1839 yahoo_process_sysmessage(gc, pkt); | |
1840 break; | |
2681 | 1841 case YAHOO_SERVICE_NEWMAIL: |
1842 yahoo_process_mail(gc, pkt); | |
1843 break; | |
1844 case YAHOO_SERVICE_NEWCONTACT: | |
1845 yahoo_process_contact(gc, pkt); | |
1846 break; | |
6784 | 1847 case YAHOO_SERVICE_AUTHRESP: |
1848 yahoo_process_authresp(gc, pkt); | |
1849 break; | |
2681 | 1850 case YAHOO_SERVICE_LIST: |
1851 yahoo_process_list(gc, pkt); | |
1852 break; | |
3147 | 1853 case YAHOO_SERVICE_AUTH: |
1854 yahoo_process_auth(gc, pkt); | |
1855 break; | |
6840 | 1856 case YAHOO_SERVICE_ADDBUDDY: |
1857 yahoo_process_addbuddy(gc, pkt); | |
1858 break; | |
6760 | 1859 case YAHOO_SERVICE_IGNORECONTACT: |
1860 yahoo_process_ignore(gc, pkt); | |
1861 break; | |
6729 | 1862 case YAHOO_SERVICE_CONFINVITE: |
1863 case YAHOO_SERVICE_CONFADDINVITE: | |
1864 yahoo_process_conference_invite(gc, pkt); | |
1865 break; | |
1866 case YAHOO_SERVICE_CONFDECLINE: | |
1867 yahoo_process_conference_decline(gc, pkt); | |
1868 break; | |
1869 case YAHOO_SERVICE_CONFLOGON: | |
1870 yahoo_process_conference_logon(gc, pkt); | |
1871 break; | |
1872 case YAHOO_SERVICE_CONFLOGOFF: | |
1873 yahoo_process_conference_logoff(gc, pkt); | |
1874 break; | |
1875 case YAHOO_SERVICE_CONFMSG: | |
1876 yahoo_process_conference_message(gc, pkt); | |
1877 break; | |
1878 case YAHOO_SERVICE_CHATONLINE: | |
1879 yahoo_process_chat_online(gc, pkt); | |
1880 break; | |
1881 case YAHOO_SERVICE_CHATLOGOUT: | |
1882 yahoo_process_chat_logout(gc, pkt); | |
1883 break; | |
1884 case YAHOO_SERVICE_CHATGOTO: | |
1885 yahoo_process_chat_goto(gc, pkt); | |
1886 break; | |
1887 case YAHOO_SERVICE_CHATJOIN: | |
1888 yahoo_process_chat_join(gc, pkt); | |
1889 break; | |
1890 case YAHOO_SERVICE_CHATLEAVE: /* XXX is this right? */ | |
1891 case YAHOO_SERVICE_CHATEXIT: | |
1892 yahoo_process_chat_exit(gc, pkt); | |
1893 break; | |
1894 case YAHOO_SERVICE_CHATINVITE: /* XXX never seen this one, might not do it right */ | |
1895 case YAHOO_SERVICE_CHATADDINVITE: | |
1896 yahoo_process_chat_addinvite(gc, pkt); | |
1897 break; | |
1898 case YAHOO_SERVICE_COMMENT: | |
1899 yahoo_process_chat_message(gc, pkt); | |
1900 break; | |
7651 | 1901 case YAHOO_SERVICE_P2PFILEXFER: |
1902 case YAHOO_SERVICE_FILETRANSFER: | |
1903 yahoo_process_filetransfer(gc, pkt); | |
1904 break; | |
9062 | 1905 case YAHOO_SERVICE_PEEPTOPEER: |
1906 yahoo_process_p2p(gc, pkt); | |
1907 break; | |
9284 | 1908 case YAHOO_SERVICE_PICTURE: |
1909 yahoo_process_picture(gc, pkt); | |
1910 break; | |
9292 | 1911 case YAHOO_SERVICE_PICTURE_UPDATE: |
1912 yahoo_process_picture_update(gc, pkt); | |
1913 break; | |
1914 case YAHOO_SERVICE_PICTURE_CHECKSUM: | |
1915 yahoo_process_picture_checksum(gc, pkt); | |
1916 break; | |
9306 | 1917 case YAHOO_SERVICE_PICTURE_UPLOAD: |
1918 yahoo_process_picture_upload(gc, pkt); | |
1919 break; | |
9604 | 1920 case YAHOO_SERVICE_AUDIBLE: |
1921 yahoo_process_audible(gc, pkt); | |
2681 | 1922 default: |
5220
7b9d78fa051e
[gaim-migrate @ 5590]
Christian Hammond <chipx86@chipx86.com>
parents:
5216
diff
changeset
|
1923 gaim_debug(GAIM_DEBUG_ERROR, "yahoo", |
5216
00bd3019749e
[gaim-migrate @ 5586]
Christian Hammond <chipx86@chipx86.com>
parents:
5205
diff
changeset
|
1924 "Unhandled service 0x%02x\n", pkt->service); |
2681 | 1925 break; |
1926 } | |
1927 } | |
1928 | |
1929 static void yahoo_pending(gpointer data, gint source, GaimInputCondition cond) | |
1930 { | |
5583 | 1931 GaimConnection *gc = data; |
2681 | 1932 struct yahoo_data *yd = gc->proto_data; |
1933 char buf[1024]; | |
1934 int len; | |
1935 | |
1936 len = read(yd->fd, buf, sizeof(buf)); | |
1937 | |
1938 if (len <= 0) { | |
6321 | 1939 gaim_connection_error(gc, _("Unable to read")); |
2681 | 1940 return; |
1941 } | |
1942 | |
1943 yd->rxqueue = g_realloc(yd->rxqueue, len + yd->rxlen); | |
1944 memcpy(yd->rxqueue + yd->rxlen, buf, len); | |
1945 yd->rxlen += len; | |
1946 | |
1947 while (1) { | |
1948 struct yahoo_packet *pkt; | |
1949 int pos = 0; | |
1950 int pktlen; | |
1951 | |
1952 if (yd->rxlen < YAHOO_PACKET_HDRLEN) | |
1953 return; | |
1954 | |
1955 pos += 4; /* YMSG */ | |
1956 pos += 2; | |
1957 pos += 2; | |
1958 | |
1959 pktlen = yahoo_get16(yd->rxqueue + pos); pos += 2; | |
5220
7b9d78fa051e
[gaim-migrate @ 5590]
Christian Hammond <chipx86@chipx86.com>
parents:
5216
diff
changeset
|
1960 gaim_debug(GAIM_DEBUG_MISC, "yahoo", |
5216
00bd3019749e
[gaim-migrate @ 5586]
Christian Hammond <chipx86@chipx86.com>
parents:
5205
diff
changeset
|
1961 "%d bytes to read, rxlen is %d\n", pktlen, yd->rxlen); |
2681 | 1962 |
1963 if (yd->rxlen < (YAHOO_PACKET_HDRLEN + pktlen)) | |
1964 return; | |
1965 | |
1966 yahoo_packet_dump(yd->rxqueue, YAHOO_PACKET_HDRLEN + pktlen); | |
1967 | |
1968 pkt = yahoo_packet_new(0, 0, 0); | |
1969 | |
1970 pkt->service = yahoo_get16(yd->rxqueue + pos); pos += 2; | |
3021 | 1971 pkt->status = yahoo_get32(yd->rxqueue + pos); pos += 4; |
5220
7b9d78fa051e
[gaim-migrate @ 5590]
Christian Hammond <chipx86@chipx86.com>
parents:
5216
diff
changeset
|
1972 gaim_debug(GAIM_DEBUG_MISC, "yahoo", |
5216
00bd3019749e
[gaim-migrate @ 5586]
Christian Hammond <chipx86@chipx86.com>
parents:
5205
diff
changeset
|
1973 "Yahoo Service: 0x%02x Status: %d\n", |
00bd3019749e
[gaim-migrate @ 5586]
Christian Hammond <chipx86@chipx86.com>
parents:
5205
diff
changeset
|
1974 pkt->service, pkt->status); |
2681 | 1975 pkt->id = yahoo_get32(yd->rxqueue + pos); pos += 4; |
1976 | |
1977 yahoo_packet_read(pkt, yd->rxqueue + pos, pktlen); | |
1978 | |
1979 yd->rxlen -= YAHOO_PACKET_HDRLEN + pktlen; | |
1980 if (yd->rxlen) { | |
1981 char *tmp = g_memdup(yd->rxqueue + YAHOO_PACKET_HDRLEN + pktlen, yd->rxlen); | |
1982 g_free(yd->rxqueue); | |
1983 yd->rxqueue = tmp; | |
1984 } else { | |
1985 g_free(yd->rxqueue); | |
1986 yd->rxqueue = NULL; | |
1987 } | |
1988 | |
1989 yahoo_packet_process(gc, pkt); | |
1990 | |
1991 yahoo_packet_free(pkt); | |
1992 } | |
1993 } | |
1994 | |
1995 static void yahoo_got_connected(gpointer data, gint source, GaimInputCondition cond) | |
1996 { | |
5583 | 1997 GaimConnection *gc = data; |
2681 | 1998 struct yahoo_data *yd; |
1999 struct yahoo_packet *pkt; | |
2000 | |
5590
011a0a975060
[gaim-migrate @ 5994]
Christian Hammond <chipx86@chipx86.com>
parents:
5583
diff
changeset
|
2001 if (!g_list_find(gaim_connections_get_all(), gc)) { |
2681 | 2002 close(source); |
2003 return; | |
2004 } | |
2005 | |
2006 if (source < 0) { | |
8057 | 2007 gaim_connection_error(gc, _("Unable to connect.")); |
2681 | 2008 return; |
2009 } | |
2010 | |
2011 yd = gc->proto_data; | |
2012 yd->fd = source; | |
2013 | |
3147 | 2014 pkt = yahoo_packet_new(YAHOO_SERVICE_AUTH, YAHOO_STATUS_AVAILABLE, 0); |
2681 | 2015 |
10394 | 2016 yahoo_packet_hash_str(pkt, 1, gaim_normalize(gc->account, gaim_account_get_username(gaim_connection_get_account(gc)))); |
10392 | 2017 yahoo_packet_send_and_free(pkt, yd); |
2681 | 2018 |
2019 gc->inpa = gaim_input_add(yd->fd, GAIM_INPUT_READ, yahoo_pending, gc); | |
2020 } | |
9370 | 2021 |
7134 | 2022 static void yahoo_got_web_connected(gpointer data, gint source, GaimInputCondition cond) |
2023 { | |
2024 GaimConnection *gc = data; | |
2025 struct yahoo_data *yd; | |
2026 struct yahoo_packet *pkt; | |
2027 | |
2028 if (!g_list_find(gaim_connections_get_all(), gc)) { | |
2029 close(source); | |
2030 return; | |
2031 } | |
2032 | |
2033 if (source < 0) { | |
8057 | 2034 gaim_connection_error(gc, _("Unable to connect.")); |
7134 | 2035 return; |
2036 } | |
2037 | |
2038 yd = gc->proto_data; | |
2039 yd->fd = source; | |
2040 | |
2041 pkt = yahoo_packet_new(YAHOO_SERVICE_WEBLOGIN, YAHOO_STATUS_WEBLOGIN, 0); | |
2042 | |
10394 | 2043 yahoo_packet_hash(pkt, "sss", 0, |
2044 gaim_normalize(gc->account, gaim_account_get_username(gaim_connection_get_account(gc))), | |
2045 1, gaim_normalize(gc->account, gaim_account_get_username(gaim_connection_get_account(gc))), | |
2046 6, yd->auth); | |
10392 | 2047 yahoo_packet_send_and_free(pkt, yd); |
2048 | |
7134 | 2049 g_free(yd->auth); |
2050 gc->inpa = gaim_input_add(yd->fd, GAIM_INPUT_READ, yahoo_pending, gc); | |
2051 } | |
2052 | |
2053 static void yahoo_web_pending(gpointer data, gint source, GaimInputCondition cond) | |
2054 { | |
2055 GaimConnection *gc = data; | |
2056 GaimAccount *account = gaim_connection_get_account(gc); | |
2057 struct yahoo_data *yd = gc->proto_data; | |
8243 | 2058 char buf[2048], *i = buf; |
8161 | 2059 int len; |
2060 GString *s; | |
7134 | 2061 |
8118 | 2062 len = read(source, buf, sizeof(buf)-1); |
8216
dcace041cfb8
[gaim-migrate @ 8939]
Christian Hammond <chipx86@chipx86.com>
parents:
8212
diff
changeset
|
2063 if (len <= 0 || (strncmp(buf, "HTTP/1.0 302", strlen("HTTP/1.0 302")) && |
dcace041cfb8
[gaim-migrate @ 8939]
Christian Hammond <chipx86@chipx86.com>
parents:
8212
diff
changeset
|
2064 strncmp(buf, "HTTP/1.1 302", strlen("HTTP/1.1 302")))) { |
7134 | 2065 gaim_connection_error(gc, _("Unable to read")); |
2066 return; | |
2067 } | |
8161 | 2068 |
2069 s = g_string_sized_new(len); | |
8118 | 2070 buf[sizeof(buf)-1] = '\0'; |
8161 | 2071 |
2072 while ((i = strstr(i, "Set-Cookie: "))) { | |
2073 i += strlen("Set-Cookie: "); | |
8243 | 2074 for (;*i != ';' && *i != '\0'; i++) |
8161 | 2075 g_string_append_c(s, *i); |
2076 | |
2077 g_string_append(s, "; "); | |
7134 | 2078 } |
8161 | 2079 |
2080 yd->auth = g_string_free(s, FALSE); | |
7134 | 2081 gaim_input_remove(gc->inpa); |
2082 close(source); | |
2083 /* Now we have our cookies to login with. I'll go get the milk. */ | |
8045 | 2084 if (gaim_proxy_connect(account, "wcs2.msg.dcn.yahoo.com", |
7134 | 2085 gaim_account_get_int(account, "port", YAHOO_PAGER_PORT), |
2086 yahoo_got_web_connected, gc) != 0) { | |
2087 gaim_connection_error(gc, _("Connection problem")); | |
2088 return; | |
2089 } | |
2090 } | |
2091 | |
2092 static void yahoo_got_cookies(gpointer data, gint source, GaimInputCondition cond) | |
2093 { | |
2094 GaimConnection *gc = data; | |
2095 struct yahoo_data *yd = gc->proto_data; | |
2096 if (source < 0) { | |
8057 | 2097 gaim_connection_error(gc, _("Unable to connect.")); |
7134 | 2098 return; |
2099 } | |
2100 write(source, yd->auth, strlen(yd->auth)); | |
2101 g_free(yd->auth); | |
2102 gc->inpa = gaim_input_add(source, GAIM_INPUT_READ, yahoo_web_pending, gc); | |
2103 } | |
2104 | |
2105 static void yahoo_login_page_hash_iter(const char *key, const char *val, GString *url) | |
2106 { | |
2107 if (!strcmp(key, "passwd")) | |
2108 return; | |
2109 url = g_string_append_c(url, '&'); | |
2110 url = g_string_append(url, key); | |
2111 url = g_string_append_c(url, '='); | |
2112 if (!strcmp(key, ".save") || !strcmp(key, ".js")) | |
2113 url = g_string_append_c(url, '1'); | |
2114 else if (!strcmp(key, ".challenge")) | |
2115 url = g_string_append(url, val); | |
2116 else | |
2117 url = g_string_append(url, gaim_url_encode(val)); | |
2118 } | |
2119 | |
2120 static GHashTable *yahoo_login_page_hash(const char *buf, size_t len) | |
2121 { | |
2122 GHashTable *hash = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); | |
7138
f189f8ccaa98
[gaim-migrate @ 7705]
Christian Hammond <chipx86@chipx86.com>
parents:
7134
diff
changeset
|
2123 const char *c = buf; |
f189f8ccaa98
[gaim-migrate @ 7705]
Christian Hammond <chipx86@chipx86.com>
parents:
7134
diff
changeset
|
2124 char *d; |
7134 | 2125 char name[64], value[64]; |
8118 | 2126 int count = sizeof(name)-1; |
7134 | 2127 while ((c < (buf + len)) && (c = strstr(c, "<input "))) { |
2128 c = strstr(c, "name=\"") + strlen("name=\""); | |
8118 | 2129 for (d = name; *c!='"' && count; c++, d++, count--) |
7134 | 2130 *d = *c; |
2131 *d = '\0'; | |
8118 | 2132 count = sizeof(value)-1; |
7134 | 2133 d = strstr(c, "value=\"") + strlen("value=\""); |
2134 if (strchr(c, '>') < d) | |
2135 break; | |
8118 | 2136 for (c = d, d = value; *c!='"' && count; c++, d++, count--) |
7134 | 2137 *d = *c; |
2138 *d = '\0'; | |
2139 g_hash_table_insert(hash, g_strdup(name), g_strdup(value)); | |
2140 } | |
2141 return hash; | |
2142 } | |
2143 | |
7138
f189f8ccaa98
[gaim-migrate @ 7705]
Christian Hammond <chipx86@chipx86.com>
parents:
7134
diff
changeset
|
2144 static void yahoo_login_page_cb(void *user_data, const char *buf, size_t len) |
7134 | 2145 { |
7138
f189f8ccaa98
[gaim-migrate @ 7705]
Christian Hammond <chipx86@chipx86.com>
parents:
7134
diff
changeset
|
2146 GaimConnection *gc = (GaimConnection *)user_data; |
7134 | 2147 GaimAccount *account = gaim_connection_get_account(gc); |
2148 struct yahoo_data *yd = gc->proto_data; | |
2149 const char *sn = gaim_account_get_username(account); | |
2150 const char *pass = gaim_account_get_password(account); | |
2151 GHashTable *hash = yahoo_login_page_hash(buf, len); | |
2152 GString *url = g_string_new("GET /config/login?login="); | |
2153 char md5[33], *hashp = md5, *chal; | |
2154 int i; | |
2155 md5_byte_t result[16]; | |
2156 md5_state_t ctx; | |
7191
4bd3892cded3
[gaim-migrate @ 7760]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
7161
diff
changeset
|
2157 |
4bd3892cded3
[gaim-migrate @ 7760]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
7161
diff
changeset
|
2158 url = g_string_append(url, sn); |
4bd3892cded3
[gaim-migrate @ 7760]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
7161
diff
changeset
|
2159 url = g_string_append(url, "&passwd="); |
4bd3892cded3
[gaim-migrate @ 7760]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
7161
diff
changeset
|
2160 |
7134 | 2161 md5_init(&ctx); |
2162 md5_append(&ctx, pass, strlen(pass)); | |
2163 md5_finish(&ctx, result); | |
2164 for (i = 0; i < 16; ++i) { | |
2165 g_snprintf(hashp, 3, "%02x", result[i]); | |
2166 hashp += 2; | |
2167 } | |
2168 chal = g_strconcat(md5, g_hash_table_lookup(hash, ".challenge"), NULL); | |
2169 md5_init(&ctx); | |
2170 md5_append(&ctx, chal, strlen(chal)); | |
2171 md5_finish(&ctx, result); | |
2172 hashp = md5; | |
2173 for (i = 0; i < 16; ++i) { | |
2174 g_snprintf(hashp, 3, "%02x", result[i]); | |
2175 hashp += 2; | |
2176 } | |
2177 /* | |
2178 md5_init(&ctx); | |
2179 md5_append(&ctx, md5, strlen(md5)); | |
2180 md5_finish(&ctx, result); | |
2181 hashp = md5; | |
2182 for (i = 0; i < 16; ++i) { | |
2183 g_snprintf(hashp, 3, "%02x", result[i]); | |
2184 hashp += 2; | |
2185 } | |
2186 */ | |
2187 g_free(chal); | |
2188 | |
2189 url = g_string_append(url, md5); | |
7138
f189f8ccaa98
[gaim-migrate @ 7705]
Christian Hammond <chipx86@chipx86.com>
parents:
7134
diff
changeset
|
2190 g_hash_table_foreach(hash, (GHFunc)yahoo_login_page_hash_iter, url); |
7134 | 2191 |
2192 url = g_string_append(url, "&.hash=1&.md5=1 HTTP/1.1\r\n" | |
2193 "Host: login.yahoo.com\r\n\r\n"); | |
2194 g_hash_table_destroy(hash); | |
2195 yd->auth = g_string_free(url, FALSE); | |
2196 if (gaim_proxy_connect(account, "login.yahoo.com", 80, yahoo_got_cookies, gc) != 0) { | |
2197 gaim_connection_error(gc, _("Connection problem")); | |
2198 return; | |
2199 } | |
2200 } | |
2201 | |
7883 | 2202 static void yahoo_server_check(GaimAccount *account) |
2203 { | |
2204 const char *server; | |
2205 | |
2206 server = gaim_account_get_string(account, "server", YAHOO_PAGER_HOST); | |
2207 | |
2208 if (strcmp(server, "scs.yahoo.com") == 0) | |
2209 gaim_account_set_string(account, "server", YAHOO_PAGER_HOST); | |
2210 } | |
9306 | 2211 |
2212 static void yahoo_picture_check(GaimAccount *account) | |
2213 { | |
2214 GaimConnection *gc = gaim_account_get_connection(account); | |
2215 const char *buddyicon; | |
2216 | |
2217 buddyicon = gaim_account_get_buddy_icon(account); | |
2218 yahoo_set_buddy_icon(gc, buddyicon); | |
2219 } | |
2220 | |
7883 | 2221 |
5583 | 2222 static void yahoo_login(GaimAccount *account) { |
2223 GaimConnection *gc = gaim_account_get_connection(account); | |
2681 | 2224 struct yahoo_data *yd = gc->proto_data = g_new0(struct yahoo_data, 1); |
2225 | |
9041 | 2226 gc->flags |= GAIM_CONNECTION_HTML | GAIM_CONNECTION_NO_BGCOLOR | GAIM_CONNECTION_NO_URLDESC; |
6629 | 2227 |
5583 | 2228 gaim_connection_update_progress(gc, _("Connecting"), 1, 2); |
2681 | 2229 |
8235 | 2230 gaim_connection_set_display_name(gc, gaim_account_get_username(account)); |
2231 | |
2681 | 2232 yd->fd = -1; |
6784 | 2233 yd->friends = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, yahoo_friend_free); |
6729 | 2234 yd->confs = NULL; |
2235 yd->conf_id = 2; | |
2681 | 2236 |
7883 | 2237 yahoo_server_check(account); |
9306 | 2238 yahoo_picture_check(account); |
7883 | 2239 |
9164 | 2240 if (gaim_account_get_bool(account, "yahoojp", FALSE)) { |
2241 yd->jp = TRUE; | |
2242 if (gaim_proxy_connect(account, | |
2243 gaim_account_get_string(account, "serverjp", YAHOOJP_PAGER_HOST), | |
2244 gaim_account_get_int(account, "port", YAHOO_PAGER_PORT), | |
2245 yahoo_got_connected, gc) != 0) | |
2246 { | |
2247 gaim_connection_error(gc, _("Connection problem")); | |
2248 return; | |
2249 } | |
2250 } else { | |
2251 yd->jp = FALSE; | |
2252 if (gaim_proxy_connect(account, | |
2253 gaim_account_get_string(account, "server", YAHOO_PAGER_HOST), | |
2254 gaim_account_get_int(account, "port", YAHOO_PAGER_PORT), | |
2255 yahoo_got_connected, gc) != 0) | |
2256 { | |
2257 gaim_connection_error(gc, _("Connection problem")); | |
2258 return; | |
2259 } | |
2681 | 2260 } |
9370 | 2261 |
2681 | 2262 |
2263 } | |
2264 | |
5583 | 2265 static void yahoo_close(GaimConnection *gc) { |
2681 | 2266 struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; |
9782 | 2267 GSList *l; |
2268 | |
2269 for (l = yd->confs; l; l = l->next) { | |
2270 GaimConversation *conv = l->data; | |
2271 | |
2272 yahoo_conf_leave(yd, gaim_conversation_get_name(conv), | |
2273 gaim_connection_get_display_name(gc), | |
2274 gaim_conv_chat_get_users(GAIM_CONV_CHAT(conv))); | |
2275 } | |
2276 g_slist_free(yd->confs); | |
6729 | 2277 |
6784 | 2278 g_hash_table_destroy(yd->friends); |
2279 if (yd->chat_name) | |
2280 g_free(yd->chat_name); | |
6729 | 2281 |
7651 | 2282 if (yd->cookie_y) |
2283 g_free(yd->cookie_y); | |
2284 if (yd->cookie_t) | |
2285 g_free(yd->cookie_t); | |
2286 | |
2681 | 2287 if (yd->fd >= 0) |
2288 close(yd->fd); | |
3720
34c95669952f
[gaim-migrate @ 3853]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
3642
diff
changeset
|
2289 |
2681 | 2290 if (yd->rxqueue) |
2291 g_free(yd->rxqueue); | |
2687
2d544f48146d
[gaim-migrate @ 2700]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2686
diff
changeset
|
2292 yd->rxlen = 0; |
9306 | 2293 if (yd->picture_url) |
2294 g_free(yd->picture_url); | |
2295 if (yd->picture_upload_todo) | |
2296 yahoo_buddy_icon_upload_data_free(yd->picture_upload_todo); | |
9376 | 2297 if (yd->ycht) |
2298 ycht_connection_close(yd->ycht); | |
2681 | 2299 if (gc->inpa) |
2300 gaim_input_remove(gc->inpa); | |
2301 g_free(yd); | |
2302 } | |
2303 | |
6695 | 2304 static const char *yahoo_list_icon(GaimAccount *a, GaimBuddy *b) |
2681 | 2305 { |
4687 | 2306 return "yahoo"; |
2681 | 2307 } |
4916 | 2308 |
9972 | 2309 static void yahoo_list_emblems(GaimBuddy *b, const char **se, const char **sw, const char **nw, const char **ne) |
4916 | 2310 { |
2311 int i = 0; | |
2312 char *emblems[4] = {NULL,NULL,NULL,NULL}; | |
6784 | 2313 GaimAccount *account; |
2314 GaimConnection *gc; | |
2315 struct yahoo_data *yd; | |
9278 | 2316 YahooFriend *f; |
10126 | 2317 GaimPresence *presence; |
2318 GaimStatus *status; | |
2319 const char *status_id; | |
6784 | 2320 |
2321 if (!b || !(account = b->account) || !(gc = gaim_account_get_connection(account)) || | |
2322 !(yd = gc->proto_data)) | |
2323 return; | |
2324 | |
9279 | 2325 f = yahoo_friend_find(gc, b->name); |
6784 | 2326 if (!f) { |
2327 *se = "notauthorized"; | |
2328 return; | |
2329 } | |
2330 | |
10126 | 2331 presence = gaim_buddy_get_presence(b); |
2332 status = gaim_presence_get_active_status(presence); | |
2333 status_id = gaim_status_get_id(status); | |
2334 | |
2335 if (gaim_presence_is_online(presence) == FALSE) { | |
4916 | 2336 *se = "offline"; |
2337 return; | |
2338 } else { | |
6784 | 2339 if (f->away) |
6691
306790891ce7
[gaim-migrate @ 7217]
Christian Hammond <chipx86@chipx86.com>
parents:
6687
diff
changeset
|
2340 emblems[i++] = "away"; |
6784 | 2341 if (f->sms) |
2342 emblems[i++] = "wireless"; | |
9283 | 2343 if (yahoo_friend_get_game(f)) |
4916 | 2344 emblems[i++] = "game"; |
2345 } | |
2346 *se = emblems[0]; | |
2347 *sw = emblems[1]; | |
2348 *nw = emblems[2]; | |
2349 *ne = emblems[3]; | |
2350 } | |
2681 | 2351 |
2352 static char *yahoo_get_status_string(enum yahoo_status a) | |
2353 { | |
2354 switch (a) { | |
2355 case YAHOO_STATUS_BRB: | |
4596 | 2356 return _("Be Right Back"); |
2681 | 2357 case YAHOO_STATUS_BUSY: |
4596 | 2358 return _("Busy"); |
2681 | 2359 case YAHOO_STATUS_NOTATHOME: |
4596 | 2360 return _("Not At Home"); |
2681 | 2361 case YAHOO_STATUS_NOTATDESK: |
4596 | 2362 return _("Not At Desk"); |
2681 | 2363 case YAHOO_STATUS_NOTINOFFICE: |
4596 | 2364 return _("Not In Office"); |
2681 | 2365 case YAHOO_STATUS_ONPHONE: |
4606 | 2366 return _("On The Phone"); |
2681 | 2367 case YAHOO_STATUS_ONVACATION: |
4596 | 2368 return _("On Vacation"); |
2681 | 2369 case YAHOO_STATUS_OUTTOLUNCH: |
4596 | 2370 return _("Out To Lunch"); |
2681 | 2371 case YAHOO_STATUS_STEPPEDOUT: |
4596 | 2372 return _("Stepped Out"); |
2873
26be84883f91
[gaim-migrate @ 2886]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2856
diff
changeset
|
2373 case YAHOO_STATUS_INVISIBLE: |
4596 | 2374 return _("Invisible"); |
4730 | 2375 case YAHOO_STATUS_IDLE: |
2376 return _("Idle"); | |
6784 | 2377 case YAHOO_STATUS_OFFLINE: |
2378 return _("Offline"); | |
2879
5fc5123b7098
[gaim-migrate @ 2892]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2878
diff
changeset
|
2379 default: |
4596 | 2380 return _("Online"); |
2681 | 2381 } |
2382 } | |
2383 | |
9030 | 2384 static void yahoo_initiate_conference(GaimBlistNode *node, gpointer data) { |
2385 | |
2386 GaimBuddy *buddy; | |
2387 GaimConnection *gc; | |
2388 | |
6729 | 2389 GHashTable *components; |
2390 struct yahoo_data *yd; | |
2391 int id; | |
2392 | |
9030 | 2393 g_return_if_fail(GAIM_BLIST_NODE_IS_BUDDY(node)); |
2394 | |
2395 buddy = (GaimBuddy *) node; | |
2396 gc = gaim_account_get_connection(buddy->account); | |
6729 | 2397 yd = gc->proto_data; |
2398 id = yd->conf_id; | |
2399 | |
2400 components = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); | |
2401 g_hash_table_replace(components, g_strdup("room"), | |
2402 g_strdup_printf("%s-%d", gaim_connection_get_display_name(gc), id)); | |
2403 g_hash_table_replace(components, g_strdup("topic"), g_strdup("Join my conference...")); | |
2404 g_hash_table_replace(components, g_strdup("type"), g_strdup("Conference")); | |
2405 yahoo_c_join(gc, components); | |
2406 g_hash_table_destroy(components); | |
2407 | |
9030 | 2408 yahoo_c_invite(gc, id, "Join my conference...", buddy->name); |
6729 | 2409 } |
2410 | |
9030 | 2411 static void yahoo_game(GaimBlistNode *node, gpointer data) { |
2412 | |
2413 GaimBuddy *buddy; | |
2414 GaimConnection *gc; | |
2415 | |
2416 struct yahoo_data *yd; | |
9283 | 2417 const char *game; |
2418 char *game2; | |
3019 | 2419 char *t; |
2420 char url[256]; | |
9278 | 2421 YahooFriend *f; |
3019 | 2422 |
9030 | 2423 g_return_if_fail(GAIM_BLIST_NODE_IS_BUDDY(node)); |
2424 | |
2425 buddy = (GaimBuddy *) node; | |
2426 gc = gaim_account_get_connection(buddy->account); | |
2427 yd = (struct yahoo_data *) gc->proto_data; | |
2428 | |
9279 | 2429 f = yahoo_friend_find(gc, buddy->name); |
6784 | 2430 if (!f) |
2431 return; | |
2432 | |
9283 | 2433 game = yahoo_friend_get_game(f); |
3019 | 2434 if (!game) |
2435 return; | |
6784 | 2436 |
9283 | 2437 t = game2 = g_strdup(strstr(game, "ante?room=")); |
2438 while (*t && *t != '\t') | |
3019 | 2439 t++; |
2440 *t = 0; | |
9283 | 2441 g_snprintf(url, sizeof url, "http://games.yahoo.com/games/%s", game2); |
10240
95ca0db2d01d
[gaim-migrate @ 11377]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
10209
diff
changeset
|
2442 gaim_notify_uri(gc, url); |
9283 | 2443 g_free(game2); |
3019 | 2444 } |
4722 | 2445 |
6695 | 2446 static char *yahoo_status_text(GaimBuddy *b) |
4722 | 2447 { |
9278 | 2448 YahooFriend *f = NULL; |
9283 | 2449 const char *msg; |
6691
306790891ce7
[gaim-migrate @ 7217]
Christian Hammond <chipx86@chipx86.com>
parents:
6687
diff
changeset
|
2450 |
9279 | 2451 f = yahoo_friend_find(b->account->gc, b->name); |
6784 | 2452 if (!f) |
2453 return g_strdup(_("Not on server list")); | |
2454 | |
2455 switch (f->status) { | |
2456 case YAHOO_STATUS_AVAILABLE: | |
2457 return NULL; | |
2458 case YAHOO_STATUS_IDLE: | |
2459 if (f->idle == -1) | |
2460 return g_strdup(yahoo_get_status_string(f->status)); | |
2461 return NULL; | |
2462 case YAHOO_STATUS_CUSTOM: | |
9283 | 2463 if (!(msg = yahoo_friend_get_status_message(f))) |
6784 | 2464 return NULL; |
9283 | 2465 return g_markup_escape_text(msg, strlen(msg)); |
9224 | 2466 |
6784 | 2467 default: |
2468 return g_strdup(yahoo_get_status_string(f->status)); | |
2469 } | |
4722 | 2470 } |
2471 | |
9220 | 2472 char *yahoo_tooltip_text(GaimBuddy *b) |
4724 | 2473 { |
9278 | 2474 YahooFriend *f; |
6784 | 2475 char *escaped, *status, *ret; |
2476 | |
9279 | 2477 f = yahoo_friend_find(b->account->gc, b->name); |
6784 | 2478 if (!f) |
8591 | 2479 status = g_strdup_printf("\n%s", _("Not on server list")); |
6784 | 2480 else |
2481 switch (f->status) { | |
2482 case YAHOO_STATUS_IDLE: | |
2483 if (f->idle == -1) { | |
2484 status = g_strdup(yahoo_get_status_string(f->status)); | |
2485 break; | |
2486 } | |
2487 return NULL; | |
2488 case YAHOO_STATUS_CUSTOM: | |
9283 | 2489 if (!yahoo_friend_get_status_message(f)) |
6784 | 2490 return NULL; |
9283 | 2491 status = g_strdup(yahoo_friend_get_status_message(f)); |
6784 | 2492 break; |
2493 default: | |
2494 status = g_strdup(yahoo_get_status_string(f->status)); | |
2495 break; | |
4745 | 2496 } |
6784 | 2497 |
2498 escaped = g_markup_escape_text(status, strlen(status)); | |
8591 | 2499 ret = g_strdup_printf(_("\n<b>%s:</b> %s"), _("Status"), escaped); |
6784 | 2500 g_free(status); |
2501 g_free(escaped); | |
2502 | |
2503 return ret; | |
4729 | 2504 } |
2505 | |
9030 | 2506 static void yahoo_addbuddyfrommenu_cb(GaimBlistNode *node, gpointer data) |
2507 { | |
2508 GaimBuddy *buddy; | |
2509 GaimConnection *gc; | |
2510 | |
2511 g_return_if_fail(GAIM_BLIST_NODE_IS_BUDDY(node)); | |
2512 | |
2513 buddy = (GaimBuddy *) node; | |
2514 gc = gaim_account_get_connection(buddy->account); | |
2515 | |
9285 | 2516 yahoo_add_buddy(gc, buddy, NULL); |
9030 | 2517 } |
2518 | |
2519 | |
2520 static void yahoo_chat_goto_menu(GaimBlistNode *node, gpointer data) | |
6796 | 2521 { |
9030 | 2522 GaimBuddy *buddy; |
2523 GaimConnection *gc; | |
2524 | |
2525 g_return_if_fail(GAIM_BLIST_NODE_IS_BUDDY(node)); | |
2526 | |
2527 buddy = (GaimBuddy *) node; | |
2528 gc = gaim_account_get_connection(buddy->account); | |
2529 | |
2530 yahoo_chat_goto(gc, buddy->name); | |
6796 | 2531 } |
2532 | |
9030 | 2533 |
2534 static GList *yahoo_buddy_menu(GaimBuddy *buddy) | |
2681 | 2535 { |
2536 GList *m = NULL; | |
9030 | 2537 GaimBlistNodeAction *act; |
2538 | |
2539 GaimConnection *gc = gaim_account_get_connection(buddy->account); | |
9370 | 2540 struct yahoo_data *yd = gc->proto_data; |
3019 | 2541 static char buf2[1024]; |
9278 | 2542 YahooFriend *f; |
6784 | 2543 |
9279 | 2544 f = yahoo_friend_find(gc, buddy->name); |
6784 | 2545 |
9370 | 2546 if (!f && !yd->wm) { |
9030 | 2547 act = gaim_blist_node_action_new(_("Add Buddy"), |
2548 yahoo_addbuddyfrommenu_cb, NULL); | |
2549 m = g_list_append(m, act); | |
6784 | 2550 |
2551 return m; | |
9030 | 2552 |
2553 } else if (f->status == YAHOO_STATUS_OFFLINE) { | |
6784 | 2554 return NULL; |
9030 | 2555 } |
2556 | |
9370 | 2557 if (!yd->wm) { |
2558 act = gaim_blist_node_action_new(_("Join in Chat"), | |
2559 yahoo_chat_goto_menu, NULL); | |
2560 m = g_list_append(m, act); | |
2561 } | |
9030 | 2562 |
2563 act = gaim_blist_node_action_new(_("Initiate Conference"), | |
2564 yahoo_initiate_conference, NULL); | |
2565 m = g_list_append(m, act); | |
6729 | 2566 |
9283 | 2567 if (yahoo_friend_get_game(f)) { |
2568 const char *game = yahoo_friend_get_game(f); | |
3019 | 2569 char *room; |
6784 | 2570 char *t; |
2571 | |
2572 if (!(room = strstr(game, "&follow="))) /* skip ahead to the url */ | |
2573 return m; | |
2574 while (*room && *room != '\t') /* skip to the tab */ | |
2575 room++; | |
2576 t = room++; /* room as now at the name */ | |
2577 while (*t != '\n') | |
2578 t++; /* replace the \n with a space */ | |
2579 *t = ' '; | |
2580 g_snprintf(buf2, sizeof buf2, "%s", room); | |
9030 | 2581 |
2582 act = gaim_blist_node_action_new(buf2, yahoo_game, NULL); | |
2583 m = g_list_append(m, act); | |
3019 | 2584 } |
6729 | 2585 |
2681 | 2586 return m; |
2587 } | |
2588 | |
9030 | 2589 |
2590 static GList *yahoo_blist_node_menu(GaimBlistNode *node) | |
2591 { | |
2592 if(GAIM_BLIST_NODE_IS_BUDDY(node)) { | |
2593 return yahoo_buddy_menu((GaimBuddy *) node); | |
2594 } else { | |
2595 return NULL; | |
2596 } | |
2597 } | |
2598 | |
2599 | |
5583 | 2600 static void yahoo_act_id(GaimConnection *gc, const char *entry) |
2681 | 2601 { |
2602 struct yahoo_data *yd = gc->proto_data; | |
2603 | |
2604 struct yahoo_packet *pkt = yahoo_packet_new(YAHOO_SERVICE_IDACT, YAHOO_STATUS_AVAILABLE, 0); | |
10394 | 2605 yahoo_packet_hash_str(pkt, 3, entry); |
10392 | 2606 yahoo_packet_send_and_free(pkt, yd); |
2681 | 2607 |
5583 | 2608 gaim_connection_set_display_name(gc, entry); |
2681 | 2609 } |
2610 | |
9015 | 2611 static void yahoo_show_act_id(GaimPluginAction *action) |
2681 | 2612 { |
9015 | 2613 GaimConnection *gc = (GaimConnection *) action->context; |
5493
3e8487580024
[gaim-migrate @ 5889]
Christian Hammond <chipx86@chipx86.com>
parents:
5436
diff
changeset
|
2614 gaim_request_input(gc, NULL, _("Active which ID?"), NULL, |
8697 | 2615 gaim_connection_get_display_name(gc), FALSE, FALSE, NULL, |
5493
3e8487580024
[gaim-migrate @ 5889]
Christian Hammond <chipx86@chipx86.com>
parents:
5436
diff
changeset
|
2616 _("OK"), G_CALLBACK(yahoo_act_id), |
3e8487580024
[gaim-migrate @ 5889]
Christian Hammond <chipx86@chipx86.com>
parents:
5436
diff
changeset
|
2617 _("Cancel"), NULL, gc); |
2681 | 2618 } |
2619 | |
9015 | 2620 static void yahoo_show_chat_goto(GaimPluginAction *action) |
7878 | 2621 { |
9015 | 2622 GaimConnection *gc = (GaimConnection *) action->context; |
7878 | 2623 gaim_request_input(gc, NULL, _("Join who in chat?"), NULL, |
8697 | 2624 "", FALSE, FALSE, NULL, |
7878 | 2625 _("OK"), G_CALLBACK(yahoo_chat_goto), |
2626 _("Cancel"), NULL, gc); | |
2627 } | |
2628 | |
9015 | 2629 static GList *yahoo_actions(GaimPlugin *plugin, gpointer context) { |
2681 | 2630 GList *m = NULL; |
9015 | 2631 GaimPluginAction *act; |
2632 | |
2633 act = gaim_plugin_action_new(_("Activate ID..."), | |
2634 yahoo_show_act_id); | |
2635 m = g_list_append(m, act); | |
2636 | |
2637 act = gaim_plugin_action_new(_("Join user in chat..."), | |
2638 yahoo_show_chat_goto); | |
2639 m = g_list_append(m, act); | |
7878 | 2640 |
2681 | 2641 return m; |
2642 } | |
2643 | |
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
7112
diff
changeset
|
2644 static int yahoo_send_im(GaimConnection *gc, const char *who, const char *what, GaimConvImFlags flags) |
2681 | 2645 { |
2646 struct yahoo_data *yd = gc->proto_data; | |
2647 struct yahoo_packet *pkt = yahoo_packet_new(YAHOO_SERVICE_MESSAGE, YAHOO_STATUS_OFFLINE, 0); | |
6629 | 2648 char *msg = yahoo_html_to_codes(what); |
7827 | 2649 char *msg2; |
2650 gboolean utf8 = TRUE; | |
9828 | 2651 int ret = 1; |
7827 | 2652 |
2653 msg2 = yahoo_string_encode(gc, msg, &utf8); | |
2681 | 2654 |
10394 | 2655 yahoo_packet_hash(pkt, "ss", 1, gaim_connection_get_display_name(gc), 5, who); |
7827 | 2656 if (utf8) |
10394 | 2657 yahoo_packet_hash_str(pkt, 97, "1"); |
2658 yahoo_packet_hash_str(pkt, 14, msg2); | |
2659 | |
2660 yahoo_packet_hash_str(pkt, 63, ";0"); /* IMvironment */ | |
2661 yahoo_packet_hash_str(pkt, 64, "0"); /* no idea */ | |
2662 yahoo_packet_hash_str(pkt, 1002, "1"); /* no idea, Yahoo 6 or later only it seems */ | |
9306 | 2663 if (!yd->picture_url) |
10394 | 2664 yahoo_packet_hash_str(pkt, 206, "0"); /* 0 = no picture, 2 = picture, maybe 1 = avatar? */ |
9306 | 2665 else |
10394 | 2666 yahoo_packet_hash_str(pkt, 206, "2"); |
2681 | 2667 |
9828 | 2668 /* We may need to not send any packets over 2000 bytes, but I'm not sure yet. */ |
2669 if ((YAHOO_PACKET_HDRLEN + yahoo_packet_length(pkt)) <= 2000) | |
10392 | 2670 yahoo_packet_send(pkt, yd); |
9828 | 2671 else |
2672 ret = -E2BIG; | |
2681 | 2673 |
2674 yahoo_packet_free(pkt); | |
6629 | 2675 |
2676 g_free(msg); | |
7827 | 2677 g_free(msg2); |
6629 | 2678 |
9828 | 2679 return ret; |
2681 | 2680 } |
2681 | |
6059 | 2682 int yahoo_send_typing(GaimConnection *gc, const char *who, int typ) |
2993 | 2683 { |
2684 struct yahoo_data *yd = gc->proto_data; | |
3019 | 2685 struct yahoo_packet *pkt = yahoo_packet_new(YAHOO_SERVICE_NOTIFY, YAHOO_STATUS_TYPING, 0); |
10394 | 2686 yahoo_packet_hash(pkt, "ssssss", 49, "TYPING", 1, gaim_connection_get_display_name(gc), |
2687 14, " ", 13, typ == GAIM_TYPING ? "1" : "0", | |
2688 5, who, 1002, "1"); | |
2993 | 2689 |
10392 | 2690 yahoo_packet_send_and_free(pkt, yd); |
2993 | 2691 |
3001 | 2692 return 0; |
2993 | 2693 } |
2694 | |
9984 | 2695 static void yahoo_set_status(GaimAccount *account, GaimStatus *status) |
2681 | 2696 { |
9984 | 2697 GaimConnection *gc = gaim_account_get_connection(account); |
2681 | 2698 struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; |
2699 struct yahoo_packet *pkt; | |
10373 | 2700 int old_status = yd->current_status; |
9984 | 2701 const char *id; |
7827 | 2702 char *conv_msg = NULL; |
8503 | 2703 char *conv_msg2 = NULL; |
9984 | 2704 |
2705 id = gaim_status_get_id(status); | |
2706 | |
10373 | 2707 if (!strcmp(id, YAHOO_STATUS_TYPE_AVAILABLE)) { |
9984 | 2708 yd->current_status = YAHOO_STATUS_AVAILABLE; |
10373 | 2709 } else if (!strcmp(id, YAHOO_STATUS_TYPE_BRB)) { |
9984 | 2710 yd->current_status = YAHOO_STATUS_BRB; |
10373 | 2711 } else if (!strcmp(id, YAHOO_STATUS_TYPE_BUSY)) { |
9984 | 2712 yd->current_status = YAHOO_STATUS_BUSY; |
10373 | 2713 } else if (!strcmp(id, YAHOO_STATUS_TYPE_NOTATHOME)) { |
9984 | 2714 yd->current_status = YAHOO_STATUS_NOTATHOME; |
10373 | 2715 } else if (!strcmp(id, YAHOO_STATUS_TYPE_NOTATDESK)) { |
9984 | 2716 yd->current_status = YAHOO_STATUS_NOTATDESK; |
10373 | 2717 } else if (!strcmp(id, YAHOO_STATUS_TYPE_NOTINOFFICE)) { |
9984 | 2718 yd->current_status = YAHOO_STATUS_NOTINOFFICE; |
10373 | 2719 } else if (!strcmp(id, YAHOO_STATUS_TYPE_ONPHONE)) { |
9984 | 2720 yd->current_status = YAHOO_STATUS_ONPHONE; |
10373 | 2721 } else if (!strcmp(id, YAHOO_STATUS_TYPE_ONVACATION)) { |
9984 | 2722 yd->current_status = YAHOO_STATUS_ONVACATION; |
10373 | 2723 } else if (!strcmp(id, YAHOO_STATUS_TYPE_OUTTOLUNCH)) { |
9984 | 2724 yd->current_status = YAHOO_STATUS_OUTTOLUNCH; |
10373 | 2725 } else if (!strcmp(id, YAHOO_STATUS_TYPE_STEPPEDOUT)) { |
9984 | 2726 yd->current_status = YAHOO_STATUS_STEPPEDOUT; |
10373 | 2727 } else if (!strcmp(id, YAHOO_STATUS_TYPE_INVISIBLE)) { |
9984 | 2728 yd->current_status = YAHOO_STATUS_INVISIBLE; |
10373 | 2729 } else if (!strcmp(id, YAHOO_STATUS_TYPE_AWAY)) { |
2681 | 2730 yd->current_status = YAHOO_STATUS_CUSTOM; |
10373 | 2731 } else if (!strcmp(id, YAHOO_STATUS_TYPE_AVAILABLE_WM)) { |
9984 | 2732 yd->current_status = YAHOO_STATUS_CUSTOM; |
2733 } else if (gc->is_idle) { /* i think this is broken */ | |
2681 | 2734 yd->current_status = YAHOO_STATUS_IDLE; |
2735 } else { | |
10373 | 2736 gaim_debug_error("yahoo", "Unexpected GaimStatus passed to yahoo_set_status!\n"); |
2681 | 2737 yd->current_status = YAHOO_STATUS_AVAILABLE; |
2738 } | |
2739 | |
10373 | 2740 if (yd->current_status == YAHOO_STATUS_INVISIBLE) { |
2741 pkt = yahoo_packet_new(YAHOO_SERVICE_Y6_VISIBLE_TOGGLE, YAHOO_STATUS_AVAILABLE, 0); | |
10394 | 2742 yahoo_packet_hash_str(pkt, 13, "2"); |
10392 | 2743 yahoo_packet_send_and_free(pkt, yd); |
10373 | 2744 |
2745 return; | |
2746 } | |
2747 | |
2748 pkt = yahoo_packet_new(YAHOO_SERVICE_Y6_STATUS_UPDATE, YAHOO_STATUS_AVAILABLE, 0); | |
10394 | 2749 yahoo_packet_hash_int(pkt, 10, yd->current_status); |
6847 | 2750 |
9984 | 2751 if (yd->current_status == YAHOO_STATUS_CUSTOM) { |
2752 const char *msg = gaim_status_get_attr_string(status, "message"); | |
10195 | 2753 |
2754 if (msg == NULL) { | |
2755 gaim_debug_info("yahoo", "Attempted to set a NULL status message.\n"); | |
2756 msg = ""; | |
2757 } | |
2758 | |
9984 | 2759 conv_msg = yahoo_string_encode(gc, msg, NULL); |
2760 conv_msg2 = gaim_markup_strip_html(conv_msg); | |
10394 | 2761 yahoo_packet_hash_str(pkt, 19, conv_msg2); |
9984 | 2762 |
10373 | 2763 } else { |
10394 | 2764 yahoo_packet_hash_str(pkt, 19, ""); |
10373 | 2765 } |
2766 | |
2767 if (gc->is_idle) | |
10394 | 2768 yahoo_packet_hash_str(pkt, 47, "2"); |
10373 | 2769 else if (!gaim_status_type_is_available(gaim_status_get_type(status))) |
10394 | 2770 yahoo_packet_hash_str(pkt, 47, "1"); |
2681 | 2771 |
10392 | 2772 yahoo_packet_send_and_free(pkt, yd); |
9984 | 2773 |
2774 g_free(conv_msg); | |
2775 g_free(conv_msg2); | |
10373 | 2776 |
2777 if (old_status == YAHOO_STATUS_INVISIBLE) { | |
2778 pkt = yahoo_packet_new(YAHOO_SERVICE_Y6_VISIBLE_TOGGLE, YAHOO_STATUS_AVAILABLE, 0); | |
10394 | 2779 yahoo_packet_hash_str(pkt, 13, "1"); |
10392 | 2780 yahoo_packet_send_and_free(pkt, yd); |
10373 | 2781 } |
2681 | 2782 } |
2783 | |
5583 | 2784 static void yahoo_set_idle(GaimConnection *gc, int idle) |
2681 | 2785 { |
2786 struct yahoo_data *yd = gc->proto_data; | |
2787 struct yahoo_packet *pkt = NULL; | |
8503 | 2788 char *msg = NULL, *msg2 = NULL; |
10373 | 2789 |
2790 if (idle && yd->current_status == YAHOO_STATUS_AVAILABLE) | |
2681 | 2791 yd->current_status = YAHOO_STATUS_IDLE; |
10373 | 2792 else if (!idle && yd->current_status == YAHOO_STATUS_IDLE) |
2681 | 2793 yd->current_status = YAHOO_STATUS_AVAILABLE; |
10373 | 2794 |
2795 | |
2796 pkt = yahoo_packet_new(YAHOO_SERVICE_Y6_STATUS_UPDATE, YAHOO_STATUS_AVAILABLE, 0); | |
2797 | |
10394 | 2798 yahoo_packet_hash_int(pkt, 10, yd->current_status); |
10373 | 2799 if (yd->current_status == YAHOO_STATUS_CUSTOM) { |
2800 GaimStatus *status = gaim_presence_get_active_status(gaim_account_get_presence(gaim_connection_get_account(gc))); | |
10379 | 2801 msg = yahoo_string_encode(gc, gaim_status_get_attr_string(status, "message"), NULL); //this line crashes, fix it |
10373 | 2802 msg2 = gaim_unescape_html(msg); |
10394 | 2803 yahoo_packet_hash_str(pkt, 19, msg2); |
6847 | 2804 } else { |
10394 | 2805 yahoo_packet_hash_str(pkt, 19, ""); |
2681 | 2806 } |
2807 | |
10373 | 2808 if (idle) |
10394 | 2809 yahoo_packet_hash_str(pkt, 47, "2"); |
10373 | 2810 else if (!gaim_presence_is_available(gaim_account_get_presence(gaim_connection_get_account(gc)))) |
10394 | 2811 yahoo_packet_hash_str(pkt, 47, "1"); |
10373 | 2812 |
2813 | |
10392 | 2814 yahoo_packet_send_and_free(pkt, yd); |
10373 | 2815 |
2816 g_free(msg); | |
2817 g_free(msg2); | |
2681 | 2818 } |
2819 | |
9979 | 2820 static GList *yahoo_status_types(GaimAccount *account) |
2681 | 2821 { |
9979 | 2822 GaimConnection *gc = gaim_account_get_connection(account); |
2823 struct yahoo_data *yd = NULL; | |
2824 GaimStatusType *type; | |
2825 GList *types = NULL; | |
2826 | |
2827 if (gc) | |
2828 yd = gc->proto_data; | |
2829 | |
10373 | 2830 type = gaim_status_type_new(GAIM_STATUS_OFFLINE, YAHOO_STATUS_TYPE_OFFLINE, _("Offline"), FALSE); |
9979 | 2831 types = g_list_append(types, type); |
2832 | |
10373 | 2833 type = gaim_status_type_new(GAIM_STATUS_ONLINE, YAHOO_STATUS_TYPE_ONLINE, _("Online"), FALSE); |
9979 | 2834 types = g_list_append(types, type); |
2835 | |
10373 | 2836 type = gaim_status_type_new(GAIM_STATUS_AVAILABLE, YAHOO_STATUS_TYPE_AVAILABLE, _("Available"), TRUE); |
9979 | 2837 types = g_list_append(types, type); |
2838 | |
2839 if (!yd || !yd->wm) { | |
10373 | 2840 type = gaim_status_type_new_with_attrs(GAIM_STATUS_AVAILABLE, YAHOO_STATUS_TYPE_AVAILABLE_WM, |
9979 | 2841 "Available With Message", TRUE, TRUE, FALSE, |
2842 "message", _("Message"), | |
10009 | 2843 gaim_value_new(GAIM_TYPE_STRING), NULL); |
9979 | 2844 types = g_list_append(types, type); |
2845 | |
2846 | |
10373 | 2847 type = gaim_status_type_new(GAIM_STATUS_AWAY, YAHOO_STATUS_TYPE_BRB, _("Be Right Back"), TRUE); |
9979 | 2848 types = g_list_append(types, type); |
2849 | |
10373 | 2850 type = gaim_status_type_new(GAIM_STATUS_AWAY, YAHOO_STATUS_TYPE_BUSY, _("Busy"), TRUE); |
9979 | 2851 types = g_list_append(types, type); |
2852 | |
10373 | 2853 type = gaim_status_type_new(GAIM_STATUS_AWAY, YAHOO_STATUS_TYPE_NOTATHOME, _("Not At Home"), TRUE); |
9979 | 2854 types = g_list_append(types, type); |
2855 | |
10373 | 2856 type = gaim_status_type_new(GAIM_STATUS_AWAY, YAHOO_STATUS_TYPE_NOTATDESK, _("Not At Desk"), TRUE); |
9979 | 2857 types = g_list_append(types, type); |
2858 | |
10373 | 2859 type = gaim_status_type_new(GAIM_STATUS_AWAY, YAHOO_STATUS_TYPE_NOTINOFFICE, _("Not In Office"), TRUE); |
9979 | 2860 types = g_list_append(types, type); |
2861 | |
10373 | 2862 type = gaim_status_type_new(GAIM_STATUS_AWAY, YAHOO_STATUS_TYPE_ONPHONE, _("On The Phone"), TRUE); |
9979 | 2863 types = g_list_append(types, type); |
2864 | |
10373 | 2865 type = gaim_status_type_new(GAIM_STATUS_AWAY, YAHOO_STATUS_TYPE_ONVACATION, _("On Vacation"), TRUE); |
9979 | 2866 types = g_list_append(types, type); |
2867 | |
10373 | 2868 type = gaim_status_type_new(GAIM_STATUS_AWAY, YAHOO_STATUS_TYPE_OUTTOLUNCH, _("Out To Lunch"), TRUE); |
9979 | 2869 types = g_list_append(types, type); |
2870 | |
10373 | 2871 type = gaim_status_type_new(GAIM_STATUS_AWAY, YAHOO_STATUS_TYPE_STEPPEDOUT, _("Stepped Out"), TRUE); |
9979 | 2872 types = g_list_append(types, type); |
2873 | |
10373 | 2874 type = gaim_status_type_new_with_attrs(GAIM_STATUS_AWAY, YAHOO_STATUS_TYPE_AWAY, |
10195 | 2875 _("Away"), TRUE, TRUE, FALSE, |
9979 | 2876 "message", _("Message"), |
10009 | 2877 gaim_value_new(GAIM_TYPE_STRING), NULL); |
9979 | 2878 types = g_list_append(types, type); |
9370 | 2879 } |
10373 | 2880 type = gaim_status_type_new(GAIM_STATUS_HIDDEN, YAHOO_STATUS_TYPE_INVISIBLE, _("Invisible"), TRUE); |
9979 | 2881 types = g_list_append(types, type); |
2882 | |
2883 | |
2884 return types; | |
2681 | 2885 } |
2886 | |
5583 | 2887 static void yahoo_keepalive(GaimConnection *gc) |
2681 | 2888 { |
2889 struct yahoo_data *yd = gc->proto_data; | |
2890 struct yahoo_packet *pkt = yahoo_packet_new(YAHOO_SERVICE_PING, YAHOO_STATUS_AVAILABLE, 0); | |
10392 | 2891 yahoo_packet_send_and_free(pkt, yd); |
6729 | 2892 |
2893 if (!yd->chat_online) | |
2894 return; | |
2895 | |
9376 | 2896 if (yd->wm) { |
2897 ycht_chat_send_keepalive(yd->ycht); | |
2898 return; | |
2899 } | |
2900 | |
6729 | 2901 pkt = yahoo_packet_new(YAHOO_SERVICE_CHATPING, YAHOO_STATUS_AVAILABLE, 0); |
10394 | 2902 yahoo_packet_hash_str(pkt, 109, gaim_connection_get_display_name(gc)); |
2903 yahoo_packet_send_and_free(pkt, yd); | |
2681 | 2904 } |
2905 | |
9285 | 2906 /* XXX - What's the deal with GaimGroup *foo? */ |
2907 static void yahoo_add_buddy(GaimConnection *gc, GaimBuddy *buddy, GaimGroup *foo) | |
2681 | 2908 { |
2909 struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; | |
2910 struct yahoo_packet *pkt; | |
6695 | 2911 GaimGroup *g; |
2681 | 2912 char *group = NULL; |
7829 | 2913 char *group2 = NULL; |
2681 | 2914 |
2915 if (!yd->logged_in) | |
2916 return; | |
2917 | |
6840 | 2918 if (foo) |
2919 group = foo->name; | |
2920 if (!group) { | |
9285 | 2921 g = gaim_find_buddys_group(gaim_find_buddy(gc->account, buddy->name)); |
6840 | 2922 if (g) |
2923 group = g->name; | |
2924 else | |
2925 group = "Buddies"; | |
2926 } | |
2681 | 2927 |
7829 | 2928 group2 = yahoo_string_encode(gc, group, NULL); |
2681 | 2929 pkt = yahoo_packet_new(YAHOO_SERVICE_ADDBUDDY, YAHOO_STATUS_AVAILABLE, 0); |
10394 | 2930 yahoo_packet_hash(pkt, "ssss", 1, gaim_connection_get_display_name(gc), |
2931 7, buddy->name, 65, group2, 14, ""); | |
10392 | 2932 yahoo_packet_send_and_free(pkt, yd); |
7829 | 2933 g_free(group2); |
2681 | 2934 } |
2935 | |
9285 | 2936 static void yahoo_remove_buddy(GaimConnection *gc, GaimBuddy *buddy, GaimGroup *group) |
2681 | 2937 { |
2938 struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; | |
9278 | 2939 YahooFriend *f; |
6795
40ba19133882
[gaim-migrate @ 7334]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
6793
diff
changeset
|
2940 struct yahoo_packet *pkt; |
6840 | 2941 GSList *buddies, *l; |
2942 GaimGroup *g; | |
2943 gboolean remove = TRUE; | |
7827 | 2944 char *cg; |
6784 | 2945 |
9285 | 2946 if (!(f = yahoo_friend_find(gc, buddy->name))) |
6784 | 2947 return; |
2948 | |
9285 | 2949 buddies = gaim_find_buddies(gaim_connection_get_account(gc), buddy->name); |
6840 | 2950 for (l = buddies; l; l = l->next) { |
2951 g = gaim_find_buddys_group(l->data); | |
9285 | 2952 if (gaim_utf8_strcasecmp(group->name, g->name)) { |
6840 | 2953 remove = FALSE; |
2954 break; | |
2955 } | |
2956 } | |
2957 | |
2958 g_slist_free(buddies); | |
2959 | |
2960 if (remove) | |
9285 | 2961 g_hash_table_remove(yd->friends, buddy->name); |
2962 | |
2963 cg = yahoo_string_encode(gc, group->name, NULL); | |
6795
40ba19133882
[gaim-migrate @ 7334]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
6793
diff
changeset
|
2964 pkt = yahoo_packet_new(YAHOO_SERVICE_REMBUDDY, YAHOO_STATUS_AVAILABLE, 0); |
10394 | 2965 yahoo_packet_hash(pkt, "sss", 1, gaim_connection_get_display_name(gc), |
2966 7, buddy->name, 65, cg); | |
10392 | 2967 yahoo_packet_send_and_free(pkt, yd); |
7827 | 2968 g_free(cg); |
2681 | 2969 } |
2970 | |
6760 | 2971 static void yahoo_add_deny(GaimConnection *gc, const char *who) { |
2972 struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; | |
2973 struct yahoo_packet *pkt; | |
2974 | |
2975 if (!yd->logged_in) | |
2976 return; | |
8057 | 2977 /* It seems to work better without this */ |
2978 | |
8113 | 2979 /* if (gc->account->perm_deny != 4) |
2980 return; */ | |
2981 | |
2982 if (!who || who[0] == '\0') | |
2983 return; | |
2984 | |
6760 | 2985 pkt = yahoo_packet_new(YAHOO_SERVICE_IGNORECONTACT, YAHOO_STATUS_AVAILABLE, 0); |
10394 | 2986 yahoo_packet_hash(pkt, "sss", 1, gaim_connection_get_display_name(gc), |
2987 7, who, 13, "1"); | |
10392 | 2988 yahoo_packet_send_and_free(pkt, yd); |
6760 | 2989 } |
2990 | |
2991 static void yahoo_rem_deny(GaimConnection *gc, const char *who) { | |
2992 struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; | |
2993 struct yahoo_packet *pkt; | |
2994 | |
2995 if (!yd->logged_in) | |
2996 return; | |
2997 | |
2998 if (!who || who[0] == '\0') | |
2999 return; | |
3000 | |
3001 pkt = yahoo_packet_new(YAHOO_SERVICE_IGNORECONTACT, YAHOO_STATUS_AVAILABLE, 0); | |
10394 | 3002 yahoo_packet_hash(pkt, "sss", 1, gaim_connection_get_display_name(gc), 7, who, 13, "2"); |
10392 | 3003 yahoo_packet_send_and_free(pkt, yd); |
6760 | 3004 } |
3005 | |
3006 static void yahoo_set_permit_deny(GaimConnection *gc) { | |
3007 GaimAccount *acct; | |
3008 GSList *deny; | |
3009 | |
3010 acct = gc->account; | |
3011 | |
3012 switch (acct->perm_deny) { | |
10105 | 3013 /* privacy 1 */ |
3014 case GAIM_PRIVACY_ALLOW_ALL: | |
10143 | 3015 for (deny = acct->deny;deny;deny = deny->next) |
3016 yahoo_rem_deny(gc, deny->data); | |
3017 break; | |
10105 | 3018 /* privacy 3 */ |
3019 case GAIM_PRIVACY_ALLOW_USERS: | |
6760 | 3020 for (deny = acct->deny;deny;deny = deny->next) |
3021 yahoo_rem_deny(gc, deny->data); | |
3022 break; | |
10105 | 3023 /* privacy 5 */ |
3024 case GAIM_PRIVACY_ALLOW_BUDDYLIST: | |
3025 /* privacy 4 */ | |
3026 case GAIM_PRIVACY_DENY_USERS: | |
6760 | 3027 for (deny = acct->deny;deny;deny = deny->next) |
3028 yahoo_add_deny(gc, deny->data); | |
3029 break; | |
10105 | 3030 /* privacy 2 */ |
3031 case GAIM_PRIVACY_DENY_ALL: | |
6760 | 3032 default: |
3033 break; | |
3034 } | |
3035 } | |
3036 | |
6513 | 3037 static gboolean yahoo_unload_plugin(GaimPlugin *plugin) |
3038 { | |
3039 yahoo_dest_colorht(); | |
3040 return TRUE; | |
3041 } | |
3042 | |
6793 | 3043 static void yahoo_change_buddys_group(GaimConnection *gc, const char *who, |
3044 const char *old_group, const char *new_group) | |
3045 { | |
3046 struct yahoo_data *yd = gc->proto_data; | |
3047 struct yahoo_packet *pkt; | |
7827 | 3048 char *gpn, *gpo; |
6793 | 3049 |
3050 /* Step 0: If they aren't on the server list anyway, | |
3051 * don't bother letting the server know. | |
3052 */ | |
9279 | 3053 if (!yahoo_friend_find(gc, who)) |
6793 | 3054 return; |
3055 | |
7827 | 3056 /* If old and new are the same, we would probably |
3057 * end up deleting the buddy, which would be bad. | |
3058 * This might happen because of the charset conversation. | |
3059 */ | |
3060 gpn = yahoo_string_encode(gc, new_group, NULL); | |
3061 gpo = yahoo_string_encode(gc, old_group, NULL); | |
3062 if (!strcmp(gpn, gpo)) { | |
3063 g_free(gpn); | |
3064 g_free(gpo); | |
3065 return; | |
3066 } | |
3067 | |
6793 | 3068 /* Step 1: Add buddy to new group. */ |
3069 pkt = yahoo_packet_new(YAHOO_SERVICE_ADDBUDDY, YAHOO_STATUS_AVAILABLE, 0); | |
10394 | 3070 yahoo_packet_hash(pkt, "ssss", 1, gaim_connection_get_display_name(gc), |
3071 7, who, 65, gpn, 14, ""); | |
10392 | 3072 yahoo_packet_send_and_free(pkt, yd); |
6793 | 3073 |
3074 /* Step 2: Remove buddy from old group */ | |
3075 pkt = yahoo_packet_new(YAHOO_SERVICE_REMBUDDY, YAHOO_STATUS_AVAILABLE, 0); | |
10394 | 3076 yahoo_packet_hash(pkt, "sss", 1, gaim_connection_get_display_name(gc), 7, who, 65, gpo); |
10392 | 3077 yahoo_packet_send_and_free(pkt, yd); |
7827 | 3078 g_free(gpn); |
3079 g_free(gpo); | |
6793 | 3080 } |
3081 | |
9285 | 3082 static void yahoo_rename_group(GaimConnection *gc, const char *old_name, |
3083 GaimGroup *group, GList *moved_buddies) | |
6793 | 3084 { |
3085 struct yahoo_data *yd = gc->proto_data; | |
3086 struct yahoo_packet *pkt; | |
7827 | 3087 char *gpn, *gpo; |
3088 | |
9285 | 3089 gpn = yahoo_string_encode(gc, group->name, NULL); |
3090 gpo = yahoo_string_encode(gc, old_name, NULL); | |
7827 | 3091 if (!strcmp(gpn, gpo)) { |
3092 g_free(gpn); | |
3093 g_free(gpo); | |
3094 return; | |
3095 } | |
6793 | 3096 |
3097 pkt = yahoo_packet_new(YAHOO_SERVICE_GROUPRENAME, YAHOO_STATUS_AVAILABLE, 0); | |
10394 | 3098 yahoo_packet_hash(pkt, "sss", 1, gaim_connection_get_display_name(gc), |
3099 65, gpo, 67, gpn); | |
10392 | 3100 yahoo_packet_send_and_free(pkt, yd); |
7827 | 3101 g_free(gpn); |
3102 g_free(gpo); | |
6793 | 3103 } |
3104 | |
10119 | 3105 static GaimCmdRet |
3106 yahoogaim_cmd_buzz(GaimConversation *c, const gchar *cmd, gchar **args, gchar **error, void *data) { | |
3107 | |
3108 GaimAccount *account = gaim_conversation_get_account(c); | |
3109 const char *username = gaim_account_get_username(account); | |
3110 | |
3111 if (*args && args[0]) | |
3112 return GAIM_CMD_RET_FAILED; | |
3113 | |
3114 gaim_debug(GAIM_DEBUG_INFO, "yahoo", | |
3115 "Sending <ding> on account %s to buddy %s.\n", username, c->name); | |
3116 gaim_conv_im_send(GAIM_CONV_IM(c), "<ding>"); | |
3117 gaim_conv_im_write(GAIM_CONV_IM(c), "", _("Buzz!!"), GAIM_MESSAGE_NICK|GAIM_MESSAGE_RECV, time(NULL)); | |
3118 return GAIM_CMD_RET_OK; | |
3119 } | |
3120 | |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3121 static GaimPlugin *my_protocol = NULL; |
2681 | 3122 |
10119 | 3123 /********************************* Commands **********************************/ |
3124 | |
3125 static GaimCmdRet | |
3126 yahoogaim_cmd_chat_join(GaimConversation *conv, const char *cmd, | |
3127 char **args, char **error, void *data) | |
3128 { | |
3129 GHashTable *comp; | |
3130 GaimConnection *gc; | |
3131 struct yahoo_data *yd; | |
3132 int id; | |
3133 | |
3134 if (!args || !args[0]) | |
3135 return GAIM_CMD_RET_FAILED; | |
3136 | |
3137 gc = gaim_conversation_get_gc(conv); | |
3138 yd = gc->proto_data; | |
3139 id = yd->conf_id; | |
3140 gaim_debug(GAIM_DEBUG_INFO, "yahoo", | |
3141 "Trying to join %s \n", args[0]); | |
3142 | |
3143 comp = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); | |
3144 g_hash_table_replace(comp, g_strdup("room"), | |
3145 g_strdup_printf("%s", g_ascii_strdown(args[0], strlen(args[0])))); | |
3146 g_hash_table_replace(comp, g_strdup("type"), g_strdup("Chat")); | |
3147 | |
3148 yahoo_c_join(gc, comp); | |
3149 | |
3150 g_hash_table_destroy(comp); | |
3151 return GAIM_CMD_RET_OK; | |
3152 } | |
3153 /************************** Plugin Initialization ****************************/ | |
3154 static void | |
3155 yahoogaim_register_commands(void) | |
3156 { | |
3157 gaim_cmd_register("join", "s", GAIM_CMD_P_PRPL, | |
3158 GAIM_CMD_FLAG_IM | GAIM_CMD_FLAG_CHAT | | |
3159 GAIM_CMD_FLAG_PRPL_ONLY, | |
3160 "prpl-yahoo", yahoogaim_cmd_chat_join, | |
3161 _("join <room>: Join a chat room on the Yahoo network"), NULL); | |
10121 | 3162 gaim_cmd_register("buzz", "", GAIM_CMD_P_PRPL, |
10119 | 3163 GAIM_CMD_FLAG_IM | GAIM_CMD_FLAG_PRPL_ONLY, |
3164 "prpl-yahoo", yahoogaim_cmd_buzz, | |
3165 _("buzz: Buzz a contact to get their attention"), NULL); | |
3166 } | |
3167 | |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3168 static GaimPluginProtocolInfo prpl_info = |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3169 { |
9308 | 3170 OPT_PROTO_MAIL_CHECK | OPT_PROTO_CHAT_TOPIC, |
6729 | 3171 NULL, /* user_splits */ |
3172 NULL, /* protocol_options */ | |
9318 | 3173 {"png", 96, 96, 96, 96, GAIM_ICON_SCALE_SEND}, |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3174 yahoo_list_icon, |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3175 yahoo_list_emblems, |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3176 yahoo_status_text, |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3177 yahoo_tooltip_text, |
9979 | 3178 yahoo_status_types, |
9030 | 3179 yahoo_blist_node_menu, |
6729 | 3180 yahoo_c_info, |
9768 | 3181 yahoo_c_info_defaults, |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3182 yahoo_login, |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3183 yahoo_close, |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3184 yahoo_send_im, |
6729 | 3185 NULL, /* set info */ |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3186 yahoo_send_typing, |
6514 | 3187 yahoo_get_info, |
9984 | 3188 yahoo_set_status, |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3189 yahoo_set_idle, |
6729 | 3190 NULL, /* change_passwd*/ |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3191 yahoo_add_buddy, |
6729 | 3192 NULL, /* add_buddies */ |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3193 yahoo_remove_buddy, |
6729 | 3194 NULL, /*remove_buddies */ |
3195 NULL, /* add_permit */ | |
6760 | 3196 yahoo_add_deny, |
6729 | 3197 NULL, /* rem_permit */ |
6760 | 3198 yahoo_rem_deny, |
3199 yahoo_set_permit_deny, | |
6729 | 3200 NULL, /* warn */ |
3201 yahoo_c_join, | |
8562 | 3202 NULL, /* reject chat invite */ |
9917 | 3203 yahoo_get_chat_name, |
6729 | 3204 yahoo_c_invite, |
3205 yahoo_c_leave, | |
3206 NULL, /* chat whisper */ | |
3207 yahoo_c_send, | |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3208 yahoo_keepalive, |
6729 | 3209 NULL, /* register_user */ |
3210 NULL, /* get_cb_info */ | |
3211 NULL, /* get_cb_away */ | |
3212 NULL, /* alias_buddy */ | |
6793 | 3213 yahoo_change_buddys_group, |
3214 yahoo_rename_group, | |
6729 | 3215 NULL, /* buddy_free */ |
3216 NULL, /* convo_closed */ | |
3217 NULL, /* normalize */ | |
9306 | 3218 yahoo_set_buddy_icon, |
7651 | 3219 NULL, /* void (*remove_group)(GaimConnection *gc, const char *group);*/ |
3220 NULL, /* char *(*get_cb_real_name)(GaimConnection *gc, int id, const char *who); */ | |
9475 | 3221 NULL, /* set_chat_topic */ |
3222 NULL, /* find_blist_chat */ | |
8113 | 3223 yahoo_roomlist_get_list, |
3224 yahoo_roomlist_cancel, | |
9466 | 3225 yahoo_roomlist_expand_category, |
9475 | 3226 NULL, /* can_receive_file */ |
9466 | 3227 yahoo_send_file |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3228 }; |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3229 |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3230 static GaimPluginInfo info = |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3231 { |
9943 | 3232 GAIM_PLUGIN_MAGIC, |
3233 GAIM_MAJOR_VERSION, | |
3234 GAIM_MINOR_VERSION, | |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3235 GAIM_PLUGIN_PROTOCOL, /**< type */ |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3236 NULL, /**< ui_requirement */ |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3237 0, /**< flags */ |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3238 NULL, /**< dependencies */ |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3239 GAIM_PRIORITY_DEFAULT, /**< priority */ |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3240 |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3241 "prpl-yahoo", /**< id */ |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3242 "Yahoo", /**< name */ |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3243 VERSION, /**< version */ |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3244 /** summary */ |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3245 N_("Yahoo Protocol Plugin"), |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3246 /** description */ |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3247 N_("Yahoo Protocol Plugin"), |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3248 NULL, /**< author */ |
6371
8f94cce8faa5
[gaim-migrate @ 6876]
Christian Hammond <chipx86@chipx86.com>
parents:
6321
diff
changeset
|
3249 GAIM_WEBSITE, /**< homepage */ |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3250 |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3251 NULL, /**< load */ |
6513 | 3252 yahoo_unload_plugin, /**< unload */ |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3253 NULL, /**< destroy */ |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3254 |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3255 NULL, /**< ui_info */ |
8993 | 3256 &prpl_info, /**< extra_info */ |
3257 NULL, | |
9015 | 3258 yahoo_actions |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3259 }; |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3260 |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3261 static void |
5920
7d385de2f9cd
[gaim-migrate @ 6360]
Christian Hammond <chipx86@chipx86.com>
parents:
5872
diff
changeset
|
3262 init_plugin(GaimPlugin *plugin) |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3263 { |
5638
0bdfa28c678e
[gaim-migrate @ 6047]
Christian Hammond <chipx86@chipx86.com>
parents:
5590
diff
changeset
|
3264 GaimAccountOption *option; |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3265 |
9164 | 3266 option = gaim_account_option_bool_new(_("Yahoo Japan"), "yahoojp", FALSE); |
3267 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); | |
3268 | |
7827 | 3269 option = gaim_account_option_string_new(_("Pager host"), "server", YAHOO_PAGER_HOST); |
3270 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); | |
3271 | |
9164 | 3272 option = gaim_account_option_string_new(_("Japan Pager host"), "serverjp", YAHOOJP_PAGER_HOST); |
3273 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); | |
3274 | |
7827 | 3275 option = gaim_account_option_int_new(_("Pager port"), "port", YAHOO_PAGER_PORT); |
3276 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); | |
7651 | 3277 |
3278 option = gaim_account_option_string_new(_("File transfer host"), "xfer_host", YAHOO_XFER_HOST); | |
3279 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); | |
3280 | |
9164 | 3281 option = gaim_account_option_string_new(_("Japan File transfer host"), "xferjp_host", YAHOOJP_XFER_HOST); |
3282 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); | |
3283 | |
7651 | 3284 option = gaim_account_option_int_new(_("File transfer port"), "xfer_port", YAHOO_XFER_PORT); |
3285 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); | |
3286 | |
8113 | 3287 option = gaim_account_option_string_new(_("Chat Room List Url"), "room_list", YAHOO_ROOMLIST_URL); |
3288 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); | |
9376 | 3289 #if 0 |
3290 option = gaim_account_option_string_new(_("YCHT Host"), "ycht-server", YAHOO_YCHT_HOST); | |
3291 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); | |
3292 | |
3293 option = gaim_account_option_int_new(_("YCHT Port"), "ycht-port", YAHOO_YCHT_PORT); | |
3294 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); | |
3295 #endif | |
3296 | |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3297 my_protocol = plugin; |
10119 | 3298 yahoogaim_register_commands(); |
6513 | 3299 yahoo_init_colorht(); |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3300 } |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3301 |
5920
7d385de2f9cd
[gaim-migrate @ 6360]
Christian Hammond <chipx86@chipx86.com>
parents:
5872
diff
changeset
|
3302 GAIM_INIT_PLUGIN(yahoo, init_plugin, info); |