NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

bin/58886: mtree: Exit with status 2 on a non-matching spec



>Number:         58886
>Category:       bin
>Synopsis:       mtree: Exit with status 2 on a non-matching spec
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    bin-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Mon Dec 09 18:50:00 +0000 2024
>Originator:     Jose Luis Duran
>Release:        trunk
>Organization:
FreeBSD
>Environment:
>Description:
A FreeBSD user reports[^1] that the mtree utility should exit with status 2 if the file hierarchy did
not match the specification.

[^1]: https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=28424
>How-To-Repeat:
:It it important to remove the time stamp from the specification, otherwise it will behave correctly, because it will take a different code path:

# mkdir -p testdir/bar
# mtree -cd -R time -p testdir >output
# rm -fr testdir/bar
# mtree -d -f output -p testdir && echo 'hierarchy matches spec'
./bar missing
hierarchy matches spec
>Fix:
A simple (naive) patch is proposed, as usual, feel free to change as you see fit.

The patch:
1. Promotes rval (the return value) to an exten (this step is not mandatory).
2. Sets the rval to 2 (MISMATCHEXIT), after printing the message that something is missing from the specification. (This matches the behavior described in the man page).
3. Add a test. The test is not really relevant, it is added here just for convenience.

Subject: [PATCH 2/2] mtree: Exit with status 2 on a non-matching spec

The mtree utility should exit with status 2 if the file hierarchy did
not match the specification.

FreeBSD PR:	28424
---
 tests/usr.sbin/mtree/t_mtree.sh | 36 +++++++++++++++++++++++++++++++++
 usr.sbin/mtree/extern.h         |  1 +
 usr.sbin/mtree/getid.c          |  8 --------
 usr.sbin/mtree/mtree.c          |  1 +
 usr.sbin/mtree/specspec.c       |  1 -
 usr.sbin/mtree/verify.c         |  8 ++++----
 6 files changed, 42 insertions(+), 13 deletions(-)

diff --git a/tests/usr.sbin/mtree/t_mtree.sh b/tests/usr.sbin/mtree/t_mtree.sh
index 5e4177c792a5..fa1aba7c9d4a 100644
--- a/tests/usr.sbin/mtree/t_mtree.sh
+++ b/tests/usr.sbin/mtree/t_mtree.sh
@@ -482,6 +482,40 @@ netbsd6_onlyfile_body()
 	FLAVOR=netbsd6 onlyfile_body
 }

+atf_test_case mtree_verify
+atf_test_case netbsd6_verify
+verify_head()
+{
+	atf_set "descr" "Verify exit code of mismatched spec"
+}
+
+verify_body()
+{
+	mkdir -p testdir/bar
+	mtree -F ${FLAVOR} -cd -R time -p testdir >output
+	rm -fr testdir/bar
+
+	atf_check -s exit:2 -o ignore -x "mtree -F ${FLAVOR} -d -f output -p testdir"
+}
+
+mtree_verify_head()
+{
+	FLAVOR=mtree verify_head
+}
+netbsd6_verify_head()
+{
+	FLAVOR=netbsd6 verify_head
+}
+
+mtree_verify_body()
+{
+	FLAVOR=mtree verify_body
+}
+netbsd6_verify_body()
+{
+	FLAVOR=netbsd6 verify_body
+}
+

 atf_init_test_cases()
 {
@@ -496,6 +530,7 @@ atf_init_test_cases()
 	atf_add_test_case mtree_nonemptydir
 	atf_add_test_case mtree_specspec_type
 	atf_add_test_case mtree_onlyfile
+	atf_add_test_case mtree_verify

 	atf_add_test_case netbsd6_create
 	atf_add_test_case netbsd6_check
@@ -507,4 +542,5 @@ atf_init_test_cases()
 	atf_add_test_case netbsd6_merge
 	atf_add_test_case netbsd6_nonemptydir
 	atf_add_test_case netbsd6_onlyfile
+	atf_add_test_case netbsd6_verify
 }
diff --git a/usr.sbin/mtree/extern.h b/usr.sbin/mtree/extern.h
index 7b58dd4a4d20..f311d23a77d5 100644
--- a/usr.sbin/mtree/extern.h
+++ b/usr.sbin/mtree/extern.h
@@ -92,6 +92,7 @@ extern size_t	mtree_lineno;
 extern enum flavor	flavor;
 extern uint32_t crc_total;
 extern int	ftsoptions, keys;
+extern int	rval;
 extern char	fullpath[];
 extern slist_t	includetags, excludetags;

diff --git a/usr.sbin/mtree/getid.c b/usr.sbin/mtree/getid.c
index 2c9e641500ec..86d7d21189b5 100644
--- a/usr.sbin/mtree/getid.c
+++ b/usr.sbin/mtree/getid.c
@@ -151,8 +151,6 @@ setup_getid(const char *dir)
 static struct group *
 gi_getgrnam(const char *name)
 {
-	int rval;
-
 	if (!grstart())
 		return NULL;
 	rval = grscan(1, 0, name);
@@ -164,8 +162,6 @@ gi_getgrnam(const char *name)
 static struct group *
 gi_getgrgid(gid_t gid)
 {
-	int rval;
-
 	if (!grstart())
 		return NULL;
 	rval = grscan(1, gid, NULL);
@@ -300,8 +296,6 @@ grmatchline(int search, gid_t gid, const char *name)
 static struct passwd *
 gi_getpwnam(const char *name)
 {
-	int rval;
-
 	if (!pwstart())
 		return NULL;
 	rval = pwscan(1, 0, name);
@@ -313,8 +307,6 @@ gi_getpwnam(const char *name)
 static struct passwd *
 gi_getpwuid(uid_t uid)
 {
-	int rval;
-
 	if (!pwstart())
 		return NULL;
 	rval = pwscan(1, uid, NULL);
diff --git a/usr.sbin/mtree/mtree.c b/usr.sbin/mtree/mtree.c
index 28f09fa32210..9c289a1c0ee0 100644
--- a/usr.sbin/mtree/mtree.c
+++ b/usr.sbin/mtree/mtree.c
@@ -61,6 +61,7 @@ __RCSID("$NetBSD: mtree.c,v 1.51 2024/12/05 17:17:15 christos Exp $");
 int	ftsoptions = FTS_PHYSICAL;
 int	bflag, dflag, eflag, iflag, jflag, lflag, mflag, nflag, qflag, rflag,
 	sflag, tflag, uflag;
+int	rval = 0;
 char	fullpath[MAXPATHLEN];

 static struct {
diff --git a/usr.sbin/mtree/specspec.c b/usr.sbin/mtree/specspec.c
index 8e1187b4c0a8..9906a058878a 100644
--- a/usr.sbin/mtree/specspec.c
+++ b/usr.sbin/mtree/specspec.c
@@ -260,7 +260,6 @@ walk_in_the_forest(NODE *t1, NODE *t2, char const *path)
 int
 mtree_specspec(FILE *fi, FILE *fj)
 {
-	int rval;
 	NODE *root1, *root2;

 	root1 = spec(fi);
diff --git a/usr.sbin/mtree/verify.c b/usr.sbin/mtree/verify.c
index be11002cef85..b58f8ce46604 100644
--- a/usr.sbin/mtree/verify.c
+++ b/usr.sbin/mtree/verify.c
@@ -66,8 +66,6 @@ static int	vwalk(void);
 int
 verify(FILE *fi)
 {
-	int rval;
-
 	root = spec(fi);
 	rval = vwalk();
 	miss(root, path);
@@ -80,7 +78,7 @@ vwalk(void)
 	FTS *t;
 	FTSENT *p;
 	NODE *ep, *level;
-	int specdepth, rval;
+	int specdepth;
 	char *argv[2];
 	char  dot[] = ".";
 	argv[0] = dot;
@@ -199,8 +197,10 @@ miss(NODE *p, char *tail)
 			if (qflag && stat(path, &statbuf) == 0 &&
 			    S_ISDIR(statbuf.st_mode))
 				p->flags |= F_VISIT;
-			else
+			else {
 				(void)printf("%s missing", path);
+				rval = MISMATCHEXIT;
+			}
 		}
 		switch (p->type) {
 		case F_BLOCK:
--
Jose Luis Duran



Home | Main Index | Thread Index | Old Index