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