commit:     f75ba2a6f7629f77c5d1ffe85602b9dc4e88824c
Author:     Mike Gilbert <floppym <AT> gentoo <DOT> org>
AuthorDate: Tue Feb 24 20:43:30 2026 +0000
Commit:     Mike Gilbert <floppym <AT> gentoo <DOT> org>
CommitDate: Tue Feb 24 21:23:22 2026 +0000
URL:        https://gitweb.gentoo.org/proj/install-xattr.git/commit/?id=f75ba2a6

Adjust exclusion logic

We do not need to allocate a buffer for the exclude list; it can point
at a constant or a mutable environement variable.

Rework the nested loops in copyxattr so my brain can comprehend them.
As a side effect, this fixes an off-by-one error when
PORTAGE_XATTR_EXCLUDE is set to "*".

Signed-off-by: Mike Gilbert <floppym <AT> gentoo.org>

 install-xattr.c | 79 ++++++++++++++++++++++-----------------------------------
 1 file changed, 31 insertions(+), 48 deletions(-)

diff --git a/install-xattr.c b/install-xattr.c
index c39c808..74cd462 100644
--- a/install-xattr.c
+++ b/install-xattr.c
@@ -42,14 +42,7 @@
 #define REAL_INSTALL "/usr/bin/install"
 #endif
 
-static char *
-xstrdup(const char *s)
-{
-       char *ret = strdup(s);
-       if (ret == NULL)
-               err(1, "strdup() failed");
-       return ret;
-}
+#define DEFAULT_EXCLUDE "btrfs.*\0security.*\0trusted.*\0system.nfs4_acl"
 
 static void *
 xmalloc(size_t size)
@@ -111,13 +104,12 @@ xsetxattr(const char *path, char *list, char *value, 
size_t size)
        return ret;
 }
 
-char *exclude;      /* strings of excluded xattr names              */
-size_t len_exclude; /* length of the string of excluded xattr names */
+static const char *exclude; /* strings of excluded xattr names */
+static size_t len_exclude;  /* length of the string of excluded xattr names */
 
 static void
 copyxattr(const char *source, const char *target)
 {
-       ssize_t i, j;           /* counters to walk through strings             
      */
        ssize_t lsize, xsize;   /* size in bytes of the list of xattrs and the 
values */
        char *lxattr;                  /* string of xattr names                 
      */
        static char *value = NULL ;    /* string of an xattr name's value       
      */
@@ -139,40 +131,33 @@ copyxattr(const char *source, const char *target)
        lxattr = xmalloc(lsize);
        lsize = xlistxattr(source, lxattr, lsize);
 
-       i = 0;
-       while (1) {
-               while (lxattr[i++] == 0)
-                       continue;
+       for (size_t i = 0;;) {
+               while (lxattr[i] == '\0')
+                       ++i;
                if (i >= lsize)
                        break;
 
-               j = 0;
-               while (1) {
-                       while (exclude[j++] == 0)
-                               continue;
+               for (size_t j = 0;;) {
+                       while (exclude[j] == '\0')
+                               ++j;
                        if (j >= len_exclude)
                                break;
-                       if (!fnmatch(&exclude[j - 1], &lxattr[i - 1], 0))
+                       if (!fnmatch(exclude + j, lxattr + i, 0))
                                goto skip;
-                       while (exclude[j++] != 0)
-                               continue;
-                       if (j >= len_exclude)
-                               break;
+                       while (exclude[j] != '\0')
+                               ++j;
                }
 
-               xsize = xgetxattr(source, &lxattr[i-1], 0, 0);
+               xsize = xgetxattr(source, lxattr + i, 0, 0);
                if (xsize > value_size) {
                        value_size = xsize;
                        value = xrealloc(value, value_size);
                }
-               xgetxattr(source, &lxattr[i-1], value, xsize);
-               xsetxattr(target, &lxattr[i-1], value, xsize);
-
+               xgetxattr(source, lxattr + i, value, xsize);
+               xsetxattr(target, lxattr + i, value, xsize);
  skip:
-               while (lxattr[i++] != 0)
-                       continue;
-               if (i >= lsize)
-                       break;
+               while (lxattr[i] != '\0')
+                       ++i;
        }
 
        /* No need to free(value) on return because its static and we */
@@ -211,22 +196,20 @@ main(int argc, char* argv[])
                err(1, "failed to spawn install");
 
        char *portage_xattr_exclude = getenv("PORTAGE_XATTR_EXCLUDE");
-       if (portage_xattr_exclude == NULL)
-               exclude = xstrdup("btrfs.* security.* trusted.* 
system.nfs4_acl");
-       else
-               exclude = xstrdup(portage_xattr_exclude);
-
-       len_exclude = strlen(exclude);
-
-       /* We convert exclude[] to an array of concatenated NUL terminated
-        * strings.  Also, no need to free(exclude) before we exit().
-        */
-       char *p = exclude;
-       char *pend = p + len_exclude;
-       while (p != pend) {
-               if (isspace(*p))
-                       *p = '\0';
-               p++;
+       if (portage_xattr_exclude) {
+               exclude = portage_xattr_exclude;
+               len_exclude = strlen(exclude);
+               /* We convert exclude[] to an array of concatenated NUL 
terminated
+                * strings.  Also, no need to free(exclude) before we exit().
+                */
+               char *pend = portage_xattr_exclude + len_exclude;
+               for (char *p = portage_xattr_exclude; p != pend; ++p)
+                       if (isspace(*p))
+                               *p = '\0';
+       }
+       else {
+               exclude = DEFAULT_EXCLUDE;
+               len_exclude = sizeof(DEFAULT_EXCLUDE) - 1;
        }
 
        opterr = 0; /* we skip many legitimate flags, so silence any warning */

Reply via email to