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