diff options
-rw-r--r-- | usr.sbin/mtree/Makefile | 4 | ||||
-rw-r--r-- | usr.sbin/mtree/compare.c | 22 | ||||
-rw-r--r-- | usr.sbin/mtree/create.c | 40 | ||||
-rw-r--r-- | usr.sbin/mtree/extern.h | 4 | ||||
-rw-r--r-- | usr.sbin/mtree/misc.c | 1 | ||||
-rw-r--r-- | usr.sbin/mtree/mtree.8 | 11 | ||||
-rw-r--r-- | usr.sbin/mtree/mtree.h | 5 | ||||
-rw-r--r-- | usr.sbin/mtree/spec.c | 10 | ||||
-rw-r--r-- | usr.sbin/mtree/verify.c | 6 |
9 files changed, 93 insertions, 10 deletions
diff --git a/usr.sbin/mtree/Makefile b/usr.sbin/mtree/Makefile index 6a5d615..a85aa4c 100644 --- a/usr.sbin/mtree/Makefile +++ b/usr.sbin/mtree/Makefile @@ -2,9 +2,9 @@ # $FreeBSD$ PROG= mtree -SRCS= compare.c crc.c create.c misc.c mtree.c spec.c verify.c +SRCS= compare.c crc.c create.c misc.c mtree.c spec.c verify.c stat_flags.c MAN8= mtree.8 -.PATH: ${.CURDIR}/../../usr.bin/cksum +.PATH: ${.CURDIR}/../../usr.bin/cksum ${.CURDIR}/../../bin/ls .if !defined(WORLD) DPADD+= ${LIBMD} diff --git a/usr.sbin/mtree/compare.c b/usr.sbin/mtree/compare.c index d48db41..9f2db9f 100644 --- a/usr.sbin/mtree/compare.c +++ b/usr.sbin/mtree/compare.c @@ -216,6 +216,28 @@ typeerr: LABEL; tab = "\t"; } } + /* + * XXX + * since chflags(2) will reset file times, the utimes() above + * may have been useless! oh well, we'd rather have correct + * flags, rather than times? + */ + if ((s->flags & F_FLAGS) && s->st_flags != p->fts_statp->st_flags) { + LABEL; + (void)printf("%sflags (\"%s\" is not ", tab, + flags_to_string(s->st_flags, "none")); + (void)printf("\"%s\"", + flags_to_string(p->fts_statp->st_flags, "none")); + if (uflag) + if (chflags(p->fts_accpath, s->st_flags)) + (void)printf(", not modified: %s)\n", + strerror(errno)); + else + (void)printf(", modified)\n"); + else + (void)printf(")\n"); + tab = "\t"; + } #ifdef MD5 if (s->flags & F_MD5) { char *new_digest, buf[33]; diff --git a/usr.sbin/mtree/create.c b/usr.sbin/mtree/create.c index 6075099..72049f4 100644 --- a/usr.sbin/mtree/create.c +++ b/usr.sbin/mtree/create.c @@ -77,10 +77,12 @@ extern int lineno; static gid_t gid; static uid_t uid; static mode_t mode; +static u_long flags; static int dsort __P((const FTSENT **, const FTSENT **)); static void output __P((int, int *, const char *, ...)); -static int statd __P((FTS *, FTSENT *, uid_t *, gid_t *, mode_t *)); +static int statd __P((FTS *, FTSENT *, uid_t *, gid_t *, mode_t *, + u_long *)); static void statf __P((int, FTSENT *)); void @@ -111,7 +113,7 @@ cwalk() (void)printf("\n"); if (!nflag) (void)printf("# %s\n", p->fts_path); - statd(t, p, &uid, &gid, &mode); + statd(t, p, &uid, &gid, &mode, &flags); statf(indent, p); break; case FTS_DP: @@ -250,31 +252,40 @@ statf(indent, p) if (keys & F_SLINK && (p->fts_info == FTS_SL || p->fts_info == FTS_SLNONE)) output(indent, &offset, "link=%s", rlink(p->fts_accpath)); + if (keys & F_FLAGS && p->fts_statp->st_flags != flags) + output(indent, &offset, "flags=%s", + flags_to_string(p->fts_statp->st_flags, "none")); (void)putchar('\n'); } #define MAXGID 5000 #define MAXUID 5000 #define MAXMODE MBITS + 1 +#define MAXFLAGS 256 +#define MAXS 16 static int -statd(t, parent, puid, pgid, pmode) +statd(t, parent, puid, pgid, pmode, pflags) FTS *t; FTSENT *parent; uid_t *puid; gid_t *pgid; mode_t *pmode; + u_long *pflags; { register FTSENT *p; register gid_t sgid; register uid_t suid; register mode_t smode; + register u_long sflags; struct group *gr; struct passwd *pw; gid_t savegid = *pgid; uid_t saveuid = *puid; mode_t savemode = *pmode; - u_short maxgid, maxuid, maxmode, g[MAXGID], u[MAXUID], m[MAXMODE]; + u_long saveflags = 0; + u_short maxgid, maxuid, maxmode, maxflags; + u_short g[MAXGID], u[MAXUID], m[MAXMODE], f[MAXFLAGS]; static int first = 1; if ((p = fts_children(t, 0)) == NULL) { @@ -286,8 +297,9 @@ statd(t, parent, puid, pgid, pmode) bzero(g, sizeof(g)); bzero(u, sizeof(u)); bzero(m, sizeof(m)); + bzero(f, sizeof(f)); - maxuid = maxgid = maxmode = 0; + maxuid = maxgid = maxmode = maxflags = 0; for (; p; p = p->fts_link) { if (!dflag || (dflag && S_ISDIR(p->fts_statp->st_mode))) { smode = p->fts_statp->st_mode & MBITS; @@ -305,6 +317,20 @@ statd(t, parent, puid, pgid, pmode) saveuid = suid; maxuid = u[suid]; } + + /* + * XXX + * note that the below will break when file flags + * are extended beyond the first 4 bytes of each + * half word of the flags + */ +#define FLAGS2IDX(f) ((f & 0xf) | ((f >> 12) & 0xf0)) + sflags = p->fts_statp->st_flags; + if (FLAGS2IDX(sflags) < MAXFLAGS && + ++f[FLAGS2IDX(sflags)] > maxflags) { + saveflags = sflags; + maxflags = u[FLAGS2IDX(sflags)]; + } } } /* @@ -344,10 +370,14 @@ statd(t, parent, puid, pgid, pmode) (void)printf(" mode=%#o", savemode); if (keys & F_NLINK) (void)printf(" nlink=1"); + if (keys & F_FLAGS && saveflags) + (void)printf(" flags=%s", + flags_to_string(saveflags, "none")); (void)printf("\n"); *puid = saveuid; *pgid = savegid; *pmode = savemode; + *pflags = saveflags; } return (0); } diff --git a/usr.sbin/mtree/extern.h b/usr.sbin/mtree/extern.h index f3b6230..c9a00b2 100644 --- a/usr.sbin/mtree/extern.h +++ b/usr.sbin/mtree/extern.h @@ -31,11 +31,15 @@ * SUCH DAMAGE. * * @(#)extern.h 8.1 (Berkeley) 6/6/93 + * $FreeBSD$ */ int compare __P((char *, NODE *, FTSENT *)); int crc __P((int, u_long *, u_long *)); void cwalk __P((void)); +char *flags_to_string __P((u_long, char *)); +int string_to_flags __P((char **, u_long *, u_long *)); + char *inotype __P((u_int)); u_int parsekey __P((char *, int *)); char *rlink __P((char *)); diff --git a/usr.sbin/mtree/misc.c b/usr.sbin/mtree/misc.c index bc94b32..ea413dd 100644 --- a/usr.sbin/mtree/misc.c +++ b/usr.sbin/mtree/misc.c @@ -60,6 +60,7 @@ typedef struct _key { /* NB: the following table must be sorted lexically. */ static KEY keylist[] = { {"cksum", F_CKSUM, NEEDVALUE}, + {"flags", F_FLAGS, NEEDVALUE}, {"gid", F_GID, NEEDVALUE}, {"gname", F_GNAME, NEEDVALUE}, {"ignore", F_IGN, 0}, diff --git a/usr.sbin/mtree/mtree.8 b/usr.sbin/mtree/mtree.8 index fc3ad4a..d01438f 100644 --- a/usr.sbin/mtree/mtree.8 +++ b/usr.sbin/mtree/mtree.8 @@ -131,6 +131,12 @@ The checksum of the file using the default algorithm specified by the .Xr cksum 1 utility. +.It Cm flags +The file flags as a symbolic name. See +.Xr chflags 1 +for information on these names. If no flags are to be set the string +.Dq none +may be used to override the current default. .It Cm ignore Ignore any file hierarchy below this file. .It Cm gid @@ -188,6 +194,7 @@ socket .El .Pp The default set of keywords are +.Cm flags , .Cm gid , .Cm mode , .Cm nlink , @@ -282,6 +289,7 @@ distribution. system specification directory .El .Sh SEE ALSO +.Xr chflags 1 , .Xr chgrp 1 , .Xr chmod 1 , .Xr cksum 1 , @@ -309,3 +317,6 @@ digests were added in .Fx 4.0 , as new attacks have demonstrated weaknesses in .Tn MD5 . +Support for file flags was added in +.Fx 4.0 , +and mostly comes from NetBSD. diff --git a/usr.sbin/mtree/mtree.h b/usr.sbin/mtree/mtree.h index 7ffb798..9d8af5d 100644 --- a/usr.sbin/mtree/mtree.h +++ b/usr.sbin/mtree/mtree.h @@ -31,13 +31,14 @@ * SUCH DAMAGE. * * @(#)mtree.h 8.1 (Berkeley) 6/6/93 + * $FreeBSD$ */ #include <string.h> #include <stdlib.h> #define KEYDEFAULT \ - (F_GID | F_MODE | F_NLINK | F_SIZE | F_SLINK | F_TIME | F_UID) + (F_GID | F_MODE | F_NLINK | F_SIZE | F_SLINK | F_TIME | F_UID | F_FLAGS) #define MISMATCHEXIT 2 @@ -55,6 +56,7 @@ typedef struct _node { gid_t st_gid; /* gid */ #define MBITS (S_ISUID|S_ISGID|S_ISTXT|S_IRWXU|S_IRWXG|S_IRWXO) mode_t st_mode; /* mode */ + u_long st_flags; /* flags */ nlink_t st_nlink; /* link count */ #define F_CKSUM 0x0001 /* check sum */ @@ -77,6 +79,7 @@ typedef struct _node { /* not change */ #define F_SHA1 0x20000 /* SHA-1 digest */ #define F_RMD160 0x40000 /* RIPEMD160 digest */ +#define F_FLAGS 0x80000 /* file flags */ u_int flags; /* items set */ #define F_BLOCK 0x001 /* block special */ diff --git a/usr.sbin/mtree/spec.c b/usr.sbin/mtree/spec.c index 4a23073..3fa9e7c 100644 --- a/usr.sbin/mtree/spec.c +++ b/usr.sbin/mtree/spec.c @@ -172,10 +172,10 @@ noparent: errx(1, "line %d: no parent node", lineno); static void set(t, ip) char *t; - register NODE *ip; + NODE *ip; { register int type; - register char *kw, *val = NULL; + char *kw, *val = NULL; struct group *gr; struct passwd *pw; mode_t *m; @@ -211,6 +211,12 @@ set(t, ip) errx(1, "strdup"); } break; + case F_FLAGS: + if (strcmp("none", val) == 0) + ip->st_flags = 0; + else if (string_to_flags(&val, &ip->st_flags,NULL) != 0) + errx(1, "line %d: invalid flag %s",lineno, val); + break; case F_GID: ip->st_gid = strtoul(val, &ep, 10); if (*ep) diff --git a/usr.sbin/mtree/verify.c b/usr.sbin/mtree/verify.c index 9b165cf..9422e5e 100644 --- a/usr.sbin/mtree/verify.c +++ b/usr.sbin/mtree/verify.c @@ -201,10 +201,16 @@ miss(p, tail) if (chown(path, p->st_uid, p->st_gid)) { (void)printf("%s: user/group/mode not modified: %s\n", path, strerror(errno)); + (void)printf("%s: warning: file mode %snot set\n", path, + (p->flags & F_FLAGS) ? "and file flags " : ""); continue; } if (chmod(path, p->st_mode)) (void)printf("%s: permissions not set: %s\n", path, strerror(errno)); + if ((p->flags & F_FLAGS) && p->st_flags && + chflags(path, p->st_flags)) + (void)printf("%s: file flags not set: %s\n", + path, strerror(errno)); } } |