mirror of
https://github.com/pi-hole/dnsmasq.git
synced 2025-12-19 18:28:25 +00:00
Define order of reading files when --addn-hosts given a directory.
Also applies to --dhcp-hostsfile and --dhcp-optsfile though it is less useful there.
This commit is contained in:
@@ -86,6 +86,12 @@ version 2.86
|
|||||||
conntrack is configured. Thanks to Yick Xie for spotting
|
conntrack is configured. Thanks to Yick Xie for spotting
|
||||||
the lack of this.
|
the lack of this.
|
||||||
|
|
||||||
|
When --dhcp-hostsfile --dhcp-optsfile and --addn-hosts are
|
||||||
|
given a directory as argument, define the order in which
|
||||||
|
files within that directory are read (alphabetical order
|
||||||
|
of filename). Thanks to Ed Wildgoose for the initial patch
|
||||||
|
and motivation for this.
|
||||||
|
|
||||||
|
|
||||||
version 2.85
|
version 2.85
|
||||||
Fix problem with DNS retries in 2.83/2.84.
|
Fix problem with DNS retries in 2.83/2.84.
|
||||||
|
|||||||
@@ -55,7 +55,8 @@ Don't read the hostnames in /etc/hosts.
|
|||||||
.B \-H, --addn-hosts=<file>
|
.B \-H, --addn-hosts=<file>
|
||||||
Additional hosts file. Read the specified file as well as /etc/hosts. If \fB--no-hosts\fP is given, read
|
Additional hosts file. Read the specified file as well as /etc/hosts. If \fB--no-hosts\fP is given, read
|
||||||
only the specified file. This option may be repeated for more than one
|
only the specified file. This option may be repeated for more than one
|
||||||
additional hosts file. If a directory is given, then read all the files contained in that directory.
|
additional hosts file. If a directory is given, then read all the files contained in that directory
|
||||||
|
in alphabetical order.
|
||||||
.TP
|
.TP
|
||||||
.B --hostsdir=<path>
|
.B --hostsdir=<path>
|
||||||
Read all the hosts files contained in the directory. New or changed files
|
Read all the hosts files contained in the directory. New or changed files
|
||||||
@@ -1165,7 +1166,7 @@ has both wired and wireless interfaces.
|
|||||||
.TP
|
.TP
|
||||||
.B --dhcp-hostsfile=<path>
|
.B --dhcp-hostsfile=<path>
|
||||||
Read DHCP host information from the specified file. If a directory
|
Read DHCP host information from the specified file. If a directory
|
||||||
is given, then read all the files contained in that directory. The file contains
|
is given, then read all the files contained in that directory in alphabetical order. The file contains
|
||||||
information about one host per line. The format of a line is the same
|
information about one host per line. The format of a line is the same
|
||||||
as text to the right of '=' in \fB--dhcp-host\fP. The advantage of storing DHCP host information
|
as text to the right of '=' in \fB--dhcp-host\fP. The advantage of storing DHCP host information
|
||||||
in this file is that it can be changed without re-starting dnsmasq:
|
in this file is that it can be changed without re-starting dnsmasq:
|
||||||
@@ -1173,7 +1174,7 @@ the file will be re-read when dnsmasq receives SIGHUP.
|
|||||||
.TP
|
.TP
|
||||||
.B --dhcp-optsfile=<path>
|
.B --dhcp-optsfile=<path>
|
||||||
Read DHCP option information from the specified file. If a directory
|
Read DHCP option information from the specified file. If a directory
|
||||||
is given, then read all the files contained in that directory. The advantage of
|
is given, then read all the files contained in that directory in alphabetical order. The advantage of
|
||||||
using this option is the same as for \fB--dhcp-hostsfile\fP: the
|
using this option is the same as for \fB--dhcp-hostsfile\fP: the
|
||||||
\fB--dhcp-optsfile\fP will be re-read when dnsmasq receives SIGHUP. Note that
|
\fB--dhcp-optsfile\fP will be re-read when dnsmasq receives SIGHUP. Note that
|
||||||
it is possible to encode the information in a
|
it is possible to encode the information in a
|
||||||
@@ -1188,7 +1189,8 @@ directory, and not an individual file. Changed or new files within
|
|||||||
the directory are read automatically, without the need to send SIGHUP.
|
the directory are read automatically, without the need to send SIGHUP.
|
||||||
If a file is deleted or changed after it has been read by dnsmasq, then the
|
If a file is deleted or changed after it has been read by dnsmasq, then the
|
||||||
host record it contained will remain until dnsmasq receives a SIGHUP, or
|
host record it contained will remain until dnsmasq receives a SIGHUP, or
|
||||||
is restarted; ie host records are only added dynamically.
|
is restarted; ie host records are only added dynamically. The order in which the
|
||||||
|
files in a directory are read is not defined.
|
||||||
.TP
|
.TP
|
||||||
.B --dhcp-optsdir=<path>
|
.B --dhcp-optsdir=<path>
|
||||||
This is equivalent to \fB--dhcp-optsfile\fP, with the differences noted for \fB--dhcp-hostsdir\fP.
|
This is equivalent to \fB--dhcp-optsfile\fP, with the differences noted for \fB--dhcp-hostsdir\fP.
|
||||||
|
|||||||
54
src/option.c
54
src/option.c
@@ -5027,15 +5027,33 @@ static int one_file(char *file, int hard_opt)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int file_filter(const struct dirent *ent)
|
||||||
|
{
|
||||||
|
size_t lenfile = strlen(ent->d_name);
|
||||||
|
|
||||||
|
/* ignore emacs backups and dotfiles */
|
||||||
|
|
||||||
|
if (lenfile == 0 ||
|
||||||
|
ent->d_name[lenfile - 1] == '~' ||
|
||||||
|
(ent->d_name[0] == '#' && ent->d_name[lenfile - 1] == '#') ||
|
||||||
|
ent->d_name[0] == '.')
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
/* expand any name which is a directory */
|
/* expand any name which is a directory */
|
||||||
struct hostsfile *expand_filelist(struct hostsfile *list)
|
struct hostsfile *expand_filelist(struct hostsfile *list)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
struct hostsfile *ah;
|
int entcnt, n;
|
||||||
|
struct hostsfile *ah, *last, *next, **up;
|
||||||
|
struct dirent **namelist;
|
||||||
|
|
||||||
/* find largest used index */
|
/* find largest used index */
|
||||||
for (i = SRC_AH, ah = list; ah; ah = ah->next)
|
for (i = SRC_AH, ah = list; ah; ah = ah->next)
|
||||||
{
|
{
|
||||||
|
last = ah;
|
||||||
|
|
||||||
if (i <= ah->index)
|
if (i <= ah->index)
|
||||||
i = ah->index + 1;
|
i = ah->index + 1;
|
||||||
|
|
||||||
@@ -5051,46 +5069,48 @@ struct hostsfile *expand_filelist(struct hostsfile *list)
|
|||||||
struct stat buf;
|
struct stat buf;
|
||||||
if (stat(ah->fname, &buf) != -1 && S_ISDIR(buf.st_mode))
|
if (stat(ah->fname, &buf) != -1 && S_ISDIR(buf.st_mode))
|
||||||
{
|
{
|
||||||
DIR *dir_stream;
|
|
||||||
struct dirent *ent;
|
struct dirent *ent;
|
||||||
|
|
||||||
/* don't read this as a file */
|
/* don't read this as a file */
|
||||||
ah->flags |= AH_INACTIVE;
|
ah->flags |= AH_INACTIVE;
|
||||||
|
|
||||||
if (!(dir_stream = opendir(ah->fname)))
|
entcnt = scandir(ah->fname, &namelist, file_filter, alphasort);
|
||||||
|
if (entcnt < 0)
|
||||||
my_syslog(LOG_ERR, _("cannot access directory %s: %s"),
|
my_syslog(LOG_ERR, _("cannot access directory %s: %s"),
|
||||||
ah->fname, strerror(errno));
|
ah->fname, strerror(errno));
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
while ((ent = readdir(dir_stream)))
|
for (n = 0; n < entcnt; n++)
|
||||||
{
|
{
|
||||||
|
ent = namelist[n];
|
||||||
size_t lendir = strlen(ah->fname);
|
size_t lendir = strlen(ah->fname);
|
||||||
size_t lenfile = strlen(ent->d_name);
|
size_t lenfile = strlen(ent->d_name);
|
||||||
struct hostsfile *ah1;
|
struct hostsfile *ah1;
|
||||||
char *path;
|
char *path;
|
||||||
|
|
||||||
/* ignore emacs backups and dotfiles */
|
|
||||||
if (lenfile == 0 ||
|
|
||||||
ent->d_name[lenfile - 1] == '~' ||
|
|
||||||
(ent->d_name[0] == '#' && ent->d_name[lenfile - 1] == '#') ||
|
|
||||||
ent->d_name[0] == '.')
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* see if we have an existing record.
|
/* see if we have an existing record.
|
||||||
dir is ah->fname
|
dir is ah->fname
|
||||||
file is ent->d_name
|
file is ent->d_name
|
||||||
path to match is ah1->fname */
|
path to match is ah1->fname */
|
||||||
|
|
||||||
for (ah1 = list; ah1; ah1 = ah1->next)
|
for (up = &list, ah1 = list; ah1; ah1 = next)
|
||||||
{
|
{
|
||||||
|
next = ah1->next;
|
||||||
|
|
||||||
if (lendir < strlen(ah1->fname) &&
|
if (lendir < strlen(ah1->fname) &&
|
||||||
strstr(ah1->fname, ah->fname) == ah1->fname &&
|
strstr(ah1->fname, ah->fname) == ah1->fname &&
|
||||||
ah1->fname[lendir] == '/' &&
|
ah1->fname[lendir] == '/' &&
|
||||||
strcmp(ah1->fname + lendir + 1, ent->d_name) == 0)
|
strcmp(ah1->fname + lendir + 1, ent->d_name) == 0)
|
||||||
{
|
{
|
||||||
ah1->flags &= ~AH_INACTIVE;
|
ah1->flags &= ~AH_INACTIVE;
|
||||||
|
/* If found, remove from list to re-insert at the end.
|
||||||
|
Unless it's already at the end. */
|
||||||
|
if (last != ah1)
|
||||||
|
*up = next;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
up = &ah1->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* make new record */
|
/* make new record */
|
||||||
@@ -5111,17 +5131,21 @@ struct hostsfile *expand_filelist(struct hostsfile *list)
|
|||||||
ah1->fname = path;
|
ah1->fname = path;
|
||||||
ah1->index = i++;
|
ah1->index = i++;
|
||||||
ah1->flags = AH_DIR;
|
ah1->flags = AH_DIR;
|
||||||
ah1->next = list;
|
|
||||||
list = ah1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Edge case, may be the last in the list anyway */
|
||||||
|
if (last != ah1)
|
||||||
|
last->next = ah1;
|
||||||
|
ah1->next = NULL;
|
||||||
|
last = ah1;
|
||||||
|
|
||||||
/* inactivate record if not regular file */
|
/* inactivate record if not regular file */
|
||||||
if ((ah1->flags & AH_DIR) && stat(ah1->fname, &buf) != -1 && !S_ISREG(buf.st_mode))
|
if ((ah1->flags & AH_DIR) && stat(ah1->fname, &buf) != -1 && !S_ISREG(buf.st_mode))
|
||||||
ah1->flags |= AH_INACTIVE;
|
ah1->flags |= AH_INACTIVE;
|
||||||
|
|
||||||
}
|
}
|
||||||
closedir(dir_stream);
|
|
||||||
}
|
}
|
||||||
|
free(namelist);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user