Mercurial > pidgin
comparison libpurple/protocols/yahoo/yahoo.c @ 25057:f9f3d8bae136
propagate from branch 'im.pidgin.pidgin' (head 420b71541a7786d593759ead8d775f487291fb97)
to branch 'im.pidgin.soc.2008.yahoo' (head 8f3e08719ea0c16d44cf58c249b04b246ebcb908)
author | Sulabh Mahajan <sulabh@soc.pidgin.im> |
---|---|
date | Tue, 17 Jun 2008 21:30:49 +0000 |
parents | ea998456c3bd d11d1ac96a0d |
children | f16aba67b685 |
comparison
equal
deleted
inserted
replaced
23374:85fc34efe733 | 25057:f9f3d8bae136 |
---|---|
213 f->away = 0; | 213 f->away = 0; |
214 | 214 |
215 if (f->status == YAHOO_STATUS_IDLE) { | 215 if (f->status == YAHOO_STATUS_IDLE) { |
216 /* Idle may have already been set in a more precise way in case 137 */ | 216 /* Idle may have already been set in a more precise way in case 137 */ |
217 if (f->idle == 0) | 217 if (f->idle == 0) |
218 f->idle = time(NULL); | 218 f->idle = time(NULL) - 60; /*Start idle at 1 min*/ |
219 } else | 219 } else |
220 f->idle = 0; | 220 f->idle = 0; |
221 | 221 |
222 if (f->status != YAHOO_STATUS_CUSTOM) | 222 if (f->status != YAHOO_STATUS_CUSTOM) |
223 yahoo_friend_set_status_message(f, NULL); | 223 yahoo_friend_set_status_message(f, NULL); |
244 | 244 |
245 f->away = strtol(pair->value, NULL, 10); | 245 f->away = strtol(pair->value, NULL, 10); |
246 if (f->away == 2) { | 246 if (f->away == 2) { |
247 /* Idle may have already been set in a more precise way in case 137 */ | 247 /* Idle may have already been set in a more precise way in case 137 */ |
248 if (f->idle == 0) | 248 if (f->idle == 0) |
249 f->idle = time(NULL); | 249 f->idle = time(NULL) - 60; /*start idle at 1 min*/ |
250 } | 250 } |
251 | 251 |
252 break; | 252 break; |
253 case 138: /* either we're not idle, or we are but won't say how long */ | 253 case 138: /* either we're not idle, or we are but won't say how long */ |
254 if (!f) | 254 if (!f) |
697 | 697 |
698 account = purple_connection_get_account(gc); | 698 account = purple_connection_get_account(gc); |
699 | 699 |
700 while (l) { | 700 while (l) { |
701 struct yahoo_pair *pair = l->data; | 701 struct yahoo_pair *pair = l->data; |
702 if (pair->key == 4) | 702 if (pair->key == 4 || pair->key == 1) |
703 from = pair->value; | 703 from = pair->value; |
704 if (pair->key == 49) | 704 if (pair->key == 49) |
705 msg = pair->value; | 705 msg = pair->value; |
706 if (pair->key == 13) | 706 if (pair->key == 13) |
707 stat = pair->value; | 707 stat = pair->value; |
767 struct _yahoo_im *im = NULL; | 767 struct _yahoo_im *im = NULL; |
768 const char *imv = NULL; | 768 const char *imv = NULL; |
769 | 769 |
770 account = purple_connection_get_account(gc); | 770 account = purple_connection_get_account(gc); |
771 | 771 |
772 if (pkt->status <= 1 || pkt->status == 5) { | 772 if (pkt->status <= 1 || pkt->status == 5 || pkt->status == YAHOO_STATUS_OFFLINE) { |
773 /* messages are reveived with status YAHOO_STATUS_OFFLINE in case of p2p */ | |
773 while (l != NULL) { | 774 while (l != NULL) { |
774 struct yahoo_pair *pair = l->data; | 775 struct yahoo_pair *pair = l->data; |
775 if (pair->key == 4) { | 776 if (pair->key == 4 || pair->key == 1) { |
776 im = g_new0(struct _yahoo_im, 1); | 777 im = g_new0(struct _yahoo_im, 1); |
777 list = g_slist_append(list, im); | 778 list = g_slist_append(list, im); |
778 im->from = pair->value; | 779 im->from = pair->value; |
779 im->time = time(NULL); | 780 im->time = time(NULL); |
780 im->utf8 = TRUE; | 781 im->utf8 = TRUE; |
2212 purple_notify_error(gc, NULL, _("Could not add buddy to server list"), buf); | 2213 purple_notify_error(gc, NULL, _("Could not add buddy to server list"), buf); |
2213 g_free(buf); | 2214 g_free(buf); |
2214 g_free(decoded_group); | 2215 g_free(decoded_group); |
2215 } | 2216 } |
2216 | 2217 |
2218 /*destroy p2p_data associated with a peer and close p2p connection*/ | |
2219 static void yahoo_p2p_disconnect_destroy_data(gpointer data) | |
2220 { | |
2221 struct yahoo_p2p_data *user_data; | |
2222 struct yahoo_data *yd; | |
2223 if(!(user_data = data)) | |
2224 return ; | |
2225 yd = user_data->gc->proto_data; | |
2226 | |
2227 purple_input_remove(user_data->input_event); | |
2228 close(user_data->source); | |
2229 g_free(user_data->host_ip); | |
2230 g_free(user_data->host_username); | |
2231 g_free(user_data); | |
2232 } | |
2233 | |
2234 /*write pkt to the source*/ | |
2235 static void yahoo_p2p_write_pkt(gint source, struct yahoo_packet *pkt) | |
2236 { | |
2237 size_t pkt_len; | |
2238 guchar *raw_packet; | |
2239 | |
2240 /*build the raw packet and send it to the host*/ | |
2241 pkt_len = yahoo_packet_build(pkt, 0, 0, 0, &raw_packet); | |
2242 if(write(source, raw_packet, pkt_len) != pkt_len) | |
2243 purple_debug_warning("yahoo","p2p: couldn't write to the source\n"); | |
2244 g_free(raw_packet); | |
2245 } | |
2246 | |
2247 /*exchange of initial p2pfilexfer packets, service type YAHOO_SERVICE_P2PFILEXFER*/ | |
2248 static void yahoo_p2p_process_p2pfilexfer(gpointer data, gint source, struct yahoo_packet *pkt) | |
2249 { | |
2250 struct yahoo_p2p_data *user_data; | |
2251 char *who = NULL; | |
2252 GSList *l = pkt->hash; | |
2253 struct yahoo_packet *pkt_to_send; | |
2254 PurpleAccount *account; | |
2255 int val_13_to_send = 0; | |
2256 | |
2257 if(!(user_data = data)) | |
2258 return ; | |
2259 | |
2260 /* lets see whats in the packet */ | |
2261 while (l) { | |
2262 struct yahoo_pair *pair = l->data; | |
2263 | |
2264 switch (pair->key) { | |
2265 case 4: | |
2266 who = pair->value; | |
2267 if(strncmp(who, user_data->host_username, strlen(user_data->host_username)) != 0) { | |
2268 /* from whom are we receiving the packets ?? */ | |
2269 purple_debug_warning("yahoo","p2p: received data from wrong user\n"); | |
2270 return; | |
2271 } | |
2272 break; | |
2273 case 13: | |
2274 user_data->val_13 = strtol(pair->value, NULL, 10); /*Value should be 5-7*/ | |
2275 break; | |
2276 /*case 5, 49 look laters, no use right now*/ | |
2277 } | |
2278 l = l->next; | |
2279 } | |
2280 | |
2281 account = purple_connection_get_account(user_data->gc); | |
2282 | |
2283 /*key_13 appears to be a sort of a counter,yahoo server sends with val_13=0, we send packet to host with val_13=1, receive back with val_13=5, we send with val_13=6, receive back with val_13=7, we send with val_13=7, then break the connection. So we keep the value for 7 and increment for not 7*/ | |
2284 | |
2285 if(user_data->val_13 != 7) | |
2286 val_13_to_send = user_data->val_13 + 1; | |
2287 else | |
2288 val_13_to_send = user_data->val_13; /* haven't ever received values other than 0, 5, 6, 7*/ | |
2289 | |
2290 /*Build the yahoo packet*/ | |
2291 pkt_to_send = yahoo_packet_new(YAHOO_SERVICE_P2PFILEXFER, YAHOO_STATUS_AVAILABLE, user_data->session_id); | |
2292 yahoo_packet_hash(pkt_to_send, "ssisi", | |
2293 4, purple_normalize(account, purple_account_get_username(account)), | |
2294 5, user_data->host_username, | |
2295 241, 0, /*Protocol identifier*/ | |
2296 49, "PEERTOPEER", | |
2297 13, val_13_to_send); | |
2298 | |
2299 /*build the raw packet and send it to the host*/ | |
2300 yahoo_p2p_write_pkt(source, pkt_to_send); | |
2301 yahoo_packet_free(pkt_to_send); | |
2302 | |
2303 } | |
2304 | |
2305 /*callback function associated with receiving of data on the source, not considering receipt of multiple YMSG packets in a single TCP packet*/ | |
2306 static void yahoo_p2p_read_pkt_cb(gpointer data, gint source, PurpleInputCondition cond) | |
2307 { | |
2308 guchar buf[1024]; /*is it safe to assume a fixed array length of 1024 ??*/ | |
2309 int len; | |
2310 int pos = 0; | |
2311 int pktlen; | |
2312 struct yahoo_packet *pkt; | |
2313 guchar *start = NULL; | |
2314 struct yahoo_p2p_data *user_data; | |
2315 struct yahoo_data *yd; | |
2316 | |
2317 if(!(user_data = data)) | |
2318 return ; | |
2319 yd = user_data->gc->proto_data; | |
2320 | |
2321 len = read(source, buf, sizeof(buf)); | |
2322 | |
2323 if ((len < 0) && ((errno == EAGAIN) || (errno == EWOULDBLOCK))) | |
2324 return ; /* No Worries*/ | |
2325 | |
2326 else if (len <= 0) | |
2327 { | |
2328 purple_debug_warning("yahoo","p2p: Error in connection, or host disconnected\n"); | |
2329 /*remove from p2p connection lists, also calls yahoo_p2p_disconnect_destroy_data*/ | |
2330 g_hash_table_remove(yd->peers,user_data->host_username); | |
2331 return; | |
2332 } | |
2333 | |
2334 if(len < YAHOO_PACKET_HDRLEN) | |
2335 return; | |
2336 | |
2337 if(strncmp((char *)buf, "YMSG", MIN(4, len)) != 0) { | |
2338 /* Not a YMSG packet */ | |
2339 purple_debug_warning("yahoo","p2p: Got something other than YMSG packet\n"); | |
2340 | |
2341 start = memchr(buf + 1, 'Y', len - 1); | |
2342 if(start) { | |
2343 g_memmove(buf, start, len - (start - buf)); | |
2344 len -= start - buf; | |
2345 } else { | |
2346 g_free(buf); | |
2347 return; | |
2348 } | |
2349 } | |
2350 | |
2351 pos += 4; /* YMSG */ | |
2352 pos += 2; | |
2353 pos += 2; | |
2354 | |
2355 pktlen = yahoo_get16(buf + pos); pos += 2; | |
2356 purple_debug(PURPLE_DEBUG_MISC, "yahoo", "p2p: %d bytes to read\n", len); | |
2357 | |
2358 pkt = yahoo_packet_new(0, 0, 0); | |
2359 pkt->service = yahoo_get16(buf + pos); pos += 2; | |
2360 pkt->status = yahoo_get32(buf + pos); pos += 4; | |
2361 pkt->id = yahoo_get32(buf + pos); pos += 4; | |
2362 | |
2363 purple_debug(PURPLE_DEBUG_MISC, "yahoo", "p2p: Yahoo Service: 0x%02x Status: %d\n",pkt->service, pkt->status); | |
2364 yahoo_packet_read(pkt, buf + pos, pktlen); | |
2365 | |
2366 /*packet processing*/ | |
2367 switch(pkt->service) { | |
2368 case YAHOO_SERVICE_P2PFILEXFER: | |
2369 yahoo_p2p_process_p2pfilexfer(data, source, pkt); | |
2370 break; | |
2371 case YAHOO_SERVICE_MESSAGE: | |
2372 yahoo_process_message(user_data->gc, pkt); | |
2373 break; | |
2374 case YAHOO_SERVICE_NOTIFY: | |
2375 yahoo_process_notify(user_data->gc, pkt); | |
2376 break; | |
2377 default: | |
2378 purple_debug_warning("yahoo","p2p: p2p service %d Unhandled\n",pkt->service); | |
2379 } | |
2380 | |
2381 yahoo_packet_free(pkt); | |
2382 } | |
2383 | |
2384 /*function called when connection to p2p host is setup*/ | |
2385 static void yahoo_p2p_init_cb(gpointer data, gint source, const gchar *error_message) | |
2386 { | |
2387 struct yahoo_p2p_data *user_data; | |
2388 struct yahoo_packet *pkt_to_send; | |
2389 PurpleAccount *account; | |
2390 | |
2391 if(error_message != NULL) { | |
2392 purple_debug_warning("yahoo","p2p: %s\n",error_message); | |
2393 return; | |
2394 } | |
2395 if(!(user_data = data)) | |
2396 return ; | |
2397 | |
2398 /*Add an Input Read event to the file descriptor*/ | |
2399 user_data->input_event = purple_input_add(source, PURPLE_INPUT_READ, yahoo_p2p_read_pkt_cb, data); | |
2400 user_data->source = source; | |
2401 | |
2402 account = purple_connection_get_account(user_data->gc); | |
2403 | |
2404 /*Build the yahoo packet*/ | |
2405 pkt_to_send = yahoo_packet_new(YAHOO_SERVICE_P2PFILEXFER, YAHOO_STATUS_AVAILABLE, user_data->session_id); | |
2406 yahoo_packet_hash(pkt_to_send, "ssisi", | |
2407 4, purple_normalize(account, purple_account_get_username(account)), | |
2408 5, user_data->host_username, | |
2409 241, 0, /*Protocol identifier*/ | |
2410 49, "PEERTOPEER", | |
2411 13, 1); /*we receive key13=0, we send key13=1*/ | |
2412 | |
2413 yahoo_p2p_write_pkt(source, pkt_to_send); /*build raw packet and send*/ | |
2414 yahoo_packet_free(pkt_to_send); | |
2415 } | |
2416 | |
2217 static void yahoo_process_p2p(PurpleConnection *gc, struct yahoo_packet *pkt) | 2417 static void yahoo_process_p2p(PurpleConnection *gc, struct yahoo_packet *pkt) |
2218 { | 2418 { |
2419 struct yahoo_data *yd = gc->proto_data; | |
2219 GSList *l = pkt->hash; | 2420 GSList *l = pkt->hash; |
2220 char *who = NULL; | 2421 char *who = NULL; |
2221 char *base64 = NULL; | 2422 char *base64 = NULL; |
2222 guchar *decoded; | 2423 guchar *decoded; |
2223 gsize len; | 2424 gsize len; |
2425 gint val_13 = 0; | |
2426 gint val_11; | |
2427 PurpleAccount *account; | |
2428 struct yahoo_p2p_data *user_data = g_new0(struct yahoo_p2p_data, 1); | |
2224 | 2429 |
2225 while (l) { | 2430 while (l) { |
2226 struct yahoo_pair *pair = l->data; | 2431 struct yahoo_pair *pair = l->data; |
2227 | 2432 |
2228 switch (pair->key) { | 2433 switch (pair->key) { |
2229 case 5: | 2434 case 5: |
2230 /* our identity */ | 2435 /* our identity */ |
2231 break; | 2436 break; |
2232 case 4: | 2437 case 4: |
2233 who = pair->value; | 2438 who = (char *)g_malloc(strlen(pair->value)); |
2439 strcpy(who, pair->value); | |
2440 user_data->host_username = who; | |
2234 break; | 2441 break; |
2235 case 1: | 2442 case 1: |
2236 /* who again, the master identity this time? */ | 2443 /* who again, the master identity this time? */ |
2237 break; | 2444 break; |
2238 case 12: | 2445 case 12: |
2239 base64 = pair->value; | 2446 base64 = pair->value; |
2240 /* so, this is an ip address. in base64. decoded it's in ascii. | 2447 /* so, this is an ip address. in base64. decoded it's in ascii. |
2241 after strtol, it's in reversed byte order. Who thought this up?*/ | 2448 after strtol, it's in reversed byte order. Who thought this up?*/ |
2242 break; | 2449 break; |
2450 case 13: | |
2451 val_13 = strtol(pair->value, NULL, 10); /*Value always 0*/ | |
2452 user_data->val_13 = val_13; | |
2453 break; | |
2454 case 11: | |
2455 val_11 = strtol(pair->value, NULL, 10); /*sent with IMs and notifications over p2p*/ | |
2456 user_data->val_11 = val_11; | |
2457 break; | |
2243 /* | 2458 /* |
2244 TODO: figure these out | 2459 TODO: figure these out |
2245 yahoo: Key: 61 Value: 0 | 2460 yahoo: Key: 61 Value: 0 |
2246 yahoo: Key: 2 Value: | 2461 yahoo: Key: 2 Value: |
2247 yahoo: Key: 13 Value: 0 | 2462 yahoo: Key: 13 Value: 0 packet count ?? |
2248 yahoo: Key: 49 Value: PEERTOPEER | 2463 yahoo: Key: 49 Value: PEERTOPEER |
2249 yahoo: Key: 140 Value: 1 | 2464 yahoo: Key: 140 Value: 1 |
2250 yahoo: Key: 11 Value: -1786225828 | |
2251 */ | 2465 */ |
2252 | 2466 |
2253 } | 2467 } |
2254 | 2468 |
2255 l = l->next; | 2469 l = l->next; |
2257 | 2471 |
2258 if (base64) { | 2472 if (base64) { |
2259 guint32 ip; | 2473 guint32 ip; |
2260 char *tmp2; | 2474 char *tmp2; |
2261 YahooFriend *f; | 2475 YahooFriend *f; |
2476 char *host_ip; | |
2262 | 2477 |
2263 decoded = purple_base64_decode(base64, &len); | 2478 decoded = purple_base64_decode(base64, &len); |
2264 if (len) { | 2479 if (len) { |
2265 char *tmp = purple_str_binary_to_ascii(decoded, len); | 2480 char *tmp = purple_str_binary_to_ascii(decoded, len); |
2266 purple_debug_info("yahoo", "Got P2P service packet (from server): who = %s, ip = %s\n", who, tmp); | 2481 purple_debug_info("yahoo", "Got P2P service packet (from server): who = %s, ip = %s\n", who, tmp); |
2269 | 2484 |
2270 tmp2 = g_strndup((const gchar *)decoded, len); /* so its \0 terminated...*/ | 2485 tmp2 = g_strndup((const gchar *)decoded, len); /* so its \0 terminated...*/ |
2271 ip = strtol(tmp2, NULL, 10); | 2486 ip = strtol(tmp2, NULL, 10); |
2272 g_free(tmp2); | 2487 g_free(tmp2); |
2273 g_free(decoded); | 2488 g_free(decoded); |
2274 tmp2 = g_strdup_printf("%u.%u.%u.%u", ip & 0xff, (ip >> 8) & 0xff, (ip >> 16) & 0xff, | 2489 host_ip = g_strdup_printf("%u.%u.%u.%u", ip & 0xff, (ip >> 8) & 0xff, (ip >> 16) & 0xff, |
2275 (ip >> 24) & 0xff); | 2490 (ip >> 24) & 0xff); |
2276 f = yahoo_friend_find(gc, who); | 2491 f = yahoo_friend_find(gc, who); |
2277 if (f) | 2492 if (f) |
2278 yahoo_friend_set_ip(f, tmp2); | 2493 yahoo_friend_set_ip(f, host_ip); |
2279 g_free(tmp2); | 2494 purple_debug_info("yahoo", "IP : %s\n", host_ip); |
2495 | |
2496 account = purple_connection_get_account(gc); | |
2497 | |
2498 user_data->host_ip = host_ip; | |
2499 user_data->session_id = pkt->id; | |
2500 user_data->gc = gc; | |
2501 | |
2502 g_hash_table_insert(yd->peers, g_strdup(who), user_data); | |
2503 | |
2504 /*connect to host*/ | |
2505 if((purple_proxy_connect(NULL, account, host_ip, YAHOO_PAGER_PORT_P2P, yahoo_p2p_init_cb, user_data))==NULL) | |
2506 purple_debug_info("yahoo","p2p: Connection to %s failed\n", host_ip); | |
2507 | |
2280 } | 2508 } |
2281 } | 2509 } |
2282 | 2510 |
2283 static void yahoo_process_audible(PurpleConnection *gc, struct yahoo_packet *pkt) | 2511 static void yahoo_process_audible(PurpleConnection *gc, struct yahoo_packet *pkt) |
2284 { | 2512 { |
2991 /* TODO: Is there a good grow size for the buffer? */ | 3219 /* TODO: Is there a good grow size for the buffer? */ |
2992 yd->txbuf = purple_circ_buffer_new(0); | 3220 yd->txbuf = purple_circ_buffer_new(0); |
2993 yd->friends = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, yahoo_friend_free); | 3221 yd->friends = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, yahoo_friend_free); |
2994 yd->imvironments = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); | 3222 yd->imvironments = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); |
2995 yd->xfer_peer_idstring_map = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, NULL); | 3223 yd->xfer_peer_idstring_map = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, NULL); |
3224 yd->peers = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, yahoo_p2p_disconnect_destroy_data); | |
2996 yd->confs = NULL; | 3225 yd->confs = NULL; |
2997 yd->conf_id = 2; | 3226 yd->conf_id = 2; |
2998 | 3227 |
2999 yd->current_status = get_yahoo_status_from_purple_status(status); | 3228 yd->current_status = get_yahoo_status_from_purple_status(status); |
3000 | 3229 |
3058 yahoo_c_leave(gc, 1); /* 1 = YAHOO_CHAT_ID */ | 3287 yahoo_c_leave(gc, 1); /* 1 = YAHOO_CHAT_ID */ |
3059 | 3288 |
3060 g_hash_table_destroy(yd->friends); | 3289 g_hash_table_destroy(yd->friends); |
3061 g_hash_table_destroy(yd->imvironments); | 3290 g_hash_table_destroy(yd->imvironments); |
3062 g_hash_table_destroy(yd->xfer_peer_idstring_map); | 3291 g_hash_table_destroy(yd->xfer_peer_idstring_map); |
3292 g_hash_table_destroy(yd->peers); | |
3063 g_free(yd->chat_name); | 3293 g_free(yd->chat_name); |
3064 | 3294 |
3065 g_free(yd->cookie_y); | 3295 g_free(yd->cookie_y); |
3066 g_free(yd->cookie_t); | 3296 g_free(yd->cookie_t); |
3067 | 3297 |
3478 purple_connection_set_display_name(gc, entry); | 3708 purple_connection_set_display_name(gc, entry); |
3479 } | 3709 } |
3480 | 3710 |
3481 static void | 3711 static void |
3482 yahoo_get_inbox_token_cb(PurpleUtilFetchUrlData *url_data, gpointer user_data, | 3712 yahoo_get_inbox_token_cb(PurpleUtilFetchUrlData *url_data, gpointer user_data, |
3483 const gchar *token, size_t len, const gchar *error_message) | 3713 const gchar *webdata, size_t len, const gchar *error_message) |
3484 { | 3714 { |
3485 PurpleConnection *gc = user_data; | 3715 PurpleConnection *gc = user_data; |
3486 gboolean set_cookie = FALSE; | 3716 gboolean set_cookie = FALSE; |
3487 gchar *url; | 3717 gchar *url; |
3718 gchar *token = NULL; | |
3719 int token_size; | |
3488 struct yahoo_data *yd = gc->proto_data; | 3720 struct yahoo_data *yd = gc->proto_data; |
3489 | 3721 |
3490 g_return_if_fail(PURPLE_CONNECTION_IS_VALID(gc)); | 3722 g_return_if_fail(PURPLE_CONNECTION_IS_VALID(gc)); |
3491 | 3723 |
3492 yd->url_datas = g_slist_remove(yd->url_datas, url_data); | 3724 yd->url_datas = g_slist_remove(yd->url_datas, url_data); |
3493 | 3725 |
3494 if (error_message != NULL) | 3726 if (error_message != NULL) |
3495 purple_debug_error("yahoo", "Requesting mail login token failed: %s\n", error_message); | 3727 purple_debug_error("yahoo", "Requesting mail login token failed: %s\n", error_message); |
3496 else if (len > 0 && token && *token) { | 3728 else if (len > 0 && webdata && *webdata) { |
3497 /* Should we not be hardcoding the rd url? */ | 3729 /*Extract token from the chunked webdata*/ |
3730 sscanf(webdata,"%x",&token_size); | |
3731 token = g_malloc(token_size); | |
3732 strncpy(token, strstr(webdata,"\r\n")+2, token_size); | |
3733 token[token_size-1]='\0'; | |
3734 | |
3735 /* Should we not be hardcoding the rd url? */ | |
3498 url = g_strdup_printf( | 3736 url = g_strdup_printf( |
3499 "http://login.yahoo.com/config/reset_cookies_token?" | 3737 "http://login.yahoo.com/config/reset_cookies_token?" |
3500 ".token=%s" | 3738 ".token=%s" |
3501 "&.done=http://us.rd.yahoo.com/messenger/client/%%3fhttp://mail.yahoo.com/", | 3739 "&.done=http://us.rd.yahoo.com/messenger/client/%%3fhttp://mail.yahoo.com/", |
3502 token); | 3740 token); |
3510 | 3748 |
3511 /* Open the mailbox with the parsed url data */ | 3749 /* Open the mailbox with the parsed url data */ |
3512 purple_notify_uri(gc, url); | 3750 purple_notify_uri(gc, url); |
3513 | 3751 |
3514 g_free(url); | 3752 g_free(url); |
3753 g_free(token); | |
3515 } | 3754 } |
3516 | 3755 |
3517 | 3756 |
3518 static void yahoo_show_inbox(PurplePluginAction *action) | 3757 static void yahoo_show_inbox(PurplePluginAction *action) |
3519 { | 3758 { |
3524 struct yahoo_data *yd = gc->proto_data; | 3763 struct yahoo_data *yd = gc->proto_data; |
3525 | 3764 |
3526 PurpleUtilFetchUrlData *url_data; | 3765 PurpleUtilFetchUrlData *url_data; |
3527 const char* base_url = "http://login.yahoo.com"; | 3766 const char* base_url = "http://login.yahoo.com"; |
3528 char *request = g_strdup_printf( | 3767 char *request = g_strdup_printf( |
3529 "POST /config/cookie_token HTTP/1.0\r\n" | 3768 "POST /config/cookie_token HTTP/1.1\r\n" |
3530 "Cookie: T=%s; path=/; domain=.yahoo.com; Y=%s;\r\n" | 3769 "Cookie: Y=%s; path=/; domain=.yahoo.com; T=%s; path=/; domain=.yahoo.com;\r\n" |
3531 "User-Agent: Mozilla/4.0 (compatible; MSIE 5.5)\r\n" | 3770 "User-Agent: Mozilla/4.0 (compatible; MSIE 5.5)\r\n" |
3532 "Host: login.yahoo.com\r\n" | 3771 "Host: login.yahoo.com\r\n" |
3533 "Content-Length: 0\r\n\r\n", | 3772 "Content-Length: 0\r\n" |
3534 yd->cookie_t, yd->cookie_y); | 3773 "Cache-Control: no-cache\r\n\r\n", |
3774 yd->cookie_y, yd->cookie_t); | |
3535 gboolean use_whole_url = FALSE; | 3775 gboolean use_whole_url = FALSE; |
3536 | 3776 |
3537 /* use whole URL if using HTTP Proxy */ | 3777 /* use whole URL if using HTTP Proxy */ |
3538 if ((gc->account->proxy_info) && (gc->account->proxy_info->type == PURPLE_PROXY_HTTP)) | 3778 if ((gc->account->proxy_info) && (gc->account->proxy_info->type == PURPLE_PROXY_HTTP)) |
3539 use_whole_url = TRUE; | 3779 use_whole_url = TRUE; |
3606 char *msg2; | 3846 char *msg2; |
3607 gboolean utf8 = TRUE; | 3847 gboolean utf8 = TRUE; |
3608 PurpleWhiteboard *wb; | 3848 PurpleWhiteboard *wb; |
3609 int ret = 1; | 3849 int ret = 1; |
3610 YahooFriend *f = NULL; | 3850 YahooFriend *f = NULL; |
3851 struct yahoo_p2p_data *user_data; | |
3611 | 3852 |
3612 msg2 = yahoo_string_encode(gc, msg, &utf8); | 3853 msg2 = yahoo_string_encode(gc, msg, &utf8); |
3613 | 3854 |
3614 yahoo_packet_hash(pkt, "ss", 1, purple_connection_get_display_name(gc), 5, who); | 3855 yahoo_packet_hash(pkt, "ss", 1, purple_connection_get_display_name(gc), 5, who); |
3615 if ((f = yahoo_friend_find(gc, who)) && f->protocol) | 3856 if ((f = yahoo_friend_find(gc, who)) && f->protocol) |
3650 yahoo_packet_hash_str(pkt, 206, "0"); /* 0 = no picture, 2 = picture, maybe 1 = avatar? */ | 3891 yahoo_packet_hash_str(pkt, 206, "0"); /* 0 = no picture, 2 = picture, maybe 1 = avatar? */ |
3651 else | 3892 else |
3652 yahoo_packet_hash_str(pkt, 206, "2"); | 3893 yahoo_packet_hash_str(pkt, 206, "2"); |
3653 | 3894 |
3654 /* We may need to not send any packets over 2000 bytes, but I'm not sure yet. */ | 3895 /* We may need to not send any packets over 2000 bytes, but I'm not sure yet. */ |
3655 if ((YAHOO_PACKET_HDRLEN + yahoo_packet_length(pkt)) <= 2000) | 3896 if ((YAHOO_PACKET_HDRLEN + yahoo_packet_length(pkt)) <= 2000) { |
3656 yahoo_packet_send(pkt, yd); | 3897 /*if p2p link exists, send through it. To-do: key 15, time value to be sent in case of p2p*/ |
3898 if( (user_data = g_hash_table_lookup(yd->peers, who)) ) { | |
3899 yahoo_packet_hash_int(pkt, 11, user_data->val_11); | |
3900 yahoo_p2p_write_pkt(user_data->source, pkt); | |
3901 } | |
3902 else | |
3903 yahoo_packet_send(pkt, yd); | |
3904 } | |
3657 else | 3905 else |
3658 ret = -E2BIG; | 3906 ret = -E2BIG; |
3659 | 3907 |
3660 yahoo_packet_free(pkt); | 3908 yahoo_packet_free(pkt); |
3661 | 3909 |
3666 } | 3914 } |
3667 | 3915 |
3668 static unsigned int yahoo_send_typing(PurpleConnection *gc, const char *who, PurpleTypingState state) | 3916 static unsigned int yahoo_send_typing(PurpleConnection *gc, const char *who, PurpleTypingState state) |
3669 { | 3917 { |
3670 struct yahoo_data *yd = gc->proto_data; | 3918 struct yahoo_data *yd = gc->proto_data; |
3919 struct yahoo_p2p_data *user_data; | |
3920 | |
3671 struct yahoo_packet *pkt = yahoo_packet_new(YAHOO_SERVICE_NOTIFY, YAHOO_STATUS_TYPING, 0); | 3921 struct yahoo_packet *pkt = yahoo_packet_new(YAHOO_SERVICE_NOTIFY, YAHOO_STATUS_TYPING, 0); |
3672 yahoo_packet_hash(pkt, "ssssss", 49, "TYPING", 1, purple_connection_get_display_name(gc), | 3922 |
3923 /*check to see if p2p link exists, send through it*/ | |
3924 if( (user_data = g_hash_table_lookup(yd->peers, who)) ) { | |
3925 yahoo_packet_hash(pkt, "sssssis", 49, "TYPING", 1, purple_connection_get_display_name(gc), | |
3926 14, " ", 13, state == PURPLE_TYPING ? "1" : "0", | |
3927 5, who, 11, user_data->val_11, 1002, "1"); /*To-do: key 15 to be sent in case of p2p*/ | |
3928 yahoo_p2p_write_pkt(user_data->source, pkt); | |
3929 yahoo_packet_free(pkt); | |
3930 } | |
3931 else { /*send through yahoo server*/ | |
3932 yahoo_packet_hash(pkt, "ssssss", 49, "TYPING", 1, purple_connection_get_display_name(gc), | |
3673 14, " ", 13, state == PURPLE_TYPING ? "1" : "0", | 3933 14, " ", 13, state == PURPLE_TYPING ? "1" : "0", |
3674 5, who, 1002, "1"); | 3934 5, who, 1002, "1"); |
3675 | 3935 yahoo_packet_send_and_free(pkt, yd); |
3676 yahoo_packet_send_and_free(pkt, yd); | 3936 } |
3677 | 3937 |
3678 return 0; | 3938 return 0; |
3679 } | 3939 } |
3680 | 3940 |
3681 static void yahoo_session_presence_remove(gpointer key, gpointer value, gpointer data) | 3941 static void yahoo_session_presence_remove(gpointer key, gpointer value, gpointer data) |