Import latest mtree from NetBSD
Merge commit 'f600477feb4ae61a75f61949eb600caff4aeea8c' MFC after: 1 week Discussed with: brooks
This commit is contained in:
+24
-15
@@ -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
|
* Copyright (c) 1989, 1993
|
||||||
@@ -38,7 +38,7 @@
|
|||||||
#if 0
|
#if 0
|
||||||
static char sccsid[] = "@(#)compare.c 8.1 (Berkeley) 6/6/93";
|
static char sccsid[] = "@(#)compare.c 8.1 (Berkeley) 6/6/93";
|
||||||
#else
|
#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
|
||||||
#endif /* not lint */
|
#endif /* not lint */
|
||||||
|
|
||||||
@@ -135,8 +135,9 @@ do { \
|
|||||||
int
|
int
|
||||||
compare(NODE *s, FTSENT *p)
|
compare(NODE *s, FTSENT *p)
|
||||||
{
|
{
|
||||||
u_int32_t len, val, flags;
|
uint32_t len, val, flags;
|
||||||
int fd, label;
|
int fd, label;
|
||||||
|
bool was_unlinked;
|
||||||
const char *cp, *tab;
|
const char *cp, *tab;
|
||||||
#if !defined(NO_MD5) || !defined(NO_RMD160) || !defined(NO_SHA1) || !defined(NO_SHA2)
|
#if !defined(NO_MD5) || !defined(NO_RMD160) || !defined(NO_SHA1) || !defined(NO_SHA2)
|
||||||
char *digestbuf;
|
char *digestbuf;
|
||||||
@@ -144,6 +145,7 @@ compare(NODE *s, FTSENT *p)
|
|||||||
|
|
||||||
tab = NULL;
|
tab = NULL;
|
||||||
label = 0;
|
label = 0;
|
||||||
|
was_unlinked = false;
|
||||||
switch(s->type) {
|
switch(s->type) {
|
||||||
case F_BLOCK:
|
case F_BLOCK:
|
||||||
if (!S_ISBLK(p->fts_statp->st_mode))
|
if (!S_ISBLK(p->fts_statp->st_mode))
|
||||||
@@ -210,47 +212,53 @@ typeerr: LABEL;
|
|||||||
s->st_mode | nodetoino(s->type),
|
s->st_mode | nodetoino(s->type),
|
||||||
s->st_rdev) == -1) ||
|
s->st_rdev) == -1) ||
|
||||||
(lchown(p->fts_accpath, p->fts_statp->st_uid,
|
(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",
|
printf(", not modified: %s%s\n",
|
||||||
strerror(errno),
|
strerror(errno),
|
||||||
flavor == F_FREEBSD9 ? "" : ")");
|
flavor == F_FREEBSD9 ? "" : ")");
|
||||||
else
|
} else {
|
||||||
printf(", modified%s\n",
|
printf(", modified%s\n",
|
||||||
flavor == F_FREEBSD9 ? "" : ")");
|
flavor == F_FREEBSD9 ? "" : ")");
|
||||||
|
was_unlinked = true;
|
||||||
|
}
|
||||||
} else
|
} else
|
||||||
printf(")\n");
|
printf(")\n");
|
||||||
tab = "\t";
|
tab = "\t";
|
||||||
}
|
}
|
||||||
/* Set the uid/gid first, then set the mode. */
|
/* 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;
|
LABEL;
|
||||||
printf(flavor == F_FREEBSD9 ?
|
printf(flavor == F_FREEBSD9 ?
|
||||||
"%suser expected %lu found %lu" : "%suser (%lu, %lu",
|
"%suser expected %lu found %lu" : "%suser (%lu, %lu",
|
||||||
tab, (u_long)s->st_uid, (u_long)p->fts_statp->st_uid);
|
tab, (u_long)s->st_uid, (u_long)p->fts_statp->st_uid);
|
||||||
if (uflag) {
|
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",
|
printf(", not modified: %s%s\n",
|
||||||
strerror(errno),
|
strerror(errno),
|
||||||
flavor == F_FREEBSD9 ? "" : ")");
|
flavor == F_FREEBSD9 ? "" : ")");
|
||||||
else
|
else
|
||||||
printf(", modified%s\n",
|
printf(", modified%s%s\n",
|
||||||
|
was_unlinked ? " by unlink" : "",
|
||||||
flavor == F_FREEBSD9 ? "" : ")");
|
flavor == F_FREEBSD9 ? "" : ")");
|
||||||
} else
|
} else
|
||||||
printf(")\n");
|
printf(")\n");
|
||||||
tab = "\t";
|
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;
|
LABEL;
|
||||||
printf(flavor == F_FREEBSD9 ?
|
printf(flavor == F_FREEBSD9 ?
|
||||||
"%sgid expected %lu found %lu" : "%sgid (%lu, %lu",
|
"%sgid expected %lu found %lu" : "%sgid (%lu, %lu",
|
||||||
tab, (u_long)s->st_gid, (u_long)p->fts_statp->st_gid);
|
tab, (u_long)s->st_gid, (u_long)p->fts_statp->st_gid);
|
||||||
if (uflag) {
|
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",
|
printf(", not modified: %s%s\n",
|
||||||
strerror(errno),
|
strerror(errno),
|
||||||
flavor == F_FREEBSD9 ? "" : ")");
|
flavor == F_FREEBSD9 ? "" : ")");
|
||||||
else
|
else
|
||||||
printf(", modified%s\n",
|
printf(", modified%s%s\n",
|
||||||
|
was_unlinked ? " by unlink" : "",
|
||||||
flavor == F_FREEBSD9 ? "" : ")");
|
flavor == F_FREEBSD9 ? "" : ")");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -258,8 +266,8 @@ typeerr: LABEL;
|
|||||||
tab = "\t";
|
tab = "\t";
|
||||||
}
|
}
|
||||||
if (s->flags & F_MODE &&
|
if (s->flags & F_MODE &&
|
||||||
s->st_mode != (p->fts_statp->st_mode & MBITS)) {
|
(was_unlinked || s->st_mode != (p->fts_statp->st_mode & MBITS))) {
|
||||||
if (lflag) {
|
if (lflag && !was_unlinked) {
|
||||||
mode_t tmode, mode;
|
mode_t tmode, mode;
|
||||||
|
|
||||||
tmode = s->st_mode;
|
tmode = s->st_mode;
|
||||||
@@ -287,7 +295,8 @@ typeerr: LABEL;
|
|||||||
strerror(errno),
|
strerror(errno),
|
||||||
flavor == F_FREEBSD9 ? "" : ")");
|
flavor == F_FREEBSD9 ? "" : ")");
|
||||||
else
|
else
|
||||||
printf(", modified%s\n",
|
printf(", modified%s%s\n",
|
||||||
|
was_unlinked ? " by unlink" : "",
|
||||||
flavor == F_FREEBSD9 ? "" : ")");
|
flavor == F_FREEBSD9 ? "" : ")");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -567,7 +576,7 @@ const char *
|
|||||||
rlink(const char *name)
|
rlink(const char *name)
|
||||||
{
|
{
|
||||||
static char lbuf[MAXPATHLEN];
|
static char lbuf[MAXPATHLEN];
|
||||||
int len;
|
ssize_t len;
|
||||||
|
|
||||||
if ((len = readlink(name, lbuf, sizeof(lbuf) - 1)) == -1)
|
if ((len = readlink(name, lbuf, sizeof(lbuf) - 1)) == -1)
|
||||||
mtree_err("%s: %s", name, strerror(errno));
|
mtree_err("%s: %s", name, strerror(errno));
|
||||||
|
|||||||
+10
-10
@@ -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
|
* Copyright (c) 1991, 1993
|
||||||
@@ -41,7 +41,7 @@
|
|||||||
#if 0
|
#if 0
|
||||||
static char sccsid[] = "@(#)crc.c 8.1 (Berkeley) 6/17/93";
|
static char sccsid[] = "@(#)crc.c 8.1 (Berkeley) 6/17/93";
|
||||||
#else
|
#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
|
||||||
#endif /* not lint */
|
#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"
|
#include "extern.h"
|
||||||
|
|
||||||
static const u_int32_t crctab[] = {
|
static const uint32_t crctab[] = {
|
||||||
0x0,
|
0x0,
|
||||||
0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b,
|
0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b,
|
||||||
0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6,
|
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
|
* 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.
|
* 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
|
int
|
||||||
crc(int fd, u_int32_t *cval, u_int32_t *clen)
|
crc(int fd, uint32_t *cval, uint32_t *clen)
|
||||||
{
|
{
|
||||||
u_char *p;
|
u_char *p;
|
||||||
int nr;
|
ssize_t nr;
|
||||||
u_int32_t thecrc, len;
|
uint32_t thecrc, len;
|
||||||
u_int32_t crctot;
|
uint32_t crctot;
|
||||||
u_char buf[16 * 1024];
|
u_char buf[16 * 1024];
|
||||||
|
|
||||||
#define COMPUTE(var, ch) (var) = (var) << 8 ^ crctab[(var) >> 24 ^ (ch)]
|
#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;
|
crctot = ~crc_total;
|
||||||
while ((nr = read(fd, buf, sizeof(buf))) > 0)
|
while ((nr = read(fd, buf, sizeof(buf))) > 0)
|
||||||
if (sflag) {
|
if (sflag) {
|
||||||
for (len += nr, p = buf; nr--; ++p) {
|
for (len += (uint32_t)nr, p = buf; nr--; ++p) {
|
||||||
COMPUTE(thecrc, *p);
|
COMPUTE(thecrc, *p);
|
||||||
COMPUTE(crctot, *p);
|
COMPUTE(crctot, *p);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (len += nr, p = buf; nr--; ++p)
|
for (len += (uint32_t)nr, p = buf; nr--; ++p)
|
||||||
COMPUTE(thecrc, *p);
|
COMPUTE(thecrc, *p);
|
||||||
}
|
}
|
||||||
if (nr < 0)
|
if (nr < 0)
|
||||||
|
|||||||
+60
-84
@@ -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
|
* Copyright (c) 1989, 1993
|
||||||
@@ -38,7 +38,7 @@
|
|||||||
#if 0
|
#if 0
|
||||||
static char sccsid[] = "@(#)create.c 8.1 (Berkeley) 6/6/93";
|
static char sccsid[] = "@(#)create.c 8.1 (Berkeley) 6/6/93";
|
||||||
#else
|
#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
|
||||||
#endif /* not lint */
|
#endif /* not lint */
|
||||||
|
|
||||||
@@ -84,13 +84,6 @@ static uid_t uid;
|
|||||||
static mode_t mode;
|
static mode_t mode;
|
||||||
static u_long flags;
|
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 *, ...)
|
static void output(FILE *, int, int *, const char *, ...)
|
||||||
__printflike(4, 5);
|
__printflike(4, 5);
|
||||||
static int statd(FILE *, FTS *, FTSENT *, uid_t *, gid_t *, mode_t *,
|
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);
|
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
|
static void
|
||||||
statf(FILE *fp, int indent, FTSENT *p)
|
statf(FILE *fp, int indent, FTSENT *p)
|
||||||
{
|
{
|
||||||
u_int32_t len, val;
|
int offset;
|
||||||
int fd, offset;
|
|
||||||
const char *name = NULL;
|
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, "",
|
offset = fprintf(fp, "%*s%s%s", indent, "",
|
||||||
S_ISDIR(p->fts_statp->st_mode) ? "" : " ", vispath(p->fts_name));
|
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",
|
output(fp, indent, &offset, "time=%jd.%09ld",
|
||||||
(intmax_t)p->fts_statp->st_mtime, (long)0);
|
(intmax_t)p->fts_statp->st_mtime, (long)0);
|
||||||
#endif
|
#endif
|
||||||
if (keys & F_CKSUM && S_ISREG(p->fts_statp->st_mode)) {
|
if (S_ISREG(p->fts_statp->st_mode)) {
|
||||||
if ((fd = open(p->fts_accpath, O_RDONLY, 0)) < 0 ||
|
dosum(fp, indent, p, &offset, F_CKSUM, crcFile, "cksum");
|
||||||
crc(fd, &val, &len))
|
|
||||||
mtree_err("%s: %s", p->fts_accpath, strerror(errno));
|
|
||||||
close(fd);
|
|
||||||
output(fp, indent, &offset, "cksum=%lu", (long)val);
|
|
||||||
}
|
|
||||||
#ifndef NO_MD5
|
#ifndef NO_MD5
|
||||||
if (keys & F_MD5 && S_ISREG(p->fts_statp->st_mode)) {
|
dosum(fp, indent, p, &offset, F_MD5, MD5File, MD5KEY);
|
||||||
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);
|
|
||||||
}
|
|
||||||
#endif /* ! NO_MD5 */
|
#endif /* ! NO_MD5 */
|
||||||
#ifndef NO_RMD160
|
#ifndef NO_RMD160
|
||||||
if (keys & F_RMD160 && S_ISREG(p->fts_statp->st_mode)) {
|
dosum(fp, indent, p, &offset, F_RMD160, RMD160File, RMD160KEY);
|
||||||
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);
|
|
||||||
}
|
|
||||||
#endif /* ! NO_RMD160 */
|
#endif /* ! NO_RMD160 */
|
||||||
#ifndef NO_SHA1
|
#ifndef NO_SHA1
|
||||||
if (keys & F_SHA1 && S_ISREG(p->fts_statp->st_mode)) {
|
dosum(fp, indent, p, &offset, F_SHA1, SHA1File, SHA1KEY);
|
||||||
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);
|
|
||||||
}
|
|
||||||
#endif /* ! NO_SHA1 */
|
#endif /* ! NO_SHA1 */
|
||||||
#ifndef NO_SHA2
|
#ifndef NO_SHA2
|
||||||
if (keys & F_SHA256 && S_ISREG(p->fts_statp->st_mode)) {
|
dosum(fp, indent, p, &offset, F_SHA256, SHA256_File, SHA256KEY);
|
||||||
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);
|
|
||||||
}
|
|
||||||
#ifdef SHA384_BLOCK_LENGTH
|
#ifdef SHA384_BLOCK_LENGTH
|
||||||
if (keys & F_SHA384 && S_ISREG(p->fts_statp->st_mode)) {
|
dosum(fp, indent, p, &offset, F_SHA384, SHA384_File, SHA384KEY);
|
||||||
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);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
if (keys & F_SHA512 && S_ISREG(p->fts_statp->st_mode)) {
|
dosum(fp, indent, p, &offset, F_SHA512, SHA512_File, SHA512KEY);
|
||||||
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);
|
|
||||||
}
|
|
||||||
#endif /* ! NO_SHA2 */
|
#endif /* ! NO_SHA2 */
|
||||||
|
}
|
||||||
if (keys & F_SLINK &&
|
if (keys & F_SLINK &&
|
||||||
(p->fts_info == FTS_SL || p->fts_info == FTS_SLNONE))
|
(p->fts_info == FTS_SL || p->fts_info == FTS_SLNONE))
|
||||||
output(fp, indent, &offset, "link=%s",
|
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);
|
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
|
void
|
||||||
output(FILE *fp, int indent, int *offset, const char *fmt, ...)
|
output(FILE *fp, int indent, int *offset, const char *fmt, ...)
|
||||||
{
|
{
|
||||||
|
|||||||
+10
-3
@@ -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
|
* Copyright (c) 1991, 1993
|
||||||
@@ -49,6 +49,12 @@
|
|||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(__FreeBSD__) && !defined(HAVE_NBTOOL_CONFIG_H)
|
||||||
|
#define FTS_CONST const
|
||||||
|
#else
|
||||||
|
#define FTS_CONST
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef MAXHOSTNAMELEN
|
#ifndef MAXHOSTNAMELEN
|
||||||
#define MAXHOSTNAMELEN 256
|
#define MAXHOSTNAMELEN 256
|
||||||
#endif
|
#endif
|
||||||
@@ -62,8 +68,9 @@ enum flavor {
|
|||||||
void addtag(slist_t *, char *);
|
void addtag(slist_t *, char *);
|
||||||
int check_excludes(const char *, const char *);
|
int check_excludes(const char *, const char *);
|
||||||
int compare(NODE *, FTSENT *);
|
int compare(NODE *, FTSENT *);
|
||||||
int crc(int, u_int32_t *, u_int32_t *);
|
int crc(int, uint32_t *, uint32_t *);
|
||||||
void cwalk(FILE *);
|
void cwalk(FILE *);
|
||||||
|
int dcmp(const FTSENT *FTS_CONST *, const FTSENT *FTS_CONST *);
|
||||||
void dump_nodes(FILE *, const char *, NODE *, int);
|
void dump_nodes(FILE *, const char *, NODE *, int);
|
||||||
void init_excludes(void);
|
void init_excludes(void);
|
||||||
int matchtags(NODE *);
|
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 int mtree_Mflag, mtree_Sflag, mtree_Wflag;
|
||||||
extern size_t mtree_lineno;
|
extern size_t mtree_lineno;
|
||||||
extern enum flavor flavor;
|
extern enum flavor flavor;
|
||||||
extern u_int32_t crc_total;
|
extern uint32_t crc_total;
|
||||||
extern int ftsoptions, keys;
|
extern int ftsoptions, keys;
|
||||||
extern char fullpath[];
|
extern char fullpath[];
|
||||||
extern slist_t includetags, excludetags;
|
extern slist_t includetags, excludetags;
|
||||||
|
|||||||
@@ -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
|
* Copyright (c) 1991, 1993
|
||||||
@@ -37,7 +37,7 @@
|
|||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
#if defined(__RCSID) && !defined(lint)
|
#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 */
|
#endif /* not lint */
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
@@ -111,7 +111,7 @@ slist_t excludetags, includetags;
|
|||||||
int keys = KEYDEFAULT;
|
int keys = KEYDEFAULT;
|
||||||
|
|
||||||
|
|
||||||
int keycompare(const void *, const void *);
|
static int keycompare(const void *, const void *);
|
||||||
|
|
||||||
u_int
|
u_int
|
||||||
parsekey(const char *name, int *needvaluep)
|
parsekey(const char *name, int *needvaluep)
|
||||||
@@ -153,7 +153,7 @@ parsetype(const char *name)
|
|||||||
return (k->val);
|
return (k->val);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
static int
|
||||||
keycompare(const void *a, const void *b)
|
keycompare(const void *a, const void *b)
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -198,7 +198,7 @@ void
|
|||||||
parsetags(slist_t *list, char *args)
|
parsetags(slist_t *list, char *args)
|
||||||
{
|
{
|
||||||
char *p, *e;
|
char *p, *e;
|
||||||
int len;
|
size_t len;
|
||||||
|
|
||||||
if (args == NULL) {
|
if (args == NULL) {
|
||||||
addtag(list, NULL);
|
addtag(list, NULL);
|
||||||
|
|||||||
+108
-31
@@ -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
|
.\" Copyright (c) 1989, 1990, 1993
|
||||||
.\" The Regents of the University of California. All rights reserved.
|
.\" The Regents of the University of California. All rights reserved.
|
||||||
@@ -56,7 +56,7 @@
|
|||||||
.\"
|
.\"
|
||||||
.\" @(#)mtree.8 8.2 (Berkeley) 12/11/93
|
.\" @(#)mtree.8 8.2 (Berkeley) 12/11/93
|
||||||
.\"
|
.\"
|
||||||
.Dd February 3, 2013
|
.Dd December 2, 2023
|
||||||
.Dt MTREE 8
|
.Dt MTREE 8
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@@ -93,9 +93,11 @@ characteristics do not match the specification, or which are
|
|||||||
missing from either the file hierarchy or the specification.
|
missing from either the file hierarchy or the specification.
|
||||||
.Pp
|
.Pp
|
||||||
The options are as follows:
|
The options are as follows:
|
||||||
.Bl -tag -width Xxxexcludexfilexx
|
.Bl -tag -width Fl
|
||||||
|
.
|
||||||
.It Fl b
|
.It Fl b
|
||||||
Suppress blank lines before entering and after exiting directories.
|
Suppress blank lines before entering and after exiting directories.
|
||||||
|
.
|
||||||
.It Fl C
|
.It Fl C
|
||||||
Convert a specification into
|
Convert a specification into
|
||||||
a format that's easier to parse with various tools.
|
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
|
In the output, each file or directory is represented using a single line
|
||||||
(which might be very long).
|
(which might be very long).
|
||||||
The full path name
|
The full path name
|
||||||
(beginning with
|
.Pq beginning with Ql \&./
|
||||||
.Dq \&./ )
|
|
||||||
is always printed as the first field;
|
is always printed as the first field;
|
||||||
.Fl K ,
|
.Fl K ,
|
||||||
.Fl k ,
|
.Fl k ,
|
||||||
@@ -120,19 +121,25 @@ can be used to control which files are printed;
|
|||||||
and the
|
and the
|
||||||
.Fl S
|
.Fl S
|
||||||
option can be used to sort the output.
|
option can be used to sort the output.
|
||||||
|
.
|
||||||
.It Fl c
|
.It Fl c
|
||||||
Print a specification for the file hierarchy originating at
|
Print a specification for the file hierarchy originating at
|
||||||
the current working directory (or the directory provided by
|
the current working directory
|
||||||
.Fl p Ar path )
|
.Po or the directory provided by
|
||||||
|
.Fl p Ar path
|
||||||
|
.Pc
|
||||||
to the standard output.
|
to the standard output.
|
||||||
The output is in a style using relative path names.
|
The output is in a style using relative path names.
|
||||||
|
.
|
||||||
.It Fl D
|
.It Fl D
|
||||||
As per
|
As per
|
||||||
.Fl C ,
|
.Fl C ,
|
||||||
except that the path name is always printed as the last field instead of
|
except that the path name is always printed as the last field instead of
|
||||||
the first.
|
the first.
|
||||||
|
.
|
||||||
.It Fl d
|
.It Fl d
|
||||||
Ignore everything except directory type files.
|
Ignore everything except directory type files.
|
||||||
|
.
|
||||||
.It Fl E Ar tags
|
.It Fl E Ar tags
|
||||||
Add the comma separated tags to the
|
Add the comma separated tags to the
|
||||||
.Dq exclusion
|
.Dq exclusion
|
||||||
@@ -141,9 +148,11 @@ Non-directories with tags which are in the exclusion list are not printed with
|
|||||||
.Fl C
|
.Fl C
|
||||||
and
|
and
|
||||||
.Fl D .
|
.Fl D .
|
||||||
|
.
|
||||||
.It Fl e
|
.It Fl e
|
||||||
Don't complain about files that are in the file hierarchy, but not in the
|
Don't complain about files that are in the file hierarchy, but not in the
|
||||||
specification.
|
specification.
|
||||||
|
.
|
||||||
.It Fl F Ar flavor
|
.It Fl F Ar flavor
|
||||||
Set the compatibility flavor of the
|
Set the compatibility flavor of the
|
||||||
.Nm
|
.Nm
|
||||||
@@ -151,22 +160,23 @@ utility.
|
|||||||
The
|
The
|
||||||
.Ar flavor
|
.Ar flavor
|
||||||
can be one of
|
can be one of
|
||||||
.Sy mtree ,
|
.Cm mtree ,
|
||||||
.Sy freebsd9 ,
|
.Cm freebsd9 ,
|
||||||
or
|
or
|
||||||
.Sy netbsd6 .
|
.Cm netbsd6 .
|
||||||
The default is
|
The default is
|
||||||
.Sy mtree .
|
.Cm mtree .
|
||||||
The
|
The
|
||||||
.Sy freebsd9
|
.Cm freebsd9
|
||||||
and
|
and
|
||||||
.Sy netbsd6
|
.Cm netbsd6
|
||||||
flavors attempt to preserve output compatiblity and command line option
|
flavors attempt to preserve output compatibility and command line option
|
||||||
backward compatibility with
|
backward compatibility with
|
||||||
.Fx 9.0
|
.Fx 9.0
|
||||||
and
|
and
|
||||||
.Nx 6.0
|
.Nx 6.0
|
||||||
respectively.
|
respectively.
|
||||||
|
.
|
||||||
.It Fl f Ar spec
|
.It Fl f Ar spec
|
||||||
Read the specification from
|
Read the specification from
|
||||||
.Ar file ,
|
.Ar file ,
|
||||||
@@ -178,10 +188,18 @@ The specifications will be sorted like output generated using
|
|||||||
.Fl c .
|
.Fl c .
|
||||||
The output format in this case is somewhat reminiscent of
|
The output format in this case is somewhat reminiscent of
|
||||||
.Xr comm 1 ,
|
.Xr comm 1 ,
|
||||||
having "in first spec only", "in second spec only", and "different"
|
having
|
||||||
columns, prefixed by zero, one and two TAB characters respectively.
|
.Dq in first spec only ,
|
||||||
Each entry in the "different" column occupies two lines, one from each
|
.Dq in second spec only ,
|
||||||
specification.
|
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
|
.It Fl I Ar tags
|
||||||
Add the comma separated tags to the
|
Add the comma separated tags to the
|
||||||
.Dq inclusion
|
.Dq inclusion
|
||||||
@@ -191,14 +209,22 @@ Non-directories with tags which are in the inclusion list are printed with
|
|||||||
and
|
and
|
||||||
.Fl D .
|
.Fl D .
|
||||||
If no inclusion list is provided, the default is to display all files.
|
If no inclusion list is provided, the default is to display all files.
|
||||||
|
.
|
||||||
.It Fl i
|
.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
|
.It Fl j
|
||||||
Indent the output 4 spaces each time a directory level is descended when
|
Indent the output 4 spaces each time a directory level is descended when
|
||||||
creating a specification with the
|
creating a specification with the
|
||||||
.Fl c
|
.Fl c
|
||||||
option.
|
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.
|
directory.
|
||||||
It does however affect the comment before the close of each directory.
|
It does however affect the comment before the close of each directory.
|
||||||
This is the equivalent of the
|
This is the equivalent of the
|
||||||
@@ -207,26 +233,31 @@ option in the
|
|||||||
.Fx
|
.Fx
|
||||||
version of
|
version of
|
||||||
.Nm .
|
.Nm .
|
||||||
|
.
|
||||||
.It Fl K Ar keywords
|
.It Fl K Ar keywords
|
||||||
Add the specified (whitespace or comma separated) keywords to the current
|
Add the specified (whitespace or comma separated) keywords to the current
|
||||||
set of keywords.
|
set of keywords.
|
||||||
If
|
If
|
||||||
.Ql all
|
.Ql all
|
||||||
is specified, add all of the other keywords.
|
is specified, add all of the other keywords.
|
||||||
|
.
|
||||||
.It Fl k Ar keywords
|
.It Fl k Ar keywords
|
||||||
Use the
|
Use the
|
||||||
.Sy type
|
.Sy type
|
||||||
keyword plus the specified (whitespace or comma separated)
|
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
|
If
|
||||||
.Ql all
|
.Ql all
|
||||||
is specified, use all of the other keywords.
|
is specified, use all of the other keywords.
|
||||||
If the
|
If the
|
||||||
.Sy type
|
.Sy type
|
||||||
keyword is not desired, suppress it with
|
keyword is not desired, suppress it with
|
||||||
.Fl R Ar type .
|
.Fl R Cm type .
|
||||||
|
.
|
||||||
.It Fl L
|
.It Fl L
|
||||||
Follow all symbolic links in the file hierarchy.
|
Follow all symbolic links in the file hierarchy.
|
||||||
|
.
|
||||||
.It Fl l
|
.It Fl l
|
||||||
Do
|
Do
|
||||||
.Dq loose
|
.Dq loose
|
||||||
@@ -235,7 +266,7 @@ will match less stringent ones.
|
|||||||
For example, a file marked mode 0444
|
For example, a file marked mode 0444
|
||||||
will pass a check for mode 0644.
|
will pass a check for mode 0644.
|
||||||
.Dq Loose
|
.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
|
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
|
set either in the specification or the file, exact checking will be
|
||||||
performed.
|
performed.
|
||||||
@@ -244,17 +275,25 @@ This option may not be set at the same time as the
|
|||||||
or
|
or
|
||||||
.Fl u
|
.Fl u
|
||||||
option.
|
option.
|
||||||
|
.
|
||||||
.It Fl M
|
.It Fl M
|
||||||
Permit merging of specification entries with different types,
|
Permit merging of specification entries with different types,
|
||||||
with the last entry taking precedence.
|
with the last entry taking precedence.
|
||||||
|
.
|
||||||
.It Fl m
|
.It Fl m
|
||||||
If the schg and/or sappnd flags are specified, reset these flags.
|
If the
|
||||||
Note that this is only possible with securelevel less than 1 (i.e.,
|
.Ql schg
|
||||||
in single user mode or while the system is running in insecure
|
and/or
|
||||||
mode).
|
.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
|
See
|
||||||
.Xr init 8
|
.Xr init 8
|
||||||
for information on security levels.
|
for information on security levels.
|
||||||
|
.
|
||||||
.It Fl n
|
.It Fl n
|
||||||
Do not emit pathname comments when creating a specification.
|
Do not emit pathname comments when creating a specification.
|
||||||
Normally
|
Normally
|
||||||
@@ -262,6 +301,7 @@ a comment is emitted before each directory and before the close of that
|
|||||||
directory when using the
|
directory when using the
|
||||||
.Fl c
|
.Fl c
|
||||||
option.
|
option.
|
||||||
|
.
|
||||||
.It Fl N Ar dbdir
|
.It Fl N Ar dbdir
|
||||||
Use the user database text file
|
Use the user database text file
|
||||||
.Pa master.passwd
|
.Pa master.passwd
|
||||||
@@ -274,31 +314,42 @@ rather than using the results from the system's
|
|||||||
and
|
and
|
||||||
.Xr getgrnam 3
|
.Xr getgrnam 3
|
||||||
(and related) library calls.
|
(and related) library calls.
|
||||||
|
.
|
||||||
.It Fl O Ar onlypaths
|
.It Fl O Ar onlypaths
|
||||||
Only include files included in this list of pathnames.
|
Only include files included in this list of pathnames.
|
||||||
|
.
|
||||||
.It Fl P
|
.It Fl P
|
||||||
Don't follow symbolic links in the file hierarchy, instead consider
|
Don't follow symbolic links in the file hierarchy, instead consider
|
||||||
the symbolic link itself in any comparisons.
|
the symbolic link itself in any comparisons.
|
||||||
This is the default.
|
This is the default.
|
||||||
|
.
|
||||||
.It Fl p Ar path
|
.It Fl p Ar path
|
||||||
Use the file hierarchy rooted in
|
Use the file hierarchy rooted in
|
||||||
.Ar path ,
|
.Ar path ,
|
||||||
instead of the current directory.
|
instead of the current directory.
|
||||||
|
.
|
||||||
.It Fl q
|
.It Fl q
|
||||||
Quiet mode.
|
Quiet mode.
|
||||||
Do not complain when a
|
Do not complain when a
|
||||||
.Dq missing
|
.Dq missing
|
||||||
directory cannot be created because it already exists.
|
directory cannot be created because it already exists.
|
||||||
This occurs when the directory is a symbolic link.
|
This occurs when the directory is a symbolic link.
|
||||||
|
.
|
||||||
.It Fl R Ar keywords
|
.It Fl R Ar keywords
|
||||||
Remove the specified (whitespace or comma separated) keywords from the current
|
Remove the specified (whitespace or comma separated) keywords from the current
|
||||||
set of keywords.
|
set of keywords.
|
||||||
If
|
If
|
||||||
.Ql all
|
.Ql all
|
||||||
is specified, remove all of the other keywords.
|
is specified, remove all of the other keywords.
|
||||||
|
.
|
||||||
.It Fl r
|
.It Fl r
|
||||||
Remove any files in the file hierarchy that are not described in the
|
Remove any files in the file hierarchy that are not described in the
|
||||||
specification.
|
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
|
.It Fl S
|
||||||
When reading a specification into an internal data structure,
|
When reading a specification into an internal data structure,
|
||||||
sort the entries.
|
sort the entries.
|
||||||
@@ -320,19 +371,23 @@ By default, if the
|
|||||||
.Fl S
|
.Fl S
|
||||||
option is not used, entries within the same directory are collected
|
option is not used, entries within the same directory are collected
|
||||||
together (separated from entries for other directories), but not sorted.
|
together (separated from entries for other directories), but not sorted.
|
||||||
|
.
|
||||||
.It Fl s Ar seed
|
.It Fl s Ar seed
|
||||||
Display a single checksum to the standard error output that represents all
|
Display a single checksum to the standard error output that represents all
|
||||||
of the files for which the keyword
|
of the files for which the keyword
|
||||||
.Sy cksum
|
.Sy cksum
|
||||||
was specified.
|
was specified.
|
||||||
The checksum is seeded with the specified value.
|
The checksum is seeded with the specified value.
|
||||||
|
.
|
||||||
.It Fl t
|
.It Fl t
|
||||||
Modify the modified time of existing files, the device type of devices, and
|
Modify the modified time of existing files, the device type of devices, and
|
||||||
symbolic link targets, to match the specification.
|
symbolic link targets, to match the specification.
|
||||||
|
.
|
||||||
.It Fl U
|
.It Fl U
|
||||||
Same as
|
Same as
|
||||||
.Fl u
|
.Fl u
|
||||||
except that a mismatch is not considered to be an error if it was corrected.
|
except that a mismatch is not considered to be an error if it was corrected.
|
||||||
|
.
|
||||||
.It Fl u
|
.It Fl u
|
||||||
Modify the owner, group, permissions, and flags of existing files,
|
Modify the owner, group, permissions, and flags of existing files,
|
||||||
the device type of devices, and symbolic link targets,
|
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,
|
Exit with a status of 0 on success,
|
||||||
2 if the file hierarchy did not match the specification, and
|
2 if the file hierarchy did not match the specification, and
|
||||||
1 if any other error occurred.
|
1 if any other error occurred.
|
||||||
|
.
|
||||||
.It Fl W
|
.It Fl W
|
||||||
Don't attempt to set various file attributes such as the
|
Don't attempt to set various file attributes such as the
|
||||||
ownership, mode, flags, or time
|
ownership, mode, flags, or time
|
||||||
@@ -358,6 +414,7 @@ This option will be most useful when used in conjunction with
|
|||||||
.Fl U
|
.Fl U
|
||||||
or
|
or
|
||||||
.Fl u .
|
.Fl u .
|
||||||
|
.
|
||||||
.It Fl X Ar exclude-file
|
.It Fl X Ar exclude-file
|
||||||
The specified file contains
|
The specified file contains
|
||||||
.Xr fnmatch 3
|
.Xr fnmatch 3
|
||||||
@@ -370,11 +427,14 @@ the starting directory); otherwise,
|
|||||||
it will be matched against basenames only.
|
it will be matched against basenames only.
|
||||||
Comments are permitted in
|
Comments are permitted in
|
||||||
the
|
the
|
||||||
.Ar exclude-list
|
.Ar exclude-file
|
||||||
file.
|
file.
|
||||||
|
.
|
||||||
.It Fl x
|
.It Fl x
|
||||||
Don't descend below mount points in the file hierarchy.
|
Don't descend below mount points in the file hierarchy.
|
||||||
|
.
|
||||||
.El
|
.El
|
||||||
|
.
|
||||||
.Pp
|
.Pp
|
||||||
Specifications are mostly composed of
|
Specifications are mostly composed of
|
||||||
.Dq keywords ,
|
.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.
|
checks based on it are performed.
|
||||||
.Pp
|
.Pp
|
||||||
Currently supported keywords are as follows:
|
Currently supported keywords are as follows:
|
||||||
.Bl -tag -width sha384digestxx
|
.
|
||||||
|
.Bl -tag -width Sy
|
||||||
.It Sy cksum
|
.It Sy cksum
|
||||||
The checksum of the file using the default algorithm specified by
|
The checksum of the file using the default algorithm specified by
|
||||||
the
|
the
|
||||||
@@ -420,6 +481,7 @@ format.)
|
|||||||
.It Ar number
|
.It Ar number
|
||||||
Opaque number (as stored on the file system).
|
Opaque number (as stored on the file system).
|
||||||
.El
|
.El
|
||||||
|
.
|
||||||
.Pp
|
.Pp
|
||||||
The following values for
|
The following values for
|
||||||
.Ar format
|
.Ar format
|
||||||
@@ -614,9 +676,24 @@ they match.
|
|||||||
.Nm
|
.Nm
|
||||||
uses
|
uses
|
||||||
.Xr strsvis 3
|
.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.
|
non-printable characters.
|
||||||
Whitespace characters are encoded as
|
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
|
.Ql \es
|
||||||
(space),
|
(space),
|
||||||
.Ql \et
|
.Ql \et
|
||||||
@@ -678,7 +755,7 @@ The
|
|||||||
utility exits with a status of 0 on success, 1 if any error occurred,
|
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.
|
and 2 if the file hierarchy did not match the specification.
|
||||||
.Sh FILES
|
.Sh FILES
|
||||||
.Bl -tag -width /etc/mtree -compact
|
.Bl -tag -width Pa -compact
|
||||||
.It Pa /etc/mtree
|
.It Pa /etc/mtree
|
||||||
system specification directory
|
system specification directory
|
||||||
.El
|
.El
|
||||||
|
|||||||
@@ -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
|
* Copyright (c) 1989, 1990, 1993
|
||||||
@@ -43,7 +43,7 @@ __COPYRIGHT("@(#) Copyright (c) 1989, 1990, 1993\
|
|||||||
#if 0
|
#if 0
|
||||||
static char sccsid[] = "@(#)mtree.c 8.1 (Berkeley) 6/6/93";
|
static char sccsid[] = "@(#)mtree.c 8.1 (Berkeley) 6/6/93";
|
||||||
#else
|
#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
|
||||||
#endif /* not lint */
|
#endif /* not lint */
|
||||||
|
|
||||||
@@ -195,7 +195,7 @@ main(int argc, char **argv)
|
|||||||
qflag = 1;
|
qflag = 1;
|
||||||
break;
|
break;
|
||||||
case 'r':
|
case 'r':
|
||||||
rflag = 1;
|
rflag++;
|
||||||
break;
|
break;
|
||||||
case 'R':
|
case 'R':
|
||||||
while ((p = strsep(&optarg, " \t,")) != NULL)
|
while ((p = strsep(&optarg, " \t,")) != NULL)
|
||||||
@@ -204,7 +204,7 @@ main(int argc, char **argv)
|
|||||||
break;
|
break;
|
||||||
case 's':
|
case 's':
|
||||||
sflag = 1;
|
sflag = 1;
|
||||||
crc_total = ~strtol(optarg, &p, 0);
|
crc_total = (uint32_t)~strtol(optarg, &p, 0);
|
||||||
if (*p)
|
if (*p)
|
||||||
mtree_err("illegal seed value -- %s", optarg);
|
mtree_err("illegal seed value -- %s", optarg);
|
||||||
break;
|
break;
|
||||||
|
|||||||
+36
-8
@@ -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
|
* Copyright (c) 1989, 1993
|
||||||
@@ -67,7 +67,7 @@
|
|||||||
#if 0
|
#if 0
|
||||||
static char sccsid[] = "@(#)spec.c 8.2 (Berkeley) 4/28/95";
|
static char sccsid[] = "@(#)spec.c 8.2 (Berkeley) 4/28/95";
|
||||||
#else
|
#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
|
||||||
#endif /* not lint */
|
#endif /* not lint */
|
||||||
|
|
||||||
@@ -224,10 +224,14 @@ noparent: mtree_err("no parent node");
|
|||||||
*/
|
*/
|
||||||
if (strcmp(centry->name, ".") == 0 && centry->type == 0)
|
if (strcmp(centry->name, ".") == 0 && centry->type == 0)
|
||||||
centry->type = F_DIR;
|
centry->type = F_DIR;
|
||||||
if (strcmp(centry->name, ".") != 0 ||
|
if (strcmp(centry->name, ".") != 0)
|
||||||
centry->type != F_DIR)
|
|
||||||
mtree_err(
|
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;
|
last = root = centry;
|
||||||
root->parent = root;
|
root->parent = root;
|
||||||
} else if (pathparent != NULL) {
|
} else if (pathparent != NULL) {
|
||||||
@@ -539,7 +543,8 @@ replacenode(NODE *cur, NODE *new)
|
|||||||
static void
|
static void
|
||||||
set(char *t, NODE *ip)
|
set(char *t, NODE *ip)
|
||||||
{
|
{
|
||||||
int type, value, len;
|
int type, value;
|
||||||
|
size_t len;
|
||||||
gid_t gid;
|
gid_t gid;
|
||||||
uid_t uid;
|
uid_t uid;
|
||||||
char *kw, *val, *md, *ep;
|
char *kw, *val, *md, *ep;
|
||||||
@@ -838,7 +843,7 @@ addchild(NODE *pathparent, NODE *centry)
|
|||||||
* directories sort after non-directories, but otherwise sort in
|
* directories sort after non-directories, but otherwise sort in
|
||||||
* strcmp() order.
|
* strcmp() order.
|
||||||
*
|
*
|
||||||
* Keep this in sync with dcmp() in create.c.
|
* Keep this in sync with dcmp() below.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
nodecmp(const NODE *a, const NODE *b)
|
nodecmp(const NODE *a, const NODE *b)
|
||||||
@@ -847,7 +852,30 @@ nodecmp(const NODE *a, const NODE *b)
|
|||||||
if ((a->type & F_DIR) != 0) {
|
if ((a->type & F_DIR) != 0) {
|
||||||
if ((b->type & F_DIR) == 0)
|
if ((b->type & F_DIR) == 0)
|
||||||
return 1;
|
return 1;
|
||||||
} else if ((b->type & F_DIR) != 0)
|
} else if ((b->type & F_DIR) != 0) {
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
return strcmp(a->name, b->name);
|
return strcmp(a->name, b->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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() above.
|
||||||
|
*/
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* $NetBSD: specspec.c,v 1.2 2012/10/05 01:27:29 christos Exp $ */
|
/* $NetBSD: specspec.c,v 1.5 2023/12/02 13:24:00 christos Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2003 Poul-Henning Kamp
|
* Copyright (c) 2003 Poul-Henning Kamp
|
||||||
@@ -31,7 +31,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__RCSID("$NetBSD: specspec.c,v 1.2 2012/10/05 01:27:29 christos Exp $");
|
__RCSID("$NetBSD: specspec.c,v 1.5 2023/12/02 13:24:00 christos Exp $");
|
||||||
|
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
#include <grp.h>
|
#include <grp.h>
|
||||||
|
|||||||
+12
-5
@@ -1,4 +1,4 @@
|
|||||||
/* $NetBSD: verify.c,v 1.44 2013/02/03 19:15:17 christos Exp $ */
|
/* $NetBSD: verify.c,v 1.50 2024/12/11 14:52:26 christos Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 1990, 1993
|
* Copyright (c) 1990, 1993
|
||||||
@@ -38,7 +38,7 @@
|
|||||||
#if 0
|
#if 0
|
||||||
static char sccsid[] = "@(#)verify.c 8.1 (Berkeley) 6/6/93";
|
static char sccsid[] = "@(#)verify.c 8.1 (Berkeley) 6/6/93";
|
||||||
#else
|
#else
|
||||||
__RCSID("$NetBSD: verify.c,v 1.44 2013/02/03 19:15:17 christos Exp $");
|
__RCSID("$NetBSD: verify.c,v 1.50 2024/12/11 14:52:26 christos Exp $");
|
||||||
#endif
|
#endif
|
||||||
#endif /* not lint */
|
#endif /* not lint */
|
||||||
|
|
||||||
@@ -86,7 +86,7 @@ vwalk(void)
|
|||||||
argv[0] = dot;
|
argv[0] = dot;
|
||||||
argv[1] = NULL;
|
argv[1] = NULL;
|
||||||
|
|
||||||
if ((t = fts_open(argv, ftsoptions, NULL)) == NULL)
|
if ((t = fts_open(argv, ftsoptions, dcmp)) == NULL)
|
||||||
mtree_err("fts_open: %s", strerror(errno));
|
mtree_err("fts_open: %s", strerror(errno));
|
||||||
level = root;
|
level = root;
|
||||||
specdepth = rval = 0;
|
specdepth = rval = 0;
|
||||||
@@ -147,8 +147,15 @@ vwalk(void)
|
|||||||
continue;
|
continue;
|
||||||
extra:
|
extra:
|
||||||
if (!eflag && !(dflag && p->fts_info == FTS_SL)) {
|
if (!eflag && !(dflag && p->fts_info == FTS_SL)) {
|
||||||
printf("extra: %s", RP(p));
|
printf(flavor == F_FREEBSD9 ? "%s extra" : "extra: %s",
|
||||||
|
RP(p));
|
||||||
if (rflag) {
|
if (rflag) {
|
||||||
|
#if HAVE_STRUCT_STAT_ST_FLAGS
|
||||||
|
if (rflag > 1 &&
|
||||||
|
lchflags(p->fts_accpath, 0) == -1)
|
||||||
|
printf(" (chflags %s)",
|
||||||
|
strerror(errno));
|
||||||
|
#endif
|
||||||
if ((S_ISDIR(p->fts_statp->st_mode)
|
if ((S_ISDIR(p->fts_statp->st_mode)
|
||||||
? rmdir : unlink)(p->fts_accpath)) {
|
? rmdir : unlink)(p->fts_accpath)) {
|
||||||
printf(", not removed: %s",
|
printf(", not removed: %s",
|
||||||
@@ -174,7 +181,7 @@ miss(NODE *p, char *tail)
|
|||||||
int create;
|
int create;
|
||||||
char *tp;
|
char *tp;
|
||||||
const char *type;
|
const char *type;
|
||||||
u_int32_t flags;
|
u_long flags;
|
||||||
|
|
||||||
for (; p; p = p->next) {
|
for (; p; p = p->next) {
|
||||||
if (p->flags & F_OPT && !(p->flags & F_VISIT))
|
if (p->flags & F_OPT && !(p->flags & F_VISIT))
|
||||||
|
|||||||
Reference in New Issue
Block a user