changeset 22717:979a81468e19

All SNACs on FLAP channel 2 except in the auth family are now sent through flap_connection_send_snac() instead of flap_connection_send(). This allows them to be tallied into the rate limiting calculations and to be throttled as necessary to prevent rate limiting violations. This does fix the instantaneous disconnection seen with the addition of ICQ Status Notes support for people with many ICQ contacts with status notes on their buddy list. Unfortunately, we still request the ICQ Status Note many times per contact, so such people now may be rate limited for a significant period of time as they connect.
author Evan Schoenberg <evan.s@dreskin.net>
date Thu, 24 Apr 2008 11:10:03 +0000
parents 80c87908ff1d
children da3de0190be2
files libpurple/protocols/oscar/bstream.c libpurple/protocols/oscar/family_admin.c libpurple/protocols/oscar/family_alert.c libpurple/protocols/oscar/family_bart.c libpurple/protocols/oscar/family_bos.c libpurple/protocols/oscar/family_buddy.c libpurple/protocols/oscar/family_chat.c libpurple/protocols/oscar/family_chatnav.c libpurple/protocols/oscar/family_feedbag.c libpurple/protocols/oscar/family_icbm.c libpurple/protocols/oscar/family_icq.c libpurple/protocols/oscar/family_locate.c libpurple/protocols/oscar/family_odir.c libpurple/protocols/oscar/family_oservice.c libpurple/protocols/oscar/family_userlookup.c libpurple/protocols/oscar/flap_connection.c libpurple/protocols/oscar/misc.c libpurple/protocols/oscar/oscar.h
diffstat 18 files changed, 875 insertions(+), 827 deletions(-) [+]
line wrap: on
line diff
--- a/libpurple/protocols/oscar/bstream.c	Thu Apr 24 02:16:30 2008 +0000
+++ b/libpurple/protocols/oscar/bstream.c	Thu Apr 24 11:10:03 2008 +0000
@@ -45,6 +45,11 @@
 	return 0;
 }
 
+void byte_stream_destroy(ByteStream *bs)
+{
+	g_free(bs->data);
+}
+
 int byte_stream_empty(ByteStream *bs)
 {
 	return bs->len - bs->offset;
--- a/libpurple/protocols/oscar/family_admin.c	Thu Apr 24 02:16:30 2008 +0000
+++ b/libpurple/protocols/oscar/family_admin.c	Thu Apr 24 11:10:03 2008 +0000
@@ -40,18 +40,18 @@
 int
 aim_admin_getinfo(OscarData *od, FlapConnection *conn, guint16 info)
 {
-	FlapFrame *fr;
+	ByteStream bs;
 	aim_snacid_t snacid;
 
-	fr = flap_frame_new(od, 0x02, 14);
+	byte_stream_new(&bs, 4);
 
-	snacid = aim_cachesnac(od, 0x0007, 0x0002, 0x0000, NULL, 0);
-	aim_putsnac(&fr->data, 0x0007, 0x0002, 0x0000, snacid);
+	byte_stream_put16(&bs, info);
+	byte_stream_put16(&bs, 0x0000);
 
-	byte_stream_put16(&fr->data, info);
-	byte_stream_put16(&fr->data, 0x0000);
+	snacid = aim_cachesnac(od, 0x0007, 0x0002, 0x0000, NULL, 0);	
+	flap_connection_send_snac(od, conn, 0x0007, 0x0002, 0x0000, snacid, &bs);	
 
-	flap_connection_send(conn, fr);
+	byte_stream_destroy(&bs);
 
 	return 0;
 }
@@ -120,25 +120,28 @@
  * Subtype 0x0004 - Set screenname formatting.
  *
  */
+/*
+ * Subtype 0x0004 - Set screenname formatting.
+ *
+ */
 int
 aim_admin_setnick(OscarData *od, FlapConnection *conn, const char *newnick)
 {
-	FlapFrame *fr;
+	ByteStream bs;
 	aim_snacid_t snacid;
 	GSList *tlvlist = NULL;
 
-	fr = flap_frame_new(od, 0x02, 10+2+2+strlen(newnick));
-
-	snacid = aim_cachesnac(od, 0x0007, 0x0004, 0x0000, NULL, 0);
-	aim_putsnac(&fr->data, 0x0007, 0x0004, 0x0000, snacid);
+	byte_stream_new(&bs, 2+2+strlen(newnick));
 
 	aim_tlvlist_add_str(&tlvlist, 0x0001, newnick);
 
-	aim_tlvlist_write(&fr->data, &tlvlist);
+	aim_tlvlist_write(&bs, &tlvlist);
 	aim_tlvlist_free(tlvlist);
 
-	flap_connection_send(conn, fr);
+	snacid = aim_cachesnac(od, 0x0007, 0x0004, 0x0000, NULL, 0);
+	flap_connection_send_snac(od, conn, 0x0007, 0x0004, 0x0000, snacid, &bs);
 
+	byte_stream_destroy(&bs);
 
 	return 0;
 }
@@ -150,14 +153,11 @@
 int
 aim_admin_changepasswd(OscarData *od, FlapConnection *conn, const char *newpw, const char *curpw)
 {
-	FlapFrame *fr;
+	ByteStream bs;
 	GSList *tlvlist = NULL;
 	aim_snacid_t snacid;
 
-	fr = flap_frame_new(od, 0x02, 10+4+strlen(curpw)+4+strlen(newpw));
-
-	snacid = aim_cachesnac(od, 0x0007, 0x0004, 0x0000, NULL, 0);
-	aim_putsnac(&fr->data, 0x0007, 0x0004, 0x0000, snacid);
+	byte_stream_new(&bs, 4+strlen(curpw)+4+strlen(newpw));
 
 	/* new password TLV t(0002) */
 	aim_tlvlist_add_str(&tlvlist, 0x0002, newpw);
@@ -165,10 +165,11 @@
 	/* current password TLV t(0012) */
 	aim_tlvlist_add_str(&tlvlist, 0x0012, curpw);
 
-	aim_tlvlist_write(&fr->data, &tlvlist);
+	aim_tlvlist_write(&bs, &tlvlist);
 	aim_tlvlist_free(tlvlist);
 
-	flap_connection_send(conn, fr);
+	snacid = aim_cachesnac(od, 0x0007, 0x0004, 0x0000, NULL, 0);
+	flap_connection_send_snac(od, conn, 0x0007, 0x0004, 0x0000, snacid, &bs);
 
 	return 0;
 }
@@ -180,21 +181,21 @@
 int
 aim_admin_setemail(OscarData *od, FlapConnection *conn, const char *newemail)
 {
-	FlapFrame *fr;
+	ByteStream bs;
 	aim_snacid_t snacid;
 	GSList *tlvlist = NULL;
 
-	fr = flap_frame_new(od, 0x02, 10+2+2+strlen(newemail));
-
-	snacid = aim_cachesnac(od, 0x0007, 0x0004, 0x0000, NULL, 0);
-	aim_putsnac(&fr->data, 0x0007, 0x0004, 0x0000, snacid);
+	byte_stream_new(&bs, 2+2+strlen(newemail));
 
 	aim_tlvlist_add_str(&tlvlist, 0x0011, newemail);
 
-	aim_tlvlist_write(&fr->data, &tlvlist);
+	aim_tlvlist_write(&bs, &tlvlist);
 	aim_tlvlist_free(tlvlist);
 
-	flap_connection_send(conn, fr);
+	snacid = aim_cachesnac(od, 0x0007, 0x0004, 0x0000, NULL, 0);
+	flap_connection_send_snac(od, conn, 0x0007, 0x0004, 0x0000, snacid, &bs);
+
+	byte_stream_destroy(&bs);
 
 	return 0;
 }
--- a/libpurple/protocols/oscar/family_alert.c	Thu Apr 24 02:16:30 2008 +0000
+++ b/libpurple/protocols/oscar/family_alert.c	Thu Apr 24 11:10:03 2008 +0000
@@ -41,40 +41,41 @@
 aim_email_sendcookies(OscarData *od)
 {
 	FlapConnection *conn;
-	FlapFrame *fr;
+	ByteStream bs;
 	aim_snacid_t snacid;
 
 	if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_ALERT)))
 		return -EINVAL;
 
-	fr = flap_frame_new(od, 0x02, 10+2+16+16);
-	snacid = aim_cachesnac(od, 0x0018, 0x0006, 0x0000, NULL, 0);
-	aim_putsnac(&fr->data, 0x0018, 0x0006, 0x0000, snacid);
+	byte_stream_new(&bs, 2+16+16);
 
 	/* Number of cookies to follow */
-	byte_stream_put16(&fr->data, 0x0002);
+	byte_stream_put16(&bs, 0x0002);
 
 	/* Cookie */
-	byte_stream_put16(&fr->data, 0x5d5e);
-	byte_stream_put16(&fr->data, 0x1708);
-	byte_stream_put16(&fr->data, 0x55aa);
-	byte_stream_put16(&fr->data, 0x11d3);
-	byte_stream_put16(&fr->data, 0xb143);
-	byte_stream_put16(&fr->data, 0x0060);
-	byte_stream_put16(&fr->data, 0xb0fb);
-	byte_stream_put16(&fr->data, 0x1ecb);
+	byte_stream_put16(&bs, 0x5d5e);
+	byte_stream_put16(&bs, 0x1708);
+	byte_stream_put16(&bs, 0x55aa);
+	byte_stream_put16(&bs, 0x11d3);
+	byte_stream_put16(&bs, 0xb143);
+	byte_stream_put16(&bs, 0x0060);
+	byte_stream_put16(&bs, 0xb0fb);
+	byte_stream_put16(&bs, 0x1ecb);
 
 	/* Cookie */
-	byte_stream_put16(&fr->data, 0xb380);
-	byte_stream_put16(&fr->data, 0x9ad8);
-	byte_stream_put16(&fr->data, 0x0dba);
-	byte_stream_put16(&fr->data, 0x11d5);
-	byte_stream_put16(&fr->data, 0x9f8a);
-	byte_stream_put16(&fr->data, 0x0060);
-	byte_stream_put16(&fr->data, 0xb0ee);
-	byte_stream_put16(&fr->data, 0x0631);
+	byte_stream_put16(&bs, 0xb380);
+	byte_stream_put16(&bs, 0x9ad8);
+	byte_stream_put16(&bs, 0x0dba);
+	byte_stream_put16(&bs, 0x11d5);
+	byte_stream_put16(&bs, 0x9f8a);
+	byte_stream_put16(&bs, 0x0060);
+	byte_stream_put16(&bs, 0xb0ee);
+	byte_stream_put16(&bs, 0x0631);
 
-	flap_connection_send(conn, fr);
+	snacid = aim_cachesnac(od, 0x0018, 0x0006, 0x0000, NULL, 0);
+	flap_connection_send_snac(od, conn, 0x0018, 0x0006, 0x0000, snacid, &bs);
+
+	byte_stream_destroy(&bs);
 
 	return 0;
 }
@@ -171,25 +172,26 @@
 aim_email_activate(OscarData *od)
 {
 	FlapConnection *conn;
-	FlapFrame *fr;
+	ByteStream bs;
 	aim_snacid_t snacid;
 
 	if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_ALERT)))
 		return -EINVAL;
 
-	fr = flap_frame_new(od, 0x02, 10+1+16);
-	snacid = aim_cachesnac(od, 0x0018, 0x0016, 0x0000, NULL, 0);
-	aim_putsnac(&fr->data, 0x0018, 0x0016, 0x0000, snacid);
+	byte_stream_new(&bs, 1+16);
 
 	/* I would guess this tells AIM that you want updates for your mail accounts */
 	/* ...but I really have no idea */
-	byte_stream_put8(&fr->data, 0x02);
-	byte_stream_put32(&fr->data, 0x04000000);
-	byte_stream_put32(&fr->data, 0x04000000);
-	byte_stream_put32(&fr->data, 0x04000000);
-	byte_stream_put32(&fr->data, 0x00000000);
+	byte_stream_put8(&bs, 0x02);
+	byte_stream_put32(&bs, 0x04000000);
+	byte_stream_put32(&bs, 0x04000000);
+	byte_stream_put32(&bs, 0x04000000);
+	byte_stream_put32(&bs, 0x00000000);
 
-	flap_connection_send(conn, fr);
+	snacid = aim_cachesnac(od, 0x0018, 0x0016, 0x0000, NULL, 0);
+	flap_connection_send_snac(od, conn, 0x0018, 0x0006, 0x0000, snacid, &bs);
+
+	byte_stream_destroy(&bs);
 
 	return 0;
 }
--- a/libpurple/protocols/oscar/family_bart.c	Thu Apr 24 02:16:30 2008 +0000
+++ b/libpurple/protocols/oscar/family_bart.c	Thu Apr 24 11:10:03 2008 +0000
@@ -40,25 +40,26 @@
 aim_bart_upload(OscarData *od, const guint8 *icon, guint16 iconlen)
 {
 	FlapConnection *conn;
-	FlapFrame *fr;
+	ByteStream bs;
 	aim_snacid_t snacid;
 
 	if (!od || !(conn = flap_connection_findbygroup(od, 0x0010)) || !icon || !iconlen)
 		return -EINVAL;
 
-	fr = flap_frame_new(od, 0x02, 10 + 2 + 2+iconlen);
-	snacid = aim_cachesnac(od, 0x0010, 0x0002, 0x0000, NULL, 0);
-	aim_putsnac(&fr->data, 0x0010, 0x0002, 0x0000, snacid);
+	byte_stream_new(&bs, 2 + 2 + iconlen);
 
 	/* The reference number for the icon */
-	byte_stream_put16(&fr->data, 1);
+	byte_stream_put16(&bs, 1);
 
 	/* The icon */
-	byte_stream_put16(&fr->data, iconlen);
-	byte_stream_putraw(&fr->data, icon, iconlen);
+	byte_stream_put16(&bs, iconlen);
+	byte_stream_putraw(&bs, icon, iconlen);
 
-	flap_connection_send(conn, fr);
-
+	snacid = aim_cachesnac(od, 0x0010, 0x0002, 0x0000, NULL, 0);
+	flap_connection_send_snac(od, conn, 0x0010, 0x0002, 0x0000, snacid, &bs);
+	
+	byte_stream_destroy(&bs);
+	
 	return 0;
 }
 
@@ -98,30 +99,31 @@
 aim_bart_request(OscarData *od, const char *sn, guint8 iconcsumtype, const guint8 *iconcsum, guint16 iconcsumlen)
 {
 	FlapConnection *conn;
-	FlapFrame *fr;
+	ByteStream bs;
 	aim_snacid_t snacid;
 
 	if (!od || !(conn = flap_connection_findbygroup(od, 0x0010)) || !sn || !strlen(sn) || !iconcsum || !iconcsumlen)
 		return -EINVAL;
 
-	fr = flap_frame_new(od, 0x02, 10 + 1+strlen(sn) + 4 + 1+iconcsumlen);
-	snacid = aim_cachesnac(od, 0x0010, 0x0004, 0x0000, NULL, 0);
-	aim_putsnac(&fr->data, 0x0010, 0x0004, 0x0000, snacid);
+	byte_stream_new(&bs, 1+strlen(sn) + 4 + 1+iconcsumlen);
 
 	/* Screen name */
-	byte_stream_put8(&fr->data, strlen(sn));
-	byte_stream_putstr(&fr->data, sn);
+	byte_stream_put8(&bs, strlen(sn));
+	byte_stream_putstr(&bs, sn);
 
 	/* Some numbers.  You like numbers, right? */
-	byte_stream_put8(&fr->data, 0x01);
-	byte_stream_put16(&fr->data, 0x0001);
-	byte_stream_put8(&fr->data, iconcsumtype);
+	byte_stream_put8(&bs, 0x01);
+	byte_stream_put16(&bs, 0x0001);
+	byte_stream_put8(&bs, iconcsumtype);
 
 	/* Icon string */
-	byte_stream_put8(&fr->data, iconcsumlen);
-	byte_stream_putraw(&fr->data, iconcsum, iconcsumlen);
+	byte_stream_put8(&bs, iconcsumlen);
+	byte_stream_putraw(&bs, iconcsum, iconcsumlen);
 
-	flap_connection_send(conn, fr);
+	snacid = aim_cachesnac(od, 0x0010, 0x0004, 0x0000, NULL, 0);
+	flap_connection_send_snac(od, conn, 0x0010, 0x0004, 0x0000, snacid, &bs);
+
+	byte_stream_destroy(&bs);
 
 	return 0;
 }
--- a/libpurple/protocols/oscar/family_bos.c	Thu Apr 24 02:16:30 2008 +0000
+++ b/libpurple/protocols/oscar/family_bos.c	Thu Apr 24 11:10:03 2008 +0000
@@ -114,7 +114,7 @@
  */
 int aim_bos_changevisibility(OscarData *od, FlapConnection *conn, int changetype, const char *denylist)
 {
-	FlapFrame *frame;
+	ByteStream bs;
 	int packlen = 0;
 	guint16 subtype;
 	char *localcpy = NULL, *tmpptr = NULL;
@@ -139,24 +139,24 @@
 	localcpy = g_strdup(denylist);
 
 	listcount = aimutil_itemcnt(localcpy, '&');
-	packlen = aimutil_tokslen(localcpy, 99, '&') + listcount + 9;
+	packlen = aimutil_tokslen(localcpy, 99, '&') + listcount-1;
 
-	frame = flap_frame_new(od, 0x02, packlen);
-
-	snacid = aim_cachesnac(od, 0x0009, subtype, 0x0000, NULL, 0);
-	aim_putsnac(&frame->data, 0x0009, subtype, 0x00, snacid);
+	byte_stream_new(&bs, packlen);
 
 	for (i = 0; (i < (listcount - 1)) && (i < 99); i++) {
 		tmpptr = aimutil_itemindex(localcpy, i, '&');
 
-		byte_stream_put8(&frame->data, strlen(tmpptr));
-		byte_stream_putstr(&frame->data, tmpptr);
+		byte_stream_put8(&bs, strlen(tmpptr));
+		byte_stream_putstr(&bs, tmpptr);
 
 		g_free(tmpptr);
 	}
 	g_free(localcpy);
 
-	flap_connection_send(conn, frame);
+	snacid = aim_cachesnac(od, 0x0009, subtype, 0x0000, NULL, 0);
+	flap_connection_send_snac(od, conn, 0x0009, subtype, 0x0000, snacid, &bs);
+
+	byte_stream_destroy(&bs);
 
 	return 0;
 }
--- a/libpurple/protocols/oscar/family_buddy.c	Thu Apr 24 02:16:30 2008 +0000
+++ b/libpurple/protocols/oscar/family_buddy.c	Thu Apr 24 11:10:03 2008 +0000
@@ -97,21 +97,21 @@
 int
 aim_buddylist_addbuddy(OscarData *od, FlapConnection *conn, const char *sn)
 {
-	FlapFrame *frame;
+	ByteStream bs;
 	aim_snacid_t snacid;
 
 	if (!sn || !strlen(sn))
 		return -EINVAL;
 
-	frame = flap_frame_new(od, 0x02, 10+1+strlen(sn));
+	byte_stream_new(&bs, 1+strlen(sn));
+
+	byte_stream_put8(&bs, strlen(sn));
+	byte_stream_putstr(&bs, sn);
 
 	snacid = aim_cachesnac(od, 0x0003, 0x0004, 0x0000, sn, strlen(sn)+1);
-	aim_putsnac(&frame->data, 0x0003, 0x0004, 0x0000, snacid);
+	flap_connection_send_snac(od, conn, 0x0003, 0x0004, 0x0000, snacid, &bs);
 
-	byte_stream_put8(&frame->data, strlen(sn));
-	byte_stream_putstr(&frame->data, sn);
-
-	flap_connection_send(conn, frame);
+	byte_stream_destroy(&bs);
 
 	return 0;
 }
@@ -129,7 +129,7 @@
 int
 aim_buddylist_set(OscarData *od, FlapConnection *conn, const char *buddy_list)
 {
-	FlapFrame *frame;
+	ByteStream bs;
 	aim_snacid_t snacid;
 	int len = 0;
 	char *localcpy = NULL;
@@ -145,10 +145,7 @@
 		tmpptr = strtok(NULL, "&");
 	}
 
-	frame = flap_frame_new(od, 0x02, 10+len);
-
-	snacid = aim_cachesnac(od, 0x0003, 0x0004, 0x0000, NULL, 0);
-	aim_putsnac(&frame->data, 0x0003, 0x0004, 0x0000, snacid);
+	byte_stream_new(&bs, len);
 
 	strncpy(localcpy, buddy_list, strlen(buddy_list) + 1);
 
@@ -157,12 +154,15 @@
 		purple_debug_misc("oscar", "---adding: %s (%" G_GSIZE_FORMAT
 				")\n", tmpptr, strlen(tmpptr));
 
-		byte_stream_put8(&frame->data, strlen(tmpptr));
-		byte_stream_putstr(&frame->data, tmpptr);
+		byte_stream_put8(&bs, strlen(tmpptr));
+		byte_stream_putstr(&bs, tmpptr);
 		tmpptr = strtok(NULL, "&");
 	}
 
-	flap_connection_send(conn, frame);
+	snacid = aim_cachesnac(od, 0x0003, 0x0004, 0x0000, NULL, 0);
+	flap_connection_send_snac(od, conn, 0x0003, 0x0004, 0x0000, snacid, &bs);
+
+	byte_stream_destroy(&bs);
 
 	g_free(localcpy);
 
@@ -179,21 +179,21 @@
 int
 aim_buddylist_removebuddy(OscarData *od, FlapConnection *conn, const char *sn)
 {
-	FlapFrame *frame;
+	ByteStream bs;
 	aim_snacid_t snacid;
 
 	if (!sn || !strlen(sn))
 		return -EINVAL;
 
-	frame = flap_frame_new(od, 0x02, 10+1+strlen(sn));
+	byte_stream_new(&bs, 1 + strlen(sn));
+
+	byte_stream_put8(&bs, strlen(sn));
+	byte_stream_putstr(&bs, sn);
 
 	snacid = aim_cachesnac(od, 0x0003, 0x0005, 0x0000, sn, strlen(sn)+1);
-	aim_putsnac(&frame->data, 0x0003, 0x0005, 0x0000, snacid);
+	flap_connection_send_snac(od, conn, 0x0003, 0x0005, 0x0000, snacid, &bs);
 
-	byte_stream_put8(&frame->data, strlen(sn));
-	byte_stream_putstr(&frame->data, sn);
-
-	flap_connection_send(conn, frame);
+	byte_stream_destroy(&bs);
 
 	return 0;
 }
--- a/libpurple/protocols/oscar/family_chat.c	Thu Apr 24 02:16:30 2008 +0000
+++ b/libpurple/protocols/oscar/family_chat.c	Thu Apr 24 11:10:03 2008 +0000
@@ -353,7 +353,7 @@
 aim_chat_send_im(OscarData *od, FlapConnection *conn, guint16 flags, const gchar *msg, int msglen, const char *encoding, const char *language)
 {
 	int i;
-	FlapFrame *frame;
+	ByteStream bs;
 	IcbmCookie *cookie;
 	aim_snacid_t snacid;
 	guint8 ckstr[8];
@@ -362,10 +362,9 @@
 	if (!od || !conn || !msg || (msglen <= 0))
 		return 0;
 
-	frame = flap_frame_new(od, 0x02, 1152);
+	byte_stream_new(&bs, 1142);
 
 	snacid = aim_cachesnac(od, 0x000e, 0x0005, 0x0000, NULL, 0);
-	aim_putsnac(&frame->data, 0x000e, 0x0005, 0x0000, snacid);
 
 	/*
 	 * Cookie
@@ -382,8 +381,8 @@
 	aim_cachecookie(od, cookie);
 
 	/* ICBM Header */
-	byte_stream_putraw(&frame->data, ckstr, 8); /* Cookie */
-	byte_stream_put16(&frame->data, 0x0003); /* Channel */
+	byte_stream_putraw(&bs, ckstr, 8); /* Cookie */
+	byte_stream_put16(&bs, 0x0003); /* Channel */
 
 	/*
 	 * Type 1: Flag meaning this message is destined to the room.
@@ -428,13 +427,15 @@
 	 */
 	aim_tlvlist_add_frozentlvlist(&tlvlist, 0x0005, &inner_tlvlist);
 
-	aim_tlvlist_write(&frame->data, &tlvlist);
+	aim_tlvlist_write(&bs, &tlvlist);
 
 	aim_tlvlist_free(inner_tlvlist);
 	aim_tlvlist_free(tlvlist);
 
-	flap_connection_send(conn, frame);
+	flap_connection_send_snac(od, conn, 0x000e, 0x0005, 0x0000, snacid, &bs);
 
+	byte_stream_destroy(&bs);
+	
 	return 0;
 }
 
--- a/libpurple/protocols/oscar/family_chatnav.c	Thu Apr 24 02:16:30 2008 +0000
+++ b/libpurple/protocols/oscar/family_chatnav.c	Thu Apr 24 11:10:03 2008 +0000
@@ -91,17 +91,16 @@
 	static const char ck[] = {"create"};
 	static const char lang[] = {"en"};
 	static const char charset[] = {"us-ascii"};
-	FlapFrame *frame;
+	ByteStream bs;
 	aim_snacid_t snacid;
 	GSList *tlvlist = NULL;
 
-	frame = flap_frame_new(od, 0x02, 1152);
+	byte_stream_new(&bs, 1142);
 
 	snacid = aim_cachesnac(od, 0x000d, 0x0008, 0x0000, NULL, 0);
-	aim_putsnac(&frame->data, 0x000d, 0x0008, 0x0000, snacid);
 
 	/* exchange */
-	byte_stream_put16(&frame->data, exchange);
+	byte_stream_put16(&bs, exchange);
 
 	/*
 	 * This looks to be a big hack.  You'll note that this entire
@@ -114,8 +113,8 @@
 	 * AOL style, I'm going to guess that it is the latter, and that
 	 * the value of the room name in create requests is ignored.
 	 */
-	byte_stream_put8(&frame->data, strlen(ck));
-	byte_stream_putstr(&frame->data, ck);
+	byte_stream_put8(&bs, strlen(ck));
+	byte_stream_putstr(&bs, ck);
 
 	/*
 	 * instance
@@ -123,22 +122,24 @@
 	 * Setting this to 0xffff apparently assigns the last instance.
 	 *
 	 */
-	byte_stream_put16(&frame->data, 0xffff);
+	byte_stream_put16(&bs, 0xffff);
 
 	/* detail level */
-	byte_stream_put8(&frame->data, 0x01);
+	byte_stream_put8(&bs, 0x01);
 
 	aim_tlvlist_add_str(&tlvlist, 0x00d3, name);
 	aim_tlvlist_add_str(&tlvlist, 0x00d6, charset);
 	aim_tlvlist_add_str(&tlvlist, 0x00d7, lang);
 
 	/* tlvcount */
-	byte_stream_put16(&frame->data, aim_tlvlist_count(tlvlist));
-	aim_tlvlist_write(&frame->data, &tlvlist);
+	byte_stream_put16(&bs, aim_tlvlist_count(tlvlist));
+	aim_tlvlist_write(&bs, &tlvlist);
 
 	aim_tlvlist_free(tlvlist);
 
-	flap_connection_send(conn, frame);
+	flap_connection_send_snac(od, conn, 0x000d, 0x0008, 0x0000, snacid, &bs);
+
+	byte_stream_destroy(&bs);
 
 	return 0;
 }
--- a/libpurple/protocols/oscar/family_feedbag.c	Thu Apr 24 02:16:30 2008 +0000
+++ b/libpurple/protocols/oscar/family_feedbag.c	Thu Apr 24 11:10:03 2008 +0000
@@ -1241,21 +1241,21 @@
 int aim_ssi_reqifchanged(OscarData *od, time_t timestamp, guint16 numitems)
 {
 	FlapConnection *conn;
-	FlapFrame *frame;
+	ByteStream bs;
 	aim_snacid_t snacid;
 
 	if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_FEEDBAG)))
 		return -EINVAL;
 
-	frame = flap_frame_new(od, 0x02, 10+4+2);
+	byte_stream_new(&bs, 4+2);
+
+	byte_stream_put32(&bs, timestamp);
+	byte_stream_put16(&bs, numitems);
 
 	snacid = aim_cachesnac(od, SNAC_FAMILY_FEEDBAG, SNAC_SUBTYPE_FEEDBAG_REQIFCHANGED, 0x0000, NULL, 0);
+	flap_connection_send_snac(od, conn, SNAC_FAMILY_FEEDBAG, SNAC_SUBTYPE_FEEDBAG_REQIFCHANGED, 0x0000, snacid, &bs);
 
-	aim_putsnac(&frame->data, SNAC_FAMILY_FEEDBAG, SNAC_SUBTYPE_FEEDBAG_REQIFCHANGED, 0x0000, snacid);
-	byte_stream_put32(&frame->data, timestamp);
-	byte_stream_put16(&frame->data, numitems);
-
-	flap_connection_send(conn, frame);
+	byte_stream_destroy(&bs);
 
 	/* Free any current data, just in case */
 	aim_ssi_freelist(od);
@@ -1343,42 +1343,44 @@
 static int aim_ssi_addmoddel(OscarData *od)
 {
 	FlapConnection *conn;
-	FlapFrame *frame;
+	ByteStream bs;
 	aim_snacid_t snacid;
-	int snaclen;
+	int bslen;
 	struct aim_ssi_tmp *cur;
 
 	if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_FEEDBAG)) || !od->ssi.pending || !od->ssi.pending->item)
 		return -EINVAL;
 
 	/* Calculate total SNAC size */
-	snaclen = 10; /* For family, subtype, flags, and SNAC ID */
+	bslen = 0;
 	for (cur=od->ssi.pending; cur; cur=cur->next) {
-		snaclen += 10; /* For length, GID, BID, type, and length */
+		bslen += 10; /* For length, GID, BID, type, and length */
 		if (cur->item->name)
-			snaclen += strlen(cur->item->name);
+			bslen += strlen(cur->item->name);
 		if (cur->item->data)
-			snaclen += aim_tlvlist_size(cur->item->data);
+			bslen += aim_tlvlist_size(cur->item->data);
 	}
 
-	frame = flap_frame_new(od, 0x02, snaclen);
+	byte_stream_new(&bs, bslen);
+
+	aim_putsnac(&bs, SNAC_FAMILY_FEEDBAG, od->ssi.pending->action, 0x0000, snacid);
+
+	for (cur=od->ssi.pending; cur; cur=cur->next) {
+		byte_stream_put16(&bs, cur->item->name ? strlen(cur->item->name) : 0);
+		if (cur->item->name)
+			byte_stream_putstr(&bs, cur->item->name);
+		byte_stream_put16(&bs, cur->item->gid);
+		byte_stream_put16(&bs, cur->item->bid);
+		byte_stream_put16(&bs, cur->item->type);
+		byte_stream_put16(&bs, cur->item->data ? aim_tlvlist_size(cur->item->data) : 0);
+		if (cur->item->data)
+			aim_tlvlist_write(&bs, &cur->item->data);
+	}
 
 	snacid = aim_cachesnac(od, SNAC_FAMILY_FEEDBAG, od->ssi.pending->action, 0x0000, NULL, 0);
-	aim_putsnac(&frame->data, SNAC_FAMILY_FEEDBAG, od->ssi.pending->action, 0x0000, snacid);
+	flap_connection_send_snac(od, conn, SNAC_FAMILY_FEEDBAG, od->ssi.pending->action, 0x0000, snacid, &bs);
 
-	for (cur=od->ssi.pending; cur; cur=cur->next) {
-		byte_stream_put16(&frame->data, cur->item->name ? strlen(cur->item->name) : 0);
-		if (cur->item->name)
-			byte_stream_putstr(&frame->data, cur->item->name);
-		byte_stream_put16(&frame->data, cur->item->gid);
-		byte_stream_put16(&frame->data, cur->item->bid);
-		byte_stream_put16(&frame->data, cur->item->type);
-		byte_stream_put16(&frame->data, cur->item->data ? aim_tlvlist_size(cur->item->data) : 0);
-		if (cur->item->data)
-			aim_tlvlist_write(&frame->data, &cur->item->data);
-	}
-
-	flap_connection_send(conn, frame);
+	byte_stream_destroy(&bs);
 
 	return 0;
 }
@@ -1684,32 +1686,32 @@
 int aim_ssi_sendauth(OscarData *od, char *sn, char *msg)
 {
 	FlapConnection *conn;
-	FlapFrame *frame;
+	ByteStream bs;
 	aim_snacid_t snacid;
 
 	if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_FEEDBAG)) || !sn)
 		return -EINVAL;
 
-	frame = flap_frame_new(od, 0x02, 10+1+strlen(sn)+2+(msg ? strlen(msg)+1 : 0)+2);
-
-	snacid = aim_cachesnac(od, SNAC_FAMILY_FEEDBAG, SNAC_SUBTYPE_FEEDBAG_SENDAUTH, 0x0000, NULL, 0);
-	aim_putsnac(&frame->data, SNAC_FAMILY_FEEDBAG, SNAC_SUBTYPE_FEEDBAG_SENDAUTH, 0x0000, snacid);
+	byte_stream_new(&bs, 1+strlen(sn)+2+(msg ? strlen(msg)+1 : 0)+2);
 
 	/* Screen name */
-	byte_stream_put8(&frame->data, strlen(sn));
-	byte_stream_putstr(&frame->data, sn);
+	byte_stream_put8(&bs, strlen(sn));
+	byte_stream_putstr(&bs, sn);
 
 	/* Message (null terminated) */
-	byte_stream_put16(&frame->data, msg ? strlen(msg) : 0);
+	byte_stream_put16(&bs, msg ? strlen(msg) : 0);
 	if (msg) {
-		byte_stream_putstr(&frame->data, msg);
-		byte_stream_put8(&frame->data, 0x00);
+		byte_stream_putstr(&bs, msg);
+		byte_stream_put8(&bs, 0x00);
 	}
 
 	/* Unknown */
-	byte_stream_put16(&frame->data, 0x0000);
+	byte_stream_put16(&bs, 0x0000);
 
-	flap_connection_send(conn, frame);
+	snacid = aim_cachesnac(od, SNAC_FAMILY_FEEDBAG, SNAC_SUBTYPE_FEEDBAG_SENDAUTH, 0x0000, NULL, 0);
+	flap_connection_send_snac(od, conn, SNAC_FAMILY_FEEDBAG, SNAC_SUBTYPE_FEEDBAG_SENDAUTH, 0x0000, snacid, &bs);
+
+	byte_stream_destroy(&bs);
 
 	return 0;
 }
@@ -1758,32 +1760,34 @@
 int aim_ssi_sendauthrequest(OscarData *od, char *sn, const char *msg)
 {
 	FlapConnection *conn;
-	FlapFrame *frame;
+	ByteStream bs;
 	aim_snacid_t snacid;
 
 	if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_FEEDBAG)) || !sn)
 		return -EINVAL;
 
-	frame = flap_frame_new(od, 0x02, 10+1+strlen(sn)+2+(msg ? strlen(msg)+1 : 0)+2);
+	byte_stream_new(&bs, 1+strlen(sn) + 2+(msg ? (strlen(msg)+1) : 0) + 2);
 
-	snacid = aim_cachesnac(od, SNAC_FAMILY_FEEDBAG, SNAC_SUBTYPE_FEEDBAG_SENDAUTHREQ, 0x0000, NULL, 0);
-	aim_putsnac(&frame->data, SNAC_FAMILY_FEEDBAG, SNAC_SUBTYPE_FEEDBAG_SENDAUTHREQ, 0x0000, snacid);
+	aim_putsnac(&bs, SNAC_FAMILY_FEEDBAG, SNAC_SUBTYPE_FEEDBAG_SENDAUTHREQ, 0x0000, snacid);
 
 	/* Screen name */
-	byte_stream_put8(&frame->data, strlen(sn));
-	byte_stream_putstr(&frame->data, sn);
+	byte_stream_put8(&bs, strlen(sn));
+	byte_stream_putstr(&bs, sn);
 
 	/* Message (null terminated) */
-	byte_stream_put16(&frame->data, msg ? strlen(msg) : 0);
+	byte_stream_put16(&bs, msg ? strlen(msg) : 0);
 	if (msg) {
-		byte_stream_putstr(&frame->data, msg);
-		byte_stream_put8(&frame->data, 0x00);
+		byte_stream_putstr(&bs, msg);
+		byte_stream_put8(&bs, 0x00);
 	}
 
 	/* Unknown */
-	byte_stream_put16(&frame->data, 0x0000);
+	byte_stream_put16(&bs, 0x0000);
 
-	flap_connection_send(conn, frame);
+	snacid = aim_cachesnac(od, SNAC_FAMILY_FEEDBAG, SNAC_SUBTYPE_FEEDBAG_SENDAUTHREQ, 0x0000, NULL, 0);
+	flap_connection_send_snac(od, conn, SNAC_FAMILY_FEEDBAG, SNAC_SUBTYPE_FEEDBAG_SENDAUTHREQ, 0x0000, snacid, &bs);
+
+	byte_stream_destroy(&bs);
 
 	return 0;
 }
@@ -1835,36 +1839,36 @@
 int aim_ssi_sendauthreply(OscarData *od, char *sn, guint8 reply, const char *msg)
 {
 	FlapConnection *conn;
-	FlapFrame *frame;
+	ByteStream bs;
 	aim_snacid_t snacid;
 
 	if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_FEEDBAG)) || !sn)
 		return -EINVAL;
 
-	frame = flap_frame_new(od, 0x02, 10 + 1+strlen(sn) + 1 + 2+(msg ? strlen(msg)+1 : 0) + 2);
-
-	snacid = aim_cachesnac(od, SNAC_FAMILY_FEEDBAG, SNAC_SUBTYPE_FEEDBAG_SENDAUTHREP, 0x0000, NULL, 0);
-	aim_putsnac(&frame->data, SNAC_FAMILY_FEEDBAG, SNAC_SUBTYPE_FEEDBAG_SENDAUTHREP, 0x0000, snacid);
+	byte_stream_new(&bs, 1+strlen(sn) + 1 + 2+(msg ? (strlen(msg)+1) : 0) + 2);
 
 	/* Screen name */
-	byte_stream_put8(&frame->data, strlen(sn));
-	byte_stream_putstr(&frame->data, sn);
+	byte_stream_put8(&bs, strlen(sn));
+	byte_stream_putstr(&bs, sn);
 
 	/* Grant or deny */
-	byte_stream_put8(&frame->data, reply);
+	byte_stream_put8(&bs, reply);
 
 	/* Message (null terminated) */
-	byte_stream_put16(&frame->data, msg ? (strlen(msg)+1) : 0);
+	byte_stream_put16(&bs, msg ? (strlen(msg)+1) : 0);
 	if (msg) {
-		byte_stream_putstr(&frame->data, msg);
-		byte_stream_put8(&frame->data, 0x00);
+		byte_stream_putstr(&bs, msg);
+		byte_stream_put8(&bs, 0x00);
 	}
 
 	/* Unknown */
-	byte_stream_put16(&frame->data, 0x0000);
+	byte_stream_put16(&bs, 0x0000);
 
-	flap_connection_send(conn, frame);
+	snacid = aim_cachesnac(od, SNAC_FAMILY_FEEDBAG, SNAC_SUBTYPE_FEEDBAG_SENDAUTHREP, 0x0000, NULL, 0);
+	flap_connection_send_snac(od, conn, SNAC_FAMILY_FEEDBAG, SNAC_SUBTYPE_FEEDBAG_SENDAUTHREP, 0x0000, snacid, &bs);
 
+	byte_stream_destroy(&bs);
+	
 	return 0;
 }
 
--- a/libpurple/protocols/oscar/family_icbm.c	Thu Apr 24 02:16:30 2008 +0000
+++ b/libpurple/protocols/oscar/family_icbm.c	Thu Apr 24 11:10:03 2008 +0000
@@ -161,7 +161,7 @@
 int aim_im_setparams(OscarData *od, struct aim_icbmparameters *params)
 {
 	FlapConnection *conn;
-	FlapFrame *frame;
+	ByteStream bs;
 	aim_snacid_t snacid;
 
 	if (!od || !(conn = flap_connection_findbygroup(od, 0x0004)))
@@ -170,23 +170,23 @@
 	if (!params)
 		return -EINVAL;
 
-	frame = flap_frame_new(od, 0x02, 10+16);
-
-	snacid = aim_cachesnac(od, 0x0004, 0x0002, 0x0000, NULL, 0);
-	aim_putsnac(&frame->data, 0x0004, 0x0002, 0x0000, snacid);
+	byte_stream_new(&bs, 16);
 
 	/* This is read-only (see Parameter Reply). Must be set to zero here. */
-	byte_stream_put16(&frame->data, 0x0000);
+	byte_stream_put16(&bs, 0x0000);
 
 	/* These are all read-write */
-	byte_stream_put32(&frame->data, params->flags);
-	byte_stream_put16(&frame->data, params->maxmsglen);
-	byte_stream_put16(&frame->data, params->maxsenderwarn);
-	byte_stream_put16(&frame->data, params->maxrecverwarn);
-	byte_stream_put32(&frame->data, params->minmsginterval);
-
-	flap_connection_send(conn, frame);
-
+	byte_stream_put32(&bs, params->flags);
+	byte_stream_put16(&bs, params->maxmsglen);
+	byte_stream_put16(&bs, params->maxsenderwarn);
+	byte_stream_put16(&bs, params->maxrecverwarn);
+	byte_stream_put32(&bs, params->minmsginterval);
+
+	snacid = aim_cachesnac(od, 0x0004, 0x0002, 0x0000, NULL, 0);
+	flap_connection_send_snac(od, conn, 0x0004, 0x0002, 0x0000, snacid, &bs);
+	
+	byte_stream_destroy(&bs);
+	
 	return 0;
 }
 
@@ -454,7 +454,7 @@
 int aim_im_sendch2_chatinvite(OscarData *od, const char *sn, const char *msg, guint16 exchange, const char *roomname, guint16 instance)
 {
 	FlapConnection *conn;
-	FlapFrame *frame;
+	ByteStream bs;
 	aim_snacid_t snacid;
 	IcbmCookie *msgcookie;
 	struct aim_invite_priv *priv;
@@ -470,10 +470,9 @@
 
 	aim_icbm_makecookie(cookie);
 
-	frame = flap_frame_new(od, 0x02, 1152+strlen(sn)+strlen(roomname)+strlen(msg));
+	byte_stream_new(&bs, 1142+strlen(sn)+strlen(roomname)+strlen(msg));
 
 	snacid = aim_cachesnac(od, 0x0004, 0x0006, 0x0000, sn, strlen(sn)+1);
-	aim_putsnac(&frame->data, 0x0004, 0x0006, 0x0000, snacid);
 
 	/* XXX should be uncached by an unwritten 'invite accept' handler */
 	priv = g_malloc(sizeof(struct aim_invite_priv));
@@ -488,7 +487,7 @@
 		g_free(priv);
 
 	/* ICBM Header */
-	aim_im_puticbm(&frame->data, cookie, 0x0002, sn);
+	aim_im_puticbm(&bs, cookie, 0x0002, sn);
 
 	/*
 	 * TLV t(0005)
@@ -513,14 +512,16 @@
 	aim_tlvlist_write(&hdrbs, &inner_tlvlist);
 
 	aim_tlvlist_add_raw(&outer_tlvlist, 0x0005, byte_stream_curpos(&hdrbs), hdrbs.data);
-	g_free(hdrbs.data);
-
-	aim_tlvlist_write(&frame->data, &outer_tlvlist);
+	byte_stream_destroy(&hdrbs);
+
+	aim_tlvlist_write(&bs, &outer_tlvlist);
 
 	aim_tlvlist_free(inner_tlvlist);
 	aim_tlvlist_free(outer_tlvlist);
 
-	flap_connection_send(conn, frame);
+	flap_connection_send_snac(od, conn, 0x0004, 0x0006, 0x0000, snacid, &bs);
+	
+	byte_stream_destroy(&bs);
 
 	return 0;
 }
@@ -534,7 +535,7 @@
 int aim_im_sendch2_icon(OscarData *od, const char *sn, const guint8 *icon, int iconlen, time_t stamp, guint16 iconsum)
 {
 	FlapConnection *conn;
-	FlapFrame *frame;
+	ByteStream bs;
 	aim_snacid_t snacid;
 	guchar cookie[8];
 
@@ -546,51 +547,52 @@
 
 	aim_icbm_makecookie(cookie);
 
-	frame = flap_frame_new(od, 0x02, 10+8+2+1+strlen(sn)+2+2+2+8+16+2+2+2+2+2+2+2+4+4+4+iconlen+strlen(AIM_ICONIDENT)+2+2);
+	byte_stream_new(&bs, 8+2+1+strlen(sn)+2+2+2+8+16+2+2+2+2+2+2+2+4+4+4+iconlen+strlen(AIM_ICONIDENT)+2+2);
 
 	snacid = aim_cachesnac(od, 0x0004, 0x0006, 0x0000, NULL, 0);
-	aim_putsnac(&frame->data, 0x0004, 0x0006, 0x0000, snacid);
 
 	/* ICBM header */
-	aim_im_puticbm(&frame->data, cookie, 0x0002, sn);
+	aim_im_puticbm(&bs, cookie, 0x0002, sn);
 
 	/*
 	 * TLV t(0005)
 	 *
 	 * Encompasses everything below.
 	 */
-	byte_stream_put16(&frame->data, 0x0005);
-	byte_stream_put16(&frame->data, 2+8+16+6+4+4+iconlen+4+4+4+strlen(AIM_ICONIDENT));
-
-	byte_stream_put16(&frame->data, 0x0000);
-	byte_stream_putraw(&frame->data, cookie, 8);
-	byte_stream_putcaps(&frame->data, OSCAR_CAPABILITY_BUDDYICON);
+	byte_stream_put16(&bs, 0x0005);
+	byte_stream_put16(&bs, 2+8+16+6+4+4+iconlen+4+4+4+strlen(AIM_ICONIDENT));
+
+	byte_stream_put16(&bs, 0x0000);
+	byte_stream_putraw(&bs, cookie, 8);
+	byte_stream_putcaps(&bs, OSCAR_CAPABILITY_BUDDYICON);
 
 	/* TLV t(000a) */
-	byte_stream_put16(&frame->data, 0x000a);
-	byte_stream_put16(&frame->data, 0x0002);
-	byte_stream_put16(&frame->data, 0x0001);
+	byte_stream_put16(&bs, 0x000a);
+	byte_stream_put16(&bs, 0x0002);
+	byte_stream_put16(&bs, 0x0001);
 
 	/* TLV t(000f) */
-	byte_stream_put16(&frame->data, 0x000f);
-	byte_stream_put16(&frame->data, 0x0000);
+	byte_stream_put16(&bs, 0x000f);
+	byte_stream_put16(&bs, 0x0000);
 
 	/* TLV t(2711) */
-	byte_stream_put16(&frame->data, 0x2711);
-	byte_stream_put16(&frame->data, 4+4+4+iconlen+strlen(AIM_ICONIDENT));
-	byte_stream_put16(&frame->data, 0x0000);
-	byte_stream_put16(&frame->data, iconsum);
-	byte_stream_put32(&frame->data, iconlen);
-	byte_stream_put32(&frame->data, stamp);
-	byte_stream_putraw(&frame->data, icon, iconlen);
-	byte_stream_putstr(&frame->data, AIM_ICONIDENT);
+	byte_stream_put16(&bs, 0x2711);
+	byte_stream_put16(&bs, 4+4+4+iconlen+strlen(AIM_ICONIDENT));
+	byte_stream_put16(&bs, 0x0000);
+	byte_stream_put16(&bs, iconsum);
+	byte_stream_put32(&bs, iconlen);
+	byte_stream_put32(&bs, stamp);
+	byte_stream_putraw(&bs, icon, iconlen);
+	byte_stream_putstr(&bs, AIM_ICONIDENT);
 
 	/* TLV t(0003) */
-	byte_stream_put16(&frame->data, 0x0003);
-	byte_stream_put16(&frame->data, 0x0000);
-
-	flap_connection_send(conn, frame);
-
+	byte_stream_put16(&bs, 0x0003);
+	byte_stream_put16(&bs, 0x0000);
+
+	flap_connection_send_snac(od, conn, 0x0004, 0x0006, 0x0000, snacid, &bs);
+
+	byte_stream_destroy(&bs);
+	
 	return 0;
 }
 
@@ -612,7 +614,7 @@
 int aim_im_sendch2_rtfmsg(OscarData *od, struct aim_sendrtfmsg_args *args)
 {
 	FlapConnection *conn;
-	FlapFrame *frame;
+	ByteStream bs;
 	aim_snacid_t snacid;
 	guchar cookie[8];
 	const char rtfcap[] = {"{97B12751-243C-4334-AD22-D6ABF73F1492}"}; /* OSCAR_CAPABILITY_ICQRTF capability in string form */
@@ -628,61 +630,62 @@
 
 	aim_icbm_makecookie(cookie);
 
-	frame = flap_frame_new(od, 0x02, 10+128+servdatalen);
+	byte_stream_new(&bs, 128+servdatalen);
 
 	snacid = aim_cachesnac(od, 0x0004, 0x0006, 0x0000, NULL, 0);
-	aim_putsnac(&frame->data, 0x0004, 0x0006, 0x0000, snacid);
 
 	/* ICBM header */
-	aim_im_puticbm(&frame->data, cookie, 0x0002, args->destsn);
+	aim_im_puticbm(&bs, cookie, 0x0002, args->destsn);
 
 	/* TLV t(0005) - Encompasses everything below. */
-	byte_stream_put16(&frame->data, 0x0005);
-	byte_stream_put16(&frame->data, 2+8+16  +  2+2+2  +  2+2  +  2+2+servdatalen);
-
-	byte_stream_put16(&frame->data, 0x0000);
-	byte_stream_putraw(&frame->data, cookie, 8);
-	byte_stream_putcaps(&frame->data, OSCAR_CAPABILITY_ICQSERVERRELAY);
+	byte_stream_put16(&bs, 0x0005);
+	byte_stream_put16(&bs, 2+8+16  +  2+2+2  +  2+2  +  2+2+servdatalen);
+
+	byte_stream_put16(&bs, 0x0000);
+	byte_stream_putraw(&bs, cookie, 8);
+	byte_stream_putcaps(&bs, OSCAR_CAPABILITY_ICQSERVERRELAY);
 
 	/* t(000a) l(0002) v(0001) */
-	byte_stream_put16(&frame->data, 0x000a);
-	byte_stream_put16(&frame->data, 0x0002);
-	byte_stream_put16(&frame->data, 0x0001);
+	byte_stream_put16(&bs, 0x000a);
+	byte_stream_put16(&bs, 0x0002);
+	byte_stream_put16(&bs, 0x0001);
 
 	/* t(000f) l(0000) v() */
-	byte_stream_put16(&frame->data, 0x000f);
-	byte_stream_put16(&frame->data, 0x0000);
+	byte_stream_put16(&bs, 0x000f);
+	byte_stream_put16(&bs, 0x0000);
 
 	/* Service Data TLV */
-	byte_stream_put16(&frame->data, 0x2711);
-	byte_stream_put16(&frame->data, servdatalen);
-
-	byte_stream_putle16(&frame->data, 11 + 16 /* 11 + (sizeof CLSID) */);
-	byte_stream_putle16(&frame->data, 9);
-	byte_stream_putcaps(&frame->data, OSCAR_CAPABILITY_EMPTY);
-	byte_stream_putle16(&frame->data, 0);
-	byte_stream_putle32(&frame->data, 0);
-	byte_stream_putle8(&frame->data, 0);
-	byte_stream_putle16(&frame->data, 0x03ea); /* trid1 */
-
-	byte_stream_putle16(&frame->data, 14);
-	byte_stream_putle16(&frame->data, 0x03eb); /* trid2 */
-	byte_stream_putle32(&frame->data, 0);
-	byte_stream_putle32(&frame->data, 0);
-	byte_stream_putle32(&frame->data, 0);
-
-	byte_stream_putle16(&frame->data, 0x0001);
-	byte_stream_putle32(&frame->data, 0);
-	byte_stream_putle16(&frame->data, strlen(args->rtfmsg)+1);
-	byte_stream_putraw(&frame->data, (const guint8 *)args->rtfmsg, strlen(args->rtfmsg)+1);
-
-	byte_stream_putle32(&frame->data, args->fgcolor);
-	byte_stream_putle32(&frame->data, args->bgcolor);
-	byte_stream_putle32(&frame->data, strlen(rtfcap)+1);
-	byte_stream_putraw(&frame->data, (const guint8 *)rtfcap, strlen(rtfcap)+1);
-
-	flap_connection_send(conn, frame);
-
+	byte_stream_put16(&bs, 0x2711);
+	byte_stream_put16(&bs, servdatalen);
+
+	byte_stream_putle16(&bs, 11 + 16 /* 11 + (sizeof CLSID) */);
+	byte_stream_putle16(&bs, 9);
+	byte_stream_putcaps(&bs, OSCAR_CAPABILITY_EMPTY);
+	byte_stream_putle16(&bs, 0);
+	byte_stream_putle32(&bs, 0);
+	byte_stream_putle8(&bs, 0);
+	byte_stream_putle16(&bs, 0x03ea); /* trid1 */
+
+	byte_stream_putle16(&bs, 14);
+	byte_stream_putle16(&bs, 0x03eb); /* trid2 */
+	byte_stream_putle32(&bs, 0);
+	byte_stream_putle32(&bs, 0);
+	byte_stream_putle32(&bs, 0);
+
+	byte_stream_putle16(&bs, 0x0001);
+	byte_stream_putle32(&bs, 0);
+	byte_stream_putle16(&bs, strlen(args->rtfmsg)+1);
+	byte_stream_putraw(&bs, (const guint8 *)args->rtfmsg, strlen(args->rtfmsg)+1);
+
+	byte_stream_putle32(&bs, args->fgcolor);
+	byte_stream_putle32(&bs, args->bgcolor);
+	byte_stream_putle32(&bs, strlen(rtfcap)+1);
+	byte_stream_putraw(&bs, (const guint8 *)rtfcap, strlen(rtfcap)+1);
+
+	flap_connection_send_snac(od, conn, 0x0004, 0x0006, 0x0000, snacid, &bs);
+
+	byte_stream_destroy(&bs);
+	
 	return 0;
 }
 
@@ -695,7 +698,7 @@
 {
 	OscarData *od;
 	FlapConnection *conn;
-	FlapFrame *frame;
+	ByteStream bs;
 	aim_snacid_t snacid;
 	GSList *outer_tlvlist = NULL, *inner_tlvlist = NULL;
 	ByteStream hdrbs;
@@ -705,13 +708,12 @@
 	if (conn == NULL)
 		return;
 
-	frame = flap_frame_new(od, 0x02, 128+strlen(peer_conn->sn));
+	byte_stream_new(&bs, 118+strlen(peer_conn->sn));
 
 	snacid = aim_cachesnac(od, 0x0004, 0x0006, 0x0000, NULL, 0);
-	aim_putsnac(&frame->data, 0x0004, 0x0006, 0x0000, snacid);
 
 	/* ICBM header */
-	aim_im_puticbm(&frame->data, peer_conn->cookie, 0x0002, peer_conn->sn);
+	aim_im_puticbm(&bs, peer_conn->cookie, 0x0002, peer_conn->sn);
 
 	aim_tlvlist_add_noval(&outer_tlvlist, 0x0003);
 
@@ -728,12 +730,14 @@
 	aim_tlvlist_add_raw(&outer_tlvlist, 0x0005, byte_stream_curpos(&hdrbs), hdrbs.data);
 	g_free(hdrbs.data);
 
-	aim_tlvlist_write(&frame->data, &outer_tlvlist);
+	aim_tlvlist_write(&bs, &outer_tlvlist);
 
 	aim_tlvlist_free(inner_tlvlist);
 	aim_tlvlist_free(outer_tlvlist);
 
-	flap_connection_send(conn, frame);
+	flap_connection_send_snac(od, conn, 0x0004, 0x0006, 0x0000, snacid, &bs);
+
+	byte_stream_destroy(&bs);
 }
 
 /**
@@ -745,7 +749,7 @@
 {
 	OscarData *od;
 	FlapConnection *conn;
-	FlapFrame *frame;
+	ByteStream bs;
 	aim_snacid_t snacid;
 
 	od = peer_conn->od;
@@ -753,21 +757,22 @@
 	if (conn == NULL)
 		return;
 
-	frame = flap_frame_new(od, 0x02, 10 + 11+strlen(peer_conn->sn) + 4+2+8+16);
+	byte_stream_new(&bs, 11+strlen(peer_conn->sn) + 4+2+8+16);
 
 	snacid = aim_cachesnac(od, 0x0004, 0x0006, 0x0000, NULL, 0);
-	aim_putsnac(&frame->data, 0x0004, 0x0006, 0x0000, snacid);
 
 	/* ICBM header */
-	aim_im_puticbm(&frame->data, peer_conn->cookie, 0x0002, peer_conn->sn);
-
-	byte_stream_put16(&frame->data, 0x0005);
-	byte_stream_put16(&frame->data, 0x001a);
-	byte_stream_put16(&frame->data, AIM_RENDEZVOUS_CONNECTED);
-	byte_stream_putraw(&frame->data, peer_conn->cookie, 8);
-	byte_stream_putcaps(&frame->data, peer_conn->type);
-
-	flap_connection_send(conn, frame);
+	aim_im_puticbm(&bs, peer_conn->cookie, 0x0002, peer_conn->sn);
+
+	byte_stream_put16(&bs, 0x0005);
+	byte_stream_put16(&bs, 0x001a);
+	byte_stream_put16(&bs, AIM_RENDEZVOUS_CONNECTED);
+	byte_stream_putraw(&bs, peer_conn->cookie, 8);
+	byte_stream_putcaps(&bs, peer_conn->type);
+
+	flap_connection_send_snac(od, conn, 0x0004, 0x0006, 0x0000, snacid, &bs);
+
+	byte_stream_destroy(&bs);	
 }
 
 /**
@@ -781,7 +786,7 @@
 aim_im_sendch2_odc_requestdirect(OscarData *od, guchar *cookie, const char *sn, const guint8 *ip, guint16 port, guint16 requestnumber)
 {
 	FlapConnection *conn;
-	FlapFrame *frame;
+	ByteStream bs;
 	aim_snacid_t snacid;
 	GSList *outer_tlvlist = NULL, *inner_tlvlist = NULL;
 	ByteStream hdrbs;
@@ -790,13 +795,12 @@
 	if (conn == NULL)
 		return;
 
-	frame = flap_frame_new(od, 0x02, 256+strlen(sn));
+	byte_stream_new(&bs, 246+strlen(sn));
 
 	snacid = aim_cachesnac(od, 0x0004, 0x0006, 0x0000, NULL, 0);
-	aim_putsnac(&frame->data, 0x0004, 0x0006, 0x0000, snacid);
 
 	/* ICBM header */
-	aim_im_puticbm(&frame->data, cookie, 0x0002, sn);
+	aim_im_puticbm(&bs, cookie, 0x0002, sn);
 
 	aim_tlvlist_add_noval(&outer_tlvlist, 0x0003);
 
@@ -814,14 +818,16 @@
 	aim_tlvlist_write(&hdrbs, &inner_tlvlist);
 
 	aim_tlvlist_add_raw(&outer_tlvlist, 0x0005, byte_stream_curpos(&hdrbs), hdrbs.data);
-	g_free(hdrbs.data);
-
-	aim_tlvlist_write(&frame->data, &outer_tlvlist);
+	byte_stream_destroy(&hdrbs);
+
+	aim_tlvlist_write(&bs, &outer_tlvlist);
 
 	aim_tlvlist_free(inner_tlvlist);
 	aim_tlvlist_free(outer_tlvlist);
 
-	flap_connection_send(conn, frame);
+	flap_connection_send_snac(od, conn, 0x0004, 0x0006, 0x0000, snacid, &bs);
+
+	byte_stream_destroy(&bs);
 }
 
 /**
@@ -832,7 +838,7 @@
 aim_im_sendch2_odc_requestproxy(OscarData *od, guchar *cookie, const char *sn, const guint8 *ip, guint16 pin, guint16 requestnumber)
 {
 	FlapConnection *conn;
-	FlapFrame *frame;
+	ByteStream bs;
 	aim_snacid_t snacid;
 	GSList *outer_tlvlist = NULL, *inner_tlvlist = NULL;
 	ByteStream hdrbs;
@@ -842,13 +848,12 @@
 	if (conn == NULL)
 		return;
 
-	frame = flap_frame_new(od, 0x02, 256+strlen(sn));
+	byte_stream_new(&bs, 246+strlen(sn));
 
 	snacid = aim_cachesnac(od, 0x0004, 0x0006, 0x0000, NULL, 0);
-	aim_putsnac(&frame->data, 0x0004, 0x0006, 0x0000, snacid);
 
 	/* ICBM header */
-	aim_im_puticbm(&frame->data, cookie, 0x0002, sn);
+	aim_im_puticbm(&bs, cookie, 0x0002, sn);
 
 	aim_tlvlist_add_noval(&outer_tlvlist, 0x0003);
 
@@ -876,14 +881,16 @@
 	aim_tlvlist_write(&hdrbs, &inner_tlvlist);
 
 	aim_tlvlist_add_raw(&outer_tlvlist, 0x0005, byte_stream_curpos(&hdrbs), hdrbs.data);
-	g_free(hdrbs.data);
-
-	aim_tlvlist_write(&frame->data, &outer_tlvlist);
+	byte_stream_destroy(&hdrbs);
+
+	aim_tlvlist_write(&bs, &outer_tlvlist);
 
 	aim_tlvlist_free(inner_tlvlist);
 	aim_tlvlist_free(outer_tlvlist);
 
-	flap_connection_send(conn, frame);
+	flap_connection_send_snac(od, conn, 0x0004, 0x0006, 0x0000, snacid, &bs);
+
+	byte_stream_destroy(&bs);
 }
 
 /**
@@ -894,7 +901,7 @@
 aim_im_sendch2_sendfile_requestdirect(OscarData *od, guchar *cookie, const char *sn, const guint8 *ip, guint16 port, guint16 requestnumber, const gchar *filename, guint32 size, guint16 numfiles)
 {
 	FlapConnection *conn;
-	FlapFrame *frame;
+	ByteStream bs;
 	aim_snacid_t snacid;
 	GSList *outer_tlvlist = NULL, *inner_tlvlist = NULL;
 	ByteStream hdrbs;
@@ -903,13 +910,12 @@
 	if (conn == NULL)
 		return;
 
-	frame = flap_frame_new(od, 0x02, 1024);
+	byte_stream_new(&bs, 1014);
 
 	snacid = aim_cachesnac(od, 0x0004, 0x0006, 0x0000, NULL, 0);
-	aim_putsnac(&frame->data, 0x0004, 0x0006, 0x0000, snacid);
 
 	/* ICBM header */
-	aim_im_puticbm(&frame->data, cookie, 0x0002, sn);
+	aim_im_puticbm(&bs, cookie, 0x0002, sn);
 
 	aim_tlvlist_add_noval(&outer_tlvlist, 0x0003);
 
@@ -958,14 +964,16 @@
 
 	aim_tlvlist_write(&hdrbs, &inner_tlvlist);
 	aim_tlvlist_add_raw(&outer_tlvlist, 0x0005, byte_stream_curpos(&hdrbs), hdrbs.data);
-	g_free(hdrbs.data);
-
-	aim_tlvlist_write(&frame->data, &outer_tlvlist);
+	byte_stream_destroy(&hdrbs);
+
+	aim_tlvlist_write(&bs, &outer_tlvlist);
 
 	aim_tlvlist_free(inner_tlvlist);
 	aim_tlvlist_free(outer_tlvlist);
 
-	flap_connection_send(conn, frame);
+	flap_connection_send_snac(od, conn, 0x0004, 0x0006, 0x0000, snacid, &bs);
+
+	byte_stream_destroy(&bs);
 }
 
 /**
@@ -976,7 +984,7 @@
 aim_im_sendch2_sendfile_requestproxy(OscarData *od, guchar *cookie, const char *sn, const guint8 *ip, guint16 pin, guint16 requestnumber, const gchar *filename, guint32 size, guint16 numfiles)
 {
 	FlapConnection *conn;
-	FlapFrame *frame;
+	ByteStream bs;
 	aim_snacid_t snacid;
 	GSList *outer_tlvlist = NULL, *inner_tlvlist = NULL;
 	ByteStream hdrbs;
@@ -986,13 +994,12 @@
 	if (conn == NULL)
 		return;
 
-	frame = flap_frame_new(od, 0x02, 1024);
+	byte_stream_new(&bs, 1014);
 
 	snacid = aim_cachesnac(od, 0x0004, 0x0006, 0x0000, NULL, 0);
-	aim_putsnac(&frame->data, 0x0004, 0x0006, 0x0000, snacid);
 
 	/* ICBM header */
-	aim_im_puticbm(&frame->data, cookie, 0x0002, sn);
+	aim_im_puticbm(&bs, cookie, 0x0002, sn);
 
 	aim_tlvlist_add_noval(&outer_tlvlist, 0x0003);
 
@@ -1030,34 +1037,36 @@
 
 	if (filename != NULL)
 	{
-		ByteStream bs;
+		ByteStream filename_bs;
 
 		/* Begin TLV t(2711) */
-		byte_stream_new(&bs, 2+2+4+strlen(filename)+1);
-		byte_stream_put16(&bs, (numfiles > 1) ? 0x0002 : 0x0001);
-		byte_stream_put16(&bs, numfiles);
-		byte_stream_put32(&bs, size);
+		byte_stream_new(&filename_bs, 2+2+4+strlen(filename)+1);
+		byte_stream_put16(&filename_bs, (numfiles > 1) ? 0x0002 : 0x0001);
+		byte_stream_put16(&filename_bs, numfiles);
+		byte_stream_put32(&filename_bs, size);
 
 		/* Filename - NULL terminated, for some odd reason */
-		byte_stream_putstr(&bs, filename);
-		byte_stream_put8(&bs, 0x00);
-
-		aim_tlvlist_add_raw(&inner_tlvlist, 0x2711, bs.len, bs.data);
-		g_free(bs.data);
+		byte_stream_putstr(&filename_bs, filename);
+		byte_stream_put8(&filename_bs, 0x00);
+
+		aim_tlvlist_add_raw(&inner_tlvlist, 0x2711, filename_bs.len, filename_bs.data);
+		byte_stream_destroy(&filename_bs);
 		/* End TLV t(2711) */
 	}
 
 	aim_tlvlist_write(&hdrbs, &inner_tlvlist);
 
 	aim_tlvlist_add_raw(&outer_tlvlist, 0x0005, byte_stream_curpos(&hdrbs), hdrbs.data);
-	g_free(hdrbs.data);
-
-	aim_tlvlist_write(&frame->data, &outer_tlvlist);
+	byte_stream_destroy(&hdrbs);
+
+	aim_tlvlist_write(&bs, &outer_tlvlist);
 
 	aim_tlvlist_free(inner_tlvlist);
 	aim_tlvlist_free(outer_tlvlist);
 
-	flap_connection_send(conn, frame);
+	flap_connection_send_snac(od, conn, 0x0004, 0x0006, 0x0000, snacid, &bs);
+
+	byte_stream_destroy(&bs);
 }
 
 /**
@@ -1072,7 +1081,7 @@
 int aim_im_sendch2_geticqaway(OscarData *od, const char *sn, int type)
 {
 	FlapConnection *conn;
-	FlapFrame *frame;
+	ByteStream bs;
 	aim_snacid_t snacid;
 	guchar cookie[8];
 
@@ -1081,79 +1090,80 @@
 
 	aim_icbm_makecookie(cookie);
 
-	frame = flap_frame_new(od, 0x02, 10+8+2+1+strlen(sn) + 4+0x5e + 4);
+	byte_stream_new(&bs, 8+2+1+strlen(sn) + 4+0x5e + 4);
 
 	snacid = aim_cachesnac(od, 0x0004, 0x0006, 0x0000, NULL, 0);
-	aim_putsnac(&frame->data, 0x0004, 0x0006, 0x0000, snacid);
 
 	/* ICBM header */
-	aim_im_puticbm(&frame->data, cookie, 0x0002, sn);
+	aim_im_puticbm(&bs, cookie, 0x0002, sn);
 
 	/* TLV t(0005) - Encompasses almost everything below. */
-	byte_stream_put16(&frame->data, 0x0005); /* T */
-	byte_stream_put16(&frame->data, 0x005e); /* L */
+	byte_stream_put16(&bs, 0x0005); /* T */
+	byte_stream_put16(&bs, 0x005e); /* L */
 	{ /* V */
-		byte_stream_put16(&frame->data, 0x0000);
+		byte_stream_put16(&bs, 0x0000);
 
 		/* Cookie */
-		byte_stream_putraw(&frame->data, cookie, 8);
+		byte_stream_putraw(&bs, cookie, 8);
 
 		/* Put the 16 byte server relay capability */
-		byte_stream_putcaps(&frame->data, OSCAR_CAPABILITY_ICQSERVERRELAY);
+		byte_stream_putcaps(&bs, OSCAR_CAPABILITY_ICQSERVERRELAY);
 
 		/* TLV t(000a) */
-		byte_stream_put16(&frame->data, 0x000a);
-		byte_stream_put16(&frame->data, 0x0002);
-		byte_stream_put16(&frame->data, 0x0001);
+		byte_stream_put16(&bs, 0x000a);
+		byte_stream_put16(&bs, 0x0002);
+		byte_stream_put16(&bs, 0x0001);
 
 		/* TLV t(000f) */
-		byte_stream_put16(&frame->data, 0x000f);
-		byte_stream_put16(&frame->data, 0x0000);
+		byte_stream_put16(&bs, 0x000f);
+		byte_stream_put16(&bs, 0x0000);
 
 		/* TLV t(2711) */
-		byte_stream_put16(&frame->data, 0x2711);
-		byte_stream_put16(&frame->data, 0x0036);
+		byte_stream_put16(&bs, 0x2711);
+		byte_stream_put16(&bs, 0x0036);
 		{ /* V */
-			byte_stream_putle16(&frame->data, 0x001b); /* L */
-			byte_stream_putle16(&frame->data, 0x0009); /* Protocol version */
-			byte_stream_putcaps(&frame->data, OSCAR_CAPABILITY_EMPTY);
-			byte_stream_putle16(&frame->data, 0x0000); /* Unknown */
-			byte_stream_putle16(&frame->data, 0x0001); /* Client features? */
-			byte_stream_putle16(&frame->data, 0x0000); /* Unknown */
-			byte_stream_putle8(&frame->data, 0x00); /* Unkizown */
-			byte_stream_putle16(&frame->data, 0xffff); /* Sequence number?  XXX - This should decrement by 1 with each request */
-
-			byte_stream_putle16(&frame->data, 0x000e); /* L */
-			byte_stream_putle16(&frame->data, 0xffff); /* Sequence number?  XXX - This should decrement by 1 with each request */
-			byte_stream_putle32(&frame->data, 0x00000000); /* Unknown */
-			byte_stream_putle32(&frame->data, 0x00000000); /* Unknown */
-			byte_stream_putle32(&frame->data, 0x00000000); /* Unknown */
+			byte_stream_putle16(&bs, 0x001b); /* L */
+			byte_stream_putle16(&bs, 0x0009); /* Protocol version */
+			byte_stream_putcaps(&bs, OSCAR_CAPABILITY_EMPTY);
+			byte_stream_putle16(&bs, 0x0000); /* Unknown */
+			byte_stream_putle16(&bs, 0x0001); /* Client features? */
+			byte_stream_putle16(&bs, 0x0000); /* Unknown */
+			byte_stream_putle8(&bs, 0x00); /* Unkizown */
+			byte_stream_putle16(&bs, 0xffff); /* Sequence number?  XXX - This should decrement by 1 with each request */
+
+			byte_stream_putle16(&bs, 0x000e); /* L */
+			byte_stream_putle16(&bs, 0xffff); /* Sequence number?  XXX - This should decrement by 1 with each request */
+			byte_stream_putle32(&bs, 0x00000000); /* Unknown */
+			byte_stream_putle32(&bs, 0x00000000); /* Unknown */
+			byte_stream_putle32(&bs, 0x00000000); /* Unknown */
 
 			/* The type of status message being requested */
 			if (type & AIM_ICQ_STATE_CHAT)
-				byte_stream_putle16(&frame->data, 0x03ec);
+				byte_stream_putle16(&bs, 0x03ec);
 			else if(type & AIM_ICQ_STATE_DND)
-				byte_stream_putle16(&frame->data, 0x03eb);
+				byte_stream_putle16(&bs, 0x03eb);
 			else if(type & AIM_ICQ_STATE_OUT)
-				byte_stream_putle16(&frame->data, 0x03ea);
+				byte_stream_putle16(&bs, 0x03ea);
 			else if(type & AIM_ICQ_STATE_BUSY)
-				byte_stream_putle16(&frame->data, 0x03e9);
+				byte_stream_putle16(&bs, 0x03e9);
 			else if(type & AIM_ICQ_STATE_AWAY)
-				byte_stream_putle16(&frame->data, 0x03e8);
-
-			byte_stream_putle16(&frame->data, 0x0001); /* Status? */
-			byte_stream_putle16(&frame->data, 0x0001); /* Priority of this message? */
-			byte_stream_putle16(&frame->data, 0x0001); /* L */
-			byte_stream_putle8(&frame->data, 0x00); /* String of length L */
+				byte_stream_putle16(&bs, 0x03e8);
+
+			byte_stream_putle16(&bs, 0x0001); /* Status? */
+			byte_stream_putle16(&bs, 0x0001); /* Priority of this message? */
+			byte_stream_putle16(&bs, 0x0001); /* L */
+			byte_stream_putle8(&bs, 0x00); /* String of length L */
 		} /* End TLV t(2711) */
 	} /* End TLV t(0005) */
 
 	/* TLV t(0003) */
-	byte_stream_put16(&frame->data, 0x0003);
-	byte_stream_put16(&frame->data, 0x0000);
-
-	flap_connection_send(conn, frame);
-
+	byte_stream_put16(&bs, 0x0003);
+	byte_stream_put16(&bs, 0x0000);
+
+	flap_connection_send_snac(od, conn, 0x0004, 0x0006, 0x0000, snacid, &bs);
+
+	byte_stream_destroy(&bs);
+	
 	return 0;
 }
 
@@ -1174,7 +1184,7 @@
 int aim_im_sendch4(OscarData *od, const char *sn, guint16 type, const char *message)
 {
 	FlapConnection *conn;
-	FlapFrame *frame;
+	ByteStream bs;
 	aim_snacid_t snacid;
 	guchar cookie[8];
 
@@ -1184,44 +1194,45 @@
 	if (!sn || !type || !message)
 		return -EINVAL;
 
-	frame = flap_frame_new(od, 0x02, 10+8+3+strlen(sn)+12+strlen(message)+1+4);
+	byte_stream_new(&bs, 8+3+strlen(sn)+12+strlen(message)+1+4);
 
 	snacid = aim_cachesnac(od, 0x0004, 0x0006, 0x0000, NULL, 0);
-	aim_putsnac(&frame->data, 0x0004, 0x0006, 0x0000, snacid);
 
 	aim_icbm_makecookie(cookie);
 
 	/* ICBM header */
-	aim_im_puticbm(&frame->data, cookie, 0x0004, sn);
+	aim_im_puticbm(&bs, cookie, 0x0004, sn);
 
 	/*
 	 * TLV t(0005)
 	 *
 	 * ICQ data (the UIN and the message).
 	 */
-	byte_stream_put16(&frame->data, 0x0005);
-	byte_stream_put16(&frame->data, 4 + 2+2+strlen(message)+1);
+	byte_stream_put16(&bs, 0x0005);
+	byte_stream_put16(&bs, 4 + 2+2+strlen(message)+1);
 
 	/*
 	 * Your UIN
 	 */
-	byte_stream_putle32(&frame->data, atoi(od->sn));
+	byte_stream_putle32(&bs, atoi(od->sn));
 
 	/*
 	 * TLV t(type) l(strlen(message)+1) v(message+NULL)
 	 */
-	byte_stream_putle16(&frame->data, type);
-	byte_stream_putle16(&frame->data, strlen(message)+1);
-	byte_stream_putraw(&frame->data, (const guint8 *)message, strlen(message)+1);
+	byte_stream_putle16(&bs, type);
+	byte_stream_putle16(&bs, strlen(message)+1);
+	byte_stream_putraw(&bs, (const guint8 *)message, strlen(message)+1);
 
 	/*
 	 * TLV t(0006) l(0000) v()
 	 */
-	byte_stream_put16(&frame->data, 0x0006);
-	byte_stream_put16(&frame->data, 0x0000);
-
-	flap_connection_send(conn, frame);
-
+	byte_stream_put16(&bs, 0x0006);
+	byte_stream_put16(&bs, 0x0000);
+
+	flap_connection_send_snac(od, conn, 0x0004, 0x0006, 0x0000, snacid, &bs);
+
+	byte_stream_destroy(&bs);
+	
 	return 0;
 }
 
@@ -2249,22 +2260,23 @@
  */
 int aim_im_warn(OscarData *od, FlapConnection *conn, const char *sn, guint32 flags)
 {
-	FlapFrame *frame;
+	ByteStream bs;
 	aim_snacid_t snacid;
 
 	if (!od || !conn || !sn)
 		return -EINVAL;
 
-	frame = flap_frame_new(od, 0x02, strlen(sn)+13);
+	byte_stream_new(&bs, strlen(sn)+3);
 
 	snacid = aim_cachesnac(od, 0x0004, 0x0008, 0x0000, sn, strlen(sn)+1);
-	aim_putsnac(&frame->data, 0x0004, 0x0008, 0x0000, snacid);
-
-	byte_stream_put16(&frame->data, (flags & AIM_WARN_ANON) ? 0x0001 : 0x0000);
-	byte_stream_put8(&frame->data, strlen(sn));
-	byte_stream_putstr(&frame->data, sn);
-
-	flap_connection_send(conn, frame);
+
+	byte_stream_put16(&bs, (flags & AIM_WARN_ANON) ? 0x0001 : 0x0000);
+	byte_stream_put8(&bs, strlen(sn));
+	byte_stream_putstr(&bs, sn);
+
+	flap_connection_send_snac(od, conn, 0x0004, 0x0008, 0x0000, snacid, &bs);
+
+	byte_stream_destroy(&bs);
 
 	return 0;
 }
@@ -2305,29 +2317,30 @@
 int aim_im_denytransfer(OscarData *od, const char *sn, const guchar *cookie, guint16 code)
 {
 	FlapConnection *conn;
-	FlapFrame *frame;
+	ByteStream bs;
 	aim_snacid_t snacid;
 	GSList *tlvlist = NULL;
 
 	if (!od || !(conn = flap_connection_findbygroup(od, 0x0004)))
 		return -EINVAL;
 
-	frame = flap_frame_new(od, 0x02, 10+8+2+1+strlen(sn)+6);
+	byte_stream_new(&bs, 8+2+1+strlen(sn)+6);
 
 	snacid = aim_cachesnac(od, 0x0004, 0x000b, 0x0000, NULL, 0);
-	aim_putsnac(&frame->data, 0x0004, 0x000b, 0x0000, snacid);
-
-	byte_stream_putraw(&frame->data, cookie, 8);
-
-	byte_stream_put16(&frame->data, 0x0002); /* channel */
-	byte_stream_put8(&frame->data, strlen(sn));
-	byte_stream_putstr(&frame->data, sn);
+
+	byte_stream_putraw(&bs, cookie, 8);
+
+	byte_stream_put16(&bs, 0x0002); /* channel */
+	byte_stream_put8(&bs, strlen(sn));
+	byte_stream_putstr(&bs, sn);
 
 	aim_tlvlist_add_16(&tlvlist, 0x0003, code);
-	aim_tlvlist_write(&frame->data, &tlvlist);
+	aim_tlvlist_write(&bs, &tlvlist);
 	aim_tlvlist_free(tlvlist);
 
-	flap_connection_send(conn, frame);
+	flap_connection_send_snac(od, conn, 0x0004, 0x000b, 0x0000, snacid, &bs);
+	
+	byte_stream_destroy(&bs);
 
 	return 0;
 }
@@ -2662,7 +2675,7 @@
 int aim_im_sendmtn(OscarData *od, guint16 type1, const char *sn, guint16 type2)
 {
 	FlapConnection *conn;
-	FlapFrame *frame;
+	ByteStream bs;
 	aim_snacid_t snacid;
 
 	if (!od || !(conn = flap_connection_findbygroup(od, 0x0002)))
@@ -2671,38 +2684,39 @@
 	if (!sn)
 		return -EINVAL;
 
-	frame = flap_frame_new(od, 0x02, 10+11+strlen(sn)+2);
+	byte_stream_new(&bs, 11+strlen(sn)+2);
 
 	snacid = aim_cachesnac(od, 0x0004, 0x0014, 0x0000, NULL, 0);
-	aim_putsnac(&frame->data, 0x0004, 0x0014, 0x0000, snacid);
 
 	/*
 	 * 8 days of light
 	 * Er, that is to say, 8 bytes of 0's
 	 */
-	byte_stream_put16(&frame->data, 0x0000);
-	byte_stream_put16(&frame->data, 0x0000);
-	byte_stream_put16(&frame->data, 0x0000);
-	byte_stream_put16(&frame->data, 0x0000);
+	byte_stream_put16(&bs, 0x0000);
+	byte_stream_put16(&bs, 0x0000);
+	byte_stream_put16(&bs, 0x0000);
+	byte_stream_put16(&bs, 0x0000);
 
 	/*
 	 * Type 1 (should be 0x0001 for mtn)
 	 */
-	byte_stream_put16(&frame->data, type1);
+	byte_stream_put16(&bs, type1);
 
 	/*
 	 * Dest sn
 	 */
-	byte_stream_put8(&frame->data, strlen(sn));
-	byte_stream_putstr(&frame->data, sn);
+	byte_stream_put8(&bs, strlen(sn));
+	byte_stream_putstr(&bs, sn);
 
 	/*
 	 * Type 2 (should be 0x0000, 0x0001, or 0x0002 for mtn)
 	 */
-	byte_stream_put16(&frame->data, type2);
-
-	flap_connection_send(conn, frame);
-
+	byte_stream_put16(&bs, type2);
+
+	flap_connection_send_snac(od, conn, 0x0004, 0x0014, 0x0000, snacid, &bs);
+
+	byte_stream_destroy(&bs);
+	
 	return 0;
 }
 
--- a/libpurple/protocols/oscar/family_icq.c	Thu Apr 24 02:16:30 2008 +0000
+++ b/libpurple/protocols/oscar/family_icq.c	Thu Apr 24 11:10:03 2008 +0000
@@ -29,7 +29,7 @@
 int aim_icq_reqofflinemsgs(OscarData *od)
 {
 	FlapConnection *conn;
-	FlapFrame *frame;
+	ByteStream bs;
 	aim_snacid_t snacid;
 	int bslen;
 
@@ -38,28 +38,29 @@
 
 	bslen = 2 + 4 + 2 + 2;
 
-	frame = flap_frame_new(od, 0x02, 10 + 4 + bslen);
+	byte_stream_new(&bs, 4 + bslen);
 
 	snacid = aim_cachesnac(od, 0x0015, 0x0002, 0x0000, NULL, 0);
-	aim_putsnac(&frame->data, 0x0015, 0x0002, 0x0000, snacid);
 
 	/* For simplicity, don't bother using a tlvlist */
-	byte_stream_put16(&frame->data, 0x0001);
-	byte_stream_put16(&frame->data, bslen);
+	byte_stream_put16(&bs, 0x0001);
+	byte_stream_put16(&bs, bslen);
 
-	byte_stream_putle16(&frame->data, bslen - 2);
-	byte_stream_putle32(&frame->data, atoi(od->sn));
-	byte_stream_putle16(&frame->data, 0x003c); /* I command thee. */
-	byte_stream_putle16(&frame->data, snacid); /* eh. */
+	byte_stream_putle16(&bs, bslen - 2);
+	byte_stream_putle32(&bs, atoi(od->sn));
+	byte_stream_putle16(&bs, 0x003c); /* I command thee. */
+	byte_stream_putle16(&bs, snacid); /* eh. */
 
-	flap_connection_send(conn, frame);
+	flap_connection_send_snac(od, conn, 0x0015, 0x0002, 0x0000, snacid, &bs);
+
+	byte_stream_destroy(&bs);
 
 	return 0;
 }
 
 int aim_icq_ackofflinemsgs(OscarData *od)
 {
-	FlapConnection *conn;
+	ByteStream bs;
 	FlapFrame *frame;
 	aim_snacid_t snacid;
 	int bslen;
@@ -69,21 +70,22 @@
 
 	bslen = 2 + 4 + 2 + 2;
 
-	frame = flap_frame_new(od, 0x02, 10 + 4 + bslen);
+	byte_stream_new(&bs, 4 + bslen);
 
 	snacid = aim_cachesnac(od, 0x0015, 0x0002, 0x0000, NULL, 0);
-	aim_putsnac(&frame->data, 0x0015, 0x0002, 0x0000, snacid);
 
 	/* For simplicity, don't bother using a tlvlist */
-	byte_stream_put16(&frame->data, 0x0001);
-	byte_stream_put16(&frame->data, bslen);
+	byte_stream_put16(&bs, 0x0001);
+	byte_stream_put16(&bs, bslen);
 
-	byte_stream_putle16(&frame->data, bslen - 2);
-	byte_stream_putle32(&frame->data, atoi(od->sn));
-	byte_stream_putle16(&frame->data, 0x003e); /* I command thee. */
-	byte_stream_putle16(&frame->data, snacid); /* eh. */
+	byte_stream_putle16(&bs, bslen - 2);
+	byte_stream_putle32(&bs, atoi(od->sn));
+	byte_stream_putle16(&bs, 0x003e); /* I command thee. */
+	byte_stream_putle16(&bs, snacid); /* eh. */
 
-	flap_connection_send(conn, frame);
+	flap_connection_send_snac(od, conn, 0x0015, 0x0002, 0x0000, snacid, &bs);
+
+	byte_stream_destroy(&bs);
 
 	return 0;
 }
@@ -93,7 +95,7 @@
 aim_icq_setsecurity(OscarData *od, gboolean auth_required, gboolean webaware)
 {
 	FlapConnection *conn;
-	FlapFrame *frame;
+	ByteStream bs;
 	aim_snacid_t snacid;
 	int bslen;
 
@@ -102,30 +104,31 @@
 
 	bslen = 2+4+2+2+2+2+2+1+1+1+1+1+1;
 
-	frame = flap_frame_new(od, 0x02, 10 + 4 + bslen);
+	byte_stream_new(&bs, 4 + bslen);
 
 	snacid = aim_cachesnac(od, 0x0015, 0x0002, 0x0000, NULL, 0);
-	aim_putsnac(&frame->data, 0x0015, 0x0002, 0x0000, snacid);
 
 	/* For simplicity, don't bother using a tlvlist */
-	byte_stream_put16(&frame->data, 0x0001);
-	byte_stream_put16(&frame->data, bslen);
+	byte_stream_put16(&bs, 0x0001);
+	byte_stream_put16(&bs, bslen);
 
-	byte_stream_putle16(&frame->data, bslen - 2);
-	byte_stream_putle32(&frame->data, atoi(od->sn));
-	byte_stream_putle16(&frame->data, 0x07d0); /* I command thee. */
-	byte_stream_putle16(&frame->data, snacid); /* eh. */
-	byte_stream_putle16(&frame->data, 0x0c3a); /* shrug. */
-	byte_stream_putle16(&frame->data, 0x030c);
-	byte_stream_putle16(&frame->data, 0x0001);
-	byte_stream_putle8(&frame->data, webaware);
-	byte_stream_putle8(&frame->data, 0xf8);
-	byte_stream_putle8(&frame->data, 0x02);
-	byte_stream_putle8(&frame->data, 0x01);
-	byte_stream_putle8(&frame->data, 0x00);
-	byte_stream_putle8(&frame->data, !auth_required);
+	byte_stream_putle16(&bs, bslen - 2);
+	byte_stream_putle32(&bs, atoi(od->sn));
+	byte_stream_putle16(&bs, 0x07d0); /* I command thee. */
+	byte_stream_putle16(&bs, snacid); /* eh. */
+	byte_stream_putle16(&bs, 0x0c3a); /* shrug. */
+	byte_stream_putle16(&bs, 0x030c);
+	byte_stream_putle16(&bs, 0x0001);
+	byte_stream_putle8(&bs, webaware);
+	byte_stream_putle8(&bs, 0xf8);
+	byte_stream_putle8(&bs, 0x02);
+	byte_stream_putle8(&bs, 0x01);
+	byte_stream_putle8(&bs, 0x00);
+	byte_stream_putle8(&bs, !auth_required);
 
-	flap_connection_send(conn, frame);
+	flap_connection_send_snac(od, conn, 0x0015, 0x0002, 0x0000, snacid, &bs);
+
+	byte_stream_destroy(&bs);
 
 	return 0;
 }
@@ -141,7 +144,7 @@
 int aim_icq_changepasswd(OscarData *od, const char *passwd)
 {
 	FlapConnection *conn;
-	FlapFrame *frame;
+	ByteStream bs;
 	aim_snacid_t snacid;
 	int bslen, passwdlen;
 
@@ -156,25 +159,26 @@
 		passwdlen = MAXICQPASSLEN;
 	bslen = 2+4+2+2+2+2+passwdlen+1;
 
-	frame = flap_frame_new(od, 0x02, 10 + 4 + bslen);
+	byte_stream_new(&bs, 4 + bslen);
 
 	snacid = aim_cachesnac(od, 0x0015, 0x0002, 0x0000, NULL, 0);
-	aim_putsnac(&frame->data, 0x0015, 0x0002, 0x0000, snacid);
 
 	/* For simplicity, don't bother using a tlvlist */
-	byte_stream_put16(&frame->data, 0x0001);
-	byte_stream_put16(&frame->data, bslen);
+	byte_stream_put16(&bs, 0x0001);
+	byte_stream_put16(&bs, bslen);
 
-	byte_stream_putle16(&frame->data, bslen - 2);
-	byte_stream_putle32(&frame->data, atoi(od->sn));
-	byte_stream_putle16(&frame->data, 0x07d0); /* I command thee. */
-	byte_stream_putle16(&frame->data, snacid); /* eh. */
-	byte_stream_putle16(&frame->data, 0x042e); /* shrug. */
-	byte_stream_putle16(&frame->data, passwdlen+1);
-	byte_stream_putstr(&frame->data, passwd);
-	byte_stream_putle8(&frame->data, '\0');
+	byte_stream_putle16(&bs, bslen - 2);
+	byte_stream_putle32(&bs, atoi(od->sn));
+	byte_stream_putle16(&bs, 0x07d0); /* I command thee. */
+	byte_stream_putle16(&bs, snacid); /* eh. */
+	byte_stream_putle16(&bs, 0x042e); /* shrug. */
+	byte_stream_putle16(&bs, passwdlen+1);
+	byte_stream_putstr(&bs, passwd);
+	byte_stream_putle8(&bs, '\0');
 
-	flap_connection_send(conn, frame);
+	flap_connection_send_snac(od, conn, 0x0015, 0x0002, 0x0000, snacid, &bs);
+
+	byte_stream_destroy(&bs);
 
 	return 0;
 }
@@ -182,7 +186,7 @@
 int aim_icq_getallinfo(OscarData *od, const char *uin)
 {
 	FlapConnection *conn;
-	FlapFrame *frame;
+	ByteStream bs;
 	aim_snacid_t snacid;
 	int bslen;
 	struct aim_icq_info *info;
@@ -195,23 +199,24 @@
 
 	bslen = 2 + 4 + 2 + 2 + 2 + 4;
 
-	frame = flap_frame_new(od, 0x02, 10 + 4 + bslen);
+	byte_stream_new(&bs, 4 + bslen);
 
 	snacid = aim_cachesnac(od, 0x0015, 0x0002, 0x0000, NULL, 0);
-	aim_putsnac(&frame->data, 0x0015, 0x0002, 0x0000, snacid);
 
 	/* For simplicity, don't bother using a tlvlist */
-	byte_stream_put16(&frame->data, 0x0001);
-	byte_stream_put16(&frame->data, bslen);
+	byte_stream_put16(&bs, 0x0001);
+	byte_stream_put16(&bs, bslen);
 
-	byte_stream_putle16(&frame->data, bslen - 2);
-	byte_stream_putle32(&frame->data, atoi(od->sn));
-	byte_stream_putle16(&frame->data, 0x07d0); /* I command thee. */
-	byte_stream_putle16(&frame->data, snacid); /* eh. */
-	byte_stream_putle16(&frame->data, 0x04b2); /* shrug. */
-	byte_stream_putle32(&frame->data, atoi(uin));
+	byte_stream_putle16(&bs, bslen - 2);
+	byte_stream_putle32(&bs, atoi(od->sn));
+	byte_stream_putle16(&bs, 0x07d0); /* I command thee. */
+	byte_stream_putle16(&bs, snacid); /* eh. */
+	byte_stream_putle16(&bs, 0x04b2); /* shrug. */
+	byte_stream_putle32(&bs, atoi(uin));
 
-	flap_connection_send(conn, frame);
+	flap_connection_send_snac(od, conn, 0x0015, 0x0002, 0x0000, snacid, &bs);
+
+	byte_stream_destroy(&bs);
 
 	/* Keep track of this request and the ICQ number and request ID */
 	info = (struct aim_icq_info *)g_new0(struct aim_icq_info, 1);
@@ -226,7 +231,7 @@
 int aim_icq_getalias(OscarData *od, const char *uin)
 {
 	FlapConnection *conn;
-	FlapFrame *frame;
+	ByteStream bs;
 	aim_snacid_t snacid;
 	int bslen;
 	struct aim_icq_info *info;
@@ -239,24 +244,25 @@
 
 	bslen = 2 + 4 + 2 + 2 + 2 + 4;
 
-	frame = flap_frame_new(od, 0x02, 10 + 4 + bslen);
+	byte_stream_new(&bs, 4 + bslen);
 
 	snacid = aim_cachesnac(od, 0x0015, 0x0002, 0x0000, NULL, 0);
-	aim_putsnac(&frame->data, 0x0015, 0x0002, 0x0000, snacid);
 
 	/* For simplicity, don't bother using a tlvlist */
-	byte_stream_put16(&frame->data, 0x0001);
-	byte_stream_put16(&frame->data, bslen);
+	byte_stream_put16(&bs, 0x0001);
+	byte_stream_put16(&bs, bslen);
 
-	byte_stream_putle16(&frame->data, bslen - 2);
-	byte_stream_putle32(&frame->data, atoi(od->sn));
-	byte_stream_putle16(&frame->data, 0x07d0); /* I command thee. */
-	byte_stream_putle16(&frame->data, snacid); /* eh. */
-	byte_stream_putle16(&frame->data, 0x04ba); /* shrug. */
-	byte_stream_putle32(&frame->data, atoi(uin));
+	byte_stream_putle16(&bs, bslen - 2);
+	byte_stream_putle32(&bs, atoi(od->sn));
+	byte_stream_putle16(&bs, 0x07d0); /* I command thee. */
+	byte_stream_putle16(&bs, snacid); /* eh. */
+	byte_stream_putle16(&bs, 0x04ba); /* shrug. */
+	byte_stream_putle32(&bs, atoi(uin));
 
-	flap_connection_send(conn, frame);
-
+	flap_connection_send_snac(od, conn, 0x0015, 0x0002, 0x0000, snacid, &bs);
+	
+	byte_stream_destroy(&bs);
+	
 	/* Keep track of this request and the ICQ number and request ID */
 	info = (struct aim_icq_info *)g_new0(struct aim_icq_info, 1);
 	info->reqid = snacid;
@@ -270,7 +276,7 @@
 int aim_icq_getsimpleinfo(OscarData *od, const char *uin)
 {
 	FlapConnection *conn;
-	FlapFrame *frame;
+	ByteStream bs;
 	aim_snacid_t snacid;
 	int bslen;
 
@@ -282,23 +288,24 @@
 
 	bslen = 2 + 4 + 2 + 2 + 2 + 4;
 
-	frame = flap_frame_new(od, 0x02, 10 + 4 + bslen);
+	byte_stream_new(&bs, 4 + bslen);
 
 	snacid = aim_cachesnac(od, 0x0015, 0x0002, 0x0000, NULL, 0);
-	aim_putsnac(&frame->data, 0x0015, 0x0002, 0x0000, snacid);
 
 	/* For simplicity, don't bother using a tlvlist */
-	byte_stream_put16(&frame->data, 0x0001);
-	byte_stream_put16(&frame->data, bslen);
+	byte_stream_put16(&bs, 0x0001);
+	byte_stream_put16(&bs, bslen);
 
-	byte_stream_putle16(&frame->data, bslen - 2);
-	byte_stream_putle32(&frame->data, atoi(od->sn));
-	byte_stream_putle16(&frame->data, 0x07d0); /* I command thee. */
-	byte_stream_putle16(&frame->data, snacid); /* eh. */
-	byte_stream_putle16(&frame->data, 0x051f); /* shrug. */
-	byte_stream_putle32(&frame->data, atoi(uin));
+	byte_stream_putle16(&bs, bslen - 2);
+	byte_stream_putle32(&bs, atoi(od->sn));
+	byte_stream_putle16(&bs, 0x07d0); /* I command thee. */
+	byte_stream_putle16(&bs, snacid); /* eh. */
+	byte_stream_putle16(&bs, 0x051f); /* shrug. */
+	byte_stream_putle32(&bs, atoi(uin));
 
-	flap_connection_send(conn, frame);
+	flap_connection_send_snac(od, conn, 0x0015, 0x0002, 0x0000, snacid, &bs);
+
+	byte_stream_destroy(&bs);
 
 	return 0;
 }
@@ -307,7 +314,7 @@
 int aim_icq_sendxmlreq(OscarData *od, const char *xml)
 {
 	FlapConnection *conn;
-	FlapFrame *frame;
+	ByteStream bs;
 	aim_snacid_t snacid;
 	int bslen;
 
@@ -319,25 +326,26 @@
 
 	bslen = 2 + 10 + 2 + strlen(xml) + 1;
 
-	frame = flap_frame_new(od, 0x02, 10 + 4 + bslen);
+	byte_stream_new(&bs, 4 + bslen);
 
 	snacid = aim_cachesnac(od, 0x0015, 0x0002, 0x0000, NULL, 0);
-	aim_putsnac(&frame->data, 0x0015, 0x0002, 0x0000, snacid);
 
 	/* For simplicity, don't bother using a tlvlist */
-	byte_stream_put16(&frame->data, 0x0001);
-	byte_stream_put16(&frame->data, bslen);
+	byte_stream_put16(&bs, 0x0001);
+	byte_stream_put16(&bs, bslen);
 
-	byte_stream_putle16(&frame->data, bslen - 2);
-	byte_stream_putle32(&frame->data, atoi(od->sn));
-	byte_stream_putle16(&frame->data, 0x07d0); /* I command thee. */
-	byte_stream_putle16(&frame->data, snacid); /* eh. */
-	byte_stream_putle16(&frame->data, 0x0998); /* shrug. */
-	byte_stream_putle16(&frame->data, strlen(xml) + 1);
-	byte_stream_putraw(&frame->data, (guint8 *)xml, strlen(xml) + 1);
+	byte_stream_putle16(&bs, bslen - 2);
+	byte_stream_putle32(&bs, atoi(od->sn));
+	byte_stream_putle16(&bs, 0x07d0); /* I command thee. */
+	byte_stream_putle16(&bs, snacid); /* eh. */
+	byte_stream_putle16(&bs, 0x0998); /* shrug. */
+	byte_stream_putle16(&bs, strlen(xml) + 1);
+	byte_stream_putraw(&bs, (guint8 *)xml, strlen(xml) + 1);
 
-	flap_connection_send(conn, frame);
-
+	flap_connection_send_snac(od, conn, 0x0015, 0x0002, 0x0000, snacid, &bs);
+	
+	byte_stream_destroy(&bs);
+	
 	return 0;
 }
 #endif
@@ -363,7 +371,7 @@
 int aim_icq_sendsms(OscarData *od, const char *name, const char *msg, const char *alias)
 {
 	FlapConnection *conn;
-	FlapFrame *frame;
+	ByteStream bs;
 	aim_snacid_t snacid;
 	int bslen, xmllen;
 	char *xml;
@@ -401,35 +409,36 @@
 
 	bslen = 36 + xmllen;
 
-	frame = flap_frame_new(od, 0x02, 10 + 4 + bslen);
+	byte_stream_new(&bs, 4 + bslen);
 
 	snacid = aim_cachesnac(od, 0x0015, 0x0002, 0x0000, NULL, 0);
-	aim_putsnac(&frame->data, 0x0015, 0x0002, 0x0000, snacid);
 
 	/* For simplicity, don't bother using a tlvlist */
-	byte_stream_put16(&frame->data, 0x0001);
-	byte_stream_put16(&frame->data, bslen);
+	byte_stream_put16(&bs, 0x0001);
+	byte_stream_put16(&bs, bslen);
 
-	byte_stream_putle16(&frame->data, bslen - 2);
-	byte_stream_putle32(&frame->data, atoi(od->sn));
-	byte_stream_putle16(&frame->data, 0x07d0); /* I command thee. */
-	byte_stream_putle16(&frame->data, snacid); /* eh. */
+	byte_stream_putle16(&bs, bslen - 2);
+	byte_stream_putle32(&bs, atoi(od->sn));
+	byte_stream_putle16(&bs, 0x07d0); /* I command thee. */
+	byte_stream_putle16(&bs, snacid); /* eh. */
 
 	/* From libicq200-0.3.2/src/SNAC-SRV.cpp */
-	byte_stream_putle16(&frame->data, 0x1482);
-	byte_stream_put16(&frame->data, 0x0001);
-	byte_stream_put16(&frame->data, 0x0016);
-	byte_stream_put32(&frame->data, 0x00000000);
-	byte_stream_put32(&frame->data, 0x00000000);
-	byte_stream_put32(&frame->data, 0x00000000);
-	byte_stream_put32(&frame->data, 0x00000000);
+	byte_stream_putle16(&bs, 0x1482);
+	byte_stream_put16(&bs, 0x0001);
+	byte_stream_put16(&bs, 0x0016);
+	byte_stream_put32(&bs, 0x00000000);
+	byte_stream_put32(&bs, 0x00000000);
+	byte_stream_put32(&bs, 0x00000000);
+	byte_stream_put32(&bs, 0x00000000);
 
-	byte_stream_put16(&frame->data, 0x0000);
-	byte_stream_put16(&frame->data, xmllen);
-	byte_stream_putstr(&frame->data, xml);
-	byte_stream_put8(&frame->data, 0x00);
+	byte_stream_put16(&bs, 0x0000);
+	byte_stream_put16(&bs, xmllen);
+	byte_stream_putstr(&bs, xml);
+	byte_stream_put8(&bs, 0x00);
 
-	flap_connection_send(conn, frame);
+	flap_connection_send_snac(od, conn, 0x0015, 0x0002, 0x0000, snacid, &bs);
+
+	byte_stream_destroy(&bs);
 
 	g_free(xml);
 	g_free(stripped);
@@ -445,7 +454,7 @@
 int aim_icq_getstatusnote(OscarData *od, const char *uin, guint8 *note_hash, guint16 note_hash_len)
 {
 	FlapConnection *conn;
-	FlapFrame *frame;
+	ByteStream bs;
 	aim_snacid_t snacid;
 	int bslen;
 
@@ -458,40 +467,39 @@
 	}
 
 	bslen = 2 + 4 + 2 + 2 + 2 + 2 + 58 + strlen(uin);
-
-	frame = flap_frame_new(od, 0x02, 10 + 4 + bslen);
+	byte_stream_new(&bs, 4 + bslen);
 
 	snacid = aim_cachesnac(od, 0x0015, 0x0002, 0x0000, NULL, 0);
-	aim_putsnac(&frame->data, 0x0015, 0x0002, 0x0000, snacid);
 
-	/* For simplicity, don't bother using a tlvlist */
-	byte_stream_put16(&frame->data, 0x0001);
-	byte_stream_put16(&frame->data, bslen);
+	byte_stream_put16(&bs, 0x0001);
+	byte_stream_put16(&bs, bslen);
 
-	byte_stream_putle16(&frame->data, bslen - 2);
-	byte_stream_putle32(&frame->data, atoi(od->sn));
-	byte_stream_putle16(&frame->data, 0x07d0); /* I command thee. */
-	byte_stream_putle16(&frame->data, snacid); /* eh. */
-	byte_stream_putle16(&frame->data, 0x0fa0); /* shrug. */
-	byte_stream_putle16(&frame->data, 58 + strlen(uin));
+	byte_stream_putle16(&bs, bslen - 2);
+	byte_stream_putle32(&bs, atoi(od->sn));
+	byte_stream_putle16(&bs, 0x07d0); /* I command thee. */
+	byte_stream_putle16(&bs, snacid); /* eh. */
+	byte_stream_putle16(&bs, 0x0fa0); /* shrug. */
+	byte_stream_putle16(&bs, 58 + strlen(uin));
 
-	byte_stream_put32(&frame->data, 0x05b90002);    /* don't ask */
-	byte_stream_put32(&frame->data, 0x80000000);
-	byte_stream_put32(&frame->data, 0x00000006);
-	byte_stream_put32(&frame->data, 0x00010002);
-	byte_stream_put32(&frame->data, 0x00020000);
-	byte_stream_put32(&frame->data, 0x04e30000);
-	byte_stream_put32(&frame->data, 0x00020002);
-	byte_stream_put32(&frame->data, 0x00000001);
+	byte_stream_put32(&bs, 0x05b90002);    /* don't ask */
+	byte_stream_put32(&bs, 0x80000000);
+	byte_stream_put32(&bs, 0x00000006);
+	byte_stream_put32(&bs, 0x00010002);
+	byte_stream_put32(&bs, 0x00020000);
+	byte_stream_put32(&bs, 0x04e30000);
+	byte_stream_put32(&bs, 0x00020002);
+	byte_stream_put32(&bs, 0x00000001);
 
-	byte_stream_put16(&frame->data, 24 + strlen(uin));
-	byte_stream_put32(&frame->data, 0x003c0010);
-	byte_stream_putraw(&frame->data, note_hash, 16); /* status note hash */
-	byte_stream_put16(&frame->data, 0x0032);        /* buddy uin */
-	byte_stream_put16(&frame->data, strlen(uin));
-	byte_stream_putstr(&frame->data, uin);
+	byte_stream_put16(&bs, 24 + strlen(uin));
+	byte_stream_put32(&bs, 0x003c0010);
+	byte_stream_putraw(&bs, note_hash, 16); /* status note hash */
+	byte_stream_put16(&bs, 0x0032);        /* buddy uin */
+	byte_stream_put16(&bs, strlen(uin));
+	byte_stream_putstr(&bs, uin);
 
-	flap_connection_send(conn, frame);
+	flap_connection_send_snac(od, conn, 0x0015, 0x0002, 0x000, snacid, &bs);
+
+	byte_stream_destroy(&bs);
 
 	return 0;
 }
@@ -768,8 +776,8 @@
 			else
 			{
 				struct aim_icq_info *info;
-				guint32 data_len;
-				FlapFrame *frame;
+				ByteStream bs;
+				guint32 bslen;
 				aim_snacid_t snacid;
 				guchar cookie[8];
 
@@ -783,84 +791,83 @@
 					break;
 				}
 
-				data_len = 13 + strlen(uin) + 30 + 6 + 4 + 55 + 85 + 4;
-				frame = flap_frame_new(od, 0x0002, 10 + 4 + data_len);
+				bslen = 13 + strlen(uin) + 30 + 6 + 4 + 55 + 85 + 4;
+				byte_stream_new(&bs, 4 + bslen);
+
 				snacid = aim_cachesnac(od, 0x0004, 0x0006, 0x0000, NULL, 0);
 
-				aim_putsnac(&frame->data, 0x0004, 0x0006, 0x0000, snacid);
-
 				aim_icbm_makecookie(cookie);
 
-				byte_stream_putraw(&frame->data, cookie, 8); /* ICBM cookie */
-				byte_stream_put16(&frame->data, 0x0002); /* message channel */
-				byte_stream_put8(&frame->data, strlen(uin)); /* uin */
-				byte_stream_putstr(&frame->data, uin);
+				byte_stream_putraw(&bs, cookie, 8); /* ICBM cookie */
+				byte_stream_put16(&bs, 0x0002); /* message channel */
+				byte_stream_put8(&bs, strlen(uin)); /* uin */
+				byte_stream_putstr(&bs, uin);
 
-				byte_stream_put16(&frame->data, 0x0005); /* rendez vous data */
-				byte_stream_put16(&frame->data, 0x00b2);
-				byte_stream_put16(&frame->data, 0x0000); /* request */
-				byte_stream_putraw(&frame->data, cookie, 8); /* ICBM cookie */
-				byte_stream_put32(&frame->data, 0x09461349); /* ICQ server relaying */
-				byte_stream_put16(&frame->data, 0x4c7f);
-				byte_stream_put16(&frame->data, 0x11d1);
-				byte_stream_put32(&frame->data, 0x82224445);
-				byte_stream_put32(&frame->data, 0x53540000);
+				byte_stream_put16(&bs, 0x0005); /* rendez vous data */
+				byte_stream_put16(&bs, 0x00b2);
+				byte_stream_put16(&bs, 0x0000); /* request */
+				byte_stream_putraw(&bs, cookie, 8); /* ICBM cookie */
+				byte_stream_put32(&bs, 0x09461349); /* ICQ server relaying */
+				byte_stream_put16(&bs, 0x4c7f);
+				byte_stream_put16(&bs, 0x11d1);
+				byte_stream_put32(&bs, 0x82224445);
+				byte_stream_put32(&bs, 0x53540000);
 
-				byte_stream_put16(&frame->data, 0x000a); /* unknown TLV */
-				byte_stream_put16(&frame->data, 0x0002);
-				byte_stream_put16(&frame->data, 0x0001);
+				byte_stream_put16(&bs, 0x000a); /* unknown TLV */
+				byte_stream_put16(&bs, 0x0002);
+				byte_stream_put16(&bs, 0x0001);
 
-				byte_stream_put16(&frame->data, 0x000f); /* unknown TLV */
-				byte_stream_put16(&frame->data, 0x0000);
+				byte_stream_put16(&bs, 0x000f); /* unknown TLV */
+				byte_stream_put16(&bs, 0x0000);
 
-				byte_stream_put16(&frame->data, 0x2711); /* extended data */
-				byte_stream_put16(&frame->data, 0x008a);
-				byte_stream_putle16(&frame->data, 0x001b); /* length */
-				byte_stream_putle16(&frame->data, 0x0009); /* version */
-				byte_stream_putle32(&frame->data, 0x00000000); /* plugin: none */
-				byte_stream_putle32(&frame->data, 0x00000000);
-				byte_stream_putle32(&frame->data, 0x00000000);
-				byte_stream_putle32(&frame->data, 0x00000000);
-				byte_stream_putle16(&frame->data, 0x0000); /* unknown */
-				byte_stream_putle32(&frame->data, 0x00000000); /* client capabilities flags */
-				byte_stream_put8(&frame->data, 0x00); /* unknown */
-				byte_stream_putle16(&frame->data, 0x0064); /* downcounter? */
-				byte_stream_putle16(&frame->data, 0x000e); /* length */
-				byte_stream_putle16(&frame->data, 0x0064); /* downcounter? */
-				byte_stream_putle32(&frame->data, 0x00000000); /* unknown */
-				byte_stream_putle32(&frame->data, 0x00000000);
-				byte_stream_putle32(&frame->data, 0x00000000);
-				byte_stream_put8(&frame->data, 0x1a); /* message type: plugin message descibed by text string */
-				byte_stream_put8(&frame->data, 0x00); /* message flags */
-				byte_stream_putle16(&frame->data, 0x0000); /* status code */
-				byte_stream_putle16(&frame->data, 0x0001); /* priority code */
-				byte_stream_putle16(&frame->data, 0x0000); /* text length */
+				byte_stream_put16(&bs, 0x2711); /* extended data */
+				byte_stream_put16(&bs, 0x008a);
+				byte_stream_putle16(&bs, 0x001b); /* length */
+				byte_stream_putle16(&bs, 0x0009); /* version */
+				byte_stream_putle32(&bs, 0x00000000); /* plugin: none */
+				byte_stream_putle32(&bs, 0x00000000);
+				byte_stream_putle32(&bs, 0x00000000);
+				byte_stream_putle32(&bs, 0x00000000);
+				byte_stream_putle16(&bs, 0x0000); /* unknown */
+				byte_stream_putle32(&bs, 0x00000000); /* client capabilities flags */
+				byte_stream_put8(&bs, 0x00); /* unknown */
+				byte_stream_putle16(&bs, 0x0064); /* downcounter? */
+				byte_stream_putle16(&bs, 0x000e); /* length */
+				byte_stream_putle16(&bs, 0x0064); /* downcounter? */
+				byte_stream_putle32(&bs, 0x00000000); /* unknown */
+				byte_stream_putle32(&bs, 0x00000000);
+				byte_stream_putle32(&bs, 0x00000000);
+				byte_stream_put8(&bs, 0x1a); /* message type: plugin message descibed by text string */
+				byte_stream_put8(&bs, 0x00); /* message flags */
+				byte_stream_putle16(&bs, 0x0000); /* status code */
+				byte_stream_putle16(&bs, 0x0001); /* priority code */
+				byte_stream_putle16(&bs, 0x0000); /* text length */
 
-				byte_stream_put8(&frame->data, 0x3a); /* message dump */
-				byte_stream_put32(&frame->data, 0x00811a18);
-				byte_stream_put32(&frame->data, 0xbc0e6c18);
-				byte_stream_put32(&frame->data, 0x47a5916f);
-				byte_stream_put32(&frame->data, 0x18dcc76f);
-				byte_stream_put32(&frame->data, 0x1a010013);
-				byte_stream_put32(&frame->data, 0x00000041);
-				byte_stream_put32(&frame->data, 0x77617920);
-				byte_stream_put32(&frame->data, 0x53746174);
-				byte_stream_put32(&frame->data, 0x7573204d);
-				byte_stream_put32(&frame->data, 0x65737361);
-				byte_stream_put32(&frame->data, 0x67650100);
-				byte_stream_put32(&frame->data, 0x00000000);
-				byte_stream_put32(&frame->data, 0x00000000);
-				byte_stream_put32(&frame->data, 0x00000000);
-				byte_stream_put32(&frame->data, 0x00000015);
-				byte_stream_put32(&frame->data, 0x00000000);
-				byte_stream_put32(&frame->data, 0x0000000d);
-				byte_stream_put32(&frame->data, 0x00000074);
-				byte_stream_put32(&frame->data, 0x6578742f);
-				byte_stream_put32(&frame->data, 0x782d616f);
-				byte_stream_put32(&frame->data, 0x6c727466);
+				byte_stream_put8(&bs, 0x3a); /* message dump */
+				byte_stream_put32(&bs, 0x00811a18);
+				byte_stream_put32(&bs, 0xbc0e6c18);
+				byte_stream_put32(&bs, 0x47a5916f);
+				byte_stream_put32(&bs, 0x18dcc76f);
+				byte_stream_put32(&bs, 0x1a010013);
+				byte_stream_put32(&bs, 0x00000041);
+				byte_stream_put32(&bs, 0x77617920);
+				byte_stream_put32(&bs, 0x53746174);
+				byte_stream_put32(&bs, 0x7573204d);
+				byte_stream_put32(&bs, 0x65737361);
+				byte_stream_put32(&bs, 0x67650100);
+				byte_stream_put32(&bs, 0x00000000);
+				byte_stream_put32(&bs, 0x00000000);
+				byte_stream_put32(&bs, 0x00000000);
+				byte_stream_put32(&bs, 0x00000015);
+				byte_stream_put32(&bs, 0x00000000);
+				byte_stream_put32(&bs, 0x0000000d);
+				byte_stream_put32(&bs, 0x00000074);
+				byte_stream_put32(&bs, 0x6578742f);
+				byte_stream_put32(&bs, 0x782d616f);
+				byte_stream_put32(&bs, 0x6c727466);
 
-				byte_stream_put16(&frame->data, 0x0003); /* server ACK requested */
-				byte_stream_put16(&frame->data, 0x0000);
+				byte_stream_put16(&bs, 0x0003); /* server ACK requested */
+				byte_stream_put16(&bs, 0x0000);
 
 				info->uin = atoi(uin);
 				info->status_note_title = status_note_title;
@@ -870,7 +877,9 @@
 				info->next = od->icq_info;
 				od->icq_info = info;
 
-				flap_connection_send(conn, frame);
+				flap_connection_send_snac(od, conn, 0x0004, 0x0006, 0x0000, snacid, &bs);
+
+				byte_stream_destroy(&bs);
 			}
 
 			g_free(uin);
--- a/libpurple/protocols/oscar/family_locate.c	Thu Apr 24 02:16:30 2008 +0000
+++ b/libpurple/protocols/oscar/family_locate.c	Thu Apr 24 11:10:03 2008 +0000
@@ -1047,7 +1047,7 @@
 				  const char *awaymsg_encoding, const gchar *awaymsg, const int awaymsg_len)
 {
 	FlapConnection *conn;
-	FlapFrame *frame;
+	ByteStream bs;
 	aim_snacid_t snacid;
 	GSList *tlvlist = NULL;
 	char *encoding;
@@ -1092,15 +1092,16 @@
 			aim_tlvlist_add_noval(&tlvlist, 0x0004);
 	}
 
-	frame = flap_frame_new(od, 0x02, 10 + aim_tlvlist_size(tlvlist));
+	byte_stream_new(&bs, aim_tlvlist_size(tlvlist));
 
 	snacid = aim_cachesnac(od, 0x0002, 0x0004, 0x0000, NULL, 0);
-	aim_putsnac(&frame->data, 0x0002, 0x004, 0x0000, snacid);
 
-	aim_tlvlist_write(&frame->data, &tlvlist);
+	aim_tlvlist_write(&bs, &tlvlist);
 	aim_tlvlist_free(tlvlist);
 
-	flap_connection_send(conn, frame);
+	flap_connection_send_snac(od, conn, 0x0002, 0x0004, 0x0000, snacid, &bs);
+
+	byte_stream_destroy(&bs);
 
 	return 0;
 }
@@ -1112,7 +1113,7 @@
 aim_locate_setcaps(OscarData *od, guint32 caps)
 {
 	FlapConnection *conn;
-	FlapFrame *frame;
+	ByteStream bs;
 	aim_snacid_t snacid;
 	GSList *tlvlist = NULL;
 
@@ -1121,15 +1122,16 @@
 
 	aim_tlvlist_add_caps(&tlvlist, 0x0005, caps);
 
-	frame = flap_frame_new(od, 0x02, 10 + aim_tlvlist_size(tlvlist));
+	byte_stream_new(&bs, aim_tlvlist_size(tlvlist));
 
 	snacid = aim_cachesnac(od, 0x0002, 0x0004, 0x0000, NULL, 0);
-	aim_putsnac(&frame->data, 0x0002, 0x004, 0x0000, snacid);
 
-	aim_tlvlist_write(&frame->data, &tlvlist);
+	aim_tlvlist_write(&bs, &tlvlist);
 	aim_tlvlist_free(tlvlist);
 
-	flap_connection_send(conn, frame);
+	flap_connection_send_snac(od, conn, 0x0002, 0x0004, 0x0000, snacid, &bs);
+
+	byte_stream_destroy(&bs);
 
 	return 0;
 }
@@ -1147,22 +1149,23 @@
 aim_locate_getinfo(OscarData *od, const char *sn, guint16 infotype)
 {
 	FlapConnection *conn;
-	FlapFrame *frame;
+	ByteStream bs;
 	aim_snacid_t snacid;
 
 	if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_LOCATE)) || !sn)
 		return -EINVAL;
 
-	frame = flap_frame_new(od, 0x02, 12+1+strlen(sn));
+	byte_stream_new(&bs, 2+1+strlen(sn));
 
 	snacid = aim_cachesnac(od, 0x0002, 0x0005, 0x0000, NULL, 0);
 
-	aim_putsnac(&frame->data, 0x0002, 0x0005, 0x0000, snacid);
-	byte_stream_put16(&frame->data, infotype);
-	byte_stream_put8(&frame->data, strlen(sn));
-	byte_stream_putstr(&frame->data, sn);
+	byte_stream_put16(&bs, infotype);
+	byte_stream_put8(&bs, strlen(sn));
+	byte_stream_putstr(&bs, sn);
 
-	flap_connection_send(conn, frame);
+	flap_connection_send_snac(od, conn, 0x0002, 0x0005, 0x0000, snacid, &bs);
+
+	byte_stream_destroy(&bs);
 
 	return 0;
 }
@@ -1238,7 +1241,7 @@
 int aim_locate_setdirinfo(OscarData *od, const char *first, const char *middle, const char *last, const char *maiden, const char *nickname, const char *street, const char *city, const char *state, const char *zip, int country, guint16 privacy)
 {
 	FlapConnection *conn;
-	FlapFrame *frame;
+	ByteStream bs;
 	aim_snacid_t snacid;
 	GSList *tlvlist = NULL;
 
@@ -1269,15 +1272,16 @@
 	if (street)
 		aim_tlvlist_add_str(&tlvlist, 0x0021, street);
 
-	frame = flap_frame_new(od, 0x02, 10+aim_tlvlist_size(tlvlist));
+	byte_stream_new(&bs, aim_tlvlist_size(tlvlist));
 
 	snacid = aim_cachesnac(od, 0x0002, 0x0009, 0x0000, NULL, 0);
 
-	aim_putsnac(&frame->data, 0x0002, 0x0009, 0x0000, snacid);
-	aim_tlvlist_write(&frame->data, &tlvlist);
+	aim_tlvlist_write(&bs, &tlvlist);
 	aim_tlvlist_free(tlvlist);
 
-	flap_connection_send(conn, frame);
+	flap_connection_send_snac(od, conn, 0x0002, 0x0009, 0x0000, snacid, &bs);
+
+	byte_stream_destroy(&bs);
 
 	return 0;
 }
@@ -1288,7 +1292,7 @@
 int aim_locate_000b(OscarData *od, const char *sn)
 {
 	FlapConnection *conn;
-	FlapFrame *frame;
+	ByteStream bs;
 	aim_snacid_t snacid;
 
 		return -EINVAL;
@@ -1296,15 +1300,16 @@
 	if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_LOCATE)) || !sn)
 		return -EINVAL;
 
-	frame = flap_frame_new(od, 0x02, 10+1+strlen(sn));
+	byte_stream_new(&bs, 1+strlen(sn));
 
 	snacid = aim_cachesnac(od, 0x0002, 0x000b, 0x0000, NULL, 0);
 
-	aim_putsnac(&frame->data, 0x0002, 0x000b, 0x0000, snacid);
-	byte_stream_put8(&frame->data, strlen(sn));
-	byte_stream_putstr(&frame->data, sn);
+	byte_stream_put8(&bs, strlen(sn));
+	byte_stream_putstr(&bs, sn);
 
-	flap_connection_send(conn, frame);
+	flap_connection_send_snac(od, conn, 0x0002, 0x000b, 0x0000, snacid, &bs);
+
+	byte_stream_destroy(&bs);
 
 	return 0;
 }
@@ -1319,7 +1324,7 @@
 aim_locate_setinterests(OscarData *od, const char *interest1, const char *interest2, const char *interest3, const char *interest4, const char *interest5, guint16 privacy)
 {
 	FlapConnection *conn;
-	FlapFrame *frame;
+	ByteStream bs;
 	aim_snacid_t snacid;
 	GSList *tlvlist = NULL;
 
@@ -1340,16 +1345,16 @@
 	if (interest5)
 		aim_tlvlist_add_str(&tlvlist, 0x0000b, interest5);
 
-	frame = flap_frame_new(od, 0x02, 10+aim_tlvlist_size(tlvlist));
+	byte_stream_new(&bs, aim_tlvlist_size(tlvlist));
 
 	snacid = aim_cachesnac(od, 0x0002, 0x000f, 0x0000, NULL, 0);
 
-	aim_putsnac(&frame->data, 0x0002, 0x000f, 0x0000, 0);
-	aim_tlvlist_write(&frame->data, &tlvlist);
+	aim_tlvlist_write(&bs, &tlvlist);
 	aim_tlvlist_free(tlvlist);
 
-	flap_connection_send(conn, frame);
-
+	flap_connection_send_snac(od, conn, 0x0002, 0x000f, 0x0000, snacid, &bs);
+	
+	byte_stream_destroy(&bs);
 	return 0;
 }
 
@@ -1369,21 +1374,21 @@
 aim_locate_getinfoshort(OscarData *od, const char *sn, guint32 flags)
 {
 	FlapConnection *conn;
-	ByteStream data;
+	ByteStream bs;
 	aim_snacid_t snacid;
 
 	if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_LOCATE)) || !sn)
 		return -EINVAL;
 
-	byte_stream_new(&data, 4 + 1 + strlen(sn));
-	byte_stream_put32(&data, flags);
-	byte_stream_put8(&data, strlen(sn));
-	byte_stream_putstr(&data, sn);
+	byte_stream_new(&bs, 4 + 1 + strlen(sn));
+	byte_stream_put32(&bs, flags);
+	byte_stream_put8(&bs, strlen(sn));
+	byte_stream_putstr(&bs, sn);
 
 	snacid = aim_cachesnac(od, 0x0002, 0x0015, 0x0000, sn, strlen(sn)+1);
-	flap_connection_send_snac(od, conn, 0x0002, 0x0015, 0x0000, snacid, &data);
+	flap_connection_send_snac(od, conn, 0x0002, 0x0015, 0x0000, snacid, &bs);
 
-	g_free(data.data);
+	byte_stream_destroy(&bs);
 
 	return 0;
 }
--- a/libpurple/protocols/oscar/family_odir.c	Thu Apr 24 02:16:30 2008 +0000
+++ b/libpurple/protocols/oscar/family_odir.c	Thu Apr 24 11:10:03 2008 +0000
@@ -41,7 +41,7 @@
 int aim_odir_email(OscarData *od, const char *region, const char *email)
 {
 	FlapConnection *conn;
-	FlapFrame *frame;
+	ByteStream bs;
 	aim_snacid_t snacid;
 	GSList *tlvlist = NULL;
 
@@ -53,14 +53,15 @@
 	aim_tlvlist_add_16(&tlvlist, 0x000a, 0x0001); /* Type of search */
 	aim_tlvlist_add_str(&tlvlist, 0x0005, email);
 
-	frame = flap_frame_new(od, 0x02, 10+aim_tlvlist_size(tlvlist));
-	snacid = aim_cachesnac(od, 0x000f, 0x0002, 0x0000, NULL, 0);
-	aim_putsnac(&frame->data, 0x000f, 0x0002, 0x0000, snacid);
+	byte_stream_new(&bs, aim_tlvlist_size(tlvlist));
 
-	aim_tlvlist_write(&frame->data, &tlvlist);
+	aim_tlvlist_write(&bs, &tlvlist);
 	aim_tlvlist_free(tlvlist);
 
-	flap_connection_send(conn, frame);
+	snacid = aim_cachesnac(od, 0x000f, 0x0002, 0x0000, NULL, 0);
+	flap_connection_send_snac(od, conn, 0x000f, 0x0002, 0x0000, snacid, &bs);
+
+	byte_stream_destroy(&bs);
 
 	return 0;
 }
@@ -89,7 +90,7 @@
 int aim_odir_name(OscarData *od, const char *region, const char *first, const char *middle, const char *last, const char *maiden, const char *nick, const char *city, const char *state, const char *country, const char *zip, const char *address)
 {
 	FlapConnection *conn;
-	FlapFrame *frame;
+	ByteStream bs;
 	aim_snacid_t snacid;
 	GSList *tlvlist = NULL;
 
@@ -120,15 +121,16 @@
 	if (address)
 		aim_tlvlist_add_str(&tlvlist, 0x0021, address);
 
-	frame = flap_frame_new(od, 0x02, 10+aim_tlvlist_size(tlvlist));
-	snacid = aim_cachesnac(od, 0x000f, 0x0002, 0x0000, NULL, 0);
-	aim_putsnac(&frame->data, 0x000f, 0x0002, 0x0000, snacid);
+	byte_stream_new(&bs, aim_tlvlist_size(tlvlist));
 
-	aim_tlvlist_write(&frame->data, &tlvlist);
+	aim_tlvlist_write(&bs, &tlvlist);
 	aim_tlvlist_free(tlvlist);
 
-	flap_connection_send(conn, frame);
+	snacid = aim_cachesnac(od, 0x000f, 0x0002, 0x0000, NULL, 0);
+	flap_connection_send_snac(od, conn, 0x000f, 0x0002, 0x0000, snacid, &bs);
 
+	byte_stream_destroy(&bs);
+	
 	return 0;
 }
 
@@ -143,7 +145,7 @@
 int aim_odir_interest(OscarData *od, const char *region, const char *interest)
 {
 	FlapConnection *conn;
-	FlapFrame *frame;
+	ByteStream bs;
 	aim_snacid_t snacid;
 	GSList *tlvlist = NULL;
 
@@ -156,15 +158,16 @@
 	if (interest)
 		aim_tlvlist_add_str(&tlvlist, 0x0001, interest);
 
-	frame = flap_frame_new(od, 0x02, 10+aim_tlvlist_size(tlvlist));
-	snacid = aim_cachesnac(od, 0x000f, 0x0002, 0x0000, NULL, 0);
-	aim_putsnac(&frame->data, 0x000f, 0x0002, 0x0000, snacid);
+	byte_stream_new(&bs, aim_tlvlist_size(tlvlist));
 
-	aim_tlvlist_write(&frame->data, &tlvlist);
+	aim_tlvlist_write(&bs, &tlvlist);
 	aim_tlvlist_free(tlvlist);
 
-	flap_connection_send(conn, frame);
-
+	snacid = aim_cachesnac(od, 0x000f, 0x0002, 0x0000, NULL, 0);
+	flap_connection_send_snac(od, conn, 0x000f, 0x0002, 0x0000, snacid, &bs);
+	
+	byte_stream_destroy(&bs);
+	
 	return 0;
 }
 
--- a/libpurple/protocols/oscar/family_oservice.c	Thu Apr 24 02:16:30 2008 +0000
+++ b/libpurple/protocols/oscar/family_oservice.c	Thu Apr 24 11:10:03 2008 +0000
@@ -31,14 +31,11 @@
 void
 aim_clientready(OscarData *od, FlapConnection *conn)
 {
-	FlapFrame *frame;
+	ByteStream bs;
 	aim_snacid_t snacid;
 	GSList *cur;
 
-	frame = flap_frame_new(od, 0x02, 1152);
-
-	snacid = aim_cachesnac(od, 0x0001, 0x0002, 0x0000, NULL, 0);
-	aim_putsnac(&frame->data, 0x0001, 0x0002, 0x0000, snacid);
+	byte_stream_new(&bs, 1142);
 
 	/*
 	 * Send only the tool versions that the server cares about (that it
@@ -50,14 +47,17 @@
 
 		if ((mod = aim__findmodulebygroup(od, GPOINTER_TO_UINT(cur->data))))
 		{
-			byte_stream_put16(&frame->data, mod->family);
-			byte_stream_put16(&frame->data, mod->version);
-			byte_stream_put16(&frame->data, mod->toolid);
-			byte_stream_put16(&frame->data, mod->toolversion);
+			byte_stream_put16(&bs, mod->family);
+			byte_stream_put16(&bs, mod->version);
+			byte_stream_put16(&bs, mod->toolid);
+			byte_stream_put16(&bs, mod->toolversion);
 		}
 	}
 
-	flap_connection_send(conn, frame);
+	snacid = aim_cachesnac(od, 0x0001, 0x0002, 0x0000, NULL, 0);
+	flap_connection_send_snac(od, conn, 0x0001, 0x0002, 0x0000, snacid, &bs);
+	
+	byte_stream_destroy(&bs);
 }
 
 /*
@@ -121,7 +121,7 @@
 aim_chat_join(OscarData *od, guint16 exchange, const char *roomname, guint16 instance)
 {
 	FlapConnection *conn;
-	FlapFrame *frame;
+	ByteStream bs;
 	aim_snacid_t snacid;
 	GSList *tlvlist = NULL;
 	struct chatsnacinfo csi;
@@ -130,27 +130,27 @@
 	if (!conn || !roomname || !strlen(roomname))
 		return -EINVAL;
 
-	frame = flap_frame_new(od, 0x02, 512);
+	byte_stream_new(&bs, 502);
 
 	memset(&csi, 0, sizeof(csi));
 	csi.exchange = exchange;
 	strncpy(csi.name, roomname, sizeof(csi.name));
 	csi.instance = instance;
 
-	snacid = aim_cachesnac(od, 0x0001, 0x0004, 0x0000, &csi, sizeof(csi));
-	aim_putsnac(&frame->data, 0x0001, 0x0004, 0x0000, snacid);
-
 	/*
 	 * Requesting service chat (0x000e)
 	 */
-	byte_stream_put16(&frame->data, 0x000e);
+	byte_stream_put16(&bs, 0x000e);
 
 	aim_tlvlist_add_chatroom(&tlvlist, 0x0001, exchange, roomname, instance);
-	aim_tlvlist_write(&frame->data, &tlvlist);
+	aim_tlvlist_write(&bs, &tlvlist);
 	aim_tlvlist_free(tlvlist);
 
-	flap_connection_send(conn, frame);
+	snacid = aim_cachesnac(od, 0x0001, 0x0004, 0x0000, &csi, sizeof(csi));
+	flap_connection_send_snac(od, conn, 0x0001, 0x0004, 0x0000, snacid, &bs);
 
+	byte_stream_destroy(&bs);
+	
 	return 0;
 }
 
@@ -376,46 +376,46 @@
 void
 aim_srv_rates_addparam(OscarData *od, FlapConnection *conn)
 {
-	FlapFrame *frame;
+	ByteStream bs;
 	aim_snacid_t snacid;
 	GSList *tmp;
 
-	frame = flap_frame_new(od, 0x02, 512);
-
-	snacid = aim_cachesnac(od, 0x0001, 0x0008, 0x0000, NULL, 0);
-	aim_putsnac(&frame->data, 0x0001, 0x0008, 0x0000, snacid);
+	byte_stream_new(&bs, 502);
 
 	for (tmp = conn->rateclasses; tmp != NULL; tmp = tmp->next)
 	{
 		struct rateclass *rateclass;
 		rateclass = tmp->data;
-		byte_stream_put16(&frame->data, rateclass->classid);
+		byte_stream_put16(&bs, rateclass->classid);
 	}
 
-	flap_connection_send(conn, frame);
+	snacid = aim_cachesnac(od, 0x0001, 0x0008, 0x0000, NULL, 0);
+	flap_connection_send_snac(od, conn, 0x0001, 0x0008, 0x0000, snacid, &bs);
+
+	byte_stream_destroy(&bs);	
 }
 
 /* Subtype 0x0009 - Delete Rate Parameter */
 void
 aim_srv_rates_delparam(OscarData *od, FlapConnection *conn)
 {
-	FlapFrame *frame;
+	ByteStream bs;
 	aim_snacid_t snacid;
 	GSList *tmp;
 
-	frame = flap_frame_new(od, 0x02, 512);
-
-	snacid = aim_cachesnac(od, 0x0001, 0x0009, 0x0000, NULL, 0);
-	aim_putsnac(&frame->data, 0x0001, 0x0009, 0x0000, snacid);
+	byte_stream_new(&bs, 502);
 
 	for (tmp = conn->rateclasses; tmp != NULL; tmp = tmp->next)
 	{
 		struct rateclass *rateclass;
 		rateclass = tmp->data;
-		byte_stream_put16(&frame->data, rateclass->classid);
+		byte_stream_put16(&bs, rateclass->classid);
 	}
 
-	flap_connection_send(conn, frame);
+	snacid = aim_cachesnac(od, 0x0001, 0x0009, 0x0000, NULL, 0);
+	flap_connection_send_snac(od, conn, 0x0001, 0x0009, 0x0000, snacid, &bs);
+
+	byte_stream_destroy(&bs);	
 }
 
 /* Subtype 0x000a - Rate Change */
@@ -489,14 +489,11 @@
 void
 aim_srv_sendpauseack(OscarData *od, FlapConnection *conn)
 {
-	FlapFrame *frame;
+	ByteStream bs;
 	aim_snacid_t snacid;
 	GSList *cur;
 
-	frame = flap_frame_new(od, 0x02, 1024);
-
-	snacid = aim_cachesnac(od, 0x0001, 0x000c, 0x0000, NULL, 0);
-	aim_putsnac(&frame->data, 0x0001, 0x000c, 0x0000, snacid);
+	byte_stream_new(&bs, 1014);
 
 	/*
 	 * This list should have all the groups that the original
@@ -504,9 +501,12 @@
 	 * we want them all back after the migration.
 	 */
 	for (cur = conn->groups; cur != NULL; cur = cur->next)
-		byte_stream_put16(&frame->data, GPOINTER_TO_UINT(cur->data));
+		byte_stream_put16(&bs, GPOINTER_TO_UINT(cur->data));
 
-	flap_connection_send(conn, frame);
+	snacid = aim_cachesnac(od, 0x0001, 0x000c, 0x0000, NULL, 0);
+	flap_connection_send_snac(od, conn, 0x0001, 0x000c, 0x0000, snacid, &bs);
+
+	byte_stream_destroy(&bs);
 }
 
 /* Subtype 0x000d - Service Resume */
@@ -732,14 +732,11 @@
 void
 aim_srv_setversions(OscarData *od, FlapConnection *conn)
 {
-	FlapFrame *frame;
+	ByteStream bs;
 	aim_snacid_t snacid;
 	GSList *cur;
 
-	frame = flap_frame_new(od, 0x02, 1152);
-
-	snacid = aim_cachesnac(od, 0x0001, 0x0017, 0x0000, NULL, 0);
-	aim_putsnac(&frame->data, 0x0001, 0x0017, 0x0000, snacid);
+	byte_stream_new(&bs, 1142);
 
 	/*
 	 * Send only the versions that the server cares about (that it
@@ -751,12 +748,15 @@
 
 		if ((mod = aim__findmodulebygroup(od, GPOINTER_TO_UINT(cur->data))))
 		{
-			byte_stream_put16(&frame->data, mod->family);
-			byte_stream_put16(&frame->data, mod->version);
+			byte_stream_put16(&bs, mod->family);
+			byte_stream_put16(&bs, mod->version);
 		}
 	}
 
-	flap_connection_send(conn, frame);
+	snacid = aim_cachesnac(od, 0x0001, 0x0017, 0x0000, NULL, 0);
+	flap_connection_send_snac(od, conn, 0x0001, 0x0017, 0x0000, snacid, &bs);
+
+	byte_stream_destroy(&bs);
 }
 
 /* Subtype 0x0018 - Host versions */
@@ -803,7 +803,7 @@
 		gboolean setavailmsg, const char *availmsg, const char *itmsurl)
 {
 	FlapConnection *conn;
-	FlapFrame *frame;
+	ByteStream bs;
 	aim_snacid_t snacid;
 	GSList *tlvlist = NULL;
 
@@ -853,19 +853,19 @@
 
 		aim_tlvlist_add_raw(&tlvlist, 0x001d,
 				byte_stream_curpos(&tmpbs), tmpbs.data);
-		g_free(tmpbs.data);
+		byte_stream_destroy(&tmpbs);
 	}
 
-	frame = flap_frame_new(od, 0x02, 10 + aim_tlvlist_size(tlvlist));
+	byte_stream_new(&bs, aim_tlvlist_size(tlvlist));
+
+	aim_tlvlist_write(&bs, &tlvlist);
+	aim_tlvlist_free(tlvlist);
 
 	snacid = aim_cachesnac(od, 0x0001, 0x001e, 0x0000, NULL, 0);
-	aim_putsnac(&frame->data, 0x0001, 0x001e, 0x0000, snacid);
+	flap_connection_send_snac(od, conn, 0x0001, 0x001e, 0x0000, snacid, &bs);
 
-	aim_tlvlist_write(&frame->data, &tlvlist);
-	aim_tlvlist_free(tlvlist);
-
-	flap_connection_send(conn, frame);
-
+	byte_stream_destroy(&bs);
+	
 	return 0;
 }
 
@@ -937,22 +937,19 @@
 int
 aim_sendmemblock(OscarData *od, FlapConnection *conn, guint32 offset, guint32 len, const guint8 *buf, guint8 flag)
 {
-	FlapFrame *frame;
+	ByteStream bs;
 	aim_snacid_t snacid;
 
 	if (!od || !conn)
 		return -EINVAL;
 
-	frame = flap_frame_new(od, 0x02, 10+2+16);
+	byte_stream_new(&bs, 2+16);
 
-	snacid = aim_cachesnac(od, 0x0001, 0x0020, 0x0000, NULL, 0);
-
-	aim_putsnac(&frame->data, 0x0001, 0x0020, 0x0000, snacid);
-	byte_stream_put16(&frame->data, 0x0010); /* md5 is always 16 bytes */
+	byte_stream_put16(&bs, 0x0010); /* md5 is always 16 bytes */
 
 	if ((flag == AIM_SENDMEMBLOCK_FLAG_ISHASH) && buf && (len == 0x10)) { /* we're getting a hash */
 
-		byte_stream_putraw(&frame->data, buf, 0x10);
+		byte_stream_putraw(&bs, buf, 0x10);
 
 	} else if (buf && (len > 0)) { /* use input buffer */
 		PurpleCipher *cipher;
@@ -966,7 +963,7 @@
 		purple_cipher_context_digest(context, 16, digest, NULL);
 		purple_cipher_context_destroy(context);
 
-		byte_stream_putraw(&frame->data, digest, 0x10);
+		byte_stream_putraw(&bs, digest, 0x10);
 
 	} else if (len == 0) { /* no length, just hash NULL (buf is optional) */
 		PurpleCipher *cipher;
@@ -985,7 +982,7 @@
 		purple_cipher_context_digest(context, 16, digest, NULL);
 		purple_cipher_context_destroy(context);
 
-		byte_stream_putraw(&frame->data, digest, 0x10);
+		byte_stream_putraw(&bs, digest, 0x10);
 
 	} else {
 
@@ -999,15 +996,15 @@
 		if ((offset == 0x03ffffff) && (len == 0x03ffffff)) {
 
 #if 1 /* with "AnrbnrAqhfzcd" */
-			byte_stream_put32(&frame->data, 0x44a95d26);
-			byte_stream_put32(&frame->data, 0xd2490423);
-			byte_stream_put32(&frame->data, 0x93b8821f);
-			byte_stream_put32(&frame->data, 0x51c54b01);
+			byte_stream_put32(&bs, 0x44a95d26);
+			byte_stream_put32(&bs, 0xd2490423);
+			byte_stream_put32(&bs, 0x93b8821f);
+			byte_stream_put32(&bs, 0x51c54b01);
 #else /* no filename */
-			byte_stream_put32(&frame->data, 0x1df8cbae);
-			byte_stream_put32(&frame->data, 0x5523b839);
-			byte_stream_put32(&frame->data, 0xa0e10db3);
-			byte_stream_put32(&frame->data, 0xa46d3b39);
+			byte_stream_put32(&bs, 0x1df8cbae);
+			byte_stream_put32(&bs, 0x5523b839);
+			byte_stream_put32(&bs, 0xa0e10db3);
+			byte_stream_put32(&bs, 0xa46d3b39);
 #endif
 
 		} else
@@ -1015,8 +1012,11 @@
 
 	}
 
-	flap_connection_send(conn, frame);
+	snacid = aim_cachesnac(od, 0x0001, 0x0020, 0x0000, NULL, 0);
+	flap_connection_send_snac(od, conn, 0x0001, 0x0020, 0x0000, snacid, &bs);
 
+	byte_stream_destroy(&bs);
+	
 	return 0;
 }
 
--- a/libpurple/protocols/oscar/family_userlookup.c	Thu Apr 24 02:16:30 2008 +0000
+++ b/libpurple/protocols/oscar/family_userlookup.c	Thu Apr 24 11:10:03 2008 +0000
@@ -62,7 +62,7 @@
 int aim_search_address(OscarData *od, const char *address)
 {
 	FlapConnection *conn;
-	FlapFrame *frame;
+	ByteStream bs;
 	aim_snacid_t snacid;
 
 	conn = flap_connection_findbygroup(od, SNAC_FAMILY_USERLOOKUP);
@@ -70,15 +70,15 @@
 	if (!conn || !address)
 		return -EINVAL;
 
-	frame = flap_frame_new(od, 0x02, 10+strlen(address));
+	byte_stream_new(&bs, strlen(address));
+
+	byte_stream_putstr(&bs, address);
 
 	snacid = aim_cachesnac(od, 0x000a, 0x0002, 0x0000, address, strlen(address)+1);
-	aim_putsnac(&frame->data, 0x000a, 0x0002, 0x0000, snacid);
+	flap_connection_send_snac(od, conn, 0x000a, 0x0002, 0x0000, snacid, &bs);
 
-	byte_stream_putstr(&frame->data, address);
-
-	flap_connection_send(conn, frame);
-
+	byte_stream_destroy(&bs);
+	
 	return 0;
 }
 
--- a/libpurple/protocols/oscar/flap_connection.c	Thu Apr 24 02:16:30 2008 +0000
+++ b/libpurple/protocols/oscar/flap_connection.c	Thu Apr 24 11:10:03 2008 +0000
@@ -115,6 +115,7 @@
 	conn = data;
 	gettimeofday(&now, NULL);
 
+	purple_debug_info("oscar", "Attempting to send %i queued SNACs for %p\n", g_queue_get_length(conn->queued_snacs), conn);
 	while (!g_queue_is_empty(conn->queued_snacs))
 	{
 		QueuedSnac *queued_snac;
@@ -189,6 +190,8 @@
 		/* (Add 100ms padding to account for inaccuracies in the calculation) */
 		if (new_current < rateclass->alert + 100)
 		{
+			purple_debug_info("oscar", "Current rate for conn %p would be %u, but we alert at %u; enqueueing\n", conn, new_current, (rateclass->alert + 100));
+
 			enqueue = TRUE;
 		}
 		else
@@ -197,6 +200,8 @@
 			rateclass->last.tv_sec = now.tv_sec;
 			rateclass->last.tv_usec = now.tv_usec;
 		}
+	} else {
+		purple_debug_warning("oscar", "No rate class found for family %u subtype %u\n", family, subtype);
 	}
 
 	if (enqueue)
--- a/libpurple/protocols/oscar/misc.c	Thu Apr 24 02:16:30 2008 +0000
+++ b/libpurple/protocols/oscar/misc.c	Thu Apr 24 11:10:03 2008 +0000
@@ -42,11 +42,7 @@
 	FlapFrame *frame;
 	aim_snacid_t snacid = 0x00000000;
 
-	frame = flap_frame_new(od, 0x02, 10);
-
-	aim_putsnac(&frame->data, family, subtype, 0x0000, snacid);
-
-	flap_connection_send(conn, frame);
+	flap_connection_send_snac(od, conn, family, subtype, 0x0000, snacid, NULL);
 }
 
 void
@@ -55,18 +51,15 @@
 	FlapFrame *frame;
 	aim_snacid_t snacid;
 
-	frame = flap_frame_new(od, 0x02, 10);
+	snacid = aim_cachesnac(od, family, subtype, 0x0000, NULL, 0);
 
-	snacid = aim_cachesnac(od, family, subtype, 0x0000, NULL, 0);
-	aim_putsnac(&frame->data, family, subtype, 0x0000, snacid);
-
-	flap_connection_send(conn, frame);
+	flap_connection_send_snac(od, conn, family, subtype, 0x0000, snacid, NULL);
 }
 
 void
 aim_genericreq_l(OscarData *od, FlapConnection *conn, guint16 family, guint16 subtype, guint32 *longdata)
 {
-	FlapFrame *frame;
+	ByteStream bs;
 	aim_snacid_t snacid;
 
 	if (!longdata)
@@ -75,20 +68,21 @@
 		return;
 	}
 
-	frame = flap_frame_new(od, 0x02, 10+4);
+	byte_stream_new(&bs, 4);
 
 	snacid = aim_cachesnac(od, family, subtype, 0x0000, NULL, 0);
 
-	aim_putsnac(&frame->data, family, subtype, 0x0000, snacid);
-	byte_stream_put32(&frame->data, *longdata);
+	byte_stream_put32(&bs, *longdata);
 
-	flap_connection_send(conn, frame);
+	flap_connection_send_snac(od, conn, family, subtype, 0x0000, snacid, NULL);
+
+	byte_stream_destroy(&bs);
 }
 
 void
 aim_genericreq_s(OscarData *od, FlapConnection *conn, guint16 family, guint16 subtype, guint16 *shortdata)
 {
-	FlapFrame *frame;
+	ByteStream bs;
 	aim_snacid_t snacid;
 
 	if (!shortdata)
@@ -97,14 +91,15 @@
 		return;
 	}
 
-	frame = flap_frame_new(od, 0x02, 10+2);
+	byte_stream_new(&bs, 2);
 
 	snacid = aim_cachesnac(od, family, subtype, 0x0000, NULL, 0);
 
-	aim_putsnac(&frame->data, family, subtype, 0x0000, snacid);
-	byte_stream_put16(&frame->data, *shortdata);
+	byte_stream_put16(&bs, *shortdata);
 
-	flap_connection_send(conn, frame);
+	flap_connection_send_snac(od, conn, family, subtype, 0x0000, snacid, NULL);
+
+	byte_stream_destroy(&bs);
 }
 
 /*
--- a/libpurple/protocols/oscar/oscar.h	Thu Apr 24 02:16:30 2008 +0000
+++ b/libpurple/protocols/oscar/oscar.h	Thu Apr 24 11:10:03 2008 +0000
@@ -1549,6 +1549,7 @@
 /* bstream.c */
 int byte_stream_new(ByteStream *bs, guint32 len);
 int byte_stream_init(ByteStream *bs, guint8 *data, int len);
+void byte_stream_destroy(ByteStream *bs);
 int byte_stream_empty(ByteStream *bs);
 int byte_stream_curpos(ByteStream *bs);
 int byte_stream_setpos(ByteStream *bs, unsigned int off);