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