aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/lib/libc/asr/asr.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/lib/libc/asr/asr.c')
-rw-r--r--contrib/lib/libc/asr/asr.c182
1 files changed, 89 insertions, 93 deletions
diff --git a/contrib/lib/libc/asr/asr.c b/contrib/lib/libc/asr/asr.c
index 3d8acea1..72b531ca 100644
--- a/contrib/lib/libc/asr/asr.c
+++ b/contrib/lib/libc/asr/asr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: asr.c,v 1.9 2012/09/07 13:49:43 eric Exp $ */
+/* $OpenBSD: asr.c,v 1.13 2012/09/09 16:45:14 eric Exp $ */
/*
* Copyright (c) 2010-2012 Eric Faurot <eric@openbsd.org>
*
@@ -42,6 +42,26 @@
#define __THREAD_NAME(x) __ ## x
#define _THREAD_PRIVATE(a, b, c) (c)
+#ifndef ASR_OPT_THREADSAFE
+#define ASR_OPT_THREADSAFE 1
+#endif
+#ifndef ASR_OPT_HOSTALIASES
+#define ASR_OPT_HOSTALIASES 1
+#endif
+#ifndef ASR_OPT_ENVOPTS
+#define ASR_OPT_ENVOPTS 1
+#endif
+#ifndef ASR_OPT_RELOADCONF
+#define ASR_OPT_RELOADCONF 1
+#endif
+#ifndef ASR_OPT_ALTCONF
+#define ASR_OPT_ALTCONF 1
+#endif
+
+#if ASR_OPT_THREADSAFE
+#include "thread_private.h"
+#endif
+
#define DEFAULT_CONFFILE "/etc/resolv.conf"
#define DEFAULT_HOSTFILE "/etc/hosts"
#define DEFAULT_CONF "lookup bind file\nnameserver 127.0.0.1\n"
@@ -58,13 +78,21 @@ static int asr_ctx_from_file(struct asr_ctx *, const char *);
static int asr_ctx_from_string(struct asr_ctx *, const char *);
static int asr_ctx_parse(struct asr_ctx *, const char *);
static int asr_parse_nameserver(struct sockaddr *, const char *);
-static char *asr_hostalias(const char *, char *, size_t);
static int asr_ndots(const char *);
-static void asr_ctx_envopts(struct asr_ctx *);
static void pass0(char **, int, struct asr_ctx *);
static int strsplit(char *, char **, int);
-
+#if ASR_OPT_HOSTALIASES
+static char *asr_hostalias(const char *, char *, size_t);
+#endif
+#if ASR_OPT_ENVOPTS
+static void asr_ctx_envopts(struct asr_ctx *);
+#endif
+#if ASR_OPT_THREADSAFE
static void *__THREAD_NAME(_asr);
+#else
+# define _THREAD_PRIVATE(a, b, c) (c)
+#endif
+
static struct asr *_asr = NULL;
#define issetugid() ((getuid() != geteuid()))
@@ -76,19 +104,22 @@ async_resolver(const char *conf)
static int init = 0;
struct asr *asr;
-#ifdef DEBUG
if (init == 0) {
+#ifdef DEBUG
if (getenv("ASR_DEBUG"))
- asr_debug = 1;
+ asr_debug = stderr;
+#endif
init = 1;
}
-#endif
+
if ((asr = calloc(1, sizeof(*asr))) == NULL)
goto fail;
+#if ASR_OPT_ALTCONF
/* If not setuid/setgid, allow to use an alternate config. */
if (conf == NULL && !issetugid())
conf = getenv("ASR_CONFIG");
+#endif
if (conf == NULL)
conf = DEFAULT_CONFFILE;
@@ -108,12 +139,14 @@ async_resolver(const char *conf)
goto fail;
if (asr_ctx_from_string(asr->a_ctx, DEFAULT_CONF) == -1)
goto fail;
+#if ASR_OPT_ENVOPTS
asr_ctx_envopts(asr->a_ctx);
+#endif
}
}
#ifdef DEBUG
- asr_dump(asr);
+ asr_dump_config(asr_debug, asr);
#endif
return (asr);
@@ -169,24 +202,16 @@ async_run(struct async *as, struct async_res *ar)
{
int r, saved_errno = errno;
-#ifdef DEBUG
- asr_printf("asr: async_run(%p, %p) %s ctx=[%p]\n",
- as, ar, asr_querystr(as->as_type), as->as_ctx);
-#endif
+ DPRINT("asr: async_run(%p, %p) %s ctx=[%p]\n", as, ar,
+ asr_querystr(as->as_type), as->as_ctx);
r = as->as_run(as, ar);
+ DPRINT("asr: async_run(%p, %p) -> %s", as, ar, asr_transitionstr(r));
#ifdef DEBUG
- if (asr_debug) {
- asr_printf("asr: async_run(%p, %p) -> %s", as, ar,
- asr_transitionstr(r));
- if (r == ASYNC_COND)
- asr_printf(" fd=%i timeout=%i\n",
- ar->ar_fd, ar->ar_timeout);
- else
- asr_printf("\n");
- fflush(stderr);
- }
+ if (r == ASYNC_COND)
#endif
+ DPRINT(" fd=%i timeout=%i", ar->ar_fd, ar->ar_timeout);
+ DPRINT("\n");
if (r == ASYNC_DONE)
async_free(as);
@@ -231,10 +256,9 @@ struct async *
async_new(struct asr_ctx *ac, int type)
{
struct async *as;
-#ifdef DEBUG
- asr_printf("asr: async_new(ctx=%p) type=%i refcount=%i\n",
- ac, type, ac->ac_refcount);
-#endif
+
+ DPRINT("asr: async_new(ctx=%p) type=%i refcount=%i\n", ac, type,
+ ac->ac_refcount);
if ((as = calloc(1, sizeof(*as))) == NULL)
return (NULL);
@@ -253,9 +277,7 @@ async_new(struct asr_ctx *ac, int type)
void
async_free(struct async *as)
{
-#ifdef DEBUG
- asr_printf("asr: async_free(%p)\n", as);
-#endif
+ DPRINT("asr: async_free(%p)\n", as);
switch(as->as_type) {
case ASR_SEND:
if (as->as_fd != -1)
@@ -334,15 +356,10 @@ asr_use_resolver(struct asr *asr)
struct asr **priv;
if (asr == NULL) {
- /* Use the thread-local resolver. */
-#ifdef DEBUG
- asr_printf("using thread-local resolver\n");
-#endif
+ DPRINT("using thread-local resolver\n");
priv = _THREAD_PRIVATE(_asr, asr, &_asr);
if (*priv == NULL) {
-#ifdef DEBUG
- asr_printf("setting up thread-local resolver\n");
-#endif
+ DPRINT("setting up thread-local resolver\n");
*priv = async_resolver(NULL);
}
asr = *priv;
@@ -356,10 +373,7 @@ asr_use_resolver(struct asr *asr)
static void
asr_ctx_ref(struct asr_ctx *ac)
{
-#ifdef DEBUG
- asr_printf("asr: asr_ctx_ref(ctx=%p) refcount=%i\n",
- ac, ac->ac_refcount);
-#endif
+ DPRINT("asr: asr_ctx_ref(ctx=%p) refcount=%i\n", ac, ac->ac_refcount);
ac->ac_refcount += 1;
}
@@ -370,10 +384,7 @@ asr_ctx_ref(struct asr_ctx *ac)
void
asr_ctx_unref(struct asr_ctx *ac)
{
-#ifdef DEBUG
- asr_printf("asr: asr_ctx_unref(ctx=%p) refcount=%i\n",
- ac, ac->ac_refcount);
-#endif
+ DPRINT("asr: asr_ctx_unref(ctx=%p) refcount=%i\n", ac, ac->ac_refcount);
if (--ac->ac_refcount)
return;
@@ -401,13 +412,16 @@ asr_ctx_free(struct asr_ctx *ac)
static void
asr_check_reload(struct asr *asr)
{
- struct stat st;
struct asr_ctx *ac;
+#if ASR_OPT_RELOADCONF
+ struct stat st;
struct timespec tp;
+#endif
if (asr->a_path == NULL)
return;
+#if ASR_OPT_RELOADCONF
#ifdef HAVE_CLOCK_GETTIME
if (clock_gettime(CLOCK_MONOTONIC, &tp) == -1)
return;
@@ -423,26 +437,26 @@ asr_check_reload(struct asr *asr)
return;
asr->a_rtime = tp.tv_sec;
-#ifdef DEBUG
- asr_printf("asr: checking for update of \"%s\"\n", asr->a_path);
-#endif
-
+ DPRINT("asr: checking for update of \"%s\"\n", asr->a_path);
if (stat(asr->a_path, &st) == -1 ||
asr->a_mtime == st.st_mtime ||
(ac = asr_ctx_create()) == NULL)
return;
asr->a_mtime = st.st_mtime;
-
-#ifdef DEBUG
- asr_printf("asr: reloading config file\n");
+#else
+ if ((ac = asr_ctx_create()) == NULL)
+ return;
#endif
+ DPRINT("asr: reloading config file\n");
if (asr_ctx_from_file(ac, asr->a_path) == -1) {
asr_ctx_free(ac);
return;
}
+#if ASR_OPT_ENVOPTS
asr_ctx_envopts(ac);
+#endif
if (asr->a_ctx)
asr_ctx_unref(asr->a_ctx);
asr->a_ctx = ac;
@@ -721,9 +735,7 @@ asr_ctx_from_file(struct asr_ctx *ac, const char *path)
r = fread(buf, 1, sizeof buf - 1, cf);
if (feof(cf) == 0) {
-#ifdef DEBUG
- asr_printf("asr: config file too long: \"%s\"\n", path);
-#endif
+ DPRINT("asr: config file too long: \"%s\"\n", path);
r = -1;
}
fclose(cf);
@@ -768,6 +780,7 @@ asr_ctx_parse(struct asr_ctx *ac, const char *str)
return (0);
}
+#if ASR_OPT_ENVOPTS
/*
* Check for environment variables altering the configuration as described
* in resolv.conf(5). Altough not documented there, this feature is disabled
@@ -801,6 +814,7 @@ asr_ctx_envopts(struct asr_ctx *ac)
asr_ctx_parse(ac, buf);
}
}
+#endif
/*
* Parse a resolv.conf(5) nameserver string into a sockaddr.
@@ -912,17 +926,14 @@ int
asr_iter_db(struct async *as)
{
if (as->as_db_idx >= as->as_ctx->ac_dbcount) {
-#ifdef DEBUG
- asr_printf("asr_iter_db: done\n");
-#endif
+ DPRINT("asr_iter_db: done\n");
return (-1);
}
as->as_db_idx += 1;
as->as_ns_idx = 0;
-#ifdef DEBUG
- asr_printf("asr_iter_db: %i\n", as->as_db_idx);
-#endif
+ DPRINT("asr_iter_db: %i\n", as->as_db_idx);
+
return (0);
}
@@ -944,9 +955,7 @@ asr_iter_ns(struct async *as)
break;
as->as_ns_idx = 0;
as->as_ns_cycles++;
-#ifdef DEBUG
- asr_printf("asr: asr_iter_ns(): cycle %i\n", as->as_ns_cycles);
-#endif
+ DPRINT("asr: asr_iter_ns(): cycle %i\n", as->as_ns_cycles);
}
return (0);
@@ -973,7 +982,9 @@ enum {
int
asr_iter_domain(struct async *as, const char *name, char * buf, size_t len)
{
+#if ASR_OPT_HOSTALIASES
char *alias;
+#endif
switch(as->as_dom_step) {
@@ -985,14 +996,13 @@ asr_iter_domain(struct async *as, const char *name, char * buf, size_t len)
* don't try anything else.
*/
if (strlen(name) && name[strlen(name) - 1] == '.') {
-#ifdef DEBUG
- asr_printf("asr: asr_iter_domain(\"%s\") fqdn\n", name);
-#endif
+ DPRINT("asr: asr_iter_domain(\"%s\") fqdn\n", name);
as->as_dom_flags |= ASYNC_DOM_FQDN;
as->as_dom_step = DOM_DONE;
return (asr_domcat(name, NULL, buf, len));
}
+#if ASR_OPT_HOSTALIASES
/*
* If "name" has no dots, it might be an alias. If so,
* That's also the only result.
@@ -1000,14 +1010,13 @@ asr_iter_domain(struct async *as, const char *name, char * buf, size_t len)
if ((as->as_ctx->ac_options & RES_NOALIASES) == 0 &&
asr_ndots(name) == 0 &&
(alias = asr_hostalias(name, buf, len)) != NULL) {
-#ifdef DEBUG
- asr_printf("asr: asr_iter_domain(\"%s\") is alias "
- "\"%s\"\n", name, alias);
-#endif
+ DPRINT("asr: asr_iter_domain(\"%s\") is alias \"%s\"\n",
+ name, alias);
as->as_dom_flags |= ASYNC_DOM_HOSTALIAS;
as->as_dom_step = DOM_DONE;
return (asr_domcat(alias, NULL, buf, len));
}
+#endif
/*
* Otherwise, we iterate through the specified search domains.
@@ -1020,10 +1029,7 @@ asr_iter_domain(struct async *as, const char *name, char * buf, size_t len)
* in resolv.conf(5).
*/
if ((asr_ndots(name)) >= as->as_ctx->ac_ndots) {
-#ifdef DEBUG
- asr_printf("asr: asr_iter_domain(\"%s\") ndots\n",
- name);
-#endif
+ DPRINT("asr: asr_iter_domain(\"%s\") ndots\n", name);
as->as_dom_flags |= ASYNC_DOM_NDOTS;
strlcpy(buf, name, len);
return (0);
@@ -1033,11 +1039,8 @@ asr_iter_domain(struct async *as, const char *name, char * buf, size_t len)
case DOM_DOMAIN:
if (as->as_dom_idx < as->as_ctx->ac_domcount) {
-#ifdef DEBUG
- asr_printf("asr: asr_iter_domain(\"%s\") "
- "domain \"%s\"\n", name,
- as->as_ctx->ac_dom[as->as_dom_idx]);
-#endif
+ DPRINT("asr: asr_iter_domain(\"%s\") domain \"%s\"\n",
+ name, as->as_ctx->ac_dom[as->as_dom_idx]);
as->as_dom_flags |= ASYNC_DOM_DOMAIN;
return (asr_domcat(name,
as->as_ctx->ac_dom[as->as_dom_idx++], buf, len));
@@ -1052,10 +1055,7 @@ asr_iter_domain(struct async *as, const char *name, char * buf, size_t len)
* do it now.
*/
if (!(as->as_dom_flags & ASYNC_DOM_NDOTS)) {
-#ifdef DEBUG
- asr_printf("asr: asr_iter_domain(\"%s\") as is\n",
- name);
-#endif
+ DPRINT("asr: asr_iter_domain(\"%s\") as is\n", name);
as->as_dom_flags |= ASYNC_DOM_ASIS;
strlcpy(buf, name, len);
return (0);
@@ -1064,13 +1064,12 @@ asr_iter_domain(struct async *as, const char *name, char * buf, size_t len)
case DOM_DONE:
default:
-#ifdef DEBUG
- asr_printf("asr: asr_iter_domain(\"%s\") done\n", name);
-#endif
+ DPRINT("asr: asr_iter_domain(\"%s\") done\n", name);
return (-1);
}
}
+#if ASR_OPT_HOSTALIASES
/*
* Check if the hostname "name" is a user-defined alias as per hostname(7).
* If so, copies the result in the buffer "abuf" of size "abufsz" and
@@ -1088,9 +1087,7 @@ asr_hostalias(const char *name, char *abuf, size_t abufsz)
if (file == NULL || issetugid() != 0 || (fp = fopen(file, "r")) == NULL)
return (NULL);
-#ifdef DEBUG
- asr_printf("asr: looking up aliases in \"%s\"\n", file);
-#endif
+ DPRINT("asr: looking up aliases in \"%s\"\n", file);
while ((buf = fgetln(fp, &len)) != NULL) {
if (buf[len - 1] == '\n')
@@ -1101,9 +1098,7 @@ asr_hostalias(const char *name, char *abuf, size_t abufsz)
if (!strcasecmp(tokens[0], name)) {
if (strlcpy(abuf, tokens[1], abufsz) > abufsz)
continue;
-#ifdef DEBUG
- asr_printf("asr: found alias \"%s\"\n", abuf);
-#endif
+ DPRINT("asr: found alias \"%s\"\n", abuf);
fclose(fp);
return (abuf);
}
@@ -1112,3 +1107,4 @@ asr_hostalias(const char *name, char *abuf, size_t abufsz)
fclose(fp);
return (NULL);
}
+#endif