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