tech-userlevel archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: Increasing FreeBSD compatibility in mtree



On Sun, Dec 16, 2012 at 04:15:35PM +0000, Christos Zoulas wrote:
> In article <20121214223041.GM40927%lor.one-eyed-alien.net@localhost>,
> Brooks Davis  <brooks%freebsd.org@localhost> wrote:

> >> I'm considering make -c -i set jflag and print a warning.  The reason
> >> for this is that -i only makes sense with -c on FreeBSD and it looks
> >> like it's a no-op on NetBSD.  Does this make sense?  This might be best
> >> as a FreeBSD specific bit of compatibility code.
> >
> >On FreeBSD the -i option is equivalent to the new -j option in NetBSD's
> >mtree in that it indents the output four spaces for each directory
> >level.  It's mostly useless in the face of -C (full path output) but
> >likely has users.
> >
> >On FreeBSD -i only does anything when -c (print a specification) is
> >specified.  On NetBSD -i sets the schg or sappnd flags when a hierarchy
> >is being verified.  Thus it appears to be a no-opn with -c is given.
> >I'd like to propose making -c and -i imply -j with a warning as a
> >compatibility measure.  I'm thinking something like the following
> >untested diff though I could just do this on FreeBSD:
> >

> Perhaps turn off -i too?

Here's an improved patch that disables iflag and documents this
behavior.  It also adds a COMPATIBILITY section which is incomplete
pending resolution of the rest of the issues.

If you do elect to commit this I might be tempted to add a comment along
the lines of:

/* FreeBSD compat, remove after 2018. */

Index: mtree.c
===================================================================
--- mtree.c     (revision 244436)
+++ mtree.c     (working copy)
@@ -236,6 +236,12 @@
        if ((cflag && Cflag) || (cflag && Dflag) || (Cflag && Dflag))
                mtree_err("-c, -C and -D flags are mutually exclusive");
 
+       if (cflag && iflag) {
+               warnx("-c and -i specified, setting -j and unsetting -i");
+               iflag = 0;
+               jflag = 1;
+       }
+
        if (iflag && mflag)
                mtree_err("-i and -m flags are mutually exclusive");
 
Index: mtree.8
===================================================================
--- mtree.8     (revision 244436)
+++ mtree.8     (working copy)
@@ -166,6 +166,16 @@
 If no inclusion list is provided, the default is to display all files.
 .It Fl i
 If specified, set the schg and/or sappnd flags.
+For compatibility with
+.Fx
+if the
+.Fl c
+and
+.Fl i
+option are both passed,
+then the
+.Fl j
+option is implied and a warning is emitted.
 .It Fl j
 Indent the output 4 spaces each time a directory level is descended when
 creating a specification with the
@@ -690,6 +700,37 @@
 or
 .Fl u
 to create directory hierarchies for, for example, distributions.
+.Sh COMPATIBILITY
+This version of the
+.Nm utility differs from the version in
+.Fx 9
+and earlier in several ways:
+.Bl -bullet -compact
+.It
+When the
+.Fl c
+option is specified a final ``..'' is not emitted to match the top
+directory.
+Files made to match by appending ``..\\n\\n''.
+.It
+The
+.Fl U
+and
+.Fl u
+options do not set the modification time or the schg and/or sappnd
+file flags unless the
+.Fl t
+and
+.Fl i
+options are also passed.
+.It
+The
+.Fl j
+option is equivalent to the
+.Fx
+.Fl i
+option and should be used in its place.
+.El
 .Sh SEE ALSO
 .Xr chflags 1 ,
 .Xr chgrp 1 ,

> >> The remaining known issues are in output format.  Since changing output
> >> format is quite disruptive to users I'm leaning toward a -F option to
> >> enable FreeBSD compatible output.  Would such an option be acceptable or
> >> should I just use #ifdef __FreeBSD__ in our tree?  Obviously, if I merge
> >> the code I'd have to make that the default.  The differences I know of
> >> are:
> >
> >In the following, consider the hierarchy under /tmp/a created with "mkdir
> >-p /tmp/a/b/c".
> >
> >>  - A "..\n\n" is printed for the top level directory.
> >
> >--FreeBSD--
> >$ mtree -p /tmp/a -c -i -n
> >
> >/set type=file uid=3006 gid=0 mode=0755 nlink=1 flags=none
> >.               type=dir nlink=3 size=512 time=1355518983.000000000
> >
> >    b               type=dir nlink=3 size=512 time=1355518986.000000000
> >
> >        c               type=dir nlink=2 size=512 time=1355518986.000000000
> >        ..
> >
> >    ..
> >
> >..
> >
> >--FreeBSD--
> >
> >--NetBSD--
> >$ nmtree -p /tmp/a -c -j -n
> >
> >/set type=file uid=1001 gid=0 mode=0755 nlink=1 flags=none
> >.               type=dir nlink=3 time=1355522292.000000000
> >
> >    b               type=dir nlink=3 time=1355522292.000000000
> >
> >        c               type=dir nlink=2 time=1355522292.000000000
> >        ..
> >
> >    ..
> >
> >--NetBSD--
> >
> >The delta is the last two lines of the FreeBSD output aren't in the
> >NetBSD output.  I don't think this on is a big deal one way or another,
> >but I speculate that FreeBSD output may better support concatination.
> 
> I am not so sure. Assuming you cd each time you find a directory, the NetBSD
> one brings you back where you started, but the FreeBSD one higher?

Hmm, that's true.  The final .. looks more complete in -j output, but is
basically a no op in practice and trivial to add after the fact which
leads me to think I should just document the difference and move on.

One compromise approach might be to enable it when -j is specified since
that's a new option on NetBSD.  That could be accomplished as follows:

Index: create.c
===================================================================
RCS file: /cvsroot/src/usr.sbin/mtree/create.c,v
retrieving revision 1.67
diff -u -r1.67 create.c
--- create.c    15 Dec 2012 01:24:40 -0000      1.67
+++ create.c    19 Dec 2012 18:20:24 -0000
@@ -143,12 +143,12 @@
                        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);
+                       if (p->fts_level > 0 || jflag)
                                printf("%*s..\n\n", indent, "");
-                       }
                        break;
                case FTS_DNR:
                case FTS_ERR:

> >>  - size keywords are printed for all file types.
> >
> >As above FreeBSD emits size of all file types.  NetBSD only does so for
> >regular files.  
> 
> I think this is more consistent, we should probably do that too.

If you're willing to do this it would be helpful.  I know I will have to
enable it to make this version acceptable on FreeBSD.  Otherwise every
non-file line will change in the default case.  Obviously the reverse
is that if you do make this change the files of NetBSD users change
instead.  That being said, the time=%d.%09d bugfix means you already
have done that in the default case so now is as good a time as any to
make major changes.

> >>  - -d mode suppresses most empty lines and uses type=dir in /set 
> >> statements.
> >
> >-d mode is directory only for both FreeBSD and NetBSD.  On FreeBSD is
> >suppresses blank lines so you can get output like:
> >
> >--FreeBSD--
> >$ mtree -p /tmp/a -c -i -n -d
> >/set type=dir uid=3006 gid=0 mode=0755 nlink=1 flags=none
> >.               nlink=3 size=512 time=1355518983.000000000
> >    b               nlink=3 size=512 time=1355518986.000000000
> >        c               nlink=2 size=512 time=1355518986.000000000
> >        ..
> >    ..
> >..
> >--FreeBSD--
> >
> >--NetBSD--
> >$ nmtree -p /tmp/a -c -j -n -d
> >
> >/set type=file uid=1001 gid=0 mode=0755 nlink=1 flags=none
> >.               type=dir nlink=3 time=1355522292.000000000
> >
> >    b               type=dir nlink=3 time=1355522292.000000000
> >
> >        c               type=dir nlink=2 time=1355522292.000000000
> >        ..
> >
> >    ..
> >
> >--NetBSD--
> >
> >NetBSD preserves the blank lines as in the samples above.  Additionally,
> >NetBSD unconditionally prints "type=file" in the /set statement which
> >means it is overridden on each line.  I believe the modifications to -d
> >in FreeBSD were intended to be used along with -i to make it easier to
> >maintain the historic /etc/mtree/BSD.*.mtree files.
> 
> Perhaps have a new option to suppress empty lines?

That could work.  What about the /set statement?  I think I'll probably
need to change that on FreeBSD to avoid churning every line.  The
type=file seems obviously wrong give that we aren't printing output for
files.

Thanks,
Brooks

Attachment: pgp5iW29NqC4W.pgp
Description: PGP signature



Home | Main Index | Thread Index | Old Index