changeset 3912:e73c48cf1645

[gaim-migrate @ 4071] Little touchups in the "admin" family. Not much has changed, but I moved some functions around because I'm weird. (This is the stuff in "protocol actions" for oscar accounts.) Some of the dialogs should look a little more, I dunno, uniform or something. Change password, format screenname, and change current registered screen name should give you some slightly userfriendly error messages now. Also "confirm account" will pop up that little message that says you should be expecting an email... I think that was one of those brain mistakes, where something was backwards, or something. Uh, so let me know if you see any problems with any of that. Why did I work on this instead of ssi? I don't know. This is funner, I guess. I'll get to ssi eventually... Meow. committer: Tailor Script <tailor@pidgin.im>
author Mark Doliner <mark@kingant.net>
date Thu, 07 Nov 2002 02:25:12 +0000
parents 816cfd8dae78
children 419bf1bc8fa2
files src/protocols/oscar/admin.c src/protocols/oscar/adverts.c src/protocols/oscar/aim.h src/protocols/oscar/auth.c src/protocols/oscar/oscar.c src/protocols/oscar/tlv.c
diffstat 6 files changed, 259 insertions(+), 175 deletions(-) [+]
line wrap: on
line diff
--- a/src/protocols/oscar/admin.c	Thu Nov 07 01:39:24 2002 +0000
+++ b/src/protocols/oscar/admin.c	Thu Nov 07 02:25:12 2002 +0000
@@ -1,60 +1,209 @@
+/*
+ * Family 0x0007 - Account Administration.
+ *
+ * Used for stuff like changing the formating of your screen name, changing your 
+ * email address, requesting an account confirmation email, getting account info, 
+ * 
+ */
 
 #define FAIM_INTERNAL
 #include <aim.h>
 
-/* called for both reply and change-reply */
+/*
+ * Subtype 0x0002 - Request a bit of account info.
+ *
+ * Info should be one of the following:
+ * 0x0001 - Screen name formatting
+ * 0x0011 - Email address
+ * 0x0013 - Unknown
+ *
+ */ 
+faim_export int aim_admin_getinfo(aim_session_t *sess, aim_conn_t *conn, fu16_t info)
+{
+	aim_frame_t *tx;
+	aim_snacid_t snacid;
+
+	if (!(tx = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 14)))
+		return -ENOMEM;
+
+	snacid = aim_cachesnac(sess, 0x0007, 0x0002, 0x0000, NULL, 0);
+	aim_putsnac(&tx->data, 0x0007, 0x0002, 0x0000, snacid);
+
+	aimbs_put16(&tx->data, info);
+	aimbs_put16(&tx->data, 0x0000);
+
+	aim_tx_enqueue(sess, tx);
+
+	return 0;
+}
+
+/*
+ * Subtypes 0x0003 and 0x0005 - Parse account info.
+ *
+ * Called in reply to both an information request (subtype 0x0002) and 
+ * an information change (subtype 0x0004).
+ *
+ */
 static int infochange(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
 {
+	aim_rxcallback_t userfunc;
+	char *url=NULL, *sn=NULL, *email=NULL;
+	fu16_t perms, tlvcount, err=0;
 
-	/*
-	 * struct {
-	 *    unsigned short perms;
-	 *    unsigned short tlvcount;
-	 *    aim_tlv_t tlvs[tlvcount];
-	 *  } admin_info[n];
-	 */
-	while (aim_bstream_empty(bs)) {
-		fu16_t perms, tlvcount;
+	perms = aimbs_get16(bs);
+	tlvcount = aimbs_get16(bs);
+
+	while (tlvcount && aim_bstream_empty(bs)) {
+		fu16_t type, length;
+
+		type = aimbs_get16(bs);
+		length = aimbs_get16(bs);
 
-		perms = aimbs_get16(bs);
-		tlvcount = aimbs_get16(bs);
+		switch (type) {
+			case 0x0001: {
+				sn = aimbs_getstr(bs, length);
+			} break;
 
-		while (tlvcount && aim_bstream_empty(bs)) {
-			aim_rxcallback_t userfunc;
-			fu16_t type, len;
-			fu8_t *val;
-			int str = 0;
+			case 0x0004: {
+				url = aimbs_getstr(bs, length);
+			} break;
 
-			type = aimbs_get16(bs);
-			len = aimbs_get16(bs);
-
-			if ((type == 0x0011) || (type == 0x0004))
-				str = 1;
+			case 0x0008: {
+				err = aimbs_get16(bs);
+			} break;
 
-			if (str)
-				val = aimbs_getstr(bs, len);
-			else
-				val = aimbs_getraw(bs, len);
+			case 0x0011: {
+				if (length == 0) {
+					email = (char*)malloc(13*sizeof(char));
+					strcpy(email, "*suppressed*");
+				} else
+					email = aimbs_getstr(bs, length);
+			} break;
+		}
 
-			/* XXX fix so its only called once for the entire packet */
-			if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))
-				userfunc(sess, rx, (snac->subtype == 0x0005) ? 1 : 0, perms, type, len, val, str);
+		tlvcount--;
+	}
 
-			free(val);
+	if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))
+		userfunc(sess, rx, (snac->subtype == 0x0005) ? 1 : 0, perms, err, url, sn, email);
 
-			tlvcount--;
-		}
-	}
+	if (sn) free(sn);
+	if (url) free(url);
+	if (email) free(email);
 
 	return 1;
 }
 
+/*
+ * Subtype 0x0004 - Set screenname formatting.
+ *
+ */
+faim_export int aim_admin_setnick(aim_session_t *sess, aim_conn_t *conn, const char *newnick)
+{
+	aim_frame_t *tx;
+	aim_snacid_t snacid;
+	aim_tlvlist_t *tl = NULL;
+
+	if (!(tx = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+2+2+strlen(newnick))))
+		return -ENOMEM;
+
+	snacid = aim_cachesnac(sess, 0x0007, 0x0004, 0x0000, NULL, 0);
+	aim_putsnac(&tx->data, 0x0007, 0x0004, 0x0000, snacid);
+
+	aim_addtlvtochain_raw(&tl, 0x0001, strlen(newnick), newnick);
+	
+	aim_writetlvchain(&tx->data, &tl);
+	aim_freetlvchain(&tl);
+	
+	aim_tx_enqueue(sess, tx);
+
+
+	return 0;
+}
+
+/*
+ * Subtype 0x0004 - Change password.
+ *
+ */
+faim_export int aim_admin_changepasswd(aim_session_t *sess, aim_conn_t *conn, const char *newpw, const char *curpw)
+{
+	aim_frame_t *tx;
+	aim_tlvlist_t *tl = NULL;
+	aim_snacid_t snacid;
+
+	if (!(tx = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+4+strlen(curpw)+4+strlen(newpw))))
+		return -ENOMEM;
+
+	snacid = aim_cachesnac(sess, 0x0007, 0x0004, 0x0000, NULL, 0);
+	aim_putsnac(&tx->data, 0x0007, 0x0004, 0x0000, snacid);
+
+	/* new password TLV t(0002) */
+	aim_addtlvtochain_raw(&tl, 0x0002, strlen(newpw), newpw);
+
+	/* current password TLV t(0012) */
+	aim_addtlvtochain_raw(&tl, 0x0012, strlen(curpw), curpw);
+
+	aim_writetlvchain(&tx->data, &tl);
+	aim_freetlvchain(&tl);
+
+	aim_tx_enqueue(sess, tx);
+
+	return 0;
+}
+
+/*
+ * Subtype 0x0004 - Change email address.
+ *
+ */
+faim_export int aim_admin_setemail(aim_session_t *sess, aim_conn_t *conn, const char *newemail)
+{
+	aim_frame_t *tx;
+	aim_snacid_t snacid;
+	aim_tlvlist_t *tl = NULL;
+
+	if (!(tx = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+2+2+strlen(newemail))))
+		return -ENOMEM;
+
+	snacid = aim_cachesnac(sess, 0x0007, 0x0004, 0x0000, NULL, 0);
+	aim_putsnac(&tx->data, 0x0007, 0x0004, 0x0000, snacid);
+
+	aim_addtlvtochain_raw(&tl, 0x0011, strlen(newemail), newemail);
+	
+	aim_writetlvchain(&tx->data, &tl);
+	aim_freetlvchain(&tl);
+	
+	aim_tx_enqueue(sess, tx);
+
+	return 0;
+}
+
+/*
+ * Subtype 0x0006 - Request account confirmation.
+ *
+ * This will cause an email to be sent to the address associated with
+ * the account.  By following the instructions in the mail, you can
+ * get the TRIAL flag removed from your account.
+ *
+ */
+faim_export int aim_admin_reqconfirm(aim_session_t *sess, aim_conn_t *conn)
+{
+	return aim_genericreq_n(sess, conn, 0x0007, 0x0006);
+}
+
+/*
+ * Subtype 0x0007 - Account confirmation request acknowledgement.
+ *
+ */
 static int accountconfirm(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
 {
 	aim_rxcallback_t userfunc;
 	fu16_t status;
+	aim_tlvlist_t *tl;
 
 	status = aimbs_get16(bs);
+	/* This is 0x0013 if unable to confirm at this time */
+
+	tl = aim_readtlvchain(bs);
 
 	if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))
 		return userfunc(sess, rx, status);
@@ -86,112 +235,3 @@
 
 	return 0;
 }
-
-faim_export int aim_admin_changepasswd(aim_session_t *sess, aim_conn_t *conn, const char *newpw, const char *curpw)
-{
-	aim_frame_t *tx;
-	aim_tlvlist_t *tl = NULL;
-	aim_snacid_t snacid;
-
-	if (!(tx = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+4+strlen(curpw)+4+strlen(newpw))))
-		return -ENOMEM;
-
-	snacid = aim_cachesnac(sess, 0x0007, 0x0004, 0x0000, NULL, 0);
-	aim_putsnac(&tx->data, 0x0007, 0x0004, 0x0000, snacid);
-
-	/* new password TLV t(0002) */
-	aim_addtlvtochain_raw(&tl, 0x0002, strlen(newpw), newpw);
-
-	/* current password TLV t(0012) */
-	aim_addtlvtochain_raw(&tl, 0x0012, strlen(curpw), curpw);
-
-	aim_writetlvchain(&tx->data, &tl);
-	aim_freetlvchain(&tl);
-
-	aim_tx_enqueue(sess, tx);
-
-	return 0;
-}
-
-/*
- * Request account confirmation. 
- *
- * This will cause an email to be sent to the address associated with
- * the account.  By following the instructions in the mail, you can
- * get the TRIAL flag removed from your account.
- *
- */
-faim_export int aim_admin_reqconfirm(aim_session_t *sess, aim_conn_t *conn)
-{
-	return aim_genericreq_n(sess, conn, 0x0007, 0x0006);
-}
-
-/*
- * Request a bit of account info.
- *
- * The only known valid tag is 0x0011 (email address).
- *
- */ 
-faim_export int aim_admin_getinfo(aim_session_t *sess, aim_conn_t *conn, fu16_t info)
-{
-	aim_frame_t *tx;
-	aim_snacid_t snacid;
-
-	if (!(tx = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 14)))
-		return -ENOMEM;
-
-	snacid = aim_cachesnac(sess, 0x0002, 0x0002, 0x0000, NULL, 0);
-	aim_putsnac(&tx->data, 0x0007, 0x0002, 0x0000, snacid);
-
-	aimbs_put16(&tx->data, info);
-	aimbs_put16(&tx->data, 0x0000);
-
-	aim_tx_enqueue(sess, tx);
-
-	return 0;
-}
-
-faim_export int aim_admin_setemail(aim_session_t *sess, aim_conn_t *conn, const char *newemail)
-{
-	aim_frame_t *tx;
-	aim_snacid_t snacid;
-	aim_tlvlist_t *tl = NULL;
-
-	if (!(tx = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+2+2+strlen(newemail))))
-		return -ENOMEM;
-
-	snacid = aim_cachesnac(sess, 0x0007, 0x0004, 0x0000, NULL, 0);
-	aim_putsnac(&tx->data, 0x0007, 0x0004, 0x0000, snacid);
-
-	aim_addtlvtochain_raw(&tl, 0x0011, strlen(newemail), newemail);
-	
-	aim_writetlvchain(&tx->data, &tl);
-	aim_freetlvchain(&tl);
-	
-	aim_tx_enqueue(sess, tx);
-
-	return 0;
-}
-
-faim_export int aim_admin_setnick(aim_session_t *sess, aim_conn_t *conn, const char *newnick)
-{
-	aim_frame_t *tx;
-	aim_snacid_t snacid;
-	aim_tlvlist_t *tl = NULL;
-
-	if (!(tx = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+2+2+strlen(newnick))))
-		return -ENOMEM;
-
-	snacid = aim_cachesnac(sess, 0x0007, 0x0004, 0x0000, NULL, 0);
-	aim_putsnac(&tx->data, 0x0007, 0x0004, 0x0000, snacid);
-
-	aim_addtlvtochain_raw(&tl, 0x0001, strlen(newnick), newnick);
-	
-	aim_writetlvchain(&tx->data, &tl);
-	aim_freetlvchain(&tl);
-	
-	aim_tx_enqueue(sess, tx);
-
-
-	return 0;
-}
--- a/src/protocols/oscar/adverts.c	Thu Nov 07 01:39:24 2002 +0000
+++ b/src/protocols/oscar/adverts.c	Thu Nov 07 02:25:12 2002 +0000
@@ -1,5 +1,5 @@
 /*
- *
+ * Family 0x0005 - Advertisements.
  *
  */
 
@@ -29,5 +29,3 @@
 
 	return 0;
 }
-
-
--- a/src/protocols/oscar/aim.h	Thu Nov 07 01:39:24 2002 +0000
+++ b/src/protocols/oscar/aim.h	Thu Nov 07 02:25:12 2002 +0000
@@ -555,6 +555,7 @@
 	char *email;
 	char *bosip;
 	fu8_t *cookie;
+	char *chpassurl;
 	struct aim_clientrelease latestrelease;
 	struct aim_clientrelease latestbeta;
 };
@@ -611,7 +612,7 @@
 faim_export aim_conn_t *aim_getconn_type_all(aim_session_t *, int type);
 faim_export aim_conn_t *aim_getconn_fd(aim_session_t *, int fd);
 
-/* aim_misc.c */
+/* misc.c */
 
 #define AIM_VISIBILITYCHANGE_PERMITADD    0x05
 #define AIM_VISIBILITYCHANGE_PERMITREMOVE 0x06
@@ -657,7 +658,7 @@
 #define AIM_RATE_CODE_CLEARLIMIT 0x0004
 faim_export int aim_ads_requestads(aim_session_t *sess, aim_conn_t *conn);
 
-/* aim_im.c */
+/* im.c */
 
 struct aim_fileheader_t {
 #if 0
@@ -903,7 +904,7 @@
 faim_export int aim_oft_getfile_ack(aim_session_t *sess, aim_conn_t *conn);
 faim_export int aim_oft_end(aim_session_t *sess, aim_conn_t *conn);
 
-/* aim_info.c */
+/* info.c */
 #define AIM_CAPS_BUDDYICON      0x00000001
 #define AIM_CAPS_VOICE          0x00000002
 #define AIM_CAPS_IMIMAGE        0x00000004
@@ -1137,7 +1138,7 @@
 faim_export int aim_email_sendcookies(aim_session_t *sess, aim_conn_t *conn);
 faim_export int aim_email_activate(aim_session_t *sess, aim_conn_t *conn);
 
-/* aim_util.c */
+/* util.c */
 /*
  * These are really ugly.  You'd think this was LISP.  I wish it was.
  *
@@ -1202,7 +1203,7 @@
 /* for libc's that dont have it */
 faim_export char *aim_strsep(char **pp, const char *delim);
 
-/* aim_meta.c */
+/* meta.c */
 faim_export char *aim_getbuilddate(void);
 faim_export char *aim_getbuildtime(void);
 faim_export int aim_getbuildstring(char *buf, int buflen);
--- a/src/protocols/oscar/auth.c	Thu Nov 07 01:39:24 2002 +0000
+++ b/src/protocols/oscar/auth.c	Thu Nov 07 02:25:12 2002 +0000
@@ -1,5 +1,8 @@
 /*
- * Deals with the authorizer (group 0x0017=23, and old-style non-SNAC login).
+ * Family 0x0017 - Authentication.
+ *
+ * Deals with the authorizer for SNAC-based login, and also old-style 
+ * non-SNAC login.
  *
  */
 
@@ -474,6 +477,11 @@
 	if (aim_gettlv(tlvlist, 0x0049, 1))
 		; /* no idea what this is */
 
+	/*
+	 * URL to change password.
+	 */
+	if (aim_gettlv(tlvlist, 0x0054, 1))
+		info.chpassurl = aim_gettlv_str(tlvlist, 0x0054, 1);
 
 	if ((userfunc = aim_callhandler(sess, rx->conn, snac ? snac->family : 0x0017, snac ? snac->subtype : 0x0003)))
 		ret = userfunc(sess, rx, &info);
@@ -482,6 +490,7 @@
 	free(info.bosip);
 	free(info.errorurl);
 	free(info.email);
+	free(info.chpassurl);
 	free(info.latestrelease.name);
 	free(info.latestrelease.url);
 	free(info.latestrelease.info);
@@ -540,4 +549,3 @@
 
 	return 0;
 }
-
--- a/src/protocols/oscar/oscar.c	Thu Nov 07 01:39:24 2002 +0000
+++ b/src/protocols/oscar/oscar.c	Thu Nov 07 02:25:12 2002 +0000
@@ -3281,40 +3281,77 @@
 	va_end(ap);
 
 	debug_printf("account confirmation returned status 0x%04x (%s)\n", status,
-			status ? "email sent" : "unknown");
-	if (status) {
+			status ? "unknown" : "email sent");
+	if (!status) {
 		g_snprintf(msg, sizeof(msg), "You should receive an email asking to confirm %s.",
 				gc->username);
-		do_error_dialog("Account confirmation requested.", msg, GAIM_INFO);
+		do_error_dialog("Account Confirmation Requested", msg, GAIM_INFO);
 	}
 
 	return 1;
 }
 
 static int gaim_info_change(aim_session_t *sess, aim_frame_t *fr, ...) {
-	int change, str;
-	fu16_t perms, type, length;
-	char *val;
+	struct gaim_connection *gc = sess->aux_data;
 	va_list ap;
-	char buf[BUF_LONG];
-	struct gaim_connection *gc = sess->aux_data;
+	fu16_t perms, err;
+	char *url, *sn, *email;
+	int change;
 
 	va_start(ap, fr);
 	change = va_arg(ap, int);
 	perms = (fu16_t)va_arg(ap, unsigned int);
-	type = (fu16_t)va_arg(ap, unsigned int);
-	length = (fu16_t)va_arg(ap, unsigned int);
-	val = va_arg(ap, char *);
-	str = va_arg(ap, int);
+	err = (fu16_t)va_arg(ap, unsigned int);
+	url = va_arg(ap, char *);
+	sn = va_arg(ap, char *);
+	email = va_arg(ap, char *);
 	va_end(ap);
 
-	debug_printf("info%s: perms = %d, type = %x, length = %d, val = %s\n",
-			change ? " change" : "", perms, type, length, str ? val : "(not string)");
-
-	/* XXX Do something for other types too. */
-	if ((type == 0x0011) && str && length) {
-		g_snprintf(buf, sizeof(buf), "The email address for %s is %s", gc->username, val);
-		do_error_dialog(buf, NULL, GAIM_INFO);
+	debug_printf("account info: because of %s, perms=0x%04x, err=0x%04x, url=%s, sn=%s, email=%s\n",
+		change ? "change" : "request", perms, err, url, sn, email);
+
+	if (err && url) {
+		char *dialog_msg;
+		char *dialog_top = g_strdup_printf(_("Error Changing Account Info"));
+		switch (err) {
+			case 0x0001: {
+				dialog_msg = g_strdup_printf(_("Error 0x%04x: Unable to format screen name because the requested screen name differs from the original."), err);
+			} break;
+			case 0x0006: {
+				dialog_msg = g_strdup_printf(_("Error 0x%04x: Unable to format screen name because the requested screen name ends in a space."), err);
+			} break;
+			case 0x000b: {
+				dialog_msg = g_strdup_printf(_("Error 0x%04x: Unable to format screen name because the requested screen name is too long."), err);
+			} break;
+			case 0x001d: {
+				dialog_msg = g_strdup_printf(_("Error 0x%04x: Unable to change email address because there is already a request pending for this screen name."), err);
+			} break;
+			case 0x0021: {
+				dialog_msg = g_strdup_printf(_("Error 0x%04x: Unable to change email address because the given address has too many screen names associated with it."), err);
+			} break;
+			case 0x0023: {
+				dialog_msg = g_strdup_printf(_("Error 0x%04x: Unable to change email address because the given address is invalid."), err);
+			} break;
+			default: {
+				dialog_msg = g_strdup_printf(_("Error 0x%04x: Unknown error."), err);
+			} break;
+		}
+		do_error_dialog(dialog_top, dialog_msg, GAIM_ERROR);
+		g_free(dialog_top);
+		g_free(dialog_msg);
+		return 1;
+	}
+
+	if (sn) {
+		char *dialog_msg = g_strdup_printf(_("Your screen name is currently formated as follows:\n%s"), sn);
+		do_error_dialog("Account Info", dialog_msg, GAIM_INFO);
+		g_free(dialog_msg);
+	}
+
+	if (email) {
+		char *dialog_msg = g_strdup_printf(_("The email address for %s is %s"), gc->username, email);
+		do_error_dialog("Account Info", dialog_msg, GAIM_INFO);
+		g_free(dialog_msg);
 	}
 
 	return 1;
--- a/src/protocols/oscar/tlv.c	Thu Nov 07 01:39:24 2002 +0000
+++ b/src/protocols/oscar/tlv.c	Thu Nov 07 02:25:12 2002 +0000
@@ -183,11 +183,11 @@
 }
 
 /**
- * aim_addtlvtochain_str - Add a string to a TLV chain
+ * aim_addtlvtochain_raw - Add a string to a TLV chain
  * @list: Desination chain (%NULL pointer if empty)
- * @type: TLV type
- * @str: String to add
- * @len: Length of string to add (not including %NULL)
+ * @t: TLV type
+ * @l: Length of string to add (not including %NULL)
+ * @v: String to add
  *
  * Adds the passed string as a TLV element of the passed type
  * to the TLV chain.