[Dnsmasq-discuss] feature: dictionary order import of addn-hosts dirs?
Ed W
lists at wildgooses.com
Sun Aug 8 13:02:11 UTC 2021
On 19/07/2021 18:52, Ed W wrote:
> Hi, around 2.82 someone posted a little patch to import the config files in dictionary order, which
> is very useful for situations where you have overlapping definitions. I'm using an addn-hosts stanza
> pointing to a directory and files currently import in a somewhat random order (suppose inode
> order?), which can lead to unexpected reverse host definitions in some cases
>
> Could we have a dictionary order import for add-hosts files please?
>
> Ed W
Hi, I have developed the attached patch without really being sure that this is the best approach. I
would be grateful for some feedback. I have used scandir without understanding if this is portable
across systems that we support with dnsmasq. Also I am trying to copy the existing coding style, but
surely I have failed.
I'm also unclear that it still works as advertised in the case that I don't have inotify enabled?
Any help?
The intent is that I have a few aliases for my local system name. However, the reverse name depends
on the order that the addn-hosts files are read. In any case predictable dictionary order seems like
a nice thing to have for all config files
Thanks
Ed W
-------------- next part --------------
--- a/src/option.c 2021-08-08 11:38:59.736193892 +0000
+++ b/src/option.c 2021-08-08 11:39:05.959267538 +0000
@@ -4819,7 +4819,9 @@
struct hostsfile *expand_filelist(struct hostsfile *list)
{
unsigned int i;
+ int entcnt, n;
struct hostsfile *ah;
+ struct dirent **namelist;
/* find largest used index */
for (i = SRC_AH, ah = list; ah; ah = ah->next)
@@ -4839,19 +4841,20 @@
struct stat buf;
if (stat(ah->fname, &buf) != -1 && S_ISDIR(buf.st_mode))
{
- DIR *dir_stream;
struct dirent *ent;
/* don't read this as a file */
ah->flags |= AH_INACTIVE;
- if (!(dir_stream = opendir(ah->fname)))
+ entcnt = scandir(ah->fname, &namelist, NULL, alphasort);
+ if (entcnt < 0)
my_syslog(LOG_ERR, _("cannot access directory %s: %s"),
ah->fname, strerror(errno));
else
{
- while ((ent = readdir(dir_stream)))
+ for (n = 0; n < entcnt; n++)
{
+ ent = namelist[n];
size_t lendir = strlen(ah->fname);
size_t lenfile = strlen(ent->d_name);
struct hostsfile *ah1;
@@ -4908,8 +4911,8 @@
ah1->flags |= AH_INACTIVE;
}
- closedir(dir_stream);
}
+ free(namelist);
}
}
--- a/src/inotify.c 2021-08-08 11:38:52.297105848 +0000
+++ b/src/inotify.c 2021-08-08 11:39:05.959267538 +0000
@@ -141,8 +141,9 @@
for (ah = daemon->dynamic_dirs; ah; ah = ah->next)
{
- DIR *dir_stream = NULL;
+ struct dirent **namelist;
struct dirent *ent;
+ int entcnt, n;
struct stat buf;
if (!(ah->flags & flag))
@@ -163,15 +164,24 @@
/* Read contents of dir _after_ calling add_watch, in the hope of avoiding
a race which misses files being added as we start */
- if (ah->wd == -1 || !(dir_stream = opendir(ah->fname)))
+ if (ah->wd == -1)
{
my_syslog(LOG_ERR, _("failed to create inotify for %s: %s"),
ah->fname, strerror(errno));
continue;
}
- while ((ent = readdir(dir_stream)))
+ entcnt = scandir(ah->fname, &namelist, NULL, alphasort);
+ if (entcnt < 0)
{
+ my_syslog(LOG_ERR, _("failed to call scandir for %s: %s"),
+ ah->fname, strerror(errno));
+ continue;
+ }
+
+ for (n = 0; n < entcnt; n++)
+ {
+ ent = namelist[n];
size_t lendir = strlen(ah->fname);
size_t lenfile = strlen(ent->d_name);
char *path;
@@ -204,7 +214,7 @@
}
}
- closedir(dir_stream);
+ free(namelist);
}
}
More information about the Dnsmasq-discuss
mailing list