]> andersk Git - libfaim.git/blob - aim_tlv.c
Fixed makefile.
[libfaim.git] / aim_tlv.c
1 #include <faim/aim.h>
2
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
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;
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));
335   return curbyte;
336 }
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 }
This page took 0.076538 seconds and 5 git commands to generate.