changeset 30406:f18b6eb0ed02

Cleanup, basically. Move the icbm snac error handling from oscar.c to family_icbm.c so we don't have to bother we va_args. This is simpler, and gives us the benefit of type checking by the compiler, which will help avoid the crash bug we encountered.
author Mark Doliner <mark@kingant.net>
date Thu, 20 May 2010 02:44:00 +0000
parents c1b8e619f1b8
children dbb5283fb21e
files libpurple/protocols/oscar/family_chatnav.c libpurple/protocols/oscar/family_icbm.c libpurple/protocols/oscar/family_locate.c libpurple/protocols/oscar/oscar.c libpurple/protocols/oscar/oscar.h libpurple/protocols/oscar/util.c
diffstat 6 files changed, 117 insertions(+), 134 deletions(-) [+]
line wrap: on
line diff
--- a/libpurple/protocols/oscar/family_chatnav.c	Thu May 20 01:39:52 2010 +0000
+++ b/libpurple/protocols/oscar/family_chatnav.c	Thu May 20 02:44:00 2010 +0000
@@ -37,7 +37,8 @@
 	guint16 error, chatnav_error;
 	GSList *tlvlist;
 
-	if (!(snac2 = aim_remsnac(od, snac->id))) {
+	snac2 = aim_remsnac(od, snac->id);
+	if (!snac2) {
 		purple_debug_warning("oscar", "chatnav error: received response to unknown request (%08x)\n", snac->id);
 		return 0;
 	}
@@ -67,8 +68,7 @@
 		ret = 1;
 	}
 
-	if (snac2)
-		g_free(snac2->data);
+	g_free(snac2->data);
 	g_free(snac2);
 
 	return ret;
--- a/libpurple/protocols/oscar/family_icbm.c	Thu May 20 01:39:52 2010 +0000
+++ b/libpurple/protocols/oscar/family_icbm.c	Thu May 20 02:44:00 2010 +0000
@@ -53,6 +53,25 @@
 
 #include "util.h"
 
+static const char * const errcodereason[] = {
+	N_("Invalid error"),
+	N_("Not logged in"),
+	N_("Cannot receive IM due to parental controls"),
+	N_("Cannot send SMS without accepting terms"),
+	N_("Cannot send SMS"), /* SMS_WITHOUT_DISCLAIMER is weird */
+	N_("Cannot send SMS to this country"),
+	N_("Unknown error"), /* Undocumented */
+	N_("Unknown error"), /* Undocumented */
+	N_("Cannot send SMS to unknown country"),
+	N_("Bot accounts cannot initiate IMs"),
+	N_("Bot account cannot IM this user"),
+	N_("Bot account reached IM limit"),
+	N_("Bot account reached daily IM limit"),
+	N_("Bot account reached monthly IM limit"),
+	N_("Unable to receive offline messages"),
+	N_("Offline message store full")
+};
+static const int errcodereasonlen = G_N_ELEMENTS(errcodereason);
 
 /**
  * Add a standard ICBM header to the given bstream with the given
@@ -157,14 +176,19 @@
 static int
 error(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, ByteStream *bs)
 {
-	int ret = 0;
-	aim_rxcallback_t userfunc;
 	aim_snac_t *snac2;
 	guint16 reason, errcode = 0;
-	char *bn;
+	const char *bn;
 	GSList *tlvlist;
-
-	if (!(snac2 = aim_remsnac(od, snac->id))) {
+	PurpleConnection *gc = od->gc;
+#ifdef TODOFT
+	PurpleXfer *xfer;
+#endif
+	const char *reason_str;
+	char *buf;
+
+	snac2 = aim_remsnac(od, snac->id);
+	if (!snac2) {
 		purple_debug_misc("oscar", "icbm error: received response from unknown request!\n");
 		return 1;
 	}
@@ -176,8 +200,11 @@
 		return 1;
 	}
 
-	if (!(bn = snac2->data)) {
+	/* Data is assumed to be the destination bn */
+	bn = snac2->data;
+	if (!bn || bn[0] == '\0') {
 		purple_debug_misc("oscar", "icbm error: received response from request without a buddy name!\n");
+		g_free(snac2->data);
 		g_free(snac2);
 		return 1;
 	}
@@ -189,16 +216,46 @@
 		errcode = aim_tlv_get16(tlvlist, 0x0008, 1);
 	aim_tlvlist_free(tlvlist);
 
+	purple_debug_error("oscar",
+			   "Message error with bn %s and reason %hu and errcode %hu\n",
+				(bn != NULL ? bn : ""), reason, errcode);
+
+#ifdef TODOFT
+	/* If this was a file transfer request, bn is a cookie */
+	if ((xfer = oscar_find_xfer_by_cookie(od->file_transfers, bn))) {
+		purple_xfer_cancel_remote(xfer);
+		return 1;
+	}
+#endif
+
 	/* Notify the user that the message wasn't delivered */
-	if ((userfunc = aim_callhandler(od, snac->family, snac->subtype)))
-		ret = userfunc(od, conn, frame, reason, errcode, bn);
-
-	if (snac2) {
-		g_free(snac2->data);
-		g_free(snac2);
+	reason_str = oscar_get_msgerr_reason(reason);
+	if (errcode != 0 && errcode < errcodereasonlen)
+		buf = g_strdup_printf(_("Unable to send message: %s (%s)"), reason_str,
+		                      _(errcodereason[errcode]));
+	else
+		buf = g_strdup_printf(_("Unable to send message: %s"), reason_str);
+
+	if (!purple_conv_present_error(bn, purple_connection_get_account(gc), buf)) {
+		g_free(buf);
+		if (errcode != 0 && errcode < errcodereasonlen)
+			buf = g_strdup_printf(_("Unable to send message to %s: %s (%s)"),
+			                      bn ? bn : "(unknown)", reason_str,
+			                      _(errcodereason[errcode]));
+		else
+			buf = g_strdup_printf(_("Unable to send message to %s: %s"),
+			                      bn ? bn : "(unknown)", reason_str);
+		purple_notify_error(od->gc, NULL, buf, reason_str);
 	}
-
-	return ret;
+	g_free(buf);
+
+
+
+
+	g_free(snac2->data);
+	g_free(snac2);
+
+	return 1;
 }
 
 /**
--- a/libpurple/protocols/oscar/family_locate.c	Thu May 20 01:39:52 2010 +0000
+++ b/libpurple/protocols/oscar/family_locate.c	Thu May 20 02:44:00 2010 +0000
@@ -1231,7 +1231,8 @@
 	guint16 reason;
 	char *bn;
 
-	if (!(snac2 = aim_remsnac(od, snac->id))) {
+	snac2 = aim_remsnac(od, snac->id);
+	if (!snac2) {
 		purple_debug_misc("oscar", "locate error: received response from unknown request!\n");
 		return 0;
 	}
@@ -1243,7 +1244,8 @@
 		return 0;
 	}
 
-	if (!(bn = snac2->data)) {
+	bn = snac2->data;
+	if (!bn) {
 		purple_debug_misc("oscar", "locate error: received response from request without a buddy name!\n");
 		g_free(snac2);
 		return 0;
@@ -1255,8 +1257,7 @@
 	if ((userfunc = aim_callhandler(od, snac->family, snac->subtype)))
 		ret = userfunc(od, conn, frame, reason, bn);
 
-	if (snac2)
-		g_free(snac2->data);
+	g_free(snac2->data);
 	g_free(snac2);
 
 	return ret;
--- a/libpurple/protocols/oscar/oscar.c	Thu May 20 01:39:52 2010 +0000
+++ b/libpurple/protocols/oscar/oscar.c	Thu May 20 02:44:00 2010 +0000
@@ -128,55 +128,6 @@
 	gchar *nick;
 };
 
-static const char * const msgerrreason[] = {
-	N_("Invalid error"),
-	N_("Invalid SNAC"),
-	N_("Rate to host"),
-	N_("Rate to client"),
-	N_("Not logged in"),
-	N_("Service unavailable"),
-	N_("Service not defined"),
-	N_("Obsolete SNAC"),
-	N_("Not supported by host"),
-	N_("Not supported by client"),
-	N_("Refused by client"),
-	N_("Reply too big"),
-	N_("Responses lost"),
-	N_("Request denied"),
-	N_("Busted SNAC payload"),
-	N_("Insufficient rights"),
-	N_("In local permit/deny"),
-	N_("Warning level too high (sender)"),
-	N_("Warning level too high (receiver)"),
-	N_("User temporarily unavailable"),
-	N_("No match"),
-	N_("List overflow"),
-	N_("Request ambiguous"),
-	N_("Queue full"),
-	N_("Not while on AOL")
-};
-static const int msgerrreasonlen = G_N_ELEMENTS(msgerrreason);
-
-static const char * const errcodereason[] = {
-	N_("Invalid error"),
-	N_("Not logged in"),
-	N_("Cannot receive IM due to parental controls"),
-	N_("Cannot send SMS without accepting terms"),
-	N_("Cannot send SMS"), /* SMS_WITHOUT_DISCLAIMER is weird */
-	N_("Cannot send SMS to this country"),
-	N_("Unknown error"), /* Undocumented */
-	N_("Unknown error"), /* Undocumented */
-	N_("Cannot send SMS to unknown country"),
-	N_("Bot accounts cannot initiate IMs"),
-	N_("Bot account cannot IM this user"),
-	N_("Bot account reached IM limit"),
-	N_("Bot account reached daily IM limit"),
-	N_("Bot account reached monthly IM limit"),
-	N_("Unable to receive offline messages"),
-	N_("Offline message store full")
-};
-static const int errcodereasonlen = G_N_ELEMENTS(errcodereason);
-
 /* All the libfaim->purple callback functions */
 
 /* Only used when connecting with the old-style BUCP login */
@@ -207,7 +158,6 @@
 static int purple_parse_searchreply(OscarData *, FlapConnection *, FlapFrame *, ...);
 static int purple_bosrights        (OscarData *, FlapConnection *, FlapFrame *, ...);
 static int purple_connerr          (OscarData *, FlapConnection *, FlapFrame *, ...);
-static int purple_parse_msgerr     (OscarData *, FlapConnection *, FlapFrame *, ...);
 static int purple_parse_mtn        (OscarData *, FlapConnection *, FlapFrame *, ...);
 static int purple_parse_locaterights(OscarData *, FlapConnection *, FlapFrame *, ...);
 static int purple_parse_buddyrights(OscarData *, FlapConnection *, FlapFrame *, ...);
@@ -1545,7 +1495,6 @@
 	oscar_data_addhandler(od, SNAC_FAMILY_ICBM, SNAC_SUBTYPE_ICBM_INCOMING, purple_parse_incoming_im, 0);
 	oscar_data_addhandler(od, SNAC_FAMILY_ICBM, SNAC_SUBTYPE_ICBM_MISSEDCALL, purple_parse_misses, 0);
 	oscar_data_addhandler(od, SNAC_FAMILY_ICBM, SNAC_SUBTYPE_ICBM_CLIENTAUTORESP, purple_parse_clientauto, 0);
-	oscar_data_addhandler(od, SNAC_FAMILY_ICBM, SNAC_SUBTYPE_ICBM_ERROR, purple_parse_msgerr, 0);
 	oscar_data_addhandler(od, SNAC_FAMILY_ICBM, SNAC_SUBTYPE_ICBM_MTN, purple_parse_mtn, 0);
 	oscar_data_addhandler(od, SNAC_FAMILY_ICBM, SNAC_SUBTYPE_ICBM_ACK, purple_parse_msgack, 0);
 #ifdef OLDSTYLE_ICQ_OFFLINEMSGS
@@ -3371,67 +3320,8 @@
 	reason = (guint16) va_arg(ap, unsigned int);
 	va_end(ap);
 
-	purple_debug_error("oscar",
-			   "snac threw error (reason 0x%04hx: %s)\n", reason,
-			   (reason < msgerrreasonlen) ? msgerrreason[reason] : "unknown");
-	return 1;
-}
-
-static int purple_parse_msgerr(OscarData *od, FlapConnection *conn, FlapFrame *fr, ...) {
-	PurpleConnection *gc = od->gc;
-#ifdef TODOFT
-	OscarData *od = purple_connection_get_protocol_data(gc);
-	PurpleXfer *xfer;
-#endif
-	va_list ap;
-	guint16 reason, errcode;
-	char *data, *reason_str, *buf;
-
-	va_start(ap, fr);
-	reason = (guint16)va_arg(ap, unsigned int);
-	errcode = (guint16)va_arg(ap, unsigned int);
-	data = va_arg(ap, char *);
-	va_end(ap);
-
-	purple_debug_error("oscar",
-			   "Message error with data %s and reason %hu and errcode %hu\n",
-				(data != NULL ? data : ""), reason, errcode);
-
-	if ((data == NULL) || (*data == '\0'))
-		/* We can't do anything if data is empty */
-		return 1;
-
-#ifdef TODOFT
-	/* If this was a file transfer request, data is a cookie */
-	if ((xfer = oscar_find_xfer_by_cookie(od->file_transfers, data))) {
-		purple_xfer_cancel_remote(xfer);
-		return 1;
-	}
-#endif
-
-	/* Data is assumed to be the destination bn */
-
-	reason_str = g_strdup((reason < msgerrreasonlen) ? _(msgerrreason[reason]) : _("Unknown reason"));
-	if (errcode != 0 && errcode < errcodereasonlen)
-		buf = g_strdup_printf(_("Unable to send message: %s (%s)"), reason_str,
-		                      _(errcodereason[errcode]));
-	else
-		buf = g_strdup_printf(_("Unable to send message: %s"), reason_str);
-
-	if (!purple_conv_present_error(data, purple_connection_get_account(gc), buf)) {
-		g_free(buf);
-		if (errcode != 0 && errcode < errcodereasonlen)
-			buf = g_strdup_printf(_("Unable to send message to %s: %s (%s)"),
-			                      data ? data : "(unknown)", reason_str,
-			                      _(errcodereason[errcode]));
-		else
-			buf = g_strdup_printf(_("Unable to send message to %s: %s"),
-			                      data ? data : "(unknown)", reason_str);
-		purple_notify_error(od->gc, NULL, buf, reason_str);
-	}
-	g_free(buf);
-	g_free(reason_str);
-
+	purple_debug_error("oscar", "snac threw error (reason 0x%04hx: %s)\n",
+			reason, oscar_get_msgerr_reason(reason));
 	return 1;
 }
 
@@ -3494,7 +3384,7 @@
 		return 1;
 
 	user_info = purple_notify_user_info_new();
-	buf = g_strdup_printf(_("User information not available: %s"), (reason < msgerrreasonlen) ? _(msgerrreason[reason]) : _("Unknown reason."));
+	buf = g_strdup_printf(_("User information not available: %s"), oscar_get_msgerr_reason(reason));
 	purple_notify_user_info_add_pair(user_info, NULL, buf);
 	purple_notify_userinfo(od->gc, destn, user_info, NULL, NULL);
 	purple_notify_user_info_destroy(user_info);
--- a/libpurple/protocols/oscar/oscar.h	Thu May 20 01:39:52 2010 +0000
+++ b/libpurple/protocols/oscar/oscar.h	Thu May 20 02:44:00 2010 +0000
@@ -1559,6 +1559,7 @@
 		(((*((buf)+2)) << 16) & 0x00ff0000) + \
 		(((*((buf)+3)) << 24) & 0xff000000))
 
+const char *oscar_get_msgerr_reason(size_t reason);
 int oscar_get_ui_info_int(const char *str, int default_value);
 const char *oscar_get_ui_info_string(const char *str, const char *default_value);
 gchar *oscar_get_clientstring(void);
--- a/libpurple/protocols/oscar/util.c	Thu May 20 01:39:52 2010 +0000
+++ b/libpurple/protocols/oscar/util.c	Thu May 20 02:44:00 2010 +0000
@@ -35,6 +35,40 @@
 #include "win32dep.h"
 #endif
 
+static const char * const msgerrreason[] = {
+	N_("Invalid error"),
+	N_("Invalid SNAC"),
+	N_("Rate to host"),
+	N_("Rate to client"),
+	N_("Not logged in"),
+	N_("Service unavailable"),
+	N_("Service not defined"),
+	N_("Obsolete SNAC"),
+	N_("Not supported by host"),
+	N_("Not supported by client"),
+	N_("Refused by client"),
+	N_("Reply too big"),
+	N_("Responses lost"),
+	N_("Request denied"),
+	N_("Busted SNAC payload"),
+	N_("Insufficient rights"),
+	N_("In local permit/deny"),
+	N_("Warning level too high (sender)"),
+	N_("Warning level too high (receiver)"),
+	N_("User temporarily unavailable"),
+	N_("No match"),
+	N_("List overflow"),
+	N_("Request ambiguous"),
+	N_("Queue full"),
+	N_("Not while on AOL")
+};
+static const int msgerrreasonlen = G_N_ELEMENTS(msgerrreason);
+
+const char *oscar_get_msgerr_reason(size_t reason)
+{
+	return (reason < msgerrreasonlen) ? _(msgerrreason[reason]) : _("Unknown reason");
+}
+
 int oscar_get_ui_info_int(const char *str, int default_value)
 {
 	GHashTable *ui_info;