Mercurial > pidgin.yaz
diff src/protocols/yahoo/yahoo.c @ 10392:a8f9e5ce4f92
[gaim-migrate @ 11620]
a little bit of clean up and reorganization of the yahoo prpl.
I moved the packet functions to their own file, renamed a couple of them,
added a convience function and used it a lot. I plan on adding several
more convience functions.
committer: Tailor Script <tailor@pidgin.im>
author | Tim Ringenbach <marv@pidgin.im> |
---|---|
date | Thu, 16 Dec 2004 21:47:54 +0000 |
parents | 232808c6d6ab |
children | 45a0a07e8b25 |
line wrap: on
line diff
--- a/src/protocols/yahoo/yahoo.c Thu Dec 16 15:36:49 2004 +0000 +++ b/src/protocols/yahoo/yahoo.c Thu Dec 16 21:47:54 2004 +0000 @@ -39,6 +39,7 @@ #include "sha.h" #include "yahoo.h" +#include "yahoo_packet.h" #include "yahoo_friend.h" #include "yahoochat.h" #include "ycht.h" @@ -55,266 +56,6 @@ static void yahoo_login_page_cb(void *user_data, const char *buf, size_t len); -struct yahoo_packet *yahoo_packet_new(enum yahoo_service service, enum yahoo_status status, int id) -{ - struct yahoo_packet *pkt = g_new0(struct yahoo_packet, 1); - - pkt->service = service; - pkt->status = status; - pkt->id = id; - - return pkt; -} - -void yahoo_packet_hash(struct yahoo_packet *pkt, int key, const char *value) -{ - struct yahoo_pair *pair = g_new0(struct yahoo_pair, 1); - pair->key = key; - pair->value = g_strdup(value); - pkt->hash = g_slist_append(pkt->hash, pair); -} - -int yahoo_packet_length(struct yahoo_packet *pkt) -{ - GSList *l; - - int len = 0; - - l = pkt->hash; - while (l) { - struct yahoo_pair *pair = l->data; - int tmp = pair->key; - do { - tmp /= 10; - len++; - } while (tmp); - len += 2; - len += strlen(pair->value); - len += 2; - l = l->next; - } - - return len; -} - -static void yahoo_packet_read(struct yahoo_packet *pkt, guchar *data, int len) -{ - int pos = 0; - - while (pos + 1 < len) { - char key[64], *value = NULL, *esc; - int accept; - int x; - - struct yahoo_pair *pair = g_new0(struct yahoo_pair, 1); - - /* this is weird, and in one of the chat packets, and causes us - * think all the values are keys and all the keys are values after - * this point if we don't handle it */ - if (data[pos] == '\0') { - while (pos + 1 < len) { - if (data[pos] == 0xc0 && data[pos + 1] == 0x80) - break; - pos++; - } - pos += 2; - g_free(pair); - continue; - } - - x = 0; - while (pos + 1 < len) { - if (data[pos] == 0xc0 && data[pos + 1] == 0x80) - break; - if (x >= sizeof(key)-1) { - x++; - pos++; - continue; - } - key[x++] = data[pos++]; - } - if (x >= sizeof(key)-1) { - x = 0; - } - key[x] = 0; - pos += 2; - pair->key = strtol(key, NULL, 10); - accept = x; /* if x is 0 there was no key, so don't accept it */ - - if (len - pos + 1 <= 0) { - /* Truncated. Garbage or something. */ - accept = 0; - } - - if (accept) { - value = g_malloc(len - pos + 1); - x = 0; - while (pos + 1 < len) { - if (data[pos] == 0xc0 && data[pos + 1] == 0x80) - break; - value[x++] = data[pos++]; - } - value[x] = 0; - pair->value = g_strdup(value); - g_free(value); - pkt->hash = g_slist_append(pkt->hash, pair); - esc = g_strescape(pair->value, NULL); - gaim_debug(GAIM_DEBUG_MISC, "yahoo", - "Key: %d \tValue: %s\n", pair->key, esc); - g_free(esc); - } else { - g_free(pair); - } - pos += 2; - - /* Skip over garbage we've noticed in the mail notifications */ - if (data[0] == '9' && data[pos] == 0x01) - pos++; - } -} - -void yahoo_packet_write(struct yahoo_packet *pkt, guchar *data) -{ - GSList *l = pkt->hash; - int pos = 0; - - while (l) { - struct yahoo_pair *pair = l->data; - guchar buf[100]; - - g_snprintf(buf, sizeof(buf), "%d", pair->key); - strcpy(data + pos, buf); - pos += strlen(buf); - data[pos++] = 0xc0; - data[pos++] = 0x80; - - strcpy(data + pos, pair->value); - pos += strlen(pair->value); - data[pos++] = 0xc0; - data[pos++] = 0x80; - - l = l->next; - } -} - -static void yahoo_packet_dump(guchar *data, int len) -{ -#ifdef YAHOO_DEBUG - int i; - - gaim_debug(GAIM_DEBUG_MISC, "yahoo", ""); - - for (i = 0; i + 1 < len; i += 2) { - if ((i % 16 == 0) && i) { - gaim_debug(GAIM_DEBUG_MISC, NULL, "\n"); - gaim_debug(GAIM_DEBUG_MISC, "yahoo", ""); - } - - gaim_debug(GAIM_DEBUG_MISC, NULL, "%02x%02x ", data[i], data[i + 1]); - } - if (i < len) - gaim_debug(GAIM_DEBUG_MISC, NULL, "%02x", data[i]); - - gaim_debug(GAIM_DEBUG_MISC, NULL, "\n"); - gaim_debug(GAIM_DEBUG_MISC, "yahoo", ""); - - for (i = 0; i < len; i++) { - if ((i % 16 == 0) && i) { - gaim_debug(GAIM_DEBUG_MISC, NULL, "\n"); - gaim_debug(GAIM_DEBUG_MISC, "yahoo", ""); - } - - if (g_ascii_isprint(data[i])) - gaim_debug(GAIM_DEBUG_MISC, NULL, "%c ", data[i]); - else - gaim_debug(GAIM_DEBUG_MISC, NULL, ". "); - } - - gaim_debug(GAIM_DEBUG_MISC, NULL, "\n"); -#endif -} - -int yahoo_send_packet(struct yahoo_data *yd, struct yahoo_packet *pkt) -{ - int pktlen = yahoo_packet_length(pkt); - int len = YAHOO_PACKET_HDRLEN + pktlen; - int ret; - - guchar *data; - int pos = 0; - - if (yd->fd < 0) - return -1; - - data = g_malloc0(len + 1); - - memcpy(data + pos, "YMSG", 4); pos += 4; - - if (yd->wm) - pos += yahoo_put16(data + pos, YAHOO_WEBMESSENGER_PROTO_VER); - else - pos += yahoo_put16(data + pos, YAHOO_PROTO_VER); - - pos += yahoo_put16(data + pos, 0x0000); - pos += yahoo_put16(data + pos, pktlen); - pos += yahoo_put16(data + pos, pkt->service); - pos += yahoo_put32(data + pos, pkt->status); - pos += yahoo_put32(data + pos, pkt->id); - - yahoo_packet_write(pkt, data + pos); - - yahoo_packet_dump(data, len); - ret = write(yd->fd, data, len); - if (ret != len) - gaim_debug_warning("yahoo", "Only wrote %d of %d bytes!", ret, len); - g_free(data); - - return ret; -} - -int yahoo_send_packet_special(int fd, struct yahoo_packet *pkt, int pad) -{ - int pktlen = yahoo_packet_length(pkt); - int len = YAHOO_PACKET_HDRLEN + pktlen; - int ret; - - guchar *data; - int pos = 0; - - if (fd < 0) - return -1; - - data = g_malloc0(len + 1); - - memcpy(data + pos, "YMSG", 4); pos += 4; - - pos += yahoo_put16(data + pos, YAHOO_PROTO_VER); - - pos += yahoo_put16(data + pos, 0x0000); - pos += yahoo_put16(data + pos, pktlen + pad); - pos += yahoo_put16(data + pos, pkt->service); - pos += yahoo_put32(data + pos, pkt->status); - pos += yahoo_put32(data + pos, pkt->id); - - yahoo_packet_write(pkt, data + pos); - - ret = write(fd, data, len); - g_free(data); - - return ret; -} - -void yahoo_packet_free(struct yahoo_packet *pkt) -{ - while (pkt->hash) { - struct yahoo_pair *pair = pkt->hash->data; - g_free(pair->value); - g_free(pair); - pkt->hash = g_slist_remove(pkt->hash, pair); - } - g_free(pkt); -} - static void yahoo_update_status(GaimConnection *gc, const char *name, YahooFriend *f) { gboolean online = TRUE; @@ -425,8 +166,7 @@ * * do_import(gc, NULL); * newpkt = yahoo_packet_new(YAHOO_SERVICE_LIST, YAHOO_STATUS_OFFLINE, 0); - * yahoo_send_packet(yd, newpkt); - * yahoo_packet_free(newpkt); + * yahoo_packet_send_and_free(newpkt, yd); */ } @@ -1280,13 +1020,10 @@ yahoo_packet_hash(pack, 96, result96); yahoo_packet_hash(pack, 1, name); - yahoo_send_packet(yd, pack); + yahoo_packet_send_and_free(pack, yd); g_free(hash_string_p); g_free(hash_string_c); - - yahoo_packet_free(pack); - } /* I'm dishing out some uber-mad props to Cerulean Studios for cracking this @@ -1743,8 +1480,7 @@ yahoo_packet_hash(pack, 192, cksum); g_free(cksum); } - yahoo_send_packet(yd, pack); - yahoo_packet_free(pack); + yahoo_packet_send_and_free(pack, yd); g_free(password_hash); g_free(crypt_hash); @@ -2287,9 +2023,7 @@ pkt = yahoo_packet_new(YAHOO_SERVICE_AUTH, YAHOO_STATUS_AVAILABLE, 0); yahoo_packet_hash(pkt, 1, gaim_normalize(gc->account, gaim_account_get_username(gaim_connection_get_account(gc)))); - yahoo_send_packet(yd, pkt); - - yahoo_packet_free(pkt); + yahoo_packet_send_and_free(pkt, yd); gc->inpa = gaim_input_add(yd->fd, GAIM_INPUT_READ, yahoo_pending, gc); } @@ -2318,9 +2052,8 @@ yahoo_packet_hash(pkt, 0, gaim_normalize(gc->account, gaim_account_get_username(gaim_connection_get_account(gc)))); yahoo_packet_hash(pkt, 1, gaim_normalize(gc->account, gaim_account_get_username(gaim_connection_get_account(gc)))); yahoo_packet_hash(pkt, 6, yd->auth); - yahoo_send_packet(yd, pkt); - - yahoo_packet_free(pkt); + yahoo_packet_send_and_free(pkt, yd); + g_free(yd->auth); gc->inpa = gaim_input_add(yd->fd, GAIM_INPUT_READ, yahoo_pending, gc); } @@ -2878,8 +2611,7 @@ struct yahoo_packet *pkt = yahoo_packet_new(YAHOO_SERVICE_IDACT, YAHOO_STATUS_AVAILABLE, 0); yahoo_packet_hash(pkt, 3, entry); - yahoo_send_packet(yd, pkt); - yahoo_packet_free(pkt); + yahoo_packet_send_and_free(pkt, yd); gaim_connection_set_display_name(gc, entry); } @@ -2944,7 +2676,7 @@ /* 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_send_packet(yd, pkt); + yahoo_packet_send(pkt, yd); else ret = -E2BIG; @@ -2967,9 +2699,7 @@ yahoo_packet_hash(pkt, 5, who); yahoo_packet_hash(pkt, 1002, "1"); - yahoo_send_packet(yd, pkt); - - yahoo_packet_free(pkt); + yahoo_packet_send_and_free(pkt, yd); return 0; } @@ -3023,8 +2753,7 @@ if (yd->current_status == YAHOO_STATUS_INVISIBLE) { pkt = yahoo_packet_new(YAHOO_SERVICE_Y6_VISIBLE_TOGGLE, YAHOO_STATUS_AVAILABLE, 0); yahoo_packet_hash(pkt, 13, "2"); - yahoo_send_packet(yd, pkt); - yahoo_packet_free(pkt); + yahoo_packet_send_and_free(pkt, yd); return; } @@ -3054,8 +2783,7 @@ else if (!gaim_status_type_is_available(gaim_status_get_type(status))) yahoo_packet_hash(pkt, 47, "1"); - yahoo_send_packet(yd, pkt); - yahoo_packet_free(pkt); + yahoo_packet_send_and_free(pkt, yd); g_free(conv_msg); g_free(conv_msg2); @@ -3063,8 +2791,7 @@ if (old_status == YAHOO_STATUS_INVISIBLE) { pkt = yahoo_packet_new(YAHOO_SERVICE_Y6_VISIBLE_TOGGLE, YAHOO_STATUS_AVAILABLE, 0); yahoo_packet_hash(pkt, 13, "1"); - yahoo_send_packet(yd, pkt); - yahoo_packet_free(pkt); + yahoo_packet_send_and_free(pkt, yd); } } @@ -3101,8 +2828,7 @@ yahoo_packet_hash(pkt, 47, "1"); - yahoo_send_packet(yd, pkt); - yahoo_packet_free(pkt); + yahoo_packet_send_and_free(pkt, yd); g_free(msg); g_free(msg2); @@ -3179,8 +2905,7 @@ { struct yahoo_data *yd = gc->proto_data; struct yahoo_packet *pkt = yahoo_packet_new(YAHOO_SERVICE_PING, YAHOO_STATUS_AVAILABLE, 0); - yahoo_send_packet(yd, pkt); - yahoo_packet_free(pkt); + yahoo_packet_send_and_free(pkt, yd); if (!yd->chat_online) return; @@ -3192,8 +2917,7 @@ pkt = yahoo_packet_new(YAHOO_SERVICE_CHATPING, YAHOO_STATUS_AVAILABLE, 0); yahoo_packet_hash(pkt, 109, gaim_connection_get_display_name(gc)); - yahoo_send_packet(yd, pkt); - yahoo_packet_free(pkt); + yahoo_packet_send_and_free(yd, pkt); } /* XXX - What's the deal with GaimGroup *foo? */ @@ -3224,8 +2948,7 @@ yahoo_packet_hash(pkt, 7, buddy->name); yahoo_packet_hash(pkt, 65, group2); yahoo_packet_hash(pkt, 14, ""); - yahoo_send_packet(yd, pkt); - yahoo_packet_free(pkt); + yahoo_packet_send_and_free(pkt, yd); g_free(group2); } @@ -3261,8 +2984,7 @@ yahoo_packet_hash(pkt, 1, gaim_connection_get_display_name(gc)); yahoo_packet_hash(pkt, 7, buddy->name); yahoo_packet_hash(pkt, 65, cg); - yahoo_send_packet(yd, pkt); - yahoo_packet_free(pkt); + yahoo_packet_send_and_free(pkt, yd); g_free(cg); } @@ -3284,8 +3006,7 @@ yahoo_packet_hash(pkt, 1, gaim_connection_get_display_name(gc)); yahoo_packet_hash(pkt, 7, who); yahoo_packet_hash(pkt, 13, "1"); - yahoo_send_packet(yd, pkt); - yahoo_packet_free(pkt); + yahoo_packet_send_and_free(pkt, yd); } static void yahoo_rem_deny(GaimConnection *gc, const char *who) { @@ -3302,8 +3023,7 @@ yahoo_packet_hash(pkt, 1, gaim_connection_get_display_name(gc)); yahoo_packet_hash(pkt, 7, who); yahoo_packet_hash(pkt, 13, "2"); - yahoo_send_packet(yd, pkt); - yahoo_packet_free(pkt); + yahoo_packet_send_and_free(pkt, yd); } static void yahoo_set_permit_deny(GaimConnection *gc) { @@ -3374,16 +3094,14 @@ yahoo_packet_hash(pkt, 7, who); yahoo_packet_hash(pkt, 65, gpn); yahoo_packet_hash(pkt, 14, ""); - yahoo_send_packet(yd, pkt); - yahoo_packet_free(pkt); + yahoo_packet_send_and_free(pkt, yd); /* Step 2: Remove buddy from old group */ pkt = yahoo_packet_new(YAHOO_SERVICE_REMBUDDY, YAHOO_STATUS_AVAILABLE, 0); yahoo_packet_hash(pkt, 1, gaim_connection_get_display_name(gc)); yahoo_packet_hash(pkt, 7, who); yahoo_packet_hash(pkt, 65, gpo); - yahoo_send_packet(yd, pkt); - yahoo_packet_free(pkt); + yahoo_packet_send_and_free(pkt, yd); g_free(gpn); g_free(gpo); } @@ -3407,8 +3125,7 @@ yahoo_packet_hash(pkt, 1, gaim_connection_get_display_name(gc)); yahoo_packet_hash(pkt, 65, gpo); yahoo_packet_hash(pkt, 67, gpn); - yahoo_send_packet(yd, pkt); - yahoo_packet_free(pkt); + yahoo_packet_send_and_free(pkt, yd); g_free(gpn); g_free(gpo); }