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