Mercurial > pidgin.yaz
changeset 26236:618d122af044
resolving conflict - merging im.pidgin.pidgin to im.pidgin.soc.2008.yahoo
author | Sulabh Mahajan <sulabh@soc.pidgin.im> |
---|---|
date | Wed, 12 Nov 2008 10:17:38 +0000 |
parents | 1317a9ae66e8 |
children | eb21f65728c0 |
files | libpurple/protocols/yahoo/yahoo.c libpurple/protocols/yahoo/yahoo.h libpurple/protocols/yahoo/yahoo_packet.h |
diffstat | 3 files changed, 114 insertions(+), 945 deletions(-) [+] |
line wrap: on
line diff
--- a/libpurple/protocols/yahoo/yahoo.c Wed Nov 12 08:19:56 2008 +0000 +++ b/libpurple/protocols/yahoo/yahoo.c Wed Nov 12 10:17:38 2008 +0000 @@ -30,7 +30,6 @@ #include "cmds.h" #include "core.h" #include "debug.h" -#include "network.h" #include "notify.h" #include "privacy.h" #include "prpl.h" @@ -39,7 +38,6 @@ #include "server.h" #include "util.h" #include "version.h" -#include "xmlnode.h" #include "yahoo.h" #include "yahoochat.h" @@ -57,6 +55,12 @@ /* #define TRY_WEBMESSENGER_LOGIN 0 */ +/* One hour */ +#define PING_TIMEOUT 3600 + +/* One minute */ +#define KEEPALIVE_TIMEOUT 60 + static void yahoo_add_buddy(PurpleConnection *gc, PurpleBuddy *, PurpleGroup *); #ifdef TRY_WEBMESSENGER_LOGIN static void yahoo_login_page_cb(PurpleUtilFetchUrlData *url_data, gpointer user_data, const gchar *url_text, size_t len, const gchar *error_message); @@ -217,7 +221,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) - 60; /* Start idle at 1 min */ + f->idle = time(NULL); } else f->idle = 0; @@ -231,8 +235,6 @@ message = pair->value; break; case 11: /* this is the buddy's session id */ - if (f) - f->session_id = strtol(pair->value, NULL, 10); break; case 17: /* in chat? */ break; @@ -250,7 +252,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) - 60; /* start idle at 1 min */ + f->idle = time(NULL); } break; @@ -519,10 +521,6 @@ purple_blist_add_buddy(b, NULL, g, NULL); } yahoo_do_group_check(account, ht, norm_bud, yd->current_list15_grp); - - /* set p2p status not connected and no p2p packet sent */ - yahoo_friend_set_p2p_status(f, YAHOO_P2PSTATUS_NOT_CONNECTED); - f->p2p_packet_sent = 0; } else { /* This buddy is on the ignore list (and therefore in no group) */ @@ -637,10 +635,6 @@ } yahoo_do_group_check(account, ht, norm_bud, grp); - /* set p2p status not connected and no p2p packet sent */ - yahoo_friend_set_p2p_status(f, YAHOO_P2PSTATUS_NOT_CONNECTED); - f->p2p_packet_sent = 0; - g_free(norm_bud); } g_strfreev(buddies); @@ -697,8 +691,7 @@ yahoo_fetch_aliases(gc); } -/* pkt_type is YAHOO_PKT_TYPE_SERVER if pkt arrives from yahoo server, YAHOO_PKT_TYPE_P2P if pkt arrives through p2p */ -static void yahoo_process_notify(PurpleConnection *gc, struct yahoo_packet *pkt, yahoo_pkt_type pkt_type) +static void yahoo_process_notify(PurpleConnection *gc, struct yahoo_packet *pkt) { PurpleAccount *account; char *msg = NULL; @@ -707,14 +700,12 @@ char *game = NULL; YahooFriend *f = NULL; GSList *l = pkt->hash; - gint val_11 = 0; - struct yahoo_data *yd = gc->proto_data; account = purple_connection_get_account(gc); while (l) { struct yahoo_pair *pair = l->data; - if (pair->key == 4 || pair->key == 1) + if (pair->key == 4) from = pair->value; if (pair->key == 49) msg = pair->value; @@ -722,22 +713,12 @@ stat = pair->value; if (pair->key == 14) game = pair->value; - if (pair->key == 11) - val_11 = strtol(pair->value, NULL, 10); l = l->next; } if (!from || !msg) return; - /* disconnect the peer if connected through p2p and sends wrong value for session id */ - if( (pkt_type == YAHOO_PKT_TYPE_P2P) && (val_11 != yd->session_id) ) { - purple_debug_warning("yahoo","p2p: %s sent us notify with wrong session id. Disconnecting p2p connection to peer\n", from); - /* remove from p2p connection lists, also calls yahoo_p2p_disconnect_destroy_data */ - g_hash_table_remove(yd->peers, from); - return; - } - if (!g_ascii_strncasecmp(msg, "TYPING", strlen("TYPING")) && (purple_privacy_check(account, from))) { @@ -774,6 +755,7 @@ } + struct _yahoo_im { char *from; int time; @@ -782,69 +764,7 @@ char *msg; }; -static void yahoo_process_sms_message(PurpleConnection *gc, struct yahoo_packet *pkt) -{ - PurpleAccount *account; - GSList *l = pkt->hash; - struct _yahoo_im *sms = NULL; - struct yahoo_data *yd; - char *server_msg = NULL; - char *m; - - yd = gc->proto_data; - account = purple_connection_get_account(gc); - - while (l != NULL) { - struct yahoo_pair *pair = l->data; - if (pair->key == 4) { - sms = g_new0(struct _yahoo_im, 1); - sms->from = g_strdup_printf("+%s", pair->value); - sms->time = time(NULL); - sms->utf8 = TRUE; - } - if (pair->key == 14) { - if (sms) - sms->msg = pair->value; - } - if (pair->key == 68) - if(sms) - g_hash_table_insert(yd->sms_carrier, g_strdup(sms->from), g_strdup(pair->value)); - if (pair->key == 16) - server_msg = pair->value; - l = l->next; - } - - if( (pkt->status == -1) || (pkt->status == YAHOO_STATUS_DISCONNECTED) ) { - if (server_msg) { - PurpleConversation *c; - c = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, sms->from, account); - if (c == NULL) - c = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, sms->from); - purple_conversation_write(c, NULL, server_msg, PURPLE_MESSAGE_SYSTEM, time(NULL)); - } - else - purple_notify_error(gc, NULL, _("Your SMS was not delivered"), NULL); - - g_free(sms->from); - g_free(sms); - return ; - } - - if (!sms->from || !sms->msg) { - g_free(sms); - return; - } - - m = yahoo_string_decode(gc, sms->msg, sms->utf8); - serv_got_im(gc, sms->from, m, 0, sms->time); - - g_free(m); - g_free(sms->from); - g_free(sms); -} - -/* pkt_type is YAHOO_PKT_TYPE_SERVER if pkt arrives from yahoo server, YAHOO_PKT_TYPE_P2P if pkt arrives through p2p */ -static void yahoo_process_message(PurpleConnection *gc, struct yahoo_packet *pkt, yahoo_pkt_type pkt_type) +static void yahoo_process_message(PurpleConnection *gc, struct yahoo_packet *pkt) { PurpleAccount *account; struct yahoo_data *yd = gc->proto_data; @@ -852,15 +772,13 @@ GSList *list = NULL; struct _yahoo_im *im = NULL; const char *imv = NULL; - gint val_11 = 0; account = purple_connection_get_account(gc); - if (pkt->status <= 1 || pkt->status == 5 || pkt->status == YAHOO_STATUS_OFFLINE) { - /* messages are reveived with status YAHOO_STATUS_OFFLINE in case of p2p */ + if (pkt->status <= 1 || pkt->status == 5) { while (l != NULL) { struct yahoo_pair *pair = l->data; - if (pair->key == 4 || pair->key == 1) { + if (pair->key == 4) { im = g_new0(struct _yahoo_im, 1); list = g_slist_append(list, im); im->from = pair->value; @@ -880,11 +798,6 @@ if (im) im->msg = pair->value; } - /* peer session id */ - if (pair->key == 11) { - if (im) - val_11 = strtol(pair->value, NULL, 10); - } /* IMV key */ if (pair->key == 63) { @@ -897,14 +810,6 @@ _("Your Yahoo! message did not get sent."), NULL); } - /* disconnect the peer if connected through p2p and sends wrong value for session id */ - if( (pkt_type == YAHOO_PKT_TYPE_P2P) && (val_11 != yd->session_id) ) { - purple_debug_warning("yahoo","p2p: %s sent us message with wrong session id. Disconnecting p2p connection to peer\n", im->from); - /* remove from p2p connection lists, also calls yahoo_p2p_disconnect_destroy_data */ - g_hash_table_remove(yd->peers, im->from); - return; - } - /** TODO: It seems that this check should be per IM, not global */ /* Check for the Doodle IMV */ if (im != NULL && imv!= NULL && im->from != NULL) @@ -972,7 +877,7 @@ c = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, im->from); username = g_markup_escape_text(im->from, -1); - serv_got_attention(gc, username, YAHOO_BUZZ); + purple_prpl_got_attention(gc, username, YAHOO_BUZZ); g_free(username); g_free(m); g_free(im); @@ -2282,8 +2187,6 @@ char *buf; YahooFriend *f; GSList *l = pkt->hash; - struct yahoo_data *yd = gc->proto_data; - int protocol = 0; while (l) { struct yahoo_pair *pair = l->data; @@ -2298,9 +2201,6 @@ case 65: group = pair->value; break; - case 241: - protocol = strtol(pair->value, NULL, 10); - break; } l = l->next; @@ -2314,16 +2214,6 @@ if (!err || (err == 2)) { /* 0 = ok, 2 = already on serv list */ f = yahoo_friend_find_or_new(gc, who); yahoo_update_status(gc, who, f); - if(protocol) - f->protocol = protocol; - - if( !g_hash_table_lookup(yd->peers, who) ) { - /* we are not connected as client, so set friend to not connected */ - yahoo_friend_set_p2p_status(f, YAHOO_P2PSTATUS_NOT_CONNECTED); - f->p2p_packet_sent = 0; - } - else /* we are already connected. set friend to YAHOO_P2PSTATUS_WE_ARE_CLIENT */ - yahoo_friend_set_p2p_status(f, YAHOO_P2PSTATUS_WE_ARE_CLIENT); return; } @@ -2336,426 +2226,6 @@ g_free(decoded_group); } -/* 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); -} - -static void yahoo_p2p_keepalive_cb(gpointer key, gpointer value, gpointer user_data) -{ - struct yahoo_p2p_data *p2p_data = value; - PurpleConnection *gc = user_data; - struct yahoo_packet *pkt_to_send; - PurpleAccount *account; - struct yahoo_data *yd = gc->proto_data; - - account = purple_connection_get_account(gc); - - pkt_to_send = yahoo_packet_new(YAHOO_SERVICE_P2PFILEXFER, YAHOO_STATUS_AVAILABLE, yd->session_id); - yahoo_packet_hash(pkt_to_send, "ssisi", - 4, purple_normalize(account, purple_account_get_username(account)), - 5, p2p_data->host_username, - 241, 0, /* Protocol identifier */ - 49, "PEERTOPEER", - 13, 7); - yahoo_p2p_write_pkt(p2p_data->source, pkt_to_send); - - yahoo_packet_free(pkt_to_send); -} - -static gboolean yahoo_p2p_keepalive(gpointer data) -{ - PurpleConnection *gc = data; - struct yahoo_data *yd = gc->proto_data; - - g_hash_table_foreach(yd->peers, yahoo_p2p_keepalive_cb, gc); - - return TRUE; -} - -/* destroy p2p_data associated with a peer and close p2p connection. - * g_hash_table_remove() calls this function to destroy p2p_data associated with the peer, - * call g_hash_table_remove() instead of this fucntion if peer has an entry in the table */ -static void yahoo_p2p_disconnect_destroy_data(gpointer data) -{ - struct yahoo_p2p_data *p2p_data; - YahooFriend *f; - - if(!(p2p_data = data)) - return ; - - /* If friend, set him not connected */ - f = yahoo_friend_find(p2p_data->gc, p2p_data->host_username); - if (f) - yahoo_friend_set_p2p_status(f, YAHOO_P2PSTATUS_NOT_CONNECTED); - - if(p2p_data->source >= 0) - close(p2p_data->source); - purple_input_remove(p2p_data->input_event); - g_free(p2p_data->host_ip); - g_free(p2p_data->host_username); - g_free(p2p_data); -} - -/* 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 *p2p_data; - char *who = NULL; - GSList *l = pkt->hash; - struct yahoo_packet *pkt_to_send; - PurpleAccount *account; - int val_13_to_send = 0; - struct yahoo_data *yd; - YahooFriend *f; - - if(!(p2p_data = data)) - return ; - - yd = p2p_data->gc->proto_data; - - /* 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, p2p_data->host_username, strlen(p2p_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: - p2p_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(p2p_data->gc); - - /* key_13: sort of a counter. - * WHEN WE ARE CLIENT: yahoo server sends val_13 = 0, we send to peer val_13 = 1, receive back val_13 = 5, - * we send val_13=6, receive val_13=7, we send val_13=7, HALT. Keep sending val_13 = 7 as keep alive. - * WHEN WE ARE SERVER: we send val_13 = 0 to yahoo server, peer sends us val_13 = 1, we send val_13 = 5, - * receive val_13 = 6, send val_13 = 7, receive val_13 = 7. HALT. Keep sending val_13 = 7 as keep alive. */ - - switch(p2p_data->val_13) { - case 1 : val_13_to_send = 5; break; - case 5 : val_13_to_send = 6; break; - case 6 : val_13_to_send = 7; break; - case 7 : if( g_hash_table_lookup(yd->peers, p2p_data->host_username) ) - return; - val_13_to_send = 7; break; - default: purple_debug_warning("yahoo","p2p:Unknown value for key 13\n"); - return; - } - - /* Build the yahoo packet */ - pkt_to_send = yahoo_packet_new(YAHOO_SERVICE_P2PFILEXFER, YAHOO_STATUS_AVAILABLE, yd->session_id); - yahoo_packet_hash(pkt_to_send, "ssisi", - 4, purple_normalize(account, purple_account_get_username(account)), - 5, p2p_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); - - if( val_13_to_send == 7 ) - if( !g_hash_table_lookup(yd->peers, p2p_data->host_username) ) { - g_hash_table_insert(yd->peers, g_strdup(p2p_data->host_username), p2p_data); - /* If the peer is a friend, set him connected */ - f = yahoo_friend_find(p2p_data->gc, p2p_data->host_username); - if (f) { - if(p2p_data->connection_type == YAHOO_P2P_WE_ARE_SERVER) { - p2p_data->session_id = f->session_id; - yahoo_friend_set_p2p_status(f, YAHOO_P2PSTATUS_WE_ARE_SERVER); - } - else - yahoo_friend_set_p2p_status(f, YAHOO_P2PSTATUS_WE_ARE_CLIENT); - } - } -} - -/* callback function associated with receiving of data, 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 *p2p_data; - struct yahoo_data *yd; - - if(!(p2p_data = data)) - return ; - yd = p2p_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 */ - if( g_hash_table_lookup(yd->peers, p2p_data->host_username) ) - g_hash_table_remove(yd->peers,p2p_data->host_username); - else - yahoo_p2p_disconnect_destroy_data(data); - 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(p2p_data->gc, pkt, YAHOO_PKT_TYPE_P2P); - break; - case YAHOO_SERVICE_NOTIFY: - yahoo_process_notify(p2p_data->gc, pkt, YAHOO_PKT_TYPE_P2P); - break; - default: - purple_debug_warning("yahoo","p2p: p2p service %d Unhandled\n",pkt->service); - } - - yahoo_packet_free(pkt); -} - -static void yahoo_p2p_server_send_connected_cb(gpointer data, gint source, PurpleInputCondition cond) -{ - int acceptfd; - struct yahoo_p2p_data *p2p_data; - struct yahoo_data *yd; - - if(!(p2p_data = data)) - return ; - yd = p2p_data->gc->proto_data; - - acceptfd = accept(source, NULL, 0); - if(acceptfd == -1 && (errno == EAGAIN || errno == EWOULDBLOCK)) - return; - else if(acceptfd == -1) { - purple_debug_warning("yahoo","yahoo_p2p_server_send_connected_cb: accept: %s\n", g_strerror(errno)); - yahoo_p2p_disconnect_destroy_data(data); - return; - } - - /* remove watcher and close p2p server */ - purple_input_remove(yd->yahoo_p2p_server_watcher); - close(yd->yahoo_local_p2p_server_fd); - yd->yahoo_local_p2p_server_fd = -1; - - /* Add an Input Read event to the file descriptor */ - p2p_data->input_event = purple_input_add(acceptfd, PURPLE_INPUT_READ, yahoo_p2p_read_pkt_cb, data); - p2p_data->source = acceptfd; -} - -static gboolean yahoo_cancel_p2p_server_listen_cb(gpointer data) -{ - struct yahoo_p2p_data *p2p_data; - struct yahoo_data *yd; - - if(!(p2p_data = data)) - return FALSE; - - yd = p2p_data->gc->proto_data; - - purple_debug_warning("yahoo","yahoo p2p server timeout, peer failed to connect"); - yahoo_p2p_disconnect_destroy_data(data); - purple_input_remove(yd->yahoo_p2p_server_watcher); - yd->yahoo_p2p_server_watcher = 0; - close(yd->yahoo_local_p2p_server_fd); - yd->yahoo_local_p2p_server_fd = -1; - yd->yahoo_p2p_server_timeout_handle = 0; - - return FALSE; -} - -static void yahoo_p2p_server_listen_cb(int listenfd, gpointer data) -{ - struct yahoo_p2p_data *p2p_data; - struct yahoo_data *yd; - - if(!(p2p_data = data)) - return ; - - if(listenfd == -1) { - purple_debug_warning("yahoo","p2p: error starting p2p server\n"); - yahoo_p2p_disconnect_destroy_data(data); - return; - } - - yd = p2p_data->gc->proto_data; - - /* Add an Input Read event to the file descriptor */ - yd->yahoo_local_p2p_server_fd = listenfd; - yd->yahoo_p2p_server_watcher = purple_input_add(listenfd, PURPLE_INPUT_READ, yahoo_p2p_server_send_connected_cb,data); - - /* add timeout */ - yd->yahoo_p2p_server_timeout_handle = purple_timeout_add_seconds(YAHOO_P2P_SERVER_TIMEOUT, yahoo_cancel_p2p_server_listen_cb, data); -} - -/* send p2p pkt containing our encoded ip, asking peer to connect to us */ -void yahoo_send_p2p_pkt(PurpleConnection *gc, const char *who, int val_13) -{ - const char *public_ip; - guint32 temp[4]; - guint32 ip; - char temp_str[100]; - gchar *base64_ip = NULL; - YahooFriend *f; - struct yahoo_packet *pkt; - PurpleAccount *account; - struct yahoo_data *yd = gc->proto_data; - struct yahoo_p2p_data *p2p_data; - - f = yahoo_friend_find(gc, who); - account = purple_connection_get_account(gc); - - /* Do not send invitation if already listening for other connection */ - if(yd->yahoo_local_p2p_server_fd >= 0) - return; - - /* One shouldn't try to connect to self */ - if( strcmp(purple_normalize(account, purple_account_get_username(account)), who) == 0) - return; - - /* send packet to only those friends who arent p2p connected and to whom we havent already sent. Do not send if this condition doesn't hold good */ - if( !( f && (yahoo_friend_get_p2p_status(f) == YAHOO_P2PSTATUS_NOT_CONNECTED) && (f->p2p_packet_sent == 0)) ) - return; - - /* Dont send p2p packet to buddies of other protocols */ - if(f->protocol) - return; - - /* Finally, don't try to connect to buddies not online or on sms */ - if( (f->status == YAHOO_STATUS_OFFLINE) || f->sms ) - return; - - public_ip = purple_network_get_public_ip(); - if( (sscanf(public_ip, "%u.%u.%u.%u", &temp[0], &temp[1], &temp[2], &temp[3])) !=4 ) - return ; - - ip = (temp[3] << 24) | (temp[2] <<16) | (temp[1] << 8) | temp[0]; - sprintf(temp_str, "%d", ip); - base64_ip = purple_base64_encode( (guchar *)temp_str, strlen(temp_str) ); - - pkt = yahoo_packet_new(YAHOO_SERVICE_PEERTOPEER, YAHOO_STATUS_AVAILABLE, 0); - yahoo_packet_hash(pkt, "sssissis", - 1, purple_normalize(account, purple_account_get_username(account)), - 4, purple_normalize(account, purple_account_get_username(account)), - 12, base64_ip, /* base64 encode ip */ - 61, 0, /* To-do : figure out what is 61 for?? */ - 2, "", - 5, who, - 13, val_13, - 49, "PEERTOPEER"); - yahoo_packet_send_and_free(pkt, yd); - - f->p2p_packet_sent = 1; /* set p2p_packet_sent to sent */ - - p2p_data = g_new0(struct yahoo_p2p_data, 1); - - p2p_data->gc = gc; - p2p_data->host_ip = NULL; - p2p_data->host_username = g_strdup(who); - p2p_data->val_13 = val_13; - p2p_data->connection_type = YAHOO_P2P_WE_ARE_SERVER; - - purple_network_listen(YAHOO_PAGER_PORT_P2P, SOCK_STREAM, yahoo_p2p_server_listen_cb, p2p_data); - - g_free(base64_ip); -} - -/* 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 *p2p_data; - struct yahoo_packet *pkt_to_send; - PurpleAccount *account; - struct yahoo_data *yd; - - if(!(p2p_data = data)) - return ; - yd = p2p_data->gc->proto_data; - - if(error_message != NULL) { - purple_debug_warning("yahoo","p2p: %s\n",error_message); - yahoo_send_p2p_pkt(p2p_data->gc, p2p_data->host_username, 2);/* send p2p init packet with val_13=2 */ - - yahoo_p2p_disconnect_destroy_data(p2p_data); - return; - } - - /* Add an Input Read event to the file descriptor */ - p2p_data->input_event = purple_input_add(source, PURPLE_INPUT_READ, yahoo_p2p_read_pkt_cb, data); - p2p_data->source = source; - - account = purple_connection_get_account(p2p_data->gc); - - /* Build the yahoo packet */ - pkt_to_send = yahoo_packet_new(YAHOO_SERVICE_P2PFILEXFER, YAHOO_STATUS_AVAILABLE, yd->session_id); - yahoo_packet_hash(pkt_to_send, "ssisi", - 4, purple_normalize(account, purple_account_get_username(account)), - 5, p2p_data->host_username, - 241, 0, /* Protocol identifier */ - 49, "PEERTOPEER", - 13, 1); /* we receive key13= 0 or 2, 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) { GSList *l = pkt->hash; @@ -2763,14 +2233,6 @@ char *base64 = NULL; guchar *decoded; gsize len; - gint val_13 = 0; - gint val_11 = 0; - PurpleAccount *account; - YahooFriend *f; - - /* if status is YAHOO_STATUS_BUSY, don't do anything, peer wont connect */ - if(pkt->status == YAHOO_STATUS_BUSY) - return ; while (l) { struct yahoo_pair *pair = l->data; @@ -2790,21 +2252,14 @@ /* 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); - break; - case 11: - val_11 = strtol(pair->value, NULL, 10); /* session id of peer */ - if( (f = yahoo_friend_find(gc, who)) ) - f->session_id = val_11; - break; /* TODO: figure these out yahoo: Key: 61 Value: 0 yahoo: Key: 2 Value: - yahoo: Key: 13 Value: 0 packet count ?? + yahoo: Key: 13 Value: 0 yahoo: Key: 49 Value: PEERTOPEER yahoo: Key: 140 Value: 1 + yahoo: Key: 11 Value: -1786225828 */ } @@ -2816,8 +2271,6 @@ guint32 ip; char *tmp2; YahooFriend *f; - char *host_ip; - struct yahoo_p2p_data *p2p_data = g_new0(struct yahoo_p2p_data, 1); decoded = purple_base64_decode(base64, &len); if (len) { @@ -2830,34 +2283,12 @@ ip = strtol(tmp2, NULL, 10); g_free(tmp2); g_free(decoded); - host_ip = g_strdup_printf("%u.%u.%u.%u", ip & 0xff, (ip >> 8) & 0xff, (ip >> 16) & 0xff, + tmp2 = 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, host_ip); - purple_debug_info("yahoo", "IP : %s\n", host_ip); - - account = purple_connection_get_account(gc); - - if(val_11==0) { - if(!f) - return; - else - val_11 = f->session_id; - } - - p2p_data->host_username = g_strdup(who); - p2p_data->val_13 = val_13; - p2p_data->session_id = val_11; - p2p_data->host_ip = host_ip; - p2p_data->gc = gc; - p2p_data->connection_type = YAHOO_P2P_WE_ARE_CLIENT; - - /* connect to host */ - if((purple_proxy_connect(NULL, account, host_ip, YAHOO_PAGER_PORT_P2P, yahoo_p2p_init_cb, p2p_data))==NULL) { - yahoo_p2p_disconnect_destroy_data(p2p_data); - purple_debug_info("yahoo","p2p: Connection to %s failed\n", host_ip); - } + yahoo_friend_set_ip(f, tmp2); + g_free(tmp2); } } @@ -2937,12 +2368,12 @@ yahoo_process_status(gc, pkt); break; case YAHOO_SERVICE_NOTIFY: - yahoo_process_notify(gc, pkt, YAHOO_PKT_TYPE_SERVER); + yahoo_process_notify(gc, pkt); break; case YAHOO_SERVICE_MESSAGE: case YAHOO_SERVICE_GAMEMSG: case YAHOO_SERVICE_CHATMSG: - yahoo_process_message(gc, pkt, YAHOO_PKT_TYPE_SERVER); + yahoo_process_message(gc, pkt); break; case YAHOO_SERVICE_SYSMESSAGE: yahoo_process_sysmessage(gc, pkt); @@ -3019,8 +2450,7 @@ break; case YAHOO_SERVICE_P2PFILEXFER: /* This case had no break and continued; thus keeping it this way.*/ - yahoo_process_p2p(gc, pkt); /* P2PFILEXFER handled the same way as process_p2p */ - yahoo_process_p2pfilexfer(gc, pkt); /* redundant ??, need to have a break now */ + yahoo_process_p2pfilexfer(gc, pkt); case YAHOO_SERVICE_FILETRANSFER: yahoo_process_filetransfer(gc, pkt); break; @@ -3054,9 +2484,6 @@ case YAHOO_SERVICE_FILETRANS_ACC_15: yahoo_process_filetrans_acc_15(gc, pkt); break; - case YAHOO_SERVICE_SMS_MSG: - yahoo_process_sms_message(gc, pkt); - break; default: purple_debug(PURPLE_DEBUG_ERROR, "yahoo", @@ -3578,11 +3005,9 @@ 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->sms_carrier = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); - yd->yahoo_p2p_timer = purple_timeout_add_seconds(YAHOO_P2P_KEEPALIVE_SECS, yahoo_p2p_keepalive, gc); yd->confs = NULL; yd->conf_id = 2; + yd->last_keepalive = yd->last_ping = time(NULL); yd->current_status = get_yahoo_status_from_purple_status(status); @@ -3641,21 +3066,10 @@ } g_slist_free(yd->cookies); - yd->chat_online = 0; + yd->chat_online = FALSE; if (yd->in_chat) yahoo_c_leave(gc, 1); /* 1 = YAHOO_CHAT_ID */ - purple_timeout_remove(yd->yahoo_p2p_timer); - if(yd->yahoo_p2p_server_timeout_handle != 0) - purple_timeout_remove(yd->yahoo_p2p_server_timeout_handle); - - /* close p2p server if it is waiting for a peer to connect */ - purple_input_remove(yd->yahoo_p2p_server_watcher); - close(yd->yahoo_local_p2p_server_fd); - yd->yahoo_local_p2p_server_fd = -1; - - g_hash_table_destroy(yd->sms_carrier); - g_hash_table_destroy(yd->peers); g_hash_table_destroy(yd->friends); g_hash_table_destroy(yd->imvironments); g_hash_table_destroy(yd->xfer_peer_idstring_map); @@ -4079,13 +3493,11 @@ static void yahoo_get_inbox_token_cb(PurpleUtilFetchUrlData *url_data, gpointer user_data, - const gchar *webdata, size_t len, const gchar *error_message) + const gchar *token, 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)); @@ -4094,14 +3506,8 @@ if (error_message != NULL) purple_debug_error("yahoo", "Requesting mail login token failed: %s\n", error_message); - 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? */ + else if (len > 0 && token && *token) { + /* Should we not be hardcoding the rd url? */ url = g_strdup_printf( "http://login.yahoo.com/config/reset_cookies_token?" ".token=%s" @@ -4119,7 +3525,6 @@ purple_notify_uri(gc, url); g_free(url); - g_free(token); } @@ -4133,19 +3538,16 @@ PurpleUtilFetchUrlData *url_data; const char* base_url = "http://login.yahoo.com"; - char *request = g_strdup_printf( - "POST /config/cookie_token HTTP/1.1\r\n" - "Cookie: Y=%s; path=/; domain=.yahoo.com; T=%s; path=/; domain=.yahoo.com;\r\n" + /* use whole URL if using HTTP Proxy */ + gboolean use_whole_url = yahoo_account_use_http_proxy(gc); + gchar *request = g_strdup_printf( + "POST %s/config/cookie_token HTTP/1.0\r\n" + "Cookie: T=%s; path=/; domain=.yahoo.com; Y=%s;\r\n" "User-Agent: Mozilla/4.0 (compatible; MSIE 5.5)\r\n" "Host: login.yahoo.com\r\n" - "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 */ - if ((gc->account->proxy_info) && (gc->account->proxy_info->type == PURPLE_PROXY_HTTP)) - use_whole_url = TRUE; + "Content-Length: 0\r\n\r\n", + use_whole_url ? base_url : "", + yd->cookie_t, yd->cookie_y); url_data = purple_util_fetch_url_request(base_url, use_whole_url, "Mozilla/4.0 (compatible; MSIE 5.5)", TRUE, request, FALSE, @@ -4158,7 +3560,7 @@ else { const char *yahoo_mail_url = (yd->jp ? YAHOOJP_MAIL_URL : YAHOO_MAIL_URL); purple_debug_error("yahoo", - "Unable to request mail login token; forwarding to login screen.\n"); + "Unable to request mail login token; forwarding to login screen."); purple_notify_uri(gc, yahoo_mail_url); } @@ -4207,195 +3609,22 @@ return m; } -struct yahoo_sms_carrier_cb_data { - PurpleConnection *gc; - char *who; - char *what; -}; - -static int yahoo_send_im(PurpleConnection *gc, const char *who, const char *what, PurpleMessageFlags flags); - -static void yahoo_get_sms_carrier_cb(PurpleUtilFetchUrlData *url_data, gpointer user_data, - const gchar *webdata, size_t len, const gchar *error_message) -{ - struct yahoo_sms_carrier_cb_data *sms_cb_data = user_data; - PurpleConnection *gc = sms_cb_data->gc; - struct yahoo_data *yd = gc->proto_data; - char *mobile_no = NULL; - char *status = NULL; - char *carrier = NULL; - PurpleAccount *account = purple_connection_get_account(gc); - PurpleConversation *conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, sms_cb_data->who, account); - - if (error_message != NULL) { - purple_conversation_write(conv, NULL, "Cant send SMS, Unable to obtain mobile carrier", PURPLE_MESSAGE_SYSTEM, time(NULL)); - - g_free(sms_cb_data->who); - g_free(sms_cb_data->what); - g_free(sms_cb_data); - return ; - } - else if (len > 0 && webdata && *webdata) { - xmlnode *validate_data_root = xmlnode_from_str(webdata, -1); - xmlnode *validate_data_child = xmlnode_get_child(validate_data_root, "mobile_no"); - mobile_no = (char *)xmlnode_get_attrib(validate_data_child, "msisdn"); - - validate_data_root = xmlnode_copy(validate_data_child); - validate_data_child = xmlnode_get_child(validate_data_root, "status"); - status = xmlnode_get_data(validate_data_child); - - validate_data_child = xmlnode_get_child(validate_data_root, "carrier"); - carrier = xmlnode_get_data(validate_data_child); - - purple_debug_info("yahoo","SMS validate data: Mobile:%s, Status:%s, Carrier:%s\n", mobile_no, status, carrier); - - if( strcmp(status, "Valid") == 0) { - g_hash_table_insert(yd->sms_carrier, g_strdup_printf("+%s", mobile_no), g_strdup(carrier)); - yahoo_send_im(sms_cb_data->gc, sms_cb_data->who, sms_cb_data->what, PURPLE_MESSAGE_SEND); - } - else { - g_hash_table_insert(yd->sms_carrier, g_strdup_printf("+%s", mobile_no), g_strdup("Unknown")); - purple_conversation_write(conv, NULL, "Cant send SMS, Unknown mobile carrier", PURPLE_MESSAGE_SYSTEM, time(NULL)); - } - - xmlnode_free(validate_data_child); - xmlnode_free(validate_data_root); - g_free(sms_cb_data->who); - g_free(sms_cb_data->what); - g_free(sms_cb_data); - g_free(mobile_no); - g_free(status); - g_free(carrier); - } -} - -static void yahoo_get_sms_carrier(PurpleConnection *gc, gpointer data) -{ - struct yahoo_data *yd = gc->proto_data; - PurpleUtilFetchUrlData *url_data; - struct yahoo_sms_carrier_cb_data *sms_cb_data; - char *validate_request_str = NULL; - char *request = NULL; - gboolean use_whole_url = FALSE; - xmlnode *validate_request_root = NULL; - xmlnode *validate_request_child = NULL; - - if(!(sms_cb_data = data)) - return; - - validate_request_root = xmlnode_new("validate"); - xmlnode_set_attrib(validate_request_root, "intl", "us"); - xmlnode_set_attrib(validate_request_root, "version", YAHOO_CLIENT_VERSION); - xmlnode_set_attrib(validate_request_root, "qos", "0"); - - validate_request_child = xmlnode_new_child(validate_request_root, "mobile_no"); - xmlnode_set_attrib(validate_request_child, "msisdn", sms_cb_data->who + 1); - - validate_request_str = xmlnode_to_str(validate_request_root, NULL); - - xmlnode_free(validate_request_child); - xmlnode_free(validate_request_root); - - request = g_strdup_printf( - "POST /mobileno?intl=us&version=%s HTTP/1.1\r\n" - "Cookie: T=%s; path=/; domain=.yahoo.com; Y=%s; path=/; domain=.yahoo.com;\r\n" - "User-Agent: Mozilla/4.0 (compatible; MSIE 5.5)\r\n" - "Host: validate.msg.yahoo.com\r\n" - "Content-Length: %d\r\n" - "Cache-Control: no-cache\r\n\r\n%s", - YAHOO_CLIENT_VERSION, yd->cookie_t, yd->cookie_y, strlen(validate_request_str), validate_request_str); - - /* use whole URL if using HTTP Proxy */ - if ((gc->account->proxy_info) && (gc->account->proxy_info->type == PURPLE_PROXY_HTTP)) - use_whole_url = TRUE; - - url_data = purple_util_fetch_url_request(YAHOO_SMS_CARRIER_URL, use_whole_url, - "Mozilla/4.0 (compatible; MSIE 5.5)", TRUE, request, FALSE, - yahoo_get_sms_carrier_cb, data); - - g_free(request); - g_free(validate_request_str); - - if (!url_data) { - PurpleAccount *account = purple_connection_get_account(gc); - PurpleConversation *conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, sms_cb_data->who, account); - purple_conversation_write(conv, NULL, "Cant send SMS, Unable to obtain mobile carrier", PURPLE_MESSAGE_SYSTEM, time(NULL)); - g_free(sms_cb_data->who); - g_free(sms_cb_data->what); - g_free(sms_cb_data); - } -} - static int yahoo_send_im(PurpleConnection *gc, const char *who, const char *what, PurpleMessageFlags flags) { struct yahoo_data *yd = gc->proto_data; - struct yahoo_packet *pkt; + struct yahoo_packet *pkt = yahoo_packet_new(YAHOO_SERVICE_MESSAGE, YAHOO_STATUS_OFFLINE, 0); char *msg = yahoo_html_to_codes(what); char *msg2; gboolean utf8 = TRUE; PurpleWhiteboard *wb; int ret = 1; YahooFriend *f = NULL; - struct yahoo_p2p_data *p2p_data; msg2 = yahoo_string_encode(gc, msg, &utf8); - if( strncmp(who, "+", 1) == 0 ) { - /* we have an sms to be sent */ - gchar *carrier = NULL; - const char *alias = NULL; - PurpleAccount *account = purple_connection_get_account(gc); - PurpleConversation *conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, who, account); - - carrier = g_hash_table_lookup(yd->sms_carrier, who); - if (!carrier) { - struct yahoo_sms_carrier_cb_data *sms_cb_data; - sms_cb_data = g_malloc(sizeof(struct yahoo_sms_carrier_cb_data)); - sms_cb_data->gc = gc; - sms_cb_data->who = g_malloc(strlen(who)); - sms_cb_data->what = g_malloc(strlen(what)); - strcpy(sms_cb_data->who, who); - strcpy(sms_cb_data->what, what); - - purple_conversation_write(conv, NULL, "Getting mobile carrier to send the sms", PURPLE_MESSAGE_SYSTEM, time(NULL)); - - yahoo_get_sms_carrier(gc, sms_cb_data); - - g_free(msg); - g_free(msg2); - return ret; - } - else if( strcmp(carrier,"Unknown") == 0 ) { - purple_conversation_write(conv, NULL, "Cant send SMS, Unknown mobile carrier", PURPLE_MESSAGE_SYSTEM, time(NULL)); - - g_free(msg); - g_free(msg2); - return -1; - } - - alias = purple_account_get_alias(account); - pkt = yahoo_packet_new(YAHOO_SERVICE_SMS_MSG, YAHOO_STATUS_AVAILABLE, 0); - yahoo_packet_hash(pkt, "sssss", - 1, purple_connection_get_display_name(gc), - 69, alias, - 5, who + 1, - 68, carrier, - 14, msg2); - yahoo_packet_send_and_free(pkt, yd); - - g_free(msg); - g_free(msg2); - - return ret; - } - - pkt = yahoo_packet_new(YAHOO_SERVICE_MESSAGE, YAHOO_STATUS_OFFLINE, 0); yahoo_packet_hash(pkt, "ss", 1, purple_connection_get_display_name(gc), 5, who); if ((f = yahoo_friend_find(gc, who)) && f->protocol) yahoo_packet_hash_int(pkt, 241, f->protocol); - else - if(strchr(who,'@')) - yahoo_packet_hash_int(pkt, 241, 2); if (utf8) yahoo_packet_hash_str(pkt, 97, "1"); @@ -4434,17 +3663,8 @@ 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) { - /* if p2p link exists, send through it. To-do: key 15, time value to be sent in case of p2p */ - if( (p2p_data = g_hash_table_lookup(yd->peers, who)) ) { - yahoo_packet_hash_int(pkt, 11, p2p_data->session_id); - yahoo_p2p_write_pkt(p2p_data->source, pkt); - } - else { - yahoo_packet_send(pkt, yd); - yahoo_send_p2p_pkt(gc, who, 0); /* send p2p packet, with val_13=0 */ - } - } + if ((YAHOO_PACKET_HDRLEN + yahoo_packet_length(pkt)) <= 2000) + yahoo_packet_send(pkt, yd); else ret = -E2BIG; @@ -4459,28 +3679,12 @@ static unsigned int yahoo_send_typing(PurpleConnection *gc, const char *who, PurpleTypingState state) { struct yahoo_data *yd = gc->proto_data; - struct yahoo_p2p_data *p2p_data; - struct yahoo_packet *pkt = yahoo_packet_new(YAHOO_SERVICE_NOTIFY, YAHOO_STATUS_TYPING, 0); - - /* Don't do anything if sms is being typed */ - if( strncmp(who, "+", 1) == 0 ) - return 0; - - /* check to see if p2p link exists, send through it */ - if( (p2p_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, p2p_data->session_id, 1002, "1"); /* To-do: key 15 to be sent in case of p2p */ - yahoo_p2p_write_pkt(p2p_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), + 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; } @@ -4674,21 +3878,36 @@ static void yahoo_keepalive(PurpleConnection *gc) { + struct yahoo_packet *pkt; struct yahoo_data *yd = gc->proto_data; - struct yahoo_packet *pkt = yahoo_packet_new(YAHOO_SERVICE_PING, YAHOO_STATUS_AVAILABLE, 0); - yahoo_packet_send_and_free(pkt, yd); - - if (!yd->chat_online) - return; - - if (yd->wm) { - ycht_chat_send_keepalive(yd->ycht); - return; + time_t now = time(NULL); + + /* We're only allowed to send a ping once an hour or the servers will boot us */ + if ((now - yd->last_ping) >= PING_TIMEOUT) { + yd->last_ping = now; + + /* The native client will only send PING or CHATPING */ + if (yd->chat_online) { + if (yd->wm) { + ycht_chat_send_keepalive(yd->ycht); + } else { + pkt = yahoo_packet_new(YAHOO_SERVICE_CHATPING, YAHOO_STATUS_AVAILABLE, 0); + yahoo_packet_hash_str(pkt, 109, purple_connection_get_display_name(gc)); + yahoo_packet_send_and_free(pkt, yd); + } + } else { + pkt = yahoo_packet_new(YAHOO_SERVICE_PING, YAHOO_STATUS_AVAILABLE, 0); + yahoo_packet_send_and_free(pkt, yd); + } } - pkt = yahoo_packet_new(YAHOO_SERVICE_CHATPING, YAHOO_STATUS_AVAILABLE, 0); - yahoo_packet_hash_str(pkt, 109, purple_connection_get_display_name(gc)); - yahoo_packet_send_and_free(pkt, yd); + if ((now - yd->last_keepalive) >= KEEPALIVE_TIMEOUT) { + yd->last_keepalive = now; + pkt = yahoo_packet_new(YAHOO_SERVICE_KEEPALIVE, YAHOO_STATUS_AVAILABLE, 0); + yahoo_packet_hash_str(pkt, 0, purple_connection_get_display_name(gc)); + yahoo_packet_send_and_free(pkt, yd); + } + } static void yahoo_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *g) @@ -4716,36 +3935,18 @@ group2 = yahoo_string_encode(gc, group, NULL); pkt = yahoo_packet_new(YAHOO_SERVICE_ADDBUDDY, YAHOO_STATUS_AVAILABLE, 0); - if(strchr(buddy->name, '@')) { - yahoo_packet_hash(pkt, "sssssssssss", - 14, "", - 65, group2, - 97, "1", - 1, purple_connection_get_display_name(gc), - 302, "319", - 300, "319", - 7, buddy->name, - 241, "2", - 334, "0", - 301, "319", - 303, "319" - ); - } - else { - yahoo_packet_hash(pkt, "ssssssssss", - 14, "", - 65, group2, - 97, "1", - 1, purple_connection_get_display_name(gc), - 302, "319", - 300, "319", - 7, buddy->name, - 334, "0", - 301, "319", - 303, "319" - ); - } - + yahoo_packet_hash(pkt, "ssssssssss", + 14, "", + 65, group2, + 97, "1", + 1, purple_connection_get_display_name(gc), + 302, "319", + 300, "319", + 7, buddy->name, + 334, "0", + 301, "319", + 303, "319" + ); if (f && f->protocol) yahoo_packet_hash_int(pkt, 241, f->protocol); yahoo_packet_send_and_free(pkt, yd); @@ -4760,9 +3961,8 @@ PurpleGroup *g; gboolean remove = TRUE; char *cg; - YahooFriend *f = yahoo_friend_find(gc, buddy->name); - - if (!f) + + if (!(yahoo_friend_find(gc, buddy->name))) return; buddies = purple_find_buddies(purple_connection_get_account(gc), buddy->name); @@ -4783,8 +3983,6 @@ pkt = yahoo_packet_new(YAHOO_SERVICE_REMBUDDY, YAHOO_STATUS_AVAILABLE, 0); yahoo_packet_hash(pkt, "sss", 1, purple_connection_get_display_name(gc), 7, buddy->name, 65, cg); - if(f->protocol) - yahoo_packet_hash_int(pkt, 241, f->protocol); yahoo_packet_send_and_free(pkt, yd); g_free(cg); } @@ -4857,12 +4055,11 @@ struct yahoo_data *yd = gc->proto_data; struct yahoo_packet *pkt; char *gpn, *gpo; - YahooFriend *f = yahoo_friend_find(gc, who); /* Step 0: If they aren't on the server list anyway, * don't bother letting the server know. */ - if (!f) + if (!yahoo_friend_find(gc, who)) return; /* If old and new are the same, we would probably @@ -4878,12 +4075,7 @@ } pkt = yahoo_packet_new(YAHOO_SERVICE_CHGRP_15, YAHOO_STATUS_AVAILABLE, 0); - if(f->protocol) - yahoo_packet_hash(pkt, "ssssissss", 1, purple_connection_get_display_name(gc), - 302, "240", 300, "240", 7, who, 241, f->protocol, 224, gpo, 264, gpn, 301, - "240", 303, "240"); - else - yahoo_packet_hash(pkt, "ssssssss", 1, purple_connection_get_display_name(gc), + yahoo_packet_hash(pkt, "ssssssss", 1, purple_connection_get_display_name(gc), 302, "240", 300, "240", 7, who, 224, gpo, 264, gpn, 301, "240", 303, "240"); yahoo_packet_send_and_free(pkt, yd); @@ -4924,7 +4116,7 @@ if (*args && args[0]) return PURPLE_CMD_RET_FAILED; - serv_send_attention(account->gc, c->name, YAHOO_BUZZ); + purple_prpl_send_attention(account->gc, c->name, YAHOO_BUZZ); return PURPLE_CMD_RET_OK; } @@ -5097,10 +4289,10 @@ purple_conv_send_confirm(conv, message); } } - /* else + /*else **If pidgindialogs_im() was in the core, we could use it here. * It is all purple_request_* based, but I'm not sure it really belongs in the core - pidgindialogs_im(); */ + pidgindialogs_im();*/ return TRUE; } @@ -5114,7 +4306,7 @@ g_hash_table_insert(params, g_strdup("type"), g_strdup("Chat")); serv_join_chat(purple_account_get_connection(acct), params); } - /* else + /*else ** Same as above (except that this would have to be re-written using purple_request_*) pidgin_blist_joinchat_show(); */ @@ -5131,6 +4323,15 @@ return FALSE; } +static GHashTable * +yahoo_get_account_text_table(PurpleAccount *account) +{ + GHashTable *table; + table = g_hash_table_new(g_str_hash, g_str_equal); + g_hash_table_insert(table, "login_label", (gpointer)_("Yahoo ID...")); + return table; +} + static PurpleWhiteboardPrplOps yahoo_whiteboard_prpl_ops = { yahoo_doodle_start, @@ -5175,7 +4376,7 @@ yahoo_add_buddy, NULL, /* add_buddies */ yahoo_remove_buddy, - NULL, /* remove_buddies */ + NULL, /*remove_buddies */ NULL, /* add_permit */ yahoo_add_deny, NULL, /* rem_permit */ @@ -5219,7 +4420,7 @@ yahoo_attention_types, sizeof(PurplePluginProtocolInfo), /* struct_size */ - NULL + yahoo_get_account_text_table, /* get_account_text_table */ }; static PurplePluginInfo info =
--- a/libpurple/protocols/yahoo/yahoo.h Wed Nov 12 08:19:56 2008 +0000 +++ b/libpurple/protocols/yahoo/yahoo.h Wed Nov 12 10:17:38 2008 +0000 @@ -30,9 +30,6 @@ #define YAHOO_PAGER_HOST "scs.msg.yahoo.com" #define YAHOO_PAGER_PORT 5050 -#define YAHOO_PAGER_PORT_P2P 5101 -#define YAHOO_P2P_KEEPALIVE_SECS 300 -#define YAHOO_P2P_SERVER_TIMEOUT 10 #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" @@ -48,7 +45,7 @@ #define YAHOOJP_MAIL_URL "http://mail.yahoo.co.jp/" #define YAHOOJP_XFER_HOST "filetransfer.msg.yahoo.co.jp" #define YAHOOJP_WEBCAM_HOST "wc.yahoo.co.jp" -/* not sure, must test: */ +/*not sure, must test:*/ #define YAHOOJP_XFER_RELAY_HOST "relay.msg.yahoo.co.jp" #define YAHOOJP_XFER_RELAY_PORT 80 #define YAHOOJP_ROOMLIST_URL "http://insider.msg.yahoo.co.jp/ycontent/" @@ -58,8 +55,6 @@ #define WEBMESSENGER_URL "http://login.yahoo.com/config/login?.src=pg" -#define YAHOO_SMS_CARRIER_URL "http://lookup.msg.vip.mud.yahoo.com" - #define YAHOO_PICURL_SETTING "picture_url" #define YAHOO_PICCKSUM_SETTING "picture_checksum" #define YAHOO_PICEXPIRE_SETTING "picture_expire" @@ -85,19 +80,10 @@ #define YAHOOJP_CLIENT_VERSION_ID "524223" #define YAHOOJP_CLIENT_VERSION "7,0,1,1" + /* Index into attention types list. */ #define YAHOO_BUZZ 0 -typedef enum { - YAHOO_PKT_TYPE_SERVER = 0, - YAHOO_PKT_TYPE_P2P -} yahoo_pkt_type; - -typedef enum { - YAHOO_P2P_WE_ARE_CLIENT =0, - YAHOO_P2P_WE_ARE_SERVER -} yahoo_p2p_connection_type; - enum yahoo_status { YAHOO_STATUS_AVAILABLE = 0, YAHOO_STATUS_BRB, @@ -127,17 +113,6 @@ guint watcher; }; -struct yahoo_p2p_data { - PurpleConnection *gc; - char *host_ip; - char *host_username; - int val_13; - guint input_event; - gint source; - int session_id; - yahoo_p2p_connection_type connection_type; -}; - struct _YchtConn; struct yahoo_data { @@ -193,20 +168,16 @@ * for when we lookup people profile or photo information. */ GSList *url_datas; - GHashTable *xfer_peer_idstring_map;/* Hey, i dont know, but putting this HashTable next to friends gives a run time fault... */ - GSList *cookies;/* contains all cookies, including _y and _t */ + GHashTable *xfer_peer_idstring_map;/*Hey, i dont know, but putting this HashTable next to friends gives a run time fault...*/ + GSList *cookies;/*contains all cookies, including _y and _t*/ /** * We may receive a list15 in multiple packets with no prior warning as to how many we'll be getting; * 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 */ - int yahoo_p2p_timer; - int yahoo_local_p2p_server_fd; - int yahoo_p2p_server_watcher; - GHashTable *sms_carrier; /* sms carrier data */ - guint yahoo_p2p_server_timeout_handle; + time_t last_ping; + time_t last_keepalive; }; #define YAHOO_MAX_STATUS_MESSAGE_LENGTH (255) @@ -235,6 +206,9 @@ char *yahoo_codes_to_html(const char *x); char *yahoo_html_to_codes(const char *src); +gboolean +yahoo_account_use_http_proxy(PurpleConnection *conn); + /** * Encode some text to send to the yahoo server. * @@ -276,7 +250,4 @@ gboolean yahoo_send_attention(PurpleConnection *gc, const char *username, guint type); GList *yahoo_attention_types(PurpleAccount *account); -/* send p2p pkt containing our encoded ip, asking peer to connect to us */ -void yahoo_send_p2p_pkt(PurpleConnection *gc, const char *who, int val_13); - #endif /* _YAHOO_H_ */
--- a/libpurple/protocols/yahoo/yahoo_packet.h Wed Nov 12 08:19:56 2008 +0000 +++ b/libpurple/protocols/yahoo/yahoo_packet.h Wed Nov 12 10:17:38 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,some sort of keep alive sent to the server every 60 secs */ + YAHOO_SERVICE_KEEPALIVE = 0x8A, 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,18 +98,15 @@ 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_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, - /* photo sharing services ?? - 0xd2, 0xd7, 0xd8, 0xda */ - YAHOO_SERVICE_CHGRP_15 = 0xe7, - YAHOO_SERVICE_STATUS_15 = 0xf0, - YAHOO_SERVICE_LIST_15 = 0xf1, 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 {