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