git: 791fb098c9e8 - stable/15 - Import latest mtree from NetBSD

From: Jose Luis Duran <jlduran_at_FreeBSD.org>
Date: Sat, 27 Dec 2025 16:29:37 UTC
The branch stable/15 has been updated by jlduran:

URL: https://cgit.FreeBSD.org/src/commit/?id=791fb098c9e84282b7d061c5708569757e6c65a3

commit 791fb098c9e84282b7d061c5708569757e6c65a3
Author:     Jose Luis Duran <jlduran@FreeBSD.org>
AuthorDate: 2025-12-19 20:14:35 +0000
Commit:     Jose Luis Duran <jlduran@FreeBSD.org>
CommitDate: 2025-12-27 16:28:01 +0000

    Import latest mtree from NetBSD
    
    Merge commit 'eb2ccba0c11b405ac613c3046997765317cc8b5c'
    
    PR:             192839
    PR:             219467
    MFC after:      1 week
    
    (cherry picked from commit f8cee1f2c2dfba6223385fd711cce9faeca76451)
---
 contrib/mtree/compare.c | 16 ++++++----------
 contrib/mtree/create.c  |  7 ++++---
 contrib/mtree/mtree.c   | 36 ++++++++++++++++++++++--------------
 contrib/mtree/spec.c    | 25 +++++++++++--------------
 4 files changed, 43 insertions(+), 41 deletions(-)

diff --git a/contrib/mtree/compare.c b/contrib/mtree/compare.c
index 3d8cf2335207..cc31ec365194 100644
--- a/contrib/mtree/compare.c
+++ b/contrib/mtree/compare.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: compare.c,v 1.61 2024/12/05 17:17:43 christos Exp $	*/
+/*	$NetBSD: compare.c,v 1.63 2025/12/14 17:30:47 christos Exp $	*/
 
 /*-
  * Copyright (c) 1989, 1993
@@ -38,7 +38,7 @@
 #if 0
 static char sccsid[] = "@(#)compare.c	8.1 (Berkeley) 6/6/93";
 #else
-__RCSID("$NetBSD: compare.c,v 1.61 2024/12/05 17:17:43 christos Exp $");
+__RCSID("$NetBSD: compare.c,v 1.63 2025/12/14 17:30:47 christos Exp $");
 #endif
 #endif /* not lint */
 
@@ -291,16 +291,12 @@ typeerr:		LABEL;
 		    (u_long)p->fts_statp->st_mode & MBITS);
 		if (uflag) {
 			if (lchmod(p->fts_accpath, s->st_mode))
-				printf(", not modified: %s%s\n",
-				    strerror(errno),
-				    flavor == F_FREEBSD9 ? "" : ")");
+				printf(", not modified: %s", strerror(errno));
 			else
-				printf(", modified%s%s\n",
-				    was_unlinked ? " by unlink" : "",
-				    flavor == F_FREEBSD9 ? "" : ")");
+				printf(", modified%s",
+				    was_unlinked ? " by unlink" : "");
 		}
-		else
-			printf(")\n");
+		printf("%s\n", flavor == F_FREEBSD9 ? "" : ")");
 		tab = "\t";
 	skip:	;
 	}
diff --git a/contrib/mtree/create.c b/contrib/mtree/create.c
index e23004851f39..191d69c6a537 100644
--- a/contrib/mtree/create.c
+++ b/contrib/mtree/create.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: create.c,v 1.79 2024/12/05 17:17:43 christos Exp $	*/
+/*	$NetBSD: create.c,v 1.80 2025/12/18 18:16:48 christos Exp $	*/
 
 /*-
  * Copyright (c) 1989, 1993
@@ -38,7 +38,7 @@
 #if 0
 static char sccsid[] = "@(#)create.c	8.1 (Berkeley) 6/6/93";
 #else
-__RCSID("$NetBSD: create.c,v 1.79 2024/12/05 17:17:43 christos Exp $");
+__RCSID("$NetBSD: create.c,v 1.80 2025/12/18 18:16:48 christos Exp $");
 #endif
 #endif /* not lint */
 
@@ -236,7 +236,8 @@ statf(FILE *fp, int indent, FTSENT *p)
 		offset += fprintf(fp, "%*s",
 		    (INDENTNAMELEN + indent) - offset, "");
 
-	if (!S_ISREG(p->fts_statp->st_mode) && (flavor == F_NETBSD6 || !dflag))
+	if (keys & F_TYPE &&
+	    !S_ISREG(p->fts_statp->st_mode) && (flavor == F_NETBSD6 || !dflag))
 		output(fp, indent, &offset, "type=%s",
 		    inotype(p->fts_statp->st_mode));
 	if (keys & (F_UID | F_UNAME) && p->fts_statp->st_uid != uid) {
diff --git a/contrib/mtree/mtree.c b/contrib/mtree/mtree.c
index 28f09fa32210..479f6acfca3a 100644
--- a/contrib/mtree/mtree.c
+++ b/contrib/mtree/mtree.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: mtree.c,v 1.51 2024/12/05 17:17:15 christos Exp $	*/
+/*	$NetBSD: mtree.c,v 1.52 2025/12/18 18:17:26 christos Exp $	*/
 
 /*-
  * Copyright (c) 1989, 1990, 1993
@@ -43,7 +43,7 @@ __COPYRIGHT("@(#) Copyright (c) 1989, 1990, 1993\
 #if 0
 static char sccsid[] = "@(#)mtree.c	8.1 (Berkeley) 6/6/93";
 #else
-__RCSID("$NetBSD: mtree.c,v 1.51 2024/12/05 17:17:15 christos Exp $");
+__RCSID("$NetBSD: mtree.c,v 1.52 2025/12/18 18:17:26 christos Exp $");
 #endif
 #endif /* not lint */
 
@@ -73,19 +73,20 @@ static struct {
 };
 
 __dead static	void	usage(void);
+static int parsekeys(char **);
 
 int
 main(int argc, char **argv)
 {
 	int	ch, status;
 	unsigned int	i;
-	int	cflag, Cflag, Dflag, Uflag, wflag;
+	int	cflag, Cflag, Dflag, Uflag, wflag, rkeys;
 	char	*dir, *p;
 	FILE	*spec1, *spec2;
 
 	setprogname(argv[0]);
 
-	cflag = Cflag = Dflag = Uflag = wflag = 0;
+	cflag = Cflag = Dflag = Uflag = wflag = rkeys = 0;
 	dir = NULL;
 	init_excludes();
 	spec1 = stdin;
@@ -150,14 +151,9 @@ main(int argc, char **argv)
 			break;
 		case 'k':
 			keys = F_TYPE;
-			while ((p = strsep(&optarg, " \t,")) != NULL)
-				if (*p != '\0')
-					keys |= parsekey(p, NULL);
-			break;
+			/*FALLTHROUGH*/
 		case 'K':
-			while ((p = strsep(&optarg, " \t,")) != NULL)
-				if (*p != '\0')
-					keys |= parsekey(p, NULL);
+			keys |= parsekeys(&optarg);
 			break;
 		case 'l':
 			lflag = 1;
@@ -198,9 +194,7 @@ main(int argc, char **argv)
 			rflag++;
 			break;
 		case 'R':
-			while ((p = strsep(&optarg, " \t,")) != NULL)
-				if (*p != '\0')
-					keys &= ~parsekey(p, NULL);
+			rkeys |= parsekeys(&optarg);
 			break;
 		case 's':
 			sflag = 1;
@@ -243,6 +237,8 @@ main(int argc, char **argv)
 	if (argc)
 		usage();
 
+	keys &= ~rkeys;
+
 	switch (flavor) {
 	case F_FREEBSD9:
 		if (cflag && iflag) {
@@ -312,6 +308,18 @@ main(int argc, char **argv)
 	exit(status);
 }
 
+static int
+parsekeys(char **arg)
+{
+	const char *p;
+	int k = 0;
+
+	while ((p = strsep(arg, " \t,")) != NULL)
+		if (*p != '\0')
+			k |= parsekey(p, NULL);
+	return k;
+}
+
 static void
 usage(void)
 {
diff --git a/contrib/mtree/spec.c b/contrib/mtree/spec.c
index 24e15f33fa8a..af5248be1596 100644
--- a/contrib/mtree/spec.c
+++ b/contrib/mtree/spec.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: spec.c,v 1.92 2024/12/05 17:17:43 christos Exp $	*/
+/*	$NetBSD: spec.c,v 1.94 2025/12/18 14:05:41 christos Exp $	*/
 
 /*-
  * Copyright (c) 1989, 1993
@@ -67,7 +67,7 @@
 #if 0
 static char sccsid[] = "@(#)spec.c	8.2 (Berkeley) 4/28/95";
 #else
-__RCSID("$NetBSD: spec.c,v 1.92 2024/12/05 17:17:43 christos Exp $");
+__RCSID("$NetBSD: spec.c,v 1.94 2025/12/18 14:05:41 christos Exp $");
 #endif
 #endif /* not lint */
 
@@ -100,7 +100,7 @@ static	dev_t	parsedev(char *);
 static	void	replacenode(NODE *, NODE *);
 static	void	set(char *, NODE *);
 static	void	unset(char *, NODE *);
-static	void	addchild(NODE *, NODE *);
+static	NODE	*addchild(NODE *, NODE *);
 static	int	nodecmp(const NODE *, const NODE *);
 static	int	appendfield(FILE *, int, const char *, ...) __printflike(3, 4);
 
@@ -239,8 +239,7 @@ noparent:		mtree_err("no parent node");
 				 * full path entry; add or replace
 				 */
 			centry->parent = pathparent;
-			addchild(pathparent, centry);
-			last = centry;
+			last = addchild(pathparent, centry);
 		} else if (strcmp(centry->name, ".") == 0) {
 				/*
 				 * duplicate "." entry; always replace
@@ -252,8 +251,7 @@ noparent:		mtree_err("no parent node");
 				 * add or replace
 				 */
 			centry->parent = last;
-			addchild(last, centry);
-			last = centry;
+			last = addchild(last, centry);
 		} else {
 				/*
 				 * new relative child in parent dir
@@ -261,8 +259,7 @@ noparent:		mtree_err("no parent node");
 				 * add or replace
 				 */
 			centry->parent = last->parent;
-			addchild(last->parent, centry);
-			last = centry;
+			last = addchild(last->parent, centry);
 		}
 	}
 	return (root);
@@ -721,7 +718,7 @@ unset(char *t, NODE *ip)
  *	a duplicate, insert it into the linked list referenced by
  *	pathparent->child.  Keep the list sorted if Sflag is set.
  */
-static void
+static NODE *
 addchild(NODE *pathparent, NODE *centry)
 {
 	NODE *samename;      /* node with the same name as centry */
@@ -740,7 +737,7 @@ addchild(NODE *pathparent, NODE *centry)
 	if (cur == NULL) {
 		/* centry is pathparent's first and only child node so far */
 		pathparent->child = centry;
-		return;
+		return centry;
 	}
 
 	/*
@@ -785,7 +782,7 @@ addchild(NODE *pathparent, NODE *centry)
 		replacenode(samename, centry);
 		if (samename == replacepos) {
 			/* The just-replaced node was in the correct position */
-			return;
+			return samename;
 		}
 		if (samename == insertpos || samename->prev == insertpos) {
 			/*
@@ -793,7 +790,7 @@ addchild(NODE *pathparent, NODE *centry)
 			 * or just after the replaced node, but that would
 			 * be equivalent to just retaining the replaced node.
 			 */
-			return;
+			return samename;
 		}
 
 		/*
@@ -833,7 +830,7 @@ addchild(NODE *pathparent, NODE *centry)
 		if (centry->next)
 			centry->next->prev = centry;
 	}
-	return;
+	return centry;
 }
 
 /*