Mercurial > pidgin
annotate libfaim/aim_tlv.c @ 312:3069be4c291e
[gaim-migrate @ 322]
I don't know why I did this. I have homework due in 15 hours that I haven't
started yet, and it's in a language I don't know and it's a project I don't
understand. If my teacher knew about this, he would be pissed. He looks
pissed all the time, even when he's not. When he smiles he looks devilish.
Maybe I only think that because literally half the class flunked the midterm.
I am not joking about that. More people got F's than A, B, and C combined.
It's 2 am and the homework's due at 5 tomorrow so what do I do? Get chat to
work. Wow. That's going to look good on my resume. "Why did you flunk this
class?" "Because I was getting chat in Instant Messenger to work." Not that
that's not something to be proud of, but I wonder which is more important to
employers. The big battle, experience versus education. Just because you
got good grades in college doesn't mean you're smarter than someone who
flunked, it just means you put in the effort necessary to get a better grade
and the other person didn't. Maybe the person who flunked was working on
real honest-to-god actually *used* software, as opposed to some stupid tree
that only gets used for a fringe branch of computer science that doesn't
offer much more than a normal heap or binary search tree offers. Maybe the
person was out there reverse-engineering protocols and allowing cross-
platform communication to occur, creating interoperability and causing a
greater demand not only for the product, but for the platform it runs on!
Given the choices, who would you pick? Someone who was told how to code a
tree and managed to get it to work, or someone who increases your userbase
and marketability?
Enough of my rant for a while. I've had waaaaay too much sugar (gummy candy is
deadly).
committer: Tailor Script <tailor@pidgin.im>
author | Eric Warmenhoven <eric@warmenhoven.org> |
---|---|
date | Fri, 02 Jun 2000 09:11:48 +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 } |