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;
 }
 
 

Reply via email to