pidgin: 2e791da1: All SNACs on FLAP channel 2 except in th...

evands at pidgin.im evands at pidgin.im
Thu Apr 24 07:15:42 EDT 2008


-----------------------------------------------------------------
Revision: 2e791da1fb1cfd6b751a0cef01aa83dc89692051
Ancestor: 90011f8844f95be26206d5698b603f1692f319a0
Author: evands at pidgin.im
Date: 2008-04-24T11:10:03
Branch: im.pidgin.pidgin
URL: http://d.pidgin.im/viewmtn/revision/info/2e791da1fb1cfd6b751a0cef01aa83dc89692051

Modified 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

ChangeLog: 

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.

-------------- next part --------------
============================================================
--- libpurple/protocols/oscar/bstream.c	262e9c813946f366ac15715a150cf71e8e737990
+++ libpurple/protocols/oscar/bstream.c	f45c93484941cfd334b3d42d577c4cb8f3ace17f
@@ -45,6 +45,11 @@ int byte_stream_init(ByteStream *bs, gui
 	return 0;
 }
 
+void byte_stream_destroy(ByteStream *bs)
+{
+	g_free(bs->data);
+}
+
 int byte_stream_empty(ByteStream *bs)
 {
 	return bs->len - bs->offset;
============================================================
--- libpurple/protocols/oscar/family_admin.c	73a745e78d1467d6c32cdbdfc9a70bd97bf82c4a
+++ libpurple/protocols/oscar/family_admin.c	b574f6479c03d3f93ffe867d407041b851d26f41
@@ -40,18 +40,18 @@ aim_admin_getinfo(OscarData *od, FlapCon
 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 @@ infochange(OscarData *od, FlapConnection
  * 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));
+	byte_stream_new(&bs, 2+2+strlen(newnick));
 
-	snacid = aim_cachesnac(od, 0x0007, 0x0004, 0x0000, NULL, 0);
-	aim_putsnac(&fr->data, 0x0007, 0x0004, 0x0000, snacid);
-
 	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,25 +153,23 @@ aim_admin_changepasswd(OscarData *od, Fl
 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));
+	byte_stream_new(&bs, 4+strlen(curpw)+4+strlen(newpw));
 
-	snacid = aim_cachesnac(od, 0x0007, 0x0004, 0x0000, NULL, 0);
-	aim_putsnac(&fr->data, 0x0007, 0x0004, 0x0000, snacid);
-
 	/* new password TLV t(0002) */
 	aim_tlvlist_add_str(&tlvlist, 0x0002, newpw);
 
 	/* 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,22 +181,22 @@ aim_admin_setemail(OscarData *od, FlapCo
 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));
+	byte_stream_new(&bs, 2+2+strlen(newemail));
 
-	snacid = aim_cachesnac(od, 0x0007, 0x0004, 0x0000, NULL, 0);
-	aim_putsnac(&fr->data, 0x0007, 0x0004, 0x0000, snacid);
-
 	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;
 }
 
============================================================
--- libpurple/protocols/oscar/family_alert.c	a299784e3c0c6ff96c25e0bc9a528c311d73434b
+++ libpurple/protocols/oscar/family_alert.c	e4a2cc635673788e9b6b7d6c477172b06e1048ec
@@ -41,41 +41,42 @@ aim_email_sendcookies(OscarData *od)
 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,26 +172,27 @@ aim_email_activate(OscarData *od)
 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;
 }
 
============================================================
--- libpurple/protocols/oscar/family_bart.c	9208b274f0ee80b3af2b1698300c8ceb890371fc
+++ libpurple/protocols/oscar/family_bart.c	8e103e55d57f0dbf5aeb9d04d5aad0b94f5796fc
@@ -40,25 +40,26 @@ aim_bart_upload(OscarData *od, const gui
 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,31 +99,32 @@ aim_bart_request(OscarData *od, const ch
 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;
 }
 
============================================================
--- libpurple/protocols/oscar/family_bos.c	2d8c644840c893272b21047244c8820ffe721579
+++ libpurple/protocols/oscar/family_bos.c	c19e9497e777dbcba750b82a01e13d58d1c3756a
@@ -114,7 +114,7 @@ int aim_bos_changevisibility(OscarData *
  */
 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,25 +139,25 @@ int aim_bos_changevisibility(OscarData *
 	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);
+	byte_stream_new(&bs, packlen);
 
-	snacid = aim_cachesnac(od, 0x0009, subtype, 0x0000, NULL, 0);
-	aim_putsnac(&frame->data, 0x0009, subtype, 0x00, snacid);
-
 	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;
 }
 
============================================================
--- libpurple/protocols/oscar/family_buddy.c	124b859676711289ab7502076e731e955a5afb7a
+++ libpurple/protocols/oscar/family_buddy.c	cab8c698b9de21da9fcf9f6a6fc6076cdbd6b6cd
@@ -97,21 +97,21 @@ aim_buddylist_addbuddy(OscarData *od, Fl
 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));
 
-	snacid = aim_cachesnac(od, 0x0003, 0x0004, 0x0000, sn, strlen(sn)+1);
-	aim_putsnac(&frame->data, 0x0003, 0x0004, 0x0000, snacid);
+	byte_stream_put8(&bs, strlen(sn));
+	byte_stream_putstr(&bs, sn);
 
-	byte_stream_put8(&frame->data, strlen(sn));
-	byte_stream_putstr(&frame->data, sn);
+	snacid = aim_cachesnac(od, 0x0003, 0x0004, 0x0000, sn, strlen(sn)+1);
+	flap_connection_send_snac(od, conn, 0x0003, 0x0004, 0x0000, snacid, &bs);
 
-	flap_connection_send(conn, frame);
+	byte_stream_destroy(&bs);
 
 	return 0;
 }
@@ -129,7 +129,7 @@ aim_buddylist_set(OscarData *od, FlapCon
 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,11 +145,8 @@ aim_buddylist_set(OscarData *od, FlapCon
 		tmpptr = strtok(NULL, "&");
 	}
 
-	frame = flap_frame_new(od, 0x02, 10+len);
+	byte_stream_new(&bs, len);
 
-	snacid = aim_cachesnac(od, 0x0003, 0x0004, 0x0000, NULL, 0);
-	aim_putsnac(&frame->data, 0x0003, 0x0004, 0x0000, snacid);
-
 	strncpy(localcpy, buddy_list, strlen(buddy_list) + 1);
 
 	for (tmpptr = strtok(localcpy, "&"); tmpptr; ) {
@@ -157,13 +154,16 @@ aim_buddylist_set(OscarData *od, FlapCon
 		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);
 
 	return 0;
@@ -179,21 +179,21 @@ aim_buddylist_removebuddy(OscarData *od,
 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));
 
-	snacid = aim_cachesnac(od, 0x0003, 0x0005, 0x0000, sn, strlen(sn)+1);
-	aim_putsnac(&frame->data, 0x0003, 0x0005, 0x0000, snacid);
+	byte_stream_put8(&bs, strlen(sn));
+	byte_stream_putstr(&bs, sn);
 
-	byte_stream_put8(&frame->data, strlen(sn));
-	byte_stream_putstr(&frame->data, sn);
+	snacid = aim_cachesnac(od, 0x0003, 0x0005, 0x0000, sn, strlen(sn)+1);
+	flap_connection_send_snac(od, conn, 0x0003, 0x0005, 0x0000, snacid, &bs);
 
-	flap_connection_send(conn, frame);
+	byte_stream_destroy(&bs);
 
 	return 0;
 }
============================================================
--- libpurple/protocols/oscar/family_chat.c	77d8c73d3f786ad96b7a5c3f4f3d6306d34a7e7f
+++ libpurple/protocols/oscar/family_chat.c	dc0c240cb692a2d53d4351f732dbb844da738e62
@@ -353,7 +353,7 @@ aim_chat_send_im(OscarData *od, FlapConn
 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 @@ aim_chat_send_im(OscarData *od, FlapConn
 	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_chat_send_im(OscarData *od, FlapConn
 	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_chat_send_im(OscarData *od, FlapConn
 	 */
 	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;
 }
 
============================================================
--- libpurple/protocols/oscar/family_chatnav.c	ebd5b2409e1ce2cc36e6a47bcf204ba56fc2c52c
+++ libpurple/protocols/oscar/family_chatnav.c	e8a1c4e5709be724e14508b66a238bf5b927881a
@@ -91,17 +91,16 @@ int aim_chatnav_createroom(OscarData *od
 	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 @@ int aim_chatnav_createroom(OscarData *od
 	 * 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,23 +122,25 @@ int aim_chatnav_createroom(OscarData *od
 	 * 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;
 }
 
============================================================
--- libpurple/protocols/oscar/family_feedbag.c	ba3e394439bb31e14198edca7aed575ea4f068e3
+++ libpurple/protocols/oscar/family_feedbag.c	2a8d7de28eaff9c1e95e9ed0267e2a5abb7fbcd0
@@ -1241,21 +1241,21 @@ int aim_ssi_reqifchanged(OscarData *od, 
 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);
 
-	snacid = aim_cachesnac(od, SNAC_FAMILY_FEEDBAG, SNAC_SUBTYPE_FEEDBAG_REQIFCHANGED, 0x0000, NULL, 0);
+	byte_stream_put32(&bs, timestamp);
+	byte_stream_put16(&bs, numitems);
 
-	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);
+	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);
 
-	flap_connection_send(conn, frame);
+	byte_stream_destroy(&bs);
 
 	/* Free any current data, just in case */
 	aim_ssi_freelist(od);
@@ -1343,43 +1343,45 @@ static int aim_ssi_addmoddel(OscarData *
 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);
 
-	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);
+	aim_putsnac(&bs, SNAC_FAMILY_FEEDBAG, od->ssi.pending->action, 0x0000, snacid);
 
 	for (cur=od->ssi.pending; cur; cur=cur->next) {
-		byte_stream_put16(&frame->data, cur->item->name ? strlen(cur->item->name) : 0);
+		byte_stream_put16(&bs, 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);
+			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(&frame->data, &cur->item->data);
+			aim_tlvlist_write(&bs, &cur->item->data);
 	}
 
-	flap_connection_send(conn, frame);
+	snacid = aim_cachesnac(od, SNAC_FAMILY_FEEDBAG, od->ssi.pending->action, 0x0000, NULL, 0);
+	flap_connection_send_snac(od, conn, SNAC_FAMILY_FEEDBAG, od->ssi.pending->action, 0x0000, snacid, &bs);
 
+	byte_stream_destroy(&bs);
+
 	return 0;
 }
 
@@ -1684,33 +1686,33 @@ int aim_ssi_sendauth(OscarData *od, char
 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);
+	byte_stream_new(&bs, 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);
-
 	/* 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,33 +1760,35 @@ int aim_ssi_sendauthrequest(OscarData *o
 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,
 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);
+	byte_stream_new(&bs, 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);
-
 	/* 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;
 }
 
============================================================
--- libpurple/protocols/oscar/family_icbm.c	8fdd7bd0305cdda828beb1281eab65a19d22acf1
+++ libpurple/protocols/oscar/family_icbm.c	eef39107ce43680679a3ddc740f3c0d762106fd3
@@ -161,7 +161,7 @@ int aim_im_setparams(OscarData *od, stru
 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 @@ int aim_im_setparams(OscarData *od, stru
 	if (!params)
 		return -EINVAL;
 
-	frame = flap_frame_new(od, 0x02, 10+16);
+	byte_stream_new(&bs, 16);
 
-	snacid = aim_cachesnac(od, 0x0004, 0x0002, 0x0000, NULL, 0);
-	aim_putsnac(&frame->data, 0x0004, 0x0002, 0x0000, snacid);
-
 	/* 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);
+	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);
 
-	flap_connection_send(conn, frame);
-
+	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 
 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 @@ int aim_im_sendch2_chatinvite(OscarData 
 
 	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 @@ int aim_im_sendch2_chatinvite(OscarData 
 		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 @@ int aim_im_sendch2_chatinvite(OscarData 
 	aim_tlvlist_write(&hdrbs, &inner_tlvlist);
 
 	aim_tlvlist_add_raw(&outer_tlvlist, 0x0005, byte_stream_curpos(&hdrbs), hdrbs.data);
-	g_free(hdrbs.data);
+	byte_stream_destroy(&hdrbs);
 
-	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);
 
 	return 0;
 }
@@ -534,7 +535,7 @@ int aim_im_sendch2_icon(OscarData *od, c
 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 @@ int aim_im_sendch2_icon(OscarData *od, c
 
 	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(&bs, 0x0005);
+	byte_stream_put16(&bs, 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, 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);
+	byte_stream_put16(&bs, 0x0003);
+	byte_stream_put16(&bs, 0x0000);
 
-	flap_connection_send(conn, frame);
+	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,
 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 @@ int aim_im_sendch2_rtfmsg(OscarData *od,
 
 	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(&bs, 0x0005);
+	byte_stream_put16(&bs, 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, 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_put16(&bs, 0x2711);
+	byte_stream_put16(&bs, 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(&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(&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(&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(&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_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(&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);
+	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(conn, frame);
+	flap_connection_send_snac(od, conn, 0x0004, 0x0006, 0x0000, snacid, &bs);
 
+	byte_stream_destroy(&bs);
+	
 	return 0;
 }
 
@@ -695,7 +698,7 @@ aim_im_sendch2_cancel(PeerConnection *pe
 {
 	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 @@ aim_im_sendch2_cancel(PeerConnection *pe
 	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_im_sendch2_cancel(PeerConnection *pe
 	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 @@ aim_im_sendch2_connected(PeerConnection 
 {
 	OscarData *od;
 	FlapConnection *conn;
-	FlapFrame *frame;
+	ByteStream bs;
 	aim_snacid_t snacid;
 
 	od = peer_conn->od;
@@ -753,21 +757,22 @@ aim_im_sendch2_connected(PeerConnection 
 	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);
+	aim_im_puticbm(&bs, 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);
+	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(conn, frame);
+	flap_connection_send_snac(od, conn, 0x0004, 0x0006, 0x0000, snacid, &bs);
+
+	byte_stream_destroy(&bs);	
 }
 
 /**
@@ -781,7 +786,7 @@ aim_im_sendch2_odc_requestdirect(OscarDa
 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 @@ aim_im_sendch2_odc_requestdirect(OscarDa
 	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_im_sendch2_odc_requestdirect(OscarDa
 	aim_tlvlist_write(&hdrbs, &inner_tlvlist);
 
 	aim_tlvlist_add_raw(&outer_tlvlist, 0x0005, byte_stream_curpos(&hdrbs), hdrbs.data);
-	g_free(hdrbs.data);
+	byte_stream_destroy(&hdrbs);
 
-	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);
 }
 
 /**
@@ -832,7 +838,7 @@ aim_im_sendch2_odc_requestproxy(OscarDat
 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 @@ aim_im_sendch2_odc_requestproxy(OscarDat
 	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_im_sendch2_odc_requestproxy(OscarDat
 	aim_tlvlist_write(&hdrbs, &inner_tlvlist);
 
 	aim_tlvlist_add_raw(&outer_tlvlist, 0x0005, byte_stream_curpos(&hdrbs), hdrbs.data);
-	g_free(hdrbs.data);
+	byte_stream_destroy(&hdrbs);
 
-	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);
 }
 
 /**
@@ -894,7 +901,7 @@ aim_im_sendch2_sendfile_requestdirect(Os
 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 @@ aim_im_sendch2_sendfile_requestdirect(Os
 	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_im_sendch2_sendfile_requestdirect(Os
 
 	aim_tlvlist_write(&hdrbs, &inner_tlvlist);
 	aim_tlvlist_add_raw(&outer_tlvlist, 0x0005, byte_stream_curpos(&hdrbs), hdrbs.data);
-	g_free(hdrbs.data);
+	byte_stream_destroy(&hdrbs);
 
-	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);
 }
 
 /**
@@ -976,7 +984,7 @@ aim_im_sendch2_sendfile_requestproxy(Osc
 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 @@ aim_im_sendch2_sendfile_requestproxy(Osc
 	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 @@ aim_im_sendch2_sendfile_requestproxy(Osc
 
 	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);
+		byte_stream_putstr(&filename_bs, filename);
+		byte_stream_put8(&filename_bs, 0x00);
 
-		aim_tlvlist_add_raw(&inner_tlvlist, 0x2711, bs.len, bs.data);
-		g_free(bs.data);
+		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);
+	byte_stream_destroy(&hdrbs);
 
-	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);
 }
 
 /**
@@ -1072,7 +1081,7 @@ int aim_im_sendch2_geticqaway(OscarData 
 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 @@ int aim_im_sendch2_geticqaway(OscarData 
 
 	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(&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(&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, 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(&bs, 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, 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);
+	byte_stream_put16(&bs, 0x0003);
+	byte_stream_put16(&bs, 0x0000);
 
-	flap_connection_send(conn, frame);
+	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 
 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 @@ int aim_im_sendch4(OscarData *od, const 
 	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);
+	byte_stream_put16(&bs, 0x0006);
+	byte_stream_put16(&bs, 0x0000);
 
-	flap_connection_send(conn, frame);
+	flap_connection_send_snac(od, conn, 0x0004, 0x0006, 0x0000, snacid, &bs);
 
+	byte_stream_destroy(&bs);
+	
 	return 0;
 }
 
@@ -2249,23 +2260,24 @@ int aim_im_warn(OscarData *od, FlapConne
  */
 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);
+	byte_stream_put16(&bs, (flags & AIM_WARN_ANON) ? 0x0001 : 0x0000);
+	byte_stream_put8(&bs, strlen(sn));
+	byte_stream_putstr(&bs, sn);
 
-	flap_connection_send(conn, frame);
+	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, c
 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_putraw(&bs, cookie, 8);
 
-	byte_stream_put16(&frame->data, 0x0002); /* channel */
-	byte_stream_put8(&frame->data, strlen(sn));
-	byte_stream_putstr(&frame->data, sn);
+	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, guint1
 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 @@ int aim_im_sendmtn(OscarData *od, guint1
 	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);
+	byte_stream_put16(&bs, type2);
 
-	flap_connection_send(conn, frame);
+	flap_connection_send_snac(od, conn, 0x0004, 0x0014, 0x0000, snacid, &bs);
 
+	byte_stream_destroy(&bs);
+	
 	return 0;
 }
 
============================================================
--- libpurple/protocols/oscar/family_icq.c	e8c57aec086ccad25bd2e0fe98cfaf4eaac8d7c9
+++ libpurple/protocols/oscar/family_icq.c	058eed88c66bcd71aeef29362f8e9a6cc22645ab
@@ -29,7 +29,7 @@ int aim_icq_reqofflinemsgs(OscarData *od
 int aim_icq_reqofflinemsgs(OscarData *od)
 {
 	FlapConnection *conn;
-	FlapFrame *frame;
+	ByteStream bs;
 	aim_snacid_t snacid;
 	int bslen;
 
@@ -38,28 +38,29 @@ int aim_icq_reqofflinemsgs(OscarData *od
 
 	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,22 +70,23 @@ int aim_icq_ackofflinemsgs(OscarData *od
 
 	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;
 }
 #endif /* OLDSTYLE_ICQ_OFFLINEMSGS */
@@ -93,7 +95,7 @@ aim_icq_setsecurity(OscarData *od, gbool
 aim_icq_setsecurity(OscarData *od, gboolean auth_required, gboolean webaware)
 {
 	FlapConnection *conn;
-	FlapFrame *frame;
+	ByteStream bs;
 	aim_snacid_t snacid;
 	int bslen;
 
@@ -102,31 +104,32 @@ aim_icq_setsecurity(OscarData *od, gbool
 
 	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, 
 int aim_icq_changepasswd(OscarData *od, const char *passwd)
 {
 	FlapConnection *conn;
-	FlapFrame *frame;
+	ByteStream bs;
 	aim_snacid_t snacid;
 	int bslen, passwdlen;
 
@@ -156,33 +159,34 @@ int aim_icq_changepasswd(OscarData *od, 
 		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;
 }
 
 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,24 +199,25 @@ int aim_icq_getallinfo(OscarData *od, co
 
 	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);
 	info->reqid = snacid;
@@ -226,7 +231,7 @@ int aim_icq_getalias(OscarData *od, cons
 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 @@ int aim_icq_getalias(OscarData *od, cons
 
 	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,
 int aim_icq_getsimpleinfo(OscarData *od, const char *uin)
 {
 	FlapConnection *conn;
-	FlapFrame *frame;
+	ByteStream bs;
 	aim_snacid_t snacid;
 	int bslen;
 
@@ -282,24 +288,25 @@ int aim_icq_getsimpleinfo(OscarData *od,
 
 	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, co
 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 @@ int aim_icq_sendxmlreq(OscarData *od, co
 
 	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
 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,36 +409,37 @@ int aim_icq_sendsms(OscarData *od, const
 
 	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,
 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,41 +467,40 @@ int aim_icq_getstatusnote(OscarData *od,
 	}
 
 	bslen = 2 + 4 + 2 + 2 + 2 + 2 + 58 + strlen(uin);
+	byte_stream_new(&bs, 4 + bslen);
 
-	frame = flap_frame_new(od, 0x02, 10 + 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 @@ icqresponse(OscarData *od, FlapConnectio
 			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 @@ icqresponse(OscarData *od, FlapConnectio
 					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 @@ icqresponse(OscarData *od, FlapConnectio
 				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);
============================================================
--- libpurple/protocols/oscar/family_locate.c	923ee1af6edf62feef1f8ae0785bdff0095c2d1f
+++ libpurple/protocols/oscar/family_locate.c	8bb1a169ca0d4a0964a4d1d3873ea9cd39551e74
@@ -1047,7 +1047,7 @@ aim_locate_setprofile(OscarData *od,
 				  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,16 +1092,17 @@ aim_locate_setprofile(OscarData *od,
 			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, guint3
 aim_locate_setcaps(OscarData *od, guint32 caps)
 {
 	FlapConnection *conn;
-	FlapFrame *frame;
+	ByteStream bs;
 	aim_snacid_t snacid;
 	GSList *tlvlist = NULL;
 
@@ -1121,16 +1122,17 @@ aim_locate_setcaps(OscarData *od, guint3
 
 	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,23 +1149,24 @@ aim_locate_getinfo(OscarData *od, const 
 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,
 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,16 +1272,17 @@ int aim_locate_setdirinfo(OscarData *od,
 	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
 int aim_locate_000b(OscarData *od, const char *sn)
 {
 	FlapConnection *conn;
-	FlapFrame *frame;
+	ByteStream bs;
 	aim_snacid_t snacid;
 
 		return -EINVAL;
@@ -1296,16 +1300,17 @@ int aim_locate_000b(OscarData *od, const
 	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, c
 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 @@ aim_locate_setinterests(OscarData *od, c
 	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, c
 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;
 }
============================================================
--- libpurple/protocols/oscar/family_odir.c	94c9fb7d228e8e5afad625a7eb14148557b85658
+++ libpurple/protocols/oscar/family_odir.c	84e44db313de45461ac3873dd71873d411f78977
@@ -41,7 +41,7 @@ int aim_odir_email(OscarData *od, const 
 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,15 +53,16 @@ int aim_odir_email(OscarData *od, const 
 	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 c
 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 @@ int aim_odir_name(OscarData *od, const c
 	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, con
 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 @@ int aim_odir_interest(OscarData *od, con
 	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;
 }
 
============================================================
--- libpurple/protocols/oscar/family_oservice.c	896a2f298fb653ee70d2a4ac1ec2180405041ad0
+++ libpurple/protocols/oscar/family_oservice.c	33c8f853c52bcaf6a77249caec571f8c0a358dcd
@@ -31,15 +31,12 @@ aim_clientready(OscarData *od, FlapConne
 void
 aim_clientready(OscarData *od, FlapConnection *conn)
 {
-	FlapFrame *frame;
+	ByteStream bs;
 	aim_snacid_t snacid;
 	GSList *cur;
 
-	frame = flap_frame_new(od, 0x02, 1152);
+	byte_stream_new(&bs, 1142);
 
-	snacid = aim_cachesnac(od, 0x0001, 0x0002, 0x0000, NULL, 0);
-	aim_putsnac(&frame->data, 0x0001, 0x0002, 0x0000, snacid);
-
 	/*
 	 * Send only the tool versions that the server cares about (that it
 	 * marked as supporting in the server ready SNAC).
@@ -50,14 +47,17 @@ aim_clientready(OscarData *od, FlapConne
 
 		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 exc
 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 @@ aim_chat_join(OscarData *od, guint16 exc
 	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 @@ aim_srv_rates_addparam(OscarData *od, Fl
 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);
+	byte_stream_new(&bs, 502);
 
-	snacid = aim_cachesnac(od, 0x0001, 0x0008, 0x0000, NULL, 0);
-	aim_putsnac(&frame->data, 0x0001, 0x0008, 0x0000, snacid);
-
 	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);
+	byte_stream_new(&bs, 502);
 
-	snacid = aim_cachesnac(od, 0x0001, 0x0009, 0x0000, NULL, 0);
-	aim_putsnac(&frame->data, 0x0001, 0x0009, 0x0000, snacid);
-
 	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,24 +489,24 @@ aim_srv_sendpauseack(OscarData *od, Flap
 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);
+	byte_stream_new(&bs, 1014);
 
-	snacid = aim_cachesnac(od, 0x0001, 0x000c, 0x0000, NULL, 0);
-	aim_putsnac(&frame->data, 0x0001, 0x000c, 0x0000, snacid);
-
 	/*
 	 * This list should have all the groups that the original
 	 * Host Online / Server Ready said this host supports.  And
 	 * 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,15 +732,12 @@ aim_srv_setversions(OscarData *od, FlapC
 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);
+	byte_stream_new(&bs, 1142);
 
-	snacid = aim_cachesnac(od, 0x0001, 0x0017, 0x0000, NULL, 0);
-	aim_putsnac(&frame->data, 0x0001, 0x0017, 0x0000, snacid);
-
 	/*
 	 * Send only the versions that the server cares about (that it
 	 * marked as supporting in the server ready SNAC).
@@ -751,12 +748,15 @@ aim_srv_setversions(OscarData *od, FlapC
 
 		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 @@ aim_srv_setextrainfo(OscarData *od,
 		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_srv_setextrainfo(OscarData *od,
 
 		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));
 
-	snacid = aim_cachesnac(od, 0x0001, 0x001e, 0x0000, NULL, 0);
-	aim_putsnac(&frame->data, 0x0001, 0x001e, 0x0000, snacid);
-
-	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, 0x001e, 0x0000, NULL, 0);
+	flap_connection_send_snac(od, conn, 0x0001, 0x001e, 0x0000, snacid, &bs);
 
+	byte_stream_destroy(&bs);
+	
 	return 0;
 }
 
@@ -937,22 +937,19 @@ aim_sendmemblock(OscarData *od, FlapConn
 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);
+	byte_stream_put16(&bs, 0x0010); /* md5 is always 16 bytes */
 
-	aim_putsnac(&frame->data, 0x0001, 0x0020, 0x0000, snacid);
-	byte_stream_put16(&frame->data, 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 @@ aim_sendmemblock(OscarData *od, FlapConn
 		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 @@ aim_sendmemblock(OscarData *od, FlapConn
 		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 @@ aim_sendmemblock(OscarData *od, FlapConn
 		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 @@ aim_sendmemblock(OscarData *od, FlapConn
 
 	}
 
-	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;
 }
 
============================================================
--- libpurple/protocols/oscar/family_userlookup.c	30746d30707df77e27888faf85e6c7de78afd4e0
+++ libpurple/protocols/oscar/family_userlookup.c	b59824ef432d65c84658fd72b55086d92f77dcf7
@@ -62,7 +62,7 @@ int aim_search_address(OscarData *od, co
 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 @@ int aim_search_address(OscarData *od, co
 	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;
 }
 
============================================================
--- libpurple/protocols/oscar/flap_connection.c	7a4abab5b2507dd0b25ae272ae8ad81606a1e511
+++ libpurple/protocols/oscar/flap_connection.c	7740afcbe34c79e9d9d086fdbfbfffde24344b39
@@ -115,6 +115,7 @@ static gboolean flap_connection_send_que
 	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 @@ flap_connection_send_snac(OscarData *od,
 		/* (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 @@ flap_connection_send_snac(OscarData *od,
 			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)
============================================================
--- libpurple/protocols/oscar/misc.c	4b53697c7ead77d36413be3a3fd4cbfa444c1fea
+++ libpurple/protocols/oscar/misc.c	0d5b8718f1cf21b4f2b6f45335c7e00eb6e318da
@@ -42,11 +42,7 @@ aim_genericreq_n(OscarData *od, FlapConn
 	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 @@ aim_genericreq_n_snacid(OscarData *od, F
 	FlapFrame *frame;
 	aim_snacid_t snacid;
 
-	frame = flap_frame_new(od, 0x02, 10);
-
 	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 @@ aim_genericreq_l(OscarData *od, FlapConn
 		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 @@ aim_genericreq_s(OscarData *od, FlapConn
 		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);
 }
 
 /*
============================================================
--- libpurple/protocols/oscar/oscar.h	e0168c2cb1f5b530919af14fa62e8786c0df4bde
+++ libpurple/protocols/oscar/oscar.h	6fcd924bf832e3a91a72dd73004516a4d2440015
@@ -1549,6 +1549,7 @@ int byte_stream_init(ByteStream *bs, gui
 /* 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);


More information about the Commits mailing list