diff options
author | Lennart Poettering <lennart@poettering.net> | 2005-08-12 00:25:52 +0000 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2005-08-12 00:25:52 +0000 |
commit | 5ebf655c85076f200955458673a8bbf0dd927407 (patch) | |
tree | 148d2a476b375603db4e3401b8d1d1236af0ae2c /avahi-common/domain.c | |
parent | e63a65b3955b173a3e8d6b78c6377a518a9922d6 (diff) |
Split avahi-common/util.h into
avahi-common/domain.h
avahi-core/fdutil.h
avahi-core/timeval.h
git-svn-id: file:///home/lennart/svn/public/avahi/trunk@299 941a03a8-eaeb-0310-b9a0-b1bbd8fe43fe
Diffstat (limited to 'avahi-common/domain.c')
-rw-r--r-- | avahi-common/domain.c | 369 |
1 files changed, 369 insertions, 0 deletions
diff --git a/avahi-common/domain.c b/avahi-common/domain.c new file mode 100644 index 0000000..b1e7cfe --- /dev/null +++ b/avahi-common/domain.c @@ -0,0 +1,369 @@ +/* $Id$ */ + +/*** + This file is part of avahi. + + avahi is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + avahi is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General + Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with avahi; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#ifdef HAVE_CONFIG_H +#include <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" + +char *avahi_get_host_name(void) { +#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(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; + + return ret_dest; +} + +char *avahi_normalize_name(const char *s) { + char tmp[256]; + size_t l; + + assert(s); + + unescape_uneeded(s, tmp, sizeof(tmp)); + + l = strlen(tmp); + + while (l > 0 && tmp[l-1] == '.') + tmp[--l] = 0; + + return avahi_strdup(tmp); +} + + +/* 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); + + if (!**name) + return NULL; + + d = dest; + + for (;;) { + if (i >= size) + return NULL; + + if (**name == '.') { + (*name)++; + break; + } + + if (**name == 0) + break; + + if (**name == '\\') { + (*name) ++; + + if (**name == 0) + break; + } + + *(d++) = *((*name) ++); + i++; + } + + assert(i < size); + + *d = 0; + + return dest; +} + +/* Escape "\" and ".", append \0 */ +char *avahi_escape_label(const uint8_t* 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 == '\\') { + if (*ret_size < 3) + return NULL; + + *((*ret_name) ++) = '\\'; + (*ret_size) --; + } + + if (*ret_size < 2) + return NULL; + + *((*ret_name)++) = *src; + (*ret_size) --; + + src_length --; + src++; + } + + **ret_name = 0; + + return r; +} + +int avahi_domain_equal(const char *a, const char *b) { + assert(a); + assert(b); + + if (a == b) + return 1; + + for (;;) { + char ca[65], cb[65], *pa, *pb; + + pa = avahi_unescape_label(&a, ca, sizeof(ca)); + pb = avahi_unescape_label(&b, cb, sizeof(cb)); + + if (!pa && !pb) + return 1; + else if ((pa && !pb) || (!pa && pb)) + return 0; + + if (strcasecmp(pa, pb)) + return 0; + } + + 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[65], cb[65], *pa, *pb; + int r; + + pa = avahi_unescape_label(&a, ca, sizeof(ca)); + pb = avahi_unescape_label(&b, cb, sizeof(cb)); + + if (!pa && !pb) + return 0; + else if (pa && !pb) + return 1; + else if (!pa && pb) + return -1; + + if ((r = strcmp(pa, pb))) + return r; + } +} + +unsigned avahi_strhash(const char *p) { + unsigned hash = 0; + + for (; *p; p++) + hash = 31 * hash + *p; + + return hash; +} + +unsigned avahi_domain_hash(const char *s) { + unsigned hash = 0; + + for (;;) { + char c[65]; + + if (!avahi_unescape_label(&s, c, sizeof(c))) + return hash; + + if (!c[0]) + continue; + + hash += avahi_strhash(avahi_strdown(c)); + } +} + +int avahi_valid_service_type(const char *t) { + const char *p; + assert(t); + + if (strlen(t) < 5) + return 0; + + if (*t != '_') + return 0; + + if (!(p = strchr(t, '.'))) + return 0; + + if (p - t > 63 || p - t < 2) + return 0; + + if (*(++p) != '_') + return 0; + + if (strchr(p, '.')) + return 0; + + if (strlen(p) > 63 || strlen(p) < 2) + return 0; + + return 1; +} + +int avahi_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 == '.') + return 0; + + dp = t; + + 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 (p - dp > 63) + return 0; + + /* A trailing dot IS allowed */ + + return 1; +} + +int avahi_valid_service_name(const char *t) { + assert(t); + + if (*t == 0) + return 0; + + if (strlen(t) > 63) + return 0; + + return 1; +} + +int avahi_valid_host_name(const char *t) { + assert(t); + + if (*t == 0) + return 0; + + if (strlen(t) > 63) + return 0; + + if (strchr(t, '.')) + return 0; + + return 1; +} + +char *avahi_strdown(char *s) { + char *c; + + assert(s); + + for (c = s; *c; c++) + *c = (char) tolower(*c); + + return s; +} + +char *avahi_strup(char *s) { + char *c; + assert(s); + + for (c = s; *c; c++) + *c = (char) toupper(*c); + + return s; +} + |