Mercurial > pidgin
annotate src/protocols/oscar/tlv.c @ 9125:668ffb8fec00
[gaim-migrate @ 9902]
(12:53:05) nosnilmot: LSchiere: not majorly important, but the pref changes
listed in the ChangeLog are out of sync
committer: Tailor Script <tailor@pidgin.im>
| author | Luke Schierer <lschiere@pidgin.im> |
|---|---|
| date | Sun, 30 May 2004 16:54:40 +0000 |
| parents | 4048e93b8ece |
| children | cee849d17167 |
| rev | line source |
|---|---|
| 2086 | 1 |
| 2 #define FAIM_INTERNAL | |
| 3 #include <aim.h> | |
| 4 | |
| 7158 | 5 static aim_tlv_t *createtlv(fu16_t type, fu16_t length, fu8_t *value) |
|
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
6 { |
| 7158 | 7 aim_tlv_t *ret; |
|
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
8 |
| 7158 | 9 if (!(ret = (aim_tlv_t *)malloc(sizeof(aim_tlv_t)))) |
|
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
10 return NULL; |
| 7158 | 11 ret->type = type; |
| 12 ret->length = length; | |
| 13 ret->value = value; | |
|
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
14 |
| 7158 | 15 return ret; |
|
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
16 } |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
17 |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
18 static void freetlv(aim_tlv_t **oldtlv) |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
19 { |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
20 |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
21 if (!oldtlv || !*oldtlv) |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
22 return; |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
23 |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
24 free((*oldtlv)->value); |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
25 free(*oldtlv); |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
26 *oldtlv = NULL; |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
27 |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
28 return; |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
29 } |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
30 |
| 2086 | 31 /** |
| 7167 | 32 * Read a TLV chain from a buffer. |
| 2086 | 33 * |
| 34 * Reads and parses a series of TLV patterns from a data buffer; the | |
| 35 * returned structure is manipulatable with the rest of the TLV | |
| 7167 | 36 * routines. When done with a TLV chain, aim_tlvlist_free() should |
| 2086 | 37 * be called to free the dynamic substructures. |
| 38 * | |
|
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
39 * XXX There should be a flag setable here to have the tlvlist contain |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
40 * bstream references, so that at least the ->value portion of each |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
41 * element doesn't need to be malloc/memcpy'd. This could prove to be |
|
8735
92cbf9713795
[gaim-migrate @ 9490]
Christian Hammond <chipx86@chipx86.com>
parents:
8225
diff
changeset
|
42 * just as efficient as the in-place TLV parsing used in a couple places |
|
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
43 * in libfaim. |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
44 * |
| 7158 | 45 * @param bs Input bstream |
| 8790 | 46 * @return Return the TLV chain read |
| 2086 | 47 */ |
| 7167 | 48 faim_internal aim_tlvlist_t *aim_tlvlist_read(aim_bstream_t *bs) |
| 2086 | 49 { |
|
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
50 aim_tlvlist_t *list = NULL, *cur; |
| 3459 | 51 |
| 52 while (aim_bstream_empty(bs) > 0) { | |
| 53 fu16_t type, length; | |
| 2086 | 54 |
|
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
55 type = aimbs_get16(bs); |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
56 length = aimbs_get16(bs); |
| 2086 | 57 |
|
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
58 #if 0 /* temporarily disabled until I know if they're still doing it or not */ |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
59 /* |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
60 * Okay, so now AOL has decided that any TLV of |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
61 * type 0x0013 can only be two bytes, despite |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
62 * what the actual given length is. So here |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
63 * we dump any invalid TLVs of that sort. Hopefully |
|
8735
92cbf9713795
[gaim-migrate @ 9490]
Christian Hammond <chipx86@chipx86.com>
parents:
8225
diff
changeset
|
64 * there's no special cases to this special case. |
|
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
65 * - mid (30jun2000) |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
66 */ |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
67 if ((type == 0x0013) && (length != 0x0002)) |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
68 length = 0x0002; |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
69 #else |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
70 if (0) |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
71 ; |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
72 #endif |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
73 else { |
| 2086 | 74 |
| 3459 | 75 if (length > aim_bstream_empty(bs)) { |
| 7167 | 76 aim_tlvlist_free(&list); |
| 3459 | 77 return NULL; |
| 78 } | |
| 79 | |
|
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
80 cur = (aim_tlvlist_t *)malloc(sizeof(aim_tlvlist_t)); |
| 3459 | 81 if (!cur) { |
| 7167 | 82 aim_tlvlist_free(&list); |
| 3459 | 83 return NULL; |
| 84 } | |
| 85 | |
|
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
86 memset(cur, 0, sizeof(aim_tlvlist_t)); |
| 2086 | 87 |
| 7158 | 88 cur->tlv = createtlv(type, length, NULL); |
| 3459 | 89 if (!cur->tlv) { |
| 90 free(cur); | |
| 7167 | 91 aim_tlvlist_free(&list); |
| 3459 | 92 return NULL; |
| 93 } | |
| 7158 | 94 if (cur->tlv->length > 0) { |
| 95 cur->tlv->value = aimbs_getraw(bs, length); | |
| 96 if (!cur->tlv->value) { | |
| 97 freetlv(&cur->tlv); | |
| 98 free(cur); | |
| 7167 | 99 aim_tlvlist_free(&list); |
| 7158 | 100 return NULL; |
| 101 } | |
| 3459 | 102 } |
|
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
103 |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
104 cur->next = list; |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
105 list = cur; |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
106 } |
| 2086 | 107 } |
| 108 | |
|
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
109 return list; |
| 2086 | 110 } |
| 111 | |
| 112 /** | |
| 7167 | 113 * Read a TLV chain from a buffer. |
| 4230 | 114 * |
| 3952 | 115 * Reads and parses a series of TLV patterns from a data buffer; the |
| 116 * returned structure is manipulatable with the rest of the TLV | |
| 7167 | 117 * routines. When done with a TLV chain, aim_tlvlist_free() should |
| 3952 | 118 * be called to free the dynamic substructures. |
| 119 * | |
| 120 * XXX There should be a flag setable here to have the tlvlist contain | |
| 121 * bstream references, so that at least the ->value portion of each | |
| 122 * element doesn't need to be malloc/memcpy'd. This could prove to be | |
|
8735
92cbf9713795
[gaim-migrate @ 9490]
Christian Hammond <chipx86@chipx86.com>
parents:
8225
diff
changeset
|
123 * just as efficient as the in-place TLV parsing used in a couple places |
| 3952 | 124 * in libfaim. |
| 125 * | |
| 7158 | 126 * @param bs Input bstream |
| 127 * @param num The max number of TLVs that will be read, or -1 if unlimited. | |
| 128 * There are a number of places where you want to read in a tlvchain, | |
| 129 * but the chain is not at the end of the SNAC, and the chain is | |
|
8735
92cbf9713795
[gaim-migrate @ 9490]
Christian Hammond <chipx86@chipx86.com>
parents:
8225
diff
changeset
|
130 * preceded by the number of TLVs. So you can limit that with this. |
| 8790 | 131 * @return Return the TLV chain read |
| 3952 | 132 */ |
| 7167 | 133 faim_internal aim_tlvlist_t *aim_tlvlist_readnum(aim_bstream_t *bs, fu16_t num) |
| 3952 | 134 { |
| 135 aim_tlvlist_t *list = NULL, *cur; | |
| 4317 | 136 |
| 3952 | 137 while ((aim_bstream_empty(bs) > 0) && (num != 0)) { |
| 138 fu16_t type, length; | |
| 139 | |
| 140 type = aimbs_get16(bs); | |
| 141 length = aimbs_get16(bs); | |
| 142 | |
| 143 if (length > aim_bstream_empty(bs)) { | |
| 7167 | 144 aim_tlvlist_free(&list); |
| 3952 | 145 return NULL; |
| 146 } | |
| 147 | |
| 148 cur = (aim_tlvlist_t *)malloc(sizeof(aim_tlvlist_t)); | |
| 149 if (!cur) { | |
| 7167 | 150 aim_tlvlist_free(&list); |
| 3952 | 151 return NULL; |
| 152 } | |
| 153 | |
| 154 memset(cur, 0, sizeof(aim_tlvlist_t)); | |
| 155 | |
| 7158 | 156 cur->tlv = createtlv(type, length, NULL); |
| 3952 | 157 if (!cur->tlv) { |
| 158 free(cur); | |
| 7167 | 159 aim_tlvlist_free(&list); |
| 3952 | 160 return NULL; |
| 161 } | |
| 7158 | 162 if (cur->tlv->length > 0) { |
| 163 cur->tlv->value = aimbs_getraw(bs, length); | |
| 164 if (!cur->tlv->value) { | |
| 165 freetlv(&cur->tlv); | |
| 166 free(cur); | |
| 7167 | 167 aim_tlvlist_free(&list); |
| 7158 | 168 return NULL; |
| 169 } | |
| 3952 | 170 } |
| 171 | |
| 7158 | 172 if (num > 0) |
| 173 num--; | |
| 3952 | 174 cur->next = list; |
| 175 list = cur; | |
| 176 } | |
| 177 | |
| 178 return list; | |
| 179 } | |
| 180 | |
| 181 /** | |
| 7167 | 182 * Read a TLV chain from a buffer. |
| 4230 | 183 * |
| 184 * Reads and parses a series of TLV patterns from a data buffer; the | |
| 185 * returned structure is manipulatable with the rest of the TLV | |
| 7167 | 186 * routines. When done with a TLV chain, aim_tlvlist_free() should |
| 4230 | 187 * be called to free the dynamic substructures. |
| 188 * | |
| 189 * XXX There should be a flag setable here to have the tlvlist contain | |
| 190 * bstream references, so that at least the ->value portion of each | |
| 191 * element doesn't need to be malloc/memcpy'd. This could prove to be | |
|
8735
92cbf9713795
[gaim-migrate @ 9490]
Christian Hammond <chipx86@chipx86.com>
parents:
8225
diff
changeset
|
192 * just as efficient as the in-place TLV parsing used in a couple places |
| 4230 | 193 * in libfaim. |
| 194 * | |
| 7158 | 195 * @param bs Input bstream |
| 196 * @param len The max length in bytes that will be read. | |
| 197 * There are a number of places where you want to read in a tlvchain, | |
| 198 * but the chain is not at the end of the SNAC, and the chain is | |
|
8735
92cbf9713795
[gaim-migrate @ 9490]
Christian Hammond <chipx86@chipx86.com>
parents:
8225
diff
changeset
|
199 * preceded by the length of the TLVs. So you can limit that with this. |
| 8790 | 200 * @return Return the TLV chain read |
| 4230 | 201 */ |
| 7167 | 202 faim_internal aim_tlvlist_t *aim_tlvlist_readlen(aim_bstream_t *bs, fu16_t len) |
| 4230 | 203 { |
| 204 aim_tlvlist_t *list = NULL, *cur; | |
| 4317 | 205 |
| 4230 | 206 while ((aim_bstream_empty(bs) > 0) && (len > 0)) { |
| 207 fu16_t type, length; | |
| 208 | |
| 209 type = aimbs_get16(bs); | |
| 210 length = aimbs_get16(bs); | |
| 211 | |
| 212 if (length > aim_bstream_empty(bs)) { | |
| 7167 | 213 aim_tlvlist_free(&list); |
| 4230 | 214 return NULL; |
| 215 } | |
| 216 | |
| 217 cur = (aim_tlvlist_t *)malloc(sizeof(aim_tlvlist_t)); | |
| 218 if (!cur) { | |
| 7167 | 219 aim_tlvlist_free(&list); |
| 4230 | 220 return NULL; |
| 221 } | |
| 222 | |
| 223 memset(cur, 0, sizeof(aim_tlvlist_t)); | |
| 224 | |
| 7158 | 225 cur->tlv = createtlv(type, length, NULL); |
| 4230 | 226 if (!cur->tlv) { |
| 227 free(cur); | |
| 7167 | 228 aim_tlvlist_free(&list); |
| 4230 | 229 return NULL; |
| 230 } | |
| 7158 | 231 if (cur->tlv->length > 0) { |
| 232 cur->tlv->value = aimbs_getraw(bs, length); | |
| 233 if (!cur->tlv->value) { | |
| 234 freetlv(&cur->tlv); | |
| 235 free(cur); | |
| 7167 | 236 aim_tlvlist_free(&list); |
| 7158 | 237 return NULL; |
| 238 } | |
| 4230 | 239 } |
| 240 | |
| 7167 | 241 len -= aim_tlvlist_size(&cur); |
| 4230 | 242 cur->next = list; |
| 243 list = cur; | |
| 244 } | |
| 245 | |
| 246 return list; | |
| 247 } | |
| 248 | |
| 249 /** | |
| 7167 | 250 * Duplicate a TLV chain. |
|
8735
92cbf9713795
[gaim-migrate @ 9490]
Christian Hammond <chipx86@chipx86.com>
parents:
8225
diff
changeset
|
251 * This is pretty self explanatory. |
| 4230 | 252 * |
| 7158 | 253 * @param orig The TLV chain you want to make a copy of. |
| 254 * @return A newly allocated TLV chain. | |
| 4230 | 255 */ |
| 256 faim_internal aim_tlvlist_t *aim_tlvlist_copy(aim_tlvlist_t *orig) | |
| 257 { | |
| 258 aim_tlvlist_t *new = NULL; | |
| 259 | |
| 260 while (orig) { | |
| 7167 | 261 aim_tlvlist_add_raw(&new, orig->tlv->type, orig->tlv->length, orig->tlv->value); |
| 4230 | 262 orig = orig->next; |
| 263 } | |
| 264 | |
| 265 return new; | |
| 266 } | |
| 267 | |
| 6101 | 268 /* |
| 269 * Compare two TLV lists for equality. This probably is not the most | |
| 270 * efficient way to do this. | |
| 271 * | |
| 272 * @param one One of the TLV chains to compare. | |
| 273 * @param two The other TLV chain to compare. | |
| 8790 | 274 * @return Return 0 if the lists are the same, return 1 if they are different. |
| 6101 | 275 */ |
| 276 faim_internal int aim_tlvlist_cmp(aim_tlvlist_t *one, aim_tlvlist_t *two) | |
| 277 { | |
| 278 aim_bstream_t bs1, bs2; | |
| 279 | |
| 7167 | 280 if (aim_tlvlist_size(&one) != aim_tlvlist_size(&two)) |
| 6101 | 281 return 1; |
| 282 | |
| 7167 | 283 aim_bstream_init(&bs1, ((fu8_t *)malloc(aim_tlvlist_size(&one)*sizeof(fu8_t))), aim_tlvlist_size(&one)); |
| 284 aim_bstream_init(&bs2, ((fu8_t *)malloc(aim_tlvlist_size(&two)*sizeof(fu8_t))), aim_tlvlist_size(&two)); | |
| 6101 | 285 |
| 7167 | 286 aim_tlvlist_write(&bs1, &one); |
| 287 aim_tlvlist_write(&bs2, &two); | |
| 6101 | 288 |
| 289 if (memcmp(bs1.data, bs2.data, bs1.len)) { | |
| 290 free(bs1.data); | |
| 291 free(bs2.data); | |
| 292 return 1; | |
| 293 } | |
| 294 | |
| 295 free(bs1.data); | |
| 296 free(bs2.data); | |
| 297 | |
| 298 return 0; | |
| 299 } | |
| 300 | |
| 4230 | 301 /** |
| 7167 | 302 * Free a TLV chain structure |
| 2086 | 303 * |
| 304 * Walks the list of TLVs in the passed TLV chain and | |
| 305 * frees each one. Note that any references to this data | |
| 306 * should be removed before calling this. | |
| 307 * | |
| 8790 | 308 * @param list Chain to be freed |
| 2086 | 309 */ |
| 7167 | 310 faim_internal void aim_tlvlist_free(aim_tlvlist_t **list) |
| 2086 | 311 { |
|
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
312 aim_tlvlist_t *cur; |
| 2086 | 313 |
|
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
314 if (!list || !*list) |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
315 return; |
| 2086 | 316 |
|
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
317 for (cur = *list; cur; ) { |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
318 aim_tlvlist_t *tmp; |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
319 |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
320 freetlv(&cur->tlv); |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
321 |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
322 tmp = cur->next; |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
323 free(cur); |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
324 cur = tmp; |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
325 } |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
326 |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
327 list = NULL; |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
328 |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
329 return; |
| 2086 | 330 } |
| 331 | |
| 332 /** | |
| 7167 | 333 * Count the number of TLVs in a chain. |
| 2086 | 334 * |
| 7167 | 335 * @param list Chain to be counted. |
| 336 * @return The number of TLVs stored in the passed chain. | |
| 2086 | 337 */ |
| 7167 | 338 faim_internal int aim_tlvlist_count(aim_tlvlist_t **list) |
| 2086 | 339 { |
|
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
340 aim_tlvlist_t *cur; |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
341 int count; |
| 2086 | 342 |
|
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
343 if (!list || !*list) |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
344 return 0; |
| 2086 | 345 |
|
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
346 for (cur = *list, count = 0; cur; cur = cur->next) |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
347 count++; |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
348 |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
349 return count; |
| 2086 | 350 } |
| 351 | |
| 352 /** | |
| 7167 | 353 * Count the number of bytes in a TLV chain. |
| 2086 | 354 * |
| 7167 | 355 * @param list Chain to be sized |
| 356 * @return The number of bytes that would be needed to | |
| 357 * write the passed TLV chain to a data buffer. | |
| 2086 | 358 */ |
| 7167 | 359 faim_internal int aim_tlvlist_size(aim_tlvlist_t **list) |
| 2086 | 360 { |
|
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
361 aim_tlvlist_t *cur; |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
362 int size; |
| 2086 | 363 |
|
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
364 if (!list || !*list) |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
365 return 0; |
| 2086 | 366 |
|
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
367 for (cur = *list, size = 0; cur; cur = cur->next) |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
368 size += (4 + cur->tlv->length); |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
369 |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
370 return size; |
| 2086 | 371 } |
| 372 | |
| 373 /** | |
| 374 * Adds the passed string as a TLV element of the passed type | |
| 375 * to the TLV chain. | |
| 376 * | |
| 7167 | 377 * @param list Desination chain (%NULL pointer if empty). |
| 378 * @param type TLV type. | |
| 8790 | 379 * @param length Length of string to add (not including %NULL). |
| 380 * @param value String to add. | |
|
8735
92cbf9713795
[gaim-migrate @ 9490]
Christian Hammond <chipx86@chipx86.com>
parents:
8225
diff
changeset
|
381 * @return The size of the value added. |
| 2086 | 382 */ |
| 7167 | 383 faim_internal int aim_tlvlist_add_raw(aim_tlvlist_t **list, const fu16_t type, const fu16_t length, const fu8_t *value) |
| 2086 | 384 { |
|
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
385 aim_tlvlist_t *newtlv, *cur; |
| 2086 | 386 |
| 7166 | 387 if (list == NULL) |
|
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
388 return 0; |
| 2086 | 389 |
|
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
390 if (!(newtlv = (aim_tlvlist_t *)malloc(sizeof(aim_tlvlist_t)))) |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
391 return 0; |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
392 memset(newtlv, 0x00, sizeof(aim_tlvlist_t)); |
| 2086 | 393 |
| 7158 | 394 if (!(newtlv->tlv = createtlv(type, length, NULL))) { |
|
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
395 free(newtlv); |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
396 return 0; |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
397 } |
| 7158 | 398 if (newtlv->tlv->length > 0) { |
|
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
399 newtlv->tlv->value = (fu8_t *)malloc(newtlv->tlv->length); |
| 7158 | 400 memcpy(newtlv->tlv->value, value, newtlv->tlv->length); |
|
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
401 } |
| 2086 | 402 |
|
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
403 if (!*list) |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
404 *list = newtlv; |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
405 else { |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
406 for(cur = *list; cur->next; cur = cur->next) |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
407 ; |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
408 cur->next = newtlv; |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
409 } |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
410 |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
411 return newtlv->tlv->length; |
| 2086 | 412 } |
| 413 | |
| 414 /** | |
| 7167 | 415 * Add a one byte integer to a TLV chain. |
|
2821
9467e4ee81be
[gaim-migrate @ 2834]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2421
diff
changeset
|
416 * |
| 7167 | 417 * @param list Destination chain. |
| 418 * @param type TLV type to add. | |
| 419 * @param value Value to add. | |
|
8735
92cbf9713795
[gaim-migrate @ 9490]
Christian Hammond <chipx86@chipx86.com>
parents:
8225
diff
changeset
|
420 * @return The size of the value added. |
|
2821
9467e4ee81be
[gaim-migrate @ 2834]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2421
diff
changeset
|
421 */ |
| 7167 | 422 faim_internal int aim_tlvlist_add_8(aim_tlvlist_t **list, const fu16_t type, const fu8_t value) |
|
2821
9467e4ee81be
[gaim-migrate @ 2834]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2421
diff
changeset
|
423 { |
|
9467e4ee81be
[gaim-migrate @ 2834]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2421
diff
changeset
|
424 fu8_t v8[1]; |
|
9467e4ee81be
[gaim-migrate @ 2834]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2421
diff
changeset
|
425 |
| 7167 | 426 aimutil_put8(v8, value); |
|
2821
9467e4ee81be
[gaim-migrate @ 2834]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2421
diff
changeset
|
427 |
| 7167 | 428 return aim_tlvlist_add_raw(list, type, 1, v8); |
|
2821
9467e4ee81be
[gaim-migrate @ 2834]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2421
diff
changeset
|
429 } |
|
9467e4ee81be
[gaim-migrate @ 2834]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2421
diff
changeset
|
430 |
|
9467e4ee81be
[gaim-migrate @ 2834]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2421
diff
changeset
|
431 /** |
| 7167 | 432 * Add a two byte integer to a TLV chain. |
| 2086 | 433 * |
| 7167 | 434 * @param list Destination chain. |
| 435 * @param type TLV type to add. | |
| 436 * @param value Value to add. | |
|
8735
92cbf9713795
[gaim-migrate @ 9490]
Christian Hammond <chipx86@chipx86.com>
parents:
8225
diff
changeset
|
437 * @return The size of the value added. |
| 2086 | 438 */ |
| 7167 | 439 faim_internal int aim_tlvlist_add_16(aim_tlvlist_t **list, const fu16_t type, const fu16_t value) |
| 2086 | 440 { |
|
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
441 fu8_t v16[2]; |
| 2086 | 442 |
| 7167 | 443 aimutil_put16(v16, value); |
| 2086 | 444 |
| 7167 | 445 return aim_tlvlist_add_raw(list, type, 2, v16); |
| 2086 | 446 } |
| 447 | |
| 448 /** | |
| 7167 | 449 * Add a four byte integer to a TLV chain. |
| 2086 | 450 * |
| 7167 | 451 * @param list Destination chain. |
| 452 * @param type TLV type to add. | |
| 453 * @param value Value to add. | |
|
8735
92cbf9713795
[gaim-migrate @ 9490]
Christian Hammond <chipx86@chipx86.com>
parents:
8225
diff
changeset
|
454 * @return The size of the value added. |
| 2086 | 455 */ |
| 7167 | 456 faim_internal int aim_tlvlist_add_32(aim_tlvlist_t **list, const fu16_t type, const fu32_t value) |
| 2086 | 457 { |
|
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
458 fu8_t v32[4]; |
| 2086 | 459 |
| 7167 | 460 aimutil_put32(v32, value); |
| 2086 | 461 |
| 7167 | 462 return aim_tlvlist_add_raw(list, type, 4, v32); |
| 2086 | 463 } |
| 464 | |
| 465 /** | |
| 466 * Adds a block of capability blocks to a TLV chain. The bitfield | |
| 467 * passed in should be a bitwise %OR of any of the %AIM_CAPS constants: | |
| 468 * | |
| 7158 | 469 * %AIM_CAPS_BUDDYICON Supports Buddy Icons |
| 8092 | 470 * %AIM_CAPS_TALK Supports Voice Chat |
| 7158 | 471 * %AIM_CAPS_IMIMAGE Supports DirectIM/IMImage |
| 472 * %AIM_CAPS_CHAT Supports Chat | |
| 473 * %AIM_CAPS_GETFILE Supports Get File functions | |
| 474 * %AIM_CAPS_SENDFILE Supports Send File functions | |
| 2086 | 475 * |
| 7158 | 476 * @param list Destination chain |
| 477 * @param type TLV type to add | |
| 478 * @param caps Bitfield of capability flags to send | |
|
8735
92cbf9713795
[gaim-migrate @ 9490]
Christian Hammond <chipx86@chipx86.com>
parents:
8225
diff
changeset
|
479 * @return The size of the value added. |
| 2086 | 480 */ |
| 7167 | 481 faim_internal int aim_tlvlist_add_caps(aim_tlvlist_t **list, const fu16_t type, const fu32_t caps) |
| 2086 | 482 { |
|
2866
6d62d4520460
[gaim-migrate @ 2879]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2821
diff
changeset
|
483 fu8_t buf[16*16]; /* XXX icky fixed length buffer */ |
|
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
484 aim_bstream_t bs; |
| 2086 | 485 |
|
2421
95b4ec08abec
[gaim-migrate @ 2434]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2270
diff
changeset
|
486 if (!caps) |
|
95b4ec08abec
[gaim-migrate @ 2434]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2270
diff
changeset
|
487 return 0; /* nothing there anyway */ |
|
95b4ec08abec
[gaim-migrate @ 2434]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2270
diff
changeset
|
488 |
|
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
489 aim_bstream_init(&bs, buf, sizeof(buf)); |
| 2086 | 490 |
|
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
491 aim_putcap(&bs, caps); |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
492 |
| 7167 | 493 return aim_tlvlist_add_raw(list, type, aim_bstream_curpos(&bs), buf); |
| 2086 | 494 } |
| 495 | |
| 7167 | 496 /** |
| 497 * Adds the given userinfo struct to a TLV chain. | |
| 498 * | |
| 499 * @param list Destination chain. | |
| 500 * @param type TLV type to add. | |
|
8735
92cbf9713795
[gaim-migrate @ 9490]
Christian Hammond <chipx86@chipx86.com>
parents:
8225
diff
changeset
|
501 * @return The size of the value added. |
| 7167 | 502 */ |
| 503 faim_internal int aim_tlvlist_add_userinfo(aim_tlvlist_t **list, fu16_t type, aim_userinfo_t *userinfo) | |
|
2270
d82efea341ef
[gaim-migrate @ 2280]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2246
diff
changeset
|
504 { |
|
d82efea341ef
[gaim-migrate @ 2280]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2246
diff
changeset
|
505 fu8_t buf[1024]; /* bleh */ |
|
d82efea341ef
[gaim-migrate @ 2280]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2246
diff
changeset
|
506 aim_bstream_t bs; |
|
d82efea341ef
[gaim-migrate @ 2280]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2246
diff
changeset
|
507 |
|
d82efea341ef
[gaim-migrate @ 2280]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2246
diff
changeset
|
508 aim_bstream_init(&bs, buf, sizeof(buf)); |
|
d82efea341ef
[gaim-migrate @ 2280]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2246
diff
changeset
|
509 |
| 7167 | 510 aim_putuserinfo(&bs, userinfo); |
|
2270
d82efea341ef
[gaim-migrate @ 2280]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2246
diff
changeset
|
511 |
| 7167 | 512 return aim_tlvlist_add_raw(list, type, aim_bstream_curpos(&bs), buf); |
|
2270
d82efea341ef
[gaim-migrate @ 2280]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2246
diff
changeset
|
513 } |
|
d82efea341ef
[gaim-migrate @ 2280]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2246
diff
changeset
|
514 |
| 2086 | 515 /** |
| 8225 | 516 * Adds the given chatroom info to a TLV chain. |
| 517 * | |
| 518 * @param list Destination chain. | |
| 519 * @param type TLV type to add. | |
| 520 * @param roomname The name of the chat. | |
| 521 * @param instance The instance. | |
|
8735
92cbf9713795
[gaim-migrate @ 9490]
Christian Hammond <chipx86@chipx86.com>
parents:
8225
diff
changeset
|
522 * @return The size of the value added. |
| 8225 | 523 */ |
| 524 faim_internal int aim_tlvlist_add_chatroom(aim_tlvlist_t **list, fu16_t type, fu16_t exchange, const char *roomname, fu16_t instance) | |
| 525 { | |
| 526 fu8_t *buf; | |
| 527 int len; | |
| 528 aim_bstream_t bs; | |
| 529 | |
| 530 len = 2 + 1 + strlen(roomname) + 2; | |
| 531 | |
| 532 if (!(buf = malloc(len))) | |
| 533 return 0; | |
| 534 | |
| 535 aim_bstream_init(&bs, buf, len); | |
| 536 | |
| 537 aimbs_put16(&bs, exchange); | |
| 538 aimbs_put8(&bs, strlen(roomname)); | |
| 539 aimbs_putraw(&bs, roomname, strlen(roomname)); | |
| 540 aimbs_put16(&bs, instance); | |
| 541 | |
| 542 len = aim_tlvlist_add_raw(list, type, aim_bstream_curpos(&bs), buf); | |
| 543 | |
| 544 free(buf); | |
| 545 | |
| 546 return len; | |
| 547 } | |
| 548 | |
| 549 /** | |
| 2086 | 550 * Adds a TLV with a zero length to a TLV chain. |
| 551 * | |
| 7167 | 552 * @param list Destination chain. |
| 553 * @param type TLV type to add. | |
|
8735
92cbf9713795
[gaim-migrate @ 9490]
Christian Hammond <chipx86@chipx86.com>
parents:
8225
diff
changeset
|
554 * @return The size of the value added. |
| 2086 | 555 */ |
| 7167 | 556 faim_internal int aim_tlvlist_add_noval(aim_tlvlist_t **list, const fu16_t type) |
| 2086 | 557 { |
| 7167 | 558 return aim_tlvlist_add_raw(list, type, 0, NULL); |
|
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
559 } |
| 2086 | 560 |
|
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
561 /* |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
562 * Note that the inner TLV chain will not be modifiable as a tlvchain once |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
563 * it is written using this. Or rather, it can be, but updates won't be |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
564 * made to this. |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
565 * |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
566 * XXX should probably support sublists for real. |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
567 * |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
568 * This is so neat. |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
569 * |
| 8790 | 570 * @param list Destination chain. |
| 571 * @param type TLV type to add. | |
| 572 * @param t1 The TLV chain you want to write. | |
| 8794 | 573 * @return The number of bytes written to the destination TLV chain. |
| 574 * 0 is returned if there was an error or if the destination | |
| 575 * TLV chain has length 0. | |
|
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
576 */ |
| 7167 | 577 faim_internal int aim_tlvlist_add_frozentlvlist(aim_tlvlist_t **list, fu16_t type, aim_tlvlist_t **tl) |
|
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
578 { |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
579 fu8_t *buf; |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
580 int buflen; |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
581 aim_bstream_t bs; |
| 2086 | 582 |
| 7167 | 583 buflen = aim_tlvlist_size(tl); |
|
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
584 |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
585 if (buflen <= 0) |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
586 return 0; |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
587 |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
588 if (!(buf = malloc(buflen))) |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
589 return 0; |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
590 |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
591 aim_bstream_init(&bs, buf, buflen); |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
592 |
| 7167 | 593 aim_tlvlist_write(&bs, tl); |
|
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
594 |
| 7167 | 595 aim_tlvlist_add_raw(list, type, aim_bstream_curpos(&bs), buf); |
|
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
596 |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
597 free(buf); |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
598 |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
599 return buflen; |
| 2086 | 600 } |
| 601 | |
| 602 /** | |
| 7166 | 603 * Substitute a TLV of a given type with a new TLV of the same type. If |
| 604 * you attempt to replace a TLV that does not exist, this function will | |
| 7167 | 605 * just add a new TLV as if you called aim_tlvlist_add_raw(). |
| 7166 | 606 * |
| 607 * @param list Desination chain (%NULL pointer if empty). | |
| 608 * @param type TLV type. | |
| 609 * @param length Length of string to add (not including %NULL). | |
| 610 * @param value String to add. | |
| 611 * @return The length of the TLV. | |
| 612 */ | |
| 613 faim_internal int aim_tlvlist_replace_raw(aim_tlvlist_t **list, const fu16_t type, const fu16_t length, const fu8_t *value) | |
| 614 { | |
| 615 aim_tlvlist_t *cur; | |
| 616 | |
| 617 if (list == NULL) | |
| 618 return 0; | |
| 619 | |
| 620 for (cur = *list; ((cur != NULL) && (cur->tlv->type != type)); cur = cur->next); | |
| 621 if (cur == NULL) | |
| 7167 | 622 return aim_tlvlist_add_raw(list, type, length, value); |
| 7166 | 623 |
| 624 free(cur->tlv->value); | |
| 625 cur->tlv->length = length; | |
| 626 if (cur->tlv->length > 0) { | |
| 627 cur->tlv->value = (fu8_t *)malloc(cur->tlv->length); | |
| 628 memcpy(cur->tlv->value, value, cur->tlv->length); | |
| 629 } else | |
| 630 cur->tlv->value = NULL; | |
| 631 | |
| 632 return cur->tlv->length; | |
| 633 } | |
| 634 | |
| 635 /** | |
| 636 * Substitute a TLV of a given type with a new TLV of the same type. If | |
| 637 * you attempt to replace a TLV that does not exist, this function will | |
| 7167 | 638 * just add a new TLV as if you called aim_tlvlist_add_raw(). |
| 7166 | 639 * |
| 640 * @param list Desination chain (%NULL pointer if empty). | |
| 641 * @param type TLV type. | |
| 642 * @return The length of the TLV. | |
| 643 */ | |
| 644 faim_internal int aim_tlvlist_replace_noval(aim_tlvlist_t **list, const fu16_t type) | |
| 645 { | |
| 646 return aim_tlvlist_replace_raw(list, type, 0, NULL); | |
| 647 } | |
| 648 | |
| 649 /** | |
| 650 * Substitute a TLV of a given type with a new TLV of the same type. If | |
| 651 * you attempt to replace a TLV that does not exist, this function will | |
| 7167 | 652 * just add a new TLV as if you called aim_tlvlist_add_raw(). |
| 7166 | 653 * |
| 654 * @param list Desination chain (%NULL pointer if empty). | |
| 655 * @param type TLV type. | |
| 656 * @param value 8 bit value to add. | |
| 657 * @return The length of the TLV. | |
| 658 */ | |
| 659 faim_internal int aim_tlvlist_replace_8(aim_tlvlist_t **list, const fu16_t type, const fu8_t value) | |
| 660 { | |
| 661 fu8_t v8[1]; | |
| 662 | |
| 663 aimutil_put8(v8, value); | |
| 664 | |
| 665 return aim_tlvlist_replace_raw(list, type, 1, v8); | |
| 666 } | |
| 667 | |
| 668 /** | |
| 669 * Substitute a TLV of a given type with a new TLV of the same type. If | |
| 670 * you attempt to replace a TLV that does not exist, this function will | |
| 7167 | 671 * just add a new TLV as if you called aim_tlvlist_add_raw(). |
| 7166 | 672 * |
| 673 * @param list Desination chain (%NULL pointer if empty). | |
| 674 * @param type TLV type. | |
| 675 * @param value 32 bit value to add. | |
| 676 * @return The length of the TLV. | |
| 677 */ | |
| 678 faim_internal int aim_tlvlist_replace_32(aim_tlvlist_t **list, const fu16_t type, const fu32_t value) | |
| 679 { | |
| 680 fu8_t v32[4]; | |
| 681 | |
| 682 aimutil_put32(v32, value); | |
| 683 | |
| 684 return aim_tlvlist_replace_raw(list, type, 4, v32); | |
| 685 } | |
| 686 | |
| 687 /** | |
| 688 * Remove a TLV of a given type. If you attempt to remove a TLV that | |
| 689 * does not exist, nothing happens. | |
| 690 * | |
| 691 * @param list Desination chain (%NULL pointer if empty). | |
| 692 * @param type TLV type. | |
| 693 */ | |
| 694 faim_internal void aim_tlvlist_remove(aim_tlvlist_t **list, const fu16_t type) | |
| 695 { | |
| 696 aim_tlvlist_t *del; | |
| 697 | |
| 698 if (!list || !(*list)) | |
| 699 return; | |
| 700 | |
| 701 /* Remove the item from the list */ | |
| 702 if ((*list)->tlv->type == type) { | |
| 703 del = *list; | |
| 704 *list = (*list)->next; | |
| 705 } else { | |
| 706 aim_tlvlist_t *cur; | |
| 707 for (cur=*list; (cur->next && (cur->next->tlv->type!=type)); cur=cur->next); | |
| 708 if (!cur->next) | |
| 709 return; | |
| 710 del = cur->next; | |
| 711 cur->next = del->next; | |
| 712 } | |
| 713 | |
| 714 /* Free the removed item */ | |
| 715 free(del->tlv->value); | |
| 716 free(del->tlv); | |
| 717 free(del); | |
| 718 } | |
| 719 | |
| 720 /** | |
| 8794 | 721 * Write a TLV chain into a data buffer. |
| 2086 | 722 * |
| 723 * Copies a TLV chain into a raw data buffer, writing only the number | |
| 724 * of bytes specified. This operation does not free the chain; | |
| 7167 | 725 * aim_tlvlist_free() must still be called to free up the memory used |
| 2086 | 726 * by the chain structures. |
| 727 * | |
|
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
728 * XXX clean this up, make better use of bstreams |
| 8790 | 729 * |
| 730 * @param bs Input bstream | |
| 731 * @param list Source TLV chain | |
| 8794 | 732 * @return Return 0 if the destination bstream is too small. |
| 2086 | 733 */ |
| 7167 | 734 faim_internal int aim_tlvlist_write(aim_bstream_t *bs, aim_tlvlist_t **list) |
| 2086 | 735 { |
|
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
736 int goodbuflen; |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
737 aim_tlvlist_t *cur; |
| 2086 | 738 |
|
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
739 /* do an initial run to test total length */ |
| 7167 | 740 goodbuflen = aim_tlvlist_size(list); |
| 2086 | 741 |
|
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
742 if (goodbuflen > aim_bstream_empty(bs)) |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
743 return 0; /* not enough buffer */ |
| 2086 | 744 |
|
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
745 /* do the real write-out */ |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
746 for (cur = *list; cur; cur = cur->next) { |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
747 aimbs_put16(bs, cur->tlv->type); |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
748 aimbs_put16(bs, cur->tlv->length); |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
749 if (cur->tlv->length) |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
750 aimbs_putraw(bs, cur->tlv->value, cur->tlv->length); |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
751 } |
| 2086 | 752 |
|
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
753 return 1; /* XXX this is a nonsensical return */ |
| 2086 | 754 } |
| 755 | |
| 756 | |
| 757 /** | |
| 7166 | 758 * Grab the Nth TLV of type type in the TLV list list. |
| 2086 | 759 * |
| 760 * Returns a pointer to an aim_tlv_t of the specified type; | |
| 761 * %NULL on error. The @nth parameter is specified starting at %1. | |
| 762 * In most cases, there will be no more than one TLV of any type | |
| 763 * in a chain. | |
| 764 * | |
| 7167 | 765 * @param list Source chain. |
| 766 * @param type Requested TLV type. | |
| 767 * @param nth Index of TLV of type to get. | |
| 7166 | 768 * @return The TLV you were looking for, or NULL if one could not be found. |
| 2086 | 769 */ |
| 7167 | 770 faim_internal aim_tlv_t *aim_tlv_gettlv(aim_tlvlist_t *list, const fu16_t type, const int nth) |
| 2086 | 771 { |
|
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
772 aim_tlvlist_t *cur; |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
773 int i; |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
774 |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
775 for (cur = list, i = 0; cur; cur = cur->next) { |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
776 if (cur && cur->tlv) { |
| 7167 | 777 if (cur->tlv->type == type) |
|
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
778 i++; |
| 7167 | 779 if (i >= nth) |
|
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
780 return cur->tlv; |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
781 } |
| 2086 | 782 } |
|
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
783 |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
784 return NULL; |
| 2086 | 785 } |
| 786 | |
| 787 /** | |
| 7167 | 788 * Retrieve the data from the nth TLV in the given TLV chain as a string. |
| 2086 | 789 * |
| 7167 | 790 * @param list Source TLV chain. |
| 791 * @param type TLV type to search for. | |
| 792 * @param nth Index of TLV to return. | |
| 793 * @return The value of the TLV you were looking for, or NULL if one could | |
| 794 * not be found. This is a dynamic buffer and must be freed by the | |
| 795 * caller. | |
| 2086 | 796 */ |
| 7167 | 797 faim_internal char *aim_tlv_getstr(aim_tlvlist_t *list, const fu16_t type, const int nth) |
| 2086 | 798 { |
|
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
799 aim_tlv_t *tlv; |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
800 char *newstr; |
| 2086 | 801 |
| 7167 | 802 if (!(tlv = aim_tlv_gettlv(list, type, nth))) |
|
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
803 return NULL; |
| 2086 | 804 |
|
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
805 newstr = (char *) malloc(tlv->length + 1); |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
806 memcpy(newstr, tlv->value, tlv->length); |
| 7011 | 807 newstr[tlv->length] = '\0'; |
|
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
808 |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
809 return newstr; |
| 2086 | 810 } |
| 811 | |
| 812 /** | |
| 7167 | 813 * Retrieve the data from the nth TLV in the given TLV chain as an 8bit |
| 814 * integer. | |
| 2086 | 815 * |
| 7167 | 816 * @param list Source TLV chain. |
| 817 * @param type TLV type to search for. | |
| 818 * @param nth Index of TLV to return. | |
| 819 * @return The value the TLV you were looking for, or 0 if one could | |
| 820 * not be found. | |
| 2086 | 821 */ |
| 7167 | 822 faim_internal fu8_t aim_tlv_get8(aim_tlvlist_t *list, const fu16_t type, const int nth) |
| 2086 | 823 { |
|
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
824 aim_tlv_t *tlv; |
| 2086 | 825 |
| 7167 | 826 if (!(tlv = aim_tlv_gettlv(list, type, nth))) |
|
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
827 return 0; /* erm */ |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
828 return aimutil_get8(tlv->value); |
| 2086 | 829 } |
| 830 | |
| 831 /** | |
| 7167 | 832 * Retrieve the data from the nth TLV in the given TLV chain as a 16bit |
| 833 * integer. | |
| 2086 | 834 * |
| 7167 | 835 * @param list Source TLV chain. |
| 836 * @param type TLV type to search for. | |
| 837 * @param nth Index of TLV to return. | |
| 838 * @return The value the TLV you were looking for, or 0 if one could | |
| 839 * not be found. | |
| 2086 | 840 */ |
| 7167 | 841 faim_internal fu16_t aim_tlv_get16(aim_tlvlist_t *list, const fu16_t type, const int nth) |
| 2086 | 842 { |
|
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
843 aim_tlv_t *tlv; |
| 2086 | 844 |
| 7167 | 845 if (!(tlv = aim_tlv_gettlv(list, type, nth))) |
|
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
846 return 0; /* erm */ |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
847 return aimutil_get16(tlv->value); |
| 2086 | 848 } |
| 849 | |
| 850 /** | |
| 7167 | 851 * Retrieve the data from the nth TLV in the given TLV chain as a 32bit |
| 852 * integer. | |
| 2086 | 853 * |
| 7167 | 854 * @param list Source TLV chain. |
| 855 * @param type TLV type to search for. | |
| 856 * @param nth Index of TLV to return. | |
| 857 * @return The value the TLV you were looking for, or 0 if one could | |
| 858 * not be found. | |
| 2086 | 859 */ |
| 7167 | 860 faim_internal fu32_t aim_tlv_get32(aim_tlvlist_t *list, const fu16_t type, const int nth) |
| 2086 | 861 { |
|
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
862 aim_tlv_t *tlv; |
| 2086 | 863 |
| 7167 | 864 if (!(tlv = aim_tlv_gettlv(list, type, nth))) |
|
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
865 return 0; /* erm */ |
|
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
866 return aimutil_get32(tlv->value); |
| 2086 | 867 } |
