Mercurial > pidgin
changeset 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 | 85fc34efe733 (current diff) d11d1ac96a0d (diff) |
children | ccbded331513 |
files | COPYRIGHT libpurple/protocols/yahoo/yahoo.c |
diffstat | 5 files changed, 322 insertions(+), 36 deletions(-) [+] |
line wrap: on
line diff
--- a/COPYRIGHT Mon Jun 16 15:19:11 2008 +0000 +++ b/COPYRIGHT Tue Jun 17 21:30:49 2008 +0000 @@ -241,6 +241,7 @@ Lucio Maciel Brian Macke Paolo Maggi +Sulabh Mahajan Willian T. Mahan Kris Marsh Fidel Martinez
--- a/libpurple/protocols/yahoo/yahoo.c Mon Jun 16 15:19:11 2008 +0000 +++ b/libpurple/protocols/yahoo/yahoo.c Tue Jun 17 21:30:49 2008 +0000 @@ -215,7 +215,7 @@ if (f->status == YAHOO_STATUS_IDLE) { /* Idle may have already been set in a more precise way in case 137 */ if (f->idle == 0) - f->idle = time(NULL); + f->idle = time(NULL) - 60; /*Start idle at 1 min*/ } else f->idle = 0; @@ -246,7 +246,7 @@ if (f->away == 2) { /* Idle may have already been set in a more precise way in case 137 */ if (f->idle == 0) - f->idle = time(NULL); + f->idle = time(NULL) - 60; /*start idle at 1 min*/ } break; @@ -699,7 +699,7 @@ while (l) { struct yahoo_pair *pair = l->data; - if (pair->key == 4) + if (pair->key == 4 || pair->key == 1) from = pair->value; if (pair->key == 49) msg = pair->value; @@ -769,10 +769,11 @@ account = purple_connection_get_account(gc); - if (pkt->status <= 1 || pkt->status == 5) { + if (pkt->status <= 1 || pkt->status == 5 || pkt->status == YAHOO_STATUS_OFFLINE) { + /* messages are reveived with status YAHOO_STATUS_OFFLINE in case of p2p */ while (l != NULL) { struct yahoo_pair *pair = l->data; - if (pair->key == 4) { + if (pair->key == 4 || pair->key == 1) { im = g_new0(struct _yahoo_im, 1); list = g_slist_append(list, im); im->from = pair->value; @@ -2214,13 +2215,217 @@ g_free(decoded_group); } +/*destroy p2p_data associated with a peer and close p2p connection*/ +static void yahoo_p2p_disconnect_destroy_data(gpointer data) +{ + struct yahoo_p2p_data *user_data; + struct yahoo_data *yd; + if(!(user_data = data)) + return ; + yd = user_data->gc->proto_data; + + purple_input_remove(user_data->input_event); + close(user_data->source); + g_free(user_data->host_ip); + g_free(user_data->host_username); + g_free(user_data); +} + +/*write pkt to the source*/ +static void yahoo_p2p_write_pkt(gint source, struct yahoo_packet *pkt) +{ + size_t pkt_len; + guchar *raw_packet; + + /*build the raw packet and send it to the host*/ + pkt_len = yahoo_packet_build(pkt, 0, 0, 0, &raw_packet); + if(write(source, raw_packet, pkt_len) != pkt_len) + purple_debug_warning("yahoo","p2p: couldn't write to the source\n"); + g_free(raw_packet); +} + +/*exchange of initial p2pfilexfer packets, service type YAHOO_SERVICE_P2PFILEXFER*/ +static void yahoo_p2p_process_p2pfilexfer(gpointer data, gint source, struct yahoo_packet *pkt) +{ + struct yahoo_p2p_data *user_data; + char *who = NULL; + GSList *l = pkt->hash; + struct yahoo_packet *pkt_to_send; + PurpleAccount *account; + int val_13_to_send = 0; + + if(!(user_data = data)) + return ; + + /* lets see whats in the packet */ + while (l) { + struct yahoo_pair *pair = l->data; + + switch (pair->key) { + case 4: + who = pair->value; + if(strncmp(who, user_data->host_username, strlen(user_data->host_username)) != 0) { + /* from whom are we receiving the packets ?? */ + purple_debug_warning("yahoo","p2p: received data from wrong user\n"); + return; + } + break; + case 13: + user_data->val_13 = strtol(pair->value, NULL, 10); /*Value should be 5-7*/ + break; + /*case 5, 49 look laters, no use right now*/ + } + l = l->next; + } + + account = purple_connection_get_account(user_data->gc); + + /*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*/ + + if(user_data->val_13 != 7) + val_13_to_send = user_data->val_13 + 1; + else + val_13_to_send = user_data->val_13; /* haven't ever received values other than 0, 5, 6, 7*/ + + /*Build the yahoo packet*/ + pkt_to_send = yahoo_packet_new(YAHOO_SERVICE_P2PFILEXFER, YAHOO_STATUS_AVAILABLE, user_data->session_id); + yahoo_packet_hash(pkt_to_send, "ssisi", + 4, purple_normalize(account, purple_account_get_username(account)), + 5, user_data->host_username, + 241, 0, /*Protocol identifier*/ + 49, "PEERTOPEER", + 13, val_13_to_send); + + /*build the raw packet and send it to the host*/ + yahoo_p2p_write_pkt(source, pkt_to_send); + yahoo_packet_free(pkt_to_send); + +} + +/*callback function associated with receiving of data on the source, not considering receipt of multiple YMSG packets in a single TCP packet*/ +static void yahoo_p2p_read_pkt_cb(gpointer data, gint source, PurpleInputCondition cond) +{ + guchar buf[1024]; /*is it safe to assume a fixed array length of 1024 ??*/ + int len; + int pos = 0; + int pktlen; + struct yahoo_packet *pkt; + guchar *start = NULL; + struct yahoo_p2p_data *user_data; + struct yahoo_data *yd; + + if(!(user_data = data)) + return ; + yd = user_data->gc->proto_data; + + len = read(source, buf, sizeof(buf)); + + if ((len < 0) && ((errno == EAGAIN) || (errno == EWOULDBLOCK))) + return ; /* No Worries*/ + + else if (len <= 0) + { + purple_debug_warning("yahoo","p2p: Error in connection, or host disconnected\n"); + /*remove from p2p connection lists, also calls yahoo_p2p_disconnect_destroy_data*/ + g_hash_table_remove(yd->peers,user_data->host_username); + return; + } + + if(len < YAHOO_PACKET_HDRLEN) + return; + + if(strncmp((char *)buf, "YMSG", MIN(4, len)) != 0) { + /* Not a YMSG packet */ + purple_debug_warning("yahoo","p2p: Got something other than YMSG packet\n"); + + start = memchr(buf + 1, 'Y', len - 1); + if(start) { + g_memmove(buf, start, len - (start - buf)); + len -= start - buf; + } else { + g_free(buf); + return; + } + } + + pos += 4; /* YMSG */ + pos += 2; + pos += 2; + + pktlen = yahoo_get16(buf + pos); pos += 2; + purple_debug(PURPLE_DEBUG_MISC, "yahoo", "p2p: %d bytes to read\n", len); + + pkt = yahoo_packet_new(0, 0, 0); + pkt->service = yahoo_get16(buf + pos); pos += 2; + pkt->status = yahoo_get32(buf + pos); pos += 4; + pkt->id = yahoo_get32(buf + pos); pos += 4; + + purple_debug(PURPLE_DEBUG_MISC, "yahoo", "p2p: Yahoo Service: 0x%02x Status: %d\n",pkt->service, pkt->status); + yahoo_packet_read(pkt, buf + pos, pktlen); + + /*packet processing*/ + switch(pkt->service) { + case YAHOO_SERVICE_P2PFILEXFER: + yahoo_p2p_process_p2pfilexfer(data, source, pkt); + break; + case YAHOO_SERVICE_MESSAGE: + yahoo_process_message(user_data->gc, pkt); + break; + case YAHOO_SERVICE_NOTIFY: + yahoo_process_notify(user_data->gc, pkt); + break; + default: + purple_debug_warning("yahoo","p2p: p2p service %d Unhandled\n",pkt->service); + } + + yahoo_packet_free(pkt); +} + +/*function called when connection to p2p host is setup*/ +static void yahoo_p2p_init_cb(gpointer data, gint source, const gchar *error_message) +{ + struct yahoo_p2p_data *user_data; + struct yahoo_packet *pkt_to_send; + PurpleAccount *account; + + if(error_message != NULL) { + purple_debug_warning("yahoo","p2p: %s\n",error_message); + return; + } + if(!(user_data = data)) + return ; + + /*Add an Input Read event to the file descriptor*/ + user_data->input_event = purple_input_add(source, PURPLE_INPUT_READ, yahoo_p2p_read_pkt_cb, data); + user_data->source = source; + + account = purple_connection_get_account(user_data->gc); + + /*Build the yahoo packet*/ + pkt_to_send = yahoo_packet_new(YAHOO_SERVICE_P2PFILEXFER, YAHOO_STATUS_AVAILABLE, user_data->session_id); + yahoo_packet_hash(pkt_to_send, "ssisi", + 4, purple_normalize(account, purple_account_get_username(account)), + 5, user_data->host_username, + 241, 0, /*Protocol identifier*/ + 49, "PEERTOPEER", + 13, 1); /*we receive key13=0, we send key13=1*/ + + yahoo_p2p_write_pkt(source, pkt_to_send); /*build raw packet and send*/ + yahoo_packet_free(pkt_to_send); +} + static void yahoo_process_p2p(PurpleConnection *gc, struct yahoo_packet *pkt) { + struct yahoo_data *yd = gc->proto_data; GSList *l = pkt->hash; char *who = NULL; char *base64 = NULL; guchar *decoded; gsize len; + gint val_13 = 0; + gint val_11; + PurpleAccount *account; + struct yahoo_p2p_data *user_data = g_new0(struct yahoo_p2p_data, 1); while (l) { struct yahoo_pair *pair = l->data; @@ -2230,7 +2435,9 @@ /* our identity */ break; case 4: - who = pair->value; + who = (char *)g_malloc(strlen(pair->value)); + strcpy(who, pair->value); + user_data->host_username = who; break; case 1: /* who again, the master identity this time? */ @@ -2240,14 +2447,21 @@ /* so, this is an ip address. in base64. decoded it's in ascii. after strtol, it's in reversed byte order. Who thought this up?*/ break; + case 13: + val_13 = strtol(pair->value, NULL, 10); /*Value always 0*/ + user_data->val_13 = val_13; + break; + case 11: + val_11 = strtol(pair->value, NULL, 10); /*sent with IMs and notifications over p2p*/ + user_data->val_11 = val_11; + break; /* TODO: figure these out yahoo: Key: 61 Value: 0 yahoo: Key: 2 Value: - yahoo: Key: 13 Value: 0 + yahoo: Key: 13 Value: 0 packet count ?? yahoo: Key: 49 Value: PEERTOPEER yahoo: Key: 140 Value: 1 - yahoo: Key: 11 Value: -1786225828 */ } @@ -2259,6 +2473,7 @@ guint32 ip; char *tmp2; YahooFriend *f; + char *host_ip; decoded = purple_base64_decode(base64, &len); if (len) { @@ -2271,12 +2486,25 @@ ip = strtol(tmp2, NULL, 10); g_free(tmp2); g_free(decoded); - tmp2 = g_strdup_printf("%u.%u.%u.%u", ip & 0xff, (ip >> 8) & 0xff, (ip >> 16) & 0xff, + host_ip = g_strdup_printf("%u.%u.%u.%u", ip & 0xff, (ip >> 8) & 0xff, (ip >> 16) & 0xff, (ip >> 24) & 0xff); f = yahoo_friend_find(gc, who); if (f) - yahoo_friend_set_ip(f, tmp2); - g_free(tmp2); + yahoo_friend_set_ip(f, host_ip); + purple_debug_info("yahoo", "IP : %s\n", host_ip); + + account = purple_connection_get_account(gc); + + user_data->host_ip = host_ip; + user_data->session_id = pkt->id; + user_data->gc = gc; + + g_hash_table_insert(yd->peers, g_strdup(who), user_data); + + /*connect to host*/ + if((purple_proxy_connect(NULL, account, host_ip, YAHOO_PAGER_PORT_P2P, yahoo_p2p_init_cb, user_data))==NULL) + purple_debug_info("yahoo","p2p: Connection to %s failed\n", host_ip); + } } @@ -2993,6 +3221,7 @@ yd->friends = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, yahoo_friend_free); yd->imvironments = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); yd->xfer_peer_idstring_map = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, NULL); + yd->peers = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, yahoo_p2p_disconnect_destroy_data); yd->confs = NULL; yd->conf_id = 2; @@ -3060,6 +3289,7 @@ g_hash_table_destroy(yd->friends); g_hash_table_destroy(yd->imvironments); g_hash_table_destroy(yd->xfer_peer_idstring_map); + g_hash_table_destroy(yd->peers); g_free(yd->chat_name); g_free(yd->cookie_y); @@ -3480,11 +3710,13 @@ static void yahoo_get_inbox_token_cb(PurpleUtilFetchUrlData *url_data, gpointer user_data, - const gchar *token, size_t len, const gchar *error_message) + const gchar *webdata, size_t len, const gchar *error_message) { PurpleConnection *gc = user_data; gboolean set_cookie = FALSE; gchar *url; + gchar *token = NULL; + int token_size; struct yahoo_data *yd = gc->proto_data; g_return_if_fail(PURPLE_CONNECTION_IS_VALID(gc)); @@ -3493,8 +3725,14 @@ if (error_message != NULL) purple_debug_error("yahoo", "Requesting mail login token failed: %s\n", error_message); - else if (len > 0 && token && *token) { - /* Should we not be hardcoding the rd url? */ + else if (len > 0 && webdata && *webdata) { + /*Extract token from the chunked webdata*/ + sscanf(webdata,"%x",&token_size); + token = g_malloc(token_size); + strncpy(token, strstr(webdata,"\r\n")+2, token_size); + token[token_size-1]='\0'; + + /* Should we not be hardcoding the rd url? */ url = g_strdup_printf( "http://login.yahoo.com/config/reset_cookies_token?" ".token=%s" @@ -3512,6 +3750,7 @@ purple_notify_uri(gc, url); g_free(url); + g_free(token); } @@ -3526,12 +3765,13 @@ PurpleUtilFetchUrlData *url_data; const char* base_url = "http://login.yahoo.com"; char *request = g_strdup_printf( - "POST /config/cookie_token HTTP/1.0\r\n" - "Cookie: T=%s; path=/; domain=.yahoo.com; Y=%s;\r\n" + "POST /config/cookie_token HTTP/1.1\r\n" + "Cookie: Y=%s; path=/; domain=.yahoo.com; T=%s; path=/; domain=.yahoo.com;\r\n" "User-Agent: Mozilla/4.0 (compatible; MSIE 5.5)\r\n" "Host: login.yahoo.com\r\n" - "Content-Length: 0\r\n\r\n", - yd->cookie_t, yd->cookie_y); + "Content-Length: 0\r\n" + "Cache-Control: no-cache\r\n\r\n", + yd->cookie_y, yd->cookie_t); gboolean use_whole_url = FALSE; /* use whole URL if using HTTP Proxy */ @@ -3608,6 +3848,7 @@ PurpleWhiteboard *wb; int ret = 1; YahooFriend *f = NULL; + struct yahoo_p2p_data *user_data; msg2 = yahoo_string_encode(gc, msg, &utf8); @@ -3652,8 +3893,15 @@ yahoo_packet_hash_str(pkt, 206, "2"); /* We may need to not send any packets over 2000 bytes, but I'm not sure yet. */ - if ((YAHOO_PACKET_HDRLEN + yahoo_packet_length(pkt)) <= 2000) - yahoo_packet_send(pkt, yd); + if ((YAHOO_PACKET_HDRLEN + yahoo_packet_length(pkt)) <= 2000) { + /*if p2p link exists, send through it. To-do: key 15, time value to be sent in case of p2p*/ + if( (user_data = g_hash_table_lookup(yd->peers, who)) ) { + yahoo_packet_hash_int(pkt, 11, user_data->val_11); + yahoo_p2p_write_pkt(user_data->source, pkt); + } + else + yahoo_packet_send(pkt, yd); + } else ret = -E2BIG; @@ -3668,12 +3916,24 @@ static unsigned int yahoo_send_typing(PurpleConnection *gc, const char *who, PurpleTypingState state) { struct yahoo_data *yd = gc->proto_data; + struct yahoo_p2p_data *user_data; + struct yahoo_packet *pkt = yahoo_packet_new(YAHOO_SERVICE_NOTIFY, YAHOO_STATUS_TYPING, 0); - yahoo_packet_hash(pkt, "ssssss", 49, "TYPING", 1, purple_connection_get_display_name(gc), + + /*check to see if p2p link exists, send through it*/ + if( (user_data = g_hash_table_lookup(yd->peers, who)) ) { + yahoo_packet_hash(pkt, "sssssis", 49, "TYPING", 1, purple_connection_get_display_name(gc), + 14, " ", 13, state == PURPLE_TYPING ? "1" : "0", + 5, who, 11, user_data->val_11, 1002, "1"); /*To-do: key 15 to be sent in case of p2p*/ + yahoo_p2p_write_pkt(user_data->source, pkt); + yahoo_packet_free(pkt); + } + else { /*send through yahoo server*/ + yahoo_packet_hash(pkt, "ssssss", 49, "TYPING", 1, purple_connection_get_display_name(gc), 14, " ", 13, state == PURPLE_TYPING ? "1" : "0", 5, who, 1002, "1"); - - yahoo_packet_send_and_free(pkt, yd); + yahoo_packet_send_and_free(pkt, yd); + } return 0; }
--- a/libpurple/protocols/yahoo/yahoo.h Mon Jun 16 15:19:11 2008 +0000 +++ b/libpurple/protocols/yahoo/yahoo.h Tue Jun 17 21:30:49 2008 +0000 @@ -30,6 +30,7 @@ #define YAHOO_PAGER_HOST "scs.msg.yahoo.com" #define YAHOO_PAGER_PORT 5050 +#define YAHOO_PAGER_PORT_P2P 5101 #define YAHOO_PROFILE_URL "http://profiles.yahoo.com/" #define YAHOO_MAIL_URL "https://login.yahoo.com/config/login?.src=ym" #define YAHOO_XFER_HOST "filetransfer.msg.yahoo.com" @@ -113,6 +114,17 @@ guint watcher; }; +struct yahoo_p2p_data { + PurpleConnection *gc; + char *host_ip; + int session_id; + char *host_username; + int val_13; + guint input_event; + gint source; + int val_11; +}; + struct _YchtConn; struct yahoo_data { @@ -176,6 +188,7 @@ * the server expects us to keep track of the group for which it is sending us contact names. */ char *current_list15_grp; + GHashTable *peers; /*information about p2p data*/ }; #define YAHOO_MAX_STATUS_MESSAGE_LENGTH (255)
--- a/libpurple/protocols/yahoo/yahoo_filexfer.c Mon Jun 16 15:19:11 2008 +0000 +++ b/libpurple/protocols/yahoo/yahoo_filexfer.c Tue Jun 17 21:30:49 2008 +0000 @@ -1213,21 +1213,35 @@ } else if(purple_xfer_get_type(xfer) == PURPLE_XFER_RECEIVE && xd->status_15 == STARTED) { - xd->txbuf = g_strdup_printf("HEAD /relay?token=%s&sender=%s&recver=%s HTTP/1.1\r\nAccept:*/*\r\nCookie:%s\r\nUser-Agent: Mozilla/4.0 (compatible; MSIE 5.5)\r\nHost:%s\r\nContent-Length: 0\r\nCache-Control: no-cache\r\n\r\n", + if(xd->info_val_249 == 1) /*receiving file via p2p, if xd->info_val_249 is 1*/ + { + xd->txbuf = g_strdup_printf("HEAD /%s HTTP/1.1\r\nAccept:*/*\r\nUser-Agent: Mozilla/4.0 (compatible; MSIE 5.5)\r\nHost: %s\r\nContent-Length: 0\r\nCache-Control: no-cache\r\n\r\n",xd->path,xd->host); + } + else /*receiving file via relaying*/ + { + xd->txbuf = g_strdup_printf("HEAD /relay?token=%s&sender=%s&recver=%s HTTP/1.1\r\nAccept:*/*\r\nCookie:%s\r\nUser-Agent: Mozilla/4.0 (compatible; MSIE 5.5)\r\nHost:%s\r\nContent-Length: 0\r\nCache-Control: no-cache\r\n\r\n", purple_url_encode(xd->xfer_idstring_for_relay), purple_normalize(account, purple_account_get_username(account)), xfer->who, cookies, xd->host); + } } else if(purple_xfer_get_type(xfer) == PURPLE_XFER_RECEIVE && xd->status_15 == HEAD_REPLY_RECEIVED) { - xd->txbuf = g_strdup_printf("GET /relay?token=%s&sender=%s&recver=%s HTTP/1.1\r\nCookie:%s\r\nUser-Agent: Mozilla/4.0 (compatible; MSIE 5.5)\r\nHost:%s\r\nConnection: Keep-Alive\r\n\r\n", + if(xd->info_val_249 == 1) /*receiving file via p2p*/ + { + xd->txbuf = g_strdup_printf("GET /%s HTTP/1.1\r\nUser-Agent: Mozilla/4.0 (compatible; MSIE 5.5)\r\nHost: %s\r\nConnection: Keep-Alive\r\n\r\n",xd->path,xd->host); + } + else /*receiving file via relaying*/ + { + xd->txbuf = g_strdup_printf("GET /relay?token=%s&sender=%s&recver=%s HTTP/1.1\r\nCookie:%s\r\nUser-Agent: Mozilla/4.0 (compatible; MSIE 5.5)\r\nHost:%s\r\nConnection: Keep-Alive\r\n\r\n", purple_url_encode(xd->xfer_idstring_for_relay), purple_normalize(account, purple_account_get_username(account)), xfer->who, cookies, xd->host); + } } else { @@ -1455,13 +1469,8 @@ val_66 = strtol(pair->value, NULL, 10); break; case 249: - val_249 = strtol(pair->value, NULL, 10); /* - * really pissed off with this- i hv seen 2 occurences of this - * being 1(its normally 3) - and in those cases, the url - * format and corresponding processing seems to be different - * (i havent tested - couldnt reproduce a 1), although i - * guess its easier. - */ + val_249 = strtol(pair->value, NULL, 10); + /* 249 has value 1 when doing p2p transfer and value 3 when relaying through yahoo server */ break; case 250: url = pair->value;
--- a/libpurple/protocols/yahoo/yahoo_packet.h Mon Jun 16 15:19:11 2008 +0000 +++ b/libpurple/protocols/yahoo/yahoo_packet.h Tue Jun 17 21:30:49 2008 +0000 @@ -76,7 +76,7 @@ YAHOO_SERVICE_IGNORECONTACT, /* > 1, 7, 13 < 1, 66, 13, 0*/ YAHOO_SERVICE_REJECTCONTACT, YAHOO_SERVICE_GROUPRENAME = 0x89, /* > 1, 65(new), 66(0), 67(old) */ - /* YAHOO_SERVICE_??? = 0x8A, */ + /* YAHOO_SERVICE_??? = 0x8A,some sort of keep alive sent to the server every 60 secs */ YAHOO_SERVICE_CHATONLINE = 0x96, /* > 109(id), 1, 6(abcde) < 0,1*/ YAHOO_SERVICE_CHATGOTO, YAHOO_SERVICE_CHATJOIN, /* > 1 104-room 129-1600326591 62-2 */ @@ -98,15 +98,18 @@ YAHOO_SERVICE_AVATAR_UPDATE = 0xc7, YAHOO_SERVICE_VERIFY_ID_EXISTS = 0xc8, YAHOO_SERVICE_AUDIBLE = 0xd0, + /*YAHOO_SERVICE_CHAT_SESSION = 0xd4,?? Reports start of chat session, gets an id from server*/ YAHOO_SERVICE_AUTH_REQ_15 = 0xd6, + YAHOO_SERVICE_FILETRANS_15 = 0xdc, + YAHOO_SERVICE_FILETRANS_INFO_15 = 0xdd, + YAHOO_SERVICE_FILETRANS_ACC_15 = 0xde, + /*photo sharing services ?? - 0xd2, 0xd7, 0xd8, 0xda*/ YAHOO_SERVICE_CHGRP_15 = 0xe7, YAHOO_SERVICE_STATUS_15 = 0xf0, YAHOO_SERVICE_LIST_15 = 0xf1, - YAHOO_SERVICE_FILETRANS_15 = 0xdc, - YAHOO_SERVICE_FILETRANS_INFO_15 = 0xdd, - YAHOO_SERVICE_FILETRANS_ACC_15 = 0xde, YAHOO_SERVICE_WEBLOGIN = 0x0226, YAHOO_SERVICE_SMS_MSG = 0x02ea + /*YAHOO_SERVICE_DISCONNECT = 0x07d1 Server forces us to disconnect. Is sent with TCP FIN flag set*/ }; struct yahoo_pair {