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
--- 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); } }
_______________________________________________ Dnsmasq-discuss mailing list Dnsmasq-discuss@lists.thekelleys.org.uk https://lists.thekelleys.org.uk/cgi-bin/mailman/listinfo/dnsmasq-discuss