svn commit: r244490 - projects/mtree/contrib/mtree
Brooks Davis
brooks at FreeBSD.org
Thu Dec 20 17:13:03 UTC 2012
Author: brooks
Date: Thu Dec 20 17:13:01 2012
New Revision: 244490
URL: http://svnweb.freebsd.org/changeset/base/244490
Log:
Introduce a concept of flavors which change the default output and
in the "freebsd9" case change the behavior of some flags to match
FreeBSD. This has been committed upstream. CVS revision numbers will
be looped back in a future commit.
Modified:
projects/mtree/contrib/mtree/create.c
projects/mtree/contrib/mtree/extern.h
projects/mtree/contrib/mtree/mtree.8
projects/mtree/contrib/mtree/mtree.c
projects/mtree/contrib/mtree/spec.c
Modified: projects/mtree/contrib/mtree/create.c
==============================================================================
--- projects/mtree/contrib/mtree/create.c Thu Dec 20 16:21:02 2012 (r244489)
+++ projects/mtree/contrib/mtree/create.c Thu Dec 20 17:13:01 2012 (r244490)
@@ -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)
Modified: projects/mtree/contrib/mtree/extern.h
==============================================================================
--- projects/mtree/contrib/mtree/extern.h Thu Dec 20 16:21:02 2012 (r244489)
+++ projects/mtree/contrib/mtree/extern.h Thu Dec 20 17:13:01 2012 (r244490)
@@ -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[];
Modified: projects/mtree/contrib/mtree/mtree.8
==============================================================================
--- projects/mtree/contrib/mtree/mtree.8 Thu Dec 20 16:21:02 2012 (r244489)
+++ projects/mtree/contrib/mtree/mtree.8 Thu Dec 20 17:13:01 2012 (r244490)
@@ -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 ,
@@ -691,6 +717,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 limititations 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 ,
Modified: projects/mtree/contrib/mtree/mtree.c
==============================================================================
--- projects/mtree/contrib/mtree/mtree.c Thu Dec 20 16:21:02 2012 (r244489)
+++ projects/mtree/contrib/mtree/mtree.c Thu Dec 20 17:13:01 2012 (r244490)
@@ -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");
@@ -261,12 +317,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);
}
Modified: projects/mtree/contrib/mtree/spec.c
==============================================================================
--- projects/mtree/contrib/mtree/spec.c Thu Dec 20 16:21:02 2012 (r244489)
+++ projects/mtree/contrib/mtree/spec.c Thu Dec 20 17:13:01 2012 (r244490)
@@ -415,11 +415,15 @@ dump_nodes(const char *dir, NODE *root,
char *
vispath(const char *path)
{
- const char extra[] = { ' ', '\t', '\n', '\\', '#', '*', '?', '[',
- '#', '\0' };
+ const char extra[] = { ' ', '\t', '\n', '\\', '\0' };
+ const char extra_glob[] = { ' ', '\t', '\n', '\\', '#', '*', '?',
+ '[', '\0' };
static char pathbuf[4*MAXPATHLEN + 1];
- strsvis(pathbuf, path, VIS_CSTYLE, extra);
+ if (flavor == F_NETBSD6)
+ strsvis(pathbuf, path, VIS_CSTYLE, extra);
+ else
+ strsvis(pathbuf, path, VIS_OCTAL, extra_glob);
return(pathbuf);
}
More information about the svn-src-projects
mailing list