]> git.meshlink.io Git - catta/commitdiff
* rename avahi_service_name_snprint() to avahi_service_name_join()
authorLennart Poettering <lennart@poettering.net>
Mon, 10 Oct 2005 22:34:06 +0000 (22:34 +0000)
committerLennart Poettering <lennart@poettering.net>
Mon, 10 Oct 2005 22:34:06 +0000 (22:34 +0000)
* add avahi_service_name_split() and make everything use it
* change avahi_normalize_name() to work on a supplied buffer instead of malloc'ed memory.
* add avahi_normalize_name_strdup() that retains the old behaviour avahi_normalize_name()
* same thing for avahi_get_host_name()/avahi_get_host_name_strdup()
* Rewrite domain name escaping and validity checking code
* Remove superfluous memory allocationsfrom various browsers and do some other major cleanups
* add new global macro AVAHI_CHECK_VALIDITY_RETURN_NULL() and modify many things to make use of it
* add AVAHI_LABEL_MAX
* patch everything to make use of AVAHI_LABEL_MAX and AVAHI_DOMAIN_NAME_MAX
* add pretty printing for NS records
* add partial pretty printing for SOA records
* add many more validity checks to various user API functions

git-svn-id: file:///home/lennart/svn/public/avahi/trunk@708 941a03a8-eaeb-0310-b9a0-b1bbd8fe43fe

16 files changed:
avahi-common/domain-test.c
avahi-common/domain.c
avahi-common/domain.h
avahi-compat-libdns_sd/compat.c
avahi-core/browse-dns-server.c
avahi-core/browse-domain.c
avahi-core/browse-service-type.c
avahi-core/browse-service.c
avahi-core/browse.c
avahi-core/dns.c
avahi-core/publish.h
avahi-core/resolve-host-name.c
avahi-core/resolve-service.c
avahi-core/rr.c
avahi-core/server.c
avahi-core/server.h

index 35ce6d6a1d86f4461aa4e1cb176766185298ace3..444f553fbfc1ea65eb5e8365d95b2fdb7f451c3c 100644 (file)
 #endif
 
 #include <stdio.h>
+#include <string.h>
+#include <assert.h>
 
 #include "domain.h"
 #include "malloc.h"
 
 int main(int argc, char *argv[]) {
     char *s;
-    char t[256];
+    char t[256], r[256];
+    const char *p;
+    size_t size;
+    char name[64], type[AVAHI_DOMAIN_NAME_MAX], domain[AVAHI_DOMAIN_NAME_MAX];
     
-    printf("host name: %s\n", s = avahi_get_host_name());
+    printf("host name: %s\n", s = avahi_get_host_name_strdup());
     avahi_free(s);
 
-    printf("%s\n", s = avahi_normalize_name("foo.foo."));
+    printf("%s\n", s = avahi_normalize_name_strdup("foo.foo\\046."));
     avahi_free(s);
 
-    printf("%s\n", s = avahi_normalize_name("foo\.foo."));
+    printf("%s\n", s = avahi_normalize_name_strdup("foo.foo\\.foo."));
     avahi_free(s);
 
     
-    printf("%s\n", s = avahi_normalize_name("\\f\\o\\\\o\\..\\f\\ \\o\\o."));
+    printf("%s\n", s = avahi_normalize_name_strdup("fo\\\\o\\..f oo."));
     avahi_free(s);
 
-    printf("%i\n", avahi_domain_equal("\\aaa bbb\\.cccc\\\\.dee.fff.", "aaa\\ bbb\\.cccc\\\\.dee.fff"));
-    printf("%i\n", avahi_domain_equal("\\A", "a"));
+    printf("%i\n", avahi_domain_equal("\\065aa bbb\\.\\046cc.cc\\\\.dee.fff.", "Aaa BBB\\.\\.cc.cc\\\\.dee.fff"));
+    printf("%i\n", avahi_domain_equal("A", "a"));
 
     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("ccc\\065aa.aa\\.b\\\\."), avahi_domain_hash("cccAaa.aa\\.b\\\\"));
 
 
-    avahi_service_name_snprint(t, sizeof(t), "foo.foo.foo \.", "_http._tcp", "test.local");
+    avahi_service_name_join(t, sizeof(t), "foo.foo.foo \.", "_http._tcp", "test.local");
     printf("<%s>\n", t);
 
-
-    avahi_service_name_snprint(t, sizeof(t), NULL, "_http._tcp", "one.two\. .local");
+    avahi_service_name_split(t, name, sizeof(name), type, sizeof(type), domain, sizeof(domain));
+    printf("name: <%s>; type: <%s>; domain <%s>\n", name, type, domain);
+    
+    avahi_service_name_join(t, sizeof(t), NULL, "_http._tcp", "one.two\. .local");
     printf("<%s>\n", t);
 
+    avahi_service_name_split(t, NULL, 0, type, sizeof(type), domain, sizeof(domain));
+    printf("name: <>; type: <%s>; domain <%s>\n", type, domain);
+
+
+    p = "--:---\\\\\\123\\065_äöü\\064\\.\\\\sjöödfhh.sdfjhskjdf";
+    printf("unescaped: <%s>, rest: %s\n", avahi_unescape_label(&p, t, sizeof(t)), p);
+
+    size = sizeof(r);
+    s = r;
     
+    printf("escaped: <%s>\n", avahi_escape_label(t, strlen(t), &s, &size));
+
+    p = r;
+    printf("unescaped: <%s>\n", avahi_unescape_label(&p, t, sizeof(t)));
+
+    assert(avahi_domain_ends_with("foo.bar.\\065\\\\\\.aaaa", "\\065\\\\\\.aaaa"));
+
+    assert(avahi_is_valid_service_type("_foo._bar._waldo"));
+    assert(!avahi_is_valid_service_type("_foo._bar.waldo"));
+    assert(!avahi_is_valid_service_type(""));
+
+    assert(!avahi_is_valid_host_name("sf.ooo."));
+    assert(avahi_is_valid_host_name("sfooo."));
+    assert(avahi_is_valid_host_name("sfooo"));
+
     return 0;
 }
index bffe56329671f900b7af24d84b6460723c04d8d1..b72a8989a0dab9a0511200847e1a149d542296a7 100644 (file)
 #include "malloc.h"
 #include "error.h"
 
-char *avahi_get_host_name(void) {
+char *avahi_get_host_name(char *ret_s, size_t size) {
 #ifdef HOST_NAME_MAX
     char t[HOST_NAME_MAX];
 #else
     char t[256];
 #endif
-    gethostname(t, sizeof(t));
-    t[sizeof(t)-1] = 0;
-    return avahi_normalize_name(t);
-}
-
-static char *unescape_uneeded(const char *src, char *ret_dest, size_t size) {
-    int escaped = 0;
     
-    assert(src);
-    assert(ret_dest);
+    assert(ret_s);
     assert(size > 0);
     
-    for (; *src; src++) {
-
-        if (!escaped && *src == '\\')
-            escaped = 1;
-        else if (escaped && (*src == '.' || *src == '\\')) {
-
-            if ((size -= 2) <= 1) break;
-            
-            *(ret_dest++) = '\\';
-            *(ret_dest++) = *src;
-            escaped = 0;
-        } else {
-            if (--size <= 1) break;
-
-            *(ret_dest++) = *src;
-            escaped = 0;
-        }
-
-    }
-
-    *ret_dest = 0;
+    gethostname(t, sizeof(t));
+    t[sizeof(t)-1] = 0;
     
-    return ret_dest;
+    return avahi_normalize_name(t, ret_s, size);
 }
 
-char *avahi_normalize_name(const char *s) {
-    char tmp[256];
-    size_t l;
-    
-    assert(s);
-
-    unescape_uneeded(s, tmp, sizeof(tmp));
-
-    l = strlen(tmp);
+char *avahi_get_host_name_strdup(void) {
+    char t[AVAHI_DOMAIN_NAME_MAX];
 
-    while (l > 0 && tmp[l-1] == '.')
-        tmp[--l] = 0;
+    if (!(avahi_get_host_name(t, sizeof(t))))
+        return NULL;
 
-    return avahi_strdup(tmp);
+    return avahi_strdup(t);
 }
 
-
 /* Read the first label from string *name, unescape "\" and write it to dest */
 char *avahi_unescape_label(const char **name, char *dest, size_t size) {
     unsigned i = 0;
@@ -106,9 +71,6 @@ char *avahi_unescape_label(const char **name, char *dest, size_t size) {
     assert(size > 0);
     assert(name);
 
-    if (!**name)
-        return NULL;
-
     d = dest;
     
     for (;;) {
@@ -124,14 +86,45 @@ char *avahi_unescape_label(const char **name, char *dest, size_t size) {
             break;
         
         if (**name == '\\') {
+            /* Escaped character */
+
             (*name) ++;
-            
+
             if (**name == 0)
-                break;
+                /* Ending NUL */
+                return NULL;
+            
+            else if (**name == '\\' || **name == '.') {
+                /* Escaped backslash or dot */
+                *(d++) = *((*name) ++);
+                i++;
+            } else if (isdigit(**name)) {
+                int n;
+
+                /* Escaped literal ASCII character */
+                
+                if (!isdigit(*(*name+1)) || !isdigit(*(*name+2)))
+                    return NULL;
+
+                n = ((uint8_t) (**name - '0') * 100) + ((uint8_t) (*(*name+1) - '0') * 10) + ((uint8_t) (*(*name +2) - '0'));
+
+                if (n > 255 || n == 0)
+                    return NULL;
+                
+                *(d++) = (char) n;
+                i++;
+
+                (*name) += 3;
+            } else
+                return NULL;
+            
+        } else {
+
+            /* Normal character */
+            
+            *(d++) = *((*name) ++);
+            i++;
         }
-        
-        *(d++) = *((*name) ++);
-        i++;
     }
 
     assert(i < size);
@@ -142,7 +135,7 @@ char *avahi_unescape_label(const char **name, char *dest, size_t size) {
 }
 
 /* Escape "\" and ".", append \0 */
-char *avahi_escape_label(const uint8_t* src, size_t src_length, char **ret_name, size_t *ret_size) {
+char *avahi_escape_label(const char* src, size_t src_length, char **ret_name, size_t *ret_size) {
     char *r;
 
     assert(src);
@@ -155,18 +148,45 @@ char *avahi_escape_label(const uint8_t* src, size_t src_length, char **ret_name,
 
     while (src_length > 0) {
         if (*src == '.' || *src == '\\') {
+
+            /* Dot or backslash */
+            
             if (*ret_size < 3)
                 return NULL;
             
             *((*ret_name) ++) = '\\';
+            *((*ret_name) ++) = *src;
+            (*ret_size) -= 2;
+            
+        } else if (
+            *src == '_' ||
+            *src == '-' ||
+            (*src >= '0' && *src <= '9') ||
+            (*src >= 'a' && *src <= 'z') ||
+            (*src >= 'A' && *src <= 'Z')) {
+
+            /* Proper character */
+            
+            if (*ret_size < 2)
+                return NULL;
+        
+            *((*ret_name)++) = *src;
             (*ret_size) --;
-        }
+            
+        } else {
 
-        if (*ret_size < 2)
-            return NULL;
-        
-        *((*ret_name)++) = *src;
-        (*ret_size) --;
+            /* Everything else */
+
+            if (*ret_size < 5)
+                return NULL;
+
+            *((*ret_name) ++) = '\\';
+            *((*ret_name) ++) = '0' + (char)  ((uint8_t) *src / 100);
+            *((*ret_name) ++) = '0' + (char) (((uint8_t) *src / 10) % 10);
+            *((*ret_name) ++) = '0' + (char)  ((uint8_t) *src % 10);
+            
+            (*ret_size) -= 4;
+        }
 
         src_length --;
         src++;
@@ -177,6 +197,53 @@ char *avahi_escape_label(const uint8_t* src, size_t src_length, char **ret_name,
     return r;
 }
 
+char *avahi_normalize_name(const char *s, char *ret_s, size_t size) {
+    int empty = 1;
+    char *r;
+    
+    assert(s);
+    assert(ret_s);
+    assert(size > 0);
+
+    r = ret_s;
+    while (*s) {
+        char label[AVAHI_LABEL_MAX];
+
+        if (!(avahi_unescape_label(&s, label, sizeof(label))))
+            return NULL;
+
+        if (strlen(label) > 0) {
+
+            if (!empty) {
+                if (size < 1)
+                    return NULL;
+
+                *(r++) = '.';
+                size--;
+
+            } else
+                empty = 0;
+            
+            avahi_escape_label(label, strlen(label), &r, &size);
+        }
+    }
+
+    if (empty)
+        return NULL;
+    
+    return ret_s;
+}
+
+char *avahi_normalize_name_strdup(const char *s) {
+    char t[AVAHI_DOMAIN_NAME_MAX];
+    assert(s);
+
+    if (!(avahi_normalize_name(s, t, sizeof(t))))
+        return NULL;
+
+    return avahi_strdup(t);
+}
+
 int avahi_domain_equal(const char *a, const char *b) {
     assert(a);
     assert(b);
@@ -185,18 +252,18 @@ int avahi_domain_equal(const char *a, const char *b) {
         return 1;
     
     for (;;) {
-        char ca[65], cb[65], *pa, *pb;
+        char ca[AVAHI_LABEL_MAX], cb[AVAHI_LABEL_MAX], *r;
 
-        pa = avahi_unescape_label(&a, ca, sizeof(ca));
-        pb = avahi_unescape_label(&b, cb, sizeof(cb));
+        r = avahi_unescape_label(&a, ca, sizeof(ca));
+        assert(r);
+        r = avahi_unescape_label(&b, cb, sizeof(cb));
+        assert(r);
 
-        if (!pa && !pb)
-            return 1;
-        else if ((pa && !pb) || (!pa && pb))
-            return 0;
-
-        if (strcasecmp(pa, pb))
+        if (strcasecmp(ca, cb))
             return 0;
+        
+        if (!*a && !*b)
+            return 1;
     }
 
     return 1;
@@ -210,113 +277,85 @@ int avahi_binary_domain_cmp(const char *a, const char *b) {
         return 0;
 
     for (;;) {
-        char ca[65], cb[65], *pa, *pb;
+        char ca[AVAHI_LABEL_MAX], cb[AVAHI_LABEL_MAX], *p;
         int r;
 
-        pa = avahi_unescape_label(&a, ca, sizeof(ca));
-        pb = avahi_unescape_label(&b, cb, sizeof(cb));
+        p = avahi_unescape_label(&a, ca, sizeof(ca));
+        assert(p);
+        p = avahi_unescape_label(&b, cb, sizeof(cb));
+        assert(p);
 
-        if (!pa && !pb)
-            return 0;
-        else if (pa && !pb)
-            return 1;
-        else if (!pa && pb)
-            return -1;
-        
-        if ((r = strcmp(pa, pb)))
+        if ((r = strcmp(ca, cb)))
             return r;
+        
+        if (!*a && !*b)
+            return 0;
     }
 }
 
 int avahi_is_valid_service_type(const char *t) {
-    const char *p;
     assert(t);
 
-    if (strlen(t) < 5)
-        return 0;
-    
-    if (*t != '_')
+    if (strlen(t) >= AVAHI_DOMAIN_NAME_MAX || !*t)
         return 0;
 
-    if (!(p = strchr(t, '.')))
-        return 0;
+    do {
+        char label[AVAHI_LABEL_MAX];
 
-    if (p - t > 63 || p - t < 2)
-        return 0;
-
-    if (*(++p) != '_')
-        return 0;
+        if (!(avahi_unescape_label(&t, label, sizeof(label))))
+            return 0;
 
-    if (strchr(p, '.'))
-        return 0;
+        if (strlen(label) <= 2 || label[0] != '_')
+            return 0;
+        
+    } while (*t);
 
-    if (strlen(p) > 63 || strlen(p) < 2)
-        return 0;
-    
     return 1;
 }
 
 int avahi_is_valid_domain_name(const char *t) {
-    const char *p, *dp;
-    int dot = 0;
-        
     assert(t);
 
-    if (*t == 0)
-        return 0;
-
-    /* Domains may not start with a dot */
-    if (*t == '.')
+    if (strlen(t) >= AVAHI_DOMAIN_NAME_MAX || !*t)
         return 0;
 
-    dp = t; 
+    do {
+        char label[AVAHI_LABEL_MAX];
 
-    for (p = t; *p; p++) {
-
-        if (*p == '.') {
-            if (dot) /* Two subsequent dots */
-                return 0;
-
-            if (p - dp > 63)
-                return 0;
-
-            dot = 1;
-            dp = p + 1;
-        } else
-            dot = 0;
-
-    }
+        if (!(avahi_unescape_label(&t, label, sizeof(label))))
+            return 0;
 
-    if (p - dp > 63)
-        return 0;
+        if (strlen(label) < 1)
+            return 0;
+        
+    } while (*t);
 
-    /* A trailing dot IS allowed */
-    
     return 1;
 }
 
 int avahi_is_valid_service_name(const char *t) {
     assert(t);
 
-    if (*t == 0)
+    if (strlen(t) >= AVAHI_LABEL_MAX || !*t)
         return 0;
-
-    if (strlen(t) > 63)
-        return 0;
-
+        
     return 1;
 }
 
 int avahi_is_valid_host_name(const char *t) {
+    char label[AVAHI_LABEL_MAX];
     assert(t);
 
-    if (*t == 0)
+    if (strlen(t) >= AVAHI_DOMAIN_NAME_MAX || !*t)
+        return 0;
+
+    if (!(avahi_unescape_label(&t, label, sizeof(label))))
         return 0;
 
-    if (strlen(t) > 63)
+    if (strlen(label) < 1)
         return 0;
 
-    if (strchr(t, '.'))
+    if (*t)
         return 0;
 
     return 1;
@@ -325,100 +364,166 @@ int avahi_is_valid_host_name(const char *t) {
 unsigned avahi_domain_hash(const char *s) {
     unsigned hash = 0;
     
-    for (;;) {
-        char c[65], *p;
-
-        if (!avahi_unescape_label(&s, c, sizeof(c)))
-            return hash;
+    while (*s) {
+        char c[AVAHI_LABEL_MAX], *p, *r;
 
-        if (!c[0])
-            continue;
+        r = avahi_unescape_label(&s, c, sizeof(c));
+        assert(r);
 
         for (p = c; *p; p++)
             hash = 31 * hash + tolower(*p);
     }
+
+    return hash;
 }
 
 int avahi_domain_ends_with(const char *domain, const char *suffix) {
     assert(domain);
     assert(suffix);
 
-    assert(avahi_is_valid_domain_name(domain));
-    assert(avahi_is_valid_domain_name(suffix));
-
     for (;;) {
-        char dummy[64];
+        char dummy[AVAHI_LABEL_MAX], *r;
+
+        if (*domain == 0)
+            return 0;
         
         if (avahi_domain_equal(domain, suffix))
             return 1;
 
-        if (!(avahi_unescape_label(&domain, dummy, sizeof(dummy))))
-            return 0;
+        r = avahi_unescape_label(&domain, dummy, sizeof(dummy));
+        assert(r);
     } 
 }
 
-static void escape_service_name(char *d, size_t size, const char *s) {
-    assert(d);
-    assert(size);
-    assert(s);
+int avahi_service_name_join(char *p, size_t size, const char *name, const char *type, const char *domain) {
+    char escaped_name[AVAHI_LABEL_MAX];
+    char normalized_type[AVAHI_DOMAIN_NAME_MAX];
+    char normalized_domain[AVAHI_DOMAIN_NAME_MAX];
+    
+    assert(p);
 
-    while (*s && size >= 2) {
-        if (*s == '.' || *s == '\\') {
-            if (size < 3)
-                break;
+    /* Validity checks */
+    
+    if ((name && !avahi_is_valid_service_name(name)))
+        return AVAHI_ERR_INVALID_SERVICE_NAME;
 
-            *(d++) = '\\';
-            size--;
-        }
-            
-        *(d++) = *(s++);
-        size--;
+    if (!avahi_is_valid_service_type(type))
+        return AVAHI_ERR_INVALID_SERVICE_TYPE;
+        
+    if (!avahi_is_valid_domain_name(domain))
+        return AVAHI_ERR_INVALID_DOMAIN_NAME;
+
+    /* Preparation */
+    
+    if (name) {
+        size_t l = sizeof(escaped_name);
+        char *e = escaped_name, *r;
+        r = avahi_escape_label(name, strlen(name), &e, &l);
+        assert(r);
     }
 
-    assert(size > 0);
-    *(d++) = 0;
-}
+    if (!(avahi_normalize_name(type, normalized_type, sizeof(normalized_type))))
+        return AVAHI_ERR_INVALID_SERVICE_TYPE;
 
+    if (!(avahi_normalize_name(domain, normalized_domain, sizeof(normalized_domain))))
+        return AVAHI_ERR_INVALID_DOMAIN_NAME;
 
-int avahi_service_name_snprint(char *p, size_t size, const char *name, const char *type, const char *domain) {
-    char *t = NULL, *d = NULL;
-    char ename[64];
-    int ret;
+    /* Concatenation */
     
-    assert(p);
+    snprintf(p, size, "%s%s%s.%s", name ? escaped_name : "", name ? "." : "", normalized_type, normalized_domain);
 
-    if ((name && !avahi_is_valid_service_name(name))) {
-        ret = AVAHI_ERR_INVALID_SERVICE_NAME;
-        goto fail;
-    }
+    return AVAHI_OK;
+}
 
-    if (!avahi_is_valid_service_type(type)) {
-        ret = AVAHI_ERR_INVALID_SERVICE_TYPE;
-        goto fail;
-    }
-        
-    if (!avahi_is_valid_domain_name(domain)) {
-        ret = AVAHI_ERR_INVALID_DOMAIN_NAME;
-        goto fail;
-    }
+
+char *avahi_strlcpy(char *dest, const char *src, size_t n) {
+    assert(dest);
+    assert(src);
+
+    if (n == 0)
+        return dest;
         
-    if (name)
-        escape_service_name(ename, sizeof(ename), name);
+    strncpy(dest, src, n-1);
+    dest[n-1] = 0;
+    return dest;
+}
+
+int avahi_service_name_split(const char *p, char *name, size_t name_size, char *type, size_t type_size, char *domain, size_t domain_size) {
+    enum {
+        NAME,
+        TYPE,
+        DOMAIN
+    } state;
+    int type_empty = 1, domain_empty = 1;
     
-    if (!(d = avahi_normalize_name(domain)) ||
-        !(t = avahi_normalize_name(type))) {
-        ret = AVAHI_ERR_NO_MEMORY;
-        goto fail;
-    }
+    assert(p);
+    assert(type);
+    assert(type_size > 0);
+    assert(domain);
+    assert(domain_size > 0);
+
+    if (name) {
+        assert(name_size > 0);
+        *name = 0;
+        state = NAME;
+    } else
+        state = TYPE;
+    
+    *type = *domain = 0;
+    
+    while (*p) {
+        char buf[64];
+        
+        if (!(avahi_unescape_label(&p, buf, sizeof(buf))))
+            return -1;
 
-    snprintf(p, size, "%s%s%s.%s", name ? ename : "", name ? "." : "", t, d);
+        switch (state) {
+            case NAME:
+                avahi_strlcpy(name, buf, name_size);
+                state = TYPE;
+                break;
 
-    ret = AVAHI_OK;
-    
-fail:
+            case TYPE:
+
+                if (buf[0] == '_') {
+
+                    if (!type_empty) {
+                        if (!type_size)
+                            return AVAHI_ERR_NO_MEMORY;
+                        
+                        *(type++) = '.';
+                        type_size --;
 
-    avahi_free(t);
-    avahi_free(d);
+                    } else
+                        type_empty = 0;
+                    
+                    if (!(avahi_escape_label(buf, strlen(buf), &type, &type_size)))
+                        return AVAHI_ERR_NO_MEMORY;
 
-    return ret;
+                    break;
+                } 
+
+                state = DOMAIN;
+                /* fall through */
+
+            case DOMAIN:
+
+                if (!domain_empty) {
+                    if (!domain_size)
+                        return AVAHI_ERR_NO_MEMORY;
+                    
+                    *(domain++) = '.';
+                    domain_size --;
+                } else
+                    domain_empty = 0;
+
+                if (!(avahi_escape_label(buf, strlen(buf), &domain, &domain_size)))
+                    return AVAHI_ERR_NO_MEMORY;
+
+                break;
+        }
+    }
+
+    return 0;
 }
+
index 59765ef761441911fd51982d1afe59dc16e1d28e..bcd036e4a9e143b9d9999d4b317872c09839e973 100644 (file)
@@ -44,13 +44,23 @@ AVAHI_C_DECL_BEGIN
  * the string brings us to 1014. */
 #define AVAHI_DOMAIN_NAME_MAX 1014
 
+/** Maxium size of an unescaped label */
+#define AVAHI_LABEL_MAX 64
+
+/** Normalize a domain name into canonical form. This drops trailing
+ * dots and removes useless backslash escapes. */
+char *avahi_normalize_name(const char *s, char *ret_s, size_t size);
+
 /** Normalize a domain name into canonical form. This drops trailing
  * dots and removes useless backslash escapes. avahi_free() the
  * result! */
-char *avahi_normalize_name(const char *s);
+char *avahi_normalize_name_strdup(const char *s);
+
+/** Return the local host name. */
+char *avahi_get_host_name(char *ret_s, size_t size); 
 
 /** Return the local host name. avahi_free() the result! */
-char *avahi_get_host_name(void); 
+char *avahi_get_host_name_strdup(void);
 
 /** Return 1 when the specified domain names are equal, 0 otherwise */
 int avahi_domain_equal(const char *a, const char *b);
@@ -63,7 +73,7 @@ int avahi_binary_domain_cmp(const char *a, const char *b);
 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);
+char *avahi_escape_label(const char* src, size_t src_length, char **ret_name, size_t *ret_size);
 
 /** Return 1 when the specified string contains a valid service type, 0 otherwise */
 int avahi_is_valid_service_type(const char *t);
@@ -84,7 +94,13 @@ unsigned avahi_domain_hash(const char *name);
 int avahi_domain_ends_with(const char *domain, const char *suffix);
 
 /** Construct a valid complete service name from a name, a type and a domain */
-int avahi_service_name_snprint(char *p, size_t size, const char *name, const char *type, const char *domain);
+int avahi_service_name_join(char *p, size_t size, const char *name, const char *type, const char *domain);
+
+/** Split a full service name into name, type and domain */
+int avahi_service_name_split(const char *p, char *name, size_t name_size, char *type, size_t type_size, char *domain, size_t domain_size);
+
+/** Just like OpenBSD strlcpy */
+char *avahi_strlcpy(char *dest, const char *src, size_t n);
 
 #ifndef DOXYGEN_SHOULD_SKIP_THIS
 AVAHI_C_DECL_END
index adca034a9fb9b43873153101056226b4104fce9d..9bb2ce8c00d7179bbbdc211dbf1d55be0afee51c 100644 (file)
@@ -582,7 +582,7 @@ static void service_resolver_callback(
             if ((p = avahi_new0(char, (l = avahi_string_list_serialize(txt, NULL, 0))+1)))
                 avahi_string_list_serialize(txt, p, l);
 
-            ret = avahi_service_name_snprint(full_name, sizeof(full_name), name, type, domain);
+            ret = avahi_service_name_join(full_name, sizeof(full_name), name, type, domain);
             assert(ret == AVAHI_OK);
 
             strcat(full_name, ".");
@@ -678,7 +678,7 @@ int DNSSD_API DNSServiceConstructFullName (
     assert(regtype);
     assert(domain);
 
-    if (avahi_service_name_snprint(fullName, kDNSServiceMaxDomainName, service, regtype, domain) < 0)
+    if (avahi_service_name_join(fullName, kDNSServiceMaxDomainName, service, regtype, domain) < 0)
         return -1;
     
     return 0;
@@ -970,9 +970,9 @@ DNSServiceErrorType DNSSD_API DNSServiceRegister (
     sdref->service_register_callback = callback;
 
     sdref->service_name = avahi_strdup(name);
-    sdref->service_regtype = regtype ? avahi_normalize_name(regtype) : NULL;
-    sdref->service_domain = domain ? avahi_normalize_name(domain) : NULL;
-    sdref->service_host = host ? avahi_normalize_name(host) : NULL;
+    sdref->service_regtype = regtype ? avahi_normalize_name_strdup(regtype) : NULL;
+    sdref->service_domain = domain ? avahi_normalize_name_strdup(domain) : NULL;
+    sdref->service_host = host ? avahi_normalize_name_strdup(host) : NULL;
     sdref->service_interface = interface == kDNSServiceInterfaceIndexAny ? AVAHI_IF_UNSPEC : (AvahiIfIndex) interface;
     sdref->service_port = ntohs(port);
     sdref->service_txt = txtRecord ? avahi_string_list_parse(txtRecord, txtLen) : NULL;
index 31da536ace66a4a005f3377845bca6f4068e69a6..52dafc288199e50fbc245f070158e4e211ff1694 100644 (file)
@@ -50,7 +50,6 @@ struct AvahiDNSServerInfo {
 
 struct AvahiSDNSServerBrowser {
     AvahiServer *server;
-    char *domain_name;
     
     AvahiSRecordBrowser *record_browser;
     AvahiSDNSServerBrowserCallback callback;
@@ -245,35 +244,41 @@ AvahiSDNSServerBrowser *avahi_s_dns_server_browser_new(
     AvahiLookupFlags flags,
     AvahiSDNSServerBrowserCallback callback,
     void* userdata) {
+
+    static const char * const type_table[AVAHI_DNS_SERVER_MAX] = {
+        "_domain._udp",
+        "_dns-update._udp"
+    };
     
     AvahiSDNSServerBrowser *b;
-    AvahiKey *k;
-    char *n = NULL;
+    AvahiKey *k = NULL;
+    char n[AVAHI_DOMAIN_NAME_MAX];
+    int r;
     
     assert(server);
     assert(callback);
-    assert(type == AVAHI_DNS_SERVER_RESOLVE || type == AVAHI_DNS_SERVER_UPDATE);
 
-    if (domain && !avahi_is_valid_domain_name(domain)) {
-        avahi_server_set_errno(server, AVAHI_ERR_INVALID_DOMAIN_NAME);
-        return NULL;
-    }
+    AVAHI_CHECK_VALIDITY_RETURN_NULL(server, AVAHI_IF_VALID(interface), AVAHI_ERR_INVALID_INTERFACE);
+    AVAHI_CHECK_VALIDITY_RETURN_NULL(server, AVAHI_PROTO_VALID(protocol), AVAHI_ERR_INVALID_PROTOCOL);
+    AVAHI_CHECK_VALIDITY_RETURN_NULL(server, AVAHI_PROTO_VALID(aprotocol), AVAHI_ERR_INVALID_PROTOCOL);
+    AVAHI_CHECK_VALIDITY_RETURN_NULL(server, !domain || avahi_is_valid_domain_name(domain), AVAHI_ERR_INVALID_DOMAIN_NAME);
+    AVAHI_CHECK_VALIDITY_RETURN_NULL(server, AVAHI_FLAGS_VALID(flags, AVAHI_LOOKUP_USE_WIDE_AREA|AVAHI_LOOKUP_USE_MULTICAST), AVAHI_ERR_INVALID_FLAGS);
+    AVAHI_CHECK_VALIDITY_RETURN_NULL(server, type < AVAHI_DNS_SERVER_MAX, AVAHI_ERR_INVALID_FLAGS);
 
     if (!domain)
         domain = server->domain_name;
 
-    if (!AVAHI_FLAGS_VALID(flags, AVAHI_LOOKUP_USE_WIDE_AREA|AVAHI_LOOKUP_USE_MULTICAST)) {
-        avahi_server_set_errno(server, AVAHI_ERR_INVALID_FLAGS);
+    if ((r = avahi_service_name_join(n, sizeof(n), NULL, type_table[type], domain)) < 0) {
+        avahi_server_set_errno(server, r);
         return NULL;
     }
-
+    
     if (!(b = avahi_new(AvahiSDNSServerBrowser, 1))) {
         avahi_server_set_errno(server, AVAHI_ERR_NO_MEMORY);
         return NULL;
     }
     
     b->server = server;
-    b->domain_name = avahi_normalize_name(domain);
     b->callback = callback;
     b->userdata = userdata;
     b->aprotocol = aprotocol;
@@ -283,19 +288,25 @@ AvahiSDNSServerBrowser *avahi_s_dns_server_browser_new(
     AVAHI_LLIST_HEAD_INIT(AvahiDNSServerInfo, b->info);
     AVAHI_LLIST_PREPEND(AvahiSDNSServerBrowser, browser, server->dns_server_browsers, b);
     
-    n = avahi_strdup_printf("%s.%s",type == AVAHI_DNS_SERVER_RESOLVE ? "_domain._udp" : "_dns-update._udp", b->domain_name);
-    k = avahi_key_new(n, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_SRV);
-    avahi_free(n);
+    if (!(k = avahi_key_new(n, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_SRV))) {
+        avahi_server_set_errno(server, AVAHI_ERR_NO_MEMORY);
+        goto fail;
+    }
     
-    b->record_browser = avahi_s_record_browser_new(server, interface, protocol, k, flags, record_browser_callback, b);
+    if (!(b->record_browser = avahi_s_record_browser_new(server, interface, protocol, k, flags, record_browser_callback, b)))
+        goto fail;
+        
     avahi_key_unref(k);
 
-    if (!b->record_browser) {
-        avahi_s_dns_server_browser_free(b);
-        return NULL;
-    }
-    
     return b;
+
+fail:
+
+    if (k)
+        avahi_key_unref(k);
+    
+    avahi_s_dns_server_browser_free(b);
+    return NULL;
 }
 
 void avahi_s_dns_server_browser_free(AvahiSDNSServerBrowser *b) {
@@ -308,7 +319,7 @@ void avahi_s_dns_server_browser_free(AvahiSDNSServerBrowser *b) {
 
     if (b->record_browser)
         avahi_s_record_browser_free(b->record_browser);
-    avahi_free(b->domain_name);
+
     avahi_free(b);
 }
 
index 2cb2f751910c88e4b63e9c697cbd1c10bbcc46e8..e2eab44bafc79ad9fcf032c10ecf86b3660d2aca 100644 (file)
 
 struct AvahiSDomainBrowser {
     AvahiServer *server;
-    char *domain_name;
     
     AvahiSRecordBrowser *record_browser;
-    AvahiLookupResultFlags flags;
     
     AvahiSDomainBrowserCallback callback;
     void* userdata;
@@ -59,13 +57,13 @@ static void record_browser_callback(
     
     if (record) {
         assert(record->key->type == AVAHI_DNS_TYPE_PTR);
-        n = avahi_normalize_name(record->data.ptr.name);
+        n = record->data.ptr.name;
     }
         
     b->callback(b, interface, protocol, event, n, flags, b->userdata);
-    avahi_free(n);
 }
 
+
 AvahiSDomainBrowser *avahi_s_domain_browser_new(
     AvahiServer *server,
     AvahiIfIndex interface,
@@ -75,34 +73,34 @@ AvahiSDomainBrowser *avahi_s_domain_browser_new(
     AvahiLookupFlags flags,
     AvahiSDomainBrowserCallback callback,
     void* userdata) {
+
+    static const char * const type_table[AVAHI_DOMAIN_BROWSER_MAX] = {
+        "r",
+        "dr",
+        "b",
+        "db",
+        "lb"
+    };
     
     AvahiSDomainBrowser *b;
-    AvahiKey *k;
-    char *n = NULL;
+    AvahiKey *k = NULL;
+    char n[AVAHI_DOMAIN_NAME_MAX];
+    int r;
     
     assert(server);
     assert(callback);
 
-    if (type >= AVAHI_DOMAIN_BROWSER_MAX) {
-        avahi_server_set_errno(server, AVAHI_ERR_INVALID_FLAGS);
-        return NULL;
-    }
-
-    if (!AVAHI_IF_VALID(interface)) {
-        avahi_server_set_errno(server, AVAHI_ERR_INVALID_INTERFACE);
-        return NULL;
-    }
-    
-    if (domain && !avahi_is_valid_domain_name(domain)) {
-        avahi_server_set_errno(server, AVAHI_ERR_INVALID_DOMAIN_NAME);
-        return NULL;
-    }
+    AVAHI_CHECK_VALIDITY_RETURN_NULL(server, AVAHI_IF_VALID(interface), AVAHI_ERR_INVALID_INTERFACE);
+    AVAHI_CHECK_VALIDITY_RETURN_NULL(server, AVAHI_PROTO_VALID(protocol), AVAHI_ERR_INVALID_PROTOCOL);
+    AVAHI_CHECK_VALIDITY_RETURN_NULL(server, type < AVAHI_DOMAIN_BROWSER_MAX, AVAHI_ERR_INVALID_FLAGS);
+    AVAHI_CHECK_VALIDITY_RETURN_NULL(server, !domain || avahi_is_valid_domain_name(domain), AVAHI_ERR_INVALID_DOMAIN_NAME);
+    AVAHI_CHECK_VALIDITY_RETURN_NULL(server, AVAHI_FLAGS_VALID(flags, AVAHI_LOOKUP_USE_WIDE_AREA|AVAHI_LOOKUP_USE_MULTICAST), AVAHI_ERR_INVALID_FLAGS);
 
     if (!domain)
         domain = server->domain_name;
-    
-    if (!AVAHI_FLAGS_VALID(flags, AVAHI_LOOKUP_USE_WIDE_AREA|AVAHI_LOOKUP_USE_MULTICAST)) {
-        avahi_server_set_errno(server, AVAHI_ERR_INVALID_FLAGS);
+
+    if ((r = avahi_service_name_join(n, sizeof(n), type_table[type], "_dns-sd._udp", domain)) < 0) {
+        avahi_server_set_errno(server, r);
         return NULL;
     }
     
@@ -112,48 +110,31 @@ AvahiSDomainBrowser *avahi_s_domain_browser_new(
     }
     
     b->server = server;
-    b->domain_name = avahi_normalize_name(domain);
     b->callback = callback;
     b->userdata = userdata;
+    b->record_browser = NULL;
 
     AVAHI_LLIST_PREPEND(AvahiSDomainBrowser, browser, server->domain_browsers, b);
 
-    switch (type) {
-        case AVAHI_DOMAIN_BROWSER_BROWSE:
-            n = avahi_strdup_printf("b._dns-sd._udp.%s", b->domain_name);
-            break;
-        case AVAHI_DOMAIN_BROWSER_BROWSE_DEFAULT:
-            n = avahi_strdup_printf("db._dns-sd._udp.%s", b->domain_name);
-            break;
-        case AVAHI_DOMAIN_BROWSER_REGISTER:
-            n = avahi_strdup_printf("r._dns-sd._udp.%s", b->domain_name);
-            break;
-        case AVAHI_DOMAIN_BROWSER_REGISTER_DEFAULT:
-            n = avahi_strdup_printf("dr._dns-sd._udp.%s", b->domain_name);
-            break;
-        case AVAHI_DOMAIN_BROWSER_BROWSE_LEGACY:
-            n = avahi_strdup_printf("lb._dns-sd._udp.%s", b->domain_name);
-            break;
-
-        case AVAHI_DOMAIN_BROWSER_MAX:
-            assert(0);
-            break;
+    if (!(k = avahi_key_new(n, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_PTR))) {
+        avahi_server_set_errno(server, AVAHI_ERR_NO_MEMORY);
+        goto fail;
     }
-
-    assert(n);
-
-    k = avahi_key_new(n, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_PTR);
-    avahi_free(n);
     
-    b->record_browser = avahi_s_record_browser_new(server, interface, protocol, k, flags, record_browser_callback, b);
-    avahi_key_unref(k);
-
-    if (!b->record_browser) {
-        avahi_s_domain_browser_free(b);
-        return NULL;
-    }
+    if (!(b->record_browser = avahi_s_record_browser_new(server, interface, protocol, k, flags, record_browser_callback, b)))
+        goto fail;
     
+    avahi_key_unref(k);
     return b;
+    
+fail:
+    
+    if (k)
+        avahi_key_unref(k);
+    
+    avahi_s_domain_browser_free(b);
+    
+    return NULL;
 }
 
 void avahi_s_domain_browser_free(AvahiSDomainBrowser *b) {
@@ -164,6 +145,5 @@ void avahi_s_domain_browser_free(AvahiSDomainBrowser *b) {
     if (b->record_browser)
         avahi_s_record_browser_free(b->record_browser);
     
-    avahi_free(b->domain_name);
     avahi_free(b);
 }
index 25673faec99af4a44f5aa510bbe1865fd8647b3f..39bf4712cdfa090466d9f22b4e802d853cdbc043 100644 (file)
@@ -35,7 +35,7 @@
 struct AvahiSServiceTypeBrowser {
     AvahiServer *server;
     char *domain_name;
-    
+
     AvahiSRecordBrowser *record_browser;
 
     AvahiSServiceTypeBrowserCallback callback;
@@ -54,46 +54,23 @@ static void record_browser_callback(
     void* userdata) {
     
     AvahiSServiceTypeBrowser *b = userdata;
-    char *n = NULL, *c = NULL;
 
     assert(rr);
     assert(b);
 
     if (record) {
-        char *e;
+        char type[AVAHI_DOMAIN_NAME_MAX], domain[AVAHI_DOMAIN_NAME_MAX];
         
         assert(record->key->type == AVAHI_DNS_TYPE_PTR);
-        
-        n = avahi_normalize_name(record->data.ptr.name);
-        
-        if (*n != '_')
-            goto fail;
-        
-        for (c = e = n; *c == '_';) {
-            c += strcspn(c, ".");
-            
-            if (*c == 0)
-                goto fail;
-            
-            assert(*c == '.');
-            e = c;
-            c++;
+
+        if (avahi_service_name_split(record->data.ptr.name, NULL, 0, type, sizeof(type), domain, sizeof(domain)) < 0) {
+            avahi_log_warn("Invalid service type '%s'", record->key->name);
+            return;
         }
-        
-        *e = 0;
-        
-        if (!avahi_domain_equal(c, b->domain_name))
-            goto fail;
-    }
-    
-    b->callback(b, interface, protocol, event, n, c, flags, b->userdata);
-    avahi_free(n);
-    
-    return;
 
-fail:
-    avahi_log_warn("Invalid service type '%s'", n);
-    avahi_free(n);
+        b->callback(b, interface, protocol, event, type, domain, flags, b->userdata);
+    } else
+        b->callback(b, interface, protocol, event, NULL, b->domain_name, flags, b->userdata);
 }
 
 AvahiSServiceTypeBrowser *avahi_s_service_type_browser_new(
@@ -106,48 +83,62 @@ AvahiSServiceTypeBrowser *avahi_s_service_type_browser_new(
     void* userdata) {
     
     AvahiSServiceTypeBrowser *b;
-    AvahiKey *k;
-    char *n = NULL;
+    AvahiKey *k = NULL;
+    char n[AVAHI_DOMAIN_NAME_MAX];
+    int r;
     
     assert(server);
     assert(callback);
 
-    if (domain && !avahi_is_valid_domain_name(domain)) {
-        avahi_server_set_errno(server, AVAHI_ERR_INVALID_DOMAIN_NAME);
-        return NULL;
-    }
+    AVAHI_CHECK_VALIDITY_RETURN_NULL(server, AVAHI_IF_VALID(interface), AVAHI_ERR_INVALID_INTERFACE);
+    AVAHI_CHECK_VALIDITY_RETURN_NULL(server, AVAHI_PROTO_VALID(protocol), AVAHI_ERR_INVALID_PROTOCOL);
+    AVAHI_CHECK_VALIDITY_RETURN_NULL(server, !domain || avahi_is_valid_domain_name(domain), AVAHI_ERR_INVALID_DOMAIN_NAME);
+    AVAHI_CHECK_VALIDITY_RETURN_NULL(server, AVAHI_FLAGS_VALID(flags, AVAHI_LOOKUP_USE_WIDE_AREA|AVAHI_LOOKUP_USE_MULTICAST), AVAHI_ERR_INVALID_FLAGS);
 
     if (!domain)
         domain = server->domain_name;
 
-    if (!AVAHI_FLAGS_VALID(flags, AVAHI_LOOKUP_USE_WIDE_AREA|AVAHI_LOOKUP_USE_MULTICAST)) {
-        avahi_server_set_errno(server, AVAHI_ERR_INVALID_FLAGS);
+    if ((r = avahi_service_name_join(n, sizeof(n), NULL, "_services._dns-sd._udp", domain)) < 0) {
+        avahi_server_set_errno(server, r);
         return NULL;
     }
-
+    
     if (!(b = avahi_new(AvahiSServiceTypeBrowser, 1))) {
         avahi_server_set_errno(server, AVAHI_ERR_NO_MEMORY);
         return NULL;
     }
     
     b->server = server;
-    b->domain_name = avahi_normalize_name(domain);
     b->callback = callback;
     b->userdata = userdata;
-
+    b->record_browser = NULL;
+    
     AVAHI_LLIST_PREPEND(AvahiSServiceTypeBrowser, browser, server->service_type_browsers, b);
 
-    n = avahi_strdup_printf("_services._dns-sd._udp.%s", b->domain_name);
-    k = avahi_key_new(n, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_PTR);
-    avahi_free(n);
+    if (!(b->domain_name = avahi_normalize_name_strdup(domain))) {
+        avahi_server_set_errno(server, AVAHI_ERR_NO_MEMORY);
+        goto fail;
+    }
     
-    b->record_browser = avahi_s_record_browser_new(server, interface, protocol, k, flags, record_browser_callback, b);
+    if (!(k = avahi_key_new(n, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_PTR))) {
+        avahi_server_set_errno(server, AVAHI_ERR_NO_MEMORY);
+        goto fail;
+    }
+    
+    if (!(b->record_browser = avahi_s_record_browser_new(server, interface, protocol, k, flags, record_browser_callback, b)))
+        goto fail;
+        
     avahi_key_unref(k);
 
-    if (!b->record_browser)
-        return NULL;
-    
     return b;
+
+fail:
+    if (k)
+        avahi_key_unref(k);
+
+    avahi_s_service_type_browser_free(b);
+    
+    return NULL;
 }
 
 void avahi_s_service_type_browser_free(AvahiSServiceTypeBrowser *b) {
@@ -157,7 +148,7 @@ void avahi_s_service_type_browser_free(AvahiSServiceTypeBrowser *b) {
 
     if (b->record_browser)
         avahi_s_record_browser_free(b->record_browser);
-    
+
     avahi_free(b->domain_name);
     avahi_free(b);
 }
index dfa6050c9bf2f42b3cc05cb6d4c305f5d7a80fdf..d89ad7a71a6405060a4f0b0a0568ce9a719e2837 100644 (file)
@@ -55,46 +55,25 @@ static void record_browser_callback(
     void* userdata) {
     
     AvahiSServiceBrowser *b = userdata;
-    char *n = NULL, *c = NULL, *s = NULL;
-    char service[128];
 
     assert(rr);
     assert(b);
 
     if (record) {
-        char *e;
+        char service[AVAHI_LABEL_MAX], type[AVAHI_DOMAIN_NAME_MAX], domain[AVAHI_DOMAIN_NAME_MAX];
+
         assert(record->key->type == AVAHI_DNS_TYPE_PTR);
-        
-        c = n = avahi_normalize_name(record->data.ptr.name);
-        
-        if (!(avahi_unescape_label((const char**) &c, service, sizeof(service))))
-            goto fail;
-        
-        for (s = e = c; *c == '_';) {
-            c += strcspn(c, ".");
-            
-            if (*c == 0)
-                goto fail;
-            
-            assert(*c == '.');
-            e = c;
-            c++;
-        }
-        
-        *e = 0;
 
-        if (!avahi_domain_equal(c, b->domain_name))
-            goto fail;
-    }
-    
-    b->callback(b, interface, protocol, event, record ? service : NULL, s, c, flags, b->userdata);
-    avahi_free(n);
+        if (avahi_service_name_split(record->data.ptr.name, service, sizeof(service), type, sizeof(type), domain, sizeof(domain)) < 0) {
+            avahi_log_warn("Failed to split '%s'", record->key->name);
+            return;
+        }
 
-    return;
+        b->callback(b, interface, protocol, event, service, type, domain, flags, b->userdata);
+        
+    } else
+        b->callback(b, interface, protocol, event, NULL, b->service_type, b->domain_name, flags, b->userdata);
 
-fail:
-    avahi_log_warn("Invalid service '%s'", n);
-    avahi_free(n);
 }
 
 AvahiSServiceBrowser *avahi_s_service_browser_new(
@@ -108,28 +87,25 @@ AvahiSServiceBrowser *avahi_s_service_browser_new(
     void* userdata) {
 
     AvahiSServiceBrowser *b;
-    AvahiKey *k;
-    char *n = NULL;
+    AvahiKey *k = NULL;
+    char n[AVAHI_DOMAIN_NAME_MAX];
+    int r;
     
     assert(server);
     assert(callback);
     assert(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_is_valid_domain_name(domain)) {
-        avahi_server_set_errno(server, AVAHI_ERR_INVALID_DOMAIN_NAME);
-        return NULL;
-    }
+    AVAHI_CHECK_VALIDITY_RETURN_NULL(server, AVAHI_IF_VALID(interface), AVAHI_ERR_INVALID_INTERFACE);
+    AVAHI_CHECK_VALIDITY_RETURN_NULL(server, AVAHI_PROTO_VALID(protocol), AVAHI_ERR_INVALID_PROTOCOL);
+    AVAHI_CHECK_VALIDITY_RETURN_NULL(server, !domain || avahi_is_valid_domain_name(domain), AVAHI_ERR_INVALID_DOMAIN_NAME);
+    AVAHI_CHECK_VALIDITY_RETURN_NULL(server, AVAHI_FLAGS_VALID(flags, AVAHI_LOOKUP_USE_WIDE_AREA|AVAHI_LOOKUP_USE_MULTICAST), AVAHI_ERR_INVALID_FLAGS);
+    AVAHI_CHECK_VALIDITY_RETURN_NULL(server, avahi_is_valid_service_type(service_type), AVAHI_ERR_INVALID_SERVICE_TYPE);
 
     if (!domain)
         domain = server->domain_name;
-    
-    if (!AVAHI_FLAGS_VALID(flags, AVAHI_LOOKUP_USE_WIDE_AREA|AVAHI_LOOKUP_USE_MULTICAST)) {
-        avahi_server_set_errno(server, AVAHI_ERR_INVALID_FLAGS);
+
+    if ((r = avahi_service_name_join(n, sizeof(n), NULL, service_type, domain)) < 0) {
+        avahi_server_set_errno(server, r);
         return NULL;
     }
     
@@ -139,26 +115,38 @@ AvahiSServiceBrowser *avahi_s_service_browser_new(
     }
     
     b->server = server;
-    b->domain_name = avahi_normalize_name(domain);
-    b->service_type = avahi_normalize_name(service_type);
+    b->domain_name = b->service_type = NULL;
     b->callback = callback;
     b->userdata = userdata;
+    b->record_browser = NULL;
+    
     AVAHI_LLIST_PREPEND(AvahiSServiceBrowser, browser, server->service_browsers, b);
 
-    n = avahi_strdup_printf("%s.%s", b->service_type, b->domain_name);
-    k = avahi_key_new(n, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_PTR);
-    avahi_free(n);
+    if (!(b->domain_name = avahi_normalize_name_strdup(domain)) ||
+        !(b->service_type = avahi_normalize_name_strdup(service_type))) {
+        avahi_server_set_errno(server, AVAHI_ERR_NO_MEMORY);
+        goto fail;
+    }
+    
+    if (!(k = avahi_key_new(n, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_PTR))) {
+        avahi_server_set_errno(server, AVAHI_ERR_NO_MEMORY);
+        goto fail;
+    }
     
-    b->record_browser = avahi_s_record_browser_new(server, interface, protocol, k, flags, record_browser_callback, b);
+    if (!(b->record_browser = avahi_s_record_browser_new(server, interface, protocol, k, flags, record_browser_callback, b)))
+        goto fail;
 
     avahi_key_unref(k);
 
-    if (!b->record_browser) {
-        avahi_s_service_browser_free(b);
-        return NULL;
-    }
-    
     return b;
+
+fail:
+
+    if (k)
+        avahi_key_unref(k);
+    
+    avahi_s_service_browser_free(b);
+    return NULL;
 }
 
 void avahi_s_service_browser_free(AvahiSServiceBrowser *b) {
index f47418af2d76631c2e2a471f3f474a65aefc5676..5617395cae60037608c3b00d2237f8151640c33c 100644 (file)
@@ -502,13 +502,6 @@ void avahi_s_record_browser_restart(AvahiSRecordBrowser *b) {
     }
 }
 
-#define CHECK_VALIDITY_RETURN_NULL(server, expression, error) { \
-        if (!(expression)) { \
-            avahi_server_set_errno((server), (error)); \
-            return NULL; \
-        } \
-}
-
 AvahiSRecordBrowser *avahi_s_record_browser_new(
     AvahiServer *server,
     AvahiIfIndex interface,
@@ -524,11 +517,12 @@ AvahiSRecordBrowser *avahi_s_record_browser_new(
     assert(key);
     assert(callback);
 
-    CHECK_VALIDITY_RETURN_NULL(server, AVAHI_IF_VALID(interface), AVAHI_ERR_INVALID_INTERFACE);
-    CHECK_VALIDITY_RETURN_NULL(server, !avahi_key_is_pattern(key), AVAHI_ERR_IS_PATTERN);
-    CHECK_VALIDITY_RETURN_NULL(server, avahi_key_is_valid(key), AVAHI_ERR_INVALID_KEY);
-    CHECK_VALIDITY_RETURN_NULL(server, AVAHI_FLAGS_VALID(flags, AVAHI_LOOKUP_USE_WIDE_AREA|AVAHI_LOOKUP_USE_MULTICAST), AVAHI_ERR_INVALID_FLAGS);
-    CHECK_VALIDITY_RETURN_NULL(server, !(flags & AVAHI_LOOKUP_USE_WIDE_AREA) || !(flags & AVAHI_LOOKUP_USE_MULTICAST), AVAHI_ERR_INVALID_FLAGS); 
+    AVAHI_CHECK_VALIDITY_RETURN_NULL(server, AVAHI_IF_VALID(interface), AVAHI_ERR_INVALID_INTERFACE);
+    AVAHI_CHECK_VALIDITY_RETURN_NULL(server, AVAHI_PROTO_VALID(protocol), AVAHI_ERR_INVALID_PROTOCOL);
+    AVAHI_CHECK_VALIDITY_RETURN_NULL(server, !avahi_key_is_pattern(key), AVAHI_ERR_IS_PATTERN);
+    AVAHI_CHECK_VALIDITY_RETURN_NULL(server, avahi_key_is_valid(key), AVAHI_ERR_INVALID_KEY);
+    AVAHI_CHECK_VALIDITY_RETURN_NULL(server, AVAHI_FLAGS_VALID(flags, AVAHI_LOOKUP_USE_WIDE_AREA|AVAHI_LOOKUP_USE_MULTICAST), AVAHI_ERR_INVALID_FLAGS);
+    AVAHI_CHECK_VALIDITY_RETURN_NULL(server, !(flags & AVAHI_LOOKUP_USE_WIDE_AREA) || !(flags & AVAHI_LOOKUP_USE_MULTICAST), AVAHI_ERR_INVALID_FLAGS); 
     
     if (!(b = avahi_new(AvahiSRecordBrowser, 1))) {
         avahi_server_set_errno(server, AVAHI_ERR_NO_MEMORY);
@@ -543,7 +537,6 @@ AvahiSRecordBrowser *avahi_s_record_browser_new(
     b->flags = flags;
     b->callback = callback;
     b->userdata = userdata;
-
     b->n_lookups = 0;
     AVAHI_LLIST_HEAD_INIT(AvahiSRBLookup, b->lookups);
     b->root_lookup = NULL;
index 941247031ad9b529a44b6312b6309e5fd72c91bf..71ec0ce473d3aab05c18ee8f0efab6fa299232ea 100644 (file)
@@ -165,7 +165,6 @@ uint8_t* avahi_dns_packet_append_name(AvahiDnsPacket *p, const char *name) {
         const char *pname;
         char label[64], *u;
         
-
         /* Check whether we can compress this name. */
 
         if (p->name_table && (prev = avahi_hashmap_lookup(p->name_table, name))) {
@@ -366,7 +365,7 @@ static int consume_labels(AvahiDnsPacket *p, unsigned idx, char *ret_name, size_
             } else
                 first_label = 0;
 
-            if (!(avahi_escape_label(AVAHI_DNS_PACKET_DATA(p) + idx, n, &ret_name, &l)))
+            if (!(avahi_escape_label((char*) AVAHI_DNS_PACKET_DATA(p) + idx, n, &ret_name, &l)))
                 return -1;
 
             idx += n;
@@ -519,6 +518,7 @@ AvahiRecord* avahi_dns_packet_consume_record(AvahiDnsPacket *p, int *ret_cache_f
     switch (type) {
         case AVAHI_DNS_TYPE_PTR:
         case AVAHI_DNS_TYPE_CNAME:
+        case AVAHI_DNS_TYPE_NS:
 
 /*             avahi_log_debug("ptr"); */
             
@@ -678,8 +678,9 @@ uint8_t* avahi_dns_packet_append_record(AvahiDnsPacket *p, AvahiRecord *r, int c
     switch (r->key->type) {
         
         case AVAHI_DNS_TYPE_PTR:
-        case AVAHI_DNS_TYPE_CNAME :
-
+        case AVAHI_DNS_TYPE_CNAME:
+        case AVAHI_DNS_TYPE_NS:
+            
             if (!(avahi_dns_packet_append_name(p, r->data.ptr.name)))
                 goto fail;
             
index c75c0678628be1cdbdbfc1ebe2a964e8e62aa310..4143bb35e4689fce7d1bca91f4a1e3abbe7b599e 100644 (file)
@@ -211,7 +211,8 @@ int avahi_server_add_service_strlst(
 /** The type of DNS server */
 typedef enum {
     AVAHI_DNS_SERVER_RESOLVE,         /**< Unicast DNS servers for normal resolves (_domain._udp)*/
-    AVAHI_DNS_SERVER_UPDATE           /**< Unicast DNS servers for updates (_dns-update._udp)*/
+    AVAHI_DNS_SERVER_UPDATE,           /**< Unicast DNS servers for updates (_dns-update._udp)*/
+    AVAHI_DNS_SERVER_MAX
 } AvahiDNSServerType;
 
 /** Publish the specified unicast DNS server address via mDNS. You may
index 940febf403feeb23034ad5df016da4ddc326f244..6315dbb7b38b4cf7c61b5bdf6ef270b1694b9711 100644 (file)
@@ -245,7 +245,7 @@ AvahiSHostNameResolver *avahi_s_host_name_resolver_new(
     }
     
     r->server = server;
-    r->host_name = avahi_normalize_name(host_name);
+    r->host_name = avahi_normalize_name_strdup(host_name);
     r->callback = callback;
     r->userdata = userdata;
     r->address_record = NULL;
index de347e278d56bb58a3acc0c32a3970295919ff8d..43b61d26f9fdefc8517a4020cca78c4d47641f69 100644 (file)
@@ -397,40 +397,26 @@ AvahiSServiceResolver *avahi_s_service_resolver_new(
     
     AvahiSServiceResolver *r;
     AvahiKey *k;
-    char t[256];
+    char n[AVAHI_DOMAIN_NAME_MAX];
     int ret;
     
     assert(server);
     assert(type);
     assert(callback);
 
-    assert(aprotocol == AVAHI_PROTO_UNSPEC || aprotocol == AVAHI_PROTO_INET || aprotocol == AVAHI_PROTO_INET6);
-
-    if (!AVAHI_IF_VALID(interface)) {
-        avahi_server_set_errno(server, AVAHI_ERR_INVALID_INTERFACE);
-        return NULL;
-    }
-
-    if (name && !avahi_is_valid_service_name(name)) {
-        avahi_server_set_errno(server, AVAHI_ERR_INVALID_SERVICE_NAME);
-        return NULL;
-    }
-
-    if (!avahi_is_valid_service_type(type)) {
-        avahi_server_set_errno(server, AVAHI_ERR_INVALID_SERVICE_TYPE);
-        return NULL;
-    }
-
-    if (domain && !avahi_is_valid_domain_name(domain)) {
-        avahi_server_set_errno(server, AVAHI_ERR_INVALID_DOMAIN_NAME);
-        return NULL;
-    }
+    AVAHI_CHECK_VALIDITY_RETURN_NULL(server, AVAHI_IF_VALID(interface), AVAHI_ERR_INVALID_INTERFACE);
+    AVAHI_CHECK_VALIDITY_RETURN_NULL(server, AVAHI_PROTO_VALID(protocol), AVAHI_ERR_INVALID_PROTOCOL);
+    AVAHI_CHECK_VALIDITY_RETURN_NULL(server, AVAHI_PROTO_VALID(aprotocol), AVAHI_ERR_INVALID_PROTOCOL);
+    AVAHI_CHECK_VALIDITY_RETURN_NULL(server, !domain || avahi_is_valid_domain_name(domain), AVAHI_ERR_INVALID_DOMAIN_NAME);
+    AVAHI_CHECK_VALIDITY_RETURN_NULL(server, !name || avahi_is_valid_service_name(name), AVAHI_ERR_INVALID_SERVICE_NAME);
+    AVAHI_CHECK_VALIDITY_RETURN_NULL(server, avahi_is_valid_service_type(type), AVAHI_ERR_INVALID_SERVICE_TYPE);
+    AVAHI_CHECK_VALIDITY_RETURN_NULL(server, AVAHI_FLAGS_VALID(flags, AVAHI_LOOKUP_USE_WIDE_AREA|AVAHI_LOOKUP_USE_MULTICAST|AVAHI_LOOKUP_NO_TXT|AVAHI_LOOKUP_NO_ADDRESS), AVAHI_ERR_INVALID_FLAGS);
 
     if (!domain)
         domain = server->domain_name;
-    
-    if (!AVAHI_FLAGS_VALID(flags, AVAHI_LOOKUP_USE_WIDE_AREA|AVAHI_LOOKUP_USE_MULTICAST|AVAHI_LOOKUP_NO_TXT|AVAHI_LOOKUP_NO_ADDRESS)) {
-        avahi_server_set_errno(server, AVAHI_ERR_INVALID_FLAGS);
+
+    if ((ret = avahi_service_name_join(n, sizeof(n), name, type, domain)) < 0) {
+        avahi_server_set_errno(server, ret);
         return NULL;
     }
     
@@ -441,8 +427,8 @@ AvahiSServiceResolver *avahi_s_service_resolver_new(
     
     r->server = server;
     r->service_name = avahi_strdup(name);
-    r->service_type = avahi_normalize_name(type);
-    r->domain_name = avahi_normalize_name(domain);
+    r->service_type = avahi_normalize_name_strdup(type);
+    r->domain_name = avahi_normalize_name_strdup(domain);
     r->callback = callback;
     r->userdata = userdata;
     r->address_protocol = aprotocol;
@@ -455,13 +441,7 @@ AvahiSServiceResolver *avahi_s_service_resolver_new(
     r->time_event = NULL;
     AVAHI_LLIST_PREPEND(AvahiSServiceResolver, resolver, server->service_resolvers, r);
 
-    if ((ret = avahi_service_name_snprint(t, sizeof(t), name, r->service_type, r->domain_name)) < 0) {
-        avahi_server_set_errno(server, ret);
-        avahi_s_service_resolver_free(r);
-        return NULL;
-    }
-    
-    k = avahi_key_new(t, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_SRV);
+    k = avahi_key_new(n, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_SRV);
     r->record_browser_srv = avahi_s_record_browser_new(server, interface, protocol, k, flags & ~(AVAHI_LOOKUP_NO_TXT|AVAHI_LOOKUP_NO_ADDRESS), record_browser_callback, r);
     avahi_key_unref(k);
 
@@ -471,7 +451,7 @@ AvahiSServiceResolver *avahi_s_service_resolver_new(
     }
 
     if (!(flags & AVAHI_LOOKUP_NO_TXT)) {
-        k = avahi_key_new(t, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_TXT);
+        k = avahi_key_new(n, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_TXT);
         r->record_browser_txt = avahi_s_record_browser_new(server, interface, protocol, k, flags & ~(AVAHI_LOOKUP_NO_TXT|AVAHI_LOOKUP_NO_ADDRESS),  record_browser_callback, r);
         avahi_key_unref(k);
         
index 90c62360605ef47e737871a2b0cd7040c6d809f5..c1faa501f9be9a485e73213596f4888598eae243 100644 (file)
@@ -47,7 +47,7 @@ AvahiKey *avahi_key_new(const char *name, uint16_t class, uint16_t type) {
         return NULL;
     }
     
-    if (!(k->name = avahi_normalize_name(name))) {
+    if (!(k->name = avahi_normalize_name_strdup(name))) {
         avahi_log_error("avahi_normalize_name() failed.");
         avahi_free(k);
         return NULL;
@@ -155,6 +155,7 @@ void avahi_record_unref(AvahiRecord *r) {
 
             case AVAHI_DNS_TYPE_PTR:
             case AVAHI_DNS_TYPE_CNAME:
+            case AVAHI_DNS_TYPE_NS:
                 avahi_free(r->data.ptr.name);
                 break;
 
@@ -212,6 +213,10 @@ const char *avahi_dns_type_to_string(uint16_t type) {
             return "SRV";
         case AVAHI_DNS_TYPE_ANY:
             return "ANY";
+        case AVAHI_DNS_TYPE_SOA:
+            return "SOA";
+        case AVAHI_DNS_TYPE_NS:
+            return "NS";
         default:
             return NULL;
     }
@@ -244,7 +249,8 @@ char *avahi_record_to_string(const AvahiRecord *r) {
             break;
             
         case AVAHI_DNS_TYPE_PTR:
-        case AVAHI_DNS_TYPE_CNAME :
+        case AVAHI_DNS_TYPE_CNAME:
+        case AVAHI_DNS_TYPE_NS:
 
             t = r->data.ptr.name;
             break;
@@ -348,6 +354,7 @@ static int rdata_equal(const AvahiRecord *a, const AvahiRecord *b) {
 
         case AVAHI_DNS_TYPE_PTR:
         case AVAHI_DNS_TYPE_CNAME:
+        case AVAHI_DNS_TYPE_NS:
             return avahi_domain_equal(a->data.ptr.name, b->data.ptr.name);
 
         case AVAHI_DNS_TYPE_HINFO:
@@ -399,6 +406,7 @@ AvahiRecord *avahi_record_copy(AvahiRecord *r) {
     switch (r->key->type) {
         case AVAHI_DNS_TYPE_PTR:
         case AVAHI_DNS_TYPE_CNAME:
+        case AVAHI_DNS_TYPE_NS:
             if (!(copy->data.ptr.name = avahi_strdup(r->data.ptr.name)))
                 goto fail;
             break;
@@ -468,6 +476,7 @@ size_t avahi_record_get_estimate_size(AvahiRecord *r) {
     switch (r->key->type) {
         case AVAHI_DNS_TYPE_PTR:
         case AVAHI_DNS_TYPE_CNAME:
+        case AVAHI_DNS_TYPE_NS:
             n += strlen(r->data.ptr.name) + 1;
             break;
 
@@ -543,6 +552,7 @@ int avahi_record_lexicographical_compare(AvahiRecord *a, AvahiRecord *b) {
 
         case AVAHI_DNS_TYPE_PTR:
         case AVAHI_DNS_TYPE_CNAME:
+        case AVAHI_DNS_TYPE_NS:
             return avahi_binary_domain_cmp(a->data.ptr.name, b->data.ptr.name);
 
         case AVAHI_DNS_TYPE_SRV: {
@@ -640,6 +650,7 @@ int avahi_record_is_valid(AvahiRecord *r) {
 
         case AVAHI_DNS_TYPE_PTR:
         case AVAHI_DNS_TYPE_CNAME:
+        case AVAHI_DNS_TYPE_NS:
             return avahi_is_valid_domain_name(r->data.ptr.name);
 
         case AVAHI_DNS_TYPE_SRV:
index 18bead92b274c6fd40f66044f9b502879df3b6cb..8082ea354d1c469b31e54563375797fd69334e0d 100644 (file)
@@ -1285,7 +1285,7 @@ int avahi_server_set_host_name(AvahiServer *s, const char *host_name) {
     withdraw_host_rrs(s);
 
     avahi_free(s->host_name);
-    s->host_name = host_name ? avahi_normalize_name(host_name) : avahi_get_host_name();
+    s->host_name = host_name ? avahi_normalize_name_strdup(host_name) : avahi_get_host_name_strdup();
     s->host_name[strcspn(s->host_name, ".")] = 0;
     update_fqdn(s);
 
@@ -1303,7 +1303,7 @@ int avahi_server_set_domain_name(AvahiServer *s, const char *domain_name) {
     withdraw_host_rrs(s);
 
     avahi_free(s->domain_name);
-    s->domain_name = domain_name ? avahi_normalize_name(domain_name) : avahi_strdup("local");
+    s->domain_name = domain_name ? avahi_normalize_name_strdup(domain_name) : avahi_strdup("local");
     update_fqdn(s);
 
     register_stuff(s);
@@ -1431,9 +1431,9 @@ AvahiServer *avahi_server_new(const AvahiPoll *poll_api, const AvahiServerConfig
     } while (s->local_service_cookie == AVAHI_SERVICE_COOKIE_INVALID);
     
     /* Get host name */
-    s->host_name = s->config.host_name ? avahi_normalize_name(s->config.host_name) : avahi_get_host_name();
+    s->host_name = s->config.host_name ? avahi_normalize_name_strdup(s->config.host_name) : avahi_get_host_name_strdup();
     s->host_name[strcspn(s->host_name, ".")] = 0;
-    s->domain_name = s->config.domain_name ? avahi_normalize_name(s->config.domain_name) : avahi_strdup("local");
+    s->domain_name = s->config.domain_name ? avahi_normalize_name_strdup(s->config.domain_name) : avahi_strdup("local");
     s->host_name_fqdn = NULL;
     update_fqdn(s);
 
@@ -1702,7 +1702,7 @@ int avahi_server_add_ptr(
     if (!(r = avahi_record_new_full(name, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_PTR, ttl)))
         return avahi_server_set_errno(s, AVAHI_ERR_NO_MEMORY);
         
-    r->data.ptr.name = avahi_normalize_name(dest);
+    r->data.ptr.name = avahi_normalize_name_strdup(dest);
     ret = avahi_server_add(s, g, interface, protocol, flags, r);
     avahi_record_unref(r);
     return ret;
@@ -1738,7 +1738,7 @@ int avahi_server_add_address(
     if (!name)
         name = s->host_name_fqdn;
     else {
-        if (!(n = avahi_normalize_name(name)))
+        if (!(n = avahi_normalize_name_strdup(name)))
             return avahi_server_set_errno(s, AVAHI_ERR_NO_MEMORY);
 
         name = n;
@@ -1834,8 +1834,10 @@ static int server_add_txt_strlst_nocopy(
     
     assert(s);
 
-    if (!(r = avahi_record_new_full(name ? name : s->host_name_fqdn, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_TXT, ttl)))
+    if (!(r = avahi_record_new_full(name ? name : s->host_name_fqdn, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_TXT, ttl))) {
+        avahi_string_list_free(strlst);
         return avahi_server_set_errno(s, AVAHI_ERR_NO_MEMORY);
+    }
     
     r->data.txt.string_list = strlst;
     ret = avahi_server_add(s, g, interface, protocol, flags, r);
@@ -1925,8 +1927,7 @@ static int server_add_service_strlst_nocopy(
     uint16_t port,
     AvahiStringList *strlst) {
 
-    char ptr_name[256], svc_name[256], enum_ptr[256];
-    char *t = NULL, *d = NULL, *h = NULL;
+    char ptr_name[AVAHI_DOMAIN_NAME_MAX], svc_name[AVAHI_DOMAIN_NAME_MAX], enum_ptr[AVAHI_DOMAIN_NAME_MAX], *h = NULL;
     AvahiRecord *r = NULL;
     int ret = AVAHI_OK;
     
@@ -1965,7 +1966,7 @@ static int server_add_service_strlst_nocopy(
     }
 
     if (host && !avahi_is_valid_domain_name(host)) {
-        return avahi_server_set_errno(s, AVAHI_ERR_INVALID_HOST_NAME);
+        ret = avahi_server_set_errno(s, AVAHI_ERR_INVALID_HOST_NAME);
         goto fail;
     }
 
@@ -1975,18 +1976,15 @@ static int server_add_service_strlst_nocopy(
     if (!host)
         host = s->host_name_fqdn;
 
-    if (!(d = avahi_normalize_name(domain)) ||
-        !(t = avahi_normalize_name(type)) ||
-        !(h = avahi_normalize_name(host))) {
+    if (!(h = avahi_normalize_name_strdup(host))) {
         ret = avahi_server_set_errno(s, AVAHI_ERR_NO_MEMORY);
         goto fail;
     }
 
-    if ((ret = avahi_service_name_snprint(svc_name, sizeof(svc_name), name, t, d)) < 0 ||
-        (ret = avahi_service_name_snprint(ptr_name, sizeof(ptr_name), NULL, t, d)) < 0) {
-        avahi_server_set_errno(s, ret);
+    if ((ret = avahi_service_name_join(svc_name, sizeof(svc_name), name, type, domain)) < 0 ||
+        (ret = avahi_service_name_join(ptr_name, sizeof(ptr_name), NULL, type, domain)) < 0 ||
+        (ret = avahi_service_name_join(enum_ptr, sizeof(enum_ptr), NULL, "_services._dns-sd._udp", domain)) < 0)
         goto fail;
-    }
 
     if ((ret = avahi_server_add_ptr(s, g, interface, protocol, flags & AVAHI_PUBLISH_IS_PROXY, AVAHI_DEFAULT_TTL, ptr_name, svc_name)) < 0)
         goto fail;
@@ -2016,16 +2014,12 @@ static int server_add_service_strlst_nocopy(
     if (ret < 0)
         goto fail;
 
-    snprintf(enum_ptr, sizeof(enum_ptr), "_services._dns-sd._udp.%s", d);
     ret = avahi_server_add_ptr(s, g, interface, protocol, (flags & AVAHI_PUBLISH_IS_PROXY), AVAHI_DEFAULT_TTL, enum_ptr, ptr_name);
 
 fail:
     
-    avahi_free(d);
-    avahi_free(t);
-    avahi_free(h);
-
     avahi_string_list_free(strlst);
+    avahi_free(h);
     
     return ret;
 }
@@ -2061,7 +2055,7 @@ int avahi_server_add_service_va(
     const char *domain,
     const char *host,
     uint16_t port,
-    va_list va){
+    va_list va) {
 
     assert(s);
     assert(type);
@@ -2093,6 +2087,7 @@ int avahi_server_add_service(
     va_start(va, port);
     ret = avahi_server_add_service_va(s, g, interface, protocol, flags, name, type, domain, host, port, va);
     va_end(va);
+    
     return ret;
 }
 
@@ -2217,8 +2212,8 @@ int avahi_server_add_dns_server_name(
     if (!domain)
         domain = s->domain_name;
 
-    if (!(n = avahi_normalize_name(name)) ||
-        !(d = avahi_normalize_name(domain))) {
+    if (!(n = avahi_normalize_name_strdup(name)) ||
+        !(d = avahi_normalize_name_strdup(domain))) {
         avahi_free(n);
         avahi_free(d);
         return avahi_server_set_errno(s, AVAHI_ERR_NO_MEMORY);
@@ -2593,7 +2588,7 @@ int avahi_server_is_service_local(AvahiServer *s, AvahiIfIndex interface, AvahiP
     if (domain && !avahi_is_valid_domain_name(domain))
         return avahi_server_set_errno(s, AVAHI_ERR_INVALID_DOMAIN_NAME);
 
-    if ((ret = avahi_service_name_snprint(n, sizeof(n), name, type, domain) < 0))
+    if ((ret = avahi_service_name_join(n, sizeof(n), name, type, domain) < 0))
         return avahi_server_set_errno(s, ret);
         
     if (!(key = avahi_key_new(n, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_SRV)))
index 1723250ea4f9aa35a5b4f859220f26fcca49f775..300ae8be4b0a901eac3b72ac672d53cd1cf9c8fc 100644 (file)
@@ -175,4 +175,11 @@ void avahi_server_increase_host_rr_pending(AvahiServer *s);
 
 int avahi_server_set_errno(AvahiServer *s, int error);
 
+#define AVAHI_CHECK_VALIDITY_RETURN_NULL(server, expression, error) { \
+        if (!(expression)) { \
+            avahi_server_set_errno((server), (error)); \
+            return NULL; \
+        } \
+}
+
 #endif