Mercurial > pidgin
annotate libfaim/aim_tlv.c @ 782:faa7faf60607
[gaim-migrate @ 792]
Plugins can communicate because the GList *plugins variable is global.
committer: Tailor Script <tailor@pidgin.im>
| author | Eric Warmenhoven <eric@warmenhoven.org> |
|---|---|
| date | Tue, 29 Aug 2000 04:38:41 +0000 |
| parents | 72e556f6b99d |
| children | f425f51a3db8 |
| rev | line source |
|---|---|
|
283
0f14e6d8a51b
[gaim-migrate @ 293]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
237
diff
changeset
|
1 #include <faim/aim.h> |
| 2 | 2 |
| 237 | 3 struct aim_tlvlist_t *aim_readtlvchain(u_char *buf, int maxlen) |
| 4 { | |
| 5 int pos; | |
| 6 struct aim_tlvlist_t *list; | |
| 7 struct aim_tlvlist_t *cur; | |
| 8 | |
| 9 u_short type; | |
| 10 u_short length; | |
| 11 | |
| 12 if (!buf) | |
| 13 return NULL; | |
| 14 | |
| 15 list = NULL; | |
| 16 | |
| 17 pos = 0; | |
| 18 | |
| 19 while (pos < maxlen) | |
| 20 { | |
| 21 type = aimutil_get16(buf+pos); | |
| 22 pos += 2; | |
| 23 | |
| 24 if (pos < maxlen) | |
| 25 { | |
| 26 length = aimutil_get16(buf+pos); | |
| 27 pos += 2; | |
| 28 | |
| 29 if ((pos+length) <= maxlen) | |
| 30 { | |
|
446
6d78b988b479
[gaim-migrate @ 456]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
31 /* |
|
6d78b988b479
[gaim-migrate @ 456]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
32 * Okay, so now AOL has decided that any TLV of |
|
6d78b988b479
[gaim-migrate @ 456]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
33 * type 0x0013 can only be two bytes, despite |
|
6d78b988b479
[gaim-migrate @ 456]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
34 * what the actual given length is. So here |
|
6d78b988b479
[gaim-migrate @ 456]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
35 * we dump any invalid TLVs of that sort. Hopefully |
|
6d78b988b479
[gaim-migrate @ 456]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
36 * theres no special cases to this special case. |
|
6d78b988b479
[gaim-migrate @ 456]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
37 * - mid (30jun2000) |
|
6d78b988b479
[gaim-migrate @ 456]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
38 */ |
|
6d78b988b479
[gaim-migrate @ 456]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
39 if ((type == 0x0013) && (length != 0x0002)) { |
|
6d78b988b479
[gaim-migrate @ 456]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
40 printf("faim: skipping TLV t(0013) with invalid length (0x%04x)\n", length); |
|
6d78b988b479
[gaim-migrate @ 456]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
41 length = 0x0002; |
|
6d78b988b479
[gaim-migrate @ 456]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
42 } else { |
|
6d78b988b479
[gaim-migrate @ 456]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
43 cur = (struct aim_tlvlist_t *)malloc(sizeof(struct aim_tlvlist_t)); |
|
6d78b988b479
[gaim-migrate @ 456]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
44 memset(cur, 0x00, sizeof(struct aim_tlvlist_t)); |
| 237 | 45 |
|
446
6d78b988b479
[gaim-migrate @ 456]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
46 cur->tlv = aim_createtlv(); |
|
6d78b988b479
[gaim-migrate @ 456]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
47 cur->tlv->type = type; |
|
6d78b988b479
[gaim-migrate @ 456]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
48 cur->tlv->length = length; |
|
6d78b988b479
[gaim-migrate @ 456]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
49 cur->tlv->value = (u_char *)malloc(length*sizeof(u_char)); |
|
6d78b988b479
[gaim-migrate @ 456]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
50 memcpy(cur->tlv->value, buf+pos, length); |
|
771
72e556f6b99d
[gaim-migrate @ 781]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
446
diff
changeset
|
51 |
|
446
6d78b988b479
[gaim-migrate @ 456]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
52 cur->next = list; |
|
6d78b988b479
[gaim-migrate @ 456]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
53 list = cur; |
|
6d78b988b479
[gaim-migrate @ 456]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
54 } |
| 237 | 55 pos += length; |
| 56 } | |
| 57 } | |
| 58 } | |
| 59 | |
| 60 return list; | |
| 61 } | |
| 62 | |
| 63 void aim_freetlvchain(struct aim_tlvlist_t **list) | |
| 64 { | |
| 65 struct aim_tlvlist_t *cur, *cur2; | |
| 66 | |
| 67 if (!list || !(*list)) | |
| 68 return; | |
| 69 | |
| 70 cur = *list; | |
| 71 while (cur) | |
| 72 { | |
| 73 aim_freetlv(&cur->tlv); | |
| 74 cur2 = cur->next; | |
| 75 free(cur); | |
| 76 cur = cur2; | |
| 77 } | |
| 78 list = NULL; | |
| 79 return; | |
| 80 } | |
| 81 | |
| 82 int aim_counttlvchain(struct aim_tlvlist_t **list) | |
| 83 { | |
| 84 struct aim_tlvlist_t *cur; | |
| 85 int count = 0; | |
| 86 | |
| 87 if (!list || !(*list)) | |
| 88 return 0; | |
| 89 | |
| 90 for (cur = *list; cur; cur = cur->next) | |
| 91 count++; | |
| 92 | |
| 93 return count; | |
| 94 } | |
| 95 | |
| 96 int aim_addtlvtochain_str(struct aim_tlvlist_t **list, unsigned short type, char *str, int len) | |
| 97 { | |
| 98 struct aim_tlvlist_t *new; | |
| 99 struct aim_tlvlist_t *cur; | |
| 100 | |
| 101 if (!list) | |
| 102 return 0; | |
| 103 | |
| 104 new = (struct aim_tlvlist_t *)malloc(sizeof(struct aim_tlvlist_t)); | |
| 105 memset(new, 0x00, sizeof(struct aim_tlvlist_t)); | |
| 106 | |
| 107 new->tlv = aim_createtlv(); | |
| 108 new->tlv->type = type; | |
| 109 new->tlv->length = len; | |
| 110 new->tlv->value = (u_char *)malloc(new->tlv->length*sizeof(u_char)); | |
| 111 memcpy(new->tlv->value, str, new->tlv->length); | |
| 112 | |
| 113 new->next = NULL; | |
| 114 | |
| 115 if (*list == NULL) { | |
| 116 *list = new; | |
| 117 } else if ((*list)->next == NULL) { | |
| 118 (*list)->next = new; | |
| 119 } else { | |
| 120 for(cur = *list; cur->next; cur = cur->next) | |
| 121 ; | |
| 122 cur->next = new; | |
| 123 } | |
| 124 return new->tlv->length; | |
| 125 } | |
| 126 | |
| 127 int aim_addtlvtochain16(struct aim_tlvlist_t **list, unsigned short type, unsigned short val) | |
| 128 { | |
| 129 struct aim_tlvlist_t *new; | |
| 130 struct aim_tlvlist_t *cur; | |
| 131 | |
| 132 if (!list) | |
| 133 return 0; | |
| 134 | |
| 135 new = (struct aim_tlvlist_t *)malloc(sizeof(struct aim_tlvlist_t)); | |
| 136 memset(new, 0x00, sizeof(struct aim_tlvlist_t)); | |
| 137 | |
| 138 new->tlv = aim_createtlv(); | |
| 139 new->tlv->type = type; | |
| 140 new->tlv->length = 2; | |
| 141 new->tlv->value = (u_char *)malloc(new->tlv->length*sizeof(u_char)); | |
| 142 aimutil_put16(new->tlv->value, val); | |
| 143 | |
| 144 new->next = NULL; | |
| 145 | |
| 146 if (*list == NULL) { | |
| 147 *list = new; | |
| 148 } else if ((*list)->next == NULL) { | |
| 149 (*list)->next = new; | |
| 150 } else { | |
| 151 for(cur = *list; cur->next; cur = cur->next) | |
| 152 ; | |
| 153 cur->next = new; | |
| 154 } | |
| 155 return 2; | |
| 156 } | |
| 157 | |
| 158 int aim_addtlvtochain32(struct aim_tlvlist_t **list, unsigned short type, unsigned long val) | |
| 159 { | |
| 160 struct aim_tlvlist_t *new; | |
| 161 struct aim_tlvlist_t *cur; | |
| 162 | |
| 163 if (!list) | |
| 164 return 0; | |
| 165 | |
| 166 new = (struct aim_tlvlist_t *)malloc(sizeof(struct aim_tlvlist_t)); | |
| 167 memset(new, 0x00, sizeof(struct aim_tlvlist_t)); | |
| 168 | |
| 169 new->tlv = aim_createtlv(); | |
| 170 new->tlv->type = type; | |
| 171 new->tlv->length = 4; | |
| 172 new->tlv->value = (u_char *)malloc(new->tlv->length*sizeof(u_char)); | |
| 173 aimutil_put32(new->tlv->value, val); | |
| 174 | |
| 175 new->next = NULL; | |
| 176 | |
| 177 if (*list == NULL) { | |
| 178 *list = new; | |
| 179 } else if ((*list)->next == NULL) { | |
| 180 (*list)->next = new; | |
| 181 } else { | |
| 182 for(cur = *list; cur->next; cur = cur->next) | |
| 183 ; | |
| 184 cur->next = new; | |
| 185 } | |
| 186 return 4; | |
| 187 } | |
| 188 | |
| 189 int aim_writetlvchain(u_char *buf, int buflen, struct aim_tlvlist_t **list) | |
| 190 { | |
| 191 int goodbuflen = 0; | |
| 192 int i = 0; | |
| 193 struct aim_tlvlist_t *cur; | |
| 194 | |
| 195 if (!list || !buf || !buflen) | |
| 196 return 0; | |
| 197 | |
| 198 /* do an initial run to test total length */ | |
| 199 for (cur = *list; cur; cur = cur->next) { | |
| 200 goodbuflen += 2 + 2; /* type + len */ | |
| 201 goodbuflen += cur->tlv->length; | |
| 202 } | |
| 203 | |
| 204 if (goodbuflen > buflen) | |
| 205 return 0; /* not enough buffer */ | |
| 206 | |
| 207 /* do the real write-out */ | |
| 208 for (cur = *list; cur; cur = cur->next) { | |
| 209 i += aimutil_put16(buf+i, cur->tlv->type); | |
| 210 i += aimutil_put16(buf+i, cur->tlv->length); | |
| 211 memcpy(buf+i, cur->tlv->value, cur->tlv->length); | |
| 212 i += cur->tlv->length; | |
| 213 } | |
| 214 | |
| 215 return i; | |
| 216 } | |
| 217 | |
| 218 | |
| 219 /* | |
| 220 * Grab the Nth TLV of type type in the TLV list list. | |
| 221 */ | |
| 222 struct aim_tlv_t *aim_gettlv(struct aim_tlvlist_t *list, u_short type, int nth) | |
| 223 { | |
| 224 int i; | |
| 225 struct aim_tlvlist_t *cur; | |
| 226 | |
| 227 i = 0; | |
| 228 for (cur = list; cur != NULL; cur = cur->next) | |
| 229 { | |
| 230 if (cur && cur->tlv) | |
| 231 { | |
| 232 if (cur->tlv->type == type) | |
| 233 i++; | |
| 234 if (i >= nth) | |
| 235 return cur->tlv; | |
| 236 } | |
| 237 } | |
| 238 return NULL; | |
| 239 } | |
| 240 | |
| 241 char *aim_gettlv_str(struct aim_tlvlist_t *list, u_short type, int nth) | |
| 242 { | |
| 243 struct aim_tlv_t *tlv; | |
| 244 char *newstr; | |
| 245 | |
| 246 if (!(tlv = aim_gettlv(list, type, nth))) | |
| 247 return NULL; | |
| 248 | |
| 249 newstr = (char *) malloc(tlv->length + 1); | |
| 250 memcpy(newstr, tlv->value, tlv->length); | |
| 251 *(newstr + tlv->length) = '\0'; | |
| 252 | |
| 253 return newstr; | |
| 254 } | |
| 255 | |
| 2 | 256 struct aim_tlv_t *aim_grabtlv(u_char *src) |
| 257 { | |
| 258 struct aim_tlv_t *dest = NULL; | |
| 259 | |
| 260 dest = aim_createtlv(); | |
| 261 | |
| 262 dest->type = src[0] << 8; | |
| 263 dest->type += src[1]; | |
| 264 | |
| 265 dest->length = src[2] << 8; | |
| 266 dest->length += src[3]; | |
| 267 | |
| 268 dest->value = (u_char *) malloc(dest->length*sizeof(u_char)); | |
| 269 memset(dest->value, 0, dest->length*sizeof(u_char)); | |
| 270 | |
| 271 memcpy(dest->value, &(src[4]), dest->length*sizeof(u_char)); | |
| 272 | |
| 273 return dest; | |
| 274 } | |
| 275 | |
| 276 struct aim_tlv_t *aim_grabtlvstr(u_char *src) | |
| 277 { | |
| 278 struct aim_tlv_t *dest = NULL; | |
| 279 | |
| 280 dest = aim_createtlv(); | |
| 281 | |
| 282 dest->type = src[0] << 8; | |
| 283 dest->type += src[1]; | |
| 284 | |
| 285 dest->length = src[2] << 8; | |
| 286 dest->length += src[3]; | |
| 287 | |
| 288 dest->value = (u_char *) malloc((dest->length+1)*sizeof(u_char)); | |
| 289 memset(dest->value, 0, (dest->length+1)*sizeof(u_char)); | |
| 290 | |
| 291 memcpy(dest->value, &(src[4]), dest->length*sizeof(u_char)); | |
| 292 dest->value[dest->length] = '\0'; | |
| 293 | |
| 294 return dest; | |
| 295 } | |
| 296 | |
| 297 int aim_puttlv (u_char *dest, struct aim_tlv_t *newtlv) | |
| 298 { | |
| 299 int i=0; | |
| 300 | |
| 301 dest[i++] = newtlv->type >> 8; | |
| 302 dest[i++] = newtlv->type & 0x00FF; | |
| 303 dest[i++] = newtlv->length >> 8; | |
| 304 dest[i++] = newtlv->length & 0x00FF; | |
| 305 memcpy(&(dest[i]), newtlv->value, newtlv->length); | |
| 306 i+=newtlv->length; | |
| 307 return i; | |
| 308 } | |
| 309 | |
| 310 struct aim_tlv_t *aim_createtlv(void) | |
| 311 { | |
| 312 struct aim_tlv_t *newtlv = NULL; | |
| 313 newtlv = (struct aim_tlv_t *)malloc(sizeof(struct aim_tlv_t)); | |
| 314 memset(newtlv, 0, sizeof(struct aim_tlv_t)); | |
| 315 return newtlv; | |
| 316 } | |
| 317 | |
| 318 int aim_freetlv(struct aim_tlv_t **oldtlv) | |
| 319 { | |
| 320 if (!oldtlv) | |
| 321 return -1; | |
| 322 if (!*oldtlv) | |
| 323 return -1; | |
| 324 if ((*oldtlv)->value) | |
| 325 free((*oldtlv)->value); | |
| 326 free(*(oldtlv)); | |
| 327 (*oldtlv) = NULL; | |
| 328 | |
| 329 return 0; | |
| 330 } | |
| 331 | |
| 332 int aim_puttlv_16(u_char *buf, u_short t, u_short v) | |
| 333 { | |
| 334 int curbyte=0; | |
| 237 | 335 curbyte += aimutil_put16(buf+curbyte, (u_short)(t&0xffff)); |
| 336 curbyte += aimutil_put16(buf+curbyte, (u_short)0x0002); | |
| 337 curbyte += aimutil_put16(buf+curbyte, (u_short)(v&0xffff)); | |
| 338 return curbyte; | |
| 339 } | |
| 340 | |
| 341 int aim_puttlv_32(u_char *buf, u_short t, u_long v) | |
| 342 { | |
| 343 int curbyte=0; | |
| 344 curbyte += aimutil_put16(buf+curbyte, (u_short)(t&0xffff)); | |
| 345 curbyte += aimutil_put16(buf+curbyte, (u_short)0x0004); | |
| 346 curbyte += aimutil_put32(buf+curbyte, (u_long)(v&0xffffffff)); | |
| 2 | 347 return curbyte; |
| 348 } | |
| 237 | 349 |
| 350 int aim_puttlv_str(u_char *buf, u_short t, u_short l, u_char *v) | |
| 351 { | |
| 352 int curbyte; | |
| 353 | |
| 354 curbyte = 0; | |
| 355 curbyte += aimutil_put16(buf+curbyte, (u_short)(t&0xffff)); | |
| 356 curbyte += aimutil_put16(buf+curbyte, (u_short)(l&0xffff)); | |
| 357 if (v) | |
| 358 memcpy(buf+curbyte, v, l); | |
| 359 curbyte += l; | |
| 360 return curbyte; | |
| 361 } |
