On Thu, 14 Aug 2025, Edgar Fuß wrote:

It looks like mtree has a problem with file names containing an asterisk

ef@trave:/tmp/x$ echo foobar >foobar
ef@trave:/tmp/x$ echo 'foo*bar' >'foo*bar'
ef@trave:/tmp/x$ ls -l
total 16
-rw-r--r--  1 ef  wheel  8 Aug 14 17:27 foo*bar
-rw-r--r--  1 ef  wheel  7 Aug 14 17:26 foobar
ef@trave:/tmp/x$ /usr/sbin/mtree -c -p /tmp/x
#          user: ef
#       machine: trave.math.uni-bonn.de
#          tree: /tmp/x
#          date: Thu Aug 14 17:27:17 2025

# .
/set type=file uid=0 gid=0 mode=0644 nlink=1 flags=none
.               type=dir uid=10513 mode=0755 nlink=2 \
               time=1755185194.512283258
   foo\052bar  uid=10513 size=8 time=1755185221.401737966
   foobar      uid=10513 size=7 time=1755185211.763689351
ef@trave:/tmp/x$ /usr/sbin/mtree -c -p /tmp/x >/tmp/x.mtree
ef@trave:/tmp/x$ /usr/sbin/mtree -p /tmp/x -f /tmp/x.mtree
foobar: size (8, 7)
        modification time (Thu Aug 14 17:27:01 2025, Thu Aug 14 17:26:51 2025)
./foobar missing

What the hell?


This is explained in the manual. If the filename in the spec. contains a
wildcard, it is treated as such:

```
     3.   A file specification, consisting of a path name, followed by
          whitespace, followed by zero or more whitespace separated
          keyword/value pairs.

          The path name may be preceded by whitespace characters.  The path
          name may contain any of the standard path name matching characters
          (`[', `]', `?' or `*'), in which case files in the hierarchy will be
          associated with the first pattern that they match.
```

But, maybe mtree(8) should not do wildcard expansion on the filenames read from
a directory entry. It should only do so if comes from a spec.:

```
diff -urN mtree.orig/spec.c mtree/spec.c
--- mtree.orig/spec.c   2024-12-06 00:53:12.760341743 +0000
+++ mtree/spec.c        2025-08-14 22:34:47.288307464 +0000
@@ -175,6 +175,10 @@
                        tname = ntname;
                        tnamelen = plen;
                }
+#define        MAGIC   "?*["
+               unsigned int flags = 0;
+               if (strpbrk(p, MAGIC))
+                       flags = F_MAGIC;
                if (strunvis(tname, p) == -1)
                        mtree_err("strunvis failed on `%s'", p);
                p = tname;
@@ -209,9 +213,7 @@
                *centry = ginfo;
                centry->lineno = mtree_lineno;
                strcpy(centry->name, p);
-#define        MAGIC   "?*["
-               if (strpbrk(p, MAGIC))
-                       centry->flags |= F_MAGIC;
+               centry->flags |= flags;
                set(next, centry);

                if (root == NULL) {
```

-RVP

Reply via email to