comparison src/protocols/oscar/locate.c @ 7259:22b5b81ca7e0

[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 <tailor@pidgin.im>
author Mark Doliner <mark@kingant.net>
date Tue, 14 Oct 2003 04:35:46 +0000
parents 0ed4d53c46f9
children dc3918a729e8
comparison
equal deleted inserted replaced
7258:d1974612b994 7259:22b5b81ca7e0
247 247
248 sess->locate.waiting_for_response = TRUE; 248 sess->locate.waiting_for_response = TRUE;
249 aim_locate_getinfoshort(sess, cur->sn, 0x00000003); 249 aim_locate_getinfoshort(sess, cur->sn, 0x00000003);
250 } 250 }
251 251
252 /*
253 * Remove this screen name from our queue. If this info was resquested
254 * by our info request queue, then pop off the next element of the queue.
255 *
256 * @param sess The aim session.
257 * @param sn Screen name of the info we just received.
258 * @return True if the request was explicit (client requested the info),
259 * false if the request was implicit (libfaim request the info).
260 */
261 static int aim_locate_gotuserinfo(aim_session_t *sess, const char *sn) {
262 struct userinfo_node *cur, *del;
263 int was_explicit = TRUE;
264
265 while ((sess->locate.request_queue != NULL) && (aim_sncmp(sn, sess->locate.request_queue->sn) == 0)) {
266 del = sess->locate.request_queue;
267 sess->locate.request_queue = del->next;
268 was_explicit = FALSE;
269 free(del->sn);
270 free(del);
271 }
272
273 cur = sess->locate.request_queue;
274 while ((cur != NULL) && (cur->next != NULL)) {
275 if (aim_sncmp(sn, cur->next->sn) == 0) {
276 del = cur->next;
277 cur->next = del->next;
278 was_explicit = FALSE;
279 free(del->sn);
280 free(del);
281 } else
282 cur = cur->next;
283 }
284
285 if (!was_explicit) {
286 sess->locate.waiting_for_response = FALSE;
287 aim_locate_dorequest(sess);
288 }
289
290 return was_explicit;
291 }
292
252 faim_internal void aim_locate_requestuserinfo(aim_session_t *sess, const char *sn) { 293 faim_internal void aim_locate_requestuserinfo(aim_session_t *sess, const char *sn) {
253 struct userinfo_node *cur; 294 struct userinfo_node *cur;
254 295
255 cur = (struct userinfo_node *)malloc(sizeof(struct userinfo_node)); 296 cur = (struct userinfo_node *)malloc(sizeof(struct userinfo_node));
256 cur->sn = strdup(sn); 297 cur->sn = strdup(sn);
731 772
732 return 0; 773 return 0;
733 } 774 }
734 775
735 /* 776 /*
777 * Subtype 0x0001
778 */
779 static int error(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
780 {
781 int ret = 0;
782 aim_rxcallback_t userfunc;
783 aim_snac_t *snac2;
784 fu16_t reason;
785 char *sn;
786 int was_explicit;
787
788 if (!(snac2 = aim_remsnac(sess, snac->id))) {
789 faimdprintf(sess, 0, "faim: locate.c, error(): received response from unknown request!\n");
790 return 0;
791 }
792
793 if ((snac2->family != 0x0002) && (snac2->type != 0x0015)) {
794 faimdprintf(sess, 0, "faim: locate.c, error(): received response from invalid request! %d\n", snac2->family);
795 return 0;
796 }
797
798 if (!(sn = snac2->data)) {
799 faimdprintf(sess, 0, "faim: locate.c, error(): received response from request without a screen name!\n");
800 return 0;
801 }
802
803 reason = aimbs_get16(bs);
804
805 /*
806 * Remove this screen name from our queue. If the client requested
807 * this buddy's info explicitly, then notify them that we do not have
808 * info for this buddy.
809 */
810 was_explicit = aim_locate_gotuserinfo(sess, sn);
811 if (was_explicit == TRUE)
812 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))
813 ret = userfunc(sess, rx, reason, sn);
814
815 if (snac2)
816 free(snac2->data);
817 free(snac2);
818
819 return ret;
820 }
821
822 /*
736 * Subtype 0x0002 823 * Subtype 0x0002
737 * 824 *
738 * Request Location services rights. 825 * Request Location services rights.
739 * 826 *
740 */ 827 */
907 aim_rxcallback_t userfunc; 994 aim_rxcallback_t userfunc;
908 aim_userinfo_t *userinfo, *userinfo2; 995 aim_userinfo_t *userinfo, *userinfo2;
909 aim_tlvlist_t *tlvlist; 996 aim_tlvlist_t *tlvlist;
910 aim_tlv_t *tlv = NULL; 997 aim_tlv_t *tlv = NULL;
911 int was_explicit; 998 int was_explicit;
912 struct userinfo_node *cur, *del;
913 999
914 userinfo = (aim_userinfo_t *)malloc(sizeof(aim_userinfo_t)); 1000 userinfo = (aim_userinfo_t *)malloc(sizeof(aim_userinfo_t));
915 aim_info_extract(sess, bs, userinfo); 1001 aim_info_extract(sess, bs, userinfo);
916 tlvlist = aim_tlvlist_read(bs); 1002 tlvlist = aim_tlvlist_read(bs);
917 1003
948 /* 1034 /*
949 * Remove this screen name from our queue. If the client requested 1035 * Remove this screen name from our queue. If the client requested
950 * this buddy's info explicitly, then notify them that we have info 1036 * this buddy's info explicitly, then notify them that we have info
951 * for this buddy. 1037 * for this buddy.
952 */ 1038 */
953 was_explicit = TRUE; 1039 was_explicit = aim_locate_gotuserinfo(sess, userinfo2->sn);
954 while ((sess->locate.request_queue != NULL) && (aim_sncmp(userinfo2->sn, sess->locate.request_queue->sn) == 0)) { 1040 if (was_explicit == TRUE)
955 del = sess->locate.request_queue;
956 sess->locate.request_queue = del->next;
957 was_explicit = FALSE;
958 free(del->sn);
959 free(del);
960 }
961 cur = sess->locate.request_queue;
962 while ((cur != NULL) && (cur->next != NULL)) {
963 if (aim_sncmp(userinfo2->sn, cur->next->sn) == 0) {
964 del = cur->next;
965 cur->next = del->next;
966 was_explicit = FALSE;
967 free(del->sn);
968 free(del);
969 } else
970 cur = cur->next;
971 }
972
973 if (was_explicit == TRUE) {
974 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) 1041 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))
975 ret = userfunc(sess, rx, userinfo2); 1042 ret = userfunc(sess, rx, userinfo2);
976 } else {
977 sess->locate.waiting_for_response = FALSE;
978 aim_locate_dorequest(sess);
979 }
980 1043
981 return ret; 1044 return ret;
982 } 1045 }
983 1046
984 /* 1047 /*
1130 return -EINVAL; 1193 return -EINVAL;
1131 1194
1132 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+4+1+strlen(sn)))) 1195 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+4+1+strlen(sn))))
1133 return -ENOMEM; 1196 return -ENOMEM;
1134 1197
1135 snacid = aim_cachesnac(sess, 0x0002, 0x0015, 0x0000, NULL, 0); 1198 snacid = aim_cachesnac(sess, 0x0002, 0x0015, 0x0000, sn, strlen(sn)+1);
1136 1199
1137 aim_putsnac(&fr->data, 0x0002, 0x0015, 0x0000, 0); 1200 aim_putsnac(&fr->data, 0x0002, 0x0015, 0x0000, snacid);
1138 aimbs_put32(&fr->data, flags); 1201 aimbs_put32(&fr->data, flags);
1139 aimbs_put8(&fr->data, strlen(sn)); 1202 aimbs_put8(&fr->data, strlen(sn));
1140 aimbs_putraw(&fr->data, sn, strlen(sn)); 1203 aimbs_putraw(&fr->data, sn, strlen(sn));
1141 1204
1142 aim_tx_enqueue(sess, fr); 1205 aim_tx_enqueue(sess, fr);
1145 } 1208 }
1146 1209
1147 static int snachandler(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs) 1210 static int snachandler(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
1148 { 1211 {
1149 1212
1150 if (snac->subtype == 0x0003) 1213 if (snac->subtype == 0x0001)
1214 return error(sess, mod, rx, snac, bs);
1215 else if (snac->subtype == 0x0003)
1151 return rights(sess, mod, rx, snac, bs); 1216 return rights(sess, mod, rx, snac, bs);
1152 else if (snac->subtype == 0x0006) 1217 else if (snac->subtype == 0x0006)
1153 return userinfo(sess, mod, rx, snac, bs); 1218 return userinfo(sess, mod, rx, snac, bs);
1154 1219
1155 return 0; 1220 return 0;