changeset 7334:83e8faa7f6d5

[gaim-migrate @ 7922] Add the ability to view users with secure IM enabled on AIM. They have a lock icon overlay. Also some other small changes and minor bandwidth usage reduction. I'm Brian Fellows! committer: Tailor Script <tailor@pidgin.im>
author Mark Doliner <mark@kingant.net>
date Sun, 26 Oct 2003 07:35:16 +0000
parents 6338cb1768ea
children 3c3039aa7259
files src/protocols/oscar/aim.h src/protocols/oscar/aim_internal.h src/protocols/oscar/im.c src/protocols/oscar/locate.c src/protocols/oscar/oscar.c
diffstat 5 files changed, 136 insertions(+), 79 deletions(-) [+]
line wrap: on
line diff
--- a/src/protocols/oscar/aim.h	Sun Oct 26 06:55:27 2003 +0000
+++ b/src/protocols/oscar/aim.h	Sun Oct 26 07:35:16 2003 +0000
@@ -1070,7 +1070,8 @@
 faim_export aim_userinfo_t *aim_locate_finduserinfo(aim_session_t *sess, const char *sn);
 
 /* 0x0002 */ faim_export int aim_locate_reqrights(aim_session_t *sess);
-/* 0x0004 */ faim_export int aim_locate_setprofile(aim_session_t *sess, const char *profile_encoding, const char *profile, const int profile_len, const char *awaymsg_encoding, const char *awaymsg, const int awaymsg_len, fu32_t caps);
+/* 0x0004 */ faim_export int aim_locate_setprofile(aim_session_t *sess, const char *profile_encoding, const char *profile, const int profile_len, const char *awaymsg_encoding, const char *awaymsg, const int awaymsg_len);
+/* 0x0004 */ faim_export int aim_locate_setcaps(aim_session_t *sess, fu32_t caps);
 /* 0x0005 */ faim_export int aim_locate_getinfo(aim_session_t *sess, const char *, fu16_t);
 /* 0x0009 */ faim_export int aim_locate_setdirinfo(aim_session_t *sess, 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, fu16_t privacy);
 /* 0x000b */ faim_export int aim_locate_000b(aim_session_t *sess, const char *sn);
--- a/src/protocols/oscar/aim_internal.h	Sun Oct 26 06:55:27 2003 +0000
+++ b/src/protocols/oscar/aim_internal.h	Sun Oct 26 07:35:16 2003 +0000
@@ -198,7 +198,8 @@
 
 /* 0x0002 - locate.c */
 faim_internal void aim_locate_requestuserinfo(aim_session_t *sess, const char *sn);
-faim_internal fu32_t aim_getcap(aim_session_t *sess, aim_bstream_t *bs, int len);
+faim_internal fu32_t aim_locate_getcaps(aim_session_t *sess, aim_bstream_t *bs, int len);
+faim_internal fu32_t aim_locate_getcaps_short(aim_session_t *sess, aim_bstream_t *bs, int len);
 faim_internal int aim_putcap(aim_bstream_t *bs, fu32_t caps);
 faim_internal void aim_info_free(aim_userinfo_t *);
 faim_internal int aim_info_extract(aim_session_t *sess, aim_bstream_t *bs, aim_userinfo_t *);
--- a/src/protocols/oscar/im.c	Sun Oct 26 06:55:27 2003 +0000
+++ b/src/protocols/oscar/im.c	Sun Oct 26 07:35:16 2003 +0000
@@ -1676,7 +1676,7 @@
 	 * The next 16bytes are a capability block so we can
 	 * identify what type of rendezvous this is.
 	 */
-	args.reqclass = aim_getcap(sess, &bbs, 0x10);
+	args.reqclass = aim_locate_getcaps(sess, &bbs, 0x10);
 
 	/* 
 	 * What follows may be TLVs or nothing, depending on the
--- a/src/protocols/oscar/locate.c	Sun Oct 26 06:55:27 2003 +0000
+++ b/src/protocols/oscar/locate.c	Sun Oct 26 07:35:16 2003 +0000
@@ -323,11 +323,7 @@
 	return NULL;
 }
 
-/*
- * This still takes a length parameter even with a bstream because capabilities
- * are not naturally bounded.
- */
-faim_internal fu32_t aim_getcap(aim_session_t *sess, aim_bstream_t *bs, int len)
+faim_internal fu32_t aim_locate_getcaps(aim_session_t *sess, aim_bstream_t *bs, int len)
 {
 	fu32_t flags = 0;
 	int offset;
@@ -339,16 +335,14 @@
 		cap = aimbs_getraw(bs, 0x10);
 
 		for (i = 0, identified = 0; !(aim_caps[i].flag & AIM_CAPS_LAST); i++) {
-
 			if (memcmp(&aim_caps[i].data, cap, 0x10) == 0) {
 				flags |= aim_caps[i].flag;
 				identified++;
 				break; /* should only match once... */
-
 			}
 		}
 
-		if (!identified) {
+		if (!identified)
 			faimdprintf(sess, 0, "unknown capability: {%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x}\n",
 					cap[0], cap[1], cap[2], cap[3],
 					cap[4], cap[5],
@@ -356,8 +350,35 @@
 					cap[8], cap[9],
 					cap[10], cap[11], cap[12], cap[13],
 					cap[14], cap[15]);
+
+		free(cap);
+	}
+
+	return flags;
+}
+
+faim_internal fu32_t aim_locate_getcaps_short(aim_session_t *sess, aim_bstream_t *bs, int len)
+{
+	fu32_t flags = 0;
+	int offset;
+
+	for (offset = 0; aim_bstream_empty(bs) && (offset < len); offset += 0x02) {
+		fu8_t *cap;
+		int i, identified;
+
+		cap = aimbs_getraw(bs, 0x02);
+
+		for (i = 0, identified = 0; !(aim_caps[i].flag & AIM_CAPS_LAST); i++) {
+			if (memcmp(&aim_caps[i].data[2], cap, 0x02) == 0) {
+				flags |= aim_caps[i].flag;
+				identified++;
+				break; /* should only match once... */
+			}
 		}
 
+		if (!identified)
+			faimdprintf(sess, 0, "unknown short capability: {%02x%02x}\n", cap[0], cap[1]);
+
 		free(cap);
 	}
 
@@ -585,7 +606,7 @@
 			 * OSCAR Capability information.
 			 *
 			 */
-			outinfo->capabilities = aim_getcap(sess, bs, length);
+			outinfo->capabilities |= aim_locate_getcaps(sess, bs, length);
 			outinfo->present |= AIM_USERINFO_PRESENT_CAPABILITIES;
 
 		} else if (type == 0x000e) {
@@ -618,6 +639,8 @@
 			 * OSCAR short capability information.  A shortened 
 			 * form of the normal capabilities.
 			 */
+			outinfo->capabilities |= aim_locate_getcaps_short(sess, bs, length);
+			outinfo->present |= AIM_USERINFO_PRESENT_CAPABILITIES;
 
 		} else if (type == 0x001b) {
 			/*
@@ -896,8 +919,7 @@
  */
 faim_export int aim_locate_setprofile(aim_session_t *sess,
 				  const char *profile_encoding, const char *profile, const int profile_len,
-				  const char *awaymsg_encoding, const char *awaymsg, const int awaymsg_len,
-				  fu32_t caps)
+				  const char *awaymsg_encoding, const char *awaymsg, const int awaymsg_len)
 {
 	aim_conn_t *conn;
 	aim_frame_t *fr;
@@ -948,8 +970,34 @@
 			aim_tlvlist_add_noval(&tl, 0x0004);
 	}
 
-	if (caps != 0x00000000)
-		aim_tlvlist_add_caps(&tl, 0x0005, caps);
+	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + aim_tlvlist_size(&tl))))
+		return -ENOMEM;
+
+	snacid = aim_cachesnac(sess, 0x0002, 0x0004, 0x0000, NULL, 0);
+	aim_putsnac(&fr->data, 0x0002, 0x004, 0x0000, snacid);
+
+	aim_tlvlist_write(&fr->data, &tl);
+	aim_tlvlist_free(&tl);
+
+	aim_tx_enqueue(sess, fr);
+
+	return 0;
+}
+
+/*
+ * Subtype 0x0004 - Set your client's capabilities.
+ */
+faim_export int aim_locate_setcaps(aim_session_t *sess, fu32_t caps)
+{
+	aim_conn_t *conn;
+	aim_frame_t *fr;
+	aim_snacid_t snacid;
+	aim_tlvlist_t *tl = NULL;
+
+	if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_LOC)))
+		return -EINVAL;
+
+	aim_tlvlist_add_caps(&tl, 0x0005, caps);
 
 	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + aim_tlvlist_size(&tl))))
 		return -ENOMEM;
@@ -1032,7 +1080,7 @@
 	if ((tlv = aim_tlv_gettlv(tlvlist, 0x0005, 1))) {
 		aim_bstream_t cbs;
 		aim_bstream_init(&cbs, tlv->value, tlv->length);
-		userinfo->capabilities = aim_getcap(sess, &cbs, tlv->length);
+		userinfo->capabilities = aim_locate_getcaps(sess, &cbs, tlv->length);
 		userinfo->present = AIM_USERINFO_PRESENT_CAPABILITIES;
 	}
 	aim_tlvlist_free(&tlvlist);
--- a/src/protocols/oscar/oscar.c	Sun Oct 26 06:55:27 2003 +0000
+++ b/src/protocols/oscar/oscar.c	Sun Oct 26 07:35:16 2003 +0000
@@ -59,8 +59,8 @@
 
 static GaimPlugin *my_protocol = NULL;
 
-static int caps_aim = AIM_CAPS_CHAT | AIM_CAPS_BUDDYICON | AIM_CAPS_DIRECTIM | AIM_CAPS_SENDFILE | AIM_CAPS_INTEROPERATE;
-static int caps_icq = AIM_CAPS_BUDDYICON | AIM_CAPS_DIRECTIM | AIM_CAPS_SENDFILE | AIM_CAPS_ICQUTF8 | AIM_CAPS_INTEROPERATE;
+static int caps_aim = AIM_CAPS_CHAT | AIM_CAPS_BUDDYICON | AIM_CAPS_DIRECTIM | AIM_CAPS_SENDFILE | AIM_CAPS_INTEROPERATE | AIM_CAPS_ICHAT;
+static int caps_icq = AIM_CAPS_BUDDYICON | AIM_CAPS_DIRECTIM | AIM_CAPS_SENDFILE | AIM_CAPS_ICQUTF8 | AIM_CAPS_INTEROPERATE | AIM_CAPS_ICHAT;
 
 static fu8_t features_aim[] = {0x01, 0x01, 0x01, 0x02};
 static fu8_t features_icq[] = {0x01, 0x06};
@@ -3122,7 +3122,7 @@
 				tmp = _("Hiptop");
 				break;
 			case AIM_CAPS_SECUREIM:
-				tmp = _("Secure IM");
+				tmp = _("Security Enabled");
 				break;
 			default:
 				tmp = NULL;
@@ -3678,7 +3678,7 @@
 	aim_reqpersonalinfo(sess, fr->conn);
 
 #ifndef NOSSI
-	gaim_debug(GAIM_DEBUG_INFO, "oscar", "ssi: requesting ssi list\n");
+	gaim_debug(GAIM_DEBUG_INFO, "oscar", "ssi: requesting rights and list\n");
 	aim_ssi_reqrights(sess);
 	aim_ssi_reqdata(sess);
 #endif
@@ -3686,9 +3686,11 @@
 	aim_locate_reqrights(sess);
 	aim_buddylist_reqrights(sess, fr->conn);
 	aim_im_reqparams(sess);
-	aim_bos_reqrights(sess, fr->conn); /* XXX - Don't call this with ssi? */
+	aim_bos_reqrights(sess, fr->conn); /* XXX - Don't call this with ssi */
 
 #ifdef NOSSI
+	gaim_debug(GAIM_DEBUG_INFO, "oscar", "bos: requesting rights\n");
+	aim_bos_reqrights(sess, fr->conn);
 	aim_bos_setgroupperm(sess, fr->conn, AIM_FLAG_ALLUSERS);
 	aim_bos_setprivacyflags(sess, fr->conn, AIM_PRIVFLAGS_ALLOWIDLE | AIM_PRIVFLAGS_ALLOWMEMBERSINCE);
 #endif
@@ -3789,9 +3791,10 @@
 	od->rights.maxsiglen = od->rights.maxawaymsglen = (guint)maxsiglen;
 
 	if (od->icq)
-		aim_locate_setprofile(sess, NULL, NULL, 0, NULL, NULL, 0, caps_icq);
+		aim_locate_setcaps(od->sess, caps_icq);
 	else
-		oscar_set_info(gc, gc->account->user_info);
+		aim_locate_setcaps(od->sess, caps_aim);
+	oscar_set_info(gc, gc->account->user_info);
 
 	return 1;
 }
@@ -3817,10 +3820,10 @@
 }
 
 static int gaim_bosrights(aim_session_t *sess, aim_frame_t *fr, ...) {
-	fu16_t maxpermits, maxdenies;
-	va_list ap;
 	GaimConnection *gc = sess->aux_data;
 	OscarData *od = (OscarData *)gc->proto_data;
+	va_list ap;
+	fu16_t maxpermits, maxdenies;
 
 	va_start(ap, fr);
 	maxpermits = (fu16_t) va_arg(ap, unsigned int);
@@ -4415,43 +4418,38 @@
 							  "Your profile remains unset; try setting it "
 							  "again when you are fully connected."));
 
-	if (od->icq)
-		aim_locate_setprofile(od->sess, NULL, NULL, 0, NULL, NULL, 0, caps_icq);
-	else {
-		if (!text) {
-			aim_locate_setprofile(od->sess, NULL, NULL, 0, NULL, NULL, 0, caps_aim);
-			return;
-		}
+	if (!text) {
+		aim_locate_setprofile(od->sess, NULL, "", 0, NULL, NULL, 0);
+		return;
+	}
 		
-		text_html = gaim_strdup_withhtml(text);
-		flags = oscar_encoding_check(text_html);
-		if (flags & AIM_IMFLAGS_UNICODE) {
-			msg = g_convert(text_html, strlen(text_html), "UCS-2BE", "UTF-8", NULL, &msglen, NULL);
-			aim_locate_setprofile(od->sess, "unicode-2-0", msg, (msglen > od->rights.maxsiglen ? od->rights.maxsiglen : msglen), NULL, NULL, 0, caps_aim);
-			g_free(msg);
-		} else if (flags & AIM_IMFLAGS_ISO_8859_1) {
-			msg = g_convert(text_html, strlen(text_html), "ISO-8859-1", "UTF-8", NULL, &msglen, NULL);
-			aim_locate_setprofile(od->sess, "iso-8859-1", msg, (msglen > od->rights.maxsiglen ? od->rights.maxsiglen : msglen), NULL, NULL, 0, caps_aim);
-			g_free(msg);
-		} else {
-			msglen = strlen(text_html);
-			aim_locate_setprofile(od->sess, "us-ascii", text_html, (msglen > od->rights.maxsiglen ? od->rights.maxsiglen : msglen), NULL, NULL, 0, caps_aim);
-		}
-
-		if (msglen > od->rights.maxsiglen) {
-			gchar *errstr;
-			errstr = g_strdup_printf(ngettext("The maximum profile length of %d byte "
-									 "has been exceeded.  Gaim has truncated it for you.",
-									 "The maximum profile length of %d bytes "
-									 "has been exceeded.  Gaim has truncated it for you.",
-									 od->rights.maxsiglen), od->rights.maxsiglen);
-			gaim_notify_warning(gc, NULL, _("Profile too long."), errstr);
-			g_free(errstr);
-		}
-
-		g_free(text_html);
-
-	}
+	text_html = gaim_strdup_withhtml(text);
+	flags = oscar_encoding_check(text_html);
+	if (flags & AIM_IMFLAGS_UNICODE) {
+		msg = g_convert(text_html, strlen(text_html), "UCS-2BE", "UTF-8", NULL, &msglen, NULL);
+		aim_locate_setprofile(od->sess, "unicode-2-0", msg, (msglen > od->rights.maxsiglen ? od->rights.maxsiglen : msglen), NULL, NULL, 0);
+		g_free(msg);
+	} else if (flags & AIM_IMFLAGS_ISO_8859_1) {
+		msg = g_convert(text_html, strlen(text_html), "ISO-8859-1", "UTF-8", NULL, &msglen, NULL);
+		aim_locate_setprofile(od->sess, "iso-8859-1", msg, (msglen > od->rights.maxsiglen ? od->rights.maxsiglen : msglen), NULL, NULL, 0);
+		g_free(msg);
+	} else {
+		msglen = strlen(text_html);
+		aim_locate_setprofile(od->sess, "us-ascii", text_html, (msglen > od->rights.maxsiglen ? od->rights.maxsiglen : msglen), NULL, NULL, 0);
+	}
+
+	if (msglen > od->rights.maxsiglen) {
+		gchar *errstr;
+		errstr = g_strdup_printf(ngettext("The maximum profile length of %d byte "
+								 "has been exceeded.  Gaim has truncated it for you.",
+								 "The maximum profile length of %d bytes "
+								 "has been exceeded.  Gaim has truncated it for you.",
+								 od->rights.maxsiglen), od->rights.maxsiglen);
+		gaim_notify_warning(gc, NULL, _("Profile too long."), errstr);
+		g_free(errstr);
+	}
+
+	g_free(text_html);
 
 	return;
 }
@@ -4477,7 +4475,7 @@
 	}
 
 	if (!text) {
-		aim_locate_setprofile(od->sess, NULL, NULL, 0, NULL, "", 0, caps_aim);
+		aim_locate_setprofile(od->sess, NULL, NULL, 0, NULL, "", 0);
 		return;
 	}
 
@@ -4486,19 +4484,19 @@
 	if (flags & AIM_IMFLAGS_UNICODE) {
 		msg = g_convert(text_html, strlen(text_html), "UCS-2BE", "UTF-8", NULL, &msglen, NULL);
 		aim_locate_setprofile(od->sess, NULL, NULL, 0, "unicode-2-0", msg, 
-			(msglen > od->rights.maxawaymsglen ? od->rights.maxawaymsglen : msglen), caps_aim);
+			(msglen > od->rights.maxawaymsglen ? od->rights.maxawaymsglen : msglen));
 		g_free(msg);
 		gc->away = g_strndup(text, od->rights.maxawaymsglen/2);
 	} else if (flags & AIM_IMFLAGS_ISO_8859_1) {
 		msg = g_convert(text_html, strlen(text_html), "ISO-8859-1", "UTF-8", NULL, &msglen, NULL);
 		aim_locate_setprofile(od->sess, NULL, NULL, 0, "iso-8859-1", msg, 
-			(msglen > od->rights.maxawaymsglen ? od->rights.maxawaymsglen : msglen), caps_aim);
+			(msglen > od->rights.maxawaymsglen ? od->rights.maxawaymsglen : msglen));
 		g_free(msg);
 		gc->away = g_strndup(text_html, od->rights.maxawaymsglen);
 	} else {
 		msglen = strlen(text_html);
 		aim_locate_setprofile(od->sess, NULL, NULL, 0, "us-ascii", text_html, 
-			(msglen > od->rights.maxawaymsglen ? od->rights.maxawaymsglen : msglen), caps_aim);
+			(msglen > od->rights.maxawaymsglen ? od->rights.maxawaymsglen : msglen));
 		gc->away = g_strndup(text_html, od->rights.maxawaymsglen);
 	}
 
@@ -4628,13 +4626,7 @@
 #else
 	if (od->sess->ssi.received_data) {
 		while (buddies) {
-			GaimBuddy *buddy = gaim_find_buddy(gc->account, (const char *)buddies->data);
-			GaimGroup *group = gaim_find_buddys_group(buddy);
-			if (buddy && group) {
-				gaim_debug(GAIM_DEBUG_INFO, "oscar",
-						   "ssi: adding buddy %s to group %s\n", (const char *)buddies->data, group->name);
-				aim_ssi_addbuddy(od->sess, buddy->name, group->name, gaim_get_buddy_alias_only(buddy), NULL, NULL, 0);
-			}
+			oscar_add_buddy(gc, (const char *)buddies->data, NULL);
 			buddies = buddies->next;
 		}
 	}
@@ -5323,16 +5315,23 @@
 
 static void oscar_list_emblems(GaimBuddy *b, char **se, char **sw, char **nw, char **ne)
 {
+	GaimAccount *account = NULL;
+	GaimConnection *gc = NULL;
+	OscarData *od = NULL;
 	char *emblems[4] = {NULL,NULL,NULL,NULL};
 	int i = 0;
+	aim_userinfo_t *userinfo = NULL;
+
+	if (b != NULL)
+		account = b->account;
+	if (account != NULL)
+		gc = account->gc;
+	if (gc != NULL)
+		od = gc->proto_data;
 
 	if (!GAIM_BUDDY_IS_ONLINE(b)) {
-		GaimAccount *account;
-		GaimConnection *gc;
-		OscarData *od;
 		char *gname;
-		if ((b->name) && (account = b->account) && (gc = account->gc) && 
-			(od = gc->proto_data) && (od->sess->ssi.received_data) && 
+		if ((b->name) && (od) && (od->sess->ssi.received_data) && 
 			(gname = aim_ssi_itemlist_findparentname(od->sess->ssi.local, b->name)) && 
 			(aim_ssi_waitingforauth(od->sess->ssi.local, gname, b->name))) {
 			emblems[i++] = "notauthorized";
@@ -5371,6 +5370,13 @@
 		emblems[i++] = "hiptop";
 /*	if (b->uc & UC_UNCONFIRMED && i < 4)
 		emblems[i++] = "unconfirmed"; */
+
+	if ((i < 4) && (od != NULL)) {
+		userinfo = aim_locate_finduserinfo(od->sess, b->name);
+		if ((userinfo != NULL) && (userinfo->capabilities & AIM_CAPS_SECUREIM))
+			emblems[i++] = "secure";
+	}
+
 	*se = emblems[0];
 	*sw = emblems[1];
 	*nw = emblems[2];
@@ -5501,6 +5507,7 @@
 	fu8_t flags = 0, length = 0;
 	char *md5 = NULL;
 
+
 	va_start(ap, fr);
 	type = va_arg(ap, int);
 
@@ -6343,7 +6350,7 @@
 static void oscar_setavailmsg(GaimConnection *gc, char *text) {
 	OscarData *od = (OscarData *)gc->proto_data;
 
-	aim_locate_setprofile(od->sess, NULL, NULL, 0, NULL, "", 0, 0);
+	aim_locate_setprofile(od->sess, NULL, NULL, 0, NULL, "", 0);
 	aim_srv_setavailmsg(od->sess, text);
 }