summaryrefslogtreecommitdiff
path: root/contrib/bind/doc/notes/db_names.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/bind/doc/notes/db_names.c')
-rw-r--r--contrib/bind/doc/notes/db_names.c184
1 files changed, 184 insertions, 0 deletions
diff --git a/contrib/bind/doc/notes/db_names.c b/contrib/bind/doc/notes/db_names.c
new file mode 100644
index 000000000000..0b4e62c78b83
--- /dev/null
+++ b/contrib/bind/doc/notes/db_names.c
@@ -0,0 +1,184 @@
+/*
+ * Copyright (c) 1996,1999 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <resolv.h>
+#include <stdio.h>
+
+#include "named.h"
+#include "tree.h"
+
+struct node {
+ struct node *parent; /* NULL for "."'s node. */
+ tree *children; /* Nodes using us as parent. */
+ /*void *userdata;*/ /* For future use. */
+ char name[sizeof(void*)]; /* Open array. */
+};
+
+static struct node rootNode;
+
+static int
+nodeCompare(t1, t2)
+ const tree_t t1, t2;
+{
+ const char *n1 = ((struct node *)t1)->name + sizeof(u_char),
+ *n2 = ((struct node *)t2)->name + sizeof(u_char);
+
+ return (strcasecmp(n1, n2));
+}
+
+/* void *
+ * db_findname(const char *name, int storeflag)
+ * find or store a presentation format domain name.
+ * returns:
+ * NULL if an error occurred (check errno)
+ * else, node's unique, opaque address.
+ */
+void *
+db_findname(name, storeflag)
+ const char *name;
+ int storeflag;
+{
+ struct node *node, *tnode;
+ const char *tname;
+ size_t len;
+ int ch;
+
+ /* The root domain has its own static node. */
+ if (name[0] == '\0')
+ return (&rootNode);
+
+ /* Locate the end of the first label. */
+ for (tname = name; (ch = *tname) != '\0'; tname++) {
+ /* Is this the end of the first label? */
+ if (ch == '.')
+ break;
+ /* Is it an escaped character? */
+ if (ch == '\\') {
+ ch = *++tname;
+ if (ch == '\0')
+ break;
+ }
+ }
+
+ /* Make sure the label's length will fit in our length byte. */
+ len = tname - name;
+ if (len > 255) {
+ errno = ENAMETOOLONG;
+ return (NULL);
+ }
+
+ /* If nothing but unescaped dots after this, elide them. */
+ while (ch == '.')
+ ch = *tname++;
+
+ /*
+ * Make a new node since the comparison function needs it
+ * and we may yet end up adding it to our parent's tree.
+ *
+ * Note that by recursing for tnode->parent, we might be
+ * creating our parents and grandparents and so on.
+ */
+ tnode = (struct node *)malloc(sizeof(struct node) - sizeof(void *)
+ + sizeof(u_char) + len + sizeof(char));
+ tnode->parent = db_findname(tname);
+ tnode->children = NULL;
+ *((u_char *)tnode->name) = (u_char)len;
+ memcpy(tnode->name + sizeof(u_char), name, len);
+ tnode->name[sizeof(u_char) + len] = '\0';
+
+ /* If our first label isn't in our parent's tree, put it there. */
+ node = tree_srch(&tnode->parent->children, nodeCompare, (tree_t)tnode);
+ if (node == NULL)
+ if (storeflag)
+ if (tree_add(&tnode->parent->children, nodeCompare,
+ (tree_t)tnode, NULL))
+ node = tnode, tnode = NULL;
+ else
+ errno = ENOMEM;
+ else
+ errno = ENOENT;
+
+ /* Get rid of tnode if we didn't consume it. */
+ if (tnode != NULL)
+ free(tnode);
+
+ /* Return the (possibly new) node, or NULL, as appropriate. */
+ return (node);
+}
+
+/* int
+ * db_getname(void *node, char *name, size_t size)
+ * given a node's unique, opaque address, format its name.
+ * returns:
+ * -1 = error occurred, check errno
+ * 0 = success
+ */
+int
+db_getname(vnode, name, size)
+ const void *vnode;
+ char *name;
+ size_t size;
+{
+ const struct node *node = vnode;
+
+ while (node != NULL) {
+ size_t len = (size_t)node->name[0];
+
+ if (size < len + 1)
+ goto too_long;
+ memcpy(name, node->name + sizeof(u_char), len);
+ name += len;
+ *name++ = '.';
+ size -= len + sizeof(char);
+ node = node->parent;
+ }
+
+ if (size < sizeof(char)) {
+ too_long:
+ errno = ENAMETOOLONG;
+ return (-1);
+ }
+ *name = '\0';
+ return (0);
+}
+
+/*
+ * char *
+ * db_makename(void *node)
+ * given a node's unique, opaque address, format and return its name.
+ * returns:
+ * pointer to the name or NULL on errors (check errno).
+ * notes:
+ * returns pointer to a static buffer, be careful how you call it.
+ */
+char *
+db_makename(vnode)
+ void *vnode;
+{
+ static char name[MAXDNAME*2];
+
+ if (db_getname(vnode, name, sizeof name) < 0)
+ return (NULL);
+ return (name);
+}