Mercurial > pidgin
annotate libfaim/aim_tlv.c @ 574:0aca48e1baa7
[gaim-migrate @ 584]
smileys wrap more properly now
committer: Tailor Script <tailor@pidgin.im>
author | Eric Warmenhoven <eric@warmenhoven.org> |
---|---|
date | Tue, 01 Aug 2000 23:50:32 +0000 |
parents | 6d78b988b479 |
children | 72e556f6b99d |
rev | line source |
---|---|
283
0f14e6d8a51b
[gaim-migrate @ 293]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
237
diff
changeset
|
1 #include <faim/aim.h> |
2 | 2 |
237 | 3 struct aim_tlvlist_t *aim_readtlvchain(u_char *buf, int maxlen) |
4 { | |
5 int pos; | |
6 struct aim_tlvlist_t *list; | |
7 struct aim_tlvlist_t *cur; | |
8 | |
9 u_short type; | |
10 u_short length; | |
11 | |
12 if (!buf) | |
13 return NULL; | |
14 | |
15 list = NULL; | |
16 | |
17 pos = 0; | |
18 | |
19 while (pos < maxlen) | |
20 { | |
21 type = aimutil_get16(buf+pos); | |
22 pos += 2; | |
23 | |
24 if (pos < maxlen) | |
25 { | |
26 length = aimutil_get16(buf+pos); | |
27 pos += 2; | |
28 | |
29 if ((pos+length) <= maxlen) | |
30 { | |
446
6d78b988b479
[gaim-migrate @ 456]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
31 /* |
6d78b988b479
[gaim-migrate @ 456]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
32 * Okay, so now AOL has decided that any TLV of |
6d78b988b479
[gaim-migrate @ 456]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
33 * type 0x0013 can only be two bytes, despite |
6d78b988b479
[gaim-migrate @ 456]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
34 * what the actual given length is. So here |
6d78b988b479
[gaim-migrate @ 456]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
35 * we dump any invalid TLVs of that sort. Hopefully |
6d78b988b479
[gaim-migrate @ 456]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
36 * theres no special cases to this special case. |
6d78b988b479
[gaim-migrate @ 456]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
37 * - mid (30jun2000) |
6d78b988b479
[gaim-migrate @ 456]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
38 */ |
6d78b988b479
[gaim-migrate @ 456]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
39 if ((type == 0x0013) && (length != 0x0002)) { |
6d78b988b479
[gaim-migrate @ 456]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
40 printf("faim: skipping TLV t(0013) with invalid length (0x%04x)\n", length); |
6d78b988b479
[gaim-migrate @ 456]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
41 length = 0x0002; |
6d78b988b479
[gaim-migrate @ 456]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
42 } else { |
6d78b988b479
[gaim-migrate @ 456]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
43 cur = (struct aim_tlvlist_t *)malloc(sizeof(struct aim_tlvlist_t)); |
6d78b988b479
[gaim-migrate @ 456]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
44 memset(cur, 0x00, sizeof(struct aim_tlvlist_t)); |
237 | 45 |
446
6d78b988b479
[gaim-migrate @ 456]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
46 cur->tlv = aim_createtlv(); |
6d78b988b479
[gaim-migrate @ 456]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
47 cur->tlv->type = type; |
6d78b988b479
[gaim-migrate @ 456]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
48 cur->tlv->length = length; |
6d78b988b479
[gaim-migrate @ 456]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
49 cur->tlv->value = (u_char *)malloc(length*sizeof(u_char)); |
6d78b988b479
[gaim-migrate @ 456]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
50 memcpy(cur->tlv->value, buf+pos, length); |
237 | 51 |
446
6d78b988b479
[gaim-migrate @ 456]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
52 cur->next = list; |
6d78b988b479
[gaim-migrate @ 456]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
53 list = cur; |
6d78b988b479
[gaim-migrate @ 456]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
54 } |
237 | 55 pos += length; |
56 } | |
57 } | |
58 } | |
59 | |
60 return list; | |
61 } | |
62 | |
63 void aim_freetlvchain(struct aim_tlvlist_t **list) | |
64 { | |
65 struct aim_tlvlist_t *cur, *cur2; | |
66 | |
67 if (!list || !(*list)) | |
68 return; | |
69 | |
70 cur = *list; | |
71 while (cur) | |
72 { | |
73 aim_freetlv(&cur->tlv); | |
74 cur2 = cur->next; | |
75 free(cur); | |
76 cur = cur2; | |
77 } | |
78 list = NULL; | |
79 return; | |
80 } | |
81 | |
82 int aim_counttlvchain(struct aim_tlvlist_t **list) | |
83 { | |
84 struct aim_tlvlist_t *cur; | |
85 int count = 0; | |
86 | |
87 if (!list || !(*list)) | |
88 return 0; | |
89 | |
90 for (cur = *list; cur; cur = cur->next) | |
91 count++; | |
92 | |
93 return count; | |
94 } | |
95 | |
96 int aim_addtlvtochain_str(struct aim_tlvlist_t **list, unsigned short type, char *str, int len) | |
97 { | |
98 struct aim_tlvlist_t *new; | |
99 struct aim_tlvlist_t *cur; | |
100 | |
101 if (!list) | |
102 return 0; | |
103 | |
104 new = (struct aim_tlvlist_t *)malloc(sizeof(struct aim_tlvlist_t)); | |
105 memset(new, 0x00, sizeof(struct aim_tlvlist_t)); | |
106 | |
107 new->tlv = aim_createtlv(); | |
108 new->tlv->type = type; | |
109 new->tlv->length = len; | |
110 new->tlv->value = (u_char *)malloc(new->tlv->length*sizeof(u_char)); | |
111 memcpy(new->tlv->value, str, new->tlv->length); | |
112 | |
113 new->next = NULL; | |
114 | |
115 if (*list == NULL) { | |
116 *list = new; | |
117 } else if ((*list)->next == NULL) { | |
118 (*list)->next = new; | |
119 } else { | |
120 for(cur = *list; cur->next; cur = cur->next) | |
121 ; | |
122 cur->next = new; | |
123 } | |
124 return new->tlv->length; | |
125 } | |
126 | |
127 int aim_addtlvtochain16(struct aim_tlvlist_t **list, unsigned short type, unsigned short val) | |
128 { | |
129 struct aim_tlvlist_t *new; | |
130 struct aim_tlvlist_t *cur; | |
131 | |
132 if (!list) | |
133 return 0; | |
134 | |
135 new = (struct aim_tlvlist_t *)malloc(sizeof(struct aim_tlvlist_t)); | |
136 memset(new, 0x00, sizeof(struct aim_tlvlist_t)); | |
137 | |
138 new->tlv = aim_createtlv(); | |
139 new->tlv->type = type; | |
140 new->tlv->length = 2; | |
141 new->tlv->value = (u_char *)malloc(new->tlv->length*sizeof(u_char)); | |
142 aimutil_put16(new->tlv->value, val); | |
143 | |
144 new->next = NULL; | |
145 | |
146 if (*list == NULL) { | |
147 *list = new; | |
148 } else if ((*list)->next == NULL) { | |
149 (*list)->next = new; | |
150 } else { | |
151 for(cur = *list; cur->next; cur = cur->next) | |
152 ; | |
153 cur->next = new; | |
154 } | |
155 return 2; | |
156 } | |
157 | |
158 int aim_addtlvtochain32(struct aim_tlvlist_t **list, unsigned short type, unsigned long val) | |
159 { | |
160 struct aim_tlvlist_t *new; | |
161 struct aim_tlvlist_t *cur; | |
162 | |
163 if (!list) | |
164 return 0; | |
165 | |
166 new = (struct aim_tlvlist_t *)malloc(sizeof(struct aim_tlvlist_t)); | |
167 memset(new, 0x00, sizeof(struct aim_tlvlist_t)); | |
168 | |
169 new->tlv = aim_createtlv(); | |
170 new->tlv->type = type; | |
171 new->tlv->length = 4; | |
172 new->tlv->value = (u_char *)malloc(new->tlv->length*sizeof(u_char)); | |
173 aimutil_put32(new->tlv->value, val); | |
174 | |
175 new->next = NULL; | |
176 | |
177 if (*list == NULL) { | |
178 *list = new; | |
179 } else if ((*list)->next == NULL) { | |
180 (*list)->next = new; | |
181 } else { | |
182 for(cur = *list; cur->next; cur = cur->next) | |
183 ; | |
184 cur->next = new; | |
185 } | |
186 return 4; | |
187 } | |
188 | |
189 int aim_writetlvchain(u_char *buf, int buflen, struct aim_tlvlist_t **list) | |
190 { | |
191 int goodbuflen = 0; | |
192 int i = 0; | |
193 struct aim_tlvlist_t *cur; | |
194 | |
195 if (!list || !buf || !buflen) | |
196 return 0; | |
197 | |
198 /* do an initial run to test total length */ | |
199 for (cur = *list; cur; cur = cur->next) { | |
200 goodbuflen += 2 + 2; /* type + len */ | |
201 goodbuflen += cur->tlv->length; | |
202 } | |
203 | |
204 if (goodbuflen > buflen) | |
205 return 0; /* not enough buffer */ | |
206 | |
207 /* do the real write-out */ | |
208 for (cur = *list; cur; cur = cur->next) { | |
209 i += aimutil_put16(buf+i, cur->tlv->type); | |
210 i += aimutil_put16(buf+i, cur->tlv->length); | |
211 memcpy(buf+i, cur->tlv->value, cur->tlv->length); | |
212 i += cur->tlv->length; | |
213 } | |
214 | |
215 return i; | |
216 } | |
217 | |
218 | |
219 /* | |
220 * Grab the Nth TLV of type type in the TLV list list. | |
221 */ | |
222 struct aim_tlv_t *aim_gettlv(struct aim_tlvlist_t *list, u_short type, int nth) | |
223 { | |
224 int i; | |
225 struct aim_tlvlist_t *cur; | |
226 | |
227 i = 0; | |
228 for (cur = list; cur != NULL; cur = cur->next) | |
229 { | |
230 if (cur && cur->tlv) | |
231 { | |
232 if (cur->tlv->type == type) | |
233 i++; | |
234 if (i >= nth) | |
235 return cur->tlv; | |
236 } | |
237 } | |
238 return NULL; | |
239 } | |
240 | |
241 char *aim_gettlv_str(struct aim_tlvlist_t *list, u_short type, int nth) | |
242 { | |
243 struct aim_tlv_t *tlv; | |
244 char *newstr; | |
245 | |
246 if (!(tlv = aim_gettlv(list, type, nth))) | |
247 return NULL; | |
248 | |
249 newstr = (char *) malloc(tlv->length + 1); | |
250 memcpy(newstr, tlv->value, tlv->length); | |
251 *(newstr + tlv->length) = '\0'; | |
252 | |
253 return newstr; | |
254 } | |
255 | |
2 | 256 struct aim_tlv_t *aim_grabtlv(u_char *src) |
257 { | |
258 struct aim_tlv_t *dest = NULL; | |
259 | |
260 dest = aim_createtlv(); | |
261 | |
262 dest->type = src[0] << 8; | |
263 dest->type += src[1]; | |
264 | |
265 dest->length = src[2] << 8; | |
266 dest->length += src[3]; | |
267 | |
268 dest->value = (u_char *) malloc(dest->length*sizeof(u_char)); | |
269 memset(dest->value, 0, dest->length*sizeof(u_char)); | |
270 | |
271 memcpy(dest->value, &(src[4]), dest->length*sizeof(u_char)); | |
272 | |
273 return dest; | |
274 } | |
275 | |
276 struct aim_tlv_t *aim_grabtlvstr(u_char *src) | |
277 { | |
278 struct aim_tlv_t *dest = NULL; | |
279 | |
280 dest = aim_createtlv(); | |
281 | |
282 dest->type = src[0] << 8; | |
283 dest->type += src[1]; | |
284 | |
285 dest->length = src[2] << 8; | |
286 dest->length += src[3]; | |
287 | |
288 dest->value = (u_char *) malloc((dest->length+1)*sizeof(u_char)); | |
289 memset(dest->value, 0, (dest->length+1)*sizeof(u_char)); | |
290 | |
291 memcpy(dest->value, &(src[4]), dest->length*sizeof(u_char)); | |
292 dest->value[dest->length] = '\0'; | |
293 | |
294 return dest; | |
295 } | |
296 | |
297 int aim_puttlv (u_char *dest, struct aim_tlv_t *newtlv) | |
298 { | |
299 int i=0; | |
300 | |
301 dest[i++] = newtlv->type >> 8; | |
302 dest[i++] = newtlv->type & 0x00FF; | |
303 dest[i++] = newtlv->length >> 8; | |
304 dest[i++] = newtlv->length & 0x00FF; | |
305 memcpy(&(dest[i]), newtlv->value, newtlv->length); | |
306 i+=newtlv->length; | |
307 return i; | |
308 } | |
309 | |
310 struct aim_tlv_t *aim_createtlv(void) | |
311 { | |
312 struct aim_tlv_t *newtlv = NULL; | |
313 newtlv = (struct aim_tlv_t *)malloc(sizeof(struct aim_tlv_t)); | |
314 memset(newtlv, 0, sizeof(struct aim_tlv_t)); | |
315 return newtlv; | |
316 } | |
317 | |
318 int aim_freetlv(struct aim_tlv_t **oldtlv) | |
319 { | |
320 if (!oldtlv) | |
321 return -1; | |
322 if (!*oldtlv) | |
323 return -1; | |
324 if ((*oldtlv)->value) | |
325 free((*oldtlv)->value); | |
326 free(*(oldtlv)); | |
327 (*oldtlv) = NULL; | |
328 | |
329 return 0; | |
330 } | |
331 | |
332 int aim_puttlv_16(u_char *buf, u_short t, u_short v) | |
333 { | |
334 int curbyte=0; | |
237 | 335 curbyte += aimutil_put16(buf+curbyte, (u_short)(t&0xffff)); |
336 curbyte += aimutil_put16(buf+curbyte, (u_short)0x0002); | |
337 curbyte += aimutil_put16(buf+curbyte, (u_short)(v&0xffff)); | |
338 return curbyte; | |
339 } | |
340 | |
341 int aim_puttlv_32(u_char *buf, u_short t, u_long v) | |
342 { | |
343 int curbyte=0; | |
344 curbyte += aimutil_put16(buf+curbyte, (u_short)(t&0xffff)); | |
345 curbyte += aimutil_put16(buf+curbyte, (u_short)0x0004); | |
346 curbyte += aimutil_put32(buf+curbyte, (u_long)(v&0xffffffff)); | |
2 | 347 return curbyte; |
348 } | |
237 | 349 |
350 int aim_puttlv_str(u_char *buf, u_short t, u_short l, u_char *v) | |
351 { | |
352 int curbyte; | |
353 | |
354 curbyte = 0; | |
355 curbyte += aimutil_put16(buf+curbyte, (u_short)(t&0xffff)); | |
356 curbyte += aimutil_put16(buf+curbyte, (u_short)(l&0xffff)); | |
357 if (v) | |
358 memcpy(buf+curbyte, v, l); | |
359 curbyte += l; | |
360 return curbyte; | |
361 } |