mirror of
https://github.com/pi-hole/dnsmasq.git
synced 2025-12-19 10:18:25 +00:00
Add --conf-script
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
74
src/option.c
74
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)
|
||||
|
||||
Reference in New Issue
Block a user