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