From ab53883c94f94958e22077c79ba1dae1850a475e Mon Sep 17 00:00:00 2001 From: Simon Kelley Date: Fri, 10 Jan 2020 20:44:48 +0000 Subject: [PATCH] Enhance --conf-dir to load files in a deterministic order. --- CHANGELOG | 3 +++ man/dnsmasq.8 | 2 +- src/option.c | 47 +++++++++++++++++++++++++++++++++-------------- 3 files changed, 37 insertions(+), 15 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 570eb46..42ad123 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -61,6 +61,9 @@ version 2.81 Thanks to Dereck Higgins for spotting this. Add --tftp-single-port option. + + Enhance --conf-dir to load files in a deterministic order. Thanks to + Evgenii Seliavka for the suggestion and initial patch. version 2.80 diff --git a/man/dnsmasq.8 b/man/dnsmasq.8 index 744eb5e..cb5cc73 100644 --- a/man/dnsmasq.8 +++ b/man/dnsmasq.8 @@ -1967,7 +1967,7 @@ which have that extension are loaded. So .B --conf-dir=/path/to/dir,*.conf loads all files with the suffix .conf in /path/to/dir. This flag may be given on the command line or in a configuration file. If giving it on the command line, be sure to -escape * characters. +escape * characters. Files are loaded in alphabetical order of filename. .TP .B --servers-file= A special case of diff --git a/src/option.c b/src/option.c index bce8659..f110b75 100644 --- a/src/option.c +++ b/src/option.c @@ -1665,9 +1665,9 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma struct dirent *ent; char *directory, *path; struct list { - char *suffix; + char *name; struct list *next; - } *ignore_suffix = NULL, *match_suffix = NULL, *li; + } *ignore_suffix = NULL, *match_suffix = NULL, *files = NULL, *li; comma = split(arg); if (!(directory = opt_string_alloc(arg))) @@ -1689,7 +1689,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma li->next = match_suffix; match_suffix = li; /* Have to copy: buffer is overwritten */ - li->suffix = opt_string_alloc(arg+1); + li->name = opt_string_alloc(arg+1); } } else @@ -1697,7 +1697,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma li->next = ignore_suffix; ignore_suffix = li; /* Have to copy: buffer is overwritten */ - li->suffix = opt_string_alloc(arg); + li->name = opt_string_alloc(arg); } } } @@ -1722,9 +1722,9 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma for (li = match_suffix; li; li = li->next) { /* check for required suffices */ - size_t ls = strlen(li->suffix); + size_t ls = strlen(li->name); if (len > ls && - strcmp(li->suffix, &ent->d_name[len - ls]) == 0) + strcmp(li->name, &ent->d_name[len - ls]) == 0) break; } if (!li) @@ -1734,9 +1734,9 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma for (li = ignore_suffix; li; li = li->next) { /* check for proscribed suffices */ - size_t ls = strlen(li->suffix); + size_t ls = strlen(li->name); if (len > ls && - strcmp(li->suffix, &ent->d_name[len - ls]) == 0) + strcmp(li->name, &ent->d_name[len - ls]) == 0) break; } if (li) @@ -1753,25 +1753,44 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma /* only reg files allowed. */ if (S_ISREG(buf.st_mode)) - one_file(path, 0); - - free(path); + { + /* sort files into order. */ + struct list **up, *new = opt_malloc(sizeof(struct list)); + new->name = path; + + for (up = &files, li = files; li; up = &li->next, li = li->next) + if (strcmp(li->name, path) >=0) + break; + + new->next = li; + *up = new; + } + } - + + for (li = files; li; li = li->next) + one_file(li->name, 0); + closedir(dir_stream); free(directory); for(; ignore_suffix; ignore_suffix = li) { li = ignore_suffix->next; - free(ignore_suffix->suffix); + free(ignore_suffix->name); free(ignore_suffix); } for(; match_suffix; match_suffix = li) { li = match_suffix->next; - free(match_suffix->suffix); + free(match_suffix->name); free(match_suffix); } + for(; files; files = li) + { + li = files->next; + free(files->name); + free(files); + } break; }