]> git.meshlink.io Git - catta/blobdiff - avahi-common/domain.c
forgot to pull the publish_no_reverse change to the example.
[catta] / avahi-common / domain.c
index e82411f185946b6edc9bd2dda27484d180549031..3b1ab683494e9e5caf6094944bd4e2e41ae96bdd 100644 (file)
@@ -1,18 +1,16 @@
-/* $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
 #include "domain.h"
 #include "malloc.h"
 #include "error.h"
-
-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
-    
-    assert(ret_s);
-    assert(size > 0);
-    
-    gethostname(t, sizeof(t));
-    t[sizeof(t)-1] = 0;
-    
-    return avahi_normalize_name(t, ret_s, size);
-}
-
-char *avahi_get_host_name_strdup(void) {
-    char t[AVAHI_DOMAIN_NAME_MAX];
-
-    if (!(avahi_get_host_name(t, sizeof(t))))
-        return NULL;
-
-    return avahi_strdup(t);
-}
+#include "address.h"
+#include "utf8.h"
 
 /* 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;
     char *d;
-    
+
     assert(dest);
     assert(size > 0);
     assert(name);
 
     d = dest;
-    
+
     for (;;) {
         if (i >= size)
             return NULL;
@@ -81,10 +56,10 @@ char *avahi_unescape_label(const char **name, char *dest, size_t size) {
             (*name)++;
             break;
         }
-        
+
         if (**name == 0)
             break;
-        
+
         if (**name == '\\') {
             /* Escaped character */
 
@@ -93,7 +68,7 @@ char *avahi_unescape_label(const char **name, char *dest, size_t size) {
             if (**name == 0)
                 /* Ending NUL */
                 return NULL;
-            
+
             else if (**name == '\\' || **name == '.') {
                 /* Escaped backslash or dot */
                 *(d++) = *((*name) ++);
@@ -102,7 +77,7 @@ char *avahi_unescape_label(const char **name, char *dest, size_t size) {
                 int n;
 
                 /* Escaped literal ASCII character */
-                
+
                 if (!isdigit(*(*name+1)) || !isdigit(*(*name+2)))
                     return NULL;
 
@@ -110,18 +85,18 @@ char *avahi_unescape_label(const char **name, char *dest, size_t size) {
 
                 if (n > 255 || n == 0)
                     return NULL;
-                
+
                 *(d++) = (char) n;
                 i++;
 
                 (*name) += 3;
             } else
                 return NULL;
-            
+
         } else {
 
             /* Normal character */
-            
+
             *(d++) = *((*name) ++);
             i++;
         }
@@ -131,6 +106,9 @@ char *avahi_unescape_label(const char **name, char *dest, size_t size) {
 
     *d = 0;
 
+    if (!avahi_utf8_valid(dest))
+        return NULL;
+
     return dest;
 }
 
@@ -150,14 +128,14 @@ char *avahi_escape_label(const char* src, size_t src_length, char **ret_name, si
         if (*src == '.' || *src == '\\') {
 
             /* Dot or backslash */
-            
+
             if (*ret_size < 3)
                 return NULL;
-            
+
             *((*ret_name) ++) = '\\';
             *((*ret_name) ++) = *src;
             (*ret_size) -= 2;
-            
+
         } else if (
             *src == '_' ||
             *src == '-' ||
@@ -166,13 +144,13 @@ char *avahi_escape_label(const char* src, size_t src_length, char **ret_name, si
             (*src >= 'A' && *src <= 'Z')) {
 
             /* Proper character */
-            
+
             if (*ret_size < 2)
                 return NULL;
-        
+
             *((*ret_name)++) = *src;
             (*ret_size) --;
-            
+
         } else {
 
             /* Everything else */
@@ -184,7 +162,7 @@ char *avahi_escape_label(const char* src, size_t src_length, char **ret_name, si
             *((*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;
         }
 
@@ -200,37 +178,41 @@ char *avahi_escape_label(const char* src, size_t src_length, char **ret_name, si
 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;
+    *ret_s = 0;
+
     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;
+        if (label[0] == 0) {
 
-                *(r++) = '.';
-                size--;
+            if (*s == 0 && empty)
+                return ret_s;
 
-            } else
-                empty = 0;
-            
-            avahi_escape_label(label, strlen(label), &r, &size);
+            return NULL;
         }
+
+        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;
 }
 
@@ -250,7 +232,7 @@ int avahi_domain_equal(const char *a, const char *b) {
 
     if (a == b)
         return 1;
-    
+
     for (;;) {
         char ca[AVAHI_LABEL_MAX], cb[AVAHI_LABEL_MAX], *r;
 
@@ -261,7 +243,7 @@ int avahi_domain_equal(const char *a, const char *b) {
 
         if (strcasecmp(ca, cb))
             return 0;
-        
+
         if (!*a && !*b)
             return 1;
     }
@@ -269,30 +251,6 @@ int avahi_domain_equal(const char *a, const char *b) {
     return 1;
 }
 
-int avahi_binary_domain_cmp(const char *a, const char *b) {
-    assert(a);
-    assert(b);
-
-    if (a == b)
-        return 0;
-
-    for (;;) {
-        char ca[AVAHI_LABEL_MAX], cb[AVAHI_LABEL_MAX], *p;
-        int r;
-
-        p = avahi_unescape_label(&a, ca, sizeof(ca));
-        assert(p);
-        p = avahi_unescape_label(&b, cb, sizeof(cb));
-        assert(p);
-
-        if ((r = strcmp(ca, cb)))
-            return r;
-        
-        if (!*a && !*b)
-            return 0;
-    }
-}
-
 int avahi_is_valid_service_type_generic(const char *t) {
     assert(t);
 
@@ -307,7 +265,7 @@ int avahi_is_valid_service_type_generic(const char *t) {
 
         if (strlen(label) <= 2 || label[0] != '_')
             return 0;
-        
+
     } while (*t);
 
     return 1;
@@ -321,7 +279,7 @@ int avahi_is_valid_service_type_strict(const char *t) {
         return 0;
 
     /* Application name */
-    
+
     if (!(avahi_unescape_label(&t, label, sizeof(label))))
         return 0;
 
@@ -332,7 +290,7 @@ int avahi_is_valid_service_type_strict(const char *t) {
         return 0;
 
     /* _tcp or _udp boilerplate */
-    
+
     if (!(avahi_unescape_label(&t, label, sizeof(label))))
         return 0;
 
@@ -341,7 +299,7 @@ int avahi_is_valid_service_type_strict(const char *t) {
 
     if (*t)
         return 0;
-    
+
     return 1;
 }
 
@@ -354,7 +312,7 @@ const char *avahi_get_type_from_subtype(const char *t) {
         return NULL;
 
     /* Subtype name */
-    
+
     if (!(avahi_unescape_label(&t, label, sizeof(label))))
         return NULL;
 
@@ -365,7 +323,7 @@ const char *avahi_get_type_from_subtype(const char *t) {
         return NULL;
 
     /* String "_sub" */
-    
+
     if (!(avahi_unescape_label(&t, label, sizeof(label))))
         return NULL;
 
@@ -376,7 +334,7 @@ const char *avahi_get_type_from_subtype(const char *t) {
         return NULL;
 
     ret = t;
-    
+
     /* Application name */
 
     if (!(avahi_unescape_label(&t, label, sizeof(label))))
@@ -387,9 +345,9 @@ const char *avahi_get_type_from_subtype(const char *t) {
 
     if (!*t)
         return NULL;
-    
+
     /* _tcp or _udp boilerplate */
-    
+
     if (!(avahi_unescape_label(&t, label, sizeof(label))))
         return NULL;
 
@@ -409,9 +367,10 @@ int avahi_is_valid_service_subtype(const char *t) {
 }
 
 int avahi_is_valid_domain_name(const char *t) {
+    int is_first = 1;
     assert(t);
 
-    if (strlen(t) >= AVAHI_DOMAIN_NAME_MAX || !*t)
+    if (strlen(t) >= AVAHI_DOMAIN_NAME_MAX)
         return 0;
 
     do {
@@ -420,9 +379,15 @@ int avahi_is_valid_domain_name(const char *t) {
         if (!(avahi_unescape_label(&t, label, sizeof(label))))
             return 0;
 
-        if (strlen(label) < 1)
+        /* Explicitly allow the root domain name */
+        if (is_first && label[0] == 0 && *t == 0)
+            return 1;
+
+        is_first = 0;
+
+        if (label[0] == 0)
             return 0;
-        
+
     } while (*t);
 
     return 1;
@@ -433,7 +398,7 @@ int avahi_is_valid_service_name(const char *t) {
 
     if (strlen(t) >= AVAHI_LABEL_MAX || !*t)
         return 0;
-        
+
     return 1;
 }
 
@@ -458,7 +423,7 @@ int avahi_is_valid_host_name(const char *t) {
 
 unsigned avahi_domain_hash(const char *s) {
     unsigned hash = 0;
-    
+
     while (*s) {
         char c[AVAHI_LABEL_MAX], *p, *r;
 
@@ -472,44 +437,26 @@ unsigned avahi_domain_hash(const char *s) {
     return hash;
 }
 
-int avahi_domain_ends_with(const char *domain, const char *suffix) {
-    assert(domain);
-    assert(suffix);
-
-    for (;;) {
-        char dummy[AVAHI_LABEL_MAX], *r;
-
-        if (*domain == 0)
-            return 0;
-        
-        if (avahi_domain_equal(domain, suffix))
-            return 1;
-
-        r = avahi_unescape_label(&domain, dummy, sizeof(dummy));
-        assert(r);
-    } 
-}
-
 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 escaped_name[AVAHI_LABEL_MAX*4];
     char normalized_type[AVAHI_DOMAIN_NAME_MAX];
     char normalized_domain[AVAHI_DOMAIN_NAME_MAX];
-    
+
     assert(p);
 
     /* Validity checks */
-    
+
     if ((name && !avahi_is_valid_service_name(name)))
         return AVAHI_ERR_INVALID_SERVICE_NAME;
 
     if (!avahi_is_valid_service_type_generic(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;
@@ -524,7 +471,7 @@ int avahi_service_name_join(char *p, size_t size, const char *name, const char *
         return AVAHI_ERR_INVALID_DOMAIN_NAME;
 
     /* Concatenation */
-    
+
     snprintf(p, size, "%s%s%s.%s", name ? escaped_name : "", name ? "." : "", normalized_type, normalized_domain);
 
     return AVAHI_OK;
@@ -535,12 +482,12 @@ int avahi_service_name_join(char *p, size_t size, const char *name, const char *
 static size_t strlcpy(char *dest, const char *src, size_t n) {
     assert(dest);
     assert(src);
-    
+
     if (n > 0) {
         strncpy(dest, src, n-1);
         dest[n-1] = 0;
     }
-    
+
     return strlen(src);
 }
 
@@ -553,7 +500,7 @@ int avahi_service_name_split(const char *p, char *name, size_t name_size, char *
         DOMAIN
     } state;
     int type_empty = 1, domain_empty = 1;
-    
+
     assert(p);
     assert(type);
     assert(type_size > 0);
@@ -566,12 +513,12 @@ int avahi_service_name_split(const char *p, char *name, size_t name_size, char *
         state = NAME;
     } else
         state = TYPE;
-    
+
     *type = *domain = 0;
-    
+
     while (*p) {
         char buf[64];
-        
+
         if (!(avahi_unescape_label(&p, buf, sizeof(buf))))
             return -1;
 
@@ -588,18 +535,18 @@ int avahi_service_name_split(const char *p, char *name, size_t name_size, char *
                     if (!type_empty) {
                         if (!type_size)
                             return AVAHI_ERR_NO_MEMORY;
-                        
+
                         *(type++) = '.';
                         type_size --;
 
                     } else
                         type_empty = 0;
-                    
+
                     if (!(avahi_escape_label(buf, strlen(buf), &type, &type_size)))
                         return AVAHI_ERR_NO_MEMORY;
 
                     break;
-                } 
+                }
 
                 state = DOMAIN;
                 /* fall through */
@@ -609,7 +556,7 @@ int avahi_service_name_split(const char *p, char *name, size_t name_size, char *
                 if (!domain_empty) {
                     if (!domain_size)
                         return AVAHI_ERR_NO_MEMORY;
-                    
+
                     *(domain++) = '.';
                     domain_size --;
                 } else
@@ -625,3 +572,38 @@ int avahi_service_name_split(const char *p, char *name, size_t name_size, char *
     return 0;
 }
 
+int avahi_is_valid_fqdn(const char *t) {
+    char label[AVAHI_LABEL_MAX];
+    char normalized[AVAHI_DOMAIN_NAME_MAX];
+    const char *k = t;
+    AvahiAddress a;
+    assert(t);
+
+    if (strlen(t) >= AVAHI_DOMAIN_NAME_MAX)
+        return 0;
+
+    if (!avahi_is_valid_domain_name(t))
+        return 0;
+
+    /* Check if there are at least two labels*/
+    if (!(avahi_unescape_label(&k, label, sizeof(label))))
+        return 0;
+
+    if (label[0] == 0 || !k)
+        return 0;
+
+    if (!(avahi_unescape_label(&k, label, sizeof(label))))
+        return 0;
+
+    if (label[0] == 0 || !k)
+        return 0;
+
+    /* Make sure that the name is not an IP address */
+    if (!(avahi_normalize_name(t, normalized, sizeof(normalized))))
+        return 0;
+
+    if (avahi_address_parse(normalized, AVAHI_PROTO_UNSPEC, &a))
+        return 0;
+
+    return 1;
+}