From 8cf671e973a4ea2ef7c9ca1321531a7ceeaa5073 Mon Sep 17 00:00:00 2001 From: Laurent Bercot Date: Tue, 11 Jul 2023 12:26:21 +0000 Subject: Good version of hosts.h Signed-off-by: Laurent Bercot --- doc/libs6dns/hosts.html | 129 ++++++++++++++++++++++++++++++++++++++++ src/include/s6-dns/hosts.h | 6 +- src/libs6dns/s6dns_hosts_init.c | 46 ++++++++------ 3 files changed, 160 insertions(+), 21 deletions(-) create mode 100644 doc/libs6dns/hosts.html diff --git a/doc/libs6dns/hosts.html b/doc/libs6dns/hosts.html new file mode 100644 index 0000000..93bfc10 --- /dev/null +++ b/doc/libs6dns/hosts.html @@ -0,0 +1,129 @@ + + + + + + s6-dns: the s6dns_hosts library interface + + + + + + +

+libs6dns
+s6-dns
+Software
+skarnet.org +

+ +

The s6dns_hosts library interface

+ +

+ The following functions are declared in the s6-dns/hosts.h header, +and implemented in the libs6dns.a or libs6dns.so library. +

+ +

General information

+ +

+ s6dns_hosts provides functions and macros - mostly macros - +to perform name-to-IP or IP-to-name resolution according to the +local /etc/hosts file. +

+ +

+ Most of the functions declared here are variations of another, more +generic function. Typically, a foobar_r function is the +generic one, and will take additional arguments such as: a pointer to +a local hosts database (compiled to an efficient format), and/or a +list and number of rules for qualification. The corresponding foobar +function is the same, except that it uses global variables to fill +these additional arguments: for instance, the hosts database made from +/etc/hosts, or the qualification rules computed from +/etc/resolv.conf. We document the simpler functions — even +though they're macros, we pretend they're functions; please refer to +the s6-dns/hosts.h +file for the exact prototypes or if you want to use the generic functions. +

+ + + +

Global variables

+ +

+ cdb s6dns_hosts_here
+s6dns_hosts_here is the global cdb database containing +the compiled data from /etc/hosts. You normally do not need to +use it manually because it is implicitly supplied to functions when you +use the macros without a _r suffix. +

+ + +

Functions

+ +

Preparation

+ +

+ int s6dns_hosts_compile (int fdr, int fdw)
+Compiles the text file data from file descriptor fdr, +which should be in /etc/hosts format, into a cdb file +written to file descriptor fdw. fdr must be +open for reading, and fdw must be open for writing and +seekable. The function returns 1 on success and 0 (and sets errno) +on failure. +

+ +

+ You normally don't need to use this function yourself, because +it's implicitly used by the following one. +

+ +

+ int s6dns_hosts_init (void)
+Initializes the database from the /etc/hosts file. +If there's a pre-compiled /etc/hosts.cdb file that +is more recent than /etc/hosts, then it is used; +else, the /etc/hosts file is compiled into a +temporary file under /tmp, which is used and +immediately unlinked. The function returns 1 on success and +0 (and sets errno) on failure. +

+ +

+ int s6dns_hosts_init_r (cdb *c, char const *txtfile, char const *cdbfile, char const *prefix)
+The generic version of the above function. Initializes the database +in *c from the compiled file cdbfile if it exists and is +more recent than txtfile, else compiles txtfile into +a temporary file with a path starting with prefix, makes it +accessible in *c and immediately unlinks it. +

+ +

+ void s6dns_hosts_free (void)
+Frees the compiled hosts database. Only use this if +you're certain you'll have no more use for it. +

+ +

+ void s6dns_hosts_free_r (cdb *c)
+The generic version of the above function. +

+ +

IP to name resolution

+ +

+ int s6dns_hosts_name_r (cdb const *c, char const *ip, stralloc *storage, genalloc *indices, int is6)
+

+ + + diff --git a/src/include/s6-dns/hosts.h b/src/include/s6-dns/hosts.h index 7c11af0..0f85d0b 100644 --- a/src/include/s6-dns/hosts.h +++ b/src/include/s6-dns/hosts.h @@ -13,8 +13,10 @@ extern cdb s6dns_hosts_here ; extern int s6dns_hosts_compile (int, int) ; -extern int s6dns_hosts_init (cdb *) ; -#define s6dns_hosts_free(c) cdb_free(c) +extern int s6dns_hosts_init_r (cdb *, char const *, char const *, char const *) ; +#define s6dns_hosts_init() s6dns_hosts_init_r(&s6dns_hosts_here, "/etc/hosts", "/etc/hosts.cdb", "/tmp/hosts.cdb") +#define s6dns_hosts_free_r(c) cdb_free(c) +#define s6dns_hosts_free() s6dns_hosts_free_r(&s6dns_hosts_here) diff --git a/src/libs6dns/s6dns_hosts_init.c b/src/libs6dns/s6dns_hosts_init.c index d3cd863..762d738 100644 --- a/src/libs6dns/s6dns_hosts_init.c +++ b/src/libs6dns/s6dns_hosts_init.c @@ -1,5 +1,6 @@ /* ISC license. */ +#include #include #include #include @@ -11,16 +12,15 @@ #include -int s6dns_hosts_init (void) +int s6dns_hosts_init_r (cdb *c, char const *txtfile, char const *cdbfile, char const *tmpprefix) { - int fdr, fdw ; - char tmp[24] = "/tmp/hosts.cdb:XXXXXX" ; - int fdc = openc_read("/etc/hosts.cdb") ; + int fdr ; + int fdc = openc_read(cdbfile) ; if (fdc >= 0) { struct stat stc, str ; if (fstat(fdc, &stc) == -1) goto errc ; - if (stat("/etc/hosts", &str) == -1) + if (stat(txtfile, &str) == -1) { if (errno == ENOENT) goto useit ; else goto errc ; @@ -28,21 +28,29 @@ int s6dns_hosts_init (void) if (stc.st_mtim > str.st_mtim) goto useit ; fd_close(fdc) ; } - fdr = openc_read("/etc/hosts") ; + + fdr = openc_read(txtfile) ; if (fdr == -1) return errno == ENOENT ? (errno = 0, 0) : -1 ; - fdw = mkstemp(tmp) ; - if (fdw == -1) goto errr ; - if (!s6dns_hosts_compile(fdr, fdw)) goto errw ; - if (lseek(fdw, 0, SEEK_SET) == -1) goto errw ; - if (!cdb_init_fromfd(&s6dns_hosts_here, fdw)) goto errw ; - fd_close(fdw) ; - unlink_void(tmp) ; - fd_close(fdr) ; - return 1 ; + { + int fdw ; + size_t len = strlen(tmpprefix) ; + char tmp[len + 8] ; + memcpy(tmp, tmpprefix, len) ; + memcpy(tmp + len, ":XXXXXX", 8) ; + fdw = mkstemp(tmp) ; + if (fdw == -1) goto errr ; + if (!s6dns_hosts_compile(fdr, fdw)) goto errw ; + if (lseek(fdw, 0, SEEK_SET) == -1) goto errw ; + if (!cdb_init_fromfd(c, fdw)) goto errw ; + fd_close(fdw) ; + unlink_void(tmp) ; + fd_close(fdr) ; + return 1 ; - errw: - fd_close(fdw) ; - unlink_void(tmp) ; + errw: + fd_close(fdw) ; + unlink_void(tmp) ; + } errr: fd_close(fdr) ; return -1 ; @@ -52,7 +60,7 @@ int s6dns_hosts_init (void) return -1 ; useit: - if (!cdb_init_fromfd(&s6dns_hosts_here, fdc)) + if (!cdb_init_fromfd(c, fdc)) { fd_close(fdc) ; return 0 ; -- cgit v1.2.3