summaryrefslogtreecommitdiffstats
path: root/avahi-common/domain.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2005-08-12 00:25:52 +0000
committerLennart Poettering <lennart@poettering.net>2005-08-12 00:25:52 +0000
commit5ebf655c85076f200955458673a8bbf0dd927407 (patch)
tree148d2a476b375603db4e3401b8d1d1236af0ae2c /avahi-common/domain.c
parente63a65b3955b173a3e8d6b78c6377a518a9922d6 (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.c369
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;
+}
+