# HG changeset patch # User Mark Doliner # Date 1274323440 0 # Node ID f18b6eb0ed025afe7a0abbe19c47c780f4a120a6 # Parent c1b8e619f1b8b5b5a5cc48d14995c6d5e034bc24 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. diff -r c1b8e619f1b8 -r f18b6eb0ed02 libpurple/protocols/oscar/family_chatnav.c --- 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; diff -r c1b8e619f1b8 -r f18b6eb0ed02 libpurple/protocols/oscar/family_icbm.c --- 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; } /** diff -r c1b8e619f1b8 -r f18b6eb0ed02 libpurple/protocols/oscar/family_locate.c --- 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; diff -r c1b8e619f1b8 -r f18b6eb0ed02 libpurple/protocols/oscar/oscar.c --- 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); diff -r c1b8e619f1b8 -r f18b6eb0ed02 libpurple/protocols/oscar/oscar.h --- 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); diff -r c1b8e619f1b8 -r f18b6eb0ed02 libpurple/protocols/oscar/util.c --- 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;