X-Git-Url: http://git.meshlink.io/?a=blobdiff_plain;f=avahi-common%2Fstrlst.c;h=04941b4e9d116fe2d88afcfeb0047c8530cbe433;hb=bf7f48d6f58f28681b81915ddc4723950b947346;hp=574b151c4b4da0d67e3f8cb91e1bbce5ccb582a1;hpb=f61b06f15ae185410e4d5795b4fd22aeb08bbb56;p=catta diff --git a/avahi-common/strlst.c b/avahi-common/strlst.c index 574b151..04941b4 100644 --- a/avahi-common/strlst.c +++ b/avahi-common/strlst.c @@ -27,9 +27,11 @@ #include #include #include +#include #include "strlst.h" #include "malloc.h" +#include "defs.h" AvahiStringList*avahi_string_list_add_anonymous(AvahiStringList *l, size_t size) { AvahiStringList *n; @@ -80,7 +82,9 @@ AvahiStringList *avahi_string_list_parse(const void* data, size_t size) { break; k = *(c++); - r = avahi_string_list_add_arbitrary(r, c, k); + + if (k > 0) /* Ignore empty strings */ + r = avahi_string_list_add_arbitrary(r, c, k); c += k; size -= 1 + k; @@ -117,8 +121,6 @@ char* avahi_string_list_to_string(AvahiStringList *l) { size_t s = 0; char *t, *e; - l = avahi_string_list_reverse(l); - for (n = l; n; n = n->next) { if (n != l) s ++; @@ -126,11 +128,11 @@ char* avahi_string_list_to_string(AvahiStringList *l) { s += n->size+2; } - if (!(t = e = avahi_new(char, s+1))) { - l = avahi_string_list_reverse(l); + if (!(t = e = avahi_new(char, s+1))) return NULL; - } + l = avahi_string_list_reverse(l); + for (n = l; n; n = n->next) { if (n != l) *(e++) = ' '; @@ -155,45 +157,64 @@ size_t avahi_string_list_serialize(AvahiStringList *l, void *data, size_t size) size_t used = 0; if (data) { - uint8_t *c; - AvahiStringList *n; - assert(data); + if (l) { + uint8_t *c; + AvahiStringList *n; - l = avahi_string_list_reverse(l); - c = data; - - for (n = l; n; n = n->next) { - size_t k; - if (size < 1) - break; - - k = n->size; - if (k > 255) - k = 255; + l = avahi_string_list_reverse(l); + c = data; - if (k > size-1) - k = size-1; + for (n = l; n; n = n->next) { + size_t k; + if (size < 1) + break; + + k = n->size; + if (k > 255) + k = 255; + + if (k > size-1) + k = size-1; + + *(c++) = k; + memcpy(c, n->text, k); + c += k; + + used += 1+ k; + } + + l = avahi_string_list_reverse(l); - *(c++) = k; - memcpy(c, n->text, k); - c += k; + } else { + + /* Empty lists are treated specially. To comply with + * section 6.1 of the DNS-SD spec, we return a single + * empty string (i.e. a NUL byte)*/ + + if (size > 0) { + *(uint8_t*) data = 0; + used = 1; + } - used += 1+ k; } - - l = avahi_string_list_reverse(l); + } else { AvahiStringList *n; - for (n = l; n; n = n->next) { - size_t k; - - k = n->size; - if (k > 255) - k = 255; - - used += 1+k; + if (!l) + used = 1; + else { + + for (n = l; n; n = n->next) { + size_t k; + + k = n->size; + if (k > 255) + k = 255; + + used += 1+k; + } } } @@ -337,3 +358,132 @@ AvahiStringList *avahi_string_list_add_printf(AvahiStringList *l, const char *fo return l; } + +AvahiStringList *avahi_string_list_find(AvahiStringList *l, const char *key) { + size_t n; + + assert(key); + n = strlen(key); + + for (; l; l = l->next) { + if (strcasecmp((char*) l->text, key) == 0) + return l; + + if (strncasecmp((char*) l->text, key, n) == 0 && l->text[n] == '=') + return l; + } + + return NULL; +} + +AvahiStringList *avahi_string_list_add_pair(AvahiStringList *l, const char *key, const char *value) { + assert(key); + + if (value) + return avahi_string_list_add_printf(l, "%s=%s", key, value); + else + return avahi_string_list_add(l, key); +} + +AvahiStringList *avahi_string_list_add_pair_arbitrary(AvahiStringList *l, const char *key, const uint8_t *value, size_t size) { + size_t n; + assert(key); + + if (!value) + return avahi_string_list_add(l, key); + + n = strlen(key); + + if (!(l = avahi_string_list_add_anonymous(l, n + 1 + size))) + return NULL; + + memcpy(l->text, key, n); + l->text[n] = '='; + memcpy(l->text + n + 1, value, size); + + return l; +} + +int avahi_string_list_get_pair(AvahiStringList *l, char **key, char **value, size_t *size) { + char *e; + + assert(l); + + if (!(e = memchr(l->text, '=', l->size))) { + + if (key) + if (!(*key = avahi_strdup((char*) l->text))) + return -1; + + if (value) + *value = NULL; + + if (size) + *size = 0; + + } else { + size_t n; + + if (key) + if (!(*key = avahi_strndup((char*) l->text, e - (char *) l->text))) + return -1; + + e++; /* Advance after '=' */ + + n = l->size - (e - (char*) l->text); + + if (value) { + + if (!(*value = avahi_memdup(e, n+1))) { + if (key) + avahi_free(*key); + return -1; + } + + (*value)[n] = 0; + } + + if (size) + *size = n; + } + + return 0; +} + +AvahiStringList *avahi_string_list_get_next(AvahiStringList *l) { + assert(l); + return l->next; +} + +uint8_t *avahi_string_list_get_text(AvahiStringList *l) { + assert(l); + return l->text; +} + +size_t avahi_string_list_get_size(AvahiStringList *l) { + assert(l); + return l->size; +} + +uint32_t avahi_string_list_get_service_cookie(AvahiStringList *l) { + AvahiStringList *f; + char *value = NULL, *end = NULL; + uint32_t ret; + + if (!(f = avahi_string_list_find(l, AVAHI_SERVICE_COOKIE))) + return AVAHI_SERVICE_COOKIE_INVALID; + + if (avahi_string_list_get_pair(f, NULL, &value, NULL) < 0 || !value) + return AVAHI_SERVICE_COOKIE_INVALID; + + ret = (uint32_t) strtoll(value, &end, 0); + + if (*value && end && *end != 0) { + avahi_free(value); + return AVAHI_SERVICE_COOKIE_INVALID; + } + + avahi_free(value); + + return ret; +}