Date: Sat, 20 Dec 2025 01:11:19 +0000 From: Jose Luis Duran <jlduran@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org Subject: git: a3b349e43987 - stable/13 - Import latest mtree from NetBSD Message-ID: <6945f7b7.35924.1cf63169@gitrepo.freebsd.org>
index | next in thread | raw e-mail
The branch stable/13 has been updated by jlduran: URL: https://cgit.FreeBSD.org/src/commit/?id=a3b349e439870eeb4f58c74b990f721d86a75e1d commit a3b349e439870eeb4f58c74b990f721d86a75e1d Author: Jose Luis Duran <jlduran@FreeBSD.org> AuthorDate: 2025-12-13 14:28:16 +0000 Commit: Jose Luis Duran <jlduran@FreeBSD.org> CommitDate: 2025-12-20 01:08:28 +0000 Import latest mtree from NetBSD Merge commit 'f600477feb4ae61a75f61949eb600caff4aeea8c' MFC after: 1 week Discussed with: brooks (cherry picked from commit 49b6dda4d71175ad615718401573be5fd024822b) --- contrib/mtree/compare.c | 39 ++++++++----- contrib/mtree/crc.c | 20 +++---- contrib/mtree/create.c | 144 ++++++++++++++++++++--------------------------- contrib/mtree/extern.h | 13 ++++- contrib/mtree/misc.c | 10 ++-- contrib/mtree/mtree.8 | 139 +++++++++++++++++++++++++++++++++++---------- contrib/mtree/mtree.c | 8 +-- contrib/mtree/spec.c | 44 ++++++++++++--- contrib/mtree/specspec.c | 4 +- contrib/mtree/verify.c | 17 ++++-- 10 files changed, 271 insertions(+), 167 deletions(-) diff --git a/contrib/mtree/compare.c b/contrib/mtree/compare.c index e3639ceea08f..c4e5bfcac1d7 100644 --- a/contrib/mtree/compare.c +++ b/contrib/mtree/compare.c @@ -1,4 +1,4 @@ -/* $NetBSD: compare.c,v 1.58 2013/11/21 18:39:50 christos Exp $ */ +/* $NetBSD: compare.c,v 1.61 2024/12/05 17:17:43 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.58 2013/11/21 18:39:50 christos Exp $"); +__RCSID("$NetBSD: compare.c,v 1.61 2024/12/05 17:17:43 christos Exp $"); #endif #endif /* not lint */ @@ -135,8 +135,9 @@ do { \ int compare(NODE *s, FTSENT *p) { - u_int32_t len, val, flags; + uint32_t len, val, flags; int fd, label; + bool was_unlinked; const char *cp, *tab; #if !defined(NO_MD5) || !defined(NO_RMD160) || !defined(NO_SHA1) || !defined(NO_SHA2) char *digestbuf; @@ -144,6 +145,7 @@ compare(NODE *s, FTSENT *p) tab = NULL; label = 0; + was_unlinked = false; switch(s->type) { case F_BLOCK: if (!S_ISBLK(p->fts_statp->st_mode)) @@ -210,47 +212,53 @@ typeerr: LABEL; s->st_mode | nodetoino(s->type), s->st_rdev) == -1) || (lchown(p->fts_accpath, p->fts_statp->st_uid, - p->fts_statp->st_gid) == -1) ) + p->fts_statp->st_gid) == -1) ) { printf(", not modified: %s%s\n", strerror(errno), flavor == F_FREEBSD9 ? "" : ")"); - else + } else { printf(", modified%s\n", flavor == F_FREEBSD9 ? "" : ")"); + was_unlinked = true; + } } else printf(")\n"); tab = "\t"; } /* Set the uid/gid first, then set the mode. */ - if (s->flags & (F_UID | F_UNAME) && s->st_uid != p->fts_statp->st_uid) { + if (s->flags & (F_UID | F_UNAME) && + (was_unlinked || s->st_uid != p->fts_statp->st_uid)) { LABEL; printf(flavor == F_FREEBSD9 ? "%suser expected %lu found %lu" : "%suser (%lu, %lu", tab, (u_long)s->st_uid, (u_long)p->fts_statp->st_uid); if (uflag) { - if (lchown(p->fts_accpath, s->st_uid, -1)) + if (lchown(p->fts_accpath, s->st_uid, (gid_t)-1)) printf(", not modified: %s%s\n", strerror(errno), flavor == F_FREEBSD9 ? "" : ")"); else - printf(", modified%s\n", + printf(", modified%s%s\n", + was_unlinked ? " by unlink" : "", flavor == F_FREEBSD9 ? "" : ")"); } else printf(")\n"); tab = "\t"; } - if (s->flags & (F_GID | F_GNAME) && s->st_gid != p->fts_statp->st_gid) { + if (s->flags & (F_GID | F_GNAME) && + (was_unlinked || s->st_gid != p->fts_statp->st_gid)) { LABEL; printf(flavor == F_FREEBSD9 ? "%sgid expected %lu found %lu" : "%sgid (%lu, %lu", tab, (u_long)s->st_gid, (u_long)p->fts_statp->st_gid); if (uflag) { - if (lchown(p->fts_accpath, -1, s->st_gid)) + if (lchown(p->fts_accpath, (uid_t)-1, s->st_gid)) printf(", not modified: %s%s\n", strerror(errno), flavor == F_FREEBSD9 ? "" : ")"); else - printf(", modified%s\n", + printf(", modified%s%s\n", + was_unlinked ? " by unlink" : "", flavor == F_FREEBSD9 ? "" : ")"); } else @@ -258,8 +266,8 @@ typeerr: LABEL; tab = "\t"; } if (s->flags & F_MODE && - s->st_mode != (p->fts_statp->st_mode & MBITS)) { - if (lflag) { + (was_unlinked || s->st_mode != (p->fts_statp->st_mode & MBITS))) { + if (lflag && !was_unlinked) { mode_t tmode, mode; tmode = s->st_mode; @@ -287,7 +295,8 @@ typeerr: LABEL; strerror(errno), flavor == F_FREEBSD9 ? "" : ")"); else - printf(", modified%s\n", + printf(", modified%s%s\n", + was_unlinked ? " by unlink" : "", flavor == F_FREEBSD9 ? "" : ")"); } else @@ -567,7 +576,7 @@ const char * rlink(const char *name) { static char lbuf[MAXPATHLEN]; - int len; + ssize_t len; if ((len = readlink(name, lbuf, sizeof(lbuf) - 1)) == -1) mtree_err("%s: %s", name, strerror(errno)); diff --git a/contrib/mtree/crc.c b/contrib/mtree/crc.c index 4eac66e5b995..69b30b206439 100644 --- a/contrib/mtree/crc.c +++ b/contrib/mtree/crc.c @@ -1,4 +1,4 @@ -/* $NetBSD: crc.c,v 1.9 2012/10/05 00:40:51 christos Exp $ */ +/* $NetBSD: crc.c,v 1.11 2024/12/05 17:17:43 christos Exp $ */ /*- * Copyright (c) 1991, 1993 @@ -41,7 +41,7 @@ #if 0 static char sccsid[] = "@(#)crc.c 8.1 (Berkeley) 6/17/93"; #else -__RCSID("$NetBSD: crc.c,v 1.9 2012/10/05 00:40:51 christos Exp $"); +__RCSID("$NetBSD: crc.c,v 1.11 2024/12/05 17:17:43 christos Exp $"); #endif #endif /* not lint */ @@ -53,7 +53,7 @@ __RCSID("$NetBSD: crc.c,v 1.9 2012/10/05 00:40:51 christos Exp $"); #include "extern.h" -static const u_int32_t crctab[] = { +static const uint32_t crctab[] = { 0x0, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, @@ -114,15 +114,15 @@ static const u_int32_t crctab[] = { * locations to store the crc and the number of bytes read. It returns 0 on * success and 1 on failure. Errno is set on failure. */ -u_int32_t crc_total = ~0; /* The crc over a number of files. */ +uint32_t crc_total = ~0u; /* The crc over a number of files. */ int -crc(int fd, u_int32_t *cval, u_int32_t *clen) +crc(int fd, uint32_t *cval, uint32_t *clen) { u_char *p; - int nr; - u_int32_t thecrc, len; - u_int32_t crctot; + ssize_t nr; + uint32_t thecrc, len; + uint32_t crctot; u_char buf[16 * 1024]; #define COMPUTE(var, ch) (var) = (var) << 8 ^ crctab[(var) >> 24 ^ (ch)] @@ -132,12 +132,12 @@ crc(int fd, u_int32_t *cval, u_int32_t *clen) crctot = ~crc_total; while ((nr = read(fd, buf, sizeof(buf))) > 0) if (sflag) { - for (len += nr, p = buf; nr--; ++p) { + for (len += (uint32_t)nr, p = buf; nr--; ++p) { COMPUTE(thecrc, *p); COMPUTE(crctot, *p); } } else { - for (len += nr, p = buf; nr--; ++p) + for (len += (uint32_t)nr, p = buf; nr--; ++p) COMPUTE(thecrc, *p); } if (nr < 0) diff --git a/contrib/mtree/create.c b/contrib/mtree/create.c index 7a09a1cc3951..e23004851f39 100644 --- a/contrib/mtree/create.c +++ b/contrib/mtree/create.c @@ -1,4 +1,4 @@ -/* $NetBSD: create.c,v 1.73 2014/04/24 17:22:41 christos Exp $ */ +/* $NetBSD: create.c,v 1.79 2024/12/05 17:17:43 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.73 2014/04/24 17:22:41 christos Exp $"); +__RCSID("$NetBSD: create.c,v 1.79 2024/12/05 17:17:43 christos Exp $"); #endif #endif /* not lint */ @@ -84,13 +84,6 @@ static uid_t uid; static mode_t mode; static u_long flags; -#ifdef __FreeBSD__ -#define FTS_CONST const -#else -#define FTS_CONST -#endif - -static int dcmp(const FTSENT *FTS_CONST *, const FTSENT *FTS_CONST *); static void output(FILE *, int, int *, const char *, ...) __printflike(4, 5); static int statd(FILE *, FTS *, FTSENT *, uid_t *, gid_t *, mode_t *, @@ -180,15 +173,59 @@ cwalk(FILE *fp) mtree_err("%s checksum: %u", fullpath, crc_total); } +static void +dosum(FILE *fp, int indent, FTSENT *p, int *offset, int flag, + char * (*func)(const char *, char *), const char *key) +{ + char *digestbuf; + + if ((keys & flag) == 0) + return; + + digestbuf = (*func)(p->fts_accpath, NULL); + if (digestbuf != NULL) { + output(fp, indent, offset, "%s=%s", key, digestbuf); + free(digestbuf); + return; + } + + if (qflag) { + warn("%s: %s failed", p->fts_path, key); + return; + } + + mtree_err("%s: %s failed: %s", p->fts_path, key, strerror(errno)); +} + +static char * +crcFile(const char *fname, char *dummy __unused) +{ + char *ptr; + uint32_t val, len; + int fd, e; + + if ((fd = open(fname, O_RDONLY)) == -1) + goto out; + + e = crc(fd, &val, &len); + close(fd); + if (e) + goto out; + + if (asprintf(&ptr, "%u", val) < 0) + goto out; + + return ptr; +out: + mtree_err("%s: %s", fname, strerror(errno)); + return NULL; +} + static void statf(FILE *fp, int indent, FTSENT *p) { - u_int32_t len, val; - int fd, offset; + int offset; const char *name = NULL; -#if !defined(NO_MD5) || !defined(NO_RMD160) || !defined(NO_SHA1) || !defined(NO_SHA2) - char *digestbuf; -#endif offset = fprintf(fp, "%*s%s%s", indent, "", S_ISDIR(p->fts_statp->st_mode) ? "" : " ", vispath(p->fts_name)); @@ -241,65 +278,25 @@ statf(FILE *fp, int indent, FTSENT *p) output(fp, indent, &offset, "time=%jd.%09ld", (intmax_t)p->fts_statp->st_mtime, (long)0); #endif - if (keys & F_CKSUM && S_ISREG(p->fts_statp->st_mode)) { - if ((fd = open(p->fts_accpath, O_RDONLY, 0)) < 0 || - crc(fd, &val, &len)) - mtree_err("%s: %s", p->fts_accpath, strerror(errno)); - close(fd); - output(fp, indent, &offset, "cksum=%lu", (long)val); - } + if (S_ISREG(p->fts_statp->st_mode)) { + dosum(fp, indent, p, &offset, F_CKSUM, crcFile, "cksum"); #ifndef NO_MD5 - if (keys & F_MD5 && S_ISREG(p->fts_statp->st_mode)) { - if ((digestbuf = MD5File(p->fts_accpath, NULL)) == NULL) - mtree_err("%s: MD5File failed: %s", p->fts_accpath, - strerror(errno)); - output(fp, indent, &offset, "%s=%s", MD5KEY, digestbuf); - free(digestbuf); - } + dosum(fp, indent, p, &offset, F_MD5, MD5File, MD5KEY); #endif /* ! NO_MD5 */ #ifndef NO_RMD160 - if (keys & F_RMD160 && S_ISREG(p->fts_statp->st_mode)) { - if ((digestbuf = RMD160File(p->fts_accpath, NULL)) == NULL) - mtree_err("%s: RMD160File failed: %s", p->fts_accpath, - strerror(errno)); - output(fp, indent, &offset, "%s=%s", RMD160KEY, digestbuf); - free(digestbuf); - } + dosum(fp, indent, p, &offset, F_RMD160, RMD160File, RMD160KEY); #endif /* ! NO_RMD160 */ #ifndef NO_SHA1 - if (keys & F_SHA1 && S_ISREG(p->fts_statp->st_mode)) { - if ((digestbuf = SHA1File(p->fts_accpath, NULL)) == NULL) - mtree_err("%s: SHA1File failed: %s", p->fts_accpath, - strerror(errno)); - output(fp, indent, &offset, "%s=%s", SHA1KEY, digestbuf); - free(digestbuf); - } + dosum(fp, indent, p, &offset, F_SHA1, SHA1File, SHA1KEY); #endif /* ! NO_SHA1 */ #ifndef NO_SHA2 - if (keys & F_SHA256 && S_ISREG(p->fts_statp->st_mode)) { - if ((digestbuf = SHA256_File(p->fts_accpath, NULL)) == NULL) - mtree_err("%s: SHA256_File failed: %s", p->fts_accpath, - strerror(errno)); - output(fp, indent, &offset, "%s=%s", SHA256KEY, digestbuf); - free(digestbuf); - } + dosum(fp, indent, p, &offset, F_SHA256, SHA256_File, SHA256KEY); #ifdef SHA384_BLOCK_LENGTH - if (keys & F_SHA384 && S_ISREG(p->fts_statp->st_mode)) { - if ((digestbuf = SHA384_File(p->fts_accpath, NULL)) == NULL) - mtree_err("%s: SHA384_File failed: %s", p->fts_accpath, - strerror(errno)); - output(fp, indent, &offset, "%s=%s", SHA384KEY, digestbuf); - free(digestbuf); - } + dosum(fp, indent, p, &offset, F_SHA384, SHA384_File, SHA384KEY); #endif - if (keys & F_SHA512 && S_ISREG(p->fts_statp->st_mode)) { - if ((digestbuf = SHA512_File(p->fts_accpath, NULL)) == NULL) - mtree_err("%s: SHA512_File failed: %s", p->fts_accpath, - strerror(errno)); - output(fp, indent, &offset, "%s=%s", SHA512KEY, digestbuf); - free(digestbuf); - } + dosum(fp, indent, p, &offset, F_SHA512, SHA512_File, SHA512KEY); #endif /* ! NO_SHA2 */ + } if (keys & F_SLINK && (p->fts_info == FTS_SL || p->fts_info == FTS_SLNONE)) output(fp, indent, &offset, "link=%s", @@ -440,27 +437,6 @@ statd(FILE *fp, FTS *t, FTSENT *parent, uid_t *puid, gid_t *pgid, mode_t *pmode, return (0); } -/* - * dcmp -- - * used as a comparison function passed to fts_open() to control - * the order in which fts_read() returns results. We make - * directories sort after non-directories, but otherwise sort in - * strcmp() order. - * - * Keep this in sync with nodecmp() in spec.c. - */ -static int -dcmp(const FTSENT *FTS_CONST *a, const FTSENT *FTS_CONST *b) -{ - - if (S_ISDIR((*a)->fts_statp->st_mode)) { - if (!S_ISDIR((*b)->fts_statp->st_mode)) - return (1); - } else if (S_ISDIR((*b)->fts_statp->st_mode)) - return (-1); - return (strcmp((*a)->fts_name, (*b)->fts_name)); -} - void output(FILE *fp, int indent, int *offset, const char *fmt, ...) { diff --git a/contrib/mtree/extern.h b/contrib/mtree/extern.h index 091cf8f84460..7b58dd4a4d20 100644 --- a/contrib/mtree/extern.h +++ b/contrib/mtree/extern.h @@ -1,4 +1,4 @@ -/* $NetBSD: extern.h,v 1.39 2014/04/24 17:22:41 christos Exp $ */ +/* $NetBSD: extern.h,v 1.41 2024/12/05 17:17:43 christos Exp $ */ /*- * Copyright (c) 1991, 1993 @@ -49,6 +49,12 @@ #include <netdb.h> #endif +#if defined(__FreeBSD__) && !defined(HAVE_NBTOOL_CONFIG_H) +#define FTS_CONST const +#else +#define FTS_CONST +#endif + #ifndef MAXHOSTNAMELEN #define MAXHOSTNAMELEN 256 #endif @@ -62,8 +68,9 @@ enum flavor { void addtag(slist_t *, char *); int check_excludes(const char *, const char *); int compare(NODE *, FTSENT *); -int crc(int, u_int32_t *, u_int32_t *); +int crc(int, uint32_t *, uint32_t *); void cwalk(FILE *); +int dcmp(const FTSENT *FTS_CONST *, const FTSENT *FTS_CONST *); void dump_nodes(FILE *, const char *, NODE *, int); void init_excludes(void); int matchtags(NODE *); @@ -83,7 +90,7 @@ extern int bflag, dflag, eflag, iflag, jflag, lflag, mflag, extern int mtree_Mflag, mtree_Sflag, mtree_Wflag; extern size_t mtree_lineno; extern enum flavor flavor; -extern u_int32_t crc_total; +extern uint32_t crc_total; extern int ftsoptions, keys; extern char fullpath[]; extern slist_t includetags, excludetags; diff --git a/contrib/mtree/misc.c b/contrib/mtree/misc.c index b99f1ce1f708..b5bd9f4e06c6 100644 --- a/contrib/mtree/misc.c +++ b/contrib/mtree/misc.c @@ -1,4 +1,4 @@ -/* $NetBSD: misc.c,v 1.34 2012/12/20 19:09:25 christos Exp $ */ +/* $NetBSD: misc.c,v 1.35 2024/12/05 17:17:43 christos Exp $ */ /*- * Copyright (c) 1991, 1993 @@ -37,7 +37,7 @@ #include <sys/cdefs.h> #if defined(__RCSID) && !defined(lint) -__RCSID("$NetBSD: misc.c,v 1.34 2012/12/20 19:09:25 christos Exp $"); +__RCSID("$NetBSD: misc.c,v 1.35 2024/12/05 17:17:43 christos Exp $"); #endif /* not lint */ #include <sys/types.h> @@ -111,7 +111,7 @@ slist_t excludetags, includetags; int keys = KEYDEFAULT; -int keycompare(const void *, const void *); +static int keycompare(const void *, const void *); u_int parsekey(const char *name, int *needvaluep) @@ -153,7 +153,7 @@ parsetype(const char *name) return (k->val); } -int +static int keycompare(const void *a, const void *b) { @@ -198,7 +198,7 @@ void parsetags(slist_t *list, char *args) { char *p, *e; - int len; + size_t len; if (args == NULL) { addtag(list, NULL); diff --git a/contrib/mtree/mtree.8 b/contrib/mtree/mtree.8 index 53bb21f711bf..99e3199de943 100644 --- a/contrib/mtree/mtree.8 +++ b/contrib/mtree/mtree.8 @@ -1,4 +1,4 @@ -.\" $NetBSD: mtree.8,v 1.69 2013/02/03 19:16:06 christos Exp $ +.\" $NetBSD: mtree.8,v 1.78 2023/12/02 13:26:09 christos Exp $ .\" .\" Copyright (c) 1989, 1990, 1993 .\" The Regents of the University of California. All rights reserved. @@ -56,7 +56,7 @@ .\" .\" @(#)mtree.8 8.2 (Berkeley) 12/11/93 .\" -.Dd February 3, 2013 +.Dd December 2, 2023 .Dt MTREE 8 .Os .Sh NAME @@ -93,9 +93,11 @@ characteristics do not match the specification, or which are missing from either the file hierarchy or the specification. .Pp The options are as follows: -.Bl -tag -width Xxxexcludexfilexx +.Bl -tag -width Fl +. .It Fl b Suppress blank lines before entering and after exiting directories. +. .It Fl C Convert a specification into a format that's easier to parse with various tools. @@ -105,8 +107,7 @@ from the file given by In the output, each file or directory is represented using a single line (which might be very long). The full path name -(beginning with -.Dq \&./ ) +.Pq beginning with Ql \&./ is always printed as the first field; .Fl K , .Fl k , @@ -120,19 +121,25 @@ can be used to control which files are printed; and the .Fl S option can be used to sort the output. +. .It Fl c Print a specification for the file hierarchy originating at -the current working directory (or the directory provided by -.Fl p Ar path ) +the current working directory +.Po or the directory provided by +.Fl p Ar path +.Pc to the standard output. The output is in a style using relative path names. +. .It Fl D As per .Fl C , except that the path name is always printed as the last field instead of the first. +. .It Fl d Ignore everything except directory type files. +. .It Fl E Ar tags Add the comma separated tags to the .Dq exclusion @@ -141,9 +148,11 @@ Non-directories with tags which are in the exclusion list are not printed with .Fl C and .Fl D . +. .It Fl e Don't complain about files that are in the file hierarchy, but not in the specification. +. .It Fl F Ar flavor Set the compatibility flavor of the .Nm @@ -151,22 +160,23 @@ utility. The .Ar flavor can be one of -.Sy mtree , -.Sy freebsd9 , +.Cm mtree , +.Cm freebsd9 , or -.Sy netbsd6 . +.Cm netbsd6 . The default is -.Sy mtree . +.Cm mtree . The -.Sy freebsd9 +.Cm freebsd9 and -.Sy netbsd6 -flavors attempt to preserve output compatiblity and command line option +.Cm netbsd6 +flavors attempt to preserve output compatibility and command line option backward compatibility with .Fx 9.0 and .Nx 6.0 respectively. +. .It Fl f Ar spec Read the specification from .Ar file , @@ -178,10 +188,18 @@ The specifications will be sorted like output generated using .Fl c . The output format in this case is somewhat reminiscent of .Xr comm 1 , -having "in first spec only", "in second spec only", and "different" -columns, prefixed by zero, one and two TAB characters respectively. -Each entry in the "different" column occupies two lines, one from each -specification. +having +.Dq in first spec only , +.Dq in second spec only , +and +.Dq different +columns, prefixed by zero, one and two +.Tn TAB +characters respectively. +Each entry in the +.Dq different +column occupies two lines, one from each specification. +. .It Fl I Ar tags Add the comma separated tags to the .Dq inclusion @@ -191,14 +209,22 @@ Non-directories with tags which are in the inclusion list are printed with and .Fl D . If no inclusion list is provided, the default is to display all files. +. .It Fl i -If specified, set the schg and/or sappnd flags. +If specified, set the +.Ql schg +and/or +.Ql sappnd +flags. +. .It Fl j Indent the output 4 spaces each time a directory level is descended when creating a specification with the .Fl c option. -This does not affect either the /set statements or the comment before each +This does not affect either the +.Ql /set +statements or the comment before each directory. It does however affect the comment before the close of each directory. This is the equivalent of the @@ -207,26 +233,31 @@ option in the .Fx version of .Nm . +. .It Fl K Ar keywords Add the specified (whitespace or comma separated) keywords to the current set of keywords. If .Ql all is specified, add all of the other keywords. +. .It Fl k Ar keywords Use the .Sy type keyword plus the specified (whitespace or comma separated) -keywords instead of the current set of keywords. +.Ar keywords +instead of the current set of keywords. If .Ql all is specified, use all of the other keywords. If the .Sy type keyword is not desired, suppress it with -.Fl R Ar type . +.Fl R Cm type . +. .It Fl L Follow all symbolic links in the file hierarchy. +. .It Fl l Do .Dq loose @@ -235,7 +266,7 @@ will match less stringent ones. For example, a file marked mode 0444 will pass a check for mode 0644. .Dq Loose -checks apply only to read, write and execute permissions -- in +checks apply only to read, write and execute permissions \(em in particular, if other bits like the sticky bit or suid/sgid bits are set either in the specification or the file, exact checking will be performed. @@ -244,17 +275,25 @@ This option may not be set at the same time as the or .Fl u option. +. .It Fl M Permit merging of specification entries with different types, with the last entry taking precedence. +. .It Fl m -If the schg and/or sappnd flags are specified, reset these flags. -Note that this is only possible with securelevel less than 1 (i.e., -in single user mode or while the system is running in insecure -mode). +If the +.Ql schg +and/or +.Ql sappnd +flags are specified, reset these flags. +Note that this is only possible with securelevel less than 1 +.Po +i.e., in single user mode or while the system is running in insecure mode +.Pc . See .Xr init 8 for information on security levels. +. .It Fl n Do not emit pathname comments when creating a specification. Normally @@ -262,6 +301,7 @@ a comment is emitted before each directory and before the close of that directory when using the .Fl c option. +. .It Fl N Ar dbdir Use the user database text file .Pa master.passwd @@ -274,31 +314,42 @@ rather than using the results from the system's and .Xr getgrnam 3 (and related) library calls. +. .It Fl O Ar onlypaths Only include files included in this list of pathnames. +. .It Fl P Don't follow symbolic links in the file hierarchy, instead consider the symbolic link itself in any comparisons. This is the default. +. .It Fl p Ar path Use the file hierarchy rooted in .Ar path , instead of the current directory. +. .It Fl q Quiet mode. Do not complain when a .Dq missing directory cannot be created because it already exists. This occurs when the directory is a symbolic link. +. .It Fl R Ar keywords Remove the specified (whitespace or comma separated) keywords from the current set of keywords. If .Ql all is specified, remove all of the other keywords. +. .It Fl r Remove any files in the file hierarchy that are not described in the specification. +Repeating the flag more than once will attempt to reset all the +file flags via +.Xr lchflags 2 +before attempting to remove the file in case the file was immutable. +. .It Fl S When reading a specification into an internal data structure, sort the entries. @@ -320,19 +371,23 @@ By default, if the .Fl S option is not used, entries within the same directory are collected together (separated from entries for other directories), but not sorted. +. .It Fl s Ar seed Display a single checksum to the standard error output that represents all of the files for which the keyword .Sy cksum was specified. The checksum is seeded with the specified value. +. .It Fl t Modify the modified time of existing files, the device type of devices, and symbolic link targets, to match the specification. +. .It Fl U Same as .Fl u except that a mismatch is not considered to be an error if it was corrected. +. .It Fl u Modify the owner, group, permissions, and flags of existing files, the device type of devices, and symbolic link targets, @@ -350,6 +405,7 @@ is given, these flags will be reset. Exit with a status of 0 on success, 2 if the file hierarchy did not match the specification, and 1 if any other error occurred. +. .It Fl W Don't attempt to set various file attributes such as the ownership, mode, flags, or time @@ -358,6 +414,7 @@ This option will be most useful when used in conjunction with .Fl U or .Fl u . +. .It Fl X Ar exclude-file The specified file contains .Xr fnmatch 3 @@ -370,11 +427,14 @@ the starting directory); otherwise, it will be matched against basenames only. Comments are permitted in the -.Ar exclude-list +.Ar exclude-file file. +. .It Fl x Don't descend below mount points in the file hierarchy. +. .El +. .Pp Specifications are mostly composed of .Dq keywords , @@ -384,7 +444,8 @@ No keywords have default values, and if a keyword has no value set, no checks based on it are performed. .Pp Currently supported keywords are as follows: -.Bl -tag -width sha384digestxx +. +.Bl -tag -width Sy .It Sy cksum The checksum of the file using the default algorithm specified by the @@ -420,6 +481,7 @@ format.) .It Ar number Opaque number (as stored on the file system). .El +. .Pp The following values for .Ar format @@ -614,9 +676,24 @@ they match. .Nm uses .Xr strsvis 3 -(in VIS_CSTYLE format) to encode path names containing +(in +.Dv VIS_OCTAL +format) to encode path names containing non-printable characters. Whitespace characters are encoded as +.Ql \e040 +(space), +.Ql \e011 +(tab), and +.Ql \e012 +(new line). +When flavor +.Sy netbsd6 +is selected, +.Xr strsvis 3 +(in +.Dv VIS_CSTYLE +format) is used and whitespace characters are encoded as .Ql \es (space), .Ql \et @@ -678,7 +755,7 @@ The utility exits with a status of 0 on success, 1 if any error occurred, and 2 if the file hierarchy did not match the specification. .Sh FILES -.Bl -tag -width /etc/mtree -compact +.Bl -tag -width Pa -compact .It Pa /etc/mtree system specification directory .El diff --git a/contrib/mtree/mtree.c b/contrib/mtree/mtree.c index 8b4cb9494d53..28f09fa32210 100644 --- a/contrib/mtree/mtree.c +++ b/contrib/mtree/mtree.c @@ -1,4 +1,4 @@ -/* $NetBSD: mtree.c,v 1.49 2014/04/24 17:22:41 christos Exp $ */ +/* $NetBSD: mtree.c,v 1.51 2024/12/05 17:17:15 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.49 2014/04/24 17:22:41 christos Exp $"); +__RCSID("$NetBSD: mtree.c,v 1.51 2024/12/05 17:17:15 christos Exp $"); #endif #endif /* not lint */ @@ -195,7 +195,7 @@ main(int argc, char **argv) qflag = 1; break; case 'r': - rflag = 1; + rflag++; break; case 'R': while ((p = strsep(&optarg, " \t,")) != NULL) @@ -204,7 +204,7 @@ main(int argc, char **argv) break; case 's': sflag = 1; - crc_total = ~strtol(optarg, &p, 0); + crc_total = (uint32_t)~strtol(optarg, &p, 0); if (*p) mtree_err("illegal seed value -- %s", optarg); break; diff --git a/contrib/mtree/spec.c b/contrib/mtree/spec.c index 6fbe6f534560..25bface34bd0 100644 --- a/contrib/mtree/spec.c +++ b/contrib/mtree/spec.c @@ -1,4 +1,4 @@ -/* $NetBSD: spec.c,v 1.89 2014/04/24 17:22:41 christos Exp $ */ +/* $NetBSD: spec.c,v 1.92 2024/12/05 17:17:43 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.89 2014/04/24 17:22:41 christos Exp $"); +__RCSID("$NetBSD: spec.c,v 1.92 2024/12/05 17:17:43 christos Exp $"); #endif #endif /* not lint */ @@ -224,10 +224,14 @@ noparent: mtree_err("no parent node"); */ if (strcmp(centry->name, ".") == 0 && centry->type == 0) centry->type = F_DIR; - if (strcmp(centry->name, ".") != 0 || - centry->type != F_DIR) + if (strcmp(centry->name, ".") != 0) mtree_err( - "root node must be the directory `.'"); + "root node must be the directory `.'," + " found `%s'", centry->name); + if (centry->type != F_DIR) + mtree_err( + "root node must type %#x != %#x", + F_DIR, centry->type); last = root = centry; root->parent = root; } else if (pathparent != NULL) { @@ -539,7 +543,8 @@ replacenode(NODE *cur, NODE *new) static void set(char *t, NODE *ip) { *** 120 LINES SKIPPED ***help
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?6945f7b7.35924.1cf63169>
