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)