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