diff libpurple/protocols/oscar/family_icbm.c @ 29986: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 d24c975c68a5 879baaf87aa2
line wrap: on
line diff
--- 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;
 }
 
 /**