]> andersk Git - libfaim.git/blame - aim_tlv.c
Oops.
[libfaim.git] / aim_tlv.c
CommitLineData
a25832e6 1#include <faim/aim.h>
9de3ca7e 2
be67fdd0 3/**
4 * aim_readtlvchain - Read a TLV chain from a buffer.
5 * @buf: Input buffer
6 * @maxlen: Length of input buffer
7 *
8 * Reads and parses a series of TLV patterns from a data buffer; the
9 * returned structure is manipulatable with the rest of the TLV
10 * routines. When done with a TLV chain, aim_freetlvchain() should
11 * be called to free the dynamic substructures.
12 *
13 */
14faim_export struct aim_tlvlist_t *aim_readtlvchain(u_char *buf, int maxlen)
49c8a2fa 15{
16 int pos;
17 struct aim_tlvlist_t *list;
18 struct aim_tlvlist_t *cur;
19
20 u_short type;
21 u_short length;
22
23 if (!buf)
24 return NULL;
25
26 list = NULL;
27
28 pos = 0;
29
30 while (pos < maxlen)
31 {
32 type = aimutil_get16(buf+pos);
33 pos += 2;
34
35 if (pos < maxlen)
36 {
37 length = aimutil_get16(buf+pos);
38 pos += 2;
39
40 if ((pos+length) <= maxlen)
41 {
13ebc4c4 42 /*
43 * Okay, so now AOL has decided that any TLV of
44 * type 0x0013 can only be two bytes, despite
45 * what the actual given length is. So here
46 * we dump any invalid TLVs of that sort. Hopefully
47 * theres no special cases to this special case.
48 * - mid (30jun2000)
49 */
50 if ((type == 0x0013) && (length != 0x0002)) {
51 printf("faim: skipping TLV t(0013) with invalid length (0x%04x)\n", length);
52 length = 0x0002;
53 } else {
54 cur = (struct aim_tlvlist_t *)malloc(sizeof(struct aim_tlvlist_t));
55 memset(cur, 0x00, sizeof(struct aim_tlvlist_t));
49c8a2fa 56
13ebc4c4 57 cur->tlv = aim_createtlv();
58 cur->tlv->type = type;
8515d6a5 59 cur->tlv->length = length;
60 if (length) {
61 cur->tlv->value = (unsigned char *)malloc(length);
62 memcpy(cur->tlv->value, buf+pos, length);
63 }
98c88242 64
13ebc4c4 65 cur->next = list;
66 list = cur;
67 }
49c8a2fa 68 pos += length;
69 }
70 }
71 }
72
73 return list;
74}
75
be67fdd0 76/**
77 * aim_freetlvchain - Free a TLV chain structure
78 * @list: Chain to be freed
79 *
80 * Walks the list of TLVs in the passed TLV chain and
81 * frees each one. Note that any references to this data
82 * should be removed before calling this.
83 *
84 */
85faim_export void aim_freetlvchain(struct aim_tlvlist_t **list)
49c8a2fa 86{
87 struct aim_tlvlist_t *cur, *cur2;
88
89 if (!list || !(*list))
90 return;
91
92 cur = *list;
93 while (cur)
94 {
95 aim_freetlv(&cur->tlv);
96 cur2 = cur->next;
97 free(cur);
98 cur = cur2;
99 }
100 list = NULL;
101 return;
102}
103
be67fdd0 104/**
105 * aim_counttlvchain - Count the number of TLVs in a chain
106 * @list: Chain to be counted
107 *
108 * Returns the number of TLVs stored in the passed chain.
109 *
110 */
111faim_export int aim_counttlvchain(struct aim_tlvlist_t **list)
e6b05d80 112{
113 struct aim_tlvlist_t *cur;
114 int count = 0;
115
116 if (!list || !(*list))
117 return 0;
118
119 for (cur = *list; cur; cur = cur->next)
120 count++;
121
122 return count;
123}
124
be67fdd0 125/**
126 * aim_sizetlvchain - Count the number of bytes in a TLV chain
127 * @list: Chain to be sized
128 *
129 * Returns the number of bytes that would be needed to
130 * write the passed TLV chain to a data buffer.
131 *
132 */
3b101546 133faim_export int aim_sizetlvchain(struct aim_tlvlist_t **list)
134{
135 struct aim_tlvlist_t *cur;
136 int size = 0;
137
138 if (!list || !(*list))
139 return 0;
140
141 for (cur = *list; cur; cur = cur->next)
142 size += (4 + cur->tlv->length);
143
144 return size;
145}
146
be67fdd0 147/**
148 * aim_addtlvtochain_str - Add a string to a TLV chain
149 * @list: Desination chain (%NULL pointer if empty)
150 * @type: TLV type
151 * @str: String to add
152 * @len: Length of string to add (not including %NULL)
153 *
154 * Adds the passed string as a TLV element of the passed type
155 * to the TLV chain.
156 *
157 */
158faim_export int aim_addtlvtochain_str(struct aim_tlvlist_t **list, unsigned short type, char *str, int len)
0e2be272 159{
a15d82b1 160 struct aim_tlvlist_t *newtlv;
0e2be272 161 struct aim_tlvlist_t *cur;
162
163 if (!list)
164 return 0;
165
a15d82b1 166 newtlv = (struct aim_tlvlist_t *)malloc(sizeof(struct aim_tlvlist_t));
167 memset(newtlv, 0x00, sizeof(struct aim_tlvlist_t));
0e2be272 168
a15d82b1 169 newtlv->tlv = aim_createtlv();
170 newtlv->tlv->type = type;
171 newtlv->tlv->length = len;
172 newtlv->tlv->value = (unsigned char *)malloc(newtlv->tlv->length*sizeof(unsigned char));
173 memcpy(newtlv->tlv->value, str, newtlv->tlv->length);
0e2be272 174
a15d82b1 175 newtlv->next = NULL;
0e2be272 176
177 if (*list == NULL) {
a15d82b1 178 *list = newtlv;
0e2be272 179 } else if ((*list)->next == NULL) {
a15d82b1 180 (*list)->next = newtlv;
0e2be272 181 } else {
182 for(cur = *list; cur->next; cur = cur->next)
183 ;
a15d82b1 184 cur->next = newtlv;
0e2be272 185 }
a15d82b1 186 return newtlv->tlv->length;
0e2be272 187}
188
be67fdd0 189/**
190 * aim_addtlvtochain16 - Add a 16bit integer to a TLV chain
191 * @list: Destination chain
192 * @type: TLV type to add
193 * @val: Value to add
194 *
195 * Adds a two-byte unsigned integer to a TLV chain.
196 *
197 */
198faim_export int aim_addtlvtochain16(struct aim_tlvlist_t **list, unsigned short type, unsigned short val)
0e2be272 199{
a15d82b1 200 struct aim_tlvlist_t *newtl;
0e2be272 201 struct aim_tlvlist_t *cur;
202
203 if (!list)
204 return 0;
205
a15d82b1 206 newtl = (struct aim_tlvlist_t *)malloc(sizeof(struct aim_tlvlist_t));
207 memset(newtl, 0x00, sizeof(struct aim_tlvlist_t));
0e2be272 208
a15d82b1 209 newtl->tlv = aim_createtlv();
210 newtl->tlv->type = type;
211 newtl->tlv->length = 2;
212 newtl->tlv->value = (unsigned char *)malloc(newtl->tlv->length*sizeof(unsigned char));
213 aimutil_put16(newtl->tlv->value, val);
0e2be272 214
a15d82b1 215 newtl->next = NULL;
0e2be272 216
217 if (*list == NULL) {
a15d82b1 218 *list = newtl;
0e2be272 219 } else if ((*list)->next == NULL) {
a15d82b1 220 (*list)->next = newtl;
0e2be272 221 } else {
222 for(cur = *list; cur->next; cur = cur->next)
223 ;
a15d82b1 224 cur->next = newtl;
0e2be272 225 }
226 return 2;
227}
228
be67fdd0 229/**
230 * aim_addtlvtochain32 - Add a 32bit integer to a TLV chain
231 * @list: Destination chain
232 * @type: TLV type to add
233 * @val: Value to add
234 *
235 * Adds a four-byte unsigned integer to a TLV chain.
236 *
237 */
238faim_export int aim_addtlvtochain32(struct aim_tlvlist_t **list, unsigned short type, unsigned long val)
0e2be272 239{
a15d82b1 240 struct aim_tlvlist_t *newtl;
0e2be272 241 struct aim_tlvlist_t *cur;
242
243 if (!list)
244 return 0;
245
a15d82b1 246 newtl = (struct aim_tlvlist_t *)malloc(sizeof(struct aim_tlvlist_t));
247 memset(newtl, 0x00, sizeof(struct aim_tlvlist_t));
0e2be272 248
a15d82b1 249 newtl->tlv = aim_createtlv();
250 newtl->tlv->type = type;
251 newtl->tlv->length = 4;
252 newtl->tlv->value = (unsigned char *)malloc(newtl->tlv->length*sizeof(unsigned char));
253 aimutil_put32(newtl->tlv->value, val);
0e2be272 254
a15d82b1 255 newtl->next = NULL;
0e2be272 256
257 if (*list == NULL) {
a15d82b1 258 *list = newtl;
0e2be272 259 } else if ((*list)->next == NULL) {
a15d82b1 260 (*list)->next = newtl;
0e2be272 261 } else {
262 for(cur = *list; cur->next; cur = cur->next)
263 ;
a15d82b1 264 cur->next = newtl;
0e2be272 265 }
266 return 4;
267}
268
be67fdd0 269/**
270 * aim_addtlvtochain_caps - Add a capability block to a TLV chain
271 * @list: Destination chain
272 * @type: TLV type to add
273 * @caps: Bitfield of capability flags to send
274 *
275 * Adds a block of capability blocks to a TLV chain. The bitfield
276 * passed in should be a bitwise %OR of any of the %AIM_CAPS constants:
277 *
278 * %AIM_CAPS_BUDDYICON Supports Buddy Icons
279 *
280 * %AIM_CAPS_VOICE Supports Voice Chat
281 *
282 * %AIM_CAPS_IMIMAGE Supports DirectIM/IMImage
283 *
284 * %AIM_CAPS_CHAT Supports Chat
285 *
286 * %AIM_CAPS_GETFILE Supports Get File functions
287 *
288 * %AIM_CAPS_SENDFILE Supports Send File functions
289 *
290 */
291faim_export int aim_addtlvtochain_caps(struct aim_tlvlist_t **list, unsigned short type, unsigned short caps)
3b101546 292{
293 unsigned char buf[128]; /* icky fixed length buffer */
294 struct aim_tlvlist_t *newtl;
295 struct aim_tlvlist_t *cur;
296
297 if(!list)
298 return 0;
299
9c38f1a7 300 newtl = (struct aim_tlvlist_t *)malloc(sizeof(struct aim_tlvlist_t));
301 memset(newtl, 0x00, sizeof(struct aim_tlvlist_t));
302
3b101546 303 newtl->tlv = aim_createtlv();
304 newtl->tlv->type = type;
305
9c38f1a7 306 newtl->tlv->length = aim_putcap(buf, sizeof(buf), caps);
3b101546 307 newtl->tlv->value = (unsigned char *)calloc(1, newtl->tlv->length);
9c38f1a7 308 memcpy(newtl->tlv->value, buf, newtl->tlv->length);
3b101546 309
310 newtl->next = NULL;
311
312 if (*list == NULL) {
313 *list = newtl;
314 } else if ((*list)->next == NULL) {
315 (*list)->next = newtl;
316 } else {
317 for(cur = *list; cur->next; cur = cur->next)
318 ;
319 cur->next = newtl;
320 }
321 return newtl->tlv->length;
322}
323
355982c5 324/**
325 * aim_addtlvtochain_noval - Add a blank TLV to a TLV chain
326 * @list: Destination chain
327 * @type: TLV type to add
328 *
329 * Adds a TLV with a zero length to a TLV chain.
330 *
331 */
332faim_internal int aim_addtlvtochain_noval(struct aim_tlvlist_t **list, unsigned short type)
333{
334 struct aim_tlvlist_t *newtlv;
335 struct aim_tlvlist_t *cur;
336
337 newtlv = (struct aim_tlvlist_t *)malloc(sizeof(struct aim_tlvlist_t));
338 memset(newtlv, 0x00, sizeof(struct aim_tlvlist_t));
339
340 newtlv->tlv = aim_createtlv();
341 newtlv->tlv->type = type;
342 newtlv->tlv->length = 0;
343 newtlv->tlv->value = NULL;
344
345 newtlv->next = NULL;
346
347 if (*list == NULL) {
348 *list = newtlv;
349 } else if ((*list)->next == NULL) {
350 (*list)->next = newtlv;
351 } else {
352 for(cur = *list; cur->next; cur = cur->next)
353 ;
354 cur->next = newtlv;
355 }
356 return newtlv->tlv->length;
357}
358
be67fdd0 359/**
360 * aim_writetlvchain - Write a TLV chain into a data buffer.
361 * @buf: Destination buffer
362 * @buflen: Maximum number of bytes that will be written to buffer
363 * @list: Source TLV chain
364 *
365 * Copies a TLV chain into a raw data buffer, writing only the number
366 * of bytes specified. This operation does not free the chain;
367 * aim_freetlvchain() must still be called to free up the memory used
368 * by the chain structures.
369 *
370 */
371faim_export int aim_writetlvchain(u_char *buf, int buflen, struct aim_tlvlist_t **list)
0e2be272 372{
373 int goodbuflen = 0;
374 int i = 0;
375 struct aim_tlvlist_t *cur;
376
377 if (!list || !buf || !buflen)
378 return 0;
379
380 /* do an initial run to test total length */
381 for (cur = *list; cur; cur = cur->next) {
382 goodbuflen += 2 + 2; /* type + len */
383 goodbuflen += cur->tlv->length;
384 }
385
386 if (goodbuflen > buflen)
387 return 0; /* not enough buffer */
388
389 /* do the real write-out */
390 for (cur = *list; cur; cur = cur->next) {
391 i += aimutil_put16(buf+i, cur->tlv->type);
392 i += aimutil_put16(buf+i, cur->tlv->length);
393 memcpy(buf+i, cur->tlv->value, cur->tlv->length);
394 i += cur->tlv->length;
395 }
396
397 return i;
398}
399
400
be67fdd0 401/**
402 * aim_gettlv - Grab the Nth TLV of type type in the TLV list list.
403 * @list: Source chain
404 * @type: Requested TLV type
405 * @nth: Index of TLV of type to get
406 *
407 * Returns a pointer to an aim_tlv_t of the specified type;
408 * %NULL on error. The @nth parameter is specified starting at %1.
409 * In most cases, there will be no more than one TLV of any type
410 * in a chain.
411 *
49c8a2fa 412 */
be67fdd0 413faim_export struct aim_tlv_t *aim_gettlv(struct aim_tlvlist_t *list, u_short type, int nth)
49c8a2fa 414{
415 int i;
416 struct aim_tlvlist_t *cur;
417
418 i = 0;
419 for (cur = list; cur != NULL; cur = cur->next)
420 {
421 if (cur && cur->tlv)
422 {
423 if (cur->tlv->type == type)
424 i++;
425 if (i >= nth)
426 return cur->tlv;
427 }
428 }
429 return NULL;
430}
431
be67fdd0 432/**
433 * aim_gettlv_str - Retrieve the Nth TLV in chain as a string.
434 * @list: Source TLV chain
435 * @type: TLV type to search for
436 * @nth: Index of TLV to return
437 *
438 * Same as aim_gettlv(), except that the return value is a %NULL-
439 * terminated string instead of an aim_tlv_t. This is a
440 * dynamic buffer and must be freed by the caller.
441 *
442 */
443faim_export char *aim_gettlv_str(struct aim_tlvlist_t *list, u_short type, int nth)
49c8a2fa 444{
445 struct aim_tlv_t *tlv;
446 char *newstr;
447
448 if (!(tlv = aim_gettlv(list, type, nth)))
449 return NULL;
450
451 newstr = (char *) malloc(tlv->length + 1);
452 memcpy(newstr, tlv->value, tlv->length);
453 *(newstr + tlv->length) = '\0';
454
455 return newstr;
456}
457
355982c5 458/**
459 * aim_gettlv8 - Retrieve the Nth TLV in chain as a 8bit integer.
460 * @list: Source TLV chain
461 * @type: TLV type to search for
462 * @nth: Index of TLV to return
463 *
464 * Same as aim_gettlv(), except that the return value is a
465 * 8bit integer instead of an aim_tlv_t.
466 *
467 */
468faim_internal unsigned char aim_gettlv8(struct aim_tlvlist_t *list, unsigned short type, int num)
469{
470 struct aim_tlv_t *tlv;
471
472 if (!(tlv = aim_gettlv(list, type, num)) || !tlv->value)
473 return 0; /* erm */
474 return aimutil_get8(tlv->value);
475}
476
477/**
478 * aim_gettlv16 - Retrieve the Nth TLV in chain as a 16bit integer.
479 * @list: Source TLV chain
480 * @type: TLV type to search for
481 * @nth: Index of TLV to return
482 *
483 * Same as aim_gettlv(), except that the return value is a
484 * 16bit integer instead of an aim_tlv_t.
485 *
486 */
487faim_internal unsigned short aim_gettlv16(struct aim_tlvlist_t *list, unsigned short type, int num)
488{
489 struct aim_tlv_t *tlv;
490
491 if (!(tlv = aim_gettlv(list, type, num)) || !tlv->value)
492 return 0; /* erm */
493 return aimutil_get16(tlv->value);
494}
495
496/**
497 * aim_gettlv32 - Retrieve the Nth TLV in chain as a 32bit integer.
498 * @list: Source TLV chain
499 * @type: TLV type to search for
500 * @nth: Index of TLV to return
501 *
502 * Same as aim_gettlv(), except that the return value is a
503 * 32bit integer instead of an aim_tlv_t.
504 *
505 */
506faim_internal unsigned long aim_gettlv32(struct aim_tlvlist_t *list, unsigned short type, int num)
507{
508 struct aim_tlv_t *tlv;
509
510 if (!(tlv = aim_gettlv(list, type, num)) || !tlv->value)
511 return 0; /* erm */
512 return aimutil_get32(tlv->value);
513}
514
be67fdd0 515/**
516 * aim_grabtlv - Grab a single TLV from a data buffer
517 * @src: Source data buffer (must be at least 4 bytes long)
518 *
519 * Creates a TLV structure aim_tlv_t and returns it
520 * filled with values from a buffer, possibly including a
521 * dynamically allocated buffer for the value portion.
522 *
523 * Both the aim_tlv_t and the tlv->value pointer
524 * must be freed by the caller if non-%NULL.
525 *
526 */
527faim_export struct aim_tlv_t *aim_grabtlv(u_char *src)
9de3ca7e 528{
529 struct aim_tlv_t *dest = NULL;
530
531 dest = aim_createtlv();
532
533 dest->type = src[0] << 8;
534 dest->type += src[1];
535
536 dest->length = src[2] << 8;
537 dest->length += src[3];
538
539 dest->value = (u_char *) malloc(dest->length*sizeof(u_char));
540 memset(dest->value, 0, dest->length*sizeof(u_char));
541
542 memcpy(dest->value, &(src[4]), dest->length*sizeof(u_char));
543
544 return dest;
545}
546
be67fdd0 547/**
548 * aim_grabtlvstr - Grab a single TLV from a data buffer as string
549 * @src: Source data buffer (must be at least 4 bytes long)
550 *
551 * Creates a TLV structure aim_tlv_t and returns it
552 * filled with values from a buffer, possibly including a
553 * dynamically allocated buffer for the value portion, which
554 * is %NULL-terminated as a string.
555 *
556 * Both the aim_tlv_t and the tlv->value pointer
557 * must be freed by the caller if non-%NULL.
558 *
559 */
560faim_export struct aim_tlv_t *aim_grabtlvstr(u_char *src)
9de3ca7e 561{
562 struct aim_tlv_t *dest = NULL;
563
564 dest = aim_createtlv();
565
566 dest->type = src[0] << 8;
567 dest->type += src[1];
568
569 dest->length = src[2] << 8;
570 dest->length += src[3];
571
572 dest->value = (u_char *) malloc((dest->length+1)*sizeof(u_char));
573 memset(dest->value, 0, (dest->length+1)*sizeof(u_char));
574
575 memcpy(dest->value, &(src[4]), dest->length*sizeof(u_char));
576 dest->value[dest->length] = '\0';
577
578 return dest;
579}
580
be67fdd0 581/**
582 * aim_puttlv - Write a aim_tlv_t into a data buffer
583 * @dest: Destination data buffer
584 * @newtlv: Source TLV structure
585 *
586 * Writes out the passed TLV structure into the buffer. No bounds
587 * checking is done on the output buffer.
588 *
589 * The passed aim_tlv_t is not freed. aim_freetlv() should
590 * still be called by the caller to free the structure.
591 *
592 */
593faim_export int aim_puttlv(u_char *dest, struct aim_tlv_t *newtlv)
9de3ca7e 594{
595 int i=0;
596
597 dest[i++] = newtlv->type >> 8;
598 dest[i++] = newtlv->type & 0x00FF;
599 dest[i++] = newtlv->length >> 8;
600 dest[i++] = newtlv->length & 0x00FF;
601 memcpy(&(dest[i]), newtlv->value, newtlv->length);
602 i+=newtlv->length;
603 return i;
604}
605
be67fdd0 606/**
607 * aim_createtlv - Generate an aim_tlv_t structure.
608 *
609 * Allocates an empty TLV structure and returns a pointer
610 * to it; %NULL on error.
611 *
612 */
613faim_export struct aim_tlv_t *aim_createtlv(void)
9de3ca7e 614{
be67fdd0 615 struct aim_tlv_t *newtlv;
616
617 if (!(newtlv = (struct aim_tlv_t *)malloc(sizeof(struct aim_tlv_t))))
618 return NULL;
9de3ca7e 619 memset(newtlv, 0, sizeof(struct aim_tlv_t));
620 return newtlv;
621}
622
be67fdd0 623/**
624 * aim_freetlv - Free a aim_tlv_t structure
625 * @oldtlv: TLV to be destroyed
626 *
627 * Frees both the TLV structure and the value portion.
628 *
629 */
630faim_export int aim_freetlv(struct aim_tlv_t **oldtlv)
9de3ca7e 631{
632 if (!oldtlv)
633 return -1;
634 if (!*oldtlv)
635 return -1;
636 if ((*oldtlv)->value)
637 free((*oldtlv)->value);
638 free(*(oldtlv));
639 (*oldtlv) = NULL;
640
641 return 0;
642}
643
355982c5 644/**
645 * aim_puttlv_8 - Write a one-byte TLV.
646 * @buf: Destination buffer
647 * @t: TLV type
648 * @v: Value
649 *
650 * Writes a TLV with a one-byte integer value portion.
651 *
652 */
653faim_export int aim_puttlv_8(unsigned char *buf, unsigned short t, unsigned char v)
654{
655 int curbyte=0;
656
657 curbyte += aimutil_put16(buf+curbyte, (unsigned short)(t&0xffff));
658 curbyte += aimutil_put16(buf+curbyte, (unsigned short)0x0001);
659 curbyte += aimutil_put8(buf+curbyte, (unsigned char)(v&0xff));
660
661 return curbyte;
662}
663
be67fdd0 664/**
665 * aim_puttlv_16 - Write a two-byte TLV.
666 * @buf: Destination buffer
667 * @t: TLV type
668 * @v: Value
669 *
670 * Writes a TLV with a two-byte integer value portion.
671 *
672 */
673faim_export int aim_puttlv_16(u_char *buf, u_short t, u_short v)
9de3ca7e 674{
675 int curbyte=0;
676 curbyte += aimutil_put16(buf+curbyte, (u_short)(t&0xffff));
677 curbyte += aimutil_put16(buf+curbyte, (u_short)0x0002);
678 curbyte += aimutil_put16(buf+curbyte, (u_short)(v&0xffff));
679 return curbyte;
680}
01b59e1e 681
be67fdd0 682/**
683 * aim_puttlv_32 - Write a four-byte TLV.
684 * @buf: Destination buffer
685 * @t: TLV type
686 * @v: Value
687 *
688 * Writes a TLV with a four-byte integer value portion.
689 *
690 */
691faim_export int aim_puttlv_32(u_char *buf, u_short t, u_long v)
01b59e1e 692{
693 int curbyte=0;
694 curbyte += aimutil_put16(buf+curbyte, (u_short)(t&0xffff));
695 curbyte += aimutil_put16(buf+curbyte, (u_short)0x0004);
696 curbyte += aimutil_put32(buf+curbyte, (u_long)(v&0xffffffff));
697 return curbyte;
698}
699
be67fdd0 700/**
701 * aim_puttlv_str - Write a string TLV.
702 * @buf: Destination buffer
703 * @t: TLV type
704 * @l: Length of string
705 * @v: String to write
706 *
707 * Writes a TLV with a string value portion. (Only the first @l
708 * bytes of the passed string will be written, which should not
709 * include the terminating NULL.)
710 *
711 */
712faim_export int aim_puttlv_str(u_char *buf, u_short t, int l, char *v)
01b59e1e 713{
714 int curbyte;
01b59e1e 715
716 curbyte = 0;
717 curbyte += aimutil_put16(buf+curbyte, (u_short)(t&0xffff));
718 curbyte += aimutil_put16(buf+curbyte, (u_short)(l&0xffff));
0c20631f 719 if (v)
78b3fb13 720 memcpy(buf+curbyte, (unsigned char *)v, l);
01b59e1e 721 curbyte += l;
722 return curbyte;
723}
This page took 0.160134 seconds and 5 git commands to generate.