From 6e35536bddb52c8e6bc201265c77a846d879b5a3 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 12 Aug 2005 21:01:28 +0000 Subject: [PATCH] * implement hashmap * de-glib-ify rr.[ch], rrlist.[ch] git-svn-id: file:///home/lennart/svn/public/avahi/trunk@306 941a03a8-eaeb-0310-b9a0-b1bbd8fe43fe --- avahi-common/domain-test.c | 2 +- avahi-common/domain.c | 55 +------ avahi-common/domain.h | 20 +-- avahi-common/malloc.c | 12 ++ avahi-common/malloc.h | 5 +- avahi-core/Makefile.am | 16 +- avahi-core/browse-dns-server.c | 2 +- avahi-core/browse-domain.c | 2 +- avahi-core/browse-service-type.c | 2 +- avahi-core/browse-service.c | 4 +- avahi-core/browse.c | 2 +- avahi-core/hashmap-test.c | 64 ++++++++ avahi-core/hashmap.c | 249 ++++++++++++++++++++++++++++++ avahi-core/hashmap.h | 51 ++++++ avahi-core/resolve-host-name.c | 2 +- avahi-core/resolve-service.c | 6 +- avahi-core/rr.c | 256 ++++++++++++++++++------------- avahi-core/rr.h | 71 ++++----- avahi-core/rrlist.c | 61 +++++--- avahi-core/rrlist.h | 6 +- avahi-core/server.c | 30 ++-- avahi-core/util.c | 24 +++ avahi-core/util.h | 6 + 23 files changed, 687 insertions(+), 261 deletions(-) create mode 100644 avahi-core/hashmap-test.c create mode 100644 avahi-core/hashmap.c create mode 100644 avahi-core/hashmap.h diff --git a/avahi-common/domain-test.c b/avahi-common/domain-test.c index 0113a8b..fc310c7 100644 --- a/avahi-common/domain-test.c +++ b/avahi-common/domain-test.c @@ -45,7 +45,7 @@ int main(int argc, char *argv[]) { printf("%i\n", avahi_domain_equal("a", "aaa")); - printf("%u = %u\n", avahi_domain_hash("\\Aaaab\\\\."), avahi_domain_hash("aaaa\\b\\\\")); +/* printf("%u = %u\n", avahi_domain_hash("\\Aaaab\\\\."), avahi_domain_hash("aaaa\\b\\\\")); */ return 0; } diff --git a/avahi-common/domain.c b/avahi-common/domain.c index b1e7cfe..5a51a39 100644 --- a/avahi-common/domain.c +++ b/avahi-common/domain.c @@ -227,32 +227,7 @@ int avahi_binary_domain_cmp(const char *a, const char *b) { } } -unsigned avahi_strhash(const char *p) { - unsigned hash = 0; - - for (; *p; p++) - hash = 31 * hash + *p; - - return hash; -} - -unsigned avahi_domain_hash(const char *s) { - unsigned hash = 0; - - for (;;) { - char c[65]; - - if (!avahi_unescape_label(&s, c, sizeof(c))) - return hash; - - if (!c[0]) - continue; - - hash += avahi_strhash(avahi_strdown(c)); - } -} - -int avahi_valid_service_type(const char *t) { +int avahi_is_valid_service_type(const char *t) { const char *p; assert(t); @@ -280,7 +255,7 @@ int avahi_valid_service_type(const char *t) { return 1; } -int avahi_valid_domain_name(const char *t) { +int avahi_is_valid_domain_name(const char *t) { const char *p, *dp; int dot = 0; @@ -319,7 +294,7 @@ int avahi_valid_domain_name(const char *t) { return 1; } -int avahi_valid_service_name(const char *t) { +int avahi_is_valid_service_name(const char *t) { assert(t); if (*t == 0) @@ -331,7 +306,7 @@ int avahi_valid_service_name(const char *t) { return 1; } -int avahi_valid_host_name(const char *t) { +int avahi_is_valid_host_name(const char *t) { assert(t); if (*t == 0) @@ -345,25 +320,3 @@ int avahi_valid_host_name(const char *t) { return 1; } - -char *avahi_strdown(char *s) { - char *c; - - assert(s); - - for (c = s; *c; c++) - *c = (char) tolower(*c); - - return s; -} - -char *avahi_strup(char *s) { - char *c; - assert(s); - - for (c = s; *c; c++) - *c = (char) toupper(*c); - - return s; -} - diff --git a/avahi-common/domain.h b/avahi-common/domain.h index fc9d7fd..83a9332 100644 --- a/avahi-common/domain.h +++ b/avahi-common/domain.h @@ -53,29 +53,17 @@ char *avahi_unescape_label(const char **name, char *dest, size_t size); /** Escape the domain name in *src and write it to *ret_name */ char *avahi_escape_label(const uint8_t* src, size_t src_length, char **ret_name, size_t *ret_size); -/** Return some kind of hash value for a string */ -unsigned avahi_strhash(const char *p); - -/** Return some kind of hash value for a domain */ -unsigned avahi_domain_hash(const char *s); - /** Return 1 when the specified string contains a valid service type, 0 otherwise */ -int avahi_valid_service_type(const char *t); +int avahi_is_valid_service_type(const char *t); /** Return 1 when the specified string contains a valid domain name, 0 otherwise */ -int avahi_valid_domain_name(const char *t); +int avahi_is_valid_domain_name(const char *t); /** Return 1 when the specified string contains a valid service name, 0 otherwise */ -int avahi_valid_service_name(const char *t); +int avahi_is_valid_service_name(const char *t); /** Return 1 when the specified string contains a valid non-FQDN host name (i.e. without dots), 0 otherwise */ -int avahi_valid_host_name(const char *t); - -/** Change every character in the string to upper case (ASCII), return a pointer to the string */ -char *avahi_strup(char *s); - -/** Change every character in the string to lower case (ASCII), return a pointer to the string */ -char *avahi_strdown(char *s); +int avahi_is_valid_host_name(const char *t); AVAHI_C_DECL_END diff --git a/avahi-common/malloc.c b/avahi-common/malloc.c index 19e1e59..1883849 100644 --- a/avahi-common/malloc.c +++ b/avahi-common/malloc.c @@ -161,6 +161,8 @@ char *avahi_strdup_vprintf(const char *fmt, va_list ap) { char *avahi_strdup_printf(const char *fmt, ... ) { char *s; va_list ap; + + assert(fmt); va_start(ap, fmt); s = avahi_strdup_vprintf(fmt, ap); @@ -169,3 +171,13 @@ char *avahi_strdup_printf(const char *fmt, ... ) { return s; } +void *avahi_memdup(const void *s, size_t l) { + void *p; + assert(s); + + if (!(p = avahi_malloc(l))) + return NULL; + + memcpy(p, s, l); + return p; +} diff --git a/avahi-common/malloc.h b/avahi-common/malloc.h index 2dd740e..b658357 100644 --- a/avahi-common/malloc.h +++ b/avahi-common/malloc.h @@ -53,7 +53,10 @@ void *avahi_realloc(void *p, size_t size); char *avahi_strdup(const char *s); /** Just like libc's strndup() */ -char *avahi_strndup(const char *s, size_t l); +char *avahi_strndup(const char *s, size_t l); + +/** Duplicate the given memory block into a new one allocated with avahi_malloc() */ +void *avahi_memdup(const void *s, size_t l); /** Wraps allocator functions */ typedef struct AvahiAllocator AvahiAllocator; diff --git a/avahi-core/Makefile.am b/avahi-core/Makefile.am index c71d6ed..e0e7d86 100644 --- a/avahi-core/Makefile.am +++ b/avahi-core/Makefile.am @@ -45,7 +45,8 @@ noinst_PROGRAMS = \ conformance-test \ avahi-reflector \ dns-test \ - timeeventq-test + timeeventq-test \ + hashmap-test libavahi_core_la_SOURCES = \ timeeventq.c timeeventq.h\ @@ -73,7 +74,8 @@ libavahi_core_la_SOURCES = \ log.c log.h \ browse-dns-server.c \ fdutil.h fdutil.c \ - util.c util.h + util.c util.h \ + hashmap.c hashmap.h libavahi_core_la_CFLAGS = $(AM_CFLAGS) libavahi_core_la_LIBADD = $(AM_LDADD) $(COMMON_LDADD) @@ -104,7 +106,8 @@ dns_test_SOURCES = \ dns-test.c \ log.c log.h \ util.c util.h \ - rr.c rr.h + rr.c rr.h \ + hashmap.c hashmap.h dns_test_CFLAGS = $(AM_CFLAGS) dns_test_LDADD = $(AM_LDADD) $(COMMON_LDADD) @@ -115,6 +118,13 @@ timeeventq_test_SOURCES = \ timeeventq_test_CFLAGS = $(AM_CFLAGS) timeeventq_test_LDADD = $(AM_LDADD) $(COMMON_LDADD) +hashmap_test_SOURCES = \ + hashmap-test.c \ + hashmap.h hashmap.c \ + util.h util.c +hashmap_test_CFLAGS = $(AM_CFLAGS) +hashmap_test_LDADD = $(AM_LDADD) $(COMMON_LDADD) + valgrind: avahi-test libtool --mode=execute valgrind ./avahi-test diff --git a/avahi-core/browse-dns-server.c b/avahi-core/browse-dns-server.c index 7b29ec6..8f87887 100644 --- a/avahi-core/browse-dns-server.c +++ b/avahi-core/browse-dns-server.c @@ -157,7 +157,7 @@ AvahiDNSServerBrowser *avahi_dns_server_browser_new(AvahiServer *server, AvahiIf g_assert(callback); g_assert(type == AVAHI_DNS_SERVER_RESOLVE || type == AVAHI_DNS_SERVER_UPDATE); - if (domain && !avahi_valid_domain_name(domain)) { + if (domain && !avahi_is_valid_domain_name(domain)) { avahi_server_set_errno(server, AVAHI_ERR_INVALID_DOMAIN_NAME); return NULL; } diff --git a/avahi-core/browse-domain.c b/avahi-core/browse-domain.c index 71bc67f..09e1e50 100644 --- a/avahi-core/browse-domain.c +++ b/avahi-core/browse-domain.c @@ -62,7 +62,7 @@ AvahiDomainBrowser *avahi_domain_browser_new(AvahiServer *server, AvahiIfIndex i g_assert(callback); g_assert(type >= AVAHI_DOMAIN_BROWSER_BROWSE && type <= AVAHI_DOMAIN_BROWSER_BROWSE_LEGACY); - if (domain && !avahi_valid_domain_name(domain)) { + if (domain && !avahi_is_valid_domain_name(domain)) { avahi_server_set_errno(server, AVAHI_ERR_INVALID_DOMAIN_NAME); return NULL; } diff --git a/avahi-core/browse-service-type.c b/avahi-core/browse-service-type.c index e769e91..61364e9 100644 --- a/avahi-core/browse-service-type.c +++ b/avahi-core/browse-service-type.c @@ -90,7 +90,7 @@ AvahiServiceTypeBrowser *avahi_service_type_browser_new(AvahiServer *server, gin g_assert(server); g_assert(callback); - if (domain && !avahi_valid_domain_name(domain)) { + if (domain && !avahi_is_valid_domain_name(domain)) { avahi_server_set_errno(server, AVAHI_ERR_INVALID_DOMAIN_NAME); return NULL; } diff --git a/avahi-core/browse-service.c b/avahi-core/browse-service.c index 35fcc53..8b3aa4c 100644 --- a/avahi-core/browse-service.c +++ b/avahi-core/browse-service.c @@ -93,12 +93,12 @@ AvahiServiceBrowser *avahi_service_browser_new(AvahiServer *server, AvahiIfIndex g_assert(callback); g_assert(service_type); - if (!avahi_valid_service_type(service_type)) { + if (!avahi_is_valid_service_type(service_type)) { avahi_server_set_errno(server, AVAHI_ERR_INVALID_SERVICE_TYPE); return NULL; } - if (domain && !avahi_valid_domain_name(domain)) { + if (domain && !avahi_is_valid_domain_name(domain)) { avahi_server_set_errno(server, AVAHI_ERR_INVALID_DOMAIN_NAME); return NULL; } diff --git a/avahi-core/browse.c b/avahi-core/browse.c index 6357095..f089cdd 100644 --- a/avahi-core/browse.c +++ b/avahi-core/browse.c @@ -129,7 +129,7 @@ AvahiRecordBrowser *avahi_record_browser_new(AvahiServer *server, AvahiIfIndex i return NULL; } - if (!avahi_key_valid(key)) { + if (!avahi_key_is_valid(key)) { avahi_server_set_errno(server, AVAHI_ERR_INVALID_KEY); return NULL; } diff --git a/avahi-core/hashmap-test.c b/avahi-core/hashmap-test.c new file mode 100644 index 0000000..a57cf8b --- /dev/null +++ b/avahi-core/hashmap-test.c @@ -0,0 +1,64 @@ +/* $Id$ */ + +/*** + This file is part of avahi. + + avahi is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + avahi is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General + Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with avahi; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + +#include +#include + +#include "hashmap.h" +#include "util.h" + +int main(int argc, char *argv[]) { + unsigned n; + AvahiHashmap *m; + const char *t; + + m = avahi_hashmap_new(avahi_string_hash, avahi_string_equal, avahi_free, avahi_free); + + avahi_hashmap_insert(m, avahi_strdup("bla"), avahi_strdup("#1")); + avahi_hashmap_insert(m, avahi_strdup("bla2"), avahi_strdup("asdf")); + avahi_hashmap_insert(m, avahi_strdup("gurke"), avahi_strdup("ffsdf")); + avahi_hashmap_insert(m, avahi_strdup("blubb"), avahi_strdup("sadfsd")); + avahi_hashmap_insert(m, avahi_strdup("bla"), avahi_strdup("#2")); + + for (n = 0; n < 1000; n ++) + avahi_hashmap_insert(m, avahi_strdup_printf("key %u", n), avahi_strdup_printf("value %u", n)); + + printf("%s\n", (const char*) avahi_hashmap_lookup(m, "bla")); + + avahi_hashmap_replace(m, avahi_strdup("bla"), avahi_strdup("#3")); + + printf("%s\n", (const char*) avahi_hashmap_lookup(m, "bla")); + + avahi_hashmap_remove(m, "bla"); + + t = (const char*) avahi_hashmap_lookup(m, "bla"); + printf("%s\n", t ? t : "(null)"); + + avahi_hashmap_free(m); + + return 0; +} diff --git a/avahi-core/hashmap.c b/avahi-core/hashmap.c new file mode 100644 index 0000000..0c44d4f --- /dev/null +++ b/avahi-core/hashmap.c @@ -0,0 +1,249 @@ +/* $Id$ */ + +/*** + This file is part of avahi. + + avahi is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + avahi is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General + Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with avahi; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include + +#include +#include +#include + +#include "hashmap.h" +#include "util.h" + +#define HASH_MAP_SIZE 123 + +typedef struct Entry Entry; +struct Entry { + AvahiHashmap *hashmap; + void *key; + void *value; + + AVAHI_LLIST_FIELDS(Entry, bucket); + AVAHI_LLIST_FIELDS(Entry, entries); +}; + +struct AvahiHashmap { + AvahiHashFunc hash_func; + AvahiEqualFunc equal_func; + AvahiFreeFunc key_free_func, value_free_func; + + Entry *entries[HASH_MAP_SIZE]; + AVAHI_LLIST_HEAD(Entry, entries_list); +}; + +static Entry* entry_get(AvahiHashmap *m, const void *key) { + unsigned idx; + Entry *e; + + idx = m->hash_func(key) % HASH_MAP_SIZE; + + for (e = m->entries[idx]; e; e = e->bucket_next) + if (m->equal_func(key, e->key)) + return e; + + return NULL; +} + +static void entry_free(AvahiHashmap *m, Entry *e, int stolen) { + unsigned idx; + assert(e); + + idx = m->hash_func(e->key) % HASH_MAP_SIZE; + + AVAHI_LLIST_REMOVE(Entry, bucket, m->entries[idx], e); + AVAHI_LLIST_REMOVE(Entry, entries, m->entries_list, e); + + if (m->key_free_func) + m->key_free_func(e->key); + if (m->value_free_func && !stolen) + m->value_free_func(e->value); + + avahi_free(e); +} + +AvahiHashmap* avahi_hashmap_new(AvahiHashFunc hash_func, AvahiEqualFunc equal_func, AvahiFreeFunc key_free_func, AvahiFreeFunc value_free_func) { + AvahiHashmap *m; + + assert(hash_func); + assert(equal_func); + + if (!(m = avahi_new(AvahiHashmap, 1))) + return NULL; + + m->hash_func = hash_func; + m->equal_func = equal_func; + m->key_free_func = key_free_func; + m->value_free_func = value_free_func; + + memset(m->entries, 0, sizeof(m->entries)); + + AVAHI_LLIST_HEAD_INIT(Entry, m->entries_list); + + return m; +} + +void avahi_hashmap_free(AvahiHashmap *m) { + assert(m); + + while (m->entries_list) + entry_free(m, m->entries_list, 0); + + avahi_free(m); +} + +void* avahi_hashmap_lookup(AvahiHashmap *m, const void *key) { + Entry *e; + + assert(m); + + if (!(e = entry_get(m, key))) + return NULL; + + return e->value; +} + +void* avahi_hashmap_steal(AvahiHashmap *m, const void *key) { + Entry *e; + void *v; + + assert(m); + + if (!(e = entry_get(m, key))) + return NULL; + + v = e->value; + entry_free(m, e, 1); + return v; +} + +int avahi_hashmap_insert(AvahiHashmap *m, void *key, void *value) { + unsigned idx; + Entry *e; + + assert(m); + + if ((e = entry_get(m, key))) { + if (m->key_free_func) + m->key_free_func(key); + if (m->value_free_func) + m->value_free_func(value); + + return 1; + } + + if (!(e = avahi_new(Entry, 1))) + return -1; + + e->hashmap = m; + e->key = key; + e->value = value; + + AVAHI_LLIST_PREPEND(Entry, entries, m->entries_list, e); + + idx = m->hash_func(key) % HASH_MAP_SIZE; + AVAHI_LLIST_PREPEND(Entry, bucket, m->entries[idx], e); + + return 0; +} + + +int avahi_hashmap_replace(AvahiHashmap *m, void *key, void *value) { + unsigned idx; + Entry *e; + + assert(m); + + if ((e = entry_get(m, key))) { + if (m->key_free_func) + m->key_free_func(e->key); + if (m->value_free_func) + m->value_free_func(e->value); + + e->key = key; + e->value = value; + + return 1; + } + + if (!(e = avahi_new(Entry, 1))) + return -1; + + e->hashmap = m; + e->key = key; + e->value = value; + + AVAHI_LLIST_PREPEND(Entry, entries, m->entries_list, e); + + idx = m->hash_func(key) % HASH_MAP_SIZE; + AVAHI_LLIST_PREPEND(Entry, bucket, m->entries[idx], e); + + return 0; +} + + +void avahi_hashmap_remove(AvahiHashmap *m, const void *key) { + Entry *e; + + assert(m); + + if (!(e = entry_get(m, key))) + return; + + entry_free(m, e, 0); +} + +unsigned avahi_string_hash(const void *data) { + const char *p = data; + unsigned hash = 0; + + for (; *p; p++) + hash = 31 * hash + *p; + + return hash; +} + +int avahi_string_equal(const void *a, const void *b) { + const char *p = a, *q = b; + + return strcmp(p, q) == 0; +} + +unsigned avahi_domain_hash(const void *data) { + unsigned hash = 0; + const char *s; + + for (;;) { + char c[65]; + + if (!avahi_unescape_label(&s, c, sizeof(c))) + return hash; + + if (!c[0]) + continue; + + hash += avahi_string_hash(avahi_strdown(c)); + } +} diff --git a/avahi-core/hashmap.h b/avahi-core/hashmap.h new file mode 100644 index 0000000..c3000ba --- /dev/null +++ b/avahi-core/hashmap.h @@ -0,0 +1,51 @@ +#ifndef foohashmaphfoo +#define foohashmaphfoo + +/* $Id$ */ + +/*** + This file is part of avahi. + + avahi is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + avahi is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General + Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with avahi; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#include + +AVAHI_C_DECL_BEGIN + +typedef struct AvahiHashmap AvahiHashmap; + +typedef unsigned (*AvahiHashFunc)(const void *data); +typedef int (*AvahiEqualFunc)(const void *a, const void *b); +typedef void (*AvahiFreeFunc)(void *p); + +AvahiHashmap* avahi_hashmap_new(AvahiHashFunc hash_func, AvahiEqualFunc equal_func, AvahiFreeFunc key_free_func, AvahiFreeFunc value_free_func); + +void avahi_hashmap_free(AvahiHashmap *m); +void* avahi_hashmap_lookup(AvahiHashmap *m, const void *key); +void* avahi_hashmap_steal(AvahiHashmap *m, const void *key); +int avahi_hashmap_insert(AvahiHashmap *m, void *key, void *data); +int avahi_hashmap_replace(AvahiHashmap *m, void *key, void *data); +void avahi_hashmap_remove(AvahiHashmap *m, const void *key); + +unsigned avahi_string_hash(const void *data); +int avahi_string_equal(const void *a, const void *b); + +unsigned avahi_domain_hash(const void *data); + +AVAHI_C_DECL_END + +#endif diff --git a/avahi-core/resolve-host-name.c b/avahi-core/resolve-host-name.c index 50fbcf8..1e6dc9f 100644 --- a/avahi-core/resolve-host-name.c +++ b/avahi-core/resolve-host-name.c @@ -116,7 +116,7 @@ AvahiHostNameResolver *avahi_host_name_resolver_new(AvahiServer *server, AvahiIf g_assert(aprotocol == AVAHI_PROTO_UNSPEC || aprotocol == AVAHI_PROTO_INET || aprotocol == AVAHI_PROTO_INET6); - if (!avahi_valid_domain_name(host_name)) { + if (!avahi_is_valid_domain_name(host_name)) { avahi_server_set_errno(server, AVAHI_ERR_INVALID_HOST_NAME); return NULL; } diff --git a/avahi-core/resolve-service.c b/avahi-core/resolve-service.c index 0e4e119..9a142ae 100644 --- a/avahi-core/resolve-service.c +++ b/avahi-core/resolve-service.c @@ -207,17 +207,17 @@ AvahiServiceResolver *avahi_service_resolver_new(AvahiServer *server, AvahiIfInd g_assert(aprotocol == AVAHI_PROTO_UNSPEC || aprotocol == AVAHI_PROTO_INET || aprotocol == AVAHI_PROTO_INET6); - if (!avahi_valid_service_name(name)) { + if (!avahi_is_valid_service_name(name)) { avahi_server_set_errno(server, AVAHI_ERR_INVALID_SERVICE_NAME); return NULL; } - if (!avahi_valid_service_type(type)) { + if (!avahi_is_valid_service_type(type)) { avahi_server_set_errno(server, AVAHI_ERR_INVALID_SERVICE_TYPE); return NULL; } - if (!avahi_valid_domain_name(domain)) { + if (!avahi_is_valid_domain_name(domain)) { avahi_server_set_errno(server, AVAHI_ERR_INVALID_DOMAIN_NAME); return NULL; } diff --git a/avahi-core/rr.c b/avahi-core/rr.c index 4ec3c11..821ca8f 100644 --- a/avahi-core/rr.c +++ b/avahi-core/rr.c @@ -28,104 +28,125 @@ #include #include #include +#include #include +#include + #include "rr.h" +#include "log.h" +#include "util.h" -AvahiKey *avahi_key_new(const gchar *name, guint16 class, guint16 type) { +AvahiKey *avahi_key_new(const char *name, uint16_t class, uint16_t type) { AvahiKey *k; - g_assert(name); + assert(name); - k = g_new(AvahiKey, 1); + if (!(k = avahi_new(AvahiKey, 1))) { + avahi_log_error("avahi_new() failed."); + return NULL; + } + + if (!(k->name = avahi_normalize_name(name))) { + avahi_log_error("avahi_normalize_name() failed."); + avahi_free(k); + return NULL; + } + k->ref = 1; - k->name = avahi_normalize_name(name); k->clazz = class; k->type = type; -/* g_message("%p %% ref=1", k); */ - return k; } AvahiKey *avahi_key_ref(AvahiKey *k) { - g_assert(k); - g_assert(k->ref >= 1); + assert(k); + assert(k->ref >= 1); k->ref++; -/* g_message("%p ++ ref=%i", k, k->ref); */ - return k; } void avahi_key_unref(AvahiKey *k) { - g_assert(k); - g_assert(k->ref >= 1); - -/* g_message("%p -- ref=%i", k, k->ref-1); */ + assert(k); + assert(k->ref >= 1); if ((--k->ref) <= 0) { - g_free(k->name); - g_free(k); + avahi_free(k->name); + avahi_free(k); } } -AvahiRecord *avahi_record_new(AvahiKey *k, guint32 ttl) { +AvahiRecord *avahi_record_new(AvahiKey *k, uint32_t ttl) { AvahiRecord *r; - g_assert(k); + assert(k); - r = g_new(AvahiRecord, 1); + if (!(r = avahi_new(AvahiRecord, 1))) { + avahi_log_error("avahi_new() failed."); + return NULL; + } + r->ref = 1; r->key = avahi_key_ref(k); memset(&r->data, 0, sizeof(r->data)); - r->ttl = ttl != (guint32) -1 ? ttl : AVAHI_DEFAULT_TTL; + r->ttl = ttl != (uint32_t) -1 ? ttl : AVAHI_DEFAULT_TTL; return r; } -AvahiRecord *avahi_record_new_full(const gchar *name, guint16 class, guint16 type, guint32 ttl) { +AvahiRecord *avahi_record_new_full(const char *name, uint16_t class, uint16_t type, uint32_t ttl) { AvahiRecord *r; AvahiKey *k; - g_assert(name); + assert(name); - k = avahi_key_new(name, class, type); + if (!(k = avahi_key_new(name, class, type))) { + avahi_log_error("avahi_key_new() failed."); + return NULL; + } + r = avahi_record_new(k, ttl); avahi_key_unref(k); + if (!r) { + avahi_log_error("avahi_record_new() failed."); + return NULL; + } + return r; } AvahiRecord *avahi_record_ref(AvahiRecord *r) { - g_assert(r); - g_assert(r->ref >= 1); + assert(r); + assert(r->ref >= 1); r->ref++; return r; } void avahi_record_unref(AvahiRecord *r) { - g_assert(r); - g_assert(r->ref >= 1); + assert(r); + assert(r->ref >= 1); if ((--r->ref) <= 0) { switch (r->key->type) { case AVAHI_DNS_TYPE_SRV: - g_free(r->data.srv.name); + avahi_free(r->data.srv.name); break; case AVAHI_DNS_TYPE_PTR: case AVAHI_DNS_TYPE_CNAME: - g_free(r->data.ptr.name); + avahi_free(r->data.ptr.name); break; case AVAHI_DNS_TYPE_HINFO: - g_free(r->data.hinfo.cpu); - g_free(r->data.hinfo.os); + avahi_free(r->data.hinfo.cpu); + avahi_free(r->data.hinfo.os); break; case AVAHI_DNS_TYPE_TXT: @@ -137,15 +158,15 @@ void avahi_record_unref(AvahiRecord *r) { break; default: - g_free(r->data.generic.data); + avahi_free(r->data.generic.data); } avahi_key_unref(r->key); - g_free(r); + avahi_free(r); } } -const gchar *avahi_dns_class_to_string(guint16 class) { +const char *avahi_dns_class_to_string(uint16_t class) { if (class & AVAHI_DNS_CACHE_FLUSH) return "FLUSH"; @@ -159,7 +180,7 @@ const gchar *avahi_dns_class_to_string(guint16 class) { } } -const gchar *avahi_dns_type_to_string(guint16 type) { +const char *avahi_dns_type_to_string(uint16_t type) { switch (type) { case AVAHI_DNS_TYPE_CNAME: return "CNAME"; @@ -182,22 +203,22 @@ const gchar *avahi_dns_type_to_string(guint16 type) { } } -gchar *avahi_key_to_string(const AvahiKey *k) { - g_assert(k); - g_assert(k->ref >= 1); +char *avahi_key_to_string(const AvahiKey *k) { + assert(k); + assert(k->ref >= 1); - return g_strdup_printf("%s\t%s\t%s", - k->name, - avahi_dns_class_to_string(k->clazz), - avahi_dns_type_to_string(k->type)); + return avahi_strdup_printf("%s\t%s\t%s", + k->name, + avahi_dns_class_to_string(k->clazz), + avahi_dns_type_to_string(k->type)); } -gchar *avahi_record_to_string(const AvahiRecord *r) { - gchar *p, *s; +char *avahi_record_to_string(const AvahiRecord *r) { + char *p, *s; char buf[257], *t = NULL, *d = NULL; - g_assert(r); - g_assert(r->ref >= 1); + assert(r); + assert(r->ref >= 1); switch (r->key->type) { case AVAHI_DNS_TYPE_A: @@ -235,16 +256,16 @@ gchar *avahi_record_to_string(const AvahiRecord *r) { } p = avahi_key_to_string(r->key); - s = g_strdup_printf("%s %s ; ttl=%u", p, t ? t : "", r->ttl); - g_free(p); - g_free(d); + s = avahi_strdup_printf("%s %s ; ttl=%u", p, t ? t : "", r->ttl); + avahi_free(p); + avahi_free(d); return s; } gboolean avahi_key_equal(const AvahiKey *a, const AvahiKey *b) { - g_assert(a); - g_assert(b); + assert(a); + assert(b); if (a == b) return TRUE; @@ -257,12 +278,12 @@ gboolean avahi_key_equal(const AvahiKey *a, const AvahiKey *b) { } gboolean avahi_key_pattern_match(const AvahiKey *pattern, const AvahiKey *k) { - g_assert(pattern); - g_assert(k); + assert(pattern); + assert(k); /* g_message("equal: %p %p", a, b); */ - g_assert(!avahi_key_is_pattern(k)); + assert(!avahi_key_is_pattern(k)); if (pattern == k) return TRUE; @@ -273,7 +294,7 @@ gboolean avahi_key_pattern_match(const AvahiKey *pattern, const AvahiKey *k) { } gboolean avahi_key_is_pattern(const AvahiKey *k) { - g_assert(k); + assert(k); return k->type == AVAHI_DNS_TYPE_ANY || @@ -281,7 +302,7 @@ gboolean avahi_key_is_pattern(const AvahiKey *k) { } guint avahi_key_hash(const AvahiKey *k) { - g_assert(k); + assert(k); return avahi_domain_hash(k->name) + @@ -290,17 +311,17 @@ guint avahi_key_hash(const AvahiKey *k) { } static gboolean rdata_equal(const AvahiRecord *a, const AvahiRecord *b) { - g_assert(a); - g_assert(b); - g_assert(a->key->type == b->key->type); + assert(a); + assert(b); + assert(a->key->type == b->key->type); /* t = avahi_record_to_string(a); */ /* g_message("comparing %s", t); */ -/* g_free(t); */ +/* avahi_free(t); */ /* t = avahi_record_to_string(b); */ /* g_message("and %s", t); */ -/* g_free(t); */ +/* avahi_free(t); */ switch (a->key->type) { @@ -337,8 +358,8 @@ static gboolean rdata_equal(const AvahiRecord *a, const AvahiRecord *b) { } gboolean avahi_record_equal_no_ttl(const AvahiRecord *a, const AvahiRecord *b) { - g_assert(a); - g_assert(b); + assert(a); + assert(b); if (a == b) return TRUE; @@ -352,7 +373,11 @@ gboolean avahi_record_equal_no_ttl(const AvahiRecord *a, const AvahiRecord *b) { AvahiRecord *avahi_record_copy(AvahiRecord *r) { AvahiRecord *copy; - copy = g_new(AvahiRecord, 1); + if (!(copy = avahi_new(AvahiRecord, 1))) { + avahi_log_error("avahi_new() failed."); + return NULL; + } + copy->ref = 1; copy->key = avahi_key_ref(r->key); copy->ttl = r->ttl; @@ -360,19 +385,26 @@ AvahiRecord *avahi_record_copy(AvahiRecord *r) { switch (r->key->type) { case AVAHI_DNS_TYPE_PTR: case AVAHI_DNS_TYPE_CNAME: - copy->data.ptr.name = g_strdup(r->data.ptr.name); + if (!(copy->data.ptr.name = avahi_strdup(r->data.ptr.name))) + goto fail; break; case AVAHI_DNS_TYPE_SRV: copy->data.srv.priority = r->data.srv.priority; copy->data.srv.weight = r->data.srv.weight; copy->data.srv.port = r->data.srv.port; - copy->data.srv.name = g_strdup(r->data.srv.name); + if (!(copy->data.srv.name = avahi_strdup(r->data.srv.name))) + goto fail; break; case AVAHI_DNS_TYPE_HINFO: - copy->data.hinfo.os = g_strdup(r->data.hinfo.os); - copy->data.hinfo.cpu = g_strdup(r->data.hinfo.cpu); + if (!(copy->data.hinfo.os = avahi_strdup(r->data.hinfo.os))) + goto fail; + + if (!(copy->data.hinfo.cpu = avahi_strdup(r->data.hinfo.cpu))) { + avahi_free(r->data.hinfo.os); + goto fail; + } break; case AVAHI_DNS_TYPE_TXT: @@ -388,25 +420,34 @@ AvahiRecord *avahi_record_copy(AvahiRecord *r) { break; default: - copy->data.generic.data = g_memdup(r->data.generic.data, r->data.generic.size); + if (!(copy->data.generic.data = avahi_memdup(r->data.generic.data, r->data.generic.size))) + goto fail; copy->data.generic.size = r->data.generic.size; break; } return copy; + +fail: + avahi_log_error("Failed to allocate memory"); + + avahi_key_unref(copy->key); + avahi_free(copy); + + return NULL; } -guint avahi_key_get_estimate_size(AvahiKey *k) { - g_assert(k); +size_t avahi_key_get_estimate_size(AvahiKey *k) { + assert(k); return strlen(k->name)+1+4; } -guint avahi_record_get_estimate_size(AvahiRecord *r) { +size_t avahi_record_get_estimate_size(AvahiRecord *r) { guint n; - g_assert(r); + assert(r); n = avahi_key_get_estimate_size(r->key) + 4 + 2; @@ -443,12 +484,12 @@ guint avahi_record_get_estimate_size(AvahiRecord *r) { return n; } -static gint lexicographical_memcmp(gconstpointer a, size_t al, gconstpointer b, size_t bl) { +static int lexicographical_memcmp(const void* a, size_t al, const void* b, size_t bl) { size_t c; - gint ret; + int ret; - g_assert(a); - g_assert(b); + assert(a); + assert(b); c = al < bl ? al : bl; if ((ret = memcmp(a, b, c))) @@ -460,22 +501,22 @@ static gint lexicographical_memcmp(gconstpointer a, size_t al, gconstpointer b, return al == c ? 1 : -1; } -static gint uint16_cmp(guint16 a, guint16 b) { +static int uint16_cmp(uint16_t a, uint16_t b) { return a == b ? 0 : (a < b ? -1 : 1); } -gint avahi_record_lexicographical_compare(AvahiRecord *a, AvahiRecord *b) { - gint r; -/* gchar *t1, *t2; */ +int avahi_record_lexicographical_compare(AvahiRecord *a, AvahiRecord *b) { + int r; +/* char *t1, *t2; */ - g_assert(a); - g_assert(b); + assert(a); + assert(b); /* t1 = avahi_record_to_string(a); */ /* t2 = avahi_record_to_string(b); */ /* g_message("lexicocmp: %s %s", t1, t2); */ -/* g_free(t1); */ -/* g_free(t2); */ +/* avahi_free(t1); */ +/* avahi_free(t2); */ if (a == b) return 0; @@ -514,8 +555,13 @@ gint avahi_record_lexicographical_compare(AvahiRecord *a, AvahiRecord *b) { guint8 *ma, *mb; guint asize, bsize; - ma = g_new(guint8, asize = avahi_string_list_serialize(a->data.txt.string_list, NULL, 0)); - mb = g_new(guint8, bsize = avahi_string_list_serialize(b->data.txt.string_list, NULL, 0)); + if (!(ma = avahi_new(guint8, asize = avahi_string_list_serialize(a->data.txt.string_list, NULL, 0)))) + goto fail; + if (!(mb = g_new(guint8, bsize = avahi_string_list_serialize(b->data.txt.string_list, NULL, 0)))) { + avahi_free(ma); + goto fail; + } + avahi_string_list_serialize(a->data.txt.string_list, ma, asize); avahi_string_list_serialize(b->data.txt.string_list, mb, bsize); @@ -528,8 +574,8 @@ gint avahi_record_lexicographical_compare(AvahiRecord *a, AvahiRecord *b) { else r = 0; - g_free(ma); - g_free(mb); + avahi_free(ma); + avahi_free(mb); return r; } @@ -544,38 +590,42 @@ gint avahi_record_lexicographical_compare(AvahiRecord *a, AvahiRecord *b) { return lexicographical_memcmp(a->data.generic.data, a->data.generic.size, b->data.generic.data, b->data.generic.size); } + +fail: + avahi_log_error("Out of memory"); + return -1; /* or whatever ... */ } -gboolean avahi_record_is_goodbye(AvahiRecord *r) { - g_assert(r); +int avahi_record_is_goodbye(AvahiRecord *r) { + assert(r); return r->ttl == 0; } -gboolean avahi_key_valid(AvahiKey *k) { - g_assert(k); +int avahi_key_is_valid(AvahiKey *k) { + assert(k); - if (!avahi_valid_domain_name(k->name)) + if (!avahi_is_valid_domain_name(k->name)) return FALSE; return TRUE; } -gboolean avahi_record_valid(AvahiRecord *r) { - g_assert(r); +int avahi_record_is_valid(AvahiRecord *r) { + assert(r); - if (!avahi_key_valid(r->key)) - return FALSE; + if (!avahi_key_is_valid(r->key)) + return 0; switch (r->key->type) { case AVAHI_DNS_TYPE_PTR: case AVAHI_DNS_TYPE_CNAME: - return avahi_valid_domain_name(r->data.ptr.name); + return avahi_is_valid_domain_name(r->data.ptr.name); case AVAHI_DNS_TYPE_SRV: - return avahi_valid_domain_name(r->data.srv.name); + return avahi_is_valid_domain_name(r->data.srv.name); case AVAHI_DNS_TYPE_HINFO: return @@ -589,12 +639,12 @@ gboolean avahi_record_valid(AvahiRecord *r) { for (strlst = r->data.txt.string_list; strlst; strlst = strlst->next) if (strlst->size > 255) - return FALSE; + return 0; - return TRUE; + return 1; } } - return TRUE; + return 1; } diff --git a/avahi-core/rr.h b/avahi-core/rr.h index f5349e9..5349076 100644 --- a/avahi-core/rr.h +++ b/avahi-core/rr.h @@ -22,13 +22,14 @@ USA. ***/ -#include +/** \file rr.h Functions and definitions for manipulating DNS resource record (RR) data. */ #include #include #include -/** \file rr.h Functions and definitions for manipulating DNS resource record (RR) data. */ +#include +#include AVAHI_C_DECL_BEGIN @@ -66,42 +67,42 @@ enum { reference counter. The structure is intended to be treated as "immutable", no changes should be imposed after creation */ typedef struct { - guint ref; /**< Reference counter */ - gchar *name; /**< Record name */ - guint16 clazz; /**< Record class, one of the AVAHI_DNS_CLASS_xxx constants */ - guint16 type; /**< Record type, one of the AVAHI_DNS_TYPE_xxx constants */ + int ref; /**< Reference counter */ + char *name; /**< Record name */ + uint16_t clazz; /**< Record class, one of the AVAHI_DNS_CLASS_xxx constants */ + uint16_t type; /**< Record type, one of the AVAHI_DNS_TYPE_xxx constants */ } AvahiKey; /** Encapsulates a DNS resource record. The structure is intended to * be treated as "immutable", no changes should be imposed after * creation. */ typedef struct { - guint ref; /**< Reference counter */ + int ref; /**< Reference counter */ AvahiKey *key; /**< Reference to the query key of thsi record */ - guint32 ttl; /**< DNS TTL of this record */ + uint32_t ttl; /**< DNS TTL of this record */ union { struct { - gpointer data; - guint16 size; + void* data; + uint16_t size; } generic; /**< Generic record data for unknown types */ struct { - guint16 priority; - guint16 weight; - guint16 port; - gchar *name; + uint16_t priority; + uint16_t weight; + uint16_t port; + char *name; } srv; /**< Data for SRV records */ struct { - gchar *name; + char *name; } ptr; /**< Data for PTR an CNAME records */ struct { - gchar *cpu; - gchar *os; + char *cpu; + char *os; } hinfo; /**< Data for HINFO records */ struct { @@ -121,7 +122,7 @@ typedef struct { } AvahiRecord; /** Create a new AvahiKey object. The reference counter will be set to 1. */ -AvahiKey *avahi_key_new(const gchar *name, guint16 clazz, guint16 type); +AvahiKey *avahi_key_new(const char *name, uint16_t clazz, uint16_t type); /** Increase the reference counter of an AvahiKey object by one */ AvahiKey *avahi_key_ref(AvahiKey *k); @@ -132,27 +133,27 @@ void avahi_key_unref(AvahiKey *k); /** Check whether two AvahiKey object contain the same * data. AVAHI_DNS_CLASS_ANY/AVAHI_DNS_TYPE_ANY are treated like any * other class/type. */ -gboolean avahi_key_equal(const AvahiKey *a, const AvahiKey *b); +int avahi_key_equal(const AvahiKey *a, const AvahiKey *b); /** Match a key to a key pattern. The pattern has a type of AVAHI_DNS_CLASS_ANY, the classes are taken to be equal. Same for the type. If the pattern has neither class nor type with ANY constants, this function is identical to avahi_key_equal(). In contrast to avahi_equal() this function is not commutative. */ -gboolean avahi_key_pattern_match(const AvahiKey *pattern, const AvahiKey *k); +int avahi_key_pattern_match(const AvahiKey *pattern, const AvahiKey *k); /** Check whether a key is a pattern key, i.e. the class/type has a * value of AVAHI_DNS_CLASS_ANY/AVAHI_DNS_TYPE_ANY */ -gboolean avahi_key_is_pattern(const AvahiKey *k); +int avahi_key_is_pattern(const AvahiKey *k); /** Return a numeric hash value for a key for usage in hash tables. */ -guint avahi_key_hash(const AvahiKey *k); +unsigned avahi_key_hash(const AvahiKey *k); /** Create a new record object. Record data should be filled in right after creation. The reference counter is set to 1. */ -AvahiRecord *avahi_record_new(AvahiKey *k, guint32 ttl); +AvahiRecord *avahi_record_new(AvahiKey *k, uint32_t ttl); /** Create a new record object. Record data should be filled in right after creation. The reference counter is set to 1. */ -AvahiRecord *avahi_record_new_full(const gchar *name, guint16 clazz, guint16 type, guint32 ttl); +AvahiRecord *avahi_record_new_full(const char *name, uint16_t clazz, uint16_t type, uint32_t ttl); /** Increase the reference counter of an AvahiRecord by one. */ AvahiRecord *avahi_record_ref(AvahiRecord *r); @@ -162,47 +163,47 @@ void avahi_record_unref(AvahiRecord *r); /** Return a textual representation of the specified DNS class. The * returned pointer points to a read only internal string. */ -const gchar *avahi_dns_class_to_string(guint16 clazz); +const char *avahi_dns_class_to_string(uint16_t clazz); /** Return a textual representation of the specified DNS class. The * returned pointer points to a read only internal string. */ -const gchar *avahi_dns_type_to_string(guint16 type); +const char *avahi_dns_type_to_string(uint16_t type); /** Create a textual representation of the specified key. g_free() the * result! */ -gchar *avahi_key_to_string(const AvahiKey *k); +char *avahi_key_to_string(const AvahiKey *k); /** Create a textual representation of the specified record, similar * in style to BIND zone file data. g_free() the result! */ -gchar *avahi_record_to_string(const AvahiRecord *r); +char *avahi_record_to_string(const AvahiRecord *r); /** Check whether two records are equal (regardless of the TTL */ -gboolean avahi_record_equal_no_ttl(const AvahiRecord *a, const AvahiRecord *b); +int avahi_record_equal_no_ttl(const AvahiRecord *a, const AvahiRecord *b); /** Make a deep copy of an AvahiRecord object */ AvahiRecord *avahi_record_copy(AvahiRecord *r); /** Returns a maximum estimate for the space that is needed to store * this key in a DNS packet. */ -guint avahi_key_get_estimate_size(AvahiKey *k); +size_t avahi_key_get_estimate_size(AvahiKey *k); /** Returns a maximum estimate for the space that is needed to store * the record in a DNS packet. */ -guint avahi_record_get_estimate_size(AvahiRecord *r); +size_t avahi_record_get_estimate_size(AvahiRecord *r); /** Do a mDNS spec conforming lexicographical comparison of the two * records. Return a negative value if a < b, a positive if a > b, * zero if equal. */ -gint avahi_record_lexicographical_compare(AvahiRecord *a, AvahiRecord *b); +int avahi_record_lexicographical_compare(AvahiRecord *a, AvahiRecord *b); /** Return TRUE if the specified record is an mDNS goodbye record. i.e. TTL is zero. */ -gboolean avahi_record_is_goodbye(AvahiRecord *r); +int avahi_record_is_goodbye(AvahiRecord *r); /** Check whether the specified key is valid */ -gboolean avahi_key_valid(AvahiKey *k); +int avahi_key_is_valid(AvahiKey *k); /** Check whether the specified record is valid */ -gboolean avahi_record_valid(AvahiRecord *r); +int avahi_record_is_valid(AvahiRecord *r); AVAHI_C_DECL_END diff --git a/avahi-core/rrlist.c b/avahi-core/rrlist.c index ce4640c..b05e1c6 100644 --- a/avahi-core/rrlist.c +++ b/avahi-core/rrlist.c @@ -19,17 +19,22 @@ USA. ***/ +#include + #include +#include + #include "rrlist.h" +#include "log.h" typedef struct AvahiRecordListItem AvahiRecordListItem; struct AvahiRecordListItem { - gboolean read; + int read; AvahiRecord *record; - gboolean unicast_response; - gboolean flush_cache; - gboolean auxiliary; + int unicast_response; + int flush_cache; + int auxiliary; AVAHI_LLIST_FIELDS(AvahiRecordListItem, items); }; @@ -40,22 +45,28 @@ struct AvahiRecordList { }; AvahiRecordList *avahi_record_list_new(void) { - AvahiRecordList *l = g_new(AvahiRecordList, 1); + AvahiRecordList *l; + + if (!(l = avahi_new(AvahiRecordList, 1))) { + avahi_log_error("avahi_new() failed."); + return NULL; + } + AVAHI_LLIST_HEAD_INIT(AvahiRecordListItem, l->read); AVAHI_LLIST_HEAD_INIT(AvahiRecordListItem, l->unread); return l; } void avahi_record_list_free(AvahiRecordList *l) { - g_assert(l); + assert(l); avahi_record_list_flush(l); - g_free(l); + avahi_free(l); } static void item_free(AvahiRecordList *l, AvahiRecordListItem *i) { - g_assert(l); - g_assert(i); + assert(l); + assert(i); if (i->read) AVAHI_LLIST_REMOVE(AvahiRecordListItem, items, l->read, i); @@ -63,11 +74,11 @@ static void item_free(AvahiRecordList *l, AvahiRecordListItem *i) { AVAHI_LLIST_REMOVE(AvahiRecordListItem, items, l->unread, i); avahi_record_unref(i->record); - g_free(i); + avahi_free(i); } void avahi_record_list_flush(AvahiRecordList *l) { - g_assert(l); + assert(l); while (l->read) item_free(l, l->read); @@ -75,14 +86,14 @@ void avahi_record_list_flush(AvahiRecordList *l) { item_free(l, l->unread); } -AvahiRecord* avahi_record_list_next(AvahiRecordList *l, gboolean *flush_cache, gboolean *unicast_response, gboolean *auxiliary) { +AvahiRecord* avahi_record_list_next(AvahiRecordList *l, int *flush_cache, int *unicast_response, int *auxiliary) { AvahiRecord *r; AvahiRecordListItem *i; if (!(i = l->unread)) return NULL; - g_assert(!i->read); + assert(!i->read); r = avahi_record_ref(i->record); if (unicast_response) @@ -103,8 +114,8 @@ AvahiRecord* avahi_record_list_next(AvahiRecordList *l, gboolean *flush_cache, g static AvahiRecordListItem *get(AvahiRecordList *l, AvahiRecord *r) { AvahiRecordListItem *i; - g_assert(l); - g_assert(r); + assert(l); + assert(r); for (i = l->read; i; i = i->items_next) if (avahi_record_equal_no_ttl(i->record, r)) @@ -117,16 +128,20 @@ static AvahiRecordListItem *get(AvahiRecordList *l, AvahiRecord *r) { return NULL; } -void avahi_record_list_push(AvahiRecordList *l, AvahiRecord *r, gboolean flush_cache, gboolean unicast_response, gboolean auxiliary) { +void avahi_record_list_push(AvahiRecordList *l, AvahiRecord *r, int flush_cache, int unicast_response, int auxiliary) { AvahiRecordListItem *i; - g_assert(l); - g_assert(r); + assert(l); + assert(r); if (get(l, r)) return; - i = g_new(AvahiRecordListItem, 1); + if (!(i = avahi_new(AvahiRecordListItem, 1))) { + avahi_log_error("avahi_new() failed."); + return; + } + i->unicast_response = unicast_response; i->flush_cache = flush_cache; i->auxiliary = auxiliary; @@ -139,8 +154,8 @@ void avahi_record_list_push(AvahiRecordList *l, AvahiRecord *r, gboolean flush_c void avahi_record_list_drop(AvahiRecordList *l, AvahiRecord *r) { AvahiRecordListItem *i; - g_assert(l); - g_assert(r); + assert(l); + assert(r); if (!(i = get(l, r))) return; @@ -148,8 +163,8 @@ void avahi_record_list_drop(AvahiRecordList *l, AvahiRecord *r) { item_free(l, i); } -gboolean avahi_record_list_empty(AvahiRecordList *l) { - g_assert(l); +int avahi_record_list_is_empty(AvahiRecordList *l) { + assert(l); return !l->unread && !l->read; } diff --git a/avahi-core/rrlist.h b/avahi-core/rrlist.h index 9651475..200dae8 100644 --- a/avahi-core/rrlist.h +++ b/avahi-core/rrlist.h @@ -31,10 +31,10 @@ AvahiRecordList *avahi_record_list_new(void); void avahi_record_list_free(AvahiRecordList *l); void avahi_record_list_flush(AvahiRecordList *l); -AvahiRecord* avahi_record_list_next(AvahiRecordList *l, gboolean *flush_cache, gboolean *unicast_response, gboolean *auxiliary); -void avahi_record_list_push(AvahiRecordList *l, AvahiRecord *r, gboolean flush_cache, gboolean unicast_response, gboolean auxiliary); +AvahiRecord* avahi_record_list_next(AvahiRecordList *l, int *flush_cache, int *unicast_response, int *auxiliary); +void avahi_record_list_push(AvahiRecordList *l, AvahiRecord *r, int flush_cache, int unicast_response, int auxiliary); void avahi_record_list_drop(AvahiRecordList *l, AvahiRecord *r); -gboolean avahi_record_list_empty(AvahiRecordList *l); +int avahi_record_list_is_empty(AvahiRecordList *l); #endif diff --git a/avahi-core/server.c b/avahi-core/server.c index 241932f..1a36e42 100644 --- a/avahi-core/server.c +++ b/avahi-core/server.c @@ -565,7 +565,7 @@ static void handle_query_packet(AvahiServer *s, AvahiDnsPacket *p, AvahiInterfac /* avahi_log_debug("query"); */ - g_assert(avahi_record_list_empty(s->record_list)); + g_assert(avahi_record_list_is_empty(s->record_list)); is_probe = avahi_dns_packet_get_field(p, AVAHI_DNS_FIELD_NSCOUNT) > 0; @@ -628,7 +628,7 @@ static void handle_query_packet(AvahiServer *s, AvahiDnsPacket *p, AvahiInterfac avahi_record_unref(record); } - if (!avahi_record_list_empty(s->record_list)) + if (!avahi_record_list_is_empty(s->record_list)) avahi_server_generate_response(s, i, p, a, port, legacy_unicast, is_probe); return; @@ -676,7 +676,7 @@ static void handle_response_packet(AvahiServer *s, AvahiDnsPacket *p, AvahiInter /* If the incoming response contained a conflicting record, some records have been scheduling for sending. We need to flush them here. */ - if (!avahi_record_list_empty(s->record_list)) + if (!avahi_record_list_is_empty(s->record_list)) avahi_server_generate_response(s, i, NULL, NULL, 0, FALSE, TRUE); } @@ -1224,7 +1224,7 @@ gint avahi_server_set_host_name(AvahiServer *s, const gchar *host_name) { g_assert(s); g_assert(host_name); - if (host_name && !avahi_valid_host_name(host_name)) + if (host_name && !avahi_is_valid_host_name(host_name)) return avahi_server_set_errno(s, AVAHI_ERR_INVALID_HOST_NAME); withdraw_host_rrs(s); @@ -1242,7 +1242,7 @@ gint avahi_server_set_domain_name(AvahiServer *s, const gchar *domain_name) { g_assert(s); g_assert(domain_name); - if (domain_name && !avahi_valid_domain_name(domain_name)) + if (domain_name && !avahi_is_valid_domain_name(domain_name)) return avahi_server_set_errno(s, AVAHI_ERR_INVALID_DOMAIN_NAME); withdraw_host_rrs(s); @@ -1268,10 +1268,10 @@ static void prepare_pollfd(AvahiServer *s, GPollFD *pollfd, gint fd) { static gint valid_server_config(const AvahiServerConfig *sc) { - if (sc->host_name && !avahi_valid_host_name(sc->host_name)) + if (sc->host_name && !avahi_is_valid_host_name(sc->host_name)) return AVAHI_ERR_INVALID_HOST_NAME; - if (sc->domain_name && !avahi_valid_domain_name(sc->domain_name)) + if (sc->domain_name && !avahi_is_valid_domain_name(sc->domain_name)) return AVAHI_ERR_INVALID_DOMAIN_NAME; return AVAHI_OK; @@ -1498,7 +1498,7 @@ gint avahi_server_add( if (avahi_key_is_pattern(r->key)) return avahi_server_set_errno(s, AVAHI_ERR_IS_PATTERN); - if (!avahi_record_valid(r)) + if (!avahi_record_is_valid(r)) return avahi_server_set_errno(s, AVAHI_ERR_INVALID_RECORD); if (check_record_conflict(s, interface, protocol, r, flags) < 0) @@ -1612,7 +1612,7 @@ gint avahi_server_add_address( name = name ? (n = avahi_normalize_name(name)) : s->host_name_fqdn; - if (!avahi_valid_domain_name(name)) { + if (!avahi_is_valid_domain_name(name)) { avahi_server_set_errno(s, AVAHI_ERR_INVALID_HOST_NAME); goto fail; } @@ -1782,16 +1782,16 @@ static gint server_add_service_strlst_nocopy( g_assert(type); g_assert(name); - if (!avahi_valid_service_name(name)) + if (!avahi_is_valid_service_name(name)) return avahi_server_set_errno(s, AVAHI_ERR_INVALID_SERVICE_NAME); - if (!avahi_valid_service_type(type)) + if (!avahi_is_valid_service_type(type)) return avahi_server_set_errno(s, AVAHI_ERR_INVALID_SERVICE_TYPE); - if (domain && !avahi_valid_domain_name(domain)) + if (domain && !avahi_is_valid_domain_name(domain)) return avahi_server_set_errno(s, AVAHI_ERR_INVALID_DOMAIN_NAME); - if (host && !avahi_valid_domain_name(host)) + if (host && !avahi_is_valid_domain_name(host)) return avahi_server_set_errno(s, AVAHI_ERR_INVALID_HOST_NAME); if (port == 0) @@ -1948,7 +1948,7 @@ gint avahi_server_add_dns_server_address( g_assert(type == AVAHI_DNS_SERVER_UPDATE || type == AVAHI_DNS_SERVER_RESOLVE); g_assert(address->family == AVAHI_PROTO_INET || address->family == AVAHI_PROTO_INET6); - if (domain && !avahi_valid_domain_name(domain)) + if (domain && !avahi_is_valid_domain_name(domain)) return avahi_server_set_errno(s, AVAHI_ERR_INVALID_DOMAIN_NAME); if (port == 0) @@ -1991,7 +1991,7 @@ gint avahi_server_add_dns_server_name( g_assert(name); g_assert(type == AVAHI_DNS_SERVER_UPDATE || type == AVAHI_DNS_SERVER_RESOLVE); - if (domain && !avahi_valid_domain_name(domain)) + if (domain && !avahi_is_valid_domain_name(domain)) return avahi_server_set_errno(s, AVAHI_ERR_INVALID_DOMAIN_NAME); if (port == 0) diff --git a/avahi-core/util.c b/avahi-core/util.c index 514f0d9..4fe8737 100644 --- a/avahi-core/util.c +++ b/avahi-core/util.c @@ -27,6 +27,7 @@ #include #include #include +#include #include @@ -91,3 +92,26 @@ char *avahi_format_mac_address(const uint8_t* mac, size_t size) { return r; } + + +char *avahi_strdown(char *s) { + char *c; + + assert(s); + + for (c = s; *c; c++) + *c = (char) tolower(*c); + + return s; +} + +char *avahi_strup(char *s) { + char *c; + assert(s); + + for (c = s; *c; c++) + *c = (char) toupper(*c); + + return s; +} + diff --git a/avahi-core/util.h b/avahi-core/util.h index ec124bc..1a07363 100644 --- a/avahi-core/util.h +++ b/avahi-core/util.h @@ -32,6 +32,12 @@ void avahi_hexdump(const void *p, size_t size); char *avahi_format_mac_address(const uint8_t* mac, size_t size); +/** Change every character in the string to upper case (ASCII), return a pointer to the string */ +char *avahi_strup(char *s); + +/** Change every character in the string to lower case (ASCII), return a pointer to the string */ +char *avahi_strdown(char *s); + AVAHI_C_DECL_END #endif -- 2.39.5