summary refs log tree commit diff
path: root/hesiod
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2005-06-15 04:14:52 +0000
committerUlrich Drepper <drepper@redhat.com>2005-06-15 04:14:52 +0000
commitb399a0c2e2014daf166a36462db9d5bd5617454c (patch)
tree477eeca004180eef0339e609885a83b0a6bd3652 /hesiod
parentec23b9bece4780a2031eedf23019cbb229e855fb (diff)
downloadglibc-b399a0c2e2014daf166a36462db9d5bd5617454c.tar.gz
glibc-b399a0c2e2014daf166a36462db9d5bd5617454c.tar.xz
glibc-b399a0c2e2014daf166a36462db9d5bd5617454c.zip
* hesiod/hesiod_p.h (struct hesiod_p): Add classes array.
	* hesiod/hesiod.c (hesiod_init): Initialize classes.  Fail if no
	valid classes were given or if both are equal.
	(hesiod_resolve): Use ctx->classes instead of hardcoded C_IN
	and C_HS order.
	(parse_config_file): Handle classes keyword.
	* hesiod/README.hesiod: Mention addition of the classes keyword.
Diffstat (limited to 'hesiod')
-rw-r--r--hesiod/README.hesiod8
-rw-r--r--hesiod/hesiod.c58
-rw-r--r--hesiod/hesiod_p.h1
3 files changed, 49 insertions, 18 deletions
diff --git a/hesiod/README.hesiod b/hesiod/README.hesiod
index 18cd5d45dd..259ce8d447 100644
--- a/hesiod/README.hesiod
+++ b/hesiod/README.hesiod
@@ -71,6 +71,14 @@ will want to create your own.  It should look something like:
 
   rhs=.your.domain
   lhs=.ns
+  classes=in,hs
+
+The optional classes settings specifies which DNS classes Hesiod
+should do lookups in.  Possible values are IN (the preferred class)
+and  HS (the deprecated class, still used by some sites).
+You may specify both classes separated by a comma to try one class
+first and then the other if no entry is available in the first
+class.  The default value of the classes variable is `IN,HS'.
 
 The value of rhs can be overridden by the environment variable
 `HES_DOMAIN'.
diff --git a/hesiod/hesiod.c b/hesiod/hesiod.c
index 7fffb310f1..e0ce510866 100644
--- a/hesiod/hesiod.c
+++ b/hesiod/hesiod.c
@@ -83,6 +83,9 @@ hesiod_init(void **context) {
 	ctx->LHS = NULL;
 	ctx->RHS = NULL;
 	ctx->res = NULL;
+	/* Set default query classes. */
+	ctx->classes[0] = C_IN;
+	ctx->classes[1] = C_HS;
 
 	configname = __secure_getenv("HESIOD_CONFIG");
 	if (!configname)
@@ -123,7 +126,7 @@ hesiod_init(void **context) {
 	 * If there is no default hesiod realm set, we return an
 	 * error.
 	 */
-	if (!ctx->RHS) {
+	if (!ctx->RHS || ctx->classes[0] == 0 || ctx->classes[0] == ctx->classes[1]) {
 		__set_errno(ENOEXEC);
 		goto cleanup;
 	}
@@ -234,15 +237,12 @@ hesiod_resolve(void *context, const char *name, const char *type) {
 		return (NULL);
 	}
 
-	if ((retvec = get_txt_records(ctx, C_IN, bindname))) {
-		free(bindname);
-		return (retvec);
-	}
+	retvec = get_txt_records(ctx, ctx->classes[0], bindname);
+
+	if (retvec == NULL && (errno == ENOENT || errno == ECONNREFUSED) && ctx->classes[1])
+		retvec = get_txt_records(ctx, ctx->classes[1], bindname);
 
-	if (errno != ENOENT && errno != ECONNREFUSED)
-		return (NULL);
 
-	retvec = get_txt_records(ctx, C_HS, bindname);
 	free(bindname);
 	return (retvec);
 }
@@ -261,7 +261,6 @@ hesiod_free_list(void *context, char **list) {
  */
 static int
 parse_config_file(struct hesiod_p *ctx, const char *filename) {
-	char *key, *data, *cp, **cpp;
 	char buf[MAXDNAME+7];
 	FILE *fp;
 
@@ -272,6 +271,9 @@ parse_config_file(struct hesiod_p *ctx, const char *filename) {
 	free(ctx->RHS);
 	free(ctx->LHS);
 	ctx->RHS = ctx->LHS = 0;
+	/* Set default query classes. */
+	ctx->classes[0] = C_IN;
+	ctx->classes[1] = C_HS;
 
 	/*
 	 * Now open and parse the file...
@@ -280,6 +282,8 @@ parse_config_file(struct hesiod_p *ctx, const char *filename) {
 		return (-1);
 
 	while (fgets(buf, sizeof(buf), fp) != NULL) {
+		char *key, *data, *cp, **cpp;
+
 		cp = buf;
 		if (*cp == '#' || *cp == '\n' || *cp == '\r')
 			continue;
@@ -297,17 +301,35 @@ parse_config_file(struct hesiod_p *ctx, const char *filename) {
 			cp++;
 		*cp++ = '\0';
 
-		if (strcmp(key, "lhs") == 0)
+		cpp = NULL;
+		if (strcasecmp(key, "lhs") == 0)
 			cpp = &ctx->LHS;
-		else if (strcmp(key, "rhs") == 0)
+		else if (strcasecmp(key, "rhs") == 0)
 			cpp = &ctx->RHS;
-		else
-			continue;
-
-		*cpp = malloc(strlen(data) + 1);
-		if (!*cpp)
-			goto cleanup;
-		strcpy(*cpp, data);
+		if (cpp) {
+			*cpp = strdup(data);
+			if (!*cpp)
+				goto cleanup;
+		} else if (strcasecmp(key, "classes") == 0) {
+			int n = 0;
+			while (*data && n < 2) {
+				cp = strchrnul(data, ',');
+				if (*cp != '\0')
+					*cp++ = '\0';
+				if (strcasecmp(data, "IN") == 0)
+					ctx->classes[n++] = C_IN;
+				else if (strcasecmp(data, "HS") == 0)
+					ctx->classes[n++] = C_HS;
+				data = cp;
+			}
+			if (n == 0) {
+				/* Restore the default.  Better than
+				   nother at all.  */
+				ctx->classes[0] = C_IN;
+				ctx->classes[1] = C_HS;
+			} else if (n == 1)
+				ctx->classes[1] = 0;
+		}
 	}
 	fclose(fp);
 	return (0);
diff --git a/hesiod/hesiod_p.h b/hesiod/hesiod_p.h
index 71aca0976d..5010d71bc9 100644
--- a/hesiod/hesiod_p.h
+++ b/hesiod/hesiod_p.h
@@ -41,6 +41,7 @@ struct hesiod_p {
 	void		(*res_set)(struct hesiod_p *, struct __res_state *,
 				   void (*)(void *));
 	struct __res_state * (*res_get)(struct hesiod_p *);
+	int		classes[2];	/* The class search order. */
 };
 
 #define MAX_HESRESP	1024