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);
 }