# HG changeset patch # User Mark Doliner # Date 1066106146 0 # Node ID 22b5b81ca7e0e9e6e2adc475c92749ca81bcb50a # Parent d1974612b994993778cb706cec6a776aa6b4d26c [gaim-migrate @ 7836] Correctly handle failed get info requests. This should fix that bug that's assigned to me, and also the problem SimGuy (and other people) have had where you need to Get Info twice before it works. committer: Tailor Script diff -r d1974612b994 -r 22b5b81ca7e0 src/protocols/oscar/aim.h --- a/src/protocols/oscar/aim.h Tue Oct 14 03:46:00 2003 +0000 +++ b/src/protocols/oscar/aim.h Tue Oct 14 04:35:46 2003 +0000 @@ -457,6 +457,7 @@ struct { struct aim_userinfo_s *userinfo; struct userinfo_node *request_queue; + struct userinfo_node *requested; int waiting_for_response; } locate; diff -r d1974612b994 -r 22b5b81ca7e0 src/protocols/oscar/locate.c --- a/src/protocols/oscar/locate.c Tue Oct 14 03:46:00 2003 +0000 +++ b/src/protocols/oscar/locate.c Tue Oct 14 04:35:46 2003 +0000 @@ -249,6 +249,47 @@ aim_locate_getinfoshort(sess, cur->sn, 0x00000003); } +/* + * Remove this screen name from our queue. If this info was resquested + * by our info request queue, then pop off the next element of the queue. + * + * @param sess The aim session. + * @param sn Screen name of the info we just received. + * @return True if the request was explicit (client requested the info), + * false if the request was implicit (libfaim request the info). + */ +static int aim_locate_gotuserinfo(aim_session_t *sess, const char *sn) { + struct userinfo_node *cur, *del; + int was_explicit = TRUE; + + while ((sess->locate.request_queue != NULL) && (aim_sncmp(sn, sess->locate.request_queue->sn) == 0)) { + del = sess->locate.request_queue; + sess->locate.request_queue = del->next; + was_explicit = FALSE; + free(del->sn); + free(del); + } + + cur = sess->locate.request_queue; + while ((cur != NULL) && (cur->next != NULL)) { + if (aim_sncmp(sn, cur->next->sn) == 0) { + del = cur->next; + cur->next = del->next; + was_explicit = FALSE; + free(del->sn); + free(del); + } else + cur = cur->next; + } + + if (!was_explicit) { + sess->locate.waiting_for_response = FALSE; + aim_locate_dorequest(sess); + } + + return was_explicit; +} + faim_internal void aim_locate_requestuserinfo(aim_session_t *sess, const char *sn) { struct userinfo_node *cur; @@ -733,6 +774,52 @@ } /* + * Subtype 0x0001 + */ +static int error(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs) +{ + int ret = 0; + aim_rxcallback_t userfunc; + aim_snac_t *snac2; + fu16_t reason; + char *sn; + int was_explicit; + + if (!(snac2 = aim_remsnac(sess, snac->id))) { + faimdprintf(sess, 0, "faim: locate.c, error(): received response from unknown request!\n"); + return 0; + } + + if ((snac2->family != 0x0002) && (snac2->type != 0x0015)) { + faimdprintf(sess, 0, "faim: locate.c, error(): received response from invalid request! %d\n", snac2->family); + return 0; + } + + if (!(sn = snac2->data)) { + faimdprintf(sess, 0, "faim: locate.c, error(): received response from request without a screen name!\n"); + return 0; + } + + reason = aimbs_get16(bs); + + /* + * Remove this screen name from our queue. If the client requested + * this buddy's info explicitly, then notify them that we do not have + * info for this buddy. + */ + was_explicit = aim_locate_gotuserinfo(sess, sn); + if (was_explicit == TRUE) + if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) + ret = userfunc(sess, rx, reason, sn); + + if (snac2) + free(snac2->data); + free(snac2); + + return ret; +} + +/* * Subtype 0x0002 * * Request Location services rights. @@ -909,7 +996,6 @@ aim_tlvlist_t *tlvlist; aim_tlv_t *tlv = NULL; int was_explicit; - struct userinfo_node *cur, *del; userinfo = (aim_userinfo_t *)malloc(sizeof(aim_userinfo_t)); aim_info_extract(sess, bs, userinfo); @@ -950,33 +1036,10 @@ * this buddy's info explicitly, then notify them that we have info * for this buddy. */ - was_explicit = TRUE; - while ((sess->locate.request_queue != NULL) && (aim_sncmp(userinfo2->sn, sess->locate.request_queue->sn) == 0)) { - del = sess->locate.request_queue; - sess->locate.request_queue = del->next; - was_explicit = FALSE; - free(del->sn); - free(del); - } - cur = sess->locate.request_queue; - while ((cur != NULL) && (cur->next != NULL)) { - if (aim_sncmp(userinfo2->sn, cur->next->sn) == 0) { - del = cur->next; - cur->next = del->next; - was_explicit = FALSE; - free(del->sn); - free(del); - } else - cur = cur->next; - } - - if (was_explicit == TRUE) { + was_explicit = aim_locate_gotuserinfo(sess, userinfo2->sn); + if (was_explicit == TRUE) if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) ret = userfunc(sess, rx, userinfo2); - } else { - sess->locate.waiting_for_response = FALSE; - aim_locate_dorequest(sess); - } return ret; } @@ -1132,9 +1195,9 @@ if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+4+1+strlen(sn)))) return -ENOMEM; - snacid = aim_cachesnac(sess, 0x0002, 0x0015, 0x0000, NULL, 0); + snacid = aim_cachesnac(sess, 0x0002, 0x0015, 0x0000, sn, strlen(sn)+1); - aim_putsnac(&fr->data, 0x0002, 0x0015, 0x0000, 0); + aim_putsnac(&fr->data, 0x0002, 0x0015, 0x0000, snacid); aimbs_put32(&fr->data, flags); aimbs_put8(&fr->data, strlen(sn)); aimbs_putraw(&fr->data, sn, strlen(sn)); @@ -1147,7 +1210,9 @@ static int snachandler(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs) { - if (snac->subtype == 0x0003) + if (snac->subtype == 0x0001) + return error(sess, mod, rx, snac, bs); + else if (snac->subtype == 0x0003) return rights(sess, mod, rx, snac, bs); else if (snac->subtype == 0x0006) return userinfo(sess, mod, rx, snac, bs); diff -r d1974612b994 -r 22b5b81ca7e0 src/protocols/oscar/oscar.c --- a/src/protocols/oscar/oscar.c Tue Oct 14 03:46:00 2003 +0000 +++ b/src/protocols/oscar/oscar.c Tue Oct 14 04:35:46 2003 +0000 @@ -3013,11 +3013,10 @@ /* * We get this error when there was an error in the locate family. This - * usually happens because libfaim couldn't get info for someone when it - * tried automatically. Seeing the message gets annoying... + * happens when you request info of someone who is offline. */ static int gaim_parse_locerr(aim_session_t *sess, aim_frame_t *fr, ...) { - /* char *buf; */ + gchar *buf; va_list ap; fu16_t reason; char *destn; @@ -3027,12 +3026,10 @@ destn = va_arg(ap, char *); va_end(ap); - /* buf = g_strdup_printf(_("User information for %s unavailable:"), destn); gaim_notify_error(sess->aux_data, NULL, buf, (reason < msgerrreasonlen) ? _(msgerrreason[reason]) : _("No reason given.")); g_free(buf); - */ return 1; }