Added support for file flags, mostly merged from the NetBSD version.
The way is now open to schg and sappnd key files and directories in our tree. There are recommendations in bin/15229. PR: bin/15229 Reviewed by: imp, brian
This commit is contained in:
parent
c6d289b2ad
commit
2d2f34a6b0
@ -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}
|
||||
|
@ -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];
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 *));
|
||||
|
@ -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},
|
||||
|
@ -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.
|
||||
|
@ -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 */
|
||||
|
@ -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)
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user