X-Git-Url: http://andersk.mit.edu/gitweb/libfaim.git/blobdiff_plain/6c4888f468fdee469f61623eb2824414ef6ceafd..276495a31c7a18b4be1eb309dbab89a020021d09:/aim_info.c diff --git a/aim_info.c b/aim_info.c index 6f8b9cd..92e1f78 100644 --- a/aim_info.c +++ b/aim_info.c @@ -14,6 +14,10 @@ u_long aim_getinfo(struct aim_session_t *sess, const char *sn) { struct command_tx_struct newpacket; + int i = 0; + + if (!sess || !conn || !sn) + return 0; if (conn) newpacket.conn = conn; @@ -26,12 +30,13 @@ u_long aim_getinfo(struct aim_session_t *sess, newpacket.commandlen = 12 + 1 + strlen(sn); newpacket.data = (char *) malloc(newpacket.commandlen); - aim_putsnac(newpacket.data, 0x0002, 0x0005, 0x0000, sess->snac_nextid); + i = aim_putsnac(newpacket.data, 0x0002, 0x0005, 0x0000, sess->snac_nextid); - aimutil_put16(newpacket.data+10, 0x0001); - aimutil_put8(newpacket.data+12, strlen(sn)); - aimutil_putstr(newpacket.data+13, sn, strlen(sn)); + i += aimutil_put16(newpacket.data+i, 0x0001); + i += aimutil_put8(newpacket.data+i, strlen(sn)); + i += aimutil_putstr(newpacket.data+i, sn, strlen(sn)); + newpacket.lock = 0; aim_tx_enqueue(sess, &newpacket); { @@ -43,7 +48,7 @@ u_long aim_getinfo(struct aim_session_t *sess, snac.flags = 0x0000; snac.data = malloc(strlen(sn)+1); - memcpy(snac.data, sn, strlen(sn)+1); + strcpy(snac.data, sn); aim_newsnac(sess, &snac); } @@ -108,6 +113,7 @@ int aim_extractuserinfo(u_char *buf, struct aim_userinfo_s *outinfo) * 0x0004 AOL Main Service user * 0x0008 Unknown bit 4 * 0x0010 Free (AIM) user + * 0x0020 Away * * In some odd cases, we can end up with more * than one of these. We only want the first, @@ -152,6 +158,31 @@ int aim_extractuserinfo(u_char *buf, struct aim_userinfo_s *outinfo) case 0x0004: outinfo->idletime = aimutil_get16(&buf[i+4]); break; + + /* + * Type = 0x000d + * + * Capability information. Not real sure of + * actual decoding. See comment on aim_bos_setprofile() + * in aim_misc.c about the capability block, its the same. + * + * Ignore. + * + */ + case 0x000d: + break; + + /* + * Type = 0x000e + * + * Unknown. Always of zero length, and always only + * on AOL users. + * + * Ignore. + * + */ + case 0x000e: + break; /* * Type = 0x000f: Session Length. (AIM) @@ -281,6 +312,7 @@ int aim_parse_userinfo_middle(struct aim_session_t *sess, char *prof = NULL; u_int i = 0; rxcallback_t userfunc=NULL; + struct aim_tlvlist_t *tlvlist; { u_long snacid = 0x000000000; @@ -289,49 +321,32 @@ int aim_parse_userinfo_middle(struct aim_session_t *sess, snacid = aimutil_get32(&command->data[6]); snac = aim_remsnac(sess, snacid); - free(snac->data); - free(snac); + if (snac) + { + if (snac->data) + free(snac->data); + else + printf("faim: parse_userinfo_middle: warning: no ->data in cached SNAC\n"); + free(snac); + } + else + printf("faim: parseuserinfo_middle: warning: no SNAC cached with for this response (%08lx)\n", snacid); } i = 10; - i += aim_extractuserinfo(command->data+i, &userinfo); - - if (i < command->commandlen) - { - if (aimutil_get16(&command->data[i]) == 0x0001) - { - int len = 0; - - len = aimutil_get16(&command->data[i+2]); - - prof_encoding = (char *) malloc(len+1); - memcpy(prof_encoding, &(command->data[i+4]), len); - prof_encoding[len] = '\0'; - - i += (2+2+len); - } - else - { - printf("faim: userinfo: **warning: unexpected TLV after TLVblock t(%04x) l(%04x)\n", aimutil_get16(command->data+i), aimutil_get16(command->data+i+2)); - i += 2 + 2 + command->data[i+3]; - } - } - if (i < command->commandlen) - { - if (aimutil_get16(&command->data[i]) == 0x0002) - { - int len = 0; - len = aimutil_get16(&command->data[i+2]); - - prof = (char *) malloc(len+1); - memcpy(prof, &(command->data[i+4]), len); - prof[len] = '\0'; - } - else - printf("faim:userinfo: **warning: profile not found, but still have data\n"); - } + /* + * extractuserinfo will give us the basic metaTLV information + */ + i += aim_extractuserinfo(command->data+i, &userinfo); + + /* + * However, in this command, there's usually more TLVs following... + */ + tlvlist = aim_readtlvchain(command->data+i, command->commandlen-i); + prof_encoding = aim_gettlv_str(tlvlist, 0x0001, 1); + prof = aim_gettlv_str(tlvlist, 0x0002, 1); userfunc = aim_callhandler(command->conn, AIM_CB_FAM_LOC, AIM_CB_LOC_USERINFO); if (userfunc) @@ -342,9 +357,10 @@ int aim_parse_userinfo_middle(struct aim_session_t *sess, prof_encoding, prof); } - + free(prof_encoding); free(prof); + aim_freetlvchain(&tlvlist); return 1; }