Module Name: src Committed By: christos Date: Thu Dec 20 16:43:17 UTC 2012
Modified Files: src/usr.sbin/mtree: create.c extern.h mtree.8 mtree.c spec.c Log Message: Implement the "flavor" output discussed in tech-userlevel@, by Brooks Davis To generate a diff of this commit: cvs rdiff -u -r1.67 -r1.68 src/usr.sbin/mtree/create.c cvs rdiff -u -r1.36 -r1.37 src/usr.sbin/mtree/extern.h cvs rdiff -u -r1.64 -r1.65 src/usr.sbin/mtree/mtree.8 cvs rdiff -u -r1.43 -r1.44 src/usr.sbin/mtree/mtree.c cvs rdiff -u -r1.84 -r1.85 src/usr.sbin/mtree/spec.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/usr.sbin/mtree/create.c diff -u src/usr.sbin/mtree/create.c:1.67 src/usr.sbin/mtree/create.c:1.68 --- src/usr.sbin/mtree/create.c:1.67 Fri Dec 14 20:24:40 2012 +++ src/usr.sbin/mtree/create.c Thu Dec 20 11:43:16 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: create.c,v 1.67 2012/12/15 01:24:40 christos Exp $ */ +/* $NetBSD: create.c,v 1.68 2012/12/20 16:43:16 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.67 2012/12/15 01:24:40 christos Exp $"); +__RCSID("$NetBSD: create.c,v 1.68 2012/12/20 16:43:16 christos Exp $"); #endif #endif /* not lint */ @@ -136,18 +136,22 @@ cwalk(void) } switch(p->fts_info) { case FTS_D: - printf("\n"); + if (!bflag) + printf("\n"); if (!nflag) printf("# %s\n", p->fts_path); statd(t, p, &uid, &gid, &mode, &flags); statf(indent, p); break; case FTS_DP: - if (p->fts_level > 0) { + if (p->fts_level > 0) if (!nflag) printf("%*s# %s\n", indent, "", p->fts_path); - printf("%*s..\n\n", indent, ""); + if (p->fts_level > 0 || flavor == F_FREEBSD9) { + printf("%*s..\n", indent, ""); + if (!bflag) + printf("\n"); } break; case FTS_DNR: @@ -186,7 +190,7 @@ statf(int indent, FTSENT *p) else offset += printf("%*s", (INDENTNAMELEN + indent) - offset, ""); - if (!S_ISREG(p->fts_statp->st_mode)) + if (!S_ISREG(p->fts_statp->st_mode) && (flavor == F_NETBSD6 || !dflag)) output(indent, &offset, "type=%s", inotype(p->fts_statp->st_mode)); if (keys & (F_UID | F_UNAME) && p->fts_statp->st_uid != uid) { @@ -212,7 +216,8 @@ statf(int indent, FTSENT *p) (long long)p->fts_statp->st_rdev); if (keys & F_NLINK && p->fts_statp->st_nlink != 1) output(indent, &offset, "nlink=%u", p->fts_statp->st_nlink); - if (keys & F_SIZE && S_ISREG(p->fts_statp->st_mode)) + if (keys & F_SIZE && + (flavor != F_NETBSD6 || S_ISREG(p->fts_statp->st_mode))) output(indent, &offset, "size=%lld", (long long)p->fts_statp->st_size); if (keys & F_TIME) @@ -349,29 +354,32 @@ statd(FTS *t, FTSENT *parent, uid_t *pui maxuid = maxgid = maxmode = maxflags = 0; for (; p; p = p->fts_link) { - smode = p->fts_statp->st_mode & MBITS; - if (smode < MTREE_MAXMODE && ++m[smode] > maxmode) { - savemode = smode; - maxmode = m[smode]; - } - sgid = p->fts_statp->st_gid; - if (sgid < MTREE_MAXGID && ++g[sgid] > maxgid) { - savegid = sgid; - maxgid = g[sgid]; - } - suid = p->fts_statp->st_uid; - if (suid < MTREE_MAXUID && ++u[suid] > maxuid) { - saveuid = suid; - maxuid = u[suid]; - } + if (flavor == F_NETBSD6 || !dflag || + (dflag && S_ISDIR(p->fts_statp->st_mode))) { + smode = p->fts_statp->st_mode & MBITS; + if (smode < MTREE_MAXMODE && ++m[smode] > maxmode) { + savemode = smode; + maxmode = m[smode]; + } + sgid = p->fts_statp->st_gid; + if (sgid < MTREE_MAXGID && ++g[sgid] > maxgid) { + savegid = sgid; + maxgid = g[sgid]; + } + suid = p->fts_statp->st_uid; + if (suid < MTREE_MAXUID && ++u[suid] > maxuid) { + saveuid = suid; + maxuid = u[suid]; + } #if HAVE_STRUCT_STAT_ST_FLAGS - sflags = FLAGS2INDEX(p->fts_statp->st_flags); - if (sflags < MTREE_MAXFLAGS && ++f[sflags] > maxflags) { - saveflags = p->fts_statp->st_flags; - maxflags = f[sflags]; - } + sflags = FLAGS2INDEX(p->fts_statp->st_flags); + if (sflags < MTREE_MAXFLAGS && ++f[sflags] > maxflags) { + saveflags = p->fts_statp->st_flags; + maxflags = f[sflags]; + } #endif + } } /* * If the /set record is the same as the last one we do not need to @@ -384,7 +392,10 @@ statd(FTS *t, FTSENT *parent, uid_t *pui ((keys & F_FLAGS) && (*pflags != saveflags)) || first) { first = 0; - printf("/set type=file"); + if (flavor != F_NETBSD6 && dflag) + printf("/set type=dir"); + else + printf("/set type=file"); if (keys & (F_UID | F_UNAME)) { if (keys & F_UNAME && (name = user_from_uid(saveuid, 1)) != NULL) Index: src/usr.sbin/mtree/extern.h diff -u src/usr.sbin/mtree/extern.h:1.36 src/usr.sbin/mtree/extern.h:1.37 --- src/usr.sbin/mtree/extern.h:1.36 Thu Oct 4 21:26:56 2012 +++ src/usr.sbin/mtree/extern.h Thu Dec 20 11:43:16 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: extern.h,v 1.36 2012/10/05 01:26:56 christos Exp $ */ +/* $NetBSD: extern.h,v 1.37 2012/12/20 16:43:16 christos Exp $ */ /*- * Copyright (c) 1991, 1993 @@ -52,6 +52,12 @@ #define MAXHOSTNAMELEN 256 #endif +enum flavor { + F_MTREE, + F_FREEBSD9, + F_NETBSD6 +}; + void addtag(slist_t *, char *); int check_excludes(const char *, const char *); int compare(NODE *, FTSENT *); @@ -69,10 +75,11 @@ void read_excludes_file(const char *); const char *rlink(const char *); int verify(FILE *); -extern int dflag, eflag, iflag, jflag, lflag, mflag, +extern int bflag, dflag, eflag, iflag, jflag, lflag, mflag, nflag, qflag, rflag, sflag, tflag, uflag; extern int mtree_Mflag, mtree_Sflag, mtree_Wflag; extern size_t mtree_lineno; +extern enum flavor flavor; extern u_int32_t crc_total; extern int ftsoptions, keys; extern char fullpath[]; Index: src/usr.sbin/mtree/mtree.8 diff -u src/usr.sbin/mtree/mtree.8:1.64 src/usr.sbin/mtree/mtree.8:1.65 --- src/usr.sbin/mtree/mtree.8:1.64 Wed Dec 12 10:52:10 2012 +++ src/usr.sbin/mtree/mtree.8 Thu Dec 20 11:43:16 2012 @@ -1,4 +1,4 @@ -.\" $NetBSD: mtree.8,v 1.64 2012/12/12 15:52:10 christos Exp $ +.\" $NetBSD: mtree.8,v 1.65 2012/12/20 16:43:16 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 October 4, 2012 +.Dd December 20, 2012 .Dt MTREE 8 .Os .Sh NAME @@ -64,9 +64,10 @@ .Nd map a directory hierarchy .Sh SYNOPSIS .Nm -.Op Fl CcDdejLlMnPqrStUuWx +.Op Fl bCcDdejLlMnPqrStUuWx .Op Fl i | Fl m .Op Fl E Ar tags +.Op Fl F Ar flavor .Op Fl f Ar spec .Op Fl I Ar tags .Op Fl K Ar keywords @@ -92,6 +93,8 @@ missing from either the file hierarchy o .Pp The options are as follows: .Bl -tag -width Xxxexcludexfilexx +.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. @@ -140,6 +143,29 @@ and .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 compatibilty flavor of the +.Nm +utility. +The +.Ar flavor +can be one of +.Sy mtree , +.Sy freebsd9 , +or +.Sy netbsd6 . +The default is +.Sy mtree . +The +.Sy freebsd9 +and +.Sy netbsd6 +flavors attempt to preserve output compatiblity and command line optio +backward compatibility with +.Fx 9 +and +.Nx 6 +respectively. .It Fl f Ar spec Read the specification from .Ar file , @@ -681,6 +707,35 @@ option can be used in combination with or .Fl u to create directory hierarchies for, for example, distributions. +.Sh COMPATIBILITY +The compatibility shims provided by the +.Fl F +option are incomplete by design. +Known limitations are described below. +.Pp +The +.Sy freebsd9 +flavor retains the default handling of lookup failures for the +.Sy uname +and +.Sy group +keywords by replacing them with appropriate +.Sy uid +and +.Sy gid +keywords rather than failing and reporting an error. +The related +.Fl w +flag is a no-op rather than causing a warning to be printed and no +keyword to be emitted. +The latter behavior is not emulated as it is potentially dangerous in +the face of /set statements. +.Pp +The +.Sy netbsd6 +flavor does not replicate the historical bug that reported time as +seconds.nanoseconds without zero padding nanosecond values less than +100000000. .Sh SEE ALSO .Xr chflags 1 , .Xr chgrp 1 , Index: src/usr.sbin/mtree/mtree.c diff -u src/usr.sbin/mtree/mtree.c:1.43 src/usr.sbin/mtree/mtree.c:1.44 --- src/usr.sbin/mtree/mtree.c:1.43 Wed Dec 12 10:51:41 2012 +++ src/usr.sbin/mtree/mtree.c Thu Dec 20 11:43:16 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: mtree.c,v 1.43 2012/12/12 15:51:41 christos Exp $ */ +/* $NetBSD: mtree.c,v 1.44 2012/12/20 16:43:16 christos Exp $ */ /*- * Copyright (c) 1989, 1990, 1993 @@ -43,7 +43,7 @@ __COPYRIGHT("@(#) Copyright (c) 1989, 19 #if 0 static char sccsid[] = "@(#)mtree.c 8.1 (Berkeley) 6/6/93"; #else -__RCSID("$NetBSD: mtree.c,v 1.43 2012/12/12 15:51:41 christos Exp $"); +__RCSID("$NetBSD: mtree.c,v 1.44 2012/12/20 16:43:16 christos Exp $"); #endif #endif /* not lint */ @@ -59,9 +59,19 @@ __RCSID("$NetBSD: mtree.c,v 1.43 2012/12 #include "extern.h" int ftsoptions = FTS_PHYSICAL; -int cflag, Cflag, dflag, Dflag, eflag, iflag, jflag, lflag, mflag, - nflag, qflag, rflag, sflag, tflag, uflag, Uflag; +int bflag, cflag, Cflag, dflag, Dflag, eflag, iflag, jflag, lflag, mflag, + nflag, qflag, rflag, sflag, tflag, uflag, Uflag, wflag; char fullpath[MAXPATHLEN]; +enum flavor flavor = F_MTREE; + +static struct { + enum flavor flavor; + const char name[9]; +} flavors[] = { + {F_MTREE, "mtree"}, + {F_FREEBSD9, "freebsd9"}, + {F_NETBSD6, "netbsd6"}, +}; __dead static void usage(void); @@ -69,6 +79,7 @@ int main(int argc, char **argv) { int ch, status; + uint i; char *dir, *p; FILE *spec1, *spec2; @@ -80,9 +91,12 @@ main(int argc, char **argv) spec2 = NULL; while ((ch = getopt(argc, argv, - "cCdDeE:f:I:ijk:K:lLmMnN:p:PqrR:s:StuUWxX:")) + "bcCdDeE:f:F:I:ijk:K:lLmMnN:p:PqrR:s:StuUwWxX:")) != -1) { switch((char)ch) { + case 'b': + bflag = 1; + break; case 'c': cflag = 1; break; @@ -115,6 +129,15 @@ main(int argc, char **argv) } else usage(); break; + case 'F': + for (i = 0; i < __arraycount(flavors); i++) + if (strcmp(optarg, flavors[i].name) == 0) { + flavor = flavors[i].flavor; + break; + } + if (i == __arraycount(flavors)) + usage(); + break; case 'i': iflag = 1; break; @@ -193,6 +216,9 @@ main(int argc, char **argv) case 'U': Uflag = uflag = 1; break; + case 'w': + wflag = 1; + break; case 'W': mtree_Wflag = 1; break; @@ -213,6 +239,36 @@ main(int argc, char **argv) if (argc) usage(); + switch (flavor) { + case F_FREEBSD9: + if (cflag && iflag) { + warnx("-c and -i passed, replacing -i with -j for " + "FreeBSD compatibility"); + iflag = 0; + jflag = 1; + } + if (dflag && !bflag) { + warnx("Adding -b to -d for FreeBSD compatibility"); + bflag = 1; + } + if (uflag && !iflag) { + warnx("Adding -i to -%c for FreeBSD compatibility", + Uflag ? 'U' : 'u'); + iflag = 1; + } + if (uflag && !tflag) { + warnx("Adding -t to -%c for FreeBSD compatibility", + Uflag ? 'U' : 'u'); + tflag = 1; + } + if (wflag) + warnx("The -w flag is a no-op"); + break; + default: + if (wflag) + usage(); + } + if (spec2 && (cflag || Cflag || Dflag)) mtree_err("Double -f, -c, -C and -D flags are mutually " "exclusive"); @@ -255,12 +311,18 @@ main(int argc, char **argv) static void usage(void) { + uint i; fprintf(stderr, - "usage: %s [-CcDdejLlMnPqrStUuWx] [-i|-m] [-E tags]\n" + "usage: %s [-bCcDdejLlMnPqrStUuWx] [-i|-m] [-E tags]\n" "\t\t[-f spec] [-f spec]\n" "\t\t[-I tags] [-K keywords] [-k keywords] [-N dbdir] [-p path]\n" - "\t\t[-R keywords] [-s seed] [-X exclude-file]\n", + "\t\t[-R keywords] [-s seed] [-X exclude-file]\n" + "\t\t[-F flavor]\n", getprogname()); + fprintf(stderr, "\nflavors:"); + for (i = 0; i < __arraycount(flavors); i++) + fprintf(stderr, " %s", flavors[i].name); + fprintf(stderr, "\n"); exit(1); } Index: src/usr.sbin/mtree/spec.c diff -u src/usr.sbin/mtree/spec.c:1.84 src/usr.sbin/mtree/spec.c:1.85 --- src/usr.sbin/mtree/spec.c:1.84 Sun Oct 7 14:40:49 2012 +++ src/usr.sbin/mtree/spec.c Thu Dec 20 11:43:16 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: spec.c,v 1.84 2012/10/07 18:40:49 christos Exp $ */ +/* $NetBSD: spec.c,v 1.85 2012/12/20 16:43:16 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.84 2012/10/07 18:40:49 christos Exp $"); +__RCSID("$NetBSD: spec.c,v 1.85 2012/12/20 16:43:16 christos Exp $"); #endif #endif /* not lint */ @@ -415,19 +415,16 @@ dump_nodes(const char *dir, NODE *root, char * vispath(const char *path) { - const char extra[] = { ' ', '\t', '\n', '\\', '#', -#ifdef notyet - /* - * We don't encode the globbing characters yet, because they - * get encoded as \c and strunvis fails to decode them - */ - '*', '?', '[', -#endif - '\0' }; + static const char extra[] = { ' ', '\t', '\n', '\\', '#', '\0' }; + static const char extra_glob[] = { ' ', '\t', '\n', '\\', '#', '*', + '?', '[', '\0' }; static char pathbuf[4*MAXPATHLEN + 1]; - strsvis(pathbuf, path, VIS_CSTYLE, extra); - return(pathbuf); + if (flavor == F_NETBSD6) + strsvis(pathbuf, path, VIS_CSTYLE, extra); + else + strsvis(pathbuf, path, VIS_OCTAL, extra_glob); + return pathbuf; }