Mercurial > pidgin.yaz
annotate src/protocols/oscar/tlv.c @ 8092:697221d5d0ff
[gaim-migrate @ 8791]
Give a nice little warning if you add an AIM or ICQ buddy with an invalid
name. I'm thinking some of those bug reports on SF about "Could not add
buddy with no name" are caused by this. Hopefully. Sometime before the
next release I'll probably actually remove invalid people from the local
list.
Also recognize the WinAIM Video and Camera caps.
committer: Tailor Script <tailor@pidgin.im>
author | Mark Doliner <mark@kingant.net> |
---|---|
date | Tue, 13 Jan 2004 05:44:37 +0000 |
parents | 6d3d8f11e765 |
children | 9790cda80d52 |
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 |
8092 | 467 * %AIM_CAPS_TALK Supports Voice Chat |
7158 | 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 } |