Mercurial > pidgin.yaz
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; |