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

Reply via email to