X-Git-Url: http://andersk.mit.edu/gitweb/libfaim.git/blobdiff_plain/01b59e1e19a0f8bbde04b559038984cfb438d4f8..0252e8c00e1141cf852ef2844e70565df5a5608c:/aim_tlv.c diff --git a/aim_tlv.c b/aim_tlv.c index 94acf03..42d3602 100644 --- a/aim_tlv.c +++ b/aim_tlv.c @@ -31,7 +31,7 @@ struct aim_tlvlist_t *aim_readtlvchain(u_char *buf, int maxlen) cur = (struct aim_tlvlist_t *)malloc(sizeof(struct aim_tlvlist_t)); memset(cur, 0x00, sizeof(struct aim_tlvlist_t)); - cur->tlv = aim_createtlv(); + cur->tlv = aim_createtlv(); cur->tlv->type = type; cur->tlv->length = length; cur->tlv->value = (u_char *)malloc(length*sizeof(u_char)); @@ -67,6 +67,143 @@ void aim_freetlvchain(struct aim_tlvlist_t **list) return; } +int aim_counttlvchain(struct aim_tlvlist_t **list) +{ + struct aim_tlvlist_t *cur; + int count = 0; + + if (!list || !(*list)) + return 0; + + for (cur = *list; cur; cur = cur->next) + count++; + + return count; +} + +int aim_addtlvtochain_str(struct aim_tlvlist_t **list, unsigned short type, char *str, int len) +{ + struct aim_tlvlist_t *new; + struct aim_tlvlist_t *cur; + + if (!list) + return 0; + + new = (struct aim_tlvlist_t *)malloc(sizeof(struct aim_tlvlist_t)); + memset(new, 0x00, sizeof(struct aim_tlvlist_t)); + + new->tlv = aim_createtlv(); + new->tlv->type = type; + new->tlv->length = len; + new->tlv->value = (u_char *)malloc(new->tlv->length*sizeof(u_char)); + memcpy(new->tlv->value, str, new->tlv->length); + + new->next = NULL; + + if (*list == NULL) { + *list = new; + } else if ((*list)->next == NULL) { + (*list)->next = new; + } else { + for(cur = *list; cur->next; cur = cur->next) + ; + cur->next = new; + } + return new->tlv->length; +} + +int aim_addtlvtochain16(struct aim_tlvlist_t **list, unsigned short type, unsigned short val) +{ + struct aim_tlvlist_t *new; + struct aim_tlvlist_t *cur; + + if (!list) + return 0; + + new = (struct aim_tlvlist_t *)malloc(sizeof(struct aim_tlvlist_t)); + memset(new, 0x00, sizeof(struct aim_tlvlist_t)); + + new->tlv = aim_createtlv(); + new->tlv->type = type; + new->tlv->length = 2; + new->tlv->value = (u_char *)malloc(new->tlv->length*sizeof(u_char)); + aimutil_put16(new->tlv->value, val); + + new->next = NULL; + + if (*list == NULL) { + *list = new; + } else if ((*list)->next == NULL) { + (*list)->next = new; + } else { + for(cur = *list; cur->next; cur = cur->next) + ; + cur->next = new; + } + return 2; +} + +int aim_addtlvtochain32(struct aim_tlvlist_t **list, unsigned short type, unsigned long val) +{ + struct aim_tlvlist_t *new; + struct aim_tlvlist_t *cur; + + if (!list) + return 0; + + new = (struct aim_tlvlist_t *)malloc(sizeof(struct aim_tlvlist_t)); + memset(new, 0x00, sizeof(struct aim_tlvlist_t)); + + new->tlv = aim_createtlv(); + new->tlv->type = type; + new->tlv->length = 4; + new->tlv->value = (u_char *)malloc(new->tlv->length*sizeof(u_char)); + aimutil_put32(new->tlv->value, val); + + new->next = NULL; + + if (*list == NULL) { + *list = new; + } else if ((*list)->next == NULL) { + (*list)->next = new; + } else { + for(cur = *list; cur->next; cur = cur->next) + ; + cur->next = new; + } + return 4; +} + +int aim_writetlvchain(u_char *buf, int buflen, struct aim_tlvlist_t **list) +{ + int goodbuflen = 0; + int i = 0; + struct aim_tlvlist_t *cur; + + if (!list || !buf || !buflen) + return 0; + + /* do an initial run to test total length */ + for (cur = *list; cur; cur = cur->next) { + goodbuflen += 2 + 2; /* type + len */ + goodbuflen += cur->tlv->length; + } + + if (goodbuflen > buflen) + return 0; /* not enough buffer */ + + /* do the real write-out */ + for (cur = *list; cur; cur = cur->next) { + i += aimutil_put16(buf+i, cur->tlv->type); + i += aimutil_put16(buf+i, cur->tlv->length); + memcpy(buf+i, cur->tlv->value, cur->tlv->length); + i += cur->tlv->length; + } + + return i; +} + + /* * Grab the Nth TLV of type type in the TLV list list. */ @@ -201,13 +338,12 @@ int aim_puttlv_32(u_char *buf, u_short t, u_long v) int aim_puttlv_str(u_char *buf, u_short t, u_short l, u_char *v) { int curbyte; - if (!v || !buf) - return 0; curbyte = 0; curbyte += aimutil_put16(buf+curbyte, (u_short)(t&0xffff)); curbyte += aimutil_put16(buf+curbyte, (u_short)(l&0xffff)); - memcpy(buf+curbyte, v, l); + if (v) + memcpy(buf+curbyte, v, l); curbyte += l; return curbyte; }