]> git.meshlink.io Git - catta/blobdiff - avahi-common/domain.c
Merge branch 'release/0.0.1'
[catta] / avahi-common / domain.c
diff --git a/avahi-common/domain.c b/avahi-common/domain.c
deleted file mode 100644 (file)
index 3b1ab68..0000000
+++ /dev/null
@@ -1,609 +0,0 @@
-/***
-  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 <config.h>
-#endif
-
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <limits.h>
-#include <stdio.h>
-#include <ctype.h>
-#include <stdlib.h>
-#include <assert.h>
-
-#include "domain.h"
-#include "malloc.h"
-#include "error.h"
-#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;
-
-        if (**name == '.') {
-            (*name)++;
-            break;
-        }
-
-        if (**name == 0)
-            break;
-
-        if (**name == '\\') {
-            /* Escaped character */
-
-            (*name) ++;
-
-            if (**name == 0)
-                /* 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++;
-        }
-    }
-
-    assert(i < size);
-
-    *d = 0;
-
-    if (!avahi_utf8_valid(dest))
-        return NULL;
-
-    return dest;
-}
-
-/* Escape "\" and ".", append \0 */
-char *avahi_escape_label(const char* src, size_t src_length, char **ret_name, size_t *ret_size) {
-    char *r;
-
-    assert(src);
-    assert(ret_name);
-    assert(*ret_name);
-    assert(ret_size);
-    assert(*ret_size > 0);
-
-    r = *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 {
-
-            /* 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++;
-    }
-
-    **ret_name = 0;
-
-    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;
-    *ret_s = 0;
-
-    while (*s) {
-        char label[AVAHI_LABEL_MAX];
-
-        if (!(avahi_unescape_label(&s, label, sizeof(label))))
-            return NULL;
-
-        if (label[0] == 0) {
-
-            if (*s == 0 && empty)
-                return ret_s;
-
-            return NULL;
-        }
-
-        if (!empty) {
-            if (size < 1)
-                return NULL;
-
-            *(r++) = '.';
-            size--;
-
-        } else
-            empty = 0;
-
-        avahi_escape_label(label, strlen(label), &r, &size);
-    }
-
-    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);
-
-    if (a == b)
-        return 1;
-
-    for (;;) {
-        char ca[AVAHI_LABEL_MAX], cb[AVAHI_LABEL_MAX], *r;
-
-        r = avahi_unescape_label(&a, ca, sizeof(ca));
-        assert(r);
-        r = avahi_unescape_label(&b, cb, sizeof(cb));
-        assert(r);
-
-        if (strcasecmp(ca, cb))
-            return 0;
-
-        if (!*a && !*b)
-            return 1;
-    }
-
-    return 1;
-}
-
-int avahi_is_valid_service_type_generic(const char *t) {
-    assert(t);
-
-    if (strlen(t) >= AVAHI_DOMAIN_NAME_MAX || !*t)
-        return 0;
-
-    do {
-        char label[AVAHI_LABEL_MAX];
-
-        if (!(avahi_unescape_label(&t, label, sizeof(label))))
-            return 0;
-
-        if (strlen(label) <= 2 || label[0] != '_')
-            return 0;
-
-    } while (*t);
-
-    return 1;
-}
-
-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;
-
-        /* 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;
-}
-
-int avahi_is_valid_service_name(const char *t) {
-    assert(t);
-
-    if (strlen(t) >= AVAHI_LABEL_MAX || !*t)
-        return 0;
-
-    return 1;
-}
-
-int avahi_is_valid_host_name(const char *t) {
-    char label[AVAHI_LABEL_MAX];
-    assert(t);
-
-    if (strlen(t) >= AVAHI_DOMAIN_NAME_MAX || !*t)
-        return 0;
-
-    if (!(avahi_unescape_label(&t, label, sizeof(label))))
-        return 0;
-
-    if (strlen(label) < 1)
-        return 0;
-
-    if (*t)
-        return 0;
-
-    return 1;
-}
-
-unsigned avahi_domain_hash(const char *s) {
-    unsigned hash = 0;
-
-    while (*s) {
-        char c[AVAHI_LABEL_MAX], *p, *r;
-
-        r = avahi_unescape_label(&s, c, sizeof(c));
-        assert(r);
-
-        for (p = c; *p; p++)
-            hash = 31 * hash + tolower(*p);
-    }
-
-    return hash;
-}
-
-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*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;
-        r = avahi_escape_label(name, strlen(name), &e, &l);
-        assert(r);
-    }
-
-    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;
-
-    /* Concatenation */
-
-    snprintf(p, size, "%s%s%s.%s", name ? escaped_name : "", name ? "." : "", normalized_type, normalized_domain);
-
-    return AVAHI_OK;
-}
-
-#ifndef HAVE_STRLCPY
-
-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);
-}
-
-#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,
-        TYPE,
-        DOMAIN
-    } state;
-    int type_empty = 1, domain_empty = 1;
-
-    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;
-
-        switch (state) {
-            case NAME:
-                strlcpy(name, buf, name_size);
-                state = TYPE;
-                break;
-
-            case TYPE:
-
-                if (buf[0] == '_') {
-
-                    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 */
-
-            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;
-}
-
-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;
-}