diff options
author | Simon Kelley <simon@thekelleys.org.uk> | 2022-02-08 11:37:06 +0000 |
---|---|---|
committer | Simon Kelley <simon@thekelleys.org.uk> | 2022-02-08 12:10:27 +0000 |
commit | e426c2d3bc182d790f83039b77a09d55230ca71f (patch) | |
tree | f79f154bb67260fcc4045a1c52b091fc5c66c4b8 | |
parent | 6279d9eaf3537be156bb722fbb700cdb673eeb38 (diff) | |
download | dnsmasq-e426c2d3bc182d790f83039b77a09d55230ca71f.tar.gz |
Add --conf-scriptv2.87test8
-rw-r--r-- | CHANGELOG | 2 | ||||
-rw-r--r-- | man/dnsmasq.8 | 21 | ||||
-rw-r--r-- | src/option.c | 74 |
3 files changed, 85 insertions, 12 deletions
@@ -47,6 +47,8 @@ version 2.87 always allocates a fresh index, they are not reused). We now take this behaviour into account and keep up with changing indexes. + Add --conf-script configuration option. + version 2.86 Handle DHCPREBIND requests in the DHCPv6 server code. diff --git a/man/dnsmasq.8 b/man/dnsmasq.8 index 6ce61dd..ca155f0 100644 --- a/man/dnsmasq.8 +++ b/man/dnsmasq.8 @@ -2141,6 +2141,23 @@ A special case of which differs in two respects. Firstly, only \fB--server\fP and \fB--rev-server\fP are allowed in the configuration file included. Secondly, the file is re-read and the configuration therein is updated when dnsmasq receives SIGHUP. +.TP +.B \--conf-script=<file>[ <arg] +Execute <file>, and treat what it emits to stdout as the contents of a configuration file. +If the script exits with a non-zero exit code, dnsmasq treats this as a fatal error. +The script can be passed arguments, space seperated from the filename and each other so, for instance +.B --conf-dir="/etc/dnsmasq-uncompress-ads /share/ads-domains.gz" + +with /etc/dnsmasq-uncompress-ads containing + +set -e + +zcat ${1} | sed -e "s:^:address=/:" -e "s:$:/:" + +exit 0 + +and /share/ads-domains.gz containing a compressed +list of ad server domains will save disk space with large ad-server blocklists. .SH CONFIG FILE At startup, dnsmasq reads .I /etc/dnsmasq.conf, @@ -2537,7 +2554,9 @@ file/directory, permissions). 5 - Other miscellaneous problem. .PP 11 or greater - a non zero return code was received from the -lease-script process "init" call. The exit code from dnsmasq is the +lease-script process "init" call or a +.B \--conf-script +file. The exit code from dnsmasq is the script's exit code with 10 added. .SH LIMITS diff --git a/src/option.c b/src/option.c index fded28e..d9dd6a3 100644 --- a/src/option.c +++ b/src/option.c @@ -179,6 +179,8 @@ struct myoption { #define LOPT_FILTER_AAAA 370 #define LOPT_STRIP_SBNET 371 #define LOPT_STRIP_MAC 372 +#define LOPT_CONF_OPT 373 +#define LOPT_CONF_SCRIPT 374 #ifdef HAVE_GETOPT_LONG static const struct option opts[] = @@ -225,6 +227,7 @@ static const struct myoption opts[] = { "local", 1, 0, LOPT_LOCAL }, { "address", 1, 0, 'A' }, { "conf-file", 2, 0, 'C' }, + { "conf-script", 1, 0, LOPT_CONF_SCRIPT }, { "no-resolv", 0, 0, 'R' }, { "expand-hosts", 0, 0, 'E' }, { "localmx", 0, 0, 'L' }, @@ -467,6 +470,7 @@ static struct { { LOPT_SCRIPTUSR, ARG_ONE, "<username>", gettext_noop("Run lease-change scripts as this user."), NULL }, { LOPT_SCRIPT_ARP, OPT_SCRIPT_ARP, NULL, gettext_noop("Call dhcp-script with changes to local ARP table."), NULL }, { '7', ARG_DUP, "<path>", gettext_noop("Read configuration from all the files in this directory."), NULL }, + { LOPT_CONF_SCRIPT, ARG_DUP, "<path>", gettext_noop("Execute file and read configuration from stdin."), NULL }, { '8', ARG_ONE, "<facility>|<file>", gettext_noop("Log to this syslog facility or file. (defaults to DAEMON)"), NULL }, { '9', OPT_LEASE_RO, NULL, gettext_noop("Do not use leasefile."), NULL }, { '0', ARG_ONE, "<integer>", gettext_noop("Maximum number of concurrent DNS queries. (defaults to %s)"), "!" }, @@ -1810,6 +1814,17 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma break; } + case LOPT_CONF_SCRIPT: /* --conf-script */ + { + char *file = opt_string_alloc(arg); + if (file) + { + one_file(file, LOPT_CONF_SCRIPT); + free(file); + } + break; + } + case '7': /* --conf-dir */ { DIR *dir_stream; @@ -4966,11 +4981,19 @@ static void read_file(char *file, FILE *f, int hard_opt) while (fgets(buff, MAXDNAME, f)) { - int white, i; - volatile int option = (hard_opt == LOPT_REV_SERV) ? 0 : hard_opt; + int white, i, script = 0; + volatile int option; char *errmess, *p, *arg, *start; size_t len; + if (hard_opt == LOPT_CONF_SCRIPT) + { + hard_opt = 0; + script = 1; + } + + option = (hard_opt == LOPT_REV_SERV) ? 0 : hard_opt; + /* Memory allocation failure longjmps here if mem_recover == 1 */ if (option != 0 || hard_opt == LOPT_REV_SERV) { @@ -5084,7 +5107,11 @@ static void read_file(char *file, FILE *f, int hard_opt) if (errmess || !one_opt(option, arg, daemon->namebuff, _("error"), 0, hard_opt == LOPT_REV_SERV)) { - sprintf(daemon->namebuff + strlen(daemon->namebuff), _(" at line %d of %s"), lineno, file); + if (script) + sprintf(daemon->namebuff + strlen(daemon->namebuff), _(" in output from %s"), file); + else + sprintf(daemon->namebuff + strlen(daemon->namebuff), _(" at line %d of %s"), lineno, file); + if (hard_opt != 0) my_syslog(LOG_ERR, "%s", daemon->namebuff); else @@ -5093,7 +5120,6 @@ static void read_file(char *file, FILE *f, int hard_opt) } mem_recover = 0; - fclose(f); } #if defined(HAVE_DHCP) && defined(HAVE_INOTIFY) @@ -5113,7 +5139,7 @@ int option_read_dynfile(char *file, int flags) static int one_file(char *file, int hard_opt) { FILE *f; - int nofile_ok = 0; + int nofile_ok = 0, do_popen = 0; static int read_stdin = 0; static struct fileread { dev_t dev; @@ -5121,13 +5147,13 @@ static int one_file(char *file, int hard_opt) struct fileread *next; } *filesread = NULL; - if (hard_opt == '7') + if (hard_opt == LOPT_CONF_OPT) { /* default conf-file reading */ hard_opt = 0; nofile_ok = 1; } - + if (hard_opt == 0 && strcmp(file, "-") == 0) { if (read_stdin == 1) @@ -5141,6 +5167,12 @@ static int one_file(char *file, int hard_opt) /* ignore repeated files. */ struct stat statbuf; + if (hard_opt == LOPT_CONF_SCRIPT) + { + hard_opt = 0; + do_popen = 1; + } + if (hard_opt == 0 && stat(file, &statbuf) == 0) { struct fileread *r; @@ -5155,8 +5187,13 @@ static int one_file(char *file, int hard_opt) r->dev = statbuf.st_dev; r->ino = statbuf.st_ino; } - - if (!(f = fopen(file, "r"))) + + if (do_popen) + { + if (!(f = popen(file, "r"))) + die(_("cannot execute %s: %s"), file, EC_FILE); + } + else if (!(f = fopen(file, "r"))) { if (errno == ENOENT && nofile_ok) return 1; /* No conffile, all done. */ @@ -5174,7 +5211,21 @@ static int one_file(char *file, int hard_opt) } } - read_file(file, f, hard_opt); + read_file(file, f, do_popen ? LOPT_CONF_SCRIPT : hard_opt); + + if (do_popen) + { + int rc; + + if ((rc = pclose(f)) == -1) + die(_("error executing %s: %s"), file, EC_MISC); + + if (rc != 0) + die(_("%s returns non-zero error code"), file, rc+10); + } + else + fclose(f); + return 1; } @@ -5315,6 +5366,7 @@ void read_servers_file(void) mark_servers(SERV_FROM_FILE); read_file(daemon->servers_file, f, LOPT_REV_SERV); + fclose(f); cleanup_servers(); check_servers(0); } @@ -5540,7 +5592,7 @@ void read_opts(int argc, char **argv, char *compile_opts) free(conffile); } else - one_file(CONFFILE, '7'); + one_file(CONFFILE, LOPT_CONF_OPT); /* port might not be known when the address is parsed - fill in here */ if (daemon->servers) |