Mercurial > pidgin
comparison src/protocols/oscar/tlv.c @ 13592:6519aeb66b31
[gaim-migrate @ 15978]
Holy cow this is crazy.
34 files changed, 5760 insertions(+), 8517 deletions(-)
* Non-blocking I/O for all of oscar. That includes normal FLAP
connections as well as file transfers and direct IM.
* Kick-ass file transfer and direct IM. Either party can request
the connection. Gaim will try both the "public" IP and the
"client" IP. It'll fall back to transferring through a proxy
if that fails. Should be relatively few memleaks (I didn't
have a lot of confidence in the non-memleakiness of the old
code). And the code is reasonably generic, so it shouldn't
be too much work to add voice chat. This might still be a
LITTLE buggy, but it shouldn't be too bad. If anything, file
transfer will be more buggy than direct IM. And sending a
file will be more buggy than receiving a file. Bug reports
with a series of steps to reproduce are welcome.
* I merged OscarData and aim_session_t
* Somewhere between 50 and 100 hours of work.
committer: Tailor Script <tailor@pidgin.im>
author | Mark Doliner <mark@kingant.net> |
---|---|
date | Fri, 07 Apr 2006 05:10:56 +0000 |
parents | f260d319bbbc |
children | a07dcc2c01bd |
comparison
equal
deleted
inserted
replaced
13591:dcfda39ad547 | 13592:6519aeb66b31 |
---|---|
19 */ | 19 */ |
20 | 20 |
21 | 21 |
22 #include "oscar.h" | 22 #include "oscar.h" |
23 | 23 |
24 static aim_tlv_t *createtlv(guint16 type, guint16 length, guint8 *value) | 24 static aim_tlv_t * |
25 createtlv(guint16 type, guint16 length, guint8 *value) | |
25 { | 26 { |
26 aim_tlv_t *ret; | 27 aim_tlv_t *ret; |
27 | 28 |
28 if (!(ret = (aim_tlv_t *)malloc(sizeof(aim_tlv_t)))) | 29 ret = g_new(aim_tlv_t, 1); |
29 return NULL; | |
30 ret->type = type; | 30 ret->type = type; |
31 ret->length = length; | 31 ret->length = length; |
32 ret->value = value; | 32 ret->value = value; |
33 | 33 |
34 return ret; | 34 return ret; |
35 } | 35 } |
36 | 36 |
37 static void freetlv(aim_tlv_t **oldtlv) | 37 static void |
38 freetlv(aim_tlv_t **oldtlv) | |
38 { | 39 { |
39 | 40 |
40 if (!oldtlv || !*oldtlv) | 41 if (!oldtlv || !*oldtlv) |
41 return; | 42 return; |
42 | 43 |
54 * returned structure is manipulatable with the rest of the TLV | 55 * returned structure is manipulatable with the rest of the TLV |
55 * routines. When done with a TLV chain, aim_tlvlist_free() should | 56 * routines. When done with a TLV chain, aim_tlvlist_free() should |
56 * be called to free the dynamic substructures. | 57 * be called to free the dynamic substructures. |
57 * | 58 * |
58 * XXX There should be a flag setable here to have the tlvlist contain | 59 * XXX There should be a flag setable here to have the tlvlist contain |
59 * bstream references, so that at least the ->value portion of each | 60 * bstream references, so that at least the ->value portion of each |
60 * element doesn't need to be malloc/memcpy'd. This could prove to be | 61 * element doesn't need to be malloc/memcpy'd. This could prove to be |
61 * just as efficient as the in-place TLV parsing used in a couple places | 62 * just as efficient as the in-place TLV parsing used in a couple places |
62 * in libfaim. | 63 * in libfaim. |
63 * | 64 * |
64 * @param bs Input bstream | 65 * @param bs Input bstream |
65 * @return Return the TLV chain read | 66 * @return Return the TLV chain read |
66 */ | 67 */ |
67 faim_internal aim_tlvlist_t *aim_tlvlist_read(ByteStream *bs) | 68 aim_tlvlist_t *aim_tlvlist_read(ByteStream *bs) |
68 { | 69 { |
69 aim_tlvlist_t *list = NULL, *cur; | 70 aim_tlvlist_t *list = NULL, *cur; |
70 | 71 |
71 while (aim_bstream_empty(bs) > 0) { | 72 while (byte_stream_empty(bs) > 0) { |
72 guint16 type, length; | 73 guint16 type, length; |
73 | 74 |
74 type = aimbs_get16(bs); | 75 type = byte_stream_get16(bs); |
75 length = aimbs_get16(bs); | 76 length = byte_stream_get16(bs); |
76 | 77 |
77 #if 0 /* temporarily disabled until I know if they're still doing it or not */ | 78 #if 0 /* temporarily disabled until I know if they're still doing it or not */ |
78 /* | 79 /* |
79 * Okay, so now AOL has decided that any TLV of | 80 * Okay, so now AOL has decided that any TLV of |
80 * type 0x0013 can only be two bytes, despite | 81 * type 0x0013 can only be two bytes, despite |
81 * what the actual given length is. So here | 82 * what the actual given length is. So here |
82 * we dump any invalid TLVs of that sort. Hopefully | 83 * we dump any invalid TLVs of that sort. Hopefully |
83 * there's no special cases to this special case. | 84 * there's no special cases to this special case. |
84 * - mid (30jun2000) | 85 * - mid (30jun2000) |
85 */ | 86 */ |
86 if ((type == 0x0013) && (length != 0x0002)) | 87 if ((type == 0x0013) && (length != 0x0002)) |
89 if (0) | 90 if (0) |
90 ; | 91 ; |
91 #endif | 92 #endif |
92 else { | 93 else { |
93 | 94 |
94 if (length > aim_bstream_empty(bs)) { | 95 if (length > byte_stream_empty(bs)) { |
95 aim_tlvlist_free(&list); | 96 aim_tlvlist_free(&list); |
96 return NULL; | 97 return NULL; |
97 } | 98 } |
98 | 99 |
99 cur = (aim_tlvlist_t *)malloc(sizeof(aim_tlvlist_t)); | 100 cur = g_new0(aim_tlvlist_t, 1); |
100 if (!cur) { | |
101 aim_tlvlist_free(&list); | |
102 return NULL; | |
103 } | |
104 | |
105 memset(cur, 0, sizeof(aim_tlvlist_t)); | |
106 | |
107 cur->tlv = createtlv(type, length, NULL); | 101 cur->tlv = createtlv(type, length, NULL); |
108 if (!cur->tlv) { | |
109 free(cur); | |
110 aim_tlvlist_free(&list); | |
111 return NULL; | |
112 } | |
113 if (cur->tlv->length > 0) { | 102 if (cur->tlv->length > 0) { |
114 cur->tlv->value = aimbs_getraw(bs, length); | 103 cur->tlv->value = byte_stream_getraw(bs, length); |
115 if (!cur->tlv->value) { | 104 if (!cur->tlv->value) { |
116 freetlv(&cur->tlv); | 105 freetlv(&cur->tlv); |
117 free(cur); | 106 free(cur); |
118 aim_tlvlist_free(&list); | 107 aim_tlvlist_free(&list); |
119 return NULL; | 108 return NULL; |
135 * returned structure is manipulatable with the rest of the TLV | 124 * returned structure is manipulatable with the rest of the TLV |
136 * routines. When done with a TLV chain, aim_tlvlist_free() should | 125 * routines. When done with a TLV chain, aim_tlvlist_free() should |
137 * be called to free the dynamic substructures. | 126 * be called to free the dynamic substructures. |
138 * | 127 * |
139 * XXX There should be a flag setable here to have the tlvlist contain | 128 * XXX There should be a flag setable here to have the tlvlist contain |
140 * bstream references, so that at least the ->value portion of each | 129 * bstream references, so that at least the ->value portion of each |
141 * element doesn't need to be malloc/memcpy'd. This could prove to be | 130 * element doesn't need to be malloc/memcpy'd. This could prove to be |
142 * just as efficient as the in-place TLV parsing used in a couple places | 131 * just as efficient as the in-place TLV parsing used in a couple places |
143 * in libfaim. | 132 * in libfaim. |
144 * | 133 * |
145 * @param bs Input bstream | 134 * @param bs Input bstream |
146 * @param num The max number of TLVs that will be read, or -1 if unlimited. | 135 * @param num The max number of TLVs that will be read, or -1 if unlimited. |
147 * There are a number of places where you want to read in a tlvchain, | 136 * There are a number of places where you want to read in a tlvchain, |
148 * but the chain is not at the end of the SNAC, and the chain is | 137 * but the chain is not at the end of the SNAC, and the chain is |
149 * preceded by the number of TLVs. So you can limit that with this. | 138 * preceded by the number of TLVs. So you can limit that with this. |
150 * @return Return the TLV chain read | 139 * @return Return the TLV chain read |
151 */ | 140 */ |
152 faim_internal aim_tlvlist_t *aim_tlvlist_readnum(ByteStream *bs, guint16 num) | 141 aim_tlvlist_t *aim_tlvlist_readnum(ByteStream *bs, guint16 num) |
153 { | 142 { |
154 aim_tlvlist_t *list = NULL, *cur; | 143 aim_tlvlist_t *list = NULL, *cur; |
155 | 144 |
156 while ((aim_bstream_empty(bs) > 0) && (num != 0)) { | 145 while ((byte_stream_empty(bs) > 0) && (num != 0)) { |
157 guint16 type, length; | 146 guint16 type, length; |
158 | 147 |
159 type = aimbs_get16(bs); | 148 type = byte_stream_get16(bs); |
160 length = aimbs_get16(bs); | 149 length = byte_stream_get16(bs); |
161 | 150 |
162 if (length > aim_bstream_empty(bs)) { | 151 if (length > byte_stream_empty(bs)) { |
163 aim_tlvlist_free(&list); | 152 aim_tlvlist_free(&list); |
164 return NULL; | 153 return NULL; |
165 } | 154 } |
166 | 155 |
167 cur = (aim_tlvlist_t *)malloc(sizeof(aim_tlvlist_t)); | 156 cur = g_new0(aim_tlvlist_t, 1); |
168 if (!cur) { | |
169 aim_tlvlist_free(&list); | |
170 return NULL; | |
171 } | |
172 | |
173 memset(cur, 0, sizeof(aim_tlvlist_t)); | |
174 | |
175 cur->tlv = createtlv(type, length, NULL); | 157 cur->tlv = createtlv(type, length, NULL); |
176 if (!cur->tlv) { | |
177 free(cur); | |
178 aim_tlvlist_free(&list); | |
179 return NULL; | |
180 } | |
181 if (cur->tlv->length > 0) { | 158 if (cur->tlv->length > 0) { |
182 cur->tlv->value = aimbs_getraw(bs, length); | 159 cur->tlv->value = byte_stream_getraw(bs, length); |
183 if (!cur->tlv->value) { | 160 if (!cur->tlv->value) { |
184 freetlv(&cur->tlv); | 161 freetlv(&cur->tlv); |
185 free(cur); | 162 free(cur); |
186 aim_tlvlist_free(&list); | 163 aim_tlvlist_free(&list); |
187 return NULL; | 164 return NULL; |
204 * returned structure is manipulatable with the rest of the TLV | 181 * returned structure is manipulatable with the rest of the TLV |
205 * routines. When done with a TLV chain, aim_tlvlist_free() should | 182 * routines. When done with a TLV chain, aim_tlvlist_free() should |
206 * be called to free the dynamic substructures. | 183 * be called to free the dynamic substructures. |
207 * | 184 * |
208 * XXX There should be a flag setable here to have the tlvlist contain | 185 * XXX There should be a flag setable here to have the tlvlist contain |
209 * bstream references, so that at least the ->value portion of each | 186 * bstream references, so that at least the ->value portion of each |
210 * element doesn't need to be malloc/memcpy'd. This could prove to be | 187 * element doesn't need to be malloc/memcpy'd. This could prove to be |
211 * just as efficient as the in-place TLV parsing used in a couple places | 188 * just as efficient as the in-place TLV parsing used in a couple places |
212 * in libfaim. | 189 * in libfaim. |
213 * | 190 * |
214 * @param bs Input bstream | 191 * @param bs Input bstream |
215 * @param len The max length in bytes that will be read. | 192 * @param len The max length in bytes that will be read. |
216 * There are a number of places where you want to read in a tlvchain, | 193 * There are a number of places where you want to read in a tlvchain, |
217 * but the chain is not at the end of the SNAC, and the chain is | 194 * but the chain is not at the end of the SNAC, and the chain is |
218 * preceded by the length of the TLVs. So you can limit that with this. | 195 * preceded by the length of the TLVs. So you can limit that with this. |
219 * @return Return the TLV chain read | 196 * @return Return the TLV chain read |
220 */ | 197 */ |
221 faim_internal aim_tlvlist_t *aim_tlvlist_readlen(ByteStream *bs, guint16 len) | 198 aim_tlvlist_t *aim_tlvlist_readlen(ByteStream *bs, guint16 len) |
222 { | 199 { |
223 aim_tlvlist_t *list = NULL, *cur; | 200 aim_tlvlist_t *list = NULL, *cur; |
224 | 201 |
225 while ((aim_bstream_empty(bs) > 0) && (len > 0)) { | 202 while ((byte_stream_empty(bs) > 0) && (len > 0)) { |
226 guint16 type, length; | 203 guint16 type, length; |
227 | 204 |
228 type = aimbs_get16(bs); | 205 type = byte_stream_get16(bs); |
229 length = aimbs_get16(bs); | 206 length = byte_stream_get16(bs); |
230 | 207 |
231 if (length > aim_bstream_empty(bs)) { | 208 if (length > byte_stream_empty(bs)) { |
232 aim_tlvlist_free(&list); | 209 aim_tlvlist_free(&list); |
233 return NULL; | 210 return NULL; |
234 } | 211 } |
235 | 212 |
236 cur = (aim_tlvlist_t *)malloc(sizeof(aim_tlvlist_t)); | 213 cur = g_new0(aim_tlvlist_t, 1); |
237 if (!cur) { | |
238 aim_tlvlist_free(&list); | |
239 return NULL; | |
240 } | |
241 | |
242 memset(cur, 0, sizeof(aim_tlvlist_t)); | |
243 | |
244 cur->tlv = createtlv(type, length, NULL); | 214 cur->tlv = createtlv(type, length, NULL); |
245 if (!cur->tlv) { | |
246 free(cur); | |
247 aim_tlvlist_free(&list); | |
248 return NULL; | |
249 } | |
250 if (cur->tlv->length > 0) { | 215 if (cur->tlv->length > 0) { |
251 cur->tlv->value = aimbs_getraw(bs, length); | 216 cur->tlv->value = byte_stream_getraw(bs, length); |
252 if (!cur->tlv->value) { | 217 if (!cur->tlv->value) { |
253 freetlv(&cur->tlv); | 218 freetlv(&cur->tlv); |
254 free(cur); | 219 free(cur); |
255 aim_tlvlist_free(&list); | 220 aim_tlvlist_free(&list); |
256 return NULL; | 221 return NULL; |
270 * This is pretty self explanatory. | 235 * This is pretty self explanatory. |
271 * | 236 * |
272 * @param orig The TLV chain you want to make a copy of. | 237 * @param orig The TLV chain you want to make a copy of. |
273 * @return A newly allocated TLV chain. | 238 * @return A newly allocated TLV chain. |
274 */ | 239 */ |
275 faim_internal aim_tlvlist_t *aim_tlvlist_copy(aim_tlvlist_t *orig) | 240 aim_tlvlist_t *aim_tlvlist_copy(aim_tlvlist_t *orig) |
276 { | 241 { |
277 aim_tlvlist_t *new = NULL; | 242 aim_tlvlist_t *new = NULL; |
278 | 243 |
279 while (orig) { | 244 while (orig) { |
280 aim_tlvlist_add_raw(&new, orig->tlv->type, orig->tlv->length, orig->tlv->value); | 245 aim_tlvlist_add_raw(&new, orig->tlv->type, orig->tlv->length, orig->tlv->value); |
283 | 248 |
284 return new; | 249 return new; |
285 } | 250 } |
286 | 251 |
287 /* | 252 /* |
288 * Compare two TLV lists for equality. This probably is not the most | 253 * Compare two TLV lists for equality. This probably is not the most |
289 * efficient way to do this. | 254 * efficient way to do this. |
290 * | 255 * |
291 * @param one One of the TLV chains to compare. | 256 * @param one One of the TLV chains to compare. |
292 * @param two The other TLV chain to compare. | 257 * @param two The other TLV chain to compare. |
293 * @return Return 0 if the lists are the same, return 1 if they are different. | 258 * @return Return 0 if the lists are the same, return 1 if they are different. |
294 */ | 259 */ |
295 faim_internal int aim_tlvlist_cmp(aim_tlvlist_t *one, aim_tlvlist_t *two) | 260 int aim_tlvlist_cmp(aim_tlvlist_t *one, aim_tlvlist_t *two) |
296 { | 261 { |
297 ByteStream bs1, bs2; | 262 ByteStream bs1, bs2; |
298 | 263 |
299 if (aim_tlvlist_size(&one) != aim_tlvlist_size(&two)) | 264 if (aim_tlvlist_size(&one) != aim_tlvlist_size(&two)) |
300 return 1; | 265 return 1; |
301 | 266 |
302 aim_bstream_init(&bs1, ((guint8 *)malloc(aim_tlvlist_size(&one)*sizeof(guint8))), aim_tlvlist_size(&one)); | 267 byte_stream_init(&bs1, ((guint8 *)malloc(aim_tlvlist_size(&one)*sizeof(guint8))), aim_tlvlist_size(&one)); |
303 aim_bstream_init(&bs2, ((guint8 *)malloc(aim_tlvlist_size(&two)*sizeof(guint8))), aim_tlvlist_size(&two)); | 268 byte_stream_init(&bs2, ((guint8 *)malloc(aim_tlvlist_size(&two)*sizeof(guint8))), aim_tlvlist_size(&two)); |
304 | 269 |
305 aim_tlvlist_write(&bs1, &one); | 270 aim_tlvlist_write(&bs1, &one); |
306 aim_tlvlist_write(&bs2, &two); | 271 aim_tlvlist_write(&bs2, &two); |
307 | 272 |
308 if (memcmp(bs1.data, bs2.data, bs1.len)) { | 273 if (memcmp(bs1.data, bs2.data, bs1.len)) { |
324 * frees each one. Note that any references to this data | 289 * frees each one. Note that any references to this data |
325 * should be removed before calling this. | 290 * should be removed before calling this. |
326 * | 291 * |
327 * @param list Chain to be freed | 292 * @param list Chain to be freed |
328 */ | 293 */ |
329 faim_internal void aim_tlvlist_free(aim_tlvlist_t **list) | 294 void aim_tlvlist_free(aim_tlvlist_t **list) |
330 { | 295 { |
331 aim_tlvlist_t *cur; | 296 aim_tlvlist_t *cur; |
332 | 297 |
333 if (!list || !*list) | 298 if (!list || !*list) |
334 return; | 299 return; |
352 * Count the number of TLVs in a chain. | 317 * Count the number of TLVs in a chain. |
353 * | 318 * |
354 * @param list Chain to be counted. | 319 * @param list Chain to be counted. |
355 * @return The number of TLVs stored in the passed chain. | 320 * @return The number of TLVs stored in the passed chain. |
356 */ | 321 */ |
357 faim_internal int aim_tlvlist_count(aim_tlvlist_t **list) | 322 int aim_tlvlist_count(aim_tlvlist_t **list) |
358 { | 323 { |
359 aim_tlvlist_t *cur; | 324 aim_tlvlist_t *cur; |
360 int count; | 325 int count; |
361 | 326 |
362 if (!list || !*list) | 327 if (!list || !*list) |
370 | 335 |
371 /** | 336 /** |
372 * Count the number of bytes in a TLV chain. | 337 * Count the number of bytes in a TLV chain. |
373 * | 338 * |
374 * @param list Chain to be sized | 339 * @param list Chain to be sized |
375 * @return The number of bytes that would be needed to | 340 * @return The number of bytes that would be needed to |
376 * write the passed TLV chain to a data buffer. | 341 * write the passed TLV chain to a data buffer. |
377 */ | 342 */ |
378 faim_internal int aim_tlvlist_size(aim_tlvlist_t **list) | 343 int aim_tlvlist_size(aim_tlvlist_t **list) |
379 { | 344 { |
380 aim_tlvlist_t *cur; | 345 aim_tlvlist_t *cur; |
381 int size; | 346 int size; |
382 | 347 |
383 if (!list || !*list) | 348 if (!list || !*list) |
397 * @param type TLV type. | 362 * @param type TLV type. |
398 * @param length Length of string to add (not including %NULL). | 363 * @param length Length of string to add (not including %NULL). |
399 * @param value String to add. | 364 * @param value String to add. |
400 * @return The size of the value added. | 365 * @return The size of the value added. |
401 */ | 366 */ |
402 faim_internal int aim_tlvlist_add_raw(aim_tlvlist_t **list, const guint16 type, const guint16 length, const guint8 *value) | 367 int aim_tlvlist_add_raw(aim_tlvlist_t **list, const guint16 type, const guint16 length, const guint8 *value) |
403 { | 368 { |
404 aim_tlvlist_t *newtlv, *cur; | 369 aim_tlvlist_t *newtlv, *cur; |
405 | 370 |
406 if (list == NULL) | 371 if (list == NULL) |
407 return 0; | 372 return 0; |
408 | 373 |
409 if (!(newtlv = (aim_tlvlist_t *)malloc(sizeof(aim_tlvlist_t)))) | 374 newtlv = g_new0(aim_tlvlist_t, 1); |
410 return 0; | 375 newtlv->tlv = createtlv(type, length, NULL); |
411 memset(newtlv, 0x00, sizeof(aim_tlvlist_t)); | 376 if (newtlv->tlv->length > 0) |
412 | 377 newtlv->tlv->value = g_memdup(value, length); |
413 if (!(newtlv->tlv = createtlv(type, length, NULL))) { | |
414 free(newtlv); | |
415 return 0; | |
416 } | |
417 if (newtlv->tlv->length > 0) { | |
418 newtlv->tlv->value = (guint8 *)malloc(newtlv->tlv->length); | |
419 memcpy(newtlv->tlv->value, value, newtlv->tlv->length); | |
420 } | |
421 | 378 |
422 if (!*list) | 379 if (!*list) |
423 *list = newtlv; | 380 *list = newtlv; |
424 else { | 381 else { |
425 for(cur = *list; cur->next; cur = cur->next) | 382 for(cur = *list; cur->next; cur = cur->next) |
436 * @param list Destination chain. | 393 * @param list Destination chain. |
437 * @param type TLV type to add. | 394 * @param type TLV type to add. |
438 * @param value Value to add. | 395 * @param value Value to add. |
439 * @return The size of the value added. | 396 * @return The size of the value added. |
440 */ | 397 */ |
441 faim_internal int aim_tlvlist_add_8(aim_tlvlist_t **list, const guint16 type, const guint8 value) | 398 int aim_tlvlist_add_8(aim_tlvlist_t **list, const guint16 type, const guint8 value) |
442 { | 399 { |
443 guint8 v8[1]; | 400 guint8 v8[1]; |
444 | 401 |
445 aimutil_put8(v8, value); | 402 aimutil_put8(v8, value); |
446 | 403 |
453 * @param list Destination chain. | 410 * @param list Destination chain. |
454 * @param type TLV type to add. | 411 * @param type TLV type to add. |
455 * @param value Value to add. | 412 * @param value Value to add. |
456 * @return The size of the value added. | 413 * @return The size of the value added. |
457 */ | 414 */ |
458 faim_internal int aim_tlvlist_add_16(aim_tlvlist_t **list, const guint16 type, const guint16 value) | 415 int aim_tlvlist_add_16(aim_tlvlist_t **list, const guint16 type, const guint16 value) |
459 { | 416 { |
460 guint8 v16[2]; | 417 guint8 v16[2]; |
461 | 418 |
462 aimutil_put16(v16, value); | 419 aimutil_put16(v16, value); |
463 | 420 |
470 * @param list Destination chain. | 427 * @param list Destination chain. |
471 * @param type TLV type to add. | 428 * @param type TLV type to add. |
472 * @param value Value to add. | 429 * @param value Value to add. |
473 * @return The size of the value added. | 430 * @return The size of the value added. |
474 */ | 431 */ |
475 faim_internal int aim_tlvlist_add_32(aim_tlvlist_t **list, const guint16 type, const guint32 value) | 432 int aim_tlvlist_add_32(aim_tlvlist_t **list, const guint16 type, const guint32 value) |
476 { | 433 { |
477 guint8 v32[4]; | 434 guint8 v32[4]; |
478 | 435 |
479 aimutil_put32(v32, value); | 436 aimutil_put32(v32, value); |
480 | 437 |
487 * @param list Destination chain. | 444 * @param list Destination chain. |
488 * @param type TLV type to add. | 445 * @param type TLV type to add. |
489 * @param value Value to add. | 446 * @param value Value to add. |
490 * @return The size of the value added. | 447 * @return The size of the value added. |
491 */ | 448 */ |
492 faim_internal int aim_tlvlist_add_str(aim_tlvlist_t **list, const guint16 type, const char *value) | 449 int aim_tlvlist_add_str(aim_tlvlist_t **list, const guint16 type, const char *value) |
493 { | 450 { |
494 return aim_tlvlist_add_raw(list, type, strlen(value), (guint8 *)value); | 451 return aim_tlvlist_add_raw(list, type, strlen(value), (guint8 *)value); |
495 } | 452 } |
496 | 453 |
497 /** | 454 /** |
498 * Adds a block of capability blocks to a TLV chain. The bitfield | 455 * Adds a block of capability blocks to a TLV chain. The bitfield |
499 * passed in should be a bitwise %OR of any of the %AIM_CAPS constants: | 456 * passed in should be a bitwise %OR of any of the %AIM_CAPS constants: |
500 * | 457 * |
501 * %AIM_CAPS_BUDDYICON Supports Buddy Icons | 458 * %OSCAR_CAPABILITY_BUDDYICON Supports Buddy Icons |
502 * %AIM_CAPS_TALK Supports Voice Chat | 459 * %OSCAR_CAPABILITY_TALK Supports Voice Chat |
503 * %AIM_CAPS_IMIMAGE Supports DirectIM/IMImage | 460 * %OSCAR_CAPABILITY_IMIMAGE Supports DirectIM/IMImage |
504 * %AIM_CAPS_CHAT Supports Chat | 461 * %OSCAR_CAPABILITY_CHAT Supports Chat |
505 * %AIM_CAPS_GETFILE Supports Get File functions | 462 * %OSCAR_CAPABILITY_GETFILE Supports Get File functions |
506 * %AIM_CAPS_SENDFILE Supports Send File functions | 463 * %OSCAR_CAPABILITY_SENDFILE Supports Send File functions |
507 * | 464 * |
508 * @param list Destination chain | 465 * @param list Destination chain |
509 * @param type TLV type to add | 466 * @param type TLV type to add |
510 * @param caps Bitfield of capability flags to send | 467 * @param caps Bitfield of capability flags to send |
511 * @return The size of the value added. | 468 * @return The size of the value added. |
512 */ | 469 */ |
513 faim_internal int aim_tlvlist_add_caps(aim_tlvlist_t **list, const guint16 type, const guint32 caps) | 470 int aim_tlvlist_add_caps(aim_tlvlist_t **list, const guint16 type, const guint32 caps) |
514 { | 471 { |
515 guint8 buf[16*16]; /* XXX icky fixed length buffer */ | 472 guint8 buf[16*16]; /* XXX icky fixed length buffer */ |
516 ByteStream bs; | 473 ByteStream bs; |
517 | 474 |
518 if (!caps) | 475 if (!caps) |
519 return 0; /* nothing there anyway */ | 476 return 0; /* nothing there anyway */ |
520 | 477 |
521 aim_bstream_init(&bs, buf, sizeof(buf)); | 478 byte_stream_init(&bs, buf, sizeof(buf)); |
522 | 479 |
523 aimbs_putcaps(&bs, caps); | 480 byte_stream_putcaps(&bs, caps); |
524 | 481 |
525 return aim_tlvlist_add_raw(list, type, aim_bstream_curpos(&bs), buf); | 482 return aim_tlvlist_add_raw(list, type, byte_stream_curpos(&bs), buf); |
526 } | 483 } |
527 | 484 |
528 /** | 485 /** |
529 * Adds the given userinfo struct to a TLV chain. | 486 * Adds the given userinfo struct to a TLV chain. |
530 * | 487 * |
531 * @param list Destination chain. | 488 * @param list Destination chain. |
532 * @param type TLV type to add. | 489 * @param type TLV type to add. |
533 * @return The size of the value added. | 490 * @return The size of the value added. |
534 */ | 491 */ |
535 faim_internal int aim_tlvlist_add_userinfo(aim_tlvlist_t **list, guint16 type, aim_userinfo_t *userinfo) | 492 int aim_tlvlist_add_userinfo(aim_tlvlist_t **list, guint16 type, aim_userinfo_t *userinfo) |
536 { | 493 { |
537 guint8 buf[1024]; /* bleh */ | 494 guint8 buf[1024]; /* bleh */ |
538 ByteStream bs; | 495 ByteStream bs; |
539 | 496 |
540 aim_bstream_init(&bs, buf, sizeof(buf)); | 497 byte_stream_init(&bs, buf, sizeof(buf)); |
541 | 498 |
542 aim_putuserinfo(&bs, userinfo); | 499 aim_putuserinfo(&bs, userinfo); |
543 | 500 |
544 return aim_tlvlist_add_raw(list, type, aim_bstream_curpos(&bs), buf); | 501 return aim_tlvlist_add_raw(list, type, byte_stream_curpos(&bs), buf); |
545 } | 502 } |
546 | 503 |
547 /** | 504 /** |
548 * Adds the given chatroom info to a TLV chain. | 505 * Adds the given chatroom info to a TLV chain. |
549 * | 506 * |
551 * @param type TLV type to add. | 508 * @param type TLV type to add. |
552 * @param roomname The name of the chat. | 509 * @param roomname The name of the chat. |
553 * @param instance The instance. | 510 * @param instance The instance. |
554 * @return The size of the value added. | 511 * @return The size of the value added. |
555 */ | 512 */ |
556 faim_internal int aim_tlvlist_add_chatroom(aim_tlvlist_t **list, guint16 type, guint16 exchange, const char *roomname, guint16 instance) | 513 int aim_tlvlist_add_chatroom(aim_tlvlist_t **list, guint16 type, guint16 exchange, const char *roomname, guint16 instance) |
557 { | 514 { |
558 guint8 *buf; | 515 guint8 *buf; |
559 int len; | 516 int len; |
560 ByteStream bs; | 517 ByteStream bs; |
561 | 518 |
562 len = 2 + 1 + strlen(roomname) + 2; | 519 len = 2 + 1 + strlen(roomname) + 2; |
563 | 520 |
564 if (!(buf = malloc(len))) | 521 buf = malloc(len); |
565 return 0; | 522 byte_stream_init(&bs, buf, len); |
566 | 523 |
567 aim_bstream_init(&bs, buf, len); | 524 byte_stream_put16(&bs, exchange); |
568 | 525 byte_stream_put8(&bs, strlen(roomname)); |
569 aimbs_put16(&bs, exchange); | 526 byte_stream_putstr(&bs, roomname); |
570 aimbs_put8(&bs, strlen(roomname)); | 527 byte_stream_put16(&bs, instance); |
571 aimbs_putstr(&bs, roomname); | 528 |
572 aimbs_put16(&bs, instance); | 529 len = aim_tlvlist_add_raw(list, type, byte_stream_curpos(&bs), buf); |
573 | |
574 len = aim_tlvlist_add_raw(list, type, aim_bstream_curpos(&bs), buf); | |
575 | 530 |
576 free(buf); | 531 free(buf); |
577 | 532 |
578 return len; | 533 return len; |
579 } | 534 } |
583 * | 538 * |
584 * @param list Destination chain. | 539 * @param list Destination chain. |
585 * @param type TLV type to add. | 540 * @param type TLV type to add. |
586 * @return The size of the value added. | 541 * @return The size of the value added. |
587 */ | 542 */ |
588 faim_internal int aim_tlvlist_add_noval(aim_tlvlist_t **list, const guint16 type) | 543 int aim_tlvlist_add_noval(aim_tlvlist_t **list, const guint16 type) |
589 { | 544 { |
590 return aim_tlvlist_add_raw(list, type, 0, NULL); | 545 return aim_tlvlist_add_raw(list, type, 0, NULL); |
591 } | 546 } |
592 | 547 |
593 /* | 548 /* |
594 * Note that the inner TLV chain will not be modifiable as a tlvchain once | 549 * Note that the inner TLV chain will not be modifiable as a tlvchain once |
595 * it is written using this. Or rather, it can be, but updates won't be | 550 * it is written using this. Or rather, it can be, but updates won't be |
596 * made to this. | 551 * made to this. |
597 * | 552 * |
598 * XXX should probably support sublists for real. | 553 * XXX should probably support sublists for real. |
599 * | 554 * |
600 * This is so neat. | 555 * This is so neat. |
601 * | 556 * |
602 * @param list Destination chain. | 557 * @param list Destination chain. |
603 * @param type TLV type to add. | 558 * @param type TLV type to add. |
604 * @param t1 The TLV chain you want to write. | 559 * @param t1 The TLV chain you want to write. |
605 * @return The number of bytes written to the destination TLV chain. | 560 * @return The number of bytes written to the destination TLV chain. |
606 * 0 is returned if there was an error or if the destination | 561 * 0 is returned if there was an error or if the destination |
607 * TLV chain has length 0. | 562 * TLV chain has length 0. |
608 */ | 563 */ |
609 faim_internal int aim_tlvlist_add_frozentlvlist(aim_tlvlist_t **list, guint16 type, aim_tlvlist_t **tl) | 564 int aim_tlvlist_add_frozentlvlist(aim_tlvlist_t **list, guint16 type, aim_tlvlist_t **tl) |
610 { | 565 { |
611 guint8 *buf; | 566 guint8 *buf; |
612 int buflen; | 567 int buflen; |
613 ByteStream bs; | 568 ByteStream bs; |
614 | 569 |
615 buflen = aim_tlvlist_size(tl); | 570 buflen = aim_tlvlist_size(tl); |
616 | 571 |
617 if (buflen <= 0) | 572 if (buflen <= 0) |
618 return 0; | 573 return 0; |
619 | 574 |
620 if (!(buf = malloc(buflen))) | 575 buf = malloc(buflen); |
621 return 0; | 576 |
622 | 577 byte_stream_init(&bs, buf, buflen); |
623 aim_bstream_init(&bs, buf, buflen); | |
624 | 578 |
625 aim_tlvlist_write(&bs, tl); | 579 aim_tlvlist_write(&bs, tl); |
626 | 580 |
627 aim_tlvlist_add_raw(list, type, aim_bstream_curpos(&bs), buf); | 581 aim_tlvlist_add_raw(list, type, byte_stream_curpos(&bs), buf); |
628 | 582 |
629 free(buf); | 583 free(buf); |
630 | 584 |
631 return buflen; | 585 return buflen; |
632 } | 586 } |
633 | 587 |
634 /** | 588 /** |
635 * Substitute a TLV of a given type with a new TLV of the same type. If | 589 * Substitute a TLV of a given type with a new TLV of the same type. If |
636 * you attempt to replace a TLV that does not exist, this function will | 590 * you attempt to replace a TLV that does not exist, this function will |
637 * just add a new TLV as if you called aim_tlvlist_add_raw(). | 591 * just add a new TLV as if you called aim_tlvlist_add_raw(). |
638 * | 592 * |
639 * @param list Desination chain (%NULL pointer if empty). | 593 * @param list Desination chain (%NULL pointer if empty). |
640 * @param type TLV type. | 594 * @param type TLV type. |
641 * @param length Length of string to add (not including %NULL). | 595 * @param length Length of string to add (not including %NULL). |
642 * @param value String to add. | 596 * @param value String to add. |
643 * @return The length of the TLV. | 597 * @return The length of the TLV. |
644 */ | 598 */ |
645 faim_internal int aim_tlvlist_replace_raw(aim_tlvlist_t **list, const guint16 type, const guint16 length, const guint8 *value) | 599 int aim_tlvlist_replace_raw(aim_tlvlist_t **list, const guint16 type, const guint16 length, const guint8 *value) |
646 { | 600 { |
647 aim_tlvlist_t *cur; | 601 aim_tlvlist_t *cur; |
648 | 602 |
649 if (list == NULL) | 603 if (list == NULL) |
650 return 0; | 604 return 0; |
654 return aim_tlvlist_add_raw(list, type, length, value); | 608 return aim_tlvlist_add_raw(list, type, length, value); |
655 | 609 |
656 free(cur->tlv->value); | 610 free(cur->tlv->value); |
657 cur->tlv->length = length; | 611 cur->tlv->length = length; |
658 if (cur->tlv->length > 0) { | 612 if (cur->tlv->length > 0) { |
659 cur->tlv->value = (guint8 *)malloc(cur->tlv->length); | 613 cur->tlv->value = g_memdup(value, length); |
660 memcpy(cur->tlv->value, value, cur->tlv->length); | |
661 } else | 614 } else |
662 cur->tlv->value = NULL; | 615 cur->tlv->value = NULL; |
663 | 616 |
664 return cur->tlv->length; | 617 return cur->tlv->length; |
665 } | 618 } |
672 * @param list Desination chain (%NULL pointer if empty). | 625 * @param list Desination chain (%NULL pointer if empty). |
673 * @param type TLV type. | 626 * @param type TLV type. |
674 * @param str String to add. | 627 * @param str String to add. |
675 * @return The length of the TLV. | 628 * @return The length of the TLV. |
676 */ | 629 */ |
677 faim_internal int aim_tlvlist_replace_str(aim_tlvlist_t **list, const guint16 type, const char *str) | 630 int aim_tlvlist_replace_str(aim_tlvlist_t **list, const guint16 type, const char *str) |
678 { | 631 { |
679 return aim_tlvlist_replace_raw(list, type, strlen(str), (const guchar *)str); | 632 return aim_tlvlist_replace_raw(list, type, strlen(str), (const guchar *)str); |
680 } | 633 } |
681 | 634 |
682 /** | 635 /** |
686 * | 639 * |
687 * @param list Desination chain (%NULL pointer if empty). | 640 * @param list Desination chain (%NULL pointer if empty). |
688 * @param type TLV type. | 641 * @param type TLV type. |
689 * @return The length of the TLV. | 642 * @return The length of the TLV. |
690 */ | 643 */ |
691 faim_internal int aim_tlvlist_replace_noval(aim_tlvlist_t **list, const guint16 type) | 644 int aim_tlvlist_replace_noval(aim_tlvlist_t **list, const guint16 type) |
692 { | 645 { |
693 return aim_tlvlist_replace_raw(list, type, 0, NULL); | 646 return aim_tlvlist_replace_raw(list, type, 0, NULL); |
694 } | 647 } |
695 | 648 |
696 /** | 649 /** |
701 * @param list Desination chain (%NULL pointer if empty). | 654 * @param list Desination chain (%NULL pointer if empty). |
702 * @param type TLV type. | 655 * @param type TLV type. |
703 * @param value 8 bit value to add. | 656 * @param value 8 bit value to add. |
704 * @return The length of the TLV. | 657 * @return The length of the TLV. |
705 */ | 658 */ |
706 faim_internal int aim_tlvlist_replace_8(aim_tlvlist_t **list, const guint16 type, const guint8 value) | 659 int aim_tlvlist_replace_8(aim_tlvlist_t **list, const guint16 type, const guint8 value) |
707 { | 660 { |
708 guint8 v8[1]; | 661 guint8 v8[1]; |
709 | 662 |
710 aimutil_put8(v8, value); | 663 aimutil_put8(v8, value); |
711 | 664 |
712 return aim_tlvlist_replace_raw(list, type, 1, v8); | 665 return aim_tlvlist_replace_raw(list, type, 1, v8); |
713 } | 666 } |
714 | 667 |
715 /** | 668 /** |
716 * Substitute a TLV of a given type with a new TLV of the same type. If | 669 * Substitute a TLV of a given type with a new TLV of the same type. If |
717 * you attempt to replace a TLV that does not exist, this function will | 670 * you attempt to replace a TLV that does not exist, this function will |
718 * just add a new TLV as if you called aim_tlvlist_add_raw(). | 671 * just add a new TLV as if you called aim_tlvlist_add_raw(). |
719 * | 672 * |
720 * @param list Desination chain (%NULL pointer if empty). | 673 * @param list Desination chain (%NULL pointer if empty). |
721 * @param type TLV type. | 674 * @param type TLV type. |
722 * @param value 32 bit value to add. | 675 * @param value 32 bit value to add. |
723 * @return The length of the TLV. | 676 * @return The length of the TLV. |
724 */ | 677 */ |
725 faim_internal int aim_tlvlist_replace_32(aim_tlvlist_t **list, const guint16 type, const guint32 value) | 678 int aim_tlvlist_replace_32(aim_tlvlist_t **list, const guint16 type, const guint32 value) |
726 { | 679 { |
727 guint8 v32[4]; | 680 guint8 v32[4]; |
728 | 681 |
729 aimutil_put32(v32, value); | 682 aimutil_put32(v32, value); |
730 | 683 |
731 return aim_tlvlist_replace_raw(list, type, 4, v32); | 684 return aim_tlvlist_replace_raw(list, type, 4, v32); |
732 } | 685 } |
733 | 686 |
734 /** | 687 /** |
735 * Remove a TLV of a given type. If you attempt to remove a TLV that | 688 * Remove a TLV of a given type. If you attempt to remove a TLV that |
736 * does not exist, nothing happens. | 689 * does not exist, nothing happens. |
737 * | 690 * |
738 * @param list Desination chain (%NULL pointer if empty). | 691 * @param list Desination chain (%NULL pointer if empty). |
739 * @param type TLV type. | 692 * @param type TLV type. |
740 */ | 693 */ |
741 faim_internal void aim_tlvlist_remove(aim_tlvlist_t **list, const guint16 type) | 694 void aim_tlvlist_remove(aim_tlvlist_t **list, const guint16 type) |
742 { | 695 { |
743 aim_tlvlist_t *del; | 696 aim_tlvlist_t *del; |
744 | 697 |
745 if (!list || !(*list)) | 698 if (!list || !(*list)) |
746 return; | 699 return; |
766 | 719 |
767 /** | 720 /** |
768 * Write a TLV chain into a data buffer. | 721 * Write a TLV chain into a data buffer. |
769 * | 722 * |
770 * Copies a TLV chain into a raw data buffer, writing only the number | 723 * Copies a TLV chain into a raw data buffer, writing only the number |
771 * of bytes specified. This operation does not free the chain; | 724 * of bytes specified. This operation does not free the chain; |
772 * aim_tlvlist_free() must still be called to free up the memory used | 725 * aim_tlvlist_free() must still be called to free up the memory used |
773 * by the chain structures. | 726 * by the chain structures. |
774 * | 727 * |
775 * XXX clean this up, make better use of bstreams | 728 * XXX clean this up, make better use of bstreams |
776 * | 729 * |
777 * @param bs Input bstream | 730 * @param bs Input bstream |
778 * @param list Source TLV chain | 731 * @param list Source TLV chain |
779 * @return Return 0 if the destination bstream is too small. | 732 * @return Return 0 if the destination bstream is too small. |
780 */ | 733 */ |
781 faim_internal int aim_tlvlist_write(ByteStream *bs, aim_tlvlist_t **list) | 734 int aim_tlvlist_write(ByteStream *bs, aim_tlvlist_t **list) |
782 { | 735 { |
783 int goodbuflen; | 736 int goodbuflen; |
784 aim_tlvlist_t *cur; | 737 aim_tlvlist_t *cur; |
785 | 738 |
786 /* do an initial run to test total length */ | 739 /* do an initial run to test total length */ |
787 goodbuflen = aim_tlvlist_size(list); | 740 goodbuflen = aim_tlvlist_size(list); |
788 | 741 |
789 if (goodbuflen > aim_bstream_empty(bs)) | 742 if (goodbuflen > byte_stream_empty(bs)) |
790 return 0; /* not enough buffer */ | 743 return 0; /* not enough buffer */ |
791 | 744 |
792 /* do the real write-out */ | 745 /* do the real write-out */ |
793 for (cur = *list; cur; cur = cur->next) { | 746 for (cur = *list; cur; cur = cur->next) { |
794 aimbs_put16(bs, cur->tlv->type); | 747 byte_stream_put16(bs, cur->tlv->type); |
795 aimbs_put16(bs, cur->tlv->length); | 748 byte_stream_put16(bs, cur->tlv->length); |
796 if (cur->tlv->length) | 749 if (cur->tlv->length) |
797 aimbs_putraw(bs, cur->tlv->value, cur->tlv->length); | 750 byte_stream_putraw(bs, cur->tlv->value, cur->tlv->length); |
798 } | 751 } |
799 | 752 |
800 return 1; /* XXX this is a nonsensical return */ | 753 return 1; /* XXX this is a nonsensical return */ |
801 } | 754 } |
802 | 755 |
803 | 756 |
804 /** | 757 /** |
805 * Grab the Nth TLV of type type in the TLV list list. | 758 * Grab the Nth TLV of type type in the TLV list list. |
806 * | 759 * |
807 * Returns a pointer to an aim_tlv_t of the specified type; | 760 * Returns a pointer to an aim_tlv_t of the specified type; |
808 * %NULL on error. The @nth parameter is specified starting at %1. | 761 * %NULL on error. The @nth parameter is specified starting at %1. |
809 * In most cases, there will be no more than one TLV of any type | 762 * In most cases, there will be no more than one TLV of any type |
810 * in a chain. | 763 * in a chain. |
811 * | 764 * |
812 * @param list Source chain. | 765 * @param list Source chain. |
813 * @param type Requested TLV type. | 766 * @param type Requested TLV type. |
814 * @param nth Index of TLV of type to get. | 767 * @param nth Index of TLV of type to get. |
815 * @return The TLV you were looking for, or NULL if one could not be found. | 768 * @return The TLV you were looking for, or NULL if one could not be found. |
816 */ | 769 */ |
817 faim_internal aim_tlv_t *aim_tlv_gettlv(aim_tlvlist_t *list, const guint16 type, const int nth) | 770 aim_tlv_t *aim_tlv_gettlv(aim_tlvlist_t *list, const guint16 type, const int nth) |
818 { | 771 { |
819 aim_tlvlist_t *cur; | 772 aim_tlvlist_t *cur; |
820 int i; | 773 int i; |
821 | 774 |
822 for (cur = list, i = 0; cur; cur = cur->next) { | 775 for (cur = list, i = 0; cur; cur = cur->next) { |
838 * @param type Requested TLV type. | 791 * @param type Requested TLV type. |
839 * @param nth Index of TLV of type to get. | 792 * @param nth Index of TLV of type to get. |
840 * @return The length of the data in this TLV, or -1 if the TLV could not be | 793 * @return The length of the data in this TLV, or -1 if the TLV could not be |
841 * found. Unless -1 is returned, this value will be 2 bytes. | 794 * found. Unless -1 is returned, this value will be 2 bytes. |
842 */ | 795 */ |
843 faim_internal int aim_tlv_getlength(aim_tlvlist_t *list, const guint16 type, const int nth) | 796 int aim_tlv_getlength(aim_tlvlist_t *list, const guint16 type, const int nth) |
844 { | 797 { |
845 aim_tlvlist_t *cur; | 798 aim_tlvlist_t *cur; |
846 int i; | 799 int i; |
847 | 800 |
848 for (cur = list, i = 0; cur; cur = cur->next) { | 801 for (cur = list, i = 0; cur; cur = cur->next) { |
865 * @param nth Index of TLV to return. | 818 * @param nth Index of TLV to return. |
866 * @return The value of the TLV you were looking for, or NULL if one could | 819 * @return The value of the TLV you were looking for, or NULL if one could |
867 * not be found. This is a dynamic buffer and must be freed by the | 820 * not be found. This is a dynamic buffer and must be freed by the |
868 * caller. | 821 * caller. |
869 */ | 822 */ |
870 faim_internal char *aim_tlv_getstr(aim_tlvlist_t *list, const guint16 type, const int nth) | 823 char *aim_tlv_getstr(aim_tlvlist_t *list, const guint16 type, const int nth) |
871 { | 824 { |
872 aim_tlv_t *tlv; | 825 aim_tlv_t *tlv; |
873 char *newstr; | 826 char *ret; |
874 | 827 |
875 if (!(tlv = aim_tlv_gettlv(list, type, nth))) | 828 if (!(tlv = aim_tlv_gettlv(list, type, nth))) |
876 return NULL; | 829 return NULL; |
877 | 830 |
878 newstr = (char *) malloc(tlv->length + 1); | 831 ret = malloc(tlv->length + 1); |
879 memcpy(newstr, tlv->value, tlv->length); | 832 memcpy(ret, tlv->value, tlv->length); |
880 newstr[tlv->length] = '\0'; | 833 ret[tlv->length] = '\0'; |
881 | 834 |
882 return newstr; | 835 return ret; |
883 } | 836 } |
884 | 837 |
885 /** | 838 /** |
886 * Retrieve the data from the nth TLV in the given TLV chain as an 8bit | 839 * Retrieve the data from the nth TLV in the given TLV chain as an 8bit |
887 * integer. | 840 * integer. |
888 * | 841 * |
889 * @param list Source TLV chain. | 842 * @param list Source TLV chain. |
890 * @param type TLV type to search for. | 843 * @param type TLV type to search for. |
891 * @param nth Index of TLV to return. | 844 * @param nth Index of TLV to return. |
892 * @return The value the TLV you were looking for, or 0 if one could | 845 * @return The value the TLV you were looking for, or 0 if one could |
893 * not be found. | 846 * not be found. |
894 */ | 847 */ |
895 faim_internal guint8 aim_tlv_get8(aim_tlvlist_t *list, const guint16 type, const int nth) | 848 guint8 aim_tlv_get8(aim_tlvlist_t *list, const guint16 type, const int nth) |
896 { | 849 { |
897 aim_tlv_t *tlv; | 850 aim_tlv_t *tlv; |
898 | 851 |
899 if (!(tlv = aim_tlv_gettlv(list, type, nth))) | 852 if (!(tlv = aim_tlv_gettlv(list, type, nth))) |
900 return 0; /* erm */ | 853 return 0; /* erm */ |
901 return aimutil_get8(tlv->value); | 854 return aimutil_get8(tlv->value); |
902 } | 855 } |
903 | 856 |
904 /** | 857 /** |
905 * Retrieve the data from the nth TLV in the given TLV chain as a 16bit | 858 * Retrieve the data from the nth TLV in the given TLV chain as a 16bit |
906 * integer. | 859 * integer. |
907 * | 860 * |
908 * @param list Source TLV chain. | 861 * @param list Source TLV chain. |
909 * @param type TLV type to search for. | 862 * @param type TLV type to search for. |
910 * @param nth Index of TLV to return. | 863 * @param nth Index of TLV to return. |
911 * @return The value the TLV you were looking for, or 0 if one could | 864 * @return The value the TLV you were looking for, or 0 if one could |
912 * not be found. | 865 * not be found. |
913 */ | 866 */ |
914 faim_internal guint16 aim_tlv_get16(aim_tlvlist_t *list, const guint16 type, const int nth) | 867 guint16 aim_tlv_get16(aim_tlvlist_t *list, const guint16 type, const int nth) |
915 { | 868 { |
916 aim_tlv_t *tlv; | 869 aim_tlv_t *tlv; |
917 | 870 |
918 if (!(tlv = aim_tlv_gettlv(list, type, nth))) | 871 if (!(tlv = aim_tlv_gettlv(list, type, nth))) |
919 return 0; /* erm */ | 872 return 0; /* erm */ |
920 return aimutil_get16(tlv->value); | 873 return aimutil_get16(tlv->value); |
921 } | 874 } |
922 | 875 |
923 /** | 876 /** |
924 * Retrieve the data from the nth TLV in the given TLV chain as a 32bit | 877 * Retrieve the data from the nth TLV in the given TLV chain as a 32bit |
925 * integer. | 878 * integer. |
926 * | 879 * |
927 * @param list Source TLV chain. | 880 * @param list Source TLV chain. |
928 * @param type TLV type to search for. | 881 * @param type TLV type to search for. |
929 * @param nth Index of TLV to return. | 882 * @param nth Index of TLV to return. |
930 * @return The value the TLV you were looking for, or 0 if one could | 883 * @return The value the TLV you were looking for, or 0 if one could |
931 * not be found. | 884 * not be found. |
932 */ | 885 */ |
933 faim_internal guint32 aim_tlv_get32(aim_tlvlist_t *list, const guint16 type, const int nth) | 886 guint32 aim_tlv_get32(aim_tlvlist_t *list, const guint16 type, const int nth) |
934 { | 887 { |
935 aim_tlv_t *tlv; | 888 aim_tlv_t *tlv; |
936 | 889 |
937 if (!(tlv = aim_tlv_gettlv(list, type, nth))) | 890 if (!(tlv = aim_tlv_gettlv(list, type, nth))) |
938 return 0; /* erm */ | 891 return 0; /* erm */ |