changeset 4889:f7150929332b

[gaim-migrate @ 5219] Fix a lil ko.po problem some people with weird gettexts had. Swap the "Open Mail" and "Close" buttons on the mail notification dialog. Is this more HIGgish? If not, lemme know and I'll burninate. I took out lots of aim_conn_t's from ssi.c in favor of looking up the connection from the session when it is needed. I like this way better, and I've been slowly moving towards it. Added some code used for uploading icons. I haven't gotten it to work yet. I'm still not exactly sure what I'm supposed to be doing. 'twould be nice if Windows AIM still did this correctly. 'twould be nice to have that kind of job security. committer: Tailor Script <tailor@pidgin.im>
author Mark Doliner <mark@kingant.net>
date Tue, 25 Mar 2003 05:01:00 +0000
parents 912294585edf
children 89cb14edf8cf
files po/ko.po src/protocols/oscar/aim.h src/protocols/oscar/icon.c src/protocols/oscar/oscar.c src/protocols/oscar/ssi.c src/prpl.c
diffstat 6 files changed, 268 insertions(+), 147 deletions(-) [+]
line wrap: on
line diff
--- a/po/ko.po	Tue Mar 25 02:30:08 2003 +0000
+++ b/po/ko.po	Tue Mar 25 05:01:00 2003 +0000
@@ -3165,7 +3165,7 @@
 #: src/buddy.c:853
 #, c-format
 msgid "Idle (%dh%02dm) "
-msgstr "»ç¿ë¾ÈÇÔ (%d½Ã°£%02ºÐ)"
+msgstr "»ç¿ë¾ÈÇÔ (%d½Ã°£%02dºÐ)"
 
 #: src/buddy.c:855
 #, c-format
--- a/src/protocols/oscar/aim.h	Tue Mar 25 02:30:08 2003 +0000
+++ b/src/protocols/oscar/aim.h	Tue Mar 25 05:01:00 2003 +0000
@@ -1126,7 +1126,8 @@
 
 
 /* icon.c */
-faim_export int aim_icon_requesticon(aim_session_t *sess, const char *sn, const fu8_t *iconstr, fu16_t iconstrlen);
+faim_export int aim_icon_upload(aim_session_t *sess, int num, const fu8_t *icon, fu16_t iconlen);
+faim_export int aim_icon_request(aim_session_t *sess, const char *sn, const fu8_t *iconstr, fu16_t iconstrlen);
 
 
 
@@ -1164,19 +1165,20 @@
 
 
 /* ssi.c */
-#define AIM_SSI_TYPE_BUDDY         0x0000
-#define AIM_SSI_TYPE_GROUP         0x0001
-#define AIM_SSI_TYPE_PERMIT        0x0002
-#define AIM_SSI_TYPE_DENY          0x0003
-#define AIM_SSI_TYPE_PDINFO        0x0004
-#define AIM_SSI_TYPE_PRESENCEPREFS 0x0005
+#define AIM_SSI_TYPE_BUDDY		0x0000
+#define AIM_SSI_TYPE_GROUP		0x0001
+#define AIM_SSI_TYPE_PERMIT		0x0002
+#define AIM_SSI_TYPE_DENY		0x0003
+#define AIM_SSI_TYPE_PDINFO		0x0004
+#define AIM_SSI_TYPE_PRESENCEPREFS	0x0005
+#define AIM_SSI_TYPE_ICONINFO		0x0014
 
-#define AIM_SSI_ACK_SUCCESS      0x0000
-#define AIM_SSI_ACK_ITEMNOTFOUND 0x0002
-#define AIM_SSI_ACK_IDNUMINUSE   0x000a
-#define AIM_SSI_ACK_ATMAX        0x000c
-#define AIM_SSI_ACK_INVALIDNAME  0x000d
-#define AIM_SSI_ACK_AUTHREQUIRED 0x000e
+#define AIM_SSI_ACK_SUCCESS		0x0000
+#define AIM_SSI_ACK_ITEMNOTFOUND	0x0002
+#define AIM_SSI_ACK_IDNUMINUSE		0x000a
+#define AIM_SSI_ACK_ATMAX		0x000c
+#define AIM_SSI_ACK_INVALIDNAME		0x000d
+#define AIM_SSI_ACK_AUTHREQUIRED	0x000e
 
 struct aim_ssi_item {
 	char *name;
@@ -1196,15 +1198,15 @@
 };
 
 /* These build the actual SNACs and queue them to be sent */
-/* 0x0002 */ faim_export int aim_ssi_reqrights(aim_session_t *sess, aim_conn_t *conn);
-/* 0x0005 */ faim_export int aim_ssi_reqdata(aim_session_t *sess, aim_conn_t *conn, time_t localstamp, fu16_t localrev);
+/* 0x0002 */ faim_export int aim_ssi_reqrights(aim_session_t *sess);
+/* 0x0005 */ faim_export int aim_ssi_reqdata(aim_session_t *sess, time_t localstamp, fu16_t localrev);
 /* 0x0007 */ faim_export int aim_ssi_enable(aim_session_t *sess);
-/* 0x0008 */ faim_export int aim_ssi_addmoddel(aim_session_t *sess, aim_conn_t *conn);
-/* 0x0011 */ faim_export int aim_ssi_modbegin(aim_session_t *sess, aim_conn_t *conn);
-/* 0x0012 */ faim_export int aim_ssi_modend(aim_session_t *sess, aim_conn_t *conn);
-/* 0x0014 */ faim_export int aim_ssi_sendauth(aim_session_t *sess, aim_conn_t *conn, char *sn, char *msg);
-/* 0x0018 */ faim_export int aim_ssi_sendauthrequest(aim_session_t *sess, aim_conn_t *conn, char *sn, char *msg);
-/* 0x001a */ faim_export int aim_ssi_sendauthreply(aim_session_t *sess, aim_conn_t *conn, char *sn, fu8_t reply, char *msg);
+/* 0x0008 */ faim_export int aim_ssi_addmoddel(aim_session_t *sess);
+/* 0x0011 */ faim_export int aim_ssi_modbegin(aim_session_t *sess);
+/* 0x0012 */ faim_export int aim_ssi_modend(aim_session_t *sess);
+/* 0x0014 */ faim_export int aim_ssi_sendauth(aim_session_t *sess, char *sn, char *msg);
+/* 0x0018 */ faim_export int aim_ssi_sendauthrequest(aim_session_t *sess, char *sn, char *msg);
+/* 0x001a */ faim_export int aim_ssi_sendauthreply(aim_session_t *sess, char *sn, fu8_t reply, char *msg);
 
 /* Client functions for retrieving SSI data */
 faim_export struct aim_ssi_item *aim_ssi_itemlist_find(struct aim_ssi_item *list, fu16_t gid, fu16_t bid);
@@ -1217,19 +1219,20 @@
 faim_export int aim_ssi_waitingforauth(struct aim_ssi_item *list, const char *gn, const char *sn);
 
 /* Client functions for changing SSI data */
-faim_export int aim_ssi_addbuddy(aim_session_t *sess, aim_conn_t *conn, const char *name, const char *group, const char *alias, const char *comment, const char *smsnum, int needauth);
-faim_export int aim_ssi_addpermit(aim_session_t *sess, aim_conn_t *conn, const char *name);
-faim_export int aim_ssi_adddeny(aim_session_t *sess, aim_conn_t *conn, const char *name);
-faim_export int aim_ssi_delbuddy(aim_session_t *sess, aim_conn_t *conn, const char *name, const char *group);
-faim_export int aim_ssi_delpermit(aim_session_t *sess, aim_conn_t *conn, const char *name);
-faim_export int aim_ssi_deldeny(aim_session_t *sess, aim_conn_t *conn, const char *name);
-faim_export int aim_ssi_movebuddy(aim_session_t *sess, aim_conn_t *conn, const char *oldgn, const char *newgn, const char *sn);
-faim_export int aim_ssi_aliasbuddy(aim_session_t *sess, aim_conn_t *conn, const char *gn, const char *sn, const char *alias);
-faim_export int aim_ssi_rename_group(aim_session_t *sess, aim_conn_t *conn, const char *oldgn, const char *newgn);
-faim_export int aim_ssi_cleanlist(aim_session_t *sess, aim_conn_t *conn);
-faim_export int aim_ssi_deletelist(aim_session_t *sess, aim_conn_t *conn);
-faim_export int aim_ssi_setpermdeny(aim_session_t *sess, aim_conn_t *conn, fu8_t permdeny, fu32_t vismask);
-faim_export int aim_ssi_setpresence(aim_session_t *sess, aim_conn_t *conn, fu32_t presence);
+faim_export int aim_ssi_addbuddy(aim_session_t *sess, const char *name, const char *group, const char *alias, const char *comment, const char *smsnum, int needauth);
+faim_export int aim_ssi_addpermit(aim_session_t *sess, const char *name);
+faim_export int aim_ssi_adddeny(aim_session_t *sess, const char *name);
+faim_export int aim_ssi_delbuddy(aim_session_t *sess, const char *name, const char *group);
+faim_export int aim_ssi_delpermit(aim_session_t *sess, const char *name);
+faim_export int aim_ssi_deldeny(aim_session_t *sess, const char *name);
+faim_export int aim_ssi_movebuddy(aim_session_t *sess, const char *oldgn, const char *newgn, const char *sn);
+faim_export int aim_ssi_aliasbuddy(aim_session_t *sess, const char *gn, const char *sn, const char *alias);
+faim_export int aim_ssi_rename_group(aim_session_t *sess, const char *oldgn, const char *newgn);
+faim_export int aim_ssi_cleanlist(aim_session_t *sess);
+faim_export int aim_ssi_deletelist(aim_session_t *sess);
+faim_export int aim_ssi_setpermdeny(aim_session_t *sess, fu8_t permdeny, fu32_t vismask);
+faim_export int aim_ssi_setpresence(aim_session_t *sess, fu32_t presence);
+faim_export int aim_ssi_seticon(aim_session_t *sess, fu8_t *iconsum, fu16_t iconsumlen);
 
 
 
--- a/src/protocols/oscar/icon.c	Tue Mar 25 02:30:08 2003 +0000
+++ b/src/protocols/oscar/icon.c	Tue Mar 25 05:01:00 2003 +0000
@@ -10,13 +10,74 @@
 #include <aim.h>
 
 /**
+ * Subtype 0x0002 - Upload your icon.
+ *
+ * @param sess The oscar session.
+ * @param conn The icon connection for this session.
+ * @param num The reference number of the icon you are uploading.
+ * @param icon The raw data of the icon image file.
+ * @param iconlen Length of the raw data of the icon image file.
+ * @return Return 0 if no errors, otherwise return the error number.
+ */
+faim_export int aim_icon_upload(aim_session_t *sess, int num, const fu8_t *icon, fu16_t iconlen)
+{
+	aim_conn_t *conn;
+	aim_frame_t *fr;
+	aim_snacid_t snacid;
+
+	if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0010)) || !num || !icon || !iconlen)
+		return -EINVAL;
+
+	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + 2 + 2+iconlen)))
+		return -ENOMEM;
+	snacid = aim_cachesnac(sess, 0x0010, 0x0002, 0x0000, NULL, 0);
+	aim_putsnac(&fr->data, 0x0010, 0x0002, 0x0000, snacid);
+
+	/* The reference number for the icon */
+	aimbs_put16(&fr->data, num);
+
+	/* The icon */
+	aimbs_put16(&fr->data, iconlen);
+	aimbs_putraw(&fr->data, icon, iconlen);
+
+	aim_tx_enqueue(sess, fr);
+
+	return 0;
+}
+
+/**
+ * Subtype 0x0003 - Acknowledgement for uploading a buddy icon.
+ *
+ * You get this honky after you upload a buddy icon.
+ */
+static int uploadack(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
+{
+	int ret = 0;
+	aim_rxcallback_t userfunc;
+	fu16_t something, somethingelse;
+	fu8_t onemorething;
+
+	something = aimbs_get16(bs);
+	somethingelse = aimbs_get16(bs);
+	onemorething = aimbs_get8(bs);
+
+	if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))
+		ret = userfunc(sess, rx);
+
+	return ret;
+}
+
+/**
  * Subtype 0x0004 - Request someone's icon.
  *
  * @param sess The oscar session.
  * @param conn The icon connection for this session.
+ * @param sn The screen name of the person who's icon you are requesting.
+ * @param iconcsum The MD5 checksum of the icon you are requesting.
+ * @param iconcsumlen Length of the MD5 checksum given above.  Should be 10 bytes.
  * @return Return 0 if no errors, otherwise return the error number.
  */
-faim_export int aim_icon_requesticon(aim_session_t *sess, const char *sn, const fu8_t *iconcsum, fu16_t iconcsumlen)
+faim_export int aim_icon_request(aim_session_t *sess, const char *sn, const fu8_t *iconcsum, fu16_t iconcsumlen)
 {
 	aim_conn_t *conn;
 	aim_frame_t *fr;
@@ -48,7 +109,6 @@
 	return 0;
 }
 
-
 /**
  * Subtype 0x0005 - Receive a buddy icon.
  *
@@ -56,10 +116,9 @@
  */
 static int parseicon(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
 {
+	int ret = 0;
 	aim_rxcallback_t userfunc;
-	int i;
 	char *sn;
-	int ret = 0;
 	fu16_t flags, iconlen;
 	fu8_t number, iconcsumlen, *iconcsum, *icon;
 
@@ -84,7 +143,9 @@
 static int snachandler(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
 {
 
-	if (snac->subtype == 0x0005)
+	if (snac->subtype == 0x0003)
+		return uploadack(sess, mod, rx, snac, bs);
+	else if (snac->subtype == 0x0005)
 		return parseicon(sess, mod, rx, snac, bs);
 
 	return 0;
--- a/src/protocols/oscar/oscar.c	Tue Mar 25 02:30:08 2003 +0000
+++ b/src/protocols/oscar/oscar.c	Tue Mar 25 05:01:00 2003 +0000
@@ -48,8 +48,8 @@
 #include "multi.h"
 #include "prpl.h"
 #include "core.h"
+#include "proxy.h"
 #include "aim.h"
-#include "proxy.h"
 
 #ifdef _WIN32
 #include "win32dep.h"
@@ -2336,9 +2336,9 @@
 		struct group *group = gaim_find_buddys_group(buddy);
 		if (buddy && group) {
 			debug_printf("ssi: adding buddy %s to group %s\n", buddy->name, group->name);
-			aim_ssi_sendauthrequest(od->sess, od->conn, data->name, msg ? msg : _("Please authorize me so I can add you to my buddy list."));
+			aim_ssi_sendauthrequest(od->sess, data->name, msg ? msg : _("Please authorize me so I can add you to my buddy list."));
 			if (!aim_ssi_itemlist_finditem(od->sess->ssi.local, group->name, buddy->name, AIM_SSI_TYPE_BUDDY))
-				aim_ssi_addbuddy(od->sess, od->conn, buddy->name, group->name, gaim_get_buddy_alias_only(buddy), NULL, NULL, 1);
+				aim_ssi_addbuddy(od->sess, buddy->name, group->name, gaim_get_buddy_alias_only(buddy), NULL, NULL, 1);
 		}
 	}
 }
@@ -2393,7 +2393,7 @@
 		aim_im_sendch4(od->sess, data->name, AIM_ICQMSG_AUTHGRANTED, &message);
 		show_got_added(gc, NULL, data->name, (buddy ? gaim_get_buddy_alias_only(buddy) : NULL), NULL);
 #else
-		aim_ssi_sendauthreply(od->sess, od->conn, data->name, 0x01, NULL);
+		aim_ssi_sendauthreply(od->sess, data->name, 0x01, NULL);
 #endif
 	}
 
@@ -2409,7 +2409,7 @@
 #ifdef NOSSI
 		aim_im_sendch4(od->sess, data->name, AIM_ICQMSG_AUTHDENIED, msg ? msg : _("No reason given."));
 #else
-		aim_ssi_sendauthreply(od->sess, od->conn, data->name, 0x00, msg ? msg : _("No reason given."));
+		aim_ssi_sendauthreply(od->sess, data->name, 0x00, msg ? msg : _("No reason given."));
 #endif
 	}
 }
@@ -3432,7 +3432,7 @@
 
 	bi = g_hash_table_lookup(od->buddyinfo, (char *)od->requesticon->data);
 	if (bi && (bi->iconcsumlen > 0)) {
-		aim_icon_requesticon(od->sess, od->requesticon->data, bi->iconcsum, bi->iconcsumlen);
+		aim_icon_request(od->sess, od->requesticon->data, bi->iconcsum, bi->iconcsumlen);
 		return FALSE;
 	} else {
 		char *sn = od->requesticon->data;
@@ -3576,8 +3576,8 @@
 
 #ifndef NOSSI
 	debug_printf("ssi: requesting ssi list\n");
-	aim_ssi_reqrights(sess, fr->conn);
-	aim_ssi_reqdata(sess, fr->conn, sess->ssi.timestamp, sess->ssi.numitems);
+	aim_ssi_reqrights(sess);
+	aim_ssi_reqdata(sess, sess->ssi.timestamp, sess->ssi.numitems);
 #endif
 
 	aim_bos_reqlocaterights(sess, fr->conn);
@@ -4366,12 +4366,11 @@
 
 	if (strcmp(state, _("Invisible"))) {
 		if (aim_ssi_getpermdeny(od->sess->ssi.local) != gc->account->permdeny)
-			aim_ssi_setpermdeny(od->sess, od->conn, gc->account->permdeny,
-					0xffffffff);
+			aim_ssi_setpermdeny(od->sess, gc->account->permdeny, 0xffffffff);
 		gc->account->permdeny = 4;
 	} else {
 		if (aim_ssi_getpermdeny(od->sess->ssi.local) != 0x03)
-			aim_ssi_setpermdeny(od->sess, od->conn, 0x03, 0xffffffff);
+			aim_ssi_setpermdeny(od->sess, 0x03, 0xffffffff);
 		gc->account->permdeny = 3;
 	}
 
@@ -4441,7 +4440,7 @@
 		struct group *group = gaim_find_buddys_group(buddy);
 		if (buddy && group) {
 			debug_printf("ssi: adding buddy %s to group %s\n", name, group->name);
-			aim_ssi_addbuddy(od->sess, od->conn, buddy->name, group->name, gaim_get_buddy_alias_only(buddy), NULL, NULL, 0);
+			aim_ssi_addbuddy(od->sess, buddy->name, group->name, gaim_get_buddy_alias_only(buddy), NULL, NULL, 0);
 		}
 	}
 #endif
@@ -4470,7 +4469,7 @@
 			struct group *group = gaim_find_buddys_group(buddy);
 			if (buddy && group) {
 				debug_printf("ssi: adding buddy %s to group %s\n", (const char *)buddies->data, group->name);
-				aim_ssi_addbuddy(od->sess, od->conn, buddy->name, group->name, gaim_get_buddy_alias_only(buddy), NULL, NULL, 0);
+				aim_ssi_addbuddy(od->sess, buddy->name, group->name, gaim_get_buddy_alias_only(buddy), NULL, NULL, 0);
 			}
 			buddies = buddies->next;
 		}
@@ -4485,7 +4484,7 @@
 #else
 	if (od->sess->ssi.received_data) {
 		debug_printf("ssi: deleting buddy %s from group %s\n", name, group);
-		aim_ssi_delbuddy(od->sess, od->conn, name, group);
+		aim_ssi_delbuddy(od->sess, name, group);
 	}
 #endif
 }
@@ -4500,7 +4499,7 @@
 	if (od->sess->ssi.received_data) {
 		while (buddies) {
 			debug_printf("ssi: deleting buddy %s from group %s\n", (char *)buddies->data, group);
-			aim_ssi_delbuddy(od->sess, od->conn, buddies->data, group);
+			aim_ssi_delbuddy(od->sess, buddies->data, group);
 			buddies = buddies->next;
 		}
 	}
@@ -4512,7 +4511,7 @@
 	struct oscar_data *od = (struct oscar_data *)gc->proto_data;
 	if (od->sess->ssi.received_data && strcmp(old_group, new_group)) {
 		debug_printf("ssi: moving buddy %s from group %s to group %s\n", name, old_group, new_group);
-		aim_ssi_movebuddy(od->sess, od->conn, old_group, new_group, name);
+		aim_ssi_movebuddy(od->sess, old_group, new_group, name);
 	}
 }
 
@@ -4522,7 +4521,7 @@
 		char *gname = aim_ssi_itemlist_findparentname(od->sess->ssi.local, name);
 		if (gname) {
 			debug_printf("ssi: changing the alias for buddy %s to %s\n", name, alias);
-			aim_ssi_aliasbuddy(od->sess, od->conn, gname, name, alias);
+			aim_ssi_aliasbuddy(od->sess, gname, name, alias);
 		}
 	}
 }
@@ -4536,7 +4535,7 @@
 			oscar_add_buddies(g, members);
 			debug_printf("ssi: moved all buddies from group %s to %s\n", old_group, new_group);
 		} else {
-			aim_ssi_rename_group(od->sess, od->conn, old_group, new_group);
+			aim_ssi_rename_group(od->sess, old_group, new_group);
 			debug_printf("ssi: renamed group %s to %s\n", old_group, new_group);
 		}
 	}
@@ -4615,7 +4614,7 @@
 	debug_printf("ssi: syncing local list and server list\n");
 
 	/* Clean the buddy list */
-	aim_ssi_cleanlist(sess, fr->conn);
+	aim_ssi_cleanlist(sess);
 
 	/* Add from server list to local list */
 	for (curitem=sess->ssi.local; curitem; curitem=curitem->next) {
@@ -4732,11 +4731,11 @@
 							/* Store local alias on server */
 							char *alias = aim_ssi_getalias(sess->ssi.local, group->name, buddy->name);
 							if (!alias && buddy->alias && strlen(buddy->alias))
-								aim_ssi_aliasbuddy(sess, od->conn, group->name, buddy->name, buddy->alias);
+								aim_ssi_aliasbuddy(sess, group->name, buddy->name, buddy->alias);
 							free(alias);
 						} else {
 							debug_printf("ssi: adding buddy %s from local list to server list\n", buddy->name);
-							aim_ssi_addbuddy(sess, od->conn, buddy->name, group->name, gaim_get_buddy_alias_only(buddy), NULL, NULL, 0);
+							aim_ssi_addbuddy(sess, buddy->name, group->name, gaim_get_buddy_alias_only(buddy), NULL, NULL, 0);
 						}
 					}
 				}
@@ -4746,7 +4745,7 @@
 			for (cur=gc->account->permit; cur; cur=cur->next)
 				if (!aim_ssi_itemlist_finditem(sess->ssi.local, NULL, cur->data, AIM_SSI_TYPE_PERMIT)) {
 					debug_printf("ssi: adding permit %s from local list to server list\n", (char *)cur->data);
-					aim_ssi_addpermit(sess, od->conn, cur->data);
+					aim_ssi_addpermit(sess, cur->data);
 				}
 		}
 
@@ -4755,13 +4754,13 @@
 			for (cur=gc->account->deny; cur; cur=cur->next)
 				if (!aim_ssi_itemlist_finditem(sess->ssi.local, NULL, cur->data, AIM_SSI_TYPE_DENY)) {
 					debug_printf("ssi: adding deny %s from local list to server list\n", (char *)cur->data);
-					aim_ssi_adddeny(sess, od->conn, cur->data);
+					aim_ssi_adddeny(sess, cur->data);
 				}
 		}
 		/* Presence settings (idle time visibility) */
 		if ((tmp = aim_ssi_getpresence(sess->ssi.local)) != 0xFFFFFFFF)
 			if (report_idle && !(tmp & 0x400))
-				aim_ssi_setpresence(sess, fr->conn, tmp | 0x400);
+				aim_ssi_setpresence(sess, tmp | 0x400);
 	} /* end adding buddies from local list to server list */
 
 	{ /* Check for maximum number of buddies */
@@ -5432,7 +5431,7 @@
 	signoff_blocked(gc);
 #else
 	if (od->sess->ssi.received_data)
-		aim_ssi_setpermdeny(od->sess, od->conn, gc->account->permdeny, 0xffffffff);
+		aim_ssi_setpermdeny(od->sess, gc->account->permdeny, 0xffffffff);
 #endif
 }
 
@@ -5444,7 +5443,7 @@
 	struct oscar_data *od = (struct oscar_data *)gc->proto_data;
 	debug_printf("ssi: About to add a permit\n");
 	if (od->sess->ssi.received_data)
-		aim_ssi_addpermit(od->sess, od->conn, who);
+		aim_ssi_addpermit(od->sess, who);
 #endif
 }
 
@@ -5456,7 +5455,7 @@
 	struct oscar_data *od = (struct oscar_data *)gc->proto_data;
 	debug_printf("ssi: About to add a deny\n");
 	if (od->sess->ssi.received_data)
-		aim_ssi_adddeny(od->sess, od->conn, who);
+		aim_ssi_adddeny(od->sess, who);
 #endif
 }
 
@@ -5468,7 +5467,7 @@
 	struct oscar_data *od = (struct oscar_data *)gc->proto_data;
 	debug_printf("ssi: About to delete a permit\n");
 	if (od->sess->ssi.received_data)
-		aim_ssi_delpermit(od->sess, od->conn, who);
+		aim_ssi_delpermit(od->sess, who);
 #endif
 }
 
@@ -5480,7 +5479,7 @@
 	struct oscar_data *od = (struct oscar_data *)gc->proto_data;
 	debug_printf("ssi: About to delete a deny\n");
 	if (od->sess->ssi.received_data)
-		aim_ssi_deldeny(od->sess, od->conn, who);
+		aim_ssi_deldeny(od->sess, who);
 #endif
 }
 
--- a/src/protocols/oscar/ssi.c	Tue Mar 25 02:30:08 2003 +0000
+++ b/src/protocols/oscar/ssi.c	Tue Mar 25 05:01:00 2003 +0000
@@ -466,15 +466,14 @@
  * call addmoddel.
  *
  * @param sess The oscar session.
- * @param conn The bos connection for this session.
  * @return Return 0 if no errors, otherwise return the error number.
  */
-static int aim_ssi_sync(aim_session_t *sess, aim_conn_t *conn)
+static int aim_ssi_sync(aim_session_t *sess)
 {
 	struct aim_ssi_item *cur1, *cur2;
 	struct aim_ssi_tmp *cur, *new;
 
-	if (!sess || !conn)
+	if (!sess)
 		return -EINVAL;
 
 	/* If we're waiting for an ack, we shouldn't do anything else */
@@ -550,7 +549,7 @@
 
 	/* We're out of stuff to do, so tell the AIM servers we're done and exit */
 	if (!sess->ssi.pending) {
-		aim_ssi_modend(sess, conn);
+		aim_ssi_modend(sess);
 		return 0;
 	}
 
@@ -559,7 +558,7 @@
 	sess->ssi.waiting_for_ack = 1;
 
 	/* Now go mail off our data and wait 4 to 6 weeks */
-	aim_ssi_addmoddel(sess, conn);
+	aim_ssi_addmoddel(sess);
 
 	return 0;
 }
@@ -615,13 +614,15 @@
  * Delete all SSI data.
  *
  * @param sess The oscar session.
- * @param conn The bos connection for this session.
  * @return Return 0 if no errors, otherwise return the error number.
  */
-faim_export int aim_ssi_deletelist(aim_session_t *sess, aim_conn_t *conn)
+faim_export int aim_ssi_deletelist(aim_session_t *sess)
 {
 	struct aim_ssi_item *cur, *del;
 
+	if (!sess)
+		return -EINVAL;
+
 	/* Free the local list */
 	cur = sess->ssi.local;
 	while (cur) {
@@ -634,7 +635,7 @@
 	sess->ssi.local = NULL;
 
 	/* Sync our local list with the server list */
-	aim_ssi_sync(sess, conn);
+	aim_ssi_sync(sess);
 
 	return 0;
 }
@@ -646,13 +647,15 @@
  * 3) Deletes any empty groups
  *
  * @param sess The oscar session.
- * @param conn The bos connection for this session.
  * @return Return 0 if no errors, otherwise return the error number.
  */
-faim_export int aim_ssi_cleanlist(aim_session_t *sess, aim_conn_t *conn)
+faim_export int aim_ssi_cleanlist(aim_session_t *sess)
 {
 	struct aim_ssi_item *cur, *next;
 
+	if (!sess)
+		return -EINVAL;
+
 	/* Delete any buddies, permits, or denies with empty names. */
 	/* If there are any buddies directly in the master group, add them to a real group. */
 	/* DESTROY any buddies that are directly in the master group. */
@@ -663,14 +666,14 @@
 		next = cur->next;
 		if (!cur->name) {
 			if (cur->type == AIM_SSI_TYPE_BUDDY)
-				aim_ssi_delbuddy(sess, conn, NULL, NULL);
+				aim_ssi_delbuddy(sess, NULL, NULL);
 			else if (cur->type == AIM_SSI_TYPE_PERMIT)
-				aim_ssi_delpermit(sess, conn, NULL);
+				aim_ssi_delpermit(sess, NULL);
 			else if (cur->type == AIM_SSI_TYPE_DENY)
-				aim_ssi_deldeny(sess, conn, NULL);
+				aim_ssi_deldeny(sess, NULL);
 		} else if ((cur->type == AIM_SSI_TYPE_BUDDY) && ((cur->gid == 0x0000) || (!aim_ssi_itemlist_find(sess->ssi.local, cur->gid, 0x0000)))) {
-			aim_ssi_addbuddy(sess, conn, cur->name, "orphans", NULL, NULL, NULL, 0);
-			aim_ssi_delbuddy(sess, conn, cur->name, NULL);
+			aim_ssi_addbuddy(sess, cur->name, "orphans", NULL, NULL, NULL, 0);
+			aim_ssi_delbuddy(sess, cur->name, NULL);
 		}
 		cur = next;
 	}
@@ -698,7 +701,6 @@
  * Add a buddy to the list.
  *
  * @param sess The oscar session.
- * @param conn The bos connection for this session.
  * @param name The name of the item.
  * @param group The group of the item.
  * @param alias The alias/nickname of the item, or NULL.
@@ -706,12 +708,12 @@
  * @param smsnum The locally assigned SMS number, or NULL.
  * @return Return 0 if no errors, otherwise return the error number.
  */
-faim_export int aim_ssi_addbuddy(aim_session_t *sess, aim_conn_t *conn, const char *name, const char *group, const char *alias, const char *comment, const char *smsnum, int needauth)
+faim_export int aim_ssi_addbuddy(aim_session_t *sess, const char *name, const char *group, const char *alias, const char *comment, const char *smsnum, int needauth)
 {
 	struct aim_ssi_item *parent;
 	aim_tlvlist_t *data = NULL;
 
-	if (!sess || !conn || !name || !group)
+	if (!sess || !name || !group)
 		return -EINVAL;
 
 	/* Find the parent */
@@ -746,7 +748,7 @@
 	aim_ssi_itemlist_rebuildgroup(sess->ssi.local, group);
 
 	/* Sync our local list with the server list */
-	aim_ssi_sync(sess, conn);
+	aim_ssi_sync(sess);
 
 	return 0;
 }
@@ -755,20 +757,20 @@
  * Add a permit buddy to the list.
  *
  * @param sess The oscar session.
- * @param conn The bos connection for this session.
  * @param name The name of the item..
  * @return Return 0 if no errors, otherwise return the error number.
  */
-faim_export int aim_ssi_addpermit(aim_session_t *sess, aim_conn_t *conn, const char *name)
+faim_export int aim_ssi_addpermit(aim_session_t *sess, const char *name)
 {
-	if (!sess || !conn || !name)
+
+	if (!sess || !name)
 		return -EINVAL;
 
 	/* Add that bad boy */
 	aim_ssi_itemlist_add(&sess->ssi.local, name, 0x0000, 0xFFFF, AIM_SSI_TYPE_PERMIT, NULL);
 
 	/* Sync our local list with the server list */
-	aim_ssi_sync(sess, conn);
+	aim_ssi_sync(sess);
 
 	return 0;
 }
@@ -777,20 +779,20 @@
  * Add a deny buddy to the list.
  *
  * @param sess The oscar session.
- * @param conn The bos connection for this session.
  * @param name The name of the item..
  * @return Return 0 if no errors, otherwise return the error number.
  */
-faim_export int aim_ssi_adddeny(aim_session_t *sess, aim_conn_t *conn, const char *name)
+faim_export int aim_ssi_adddeny(aim_session_t *sess, const char *name)
 {
-	if (!sess || !conn || !name)
+
+	if (!sess || !name)
 		return -EINVAL;
 
 	/* Add that bad boy */
 	aim_ssi_itemlist_add(&sess->ssi.local, name, 0x0000, 0xFFFF, AIM_SSI_TYPE_DENY, NULL);
 
 	/* Sync our local list with the server list */
-	aim_ssi_sync(sess, conn);
+	aim_ssi_sync(sess);
 
 	return 0;
 }
@@ -799,16 +801,15 @@
  * Deletes a buddy from the list.
  *
  * @param sess The oscar session.
- * @param conn The bos connection for this session.
  * @param name The name of the item, or NULL.
  * @param group The group of the item, or NULL.
  * @return Return 0 if no errors, otherwise return the error number.
  */
-faim_export int aim_ssi_delbuddy(aim_session_t *sess, aim_conn_t *conn, const char *name, const char *group)
+faim_export int aim_ssi_delbuddy(aim_session_t *sess, const char *name, const char *group)
 {
 	struct aim_ssi_item *del;
 
-	if (!sess || !conn)
+	if (!sess)
 		return -EINVAL;
 
 	/* Find the buddy */
@@ -835,7 +836,7 @@
 	}
 
 	/* Sync our local list with the server list */
-	aim_ssi_sync(sess, conn);
+	aim_ssi_sync(sess);
 
 	return 0;
 }
@@ -844,15 +845,14 @@
  * Deletes a permit buddy from the list.
  *
  * @param sess The oscar session.
- * @param conn The bos connection for this session.
  * @param name The name of the item, or NULL.
  * @return Return 0 if no errors, otherwise return the error number.
  */
-faim_export int aim_ssi_delpermit(aim_session_t *sess, aim_conn_t *conn, const char *name)
+faim_export int aim_ssi_delpermit(aim_session_t *sess, const char *name)
 {
 	struct aim_ssi_item *del;
 
-	if (!sess || !conn)
+	if (!sess)
 		return -EINVAL;
 
 	/* Find the item */
@@ -863,7 +863,7 @@
 	aim_ssi_itemlist_del(&sess->ssi.local, del);
 
 	/* Sync our local list with the server list */
-	aim_ssi_sync(sess, conn);
+	aim_ssi_sync(sess);
 
 	return 0;
 }
@@ -872,15 +872,14 @@
  * Deletes a deny buddy from the list.
  *
  * @param sess The oscar session.
- * @param conn The bos connection for this session.
  * @param name The name of the item, or NULL.
  * @return Return 0 if no errors, otherwise return the error number.
  */
-faim_export int aim_ssi_deldeny(aim_session_t *sess, aim_conn_t *conn, const char *name)
+faim_export int aim_ssi_deldeny(aim_session_t *sess, const char *name)
 {
 	struct aim_ssi_item *del;
 
-	if (!sess || !conn)
+	if (!sess)
 		return -EINVAL;
 
 	/* Find the item */
@@ -891,7 +890,7 @@
 	aim_ssi_itemlist_del(&sess->ssi.local, del);
 
 	/* Sync our local list with the server list */
-	aim_ssi_sync(sess, conn);
+	aim_ssi_sync(sess);
 
 	return 0;
 }
@@ -901,16 +900,15 @@
  * buddy and re-adds it.
  *
  * @param sess The oscar session.
- * @param conn The bos connection for this session.
  * @param oldgn The group that the buddy is currently in.
  * @param newgn The group that the buddy should be moved in to.
  * @param sn The name of the buddy to be moved.
  * @return Return 0 if no errors, otherwise return the error number.
  */
-faim_export int aim_ssi_movebuddy(aim_session_t *sess, aim_conn_t *conn, const char *oldgn, const char *newgn, const char *sn)
+faim_export int aim_ssi_movebuddy(aim_session_t *sess, const char *oldgn, const char *newgn, const char *sn)
 {
-	aim_ssi_addbuddy(sess, conn, sn, newgn, aim_ssi_getalias(sess->ssi.local, oldgn, sn), NULL, NULL, aim_ssi_waitingforauth(sess->ssi.local, oldgn, sn));
-	aim_ssi_delbuddy(sess, conn, sn, oldgn);
+	aim_ssi_addbuddy(sess, sn, newgn, aim_ssi_getalias(sess->ssi.local, oldgn, sn), NULL, NULL, aim_ssi_waitingforauth(sess->ssi.local, oldgn, sn));
+	aim_ssi_delbuddy(sess, sn, oldgn);
 	return 0;
 }
 
@@ -918,18 +916,17 @@
  * Change the alias stored on the server for a given buddy.
  *
  * @param sess The oscar session.
- * @param conn The bos connection for this session.
  * @param gn The group that the buddy is currently in.
  * @param sn The screen name of the buddy.
  * @param alias The new alias for the buddy.
  * @return Return 0 if no errors, otherwise return the error number.
  */
-faim_export int aim_ssi_aliasbuddy(aim_session_t *sess, aim_conn_t *conn, const char *gn, const char *sn, const char *alias)
+faim_export int aim_ssi_aliasbuddy(aim_session_t *sess, const char *gn, const char *sn, const char *alias)
 {
 	struct aim_ssi_item *tmp;
 	aim_tlvlist_t *data = NULL;
 
-	if (!sess || !conn || !gn || !sn)
+	if (!sess || !gn || !sn)
 		return -EINVAL;
 
 	if (!(tmp = aim_ssi_itemlist_finditem(sess->ssi.local, gn, sn, AIM_SSI_TYPE_BUDDY)))
@@ -946,7 +943,7 @@
 	tmp->data = data;
 
 	/* Sync our local list with the server list */
-	aim_ssi_sync(sess, conn);
+	aim_ssi_sync(sess);
 
 	return 0;
 }
@@ -955,16 +952,15 @@
  * Rename a group.
  *
  * @param sess The oscar session.
- * @param conn The bos connection for this session.
  * @param oldgn The old group name.
  * @param newgn The new group name.
  * @return Return 0 if no errors, otherwise return the error number.
  */
-faim_export int aim_ssi_rename_group(aim_session_t *sess, aim_conn_t *conn, const char *oldgn, const char *newgn)
+faim_export int aim_ssi_rename_group(aim_session_t *sess, const char *oldgn, const char *newgn)
 {
 	struct aim_ssi_item *group;
 
-	if (!sess || !conn || !oldgn || !newgn)
+	if (!sess || !oldgn || !newgn)
 		return -EINVAL;
 
 	if (!(group = aim_ssi_itemlist_finditem(sess->ssi.local, oldgn, NULL, AIM_SSI_TYPE_GROUP)))
@@ -975,7 +971,7 @@
 	strcpy(group->name, newgn);
 
 	/* Sync our local list with the server list */
-	aim_ssi_sync(sess, conn);
+	aim_ssi_sync(sess);
 
 	return 0;
 }
@@ -984,7 +980,6 @@
  * Stores your permit/deny setting on the server, and starts using it.
  *
  * @param sess The oscar session.
- * @param conn The bos connection for this session.
  * @param permdeny Your permit/deny setting.  Can be one of the following:
  *        1 - Allow all users
  *        2 - Block all users
@@ -995,12 +990,12 @@
  *        visible.  See the AIM_FLAG_BLEH #defines in aim.h
  * @return Return 0 if no errors, otherwise return the error number.
  */
-faim_export int aim_ssi_setpermdeny(aim_session_t *sess, aim_conn_t *conn, fu8_t permdeny, fu32_t vismask)
+faim_export int aim_ssi_setpermdeny(aim_session_t *sess, fu8_t permdeny, fu32_t vismask)
 {
 	struct aim_ssi_item *tmp;
 	aim_tlvlist_t *data = NULL;
 
-	if (!sess || !conn)
+	if (!sess)
 		return -EINVAL;
 
 	/* Need to add the x00ca TLV to the TLV chain */
@@ -1018,7 +1013,51 @@
 	}
 
 	/* Sync our local list with the server list */
-	aim_ssi_sync(sess, conn);
+	aim_ssi_sync(sess);
+
+	return 0;
+}
+
+/**
+ * Set buddy icon information
+ *
+ * @param sess The oscar session.
+ * @param iconcsum The MD5 checksum of the icon you are using.
+ * @param iconcsumlen Length of the MD5 checksum given above.  Should be 10 bytes.
+ * @return Return 0 if no errors, otherwise return the error number.
+ */
+faim_export int aim_ssi_seticon(aim_session_t *sess, fu8_t *iconsum, fu16_t iconsumlen)
+{
+	struct aim_ssi_item *tmp;
+	aim_tlvlist_t *data = NULL;
+	fu8_t *csumdata;
+
+	if (!sess || !iconsum || !iconsumlen)
+		return -EINVAL;
+
+	/* Create the data for the TLV containing the icon checksum */
+	if (!(csumdata = (fu8_t *)malloc((iconsumlen+2)*sizeof(fu8_t))))
+		return -ENOMEM;
+	csumdata[0] = 0x00;
+	csumdata[1] = 0x10;
+	memcpy(&csumdata[2], iconsum, iconsumlen);
+
+	/* Need to add the x0131 TLV to the TLV chain */
+	aim_addtlvtochain_noval(&data, 0x0131);
+
+	/* Need to add the x00d5 TLV to the TLV chain */
+	aim_addtlvtochain_raw(&data, 0x00d5, 0x0012, csumdata);
+
+	if ((tmp = aim_ssi_itemlist_finditem(sess->ssi.local, NULL, "0", AIM_SSI_TYPE_ICONINFO))) {
+		aim_freetlvchain(&tmp->data);
+		tmp->data = data;
+	} else {
+		tmp = aim_ssi_itemlist_add(&sess->ssi.local, "0", 0x0000, 0xFFFF, AIM_SSI_TYPE_ICONINFO, data);
+		aim_freetlvchain(&data);
+	}
+
+	/* Sync our local list with the server list */
+	aim_ssi_sync(sess);
 
 	return 0;
 }
@@ -1027,16 +1066,15 @@
  * Stores your setting for whether you should show up as idle or not.
  *
  * @param sess The oscar session.
- * @param conn The bos connection for this session.
  * @param presence I think it's a bitmask, but I only know what one of the bits is:
  *        0x00000400 - Allow others to see your idle time
  * @return Return 0 if no errors, otherwise return the error number.
  */
-faim_export int aim_ssi_setpresence(aim_session_t *sess, aim_conn_t *conn, fu32_t presence) {
+faim_export int aim_ssi_setpresence(aim_session_t *sess, fu32_t presence) {
 	struct aim_ssi_item *tmp;
 	aim_tlvlist_t *data = NULL;
 
-	if (!sess || !conn)
+	if (!sess)
 		return -EINVAL;
 
 	/* Need to add the x00c9 TLV to the TLV chain */
@@ -1051,7 +1089,7 @@
 	}
 
 	/* Sync our local list with the server list */
-	aim_ssi_sync(sess, conn);
+	aim_ssi_sync(sess);
 
 	return 0;
 }
@@ -1059,8 +1097,13 @@
 /*
  * Subtype 0x0002 - Request SSI Rights.
  */
-faim_export int aim_ssi_reqrights(aim_session_t *sess, aim_conn_t *conn)
+faim_export int aim_ssi_reqrights(aim_session_t *sess)
 {
+	aim_conn_t *conn;
+
+	if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_SSI)))
+		return -EINVAL;
+
 	return aim_genericreq_n(sess, conn, AIM_CB_FAM_SSI, AIM_CB_SSI_REQRIGHTS);
 }
 
@@ -1123,12 +1166,13 @@
  * Note that the client should never increment the revision, only the server.
  * 
  */
-faim_export int aim_ssi_reqdata(aim_session_t *sess, aim_conn_t *conn, time_t timestamp, fu16_t numitems)
+faim_export int aim_ssi_reqdata(aim_session_t *sess, time_t timestamp, fu16_t numitems)
 {
+	aim_conn_t *conn;
 	aim_frame_t *fr;
 	aim_snacid_t snacid;
 
-	if (!sess || !conn)
+	if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_SSI)))
 		return -EINVAL;
 
 	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+4+2)))
@@ -1223,14 +1267,15 @@
  * difference is the subtype that is set for the SNAC.
  * 
  */
-faim_export int aim_ssi_addmoddel(aim_session_t *sess, aim_conn_t *conn)
+faim_export int aim_ssi_addmoddel(aim_session_t *sess)
 {
+	aim_conn_t *conn;
 	aim_frame_t *fr;
 	aim_snacid_t snacid;
 	int snaclen;
 	struct aim_ssi_tmp *cur;
 
-	if (!sess || !conn || !sess->ssi.pending || !sess->ssi.pending->item)
+	if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_SSI)) || !sess->ssi.pending || !sess->ssi.pending->item)
 		return -EINVAL;
 
 	/* Calculate total SNAC size */
@@ -1518,7 +1563,7 @@
 	if (!sess->ssi.pending) {
 		sess->ssi.pending = NULL;
 		sess->ssi.waiting_for_ack = 0;
-		aim_ssi_sync(sess, rx->conn);
+		aim_ssi_sync(sess);
 	}
 
 	return ret;
@@ -1550,8 +1595,13 @@
  * Tells the server you're going to start modifying data.
  * 
  */
-faim_export int aim_ssi_modbegin(aim_session_t *sess, aim_conn_t *conn)
+faim_export int aim_ssi_modbegin(aim_session_t *sess)
 {
+	aim_conn_t *conn;
+
+	if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_SSI)))
+		return -EINVAL;
+
 	return aim_genericreq_n(sess, conn, AIM_CB_FAM_SSI, AIM_CB_SSI_EDITSTART);
 }
 
@@ -1561,8 +1611,13 @@
  * Tells the server you're finished modifying data.
  *
  */
-faim_export int aim_ssi_modend(aim_session_t *sess, aim_conn_t *conn)
+faim_export int aim_ssi_modend(aim_session_t *sess)
 {
+	aim_conn_t *conn;
+
+	if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_SSI)))
+		return -EINVAL;
+
 	return aim_genericreq_n(sess, conn, AIM_CB_FAM_SSI, AIM_CB_SSI_EDITSTOP);
 }
 
@@ -1572,12 +1627,13 @@
  * Authorizes a contact so they can add you to their contact list.
  *
  */
-faim_export int aim_ssi_sendauth(aim_session_t *sess, aim_conn_t *conn, char *sn, char *msg)
+faim_export int aim_ssi_sendauth(aim_session_t *sess, char *sn, char *msg)
 {
+	aim_conn_t *conn;
 	aim_frame_t *fr;
 	aim_snacid_t snacid;
 
-	if (!sess || !conn || !sn)
+	if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_SSI)) || !sn)
 		return -EINVAL;
 
 	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+1+strlen(sn)+2+(msg ? strlen(msg)+1 : 0)+2)))
@@ -1646,12 +1702,13 @@
  * granted, denied, or dropped.
  *
  */
-faim_export int aim_ssi_sendauthrequest(aim_session_t *sess, aim_conn_t *conn, char *sn, char *msg)
+faim_export int aim_ssi_sendauthrequest(aim_session_t *sess, char *sn, char *msg)
 {
+	aim_conn_t *conn;
 	aim_frame_t *fr;
 	aim_snacid_t snacid;
 
-	if (!sess || !conn || !sn)
+	if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_SSI)) || !sn)
 		return -EINVAL;
 
 	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+1+strlen(sn)+2+(msg ? strlen(msg)+1 : 0)+2)))
@@ -1723,12 +1780,13 @@
  * if reply=0x01 then grant
  *
  */
-faim_export int aim_ssi_sendauthreply(aim_session_t *sess, aim_conn_t *conn, char *sn, fu8_t reply, char *msg)
+faim_export int aim_ssi_sendauthreply(aim_session_t *sess, char *sn, fu8_t reply, char *msg)
 {
+	aim_conn_t *conn;
 	aim_frame_t *fr;
 	aim_snacid_t snacid;
 
-	if (!sess || !conn || !sn)
+	if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_SSI)) || !sn)
 		return -EINVAL;
 
 	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + 1+strlen(sn) + 1 + 2+(msg ? strlen(msg)+1 : 0) + 2)))
--- a/src/prpl.c	Tue Mar 25 02:30:08 2003 +0000
+++ b/src/prpl.c	Tue Mar 25 05:01:00 2003 +0000
@@ -521,11 +521,6 @@
 	gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
 	gtk_widget_show(hbox);
 
-	close = picture_button(mn->email_win, _("Close"), cancel_xpm);
-	gtk_window_set_focus(GTK_WINDOW(mn->email_win), close);
-	gtk_box_pack_end(GTK_BOX(hbox), close, 0, 0, 5);
-	g_signal_connect(GTK_OBJECT(close), "clicked", G_CALLBACK(des_email_win), mn);
-
 	if (url) {
 		mn->url = g_strdup(url);
 		urlbut = picture_button(mn->email_win, _("Open Mail"), tb_forward_xpm);
@@ -534,6 +529,11 @@
 		g_signal_connect(GTK_OBJECT(urlbut), "clicked", G_CALLBACK(des_email_win), mn);
 	}
 
+	close = picture_button(mn->email_win, _("Close"), cancel_xpm);
+	gtk_window_set_focus(GTK_WINDOW(mn->email_win), close);
+	gtk_box_pack_end(GTK_BOX(hbox), close, 0, 0, 5);
+	g_signal_connect(GTK_OBJECT(close), "clicked", G_CALLBACK(des_email_win), mn);
+
 	gtk_widget_show(mn->email_win);
 }