Sun, 30 Apr 2000 21:47:04 +0000
[gaim-migrate @ 210]
Made the receive non-blocking, added a cancel button, and a few other updates.
No, sending a file to someone does not work yet. Be patient.
| 2 | 1 | /* |
| 2 | aim_info.c | |
| 3 | ||
| 4 | The functions here are responsible for requesting and parsing information- | |
| 5 | gathering SNACs. | |
| 6 | ||
| 7 | */ | |
| 8 | ||
| 9 | ||
| 10 | #include "aim.h" /* for most everything */ | |
| 11 | ||
| 12 | u_long aim_getinfo(struct aim_conn_t *conn, const char *sn) | |
| 13 | { | |
| 14 | struct command_tx_struct newpacket; | |
| 15 | ||
| 16 | if (conn) | |
| 17 | newpacket.conn = conn; | |
| 18 | else | |
| 19 | newpacket.conn = aim_getconn_type(AIM_CONN_TYPE_BOS); | |
| 20 | ||
| 21 | newpacket.lock = 1; | |
| 22 | newpacket.type = 0x0002; | |
| 23 | ||
| 24 | newpacket.commandlen = 12 + 1 + strlen(sn); | |
| 25 | newpacket.data = (char *) malloc(newpacket.commandlen); | |
| 26 | ||
| 27 | newpacket.data[0] = 0x00; | |
| 28 | newpacket.data[1] = 0x02; | |
| 29 | newpacket.data[2] = 0x00; | |
| 30 | newpacket.data[3] = 0x05; | |
| 31 | newpacket.data[4] = 0x00; | |
| 32 | newpacket.data[5] = 0x00; | |
| 33 | ||
| 34 | /* SNAC reqid */ | |
| 35 | newpacket.data[6] = (aim_snac_nextid >> 24) & 0xFF; | |
| 36 | newpacket.data[7] = (aim_snac_nextid >> 16) & 0xFF; | |
| 37 | newpacket.data[8] = (aim_snac_nextid >> 8) & 0xFF; | |
| 38 | newpacket.data[9] = (aim_snac_nextid) & 0xFF; | |
| 39 | ||
| 40 | /* TLV: Screen Name */ | |
| 41 | /* t(0x0001) */ | |
| 42 | newpacket.data[10] = 0x00; | |
| 43 | newpacket.data[11] = 0x01; | |
| 44 | /* l() */ | |
| 45 | newpacket.data[12] = strlen(sn); | |
| 46 | /* v() */ | |
| 47 | memcpy(&(newpacket.data[13]), sn, strlen(sn)); | |
| 48 | ||
| 49 | aim_tx_enqueue(&newpacket); | |
| 50 | ||
| 51 | { | |
| 52 | struct aim_snac_t snac; | |
| 53 | ||
| 54 | snac.id = aim_snac_nextid; | |
| 55 | snac.family = 0x0002; | |
| 56 | snac.type = 0x0005; | |
| 57 | snac.flags = 0x0000; | |
| 58 | ||
| 59 | snac.data = malloc(strlen(sn)+1); | |
| 60 | memcpy(snac.data, sn, strlen(sn)+1); | |
| 61 | ||
| 62 | aim_newsnac(&snac); | |
| 63 | } | |
| 64 | ||
| 65 | return (aim_snac_nextid++); | |
| 66 | } | |
| 67 | ||
| 68 | /* | |
| 69 | * This parses the user info stuff out all nice and pretty then calls | |
| 70 | * the higher-level callback (in the user app). | |
| 71 | * | |
| 72 | */ | |
| 73 | ||
| 74 | int aim_parse_userinfo_middle(struct command_rx_struct *command) | |
| 75 | { | |
| 76 | char *sn = NULL; | |
| 77 | char *prof_encoding = NULL; | |
| 78 | char *prof = NULL; | |
| 79 | u_short warnlevel = 0x0000; | |
| 80 | u_short idletime = 0x0000; | |
| 81 | u_short class = 0x0000; | |
| 82 | u_long membersince = 0x00000000; | |
| 83 | u_long onlinesince = 0x00000000; | |
| 84 | int tlvcnt = 0; | |
| 85 | int i = 0; | |
| 86 | ||
| 87 | { | |
| 88 | u_long snacid = 0x000000000; | |
| 89 | struct aim_snac_t *snac = NULL; | |
| 90 | ||
| 91 | snacid = (command->data[6] << 24) & 0xFF000000; | |
| 92 | snacid+= (command->data[7] << 16) & 0x00FF0000; | |
| 93 | snacid+= (command->data[8] << 8) & 0x0000FF00; | |
| 94 | snacid+= (command->data[9]) & 0x000000FF; | |
| 95 | ||
| 96 | snac = aim_remsnac(snacid); | |
| 97 | ||
| 98 | free(snac->data); | |
| 99 | free(snac); | |
| 100 | ||
| 101 | } | |
| 102 | ||
| 103 | sn = (char *) malloc(command->data[10]+1); | |
| 104 | memcpy(sn, &(command->data[11]), command->data[10]); | |
| 105 | sn[(int)command->data[10]] = '\0'; | |
| 106 | ||
| 107 | i = 11 + command->data[10]; | |
| 108 | warnlevel = ((command->data[i++]) << 8) & 0xFF00; | |
| 109 | warnlevel += (command->data[i++]) & 0x00FF; | |
| 110 | ||
| 111 | tlvcnt = ((command->data[i++]) << 8) & 0xFF00; | |
| 112 | tlvcnt += (command->data[i++]) & 0x00FF; | |
| 113 | ||
| 114 | /* a mini TLV parser */ | |
| 115 | { | |
| 116 | int curtlv = 0; | |
| 117 | int tlv1 = 0; | |
| 118 | ||
| 119 | while (curtlv < tlvcnt) | |
| 120 | { | |
| 121 | if ((command->data[i] == 0x00) && | |
| 122 | (command->data[i+1] == 0x01) ) | |
| 123 | { | |
| 124 | if (tlv1) | |
| 125 | break; | |
| 126 | /* t(0001) = class */ | |
| 127 | class = ((command->data[i+4]) << 8) & 0xFF00; | |
| 128 | class += (command->data[i+5]) & 0x00FF; | |
| 129 | i += (2 + 2 + command->data[i+3]); | |
| 130 | tlv1++; | |
| 131 | } | |
| 132 | else if ((command->data[i] == 0x00) && | |
| 133 | (command->data[i+1] == 0x02)) | |
| 134 | { | |
| 135 | /* t(0002) = member since date */ | |
| 136 | if (command->data[i+3] != 0x04) | |
| 137 | printf("faim: userinfo: **warning: strange v(%x) for t(2)\n", command->data[i+3]); | |
| 138 | ||
| 139 | membersince = ((command->data[i+4]) << 24) & 0xFF000000; | |
| 140 | membersince += ((command->data[i+5]) << 16) & 0x00FF0000; | |
| 141 | membersince += ((command->data[i+6]) << 8) & 0x0000FF00; | |
| 142 | membersince += ((command->data[i+7]) ) & 0x000000FF; | |
| 143 | i += (2 + 2 + command->data[i+3]); | |
| 144 | } | |
| 145 | else if ((command->data[i] == 0x00) && | |
| 146 | (command->data[i+1] == 0x03)) | |
| 147 | { | |
| 148 | /* t(0003) = on since date */ | |
| 149 | if (command->data[i+3] != 0x04) | |
| 150 | printf("faim: userinfo: **warning: strange v(%x) for t(3)\n", command->data[i+3]); | |
| 151 | ||
| 152 | onlinesince = ((command->data[i+4]) << 24) & 0xFF000000; | |
| 153 | onlinesince += ((command->data[i+5]) << 16) & 0x00FF0000; | |
| 154 | onlinesince += ((command->data[i+6]) << 8) & 0x0000FF00; | |
| 155 | onlinesince += ((command->data[i+7]) ) & 0x000000FF; | |
| 156 | i += (2 + 2 + command->data[i+3]); | |
| 157 | } | |
| 158 | else if ((command->data[i] == 0x00) && | |
| 159 | (command->data[i+1] == 0x04) ) | |
| 160 | { | |
| 161 | /* t(0004) = idle time */ | |
| 162 | if (command->data[i+3] != 0x02) | |
| 163 | printf("faim: userinfo: **warning: strange v(%x) for t(4)\n", command->data[i+3]); | |
| 164 | idletime = ((command->data[i+4]) << 8) & 0xFF00; | |
| 165 | idletime += (command->data[i+5]) & 0x00FF; | |
| 166 | i += (2 + 2 + command->data[i+3]); | |
| 167 | } | |
| 168 | else | |
| 169 | { | |
| 170 | printf("faim: userinfo: **warning: unexpected TLV t(%02x%02x) l(%02x%02x)\n", command->data[i], command->data[i+1], command->data[i+2], command->data[i+3]); | |
| 171 | i += (2 + 2 + command->data[i+3]); | |
| 172 | } | |
| 173 | curtlv++; | |
| 174 | } | |
| 175 | } | |
| 176 | if (i < command->commandlen) | |
| 177 | { | |
| 178 | if ( (command->data[i] == 0x00) && | |
| 179 | (command->data[i+1] == 0x01) ) | |
| 180 | { | |
| 181 | int len = 0; | |
| 182 | ||
| 183 | len = ((command->data[i+2] << 8) & 0xFF00); | |
| 184 | len += (command->data[i+3]) & 0x00FF; | |
| 185 | ||
| 186 | prof_encoding = (char *) malloc(len+1); | |
| 187 | memcpy(prof_encoding, &(command->data[i+4]), len); | |
| 188 | prof_encoding[len] = '\0'; | |
| 189 | ||
| 190 | i += (2+2+len); | |
| 191 | } | |
| 192 | else | |
| 193 | { | |
| 194 | printf("faim: userinfo: **warning: unexpected TLV after TLVblock t(%02x%02x) l(%02x%02x)\n", command->data[i], command->data[i+1], command->data[i+2], command->data[i+3]); | |
| 195 | i += 2 + 2 + command->data[i+3]; | |
| 196 | } | |
| 197 | } | |
| 198 | ||
| 199 | if (i < command->commandlen) | |
| 200 | { | |
| 201 | int len = 0; | |
| 202 | ||
| 203 | len = ((command->data[i+2]) << 8) & 0xFF00; | |
| 204 | len += (command->data[i+3]) & 0x00FF; | |
| 205 | ||
| 206 | prof = (char *) malloc(len+1); | |
| 207 | memcpy(prof, &(command->data[i+4]), len); | |
| 208 | prof[len] = '\0'; | |
| 209 | } | |
| 210 | else | |
| 211 | printf("faim: userinfo: **early parse abort...no profile?\n"); | |
| 212 | ||
| 213 | i = (aim_callbacks[AIM_CB_USERINFO])(command, sn, prof_encoding, prof, warnlevel, idletime, class, membersince, onlinesince); | |
| 214 | ||
| 215 | free(sn); | |
| 216 | free(prof_encoding); | |
| 217 | free(prof); | |
| 218 | ||
| 219 | return i; | |
| 220 | } |