From b399a0c2e2014daf166a36462db9d5bd5617454c Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Wed, 15 Jun 2005 04:14:52 +0000 Subject: * 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. --- hesiod/README.hesiod | 8 ++++++++ hesiod/hesiod.c | 58 ++++++++++++++++++++++++++++++++++++---------------- hesiod/hesiod_p.h | 1 + 3 files changed, 49 insertions(+), 18 deletions(-) (limited to 'hesiod') 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 -- cgit 1.4.1