#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) {
*d = 0;
+ if (!avahi_utf8_valid(dest))
+ return NULL;
+
return dest;
}
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 (label[0] == 0) {
- if (!empty) {
- if (size < 1)
- return NULL;
+ if (*s == 0 && empty)
+ return ret_s;
- *(r++) = '.';
- size--;
-
- } 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;
}
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(const char *t) {
+int avahi_is_valid_service_type_generic(const char *t) {
assert(t);
if (strlen(t) >= AVAHI_DOMAIN_NAME_MAX || !*t)
return 1;
}
-int avahi_is_valid_domain_name(const char *t) {
+int avahi_is_valid_service_type_strict(const char *t) {
+ char label[AVAHI_LABEL_MAX];
assert(t);
if (strlen(t) >= AVAHI_DOMAIN_NAME_MAX || !*t)
return 0;
+ /* Application name */
+
+ if (!(avahi_unescape_label(&t, label, sizeof(label))))
+ return 0;
+
+ if (strlen(label) <= 2 || label[0] != '_')
+ return 0;
+
+ if (!*t)
+ return 0;
+
+ /* _tcp or _udp boilerplate */
+
+ if (!(avahi_unescape_label(&t, label, sizeof(label))))
+ return 0;
+
+ if (strcasecmp(label, "_tcp") && strcasecmp(label, "_udp"))
+ return 0;
+
+ if (*t)
+ return 0;
+
+ return 1;
+}
+
+const char *avahi_get_type_from_subtype(const char *t) {
+ char label[AVAHI_LABEL_MAX];
+ const char *ret;
+ assert(t);
+
+ if (strlen(t) >= AVAHI_DOMAIN_NAME_MAX || !*t)
+ return NULL;
+
+ /* Subtype name */
+
+ if (!(avahi_unescape_label(&t, label, sizeof(label))))
+ return NULL;
+
+ if (strlen(label) <= 2 || label[0] != '_')
+ return NULL;
+
+ if (!*t)
+ return NULL;
+
+ /* String "_sub" */
+
+ if (!(avahi_unescape_label(&t, label, sizeof(label))))
+ return NULL;
+
+ if (strcasecmp(label, "_sub"))
+ return NULL;
+
+ if (!*t)
+ return NULL;
+
+ ret = t;
+
+ /* Application name */
+
+ if (!(avahi_unescape_label(&t, label, sizeof(label))))
+ return NULL;
+
+ if (strlen(label) <= 2 || label[0] != '_')
+ return NULL;
+
+ if (!*t)
+ return NULL;
+
+ /* _tcp or _udp boilerplate */
+
+ if (!(avahi_unescape_label(&t, label, sizeof(label))))
+ return NULL;
+
+ if (strcasecmp(label, "_tcp") && strcasecmp(label, "_udp"))
+ return NULL;
+
+ if (*t)
+ return NULL;
+
+ return ret;
+}
+
+int avahi_is_valid_service_subtype(const char *t) {
+ assert(t);
+
+ return !!avahi_get_type_from_subtype(t);
+}
+
+int avahi_is_valid_domain_name(const char *t) {
+ int is_first = 1;
+ assert(t);
+
+ if (strlen(t) >= AVAHI_DOMAIN_NAME_MAX)
+ return 0;
+
do {
char label[AVAHI_LABEL_MAX];
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 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];
if ((name && !avahi_is_valid_service_name(name)))
return AVAHI_ERR_INVALID_SERVICE_NAME;
- if (!avahi_is_valid_service_type(type))
+ if (!avahi_is_valid_service_type_generic(type))
return AVAHI_ERR_INVALID_SERVICE_TYPE;
if (!avahi_is_valid_domain_name(domain))
return AVAHI_OK;
}
+#ifndef HAVE_STRLCPY
-char *avahi_strlcpy(char *dest, const char *src, size_t n) {
+static size_t strlcpy(char *dest, const char *src, size_t n) {
assert(dest);
assert(src);
-
- if (n == 0)
- return dest;
-
- strncpy(dest, src, n-1);
- dest[n-1] = 0;
- return dest;
+
+ if (n > 0) {
+ strncpy(dest, src, n-1);
+ dest[n-1] = 0;
+ }
+
+ return strlen(src);
}
+#endif
+
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,
switch (state) {
case NAME:
- avahi_strlcpy(name, buf, name_size);
+ strlcpy(name, buf, name_size);
state = TYPE;
break;
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;
+}