]> Zhao Yanbai Git Server - minix.git/commitdiff
mtree mknod 83/83/2
authorBen Gras <ben@minix3.org>
Wed, 10 Oct 2012 15:20:17 +0000 (17:20 +0200)
committerLionel Sambuc <lionel@minix3.org>
Wed, 24 Oct 2012 11:42:44 +0000 (13:42 +0200)
Change-Id: I887437c7b84839fc644da4c55bd59b6a414408ef

25 files changed:
commands/Makefile
commands/mknod/Makefile [deleted file]
commands/mknod/mknod.c [deleted file]
man/man8/Makefile
man/man8/mknod.8 [deleted file]
releasetools/nbsd_ports
sbin/Makefile
sbin/mknod/Makefile [new file with mode: 0644]
sbin/mknod/mknod.8 [new file with mode: 0644]
sbin/mknod/mknod.c [new file with mode: 0644]
sbin/mknod/pack_dev.c [new file with mode: 0644]
sbin/mknod/pack_dev.h [new file with mode: 0644]
usr.sbin/Makefile
usr.sbin/mtree/Makefile
usr.sbin/mtree/compare.c
usr.sbin/mtree/crc.c
usr.sbin/mtree/create.c
usr.sbin/mtree/extern.h
usr.sbin/mtree/misc.c
usr.sbin/mtree/mtree.8
usr.sbin/mtree/mtree.c
usr.sbin/mtree/mtree.h
usr.sbin/mtree/spec.c
usr.sbin/mtree/specspec.c [new file with mode: 0644]
usr.sbin/mtree/verify.c

index c618efa5d2866d79727fc893d1eec823bdc85b7e..8a697d888d7377e30e08b5e4352dfc477827945e 100644 (file)
@@ -15,7 +15,7 @@ SUBDIR=       add_route arp ash at backup banner basename btrace cal \
        intr ipcrm ipcs irdpd isoread join kill last \
        less loadkeys loadramdisk logger look lp \
        lpd ls lspci mail MAKEDEV \
-       mesg mined mkfifo mknod \
+       mesg mined mkfifo \
        mkproto mount mt netconf nice acknm nohup \
        nonamed od paste patch pax \
        ping postinstall poweroff pr prep printf printroot \
diff --git a/commands/mknod/Makefile b/commands/mknod/Makefile
deleted file mode 100644 (file)
index fe1ab21..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-PROG=  mknod
-MAN=
-
-.include <bsd.prog.mk>
diff --git a/commands/mknod/mknod.c b/commands/mknod/mknod.c
deleted file mode 100644 (file)
index 43d3b73..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-/* mknod - build a special file                Author: Andy Tanenbaum */
-
-#include <sys/types.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <minix/minlib.h>
-#include <errno.h>
-#include <stdio.h>
-#ifdef __NBSD_LIBC
-#include <sys/stat.h>
-#endif
-
-int main(int argc, char *argv []);
-void badcomm(void);
-void badfifo(void);
-void badchar(void);
-void badblock(void);
-
-int main(argc, argv)
-int argc;
-char *argv[];
-{
-/* Mknod name b/c major minor makes a node. */
-
-  int mode, major, minor, dev;
-
-  if (argc < 3) badcomm();
-  if (*argv[2] != 'b' && *argv[2] != 'c' && *argv[2] != 'p') badcomm();
-  if (*argv[2] == 'p' && argc != 3) badfifo();
-  if (*argv[2] == 'c' && argc != 5) badchar();
-  if (*argv[2] == 'b' && argc != 5) badblock();
-  if (*argv[2] == 'p') {
-       mode = 010666;
-       dev = 0;
-  } else {
-       mode = (*argv[2] == 'b' ? 060666 : 020666);
-       major = atoi(argv[3]);
-       minor = atoi(argv[4]);
-       if (major - 1 > 0xFE || minor > 0xFF) badcomm();
-       dev = (major << 8) | minor;
-  }
-  if (mknod(argv[1], mode, dev) < 0) {
-       int err = errno;
-       std_err("mknod: ");
-       errno = err;
-       perror(argv[1]);
-  }
-  return(0);
-}
-
-void badcomm()
-{
-  std_err("Usage: mknod name b/c/p [major minor]\n");
-  exit(1);
-}
-
-void badfifo()
-{
-  std_err("Usage: mknod name p\n");
-  exit(1);
-}
-
-void badchar()
-{
-  std_err("Usage: mknod name c major minor\n");
-  exit(1);
-}
-
-void badblock()
-{
-  std_err("Usage: mknod name b major minor\n");
-  exit(1);
-}
index cbcdb079e58807250cc4ae2285d698562f61652f..ac6cc6cf20864b41e145f3b5f4789a845832e47b 100644 (file)
@@ -3,7 +3,7 @@ MAN=    add_route.8 backup.8 boot.8 btrace.8 \
        dhcpd.8 diskctl.8 elvprsv.8 fbdctl.8 fdisk.8 fingerd.8 \
        getty.8 halt.8 hgfs.8 httpd.8 ifconfig.8 inet.8 init.8 \
        intr.8 irdpd.8 loadramdisk.8 MAKEDEV.8 \
-       mknod.8 netconf.8 newroot.8 nonamed.8 \
+       netconf.8 newroot.8 nonamed.8 \
        ossdevlinks.8 part.8 partition.8 \
        poweroff.8 printroot.8 pr_routes.8 pwdauth.8 rarpd.8 \
        rdate.8 readclock.8 reboot.8 repartition.8 \
diff --git a/man/man8/mknod.8 b/man/man8/mknod.8
deleted file mode 100644 (file)
index c28ef1d..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-.TH MKNOD 8
-.SH NAME
-mknod \- create a special file
-.SH SYNOPSIS
-\fBmknod \fIfile\fR [\fBb\fR] [\fBc\fR] \fImajor \fIminor\fR
-.br
-\fBmknod \fIfile\fR \fBp\fR\fR
-.br
-.de FL
-.TP
-\\fB\\$1\\fR
-\\$2
-..
-.de EX
-.TP 20
-\\fB\\$1\\fR
-# \\$2
-..
-.SH EXAMPLES
-.TP 20
-.B mknod /dev/plotter c 7 0
-# Create special file for a plotter
-.TP 20
-.B mknod /dev/fd3 b 2 3
-# Create a device for diskette drive 3
-.TP 20
-.B mknod /tmp/stream p
-# Create a named pipe
-.SH DESCRIPTION
-.PP
-.I Mknod
-creates a special file named
-.I file ,
-with the indicated major and minor device numbers.
-The second argument specifies a block special, a character special, or a
-named pipe.  Named pipes do not have device numbers so they are omitted.
-.SH "SEE ALSO"
-.BR mkfifo (1),
-.BR mknod (2).
index 17015e0b205880b4aa251e587c392084d21965a3..1c5afed4ec9325d9d1442747b0dac8aece720608 100644 (file)
@@ -5,6 +5,8 @@
 2012/10/17 12:00:00,tools/cksum
 2012/10/17 12:00:00,usr.bin/cksum
 2012/10/17 12:00:00,usr.sbin/postinstall
+2012/10/10 16:16:12,sbin/mknod
+2012/10/10 16:16:12,usr.sbin/mtree
 2012/05/01 16:16:12,external/bsd/libarchive
 2012/02/10 16:16:12,usr.sbin/chroot
 2011/01/17 18:11:10,usr.bin/ldd
index 220ff19f36dff568e05d5324eef47fb928678f43..7f30c293a9849d108c7f3d34470e05f395edf1fa 100644 (file)
@@ -2,6 +2,6 @@
 
 .include <bsd.own.mk>
 
-SUBDIR= fsck fsck_ext2fs newfs_ext2fs
+SUBDIR= fsck fsck_ext2fs newfs_ext2fs mknod
 
 .include <bsd.subdir.mk>
diff --git a/sbin/mknod/Makefile b/sbin/mknod/Makefile
new file mode 100644 (file)
index 0000000..a7d1505
--- /dev/null
@@ -0,0 +1,8 @@
+#      $NetBSD: Makefile,v 1.13 2009/04/11 07:58:12 lukem Exp $
+#      @(#)Makefile    8.1 (Berkeley) 6/5/93
+
+PROG=  mknod
+SRCS=  mknod.c pack_dev.c
+MAN=   mknod.8
+
+.include <bsd.prog.mk>
diff --git a/sbin/mknod/mknod.8 b/sbin/mknod/mknod.8
new file mode 100644 (file)
index 0000000..b0d2a95
--- /dev/null
@@ -0,0 +1,229 @@
+.\"    $NetBSD: mknod.8,v 1.28 2004/06/17 21:30:14 dsl Exp $
+.\"
+.\" Copyright (c) 1980, 1991, 1993
+.\"    The Regents of the University of California.  All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of the University nor the names of its contributors
+.\"    may be used to endorse or promote products derived from this software
+.\"    without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\"     @(#)mknod.8    8.2 (Berkeley) 12/11/93
+.\"
+.Dd June 17, 2004
+.Dt MKNOD 8
+.Os
+.Sh NAME
+.Nm mknod
+.Nd make device special file
+.Sh SYNOPSIS
+.Nm
+.Op Fl rR
+.Op Fl F Ar fmt
+.Op Fl g Ar gid
+.Op Fl m Ar mode
+.Op Fl u Ar uid
+.Ar name
+.Op Cm c | Cm b
+.Op Ar driver | Ar major
+.Ar minor
+.Nm
+.Op Fl rR
+.Op Fl F Ar fmt
+.Op Fl g Ar gid
+.Op Fl m Ar mode
+.Op Fl u Ar uid
+.Ar name
+.Op Cm c | Cm b
+.Ar major unit subunit
+.Nm
+.Op Fl rR
+.Op Fl g Ar gid
+.Op Fl m Ar mode
+.Op Fl u Ar uid
+.Ar name
+.Op Cm c | Cm b
+.Ar number
+.Nm
+.Op Fl rR
+.Op Fl g Ar gid
+.Op Fl m Ar mode
+.Op Fl u Ar uid
+.Ar name
+.Cm p
+.Nm
+.Fl l
+.Sh DESCRIPTION
+The
+.Nm
+command creates device special files, or fifos.
+Normally the shell script
+.Pa /dev/MAKEDEV
+is used to create special files for commonly known devices; it executes
+.Nm
+with the appropriate arguments and can make all the files required for the
+device.
+.Pp
+To make nodes manually, the arguments are:
+.Pp
+.Bl -tag -width xmxmode
+.It Fl r
+Replace an existing file if its type is incorrect.
+.It Fl R
+Replace an existing file if its type is incorrect.
+Correct the mode, user and group.
+.It Fl F Ar fmt
+Create device nodes that may be used by an operating system which
+uses device numbers packed in a different format than
+.Nx
+uses.
+This is necessary when
+.Nx
+is used as an
+.Tn NFS
+server for netbooted computers running other operating systems.
+.Pp
+The following values for the
+.Ar fmt
+are recognized:
+.Sy native ,
+.Sy 386bsd ,
+.Sy 4bsd ,
+.Sy bsdos ,
+.Sy freebsd ,
+.Sy hpux ,
+.Sy isc ,
+.Sy linux ,
+.Sy netbsd ,
+.Sy osf1 ,
+.Sy sco ,
+.Sy solaris ,
+.Sy sunos ,
+.Sy svr3 ,
+.Sy svr4 ,
+and
+.Sy ultrix .
+.It Fl g Ar gid
+Specify the group for the device node.
+The
+.Ar gid
+operand may be a numeric group ID or a group name.
+If a group name is also a numeric group ID,
+the operand is used as a group name.
+Precede a numeric group ID with a
+.Cm #
+to stop it being treated as a name.
+.It Fl m Ar mode
+Specify the mode for the device node.
+The mode may be absolute or symbolic, see
+.Xr chmod 1 .
+.It Fl u Ar uid
+Specify the user for the device node.
+The
+.Ar uid
+operand may be a numeric user ID or a user name.
+If a user name is also a numeric user ID,
+the operand is used as a user name.
+Precede a numeric user ID with a
+.Cm #
+to stop it being treated as a name.
+.It Ar name
+Device name, for example
+.Dq sd
+for a SCSI disk on an HP300 or a
+.Dq pty
+for pseudo-devices.
+.It Cm b | Cm c | Cm p
+Type of device.
+If the device is a block type device such as a tape or disk drive
+which needs both cooked and raw special files, the type is
+.Cm b .
+All other devices are character type devices, such as terminal
+and pseudo devices, and are type
+.Cm c .
+Specifying
+.Cm p
+creates fifo files.
+.It Ar driver | Ar major
+The major device number is an integer number which tells the kernel
+which device driver entry point to use.
+If the device driver is configured into the current kernel it may be
+specified by driver name or major number.
+To find out which major device number to use for a particular device,
+use
+.Nm
+.Fl l ,
+check the file
+.Pa /dev/MAKEDEV
+to see if the device is known, or check
+the system dependent device configuration file:
+.Bd -filled -offset indent
+.Dq Pa /usr/src/sys/arch/\*[Lt]arch\*[Gt]/\*[Lt]arch\*[Gt]/conf.c
+.Ed
+.Pp
+.Po
+e.g.
+.Pa /usr/src/sys/arch/vax/vax/conf.c
+.Pc .
+.It Ar minor
+The minor device number tells the kernel which one of several similar
+devices the node corresponds to; for example, it may be a specific serial
+port or pty.
+.It Ar unit No and Ar subunit
+The unit and subunit numbers select a subset of a device; for example, the
+unit may specify a particular SCSI disk, and the subunit a partition on
+that disk.
+(Currently this form of specification is only supported by the
+.Ar bsdos
+format, for compatibility with the
+.Bsx
+.Nm ) .
+.It Ar number
+A single opaque device number.
+Useful for netbooted computers which require device numbers packed
+in a format that isn't supported by
+.Fl F .
+.It Fl l
+List the device drivers configured into the current kernel together with their
+block and character major numbers.
+.El
+.Sh SEE ALSO
+.Xr chmod 1 ,
+.Xr mkfifo 1 ,
+.Xr mkfifo 2 ,
+.Xr mknod 2 ,
+.Xr MAKEDEV 8
+.Sh HISTORY
+A
+.Nm
+command appeared in
+.At v6 .
+The
+.Fl F
+option appeared in
+.Nx 1.4 .
+The
+.Fl g , l , m , r , R ,
+and
+.Fl u
+options, and the ability to specify a driver by name appeared in
+.Nx 2.0 .
diff --git a/sbin/mknod/mknod.c b/sbin/mknod/mknod.c
new file mode 100644 (file)
index 0000000..3d8bb5e
--- /dev/null
@@ -0,0 +1,393 @@
+/*     $NetBSD: mknod.c,v 1.40 2011/08/27 18:37:41 joerg Exp $ */
+
+/*-
+ * Copyright (c) 1998, 2001 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Charles M. Hannum.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if HAVE_NBTOOL_CONFIG_H
+#include "nbtool_config.h"
+#endif
+
+#include <sys/cdefs.h>
+#ifndef lint
+__COPYRIGHT("@(#) Copyright (c) 1998\
+ The NetBSD Foundation, Inc.  All rights reserved.");
+__RCSID("$NetBSD: mknod.c,v 1.40 2011/08/27 18:37:41 joerg Exp $");
+#endif /* not lint */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/param.h>
+#if !HAVE_NBTOOL_CONFIG_H
+#include <sys/sysctl.h>
+#endif
+
+#include <err.h>
+#include <errno.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <pwd.h>
+#include <grp.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "pack_dev.h"
+
+static int gid_name(const char *, gid_t *);
+static portdev_t callPack(pack_t *, int, u_long *);
+
+__dead static  void    usage(void);
+
+#ifdef KERN_DRIVERS
+static struct kinfo_drivers *kern_drivers;
+static int num_drivers;
+
+static void get_device_info(void);
+static void print_device_info(char **);
+static int major_from_name(const char *, mode_t);
+#endif
+
+#define        MAXARGS 3               /* 3 for bsdos, 2 for rest */
+
+int
+main(int argc, char **argv)
+{
+       char    *name, *p;
+       mode_t   mode;
+       portdev_t        dev;
+       pack_t  *pack;
+       u_long   numbers[MAXARGS];
+       int      n, ch, fifo, hasformat;
+       int      r_flag = 0;            /* force: delete existing entry */
+#ifdef KERN_DRIVERS
+       int      l_flag = 0;            /* list device names and numbers */
+       int      major;
+#endif
+       void    *modes = 0;
+       uid_t    uid = -1;
+       gid_t    gid = -1;
+       int      rval;
+
+       dev = 0;
+       fifo = hasformat = 0;
+       pack = pack_native;
+
+#ifdef KERN_DRIVERS
+       while ((ch = getopt(argc, argv, "lrRF:g:m:u:")) != -1) {
+#else
+       while ((ch = getopt(argc, argv, "rRF:g:m:u:")) != -1) {
+#endif
+               switch (ch) {
+
+#ifdef KERN_DRIVERS
+               case 'l':
+                       l_flag = 1;
+                       break;
+#endif
+
+               case 'r':
+                       r_flag = 1;
+                       break;
+
+               case 'R':
+                       r_flag = 2;
+                       break;
+
+               case 'F':
+                       pack = pack_find(optarg);
+                       if (pack == NULL)
+                               errx(1, "invalid format: %s", optarg);
+                       hasformat++;
+                       break;
+
+               case 'g':
+                       if (optarg[0] == '#') {
+                               gid = strtol(optarg + 1, &p, 10);
+                               if (*p == 0)
+                                       break;
+                       }
+                       if (gid_name(optarg, &gid) == 0)
+                               break;
+                       gid = strtol(optarg, &p, 10);
+                       if (*p == 0)
+                               break;
+                       errx(1, "%s: invalid group name", optarg);
+
+               case 'm':
+                       modes = setmode(optarg);
+                       if (modes == NULL)
+                               err(1, "Cannot set file mode `%s'", optarg);
+                       break;
+
+               case 'u':
+                       if (optarg[0] == '#') {
+                               uid = strtol(optarg + 1, &p, 10);
+                               if (*p == 0)
+                                       break;
+                       }
+                       if (uid_from_user(optarg, &uid) == 0)
+                               break;
+                       uid = strtol(optarg, &p, 10);
+                       if (*p == 0)
+                               break;
+                       errx(1, "%s: invalid user name", optarg);
+
+               default:
+               case '?':
+                       usage();
+               }
+       }
+       argc -= optind;
+       argv += optind;
+
+#ifdef KERN_DRIVERS
+       if (l_flag) {
+               print_device_info(argv);
+               return 0;
+       }
+#endif
+
+       if (argc < 2 || argc > 10)
+               usage();
+
+       name = *argv;
+       argc--;
+       argv++;
+
+       umask(mode = umask(0));
+       mode = (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH) & ~mode;
+
+       if (argv[0][1] != '\0')
+               goto badtype;
+       switch (*argv[0]) {
+       case 'c':
+               mode |= S_IFCHR;
+               break;
+
+       case 'b':
+               mode |= S_IFBLK;
+               break;
+
+       case 'p':
+               if (hasformat)
+                       errx(1, "format is meaningless for fifos");
+               mode |= S_IFIFO;
+               fifo = 1;
+               break;
+
+       default:
+ badtype:
+               errx(1, "node type must be 'b', 'c' or 'p'.");
+       }
+       argc--;
+       argv++;
+
+       if (fifo) {
+               if (argc != 0)
+                       usage();
+       } else {
+               if (argc < 1 || argc > MAXARGS)
+                       usage();
+       }
+
+       for (n = 0; n < argc; n++) {
+               errno = 0;
+               numbers[n] = strtoul(argv[n], &p, 0);
+               if (*p == 0 && errno == 0)
+                       continue;
+#ifdef KERN_DRIVERS
+               if (n == 0) {
+                       major = major_from_name(argv[0], mode);
+                       if (major != -1) {
+                               numbers[0] = major;
+                               continue;
+                       }
+                       if (!isdigit(*(unsigned char *)argv[0]))
+                               errx(1, "unknown driver: %s", argv[0]);
+               }
+#endif
+               errx(1, "invalid number: %s", argv[n]);
+       }
+
+       switch (argc) {
+       case 0:
+               dev = 0;
+               break;
+
+       case 1:
+               dev = numbers[0];
+               break;
+
+       default:
+               dev = callPack(pack, argc, numbers);
+               break;
+       }
+
+       if (modes != NULL)
+               mode = getmode(modes, mode);
+       umask(0);
+       rval = fifo ? mkfifo(name, mode) : mknod(name, mode, dev);
+       if (rval < 0 && errno == EEXIST && r_flag) {
+               struct stat sb;
+               if (lstat(name, &sb) != 0 || (!fifo && sb.st_rdev != dev))
+                       sb.st_mode = 0;
+
+               if ((sb.st_mode & S_IFMT) == (mode & S_IFMT)) {
+                       if (r_flag == 1)
+                               /* Ignore permissions and user/group */
+                               return 0;
+                       if (sb.st_mode != mode)
+                               rval = chmod(name, mode);
+                       else
+                               rval = 0;
+               } else {
+                       unlink(name);
+                       rval = fifo ? mkfifo(name, mode)
+                                   : mknod(name, mode, dev);
+               }
+       }
+       if (rval < 0)
+               err(1, "%s", name);
+       if ((uid != (uid_t)-1 || gid != (uid_t)-1) && chown(name, uid, gid) == -1)
+               /* XXX Should we unlink the files here? */
+               warn("%s: uid/gid not changed", name);
+
+       return 0;
+}
+
+static void
+usage(void)
+{
+       const char *progname = getprogname();
+
+       (void)fprintf(stderr,
+           "usage: %s [-rR] [-F format] [-m mode] [-u user] [-g group]\n",
+           progname);
+       (void)fprintf(stderr,
+#ifdef KERN_DRIVERS
+           "                   [ name [b | c] [major | driver] minor\n"
+#else
+           "                   [ name [b | c] major minor\n"
+#endif
+           "                   | name [b | c] major unit subunit\n"
+           "                   | name [b | c] number\n"
+           "                   | name p ]\n");
+#ifdef KERN_DRIVERS
+       (void)fprintf(stderr, "       %s -l [driver] ...\n", progname);
+#endif
+       exit(1);
+}
+
+static int
+gid_name(const char *name, gid_t *gid)
+{
+       struct group *g;
+
+       g = getgrnam(name);
+       if (!g)
+               return -1;
+       *gid = g->gr_gid;
+       return 0;
+}
+
+static portdev_t
+callPack(pack_t *f, int n, u_long *numbers)
+{
+       portdev_t d;
+       const char *error = NULL;
+
+       d = (*f)(n, numbers, &error);
+       if (error != NULL)
+               errx(1, "%s", error);
+       return d;
+}
+
+#ifdef KERN_DRIVERS
+static void
+get_device_info(void)
+{
+       static int mib[2] = {CTL_KERN, KERN_DRIVERS};
+       size_t len;
+
+       if (sysctl(mib, 2, NULL, &len, NULL, 0) != 0)
+               err(1, "kern.drivers" );
+       kern_drivers = malloc(len);
+       if (kern_drivers == NULL)
+               err(1, "malloc");
+       if (sysctl(mib, 2, kern_drivers, &len, NULL, 0) != 0)
+               err(1, "kern.drivers" );
+
+       num_drivers = len / sizeof *kern_drivers;
+}
+
+static void
+print_device_info(char **names)
+{
+       int i;
+       struct kinfo_drivers *kd;
+
+       if (kern_drivers == NULL)
+               get_device_info();
+
+       do {
+               kd = kern_drivers;
+               for (i = 0; i < num_drivers; kd++, i++) {
+                       if (*names && strcmp(*names, kd->d_name))
+                               continue;
+                       printf("%s", kd->d_name);
+                       if (kd->d_cmajor != -1)
+                               printf(" character major %d", kd->d_cmajor);
+                       if (kd->d_bmajor != -1)
+                               printf(" block major %d", kd->d_bmajor);
+                       printf("\n");
+               }
+       } while (*names && *++names);
+}
+
+static int
+major_from_name(const char *name, mode_t mode)
+{
+       int i;
+       struct kinfo_drivers *kd;
+
+       if (kern_drivers == NULL)
+               get_device_info();
+
+       kd = kern_drivers;
+       for (i = 0; i < num_drivers; kd++, i++) {
+               if (strcmp(name, kd->d_name))
+                       continue;
+               if (S_ISCHR(mode))
+                       return kd->d_cmajor;
+               return kd->d_bmajor;
+       }
+       return -1;
+}
+#endif
diff --git a/sbin/mknod/pack_dev.c b/sbin/mknod/pack_dev.c
new file mode 100644 (file)
index 0000000..800a56c
--- /dev/null
@@ -0,0 +1,290 @@
+/*     $NetBSD: pack_dev.c,v 1.11 2011/08/27 18:37:41 joerg Exp $      */
+
+/*-
+ * Copyright (c) 1998, 2001 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Charles M. Hannum.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if HAVE_NBTOOL_CONFIG_H
+#include "nbtool_config.h"
+#endif
+
+#include <sys/cdefs.h>
+#if !defined(lint)
+__RCSID("$NetBSD: pack_dev.c,v 1.11 2011/08/27 18:37:41 joerg Exp $");
+#endif /* not lint */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "pack_dev.h"
+
+static pack_t  pack_netbsd;
+static pack_t  pack_freebsd;
+static pack_t  pack_8_8;
+static pack_t  pack_12_20;
+static pack_t  pack_14_18;
+static pack_t  pack_8_24;
+static pack_t  pack_bsdos;
+static int     compare_format(const void *, const void *);
+
+static const char iMajorError[] = "invalid major number";
+static const char iMinorError[] = "invalid minor number";
+static const char tooManyFields[] = "too many fields for format";
+
+       /* exported */
+portdev_t
+pack_native(int n, u_long numbers[], const char **error)
+{
+       portdev_t dev = 0;
+
+       if (n == 2) {
+               dev = makedev(numbers[0], numbers[1]);
+               if ((u_long)major(dev) != numbers[0])
+                       *error = iMajorError;
+               else if ((u_long)minor(dev) != numbers[1])
+                       *error = iMinorError;
+       } else
+               *error = tooManyFields;
+       return (dev);
+}
+
+
+static portdev_t
+pack_netbsd(int n, u_long numbers[], const char **error)
+{
+       portdev_t dev = 0;
+
+       if (n == 2) {
+               dev = makedev_netbsd(numbers[0], numbers[1]);
+               if ((u_long)major_netbsd(dev) != numbers[0])
+                       *error = iMajorError;
+               else if ((u_long)minor_netbsd(dev) != numbers[1])
+                       *error = iMinorError;
+       } else
+               *error = tooManyFields;
+       return (dev);
+}
+
+
+#define        major_freebsd(x)        ((int32_t)(((x) & 0x0000ff00) >> 8))
+#define        minor_freebsd(x)        ((int32_t)(((x) & 0xffff00ff) >> 0))
+#define        makedev_freebsd(x,y)    ((portdev_t)((((x) << 8) & 0x0000ff00) | \
+                                        (((y) << 0) & 0xffff00ff)))
+
+static portdev_t
+pack_freebsd(int n, u_long numbers[], const char **error)
+{
+       portdev_t dev = 0;
+
+       if (n == 2) {
+               dev = makedev_freebsd(numbers[0], numbers[1]);
+               if ((u_long)major_freebsd(dev) != numbers[0])
+                       *error = iMajorError;
+               if ((u_long)minor_freebsd(dev) != numbers[1])
+                       *error = iMinorError;
+       } else
+               *error = tooManyFields;
+       return (dev);
+}
+
+
+#define        major_8_8(x)            ((int32_t)(((x) & 0x0000ff00) >> 8))
+#define        minor_8_8(x)            ((int32_t)(((x) & 0x000000ff) >> 0))
+#define        makedev_8_8(x,y)        ((portdev_t)((((x) << 8) & 0x0000ff00) | \
+                                        (((y) << 0) & 0x000000ff)))
+
+static portdev_t
+pack_8_8(int n, u_long numbers[], const char **error)
+{
+       portdev_t dev = 0;
+
+       if (n == 2) {
+               dev = makedev_8_8(numbers[0], numbers[1]);
+               if ((u_long)major_8_8(dev) != numbers[0])
+                       *error = iMajorError;
+               if ((u_long)minor_8_8(dev) != numbers[1])
+                       *error = iMinorError;
+       } else
+               *error = tooManyFields;
+       return (dev);
+}
+
+
+#define        major_12_20(x)          ((int32_t)(((x) & 0xfff00000) >> 20))
+#define        minor_12_20(x)          ((int32_t)(((x) & 0x000fffff) >>  0))
+#define        makedev_12_20(x,y)      ((portdev_t)((((x) << 20) & 0xfff00000) | \
+                                        (((y) <<  0) & 0x000fffff)))
+
+static portdev_t
+pack_12_20(int n, u_long numbers[], const char **error)
+{
+       portdev_t dev = 0;
+
+       if (n == 2) {
+               dev = makedev_12_20(numbers[0], numbers[1]);
+               if ((u_long)major_12_20(dev) != numbers[0])
+                       *error = iMajorError;
+               if ((u_long)minor_12_20(dev) != numbers[1])
+                       *error = iMinorError;
+       } else
+               *error = tooManyFields;
+       return (dev);
+}
+
+
+#define        major_14_18(x)          ((int32_t)(((x) & 0xfffc0000) >> 18))
+#define        minor_14_18(x)          ((int32_t)(((x) & 0x0003ffff) >>  0))
+#define        makedev_14_18(x,y)      ((portdev_t)((((x) << 18) & 0xfffc0000) | \
+                                        (((y) <<  0) & 0x0003ffff)))
+
+static portdev_t
+pack_14_18(int n, u_long numbers[], const char **error)
+{
+       portdev_t dev = 0;
+
+       if (n == 2) {
+               dev = makedev_14_18(numbers[0], numbers[1]);
+               if ((u_long)major_14_18(dev) != numbers[0])
+                       *error = iMajorError;
+               if ((u_long)minor_14_18(dev) != numbers[1])
+                       *error = iMinorError;
+       } else
+               *error = tooManyFields;
+       return (dev);
+}
+
+
+#define        major_8_24(x)           ((int32_t)(((x) & 0xff000000) >> 24))
+#define        minor_8_24(x)           ((int32_t)(((x) & 0x00ffffff) >>  0))
+#define        makedev_8_24(x,y)       ((portdev_t)((((x) << 24) & 0xff000000) | \
+                                        (((y) <<  0) & 0x00ffffff)))
+
+static portdev_t
+pack_8_24(int n, u_long numbers[], const char **error)
+{
+       portdev_t dev = 0;
+
+       if (n == 2) {
+               dev = makedev_8_24(numbers[0], numbers[1]);
+               if ((u_long)major_8_24(dev) != numbers[0])
+                       *error = iMajorError;
+               if ((u_long)minor_8_24(dev) != numbers[1])
+                       *error = iMinorError;
+       } else
+               *error = tooManyFields;
+       return (dev);
+}
+
+
+#define        major_12_12_8(x)        ((int32_t)(((x) & 0xfff00000) >> 20))
+#define        unit_12_12_8(x)         ((int32_t)(((x) & 0x000fff00) >>  8))
+#define        subunit_12_12_8(x)      ((int32_t)(((x) & 0x000000ff) >>  0))
+#define        makedev_12_12_8(x,y,z)  ((portdev_t)((((x) << 20) & 0xfff00000) | \
+                                        (((y) <<  8) & 0x000fff00) | \
+                                        (((z) <<  0) & 0x000000ff)))
+
+static portdev_t
+pack_bsdos(int n, u_long numbers[], const char **error)
+{
+       portdev_t dev = 0;
+
+       if (n == 2) {
+               dev = makedev_12_20(numbers[0], numbers[1]);
+               if ((u_long)major_12_20(dev) != numbers[0])
+                       *error = iMajorError;
+               if ((u_long)minor_12_20(dev) != numbers[1])
+                       *error = iMinorError;
+       } else if (n == 3) {
+               dev = makedev_12_12_8(numbers[0], numbers[1], numbers[2]);
+               if ((u_long)major_12_12_8(dev) != numbers[0])
+                       *error = iMajorError;
+               if ((u_long)unit_12_12_8(dev) != numbers[1])
+                       *error = "invalid unit number";
+               if ((u_long)subunit_12_12_8(dev) != numbers[2])
+                       *error = "invalid subunit number";
+       } else
+               *error = tooManyFields;
+       return (dev);
+}
+
+
+               /* list of formats and pack functions */
+               /* this list must be sorted lexically */
+static struct format {
+       const char      *name;
+       pack_t          *pack;
+} formats[] = {
+       {"386bsd",  pack_8_8},
+       {"4bsd",    pack_8_8},
+       {"bsdos",   pack_bsdos},
+       {"freebsd", pack_freebsd},
+       {"hpux",    pack_8_24},
+       {"isc",     pack_8_8},
+       {"linux",   pack_8_8},
+       {"native",  pack_native},
+       {"netbsd",  pack_netbsd},
+       {"osf1",    pack_12_20},
+       {"sco",     pack_8_8},
+       {"solaris", pack_14_18},
+       {"sunos",   pack_8_8},
+       {"svr3",    pack_8_8},
+       {"svr4",    pack_14_18},
+       {"ultrix",  pack_8_8},
+};
+
+static int
+compare_format(const void *key, const void *element)
+{
+       const char              *name;
+       const struct format     *format;
+
+       name = key;
+       format = element;
+
+       return (strcmp(name, format->name));
+}
+
+
+pack_t *
+pack_find(const char *name)
+{
+       struct format   *format;
+
+       format = bsearch(name, formats,
+           sizeof(formats)/sizeof(formats[0]),
+           sizeof(formats[0]), compare_format);
+       if (format == 0)
+               return (NULL);
+       return (format->pack);
+}
diff --git a/sbin/mknod/pack_dev.h b/sbin/mknod/pack_dev.h
new file mode 100644 (file)
index 0000000..d909df4
--- /dev/null
@@ -0,0 +1,52 @@
+/*     $NetBSD: pack_dev.h,v 1.7 2008/04/28 20:23:09 martin Exp $      */
+
+/*-
+ * Copyright (c) 1998, 2001 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Charles M. Hannum.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef        _PACK_DEV_H
+#define        _PACK_DEV_H
+
+#ifdef __CYGWIN__
+typedef        __dev32_t       portdev_t;
+#else
+typedef        dev_t           portdev_t;
+#endif
+typedef        portdev_t pack_t(int, u_long [], const char **);
+
+pack_t *pack_find(const char *);
+pack_t  pack_native;
+
+#define        major_netbsd(x)         ((int32_t)((((x) & 0x000fff00) >>  8)))
+#define        minor_netbsd(x)         ((int32_t)((((x) & 0xfff00000) >> 12) | \
+                                          (((x) & 0x000000ff) >>  0)))
+#define        makedev_netbsd(x,y)     ((dev_t)((((x) <<  8) & 0x000fff00) | \
+                                        (((y) << 12) & 0xfff00000) | \
+                                        (((y) <<  0) & 0x000000ff)))
+
+#endif /* _PACK_DEV_H */
index ace63176878d88ba5c8c3ea1c349ceb50237e3ae..d06abea76ec81eb7f6b752aeed13a6e505816367 100644 (file)
@@ -3,6 +3,6 @@
 .include <bsd.own.mk>
 
 # NetBSD imports
-SUBDIR= installboot pwd_mkdb user vipw zic chroot mkfs.mfs
+SUBDIR= installboot pwd_mkdb user vipw zic chroot mkfs.mfs mtree
 
 .include <bsd.subdir.mk>
index 41b7b66f2876a6096a90b3f13d5b7b6d4e381983..bd81e34ccb40274917716d758b56fd505c6a8e0d 100644 (file)
@@ -1,14 +1,16 @@
-#      $NetBSD: Makefile,v 1.32 2009/04/22 15:23:05 lukem Exp $
+#      $NetBSD: Makefile,v 1.33 2012/10/05 01:26:56 christos Exp $
 #      from: @(#)Makefile      8.2 (Berkeley) 4/27/95
 
 .include <bsd.own.mk>
 
+CPPFLAGS+= -Dlchown=chown -Dlchmod=chmod 
+
 PROG=  mtree
 #CPPFLAGS+=-DDEBUG
 CPPFLAGS+= -DMTREE
 MAN=   mtree.8
-SRCS=  compare.c crc.c create.c excludes.c misc.c mtree.c spec.c verify.c \
-       getid.c pack_dev.c
+SRCS=  compare.c crc.c create.c excludes.c misc.c mtree.c spec.c specspec.c \
+       verify.c getid.c pack_dev.c
 .if (${HOSTPROG:U} == "")
 DPADD+= ${LIBUTIL}
 LDADD+= -lutil
index 8d96ed01f9cc7a86fed70eeb509ae935ce5413bc..8b66181ada4644ce081114753be974bb9a0ec37b 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: compare.c,v 1.52 2008/12/28 19:36:30 christos Exp $    */
+/*     $NetBSD: compare.c,v 1.55 2012/10/05 00:59:35 christos Exp $    */
 
 /*-
  * Copyright (c) 1989, 1993
 #if 0
 static char sccsid[] = "@(#)compare.c  8.1 (Berkeley) 6/6/93";
 #else
-__RCSID("$NetBSD: compare.c,v 1.52 2008/12/28 19:36:30 christos Exp $");
+__RCSID("$NetBSD: compare.c,v 1.55 2012/10/05 00:59:35 christos Exp $");
 #endif
 #endif /* not lint */
 
 #include <sys/param.h>
+#include <sys/stat.h>
 
 #include <errno.h>
 #include <fcntl.h>
@@ -83,6 +84,7 @@ do {                                                                  \
 
 #if HAVE_STRUCT_STAT_ST_FLAGS
 
+
 #define CHANGEFLAGS                                                    \
        if (flags != p->fts_statp->st_flags) {                          \
                char *sf;                                               \
@@ -124,6 +126,28 @@ do {                                                                       \
 } while (0)
 #endif /* HAVE_STRUCT_STAT_ST_FLAGS */
 
+#ifdef __minix
+#if 0
+int
+lchmod(const char *path, mode_t flags)
+{
+       return -1;
+}
+
+int
+lchown(const char *path, uid_t owner, gid_t group)
+{
+       return -1;
+}
+#endif
+
+int
+utimes(const char *path, const struct timeval times[2])
+{
+       return -1;
+}
+#endif
+
 int
 compare(NODE *s, FTSENT *p)
 {
@@ -174,7 +198,7 @@ typeerr:            LABEL;
        }
        if (mtree_Wflag)
                goto afterpermwhack;
-#if HAVE_STRUCT_STAT_ST_FLAGS && !defined(__minix)
+#if HAVE_STRUCT_STAT_ST_FLAGS
        if (iflag && !uflag) {
                if (s->flags & F_FLAGS)
                    SETFLAGS(p->fts_statp->st_flags, SP_FLGS);
@@ -194,7 +218,6 @@ typeerr:            LABEL;
                    tab, (long long)s->st_rdev,
                    (long long)p->fts_statp->st_rdev);
                if (uflag) {
-#ifndef __minix
                        if ((unlink(p->fts_accpath) == -1) ||
                            (mknod(p->fts_accpath,
                              s->st_mode | nodetoino(s->type),
@@ -205,7 +228,6 @@ typeerr:            LABEL;
                                    strerror(errno));
                         else
                                printf(", modified)\n");
-#endif
                } else
                        printf(")\n");
                tab = "\t";
@@ -216,13 +238,11 @@ typeerr:          LABEL;
                printf("%suser (%lu, %lu",
                    tab, (u_long)s->st_uid, (u_long)p->fts_statp->st_uid);
                if (uflag) {
-#ifndef __minix
                        if (lchown(p->fts_accpath, s->st_uid, -1))
                                printf(", not modified: %s)\n",
                                    strerror(errno));
                        else
                                printf(", modified)\n");
-#endif
                } else
                        printf(")\n");
                tab = "\t";
@@ -232,13 +252,11 @@ typeerr:          LABEL;
                printf("%sgid (%lu, %lu",
                    tab, (u_long)s->st_gid, (u_long)p->fts_statp->st_gid);
                if (uflag) {
-#ifndef __minix
                        if (lchown(p->fts_accpath, -1, s->st_gid))
                                printf(", not modified: %s)\n",
                                    strerror(errno));
                        else
                                printf(", modified)\n");
-#endif
                }
                else
                        printf(")\n");
@@ -267,13 +285,11 @@ typeerr:          LABEL;
                    tab, (u_long)s->st_mode,
                    (u_long)p->fts_statp->st_mode & MBITS);
                if (uflag) {
-#ifndef __minix                
                        if (lchmod(p->fts_accpath, s->st_mode))
                                printf(", not modified: %s)\n",
                                    strerror(errno));
                        else
                                printf(", modified)\n");
-#endif
                }
                else
                        printf(")\n");
@@ -328,20 +344,18 @@ typeerr:          LABEL;
                            tab, ctime(&smtime));
                        printf("%.24s", ctime(&pmtime));
                        if (tflag) {
-#ifndef __minix
                                tv[1] = tv[0];
                                if (utimes(p->fts_accpath, tv))
                                        printf(", not modified: %s)\n",
                                            strerror(errno));
                                else
                                        printf(", modified)\n");
-#endif
                        } else
                                printf(")\n");
                        tab = "\t";
                }
        }
-#if HAVE_STRUCT_STAT_ST_FLAGS && !defined(__minix)
+#if HAVE_STRUCT_STAT_ST_FLAGS
        /*
         * XXX
         * since lchflags(2) will reset file times, the utimes() above
@@ -404,14 +418,14 @@ typeerr:          LABEL;
        if (s->flags & F_MD5) {
                if ((digestbuf = MD5File(p->fts_accpath, NULL)) == NULL) {
                        LABEL;
-                       printf("%smd5: %s: %s\n",
-                           tab, p->fts_accpath, strerror(errno));
+                       printf("%s%s: %s: %s\n",
+                           tab, MD5KEY, p->fts_accpath, strerror(errno));
                        tab = "\t";
                } else {
                        if (strcmp(s->md5digest, digestbuf)) {
                                LABEL;
-                               printf("%smd5 (0x%s, 0x%s)\n",
-                                   tab, s->md5digest, digestbuf);
+                               printf("%s%s (0x%s, 0x%s)\n",
+                                   tab, MD5KEY, s->md5digest, digestbuf);
                        }
                        tab = "\t";
                        free(digestbuf);
@@ -422,14 +436,14 @@ typeerr:          LABEL;
        if (s->flags & F_RMD160) {
                if ((digestbuf = RMD160File(p->fts_accpath, NULL)) == NULL) {
                        LABEL;
-                       printf("%srmd160: %s: %s\n",
-                           tab, p->fts_accpath, strerror(errno));
+                       printf("%s%s: %s: %s\n",
+                           tab, RMD160KEY, p->fts_accpath, strerror(errno));
                        tab = "\t";
                } else {
                        if (strcmp(s->rmd160digest, digestbuf)) {
                                LABEL;
-                               printf("%srmd160 (0x%s, 0x%s)\n",
-                                   tab, s->rmd160digest, digestbuf);
+                               printf("%s%s (0x%s, 0x%s)\n",
+                                   tab, RMD160KEY, s->rmd160digest, digestbuf);
                        }
                        tab = "\t";
                        free(digestbuf);
@@ -440,14 +454,14 @@ typeerr:          LABEL;
        if (s->flags & F_SHA1) {
                if ((digestbuf = SHA1File(p->fts_accpath, NULL)) == NULL) {
                        LABEL;
-                       printf("%ssha1: %s: %s\n",
-                           tab, p->fts_accpath, strerror(errno));
+                       printf("%s%s: %s: %s\n",
+                           tab, SHA1KEY, p->fts_accpath, strerror(errno));
                        tab = "\t";
                } else {
                        if (strcmp(s->sha1digest, digestbuf)) {
                                LABEL;
-                               printf("%ssha1 (0x%s, 0x%s)\n",
-                                   tab, s->sha1digest, digestbuf);
+                               printf("%s%s (0x%s, 0x%s)\n",
+                                   tab, SHA1KEY, s->sha1digest, digestbuf);
                        }
                        tab = "\t";
                        free(digestbuf);
@@ -458,46 +472,48 @@ typeerr:          LABEL;
        if (s->flags & F_SHA256) {
                if ((digestbuf = SHA256_File(p->fts_accpath, NULL)) == NULL) {
                        LABEL;
-                       printf("%ssha256: %s: %s\n",
-                           tab, p->fts_accpath, strerror(errno));
+                       printf("%s%s: %s: %s\n",
+                           tab, SHA256KEY, p->fts_accpath, strerror(errno));
                        tab = "\t";
                } else {
                        if (strcmp(s->sha256digest, digestbuf)) {
                                LABEL;
-                               printf("%ssha256 (0x%s, 0x%s)\n",
-                                   tab, s->sha256digest, digestbuf);
+                               printf("%s%s (0x%s, 0x%s)\n",
+                                   tab, SHA256KEY, s->sha256digest, digestbuf);
                        }
                        tab = "\t";
                        free(digestbuf);
                }
        }
+#ifdef SHA384_BLOCK_LENGTH
        if (s->flags & F_SHA384) {
                if ((digestbuf = SHA384_File(p->fts_accpath, NULL)) == NULL) {
                        LABEL;
-                       printf("%ssha384: %s: %s\n",
-                           tab, p->fts_accpath, strerror(errno));
+                       printf("%s%s: %s: %s\n",
+                           tab, SHA384KEY, p->fts_accpath, strerror(errno));
                        tab = "\t";
                } else {
                        if (strcmp(s->sha384digest, digestbuf)) {
                                LABEL;
-                               printf("%ssha384 (0x%s, 0x%s)\n",
-                                   tab, s->sha384digest, digestbuf);
+                               printf("%s%s (0x%s, 0x%s)\n",
+                                   tab, SHA384KEY, s->sha384digest, digestbuf);
                        }
                        tab = "\t";
                        free(digestbuf);
                }
        }
+#endif
        if (s->flags & F_SHA512) {
                if ((digestbuf = SHA512_File(p->fts_accpath, NULL)) == NULL) {
                        LABEL;
-                       printf("%ssha512: %s: %s\n",
-                           tab, p->fts_accpath, strerror(errno));
+                       printf("%s%s: %s: %s\n",
+                           tab, SHA512KEY, p->fts_accpath, strerror(errno));
                        tab = "\t";
                } else {
                        if (strcmp(s->sha512digest, digestbuf)) {
                                LABEL;
-                               printf("%ssha512 (0x%s, 0x%s)\n",
-                                   tab, s->sha512digest, digestbuf);
+                               printf("%s%s (0x%s, 0x%s)\n",
+                                   tab, SHA512KEY, s->sha512digest, digestbuf);
                        }
                        tab = "\t";
                        free(digestbuf);
index 6e2dfd41076531f763ad93723f56456c06a4d6c7..4eac66e5b9952df0991c6831d445a374957bc5ba 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: crc.c,v 1.8 2005/06/02 06:04:46 lukem Exp $    */
+/*     $NetBSD: crc.c,v 1.9 2012/10/05 00:40:51 christos Exp $ */
 
 /*-
  * Copyright (c) 1991, 1993
@@ -41,7 +41,7 @@
 #if 0
 static char sccsid[] = "@(#)crc.c      8.1 (Berkeley) 6/17/93";
 #else
-__RCSID("$NetBSD: crc.c,v 1.8 2005/06/02 06:04:46 lukem Exp $");
+__RCSID("$NetBSD: crc.c,v 1.9 2012/10/05 00:40:51 christos Exp $");
 #endif
 #endif /* not lint */
 
@@ -114,7 +114,6 @@ static const u_int32_t crctab[] = {
  * locations to store the crc and the number of bytes read.  It returns 0 on
  * success and 1 on failure.  Errno is set on failure.
  */
-extern int sflag;
 u_int32_t crc_total = ~0;              /* The crc over a number of files. */
 
 int
index fdc8d693259ded28581d44e31aa60b88feb6d547..b9a3c44eed9d8dd643ca1c0dd606f89eb34e1848 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: create.c,v 1.58 2009/04/03 21:18:59 apb Exp $  */
+/*     $NetBSD: create.c,v 1.65 2012/10/05 01:21:44 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.58 2009/04/03 21:18:59 apb Exp $");
+__RCSID("$NetBSD: create.c,v 1.65 2012/10/05 01:21:44 christos Exp $");
 #endif
 #endif /* not lint */
 
@@ -83,11 +83,17 @@ static uid_t uid;
 static mode_t mode;
 static u_long flags;
 
-static int     dcmp(const FTSENT **, const FTSENT **);
-static void    output(int *, const char *, ...)
-       __attribute__((__format__(__printf__, 2, 3)));
+#ifdef __FreeBSD__
+#define        FTS_CONST const
+#else
+#define        FTS_CONST
+#endif
+
+static int     dcmp(const FTSENT *FTS_CONST *, const FTSENT *FTS_CONST *);
+static void    output(int, int *, const char *, ...)
+       __attribute__((__format__(__printf__, 3, 4)));
 static int     statd(FTS *, FTSENT *, uid_t *, gid_t *, mode_t *, u_long *);
-static void    statf(FTSENT *);
+static void    statf(int, FTSENT *);
 
 void
 cwalk(void)
@@ -99,6 +105,7 @@ cwalk(void)
        const char *user;
        char *argv[2];
        char  dot[] = ".";
+       int indent = 0;
 
        argv[0] = dot;
        argv[1] = NULL;
@@ -112,26 +119,32 @@ cwalk(void)
                    "<unknown>";
        }
 
-       printf(
-           "#\t   user: %s\n#\tmachine: %s\n#\t   tree: %s\n#\t   date: %s",
-           user, host, fullpath, ctime(&clocktime));
+       if (!nflag)
+               printf(
+                   "#\t   user: %s\n#\tmachine: %s\n#\t   tree: %s\n"
+                   "#\t   date: %s",
+                   user, host, fullpath, ctime(&clocktime));
 
        if ((t = fts_open(argv, ftsoptions, dcmp)) == NULL)
                mtree_err("fts_open: %s", strerror(errno));
        while ((p = fts_read(t)) != NULL) {
+               if (jflag)
+                       indent = p->fts_level * 4;
                if (check_excludes(p->fts_name, p->fts_path)) {
                        fts_set(t, p, FTS_SKIP);
                        continue;
                }
                switch(p->fts_info) {
                case FTS_D:
-                       printf("\n# %s\n", p->fts_path);
+                       if (!nflag)
+                               printf("\n# %s\n", p->fts_path);
                        statd(t, p, &uid, &gid, &mode, &flags);
-                       statf(p);
+                       statf(indent, p);
                        break;
                case FTS_DP:
-                       if (p->fts_level > 0)
-                               printf("# %s\n..\n\n", p->fts_path);
+                       if (!nflag && p->fts_level > 0)
+                               printf("%*s# %s\n%*s..\n\n", indent, "",
+                                   p->fts_path, indent, "");
                        break;
                case FTS_DNR:
                case FTS_ERR:
@@ -141,7 +154,7 @@ cwalk(void)
                        break;
                default:
                        if (!dflag)
-                               statf(p);
+                               statf(indent, p);
                        break;
 
                }
@@ -152,56 +165,59 @@ cwalk(void)
 }
 
 static void
-statf(FTSENT *p)
+statf(int indent, FTSENT *p)
 {
        u_int32_t len, val;
-       int fd, indent;
-       const char *name;
+       int fd, offset;
+       const char *name = NULL;
 #if !defined(NO_MD5) || !defined(NO_RMD160) || !defined(NO_SHA1) || !defined(NO_SHA2)
        char *digestbuf;
 #endif
 
-       indent = printf("%s%s",
+       offset = printf("%*s%s%s", indent, "",
            S_ISDIR(p->fts_statp->st_mode) ? "" : "    ", vispath(p->fts_name));
 
-       if (indent > INDENTNAMELEN)
-               indent = MAXLINELEN;
+       if (offset > (INDENTNAMELEN + indent))
+               offset = MAXLINELEN;
        else
-               indent += printf("%*s", INDENTNAMELEN - indent, "");
+               offset += printf("%*s", (INDENTNAMELEN + indent) - offset, "");
 
        if (!S_ISREG(p->fts_statp->st_mode))
-               output(&indent, "type=%s", inotype(p->fts_statp->st_mode));
+               output(indent, &offset, "type=%s",
+                   inotype(p->fts_statp->st_mode));
        if (keys & (F_UID | F_UNAME) && p->fts_statp->st_uid != uid) {
                if (keys & F_UNAME &&
                    (name = user_from_uid(p->fts_statp->st_uid, 1)) != NULL)
-                       output(&indent, "uname=%s", name);
-               else /* if (keys & F_UID) */
-                       output(&indent, "uid=%u", p->fts_statp->st_uid);
+                       output(indent, &offset, "uname=%s", name);
+               if (keys & F_UID || (keys & F_UNAME && name == NULL))
+                       output(indent, &offset, "uid=%u", p->fts_statp->st_uid);
        }
        if (keys & (F_GID | F_GNAME) && p->fts_statp->st_gid != gid) {
                if (keys & F_GNAME &&
                    (name = group_from_gid(p->fts_statp->st_gid, 1)) != NULL)
-                       output(&indent, "gname=%s", name);
-               else /* if (keys & F_GID) */
-                       output(&indent, "gid=%u", p->fts_statp->st_gid);
+                       output(indent, &offset, "gname=%s", name);
+               if (keys & F_GID || (keys & F_GNAME && name == NULL))
+                       output(indent, &offset, "gid=%u", p->fts_statp->st_gid);
        }
        if (keys & F_MODE && (p->fts_statp->st_mode & MBITS) != mode)
-               output(&indent, "mode=%#o", p->fts_statp->st_mode & MBITS);
+               output(indent, &offset, "mode=%#o",
+                   p->fts_statp->st_mode & MBITS);
        if (keys & F_DEV &&
            (S_ISBLK(p->fts_statp->st_mode) || S_ISCHR(p->fts_statp->st_mode)))
-               output(&indent, "device=%#llx",
+               output(indent, &offset, "device=%#llx",
                    (long long)p->fts_statp->st_rdev);
        if (keys & F_NLINK && p->fts_statp->st_nlink != 1)
-               output(&indent, "nlink=%u", p->fts_statp->st_nlink);
+               output(indent, &offset, "nlink=%u", p->fts_statp->st_nlink);
        if (keys & F_SIZE && S_ISREG(p->fts_statp->st_mode))
-               output(&indent, "size=%lld", (long long)p->fts_statp->st_size);
+               output(indent, &offset, "size=%lld",
+                   (long long)p->fts_statp->st_size);
        if (keys & F_TIME)
 #if defined(BSD4_4) && !defined(HAVE_NBTOOL_CONFIG_H)
-               output(&indent, "time=%ld.%ld",
+               output(indent, &offset, "time=%ld.%09ld",
                    (long)p->fts_statp->st_mtimespec.tv_sec,
                    p->fts_statp->st_mtimespec.tv_nsec);
 #else
-               output(&indent, "time=%ld.%ld",
+               output(indent, &offset, "time=%ld.%09ld",
                    (long)p->fts_statp->st_mtime, (long)0);
 #endif
        if (keys & F_CKSUM && S_ISREG(p->fts_statp->st_mode)) {
@@ -209,59 +225,70 @@ statf(FTSENT *p)
                    crc(fd, &val, &len))
                        mtree_err("%s: %s", p->fts_accpath, strerror(errno));
                close(fd);
-               output(&indent, "cksum=%lu", (long)val);
+               output(indent, &offset, "cksum=%lu", (long)val);
        }
 #ifndef NO_MD5
        if (keys & F_MD5 && S_ISREG(p->fts_statp->st_mode)) {
                if ((digestbuf = MD5File(p->fts_accpath, NULL)) == NULL)
-                       mtree_err("%s: MD5File failed: %s", p->fts_accpath, strerror(errno));
-               output(&indent, "md5=%s", digestbuf);
+                       mtree_err("%s: MD5File failed: %s", p->fts_accpath,
+                           strerror(errno));
+               output(indent, &offset, "%s=%s", MD5KEY, digestbuf);
                free(digestbuf);
        }
 #endif /* ! NO_MD5 */
 #ifndef NO_RMD160
        if (keys & F_RMD160 && S_ISREG(p->fts_statp->st_mode)) {
                if ((digestbuf = RMD160File(p->fts_accpath, NULL)) == NULL)
-                       mtree_err("%s: RMD160File failed: %s", p->fts_accpath, strerror(errno));
-               output(&indent, "rmd160=%s", digestbuf);
+                       mtree_err("%s: RMD160File failed: %s", p->fts_accpath,
+                           strerror(errno));
+               output(indent, &offset, "%s=%s", RMD160KEY, digestbuf);
                free(digestbuf);
        }
 #endif /* ! NO_RMD160 */
 #ifndef NO_SHA1
        if (keys & F_SHA1 && S_ISREG(p->fts_statp->st_mode)) {
                if ((digestbuf = SHA1File(p->fts_accpath, NULL)) == NULL)
-                       mtree_err("%s: SHA1File failed: %s", p->fts_accpath, strerror(errno));
-               output(&indent, "sha1=%s", digestbuf);
+                       mtree_err("%s: SHA1File failed: %s", p->fts_accpath,
+                           strerror(errno));
+               output(indent, &offset, "%s=%s", SHA1KEY, digestbuf);
                free(digestbuf);
        }
 #endif /* ! NO_SHA1 */
 #ifndef NO_SHA2
        if (keys & F_SHA256 && S_ISREG(p->fts_statp->st_mode)) {
                if ((digestbuf = SHA256_File(p->fts_accpath, NULL)) == NULL)
-                       mtree_err("%s: SHA256_File failed: %s", p->fts_accpath, strerror(errno));
-               output(&indent, "sha256=%s", digestbuf);
+                       mtree_err("%s: SHA256_File failed: %s", p->fts_accpath,
+                           strerror(errno));
+               output(indent, &offset, "%s=%s", SHA256KEY, digestbuf);
                free(digestbuf);
        }
+#ifdef SHA384_BLOCK_LENGTH
        if (keys & F_SHA384 && S_ISREG(p->fts_statp->st_mode)) {
                if ((digestbuf = SHA384_File(p->fts_accpath, NULL)) == NULL)
-                       mtree_err("%s: SHA384_File failed: %s", p->fts_accpath, strerror(errno));
-               output(&indent, "sha384=%s", digestbuf);
+                       mtree_err("%s: SHA384_File failed: %s", p->fts_accpath,
+                           strerror(errno));
+               output(indent, &offset, "%s=%s", SHA384KEY, digestbuf);
                free(digestbuf);
        }
+#endif
        if (keys & F_SHA512 && S_ISREG(p->fts_statp->st_mode)) {
                if ((digestbuf = SHA512_File(p->fts_accpath, NULL)) == NULL)
-                       mtree_err("%s: SHA512_File failed: %s", p->fts_accpath, strerror(errno));
-               output(&indent, "sha512=%s", digestbuf);
+                       mtree_err("%s: SHA512_File failed: %s", p->fts_accpath,
+                           strerror(errno));
+               output(indent, &offset, "%s=%s", SHA512KEY, digestbuf);
                free(digestbuf);
        }
 #endif /* ! NO_SHA2 */
        if (keys & F_SLINK &&
            (p->fts_info == FTS_SL || p->fts_info == FTS_SLNONE))
-               output(&indent, "link=%s", vispath(rlink(p->fts_accpath)));
+               output(indent, &offset, "link=%s",
+                   vispath(rlink(p->fts_accpath)));
 #if HAVE_STRUCT_STAT_ST_FLAGS
-       if (keys & F_FLAGS && p->fts_statp->st_flags != flags)
-               output(&indent, "flags=%s",
-                   flags_to_string(p->fts_statp->st_flags, "none"));
+       if (keys & F_FLAGS && p->fts_statp->st_flags != flags) {
+               char *str = flags_to_string(p->fts_statp->st_flags, "none");
+               output(indent, &offset, "flags=%s", str);
+               free(str);
+       }
 #endif
        putchar('\n');
 }
@@ -291,7 +318,7 @@ statd(FTS *t, FTSENT *parent, uid_t *puid, gid_t *pgid, mode_t *pmode,
        uid_t suid;
        mode_t smode;
        u_long sflags = 0;
-       const char *name;
+       const char *name = NULL;
        gid_t savegid;
        uid_t saveuid;
        mode_t savemode;
@@ -358,23 +385,25 @@ statd(FTS *t, FTSENT *parent, uid_t *puid, gid_t *pgid, mode_t *pmode,
                        if (keys & F_UNAME &&
                            (name = user_from_uid(saveuid, 1)) != NULL)
                                printf(" uname=%s", name);
-                       else /* if (keys & F_UID) */
+                       if (keys & F_UID || (keys & F_UNAME && name == NULL))
                                printf(" uid=%lu", (u_long)saveuid);
                }
                if (keys & (F_GID | F_GNAME)) {
                        if (keys & F_GNAME &&
                            (name = group_from_gid(savegid, 1)) != NULL)
                                printf(" gname=%s", name);
-                       else /* if (keys & F_UID) */
+                       if (keys & F_GID || (keys & F_GNAME && name == NULL))
                                printf(" gid=%lu", (u_long)savegid);
                }
                if (keys & F_MODE)
                        printf(" mode=%#lo", (u_long)savemode);
                if (keys & F_NLINK)
                        printf(" nlink=1");
-               if (keys & F_FLAGS)
-                       printf(" flags=%s",
-                           flags_to_string(saveflags, "none"));
+               if (keys & F_FLAGS) {
+                       char *str = flags_to_string(saveflags, "none");
+                       printf(" flags=%s", str);
+                       free(str);
+               }
                printf("\n");
                *puid = saveuid;
                *pgid = savegid;
@@ -394,7 +423,7 @@ statd(FTS *t, FTSENT *parent, uid_t *puid, gid_t *pgid, mode_t *pmode,
  * Keep this in sync with nodecmp() in spec.c.
  */
 static int
-dcmp(const FTSENT **a, const FTSENT **b)
+dcmp(const FTSENT *FTS_CONST *a, const FTSENT *FTS_CONST *b)
 {
 
        if (S_ISDIR((*a)->fts_statp->st_mode)) {
@@ -406,7 +435,7 @@ dcmp(const FTSENT **a, const FTSENT **b)
 }
 
 void
-output(int *offset, const char *fmt, ...)
+output(int indent, int *offset, const char *fmt, ...)
 {
        va_list ap;
        char buf[1024];
@@ -416,8 +445,8 @@ output(int *offset, const char *fmt, ...)
        va_end(ap);
 
        if (*offset + strlen(buf) > MAXLINELEN - 3) {
-               printf(" \\\n%*s", INDENTNAMELEN, "");
-               *offset = INDENTNAMELEN;
+               printf(" \\\n%*s", INDENTNAMELEN + indent, "");
+               *offset = INDENTNAMELEN + indent;
        }
        *offset += printf(" %s", buf) + 1;
 }
index 31d479246f6c548ae5bced2a58f398ae347c915a..0070816849d90e50f4da3e4a66b2d0a161cc3442 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: extern.h,v 1.32 2011/08/29 20:37:43 joerg Exp $        */
+/*     $NetBSD: extern.h,v 1.36 2012/10/05 01:26:56 christos Exp $     */
 
 /*-
  * Copyright (c) 1991, 1993
 #if HAVE_NBTOOL_CONFIG_H
 #include "nbtool_config.h"
 #else 
+#ifndef __minix
 #define HAVE_STRUCT_STAT_ST_FLAGS 1
 #endif
+#endif
  
 #include <err.h> 
 #include <fts.h>
@@ -67,9 +69,10 @@ void  parsetags(slist_t *, char *);
 u_int   parsetype(const char *);
 void    read_excludes_file(const char *);
 const char *rlink(const char *);
-int     verify(void);
+int     verify(FILE *);
 
-extern int     dflag, eflag, iflag, lflag, mflag, rflag, sflag, tflag, uflag;
+extern int     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 u_int32_t crc_total;
index ba6a5ee1d7d8d9c363510cd5664e80413ff8f9e4..4c5e5f6a4e3c2290ee8092da09c2f7f9463ff71c 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: misc.c,v 1.30 2009/01/18 12:09:38 lukem Exp $  */
+/*     $NetBSD: misc.c,v 1.32 2012/10/05 01:31:05 christos Exp $       */
 
 /*-
  * Copyright (c) 1991, 1993
@@ -37,7 +37,7 @@
 
 #include <sys/cdefs.h>
 #if defined(__RCSID) && !defined(lint)
-__RCSID("$NetBSD: misc.c,v 1.30 2009/01/18 12:09:38 lukem Exp $");
+__RCSID("$NetBSD: misc.c,v 1.32 2012/10/05 01:31:05 christos Exp $");
 #endif /* not lint */
 
 #include <sys/types.h>
@@ -71,7 +71,10 @@ static KEY keylist[] = {
        {"md5digest",   F_MD5,          NEEDVALUE},
        {"mode",        F_MODE,         NEEDVALUE},
        {"nlink",       F_NLINK,        NEEDVALUE},
+       {"nochange",    F_NOCHANGE,     0},
        {"optional",    F_OPT,          0},
+       {"ripemd160digest", F_RMD160,   NEEDVALUE},
+       {"rmd160digest",F_RMD160,       NEEDVALUE},
        {"rmd160",      F_RMD160,       NEEDVALUE},
        {"rmd160digest",F_RMD160,       NEEDVALUE},
        {"sha1",        F_SHA1,         NEEDVALUE},
index 8a150b6a92cc30496104704e802dd411b399b51e..67ffb73fc34b2a57f38ed33e26c42abc112a6168 100644 (file)
@@ -1,4 +1,4 @@
-.\"    $NetBSD: mtree.8,v 1.53 2010/01/20 14:00:48 wiz Exp $
+.\"    $NetBSD: mtree.8,v 1.63 2012/10/05 09:18:02 wiz 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 January 20, 2010
+.Dd October 4, 2012
 .Dt MTREE 8
 .Os
 .Sh NAME
@@ -64,7 +64,7 @@
 .Nd map a directory hierarchy
 .Sh SYNOPSIS
 .Nm
-.Op Fl CcDdeLlMPrSUuWx
+.Op Fl CcDdejLlMnPqrSUuWx
 .Op Fl i | Fl m
 .Op Fl E Ar tags
 .Op Fl f Ar spec
@@ -104,8 +104,8 @@ The full path name
 (beginning with
 .Dq \&./ )
 is always printed as the first field;
-.Fl k ,
 .Fl K ,
+.Fl k ,
 and
 .Fl R
 can be used to control which other keywords are printed;
@@ -113,6 +113,7 @@ can be used to control which other keywords are printed;
 and
 .Fl I
 can be used to control which files are printed;
+and the
 .Fl S
 option can be used to sort the output.
 .It Fl c
@@ -143,6 +144,17 @@ specification.
 Read the specification from
 .Ar file  ,
 instead of from the standard input.
+.Pp
+If this option is specified twice, the two specifications are compared
+to each other rather than to the file hierarchy.
+The specifications will be sorted like output generated using
+.Fl c .
+The output format in this case is somewhat reminiscent of
+.Xr comm 1 ,
+having "in first spec only", "in second spec only", and "different"
+columns, prefixed by zero, one and two TAB characters respectively.
+Each entry in the "different" column occupies two lines, one from each
+specification.
 .It Fl I Ar tags
 Add the comma separated tags to the
 .Dq inclusion
@@ -154,6 +166,20 @@ and
 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.
+.It Fl j
+Indent the output 4 spaces each time a directory level is descended when
+creating a specification with the
+.Fl c
+option.
+This does not affect either the /set statements or the comment before each
+directory.
+It does however affect the comment before the close of each directory.
+This is the equivalent of the
+.Fl i
+option in the
+.Fx
+version of
+.Nm .
 .It Fl K Ar keywords
 Add the specified (whitespace or comma separated) keywords to the current
 set of keywords.
@@ -187,13 +213,13 @@ particular, if other bits like the sticky bit or suid/sgid bits are
 set either in the specification or the file, exact checking will be
 performed.
 This option may not be set at the same time as the
-.Fl u
-or
 .Fl U
+or
+.Fl u
 option.
 .It Fl M
 Permit merging of specification entries with different types,
-with the last entry take precedence.
+with the last entry taking precedence.
 .It Fl m
 If the schg and/or sappnd flags are specified, reset these flags.
 Note that this is only possible with securelevel less than 1 (i.e.,
@@ -202,6 +228,13 @@ mode).
 See
 .Xr init 8
 for information on security levels.
+.It Fl n
+Do not emit pathname comments when creating a specification.
+Normally
+a comment is emitted before each directory and before the close of that
+directory when using the
+.Fl c
+option.
 .It Fl N Ar dbdir
 Use the user database text file
 .Pa master.passwd
@@ -222,6 +255,12 @@ This is the default.
 Use the file hierarchy rooted in
 .Ar path  ,
 instead of the current directory.
+.It Fl q
+Quiet mode.
+Do not complain when a
+.Dq missing
+directory cannot be created because it already exists.
+This occurs when the directory is a symbolic link.
 .It Fl R Ar keywords
 Remove the specified (whitespace or comma separated) keywords from the current
 set of keywords.
@@ -287,9 +326,9 @@ Don't attempt to set various file attributes such as the
 ownership, mode, flags, or time
 when creating new directories or changing existing entries.
 This option will be most useful when used in conjunction with
-.Fl u
+.Fl U
 or
-.Fl U .
+.Fl u .
 .It Fl X Ar exclude-file
 The specified file contains
 .Xr fnmatch 3
@@ -329,7 +368,6 @@ or
 .Sy char
 file types.
 The argument must be one of the following forms:
-.Pp
 .Bl -tag -width 4n
 .It Ar format , Ns Ar major , Ns Ar minor
 A device with
@@ -411,9 +449,14 @@ The current file's permissions as a numeric (octal) or symbolic
 value.
 .It Sy nlink
 The number of hard links the file is expected to have.
+.It Sy nochange
+Make sure this file or directory exists but otherwise ignore all attributes.
 .It Sy optional
 The file is optional; don't complain about the file if it's
 not in the file hierarchy.
+.It Sy ripemd160digest
+Synonym for
+.Sy rmd160 .
 .It Sy rmd160
 The
 .Tn RMD-160
@@ -459,7 +502,10 @@ and
 These may be specified without leading or trailing commas, but will be
 stored internally with them.
 .It Sy time
-The last modification time of the file.
+The last modification time of the file,
+in second and nanoseconds.
+The value should include a period character and exactly nine digits after
+the period.
 .It Sy type
 The type of the file; may be set to any one of the following:
 .Pp
@@ -498,7 +544,6 @@ and
 .Sy uid .
 .Pp
 There are four types of lines in a specification:
-.Pp
 .Bl -enum
 .It
 Set global values for a keyword.
@@ -581,7 +626,7 @@ appropriately.
 Multiple entries for the same full path are permitted if the types
 are the same (unless
 .Fl M
-is given, and then the types may differ);
+is given, in which case the types may differ);
 in this case the settings for the last entry take precedence.
 .Pp
 A path name that does not contain a slash will be treated as a relative path.
@@ -631,10 +676,11 @@ can be used to detect which of the binaries have actually been modified.
 .Pp
 The
 .Fl d
-and
+option can be used in combination with
+.Fl U
+or
 .Fl u
-options can be used in combination to create directory hierarchies
-for distributions and other such things.
+to create directory hierarchies for, for example, distributions.
 .Sh SEE ALSO
 .Xr chflags 1 ,
 .Xr chgrp 1 ,
@@ -681,8 +727,8 @@ keywords,
 .Fl D ,
 .Fl E ,
 .Fl I ,
-.Fl l ,
 .Fl L ,
+.Fl l ,
 .Fl N ,
 .Fl P ,
 .Fl R ,
index 31219abfc9b94a390640d11e489a03ea9fcc2cf2..2174b3d9d846baf22e213d78b0f486de335a21cc 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: mtree.c,v 1.37 2011/08/29 20:37:43 joerg Exp $ */
+/*     $NetBSD: mtree.c,v 1.42 2012/10/05 09:18:08 wiz Exp $   */
 
 /*-
  * Copyright (c) 1989, 1990, 1993
@@ -43,7 +43,7 @@ __COPYRIGHT("@(#) Copyright (c) 1989, 1990, 1993\
 #if 0
 static char sccsid[] = "@(#)mtree.c    8.1 (Berkeley) 6/6/93";
 #else
-__RCSID("$NetBSD: mtree.c,v 1.37 2011/08/29 20:37:43 joerg Exp $");
+__RCSID("$NetBSD: mtree.c,v 1.42 2012/10/05 09:18:08 wiz Exp $");
 #endif
 #endif /* not lint */
 
@@ -59,8 +59,8 @@ __RCSID("$NetBSD: mtree.c,v 1.37 2011/08/29 20:37:43 joerg Exp $");
 #include "extern.h"
 
 int    ftsoptions = FTS_PHYSICAL;
-int    cflag, Cflag, dflag, Dflag, eflag, iflag, lflag, mflag,
-       rflag, sflag, tflag, uflag, Uflag;
+int    cflag, Cflag, dflag, Dflag, eflag, iflag, jflag, lflag, mflag,
+       nflag, qflag, rflag, sflag, tflag, uflag, Uflag;
 char   fullpath[MAXPATHLEN];
 
 __dead static  void    usage(void);
@@ -70,14 +70,17 @@ main(int argc, char **argv)
 {
        int     ch, status;
        char    *dir, *p;
+       FILE    *spec1, *spec2;
 
        setprogname(argv[0]);
 
        dir = NULL;
        init_excludes();
+       spec1 = stdin;
+       spec2 = NULL;
 
        while ((ch = getopt(argc, argv,
-           "cCdDeE:f:I:ik:K:lLmMN:p:PrR:s:StuUWxX:"))
+           "cCdDeE:f:I:ik:K:lLmMnN:p:PqrR:s:StuUWxX:"))
            != -1) {
                switch((char)ch) {
                case 'c':
@@ -99,8 +102,18 @@ main(int argc, char **argv)
                        eflag = 1;
                        break;
                case 'f':
-                       if (!(freopen(optarg, "r", stdin)))
-                               mtree_err("%s: %s", optarg, strerror(errno));
+                       if (spec1 == stdin) {
+                               spec1 = fopen(optarg, "r");
+                               if (spec1 == NULL)
+                                       mtree_err("%s: %s", optarg,
+                                           strerror(errno));
+                       } else if (spec2 == NULL) {
+                               spec2 = fopen(optarg, "r");
+                               if (spec2 == NULL)
+                                       mtree_err("%s: %s", optarg,
+                                           strerror(errno));
+                       } else
+                               usage();
                        break;
                case 'i':
                        iflag = 1;
@@ -108,6 +121,9 @@ main(int argc, char **argv)
                case 'I':
                        parsetags(&includetags, optarg);
                        break;
+               case 'j':
+                       jflag = 1;
+                       break;
                case 'k':
                        keys = F_TYPE;
                        while ((p = strsep(&optarg, " \t,")) != NULL)
@@ -132,6 +148,9 @@ main(int argc, char **argv)
                case 'M':
                        mtree_Mflag = 1;
                        break;
+               case 'n':
+                       nflag = 1;
+                       break;
                case 'N':
                        if (! setup_getid(optarg))
                                mtree_err(
@@ -145,6 +164,9 @@ main(int argc, char **argv)
                        ftsoptions &= ~FTS_LOGICAL;
                        ftsoptions |= FTS_PHYSICAL;
                        break;
+               case 'q':
+                       qflag = 1;
+                       break;
                case 'r':
                        rflag = 1;
                        break;
@@ -163,11 +185,9 @@ main(int argc, char **argv)
                        mtree_Sflag = 1;
                        break;
                case 't':
-                       mtree_err("Minix does not support utimes(2)");
                        tflag = 1;
                        break;
                case 'u':
-                       mtree_err("Minix does not support lchmod(3)");
                        uflag = 1;
                        break;
                case 'U':
@@ -193,6 +213,13 @@ main(int argc, char **argv)
        if (argc)
                usage();
 
+       if (spec2 && (cflag || Cflag || Dflag))
+               mtree_err("Double -f, -c, -C and -D flags are mutually "
+                   "exclusive");
+
+       if (dir && spec2)
+               mtree_err("Double -f and -p flags are mutually exclusive");
+
        if (dir && chdir(dir))
                mtree_err("%s: %s", dir, strerror(errno));
 
@@ -213,10 +240,13 @@ main(int argc, char **argv)
                exit(0);
        }
        if (Cflag || Dflag) {
-               dump_nodes("", spec(stdin), Dflag);
+               dump_nodes("", spec(spec1), Dflag);
                exit(0);
        }
-       status = verify();
+       if (spec2 != NULL)
+               status = mtree_specspec(spec1, spec2);
+       else
+               status = verify(spec1);
        if (Uflag && (status == MISMATCHEXIT))
                status = 0;
        exit(status);
@@ -227,7 +257,8 @@ usage(void)
 {
 
        fprintf(stderr,
-           "usage: %s [-CcDdeLlMPrSUuWx] [-i|-m] [-E tags] [-f spec]\n"
+           "usage: %s [-CcDdejLlMnPqrSUuWx] [-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",
            getprogname());
index 81e53867557ac038428eee4d68f845dca808b1d7..93d6cdfb0e7bb9c2743597e66a422218ee5d952b 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: mtree.h,v 1.27 2009/04/04 21:49:49 apb Exp $   */
+/*     $NetBSD: mtree.h,v 1.31 2012/10/05 09:17:29 wiz Exp $   */
 
 /*-
  * Copyright (c) 1990, 1993
@@ -86,6 +86,8 @@ typedef struct _node {
 #define        F_UID           0x00080000              /* uid */
 #define        F_UNAME         0x00100000              /* user name */
 #define        F_VISIT         0x00200000              /* file visited */
+#define        F_NOCHANGE      0x00400000              /* check existence, but not */
+                                               /* other properties */
 #define        F_SHA256        0x00800000              /* SHA256 digest */
 #define        F_SHA384        0x01000000              /* SHA384 digest */
 #define        F_SHA512        0x02000000              /* SHA512 digest */
@@ -120,9 +122,26 @@ const char *inotype(u_int);
 u_int           nodetoino(u_int);
 int             setup_getid(const char *);
 NODE           *spec(FILE *);
+int             mtree_specspec(FILE *, FILE *);
 void            free_nodes(NODE *);
 char           *vispath(const char *);
 
+#ifdef __FreeBSD__
+#define KEY_DIGEST "digest"
+#else
+#define KEY_DIGEST
+#endif
+
+#define        MD5KEY          "md5"           KEY_DIGEST
+#ifdef __FreeBSD__
+#define        RMD160KEY       "ripemd160"     KEY_DIGEST
+#else
+#define        RMD160KEY       "rmd160"        KEY_DIGEST
+#endif
+#define        SHA1KEY         "sha1"          KEY_DIGEST
+#define        SHA256KEY       "sha256"        KEY_DIGEST
+#define        SHA384KEY       "sha384"
+#define        SHA512KEY       "sha512"
 
 #define        RP(p)   \
        ((p)->fts_path[0] == '.' && (p)->fts_path[1] == '/' ? \
index 1d52efd3da61a4fc04520bc05d3615dcc96c8a98..1dcedb434dd987fedb98ffbba7e8a856ef32b012 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: spec.c,v 1.80 2012/03/15 02:02:24 joerg Exp $  */
+/*     $NetBSD: spec.c,v 1.84 2012/10/07 18:40:49 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.80 2012/03/15 02:02:24 joerg Exp $");
+__RCSID("$NetBSD: spec.c,v 1.84 2012/10/07 18:40:49 christos Exp $");
 #endif
 #endif /* not lint */
 
@@ -358,23 +358,28 @@ dump_nodes(const char *dir, NODE *root, int pathlast)
                if (MATCHFLAG(F_SIZE))
                        appendfield(pathlast, "size=%lld", (long long)cur->st_size);
                if (MATCHFLAG(F_TIME))
-                       appendfield(pathlast, "time=%lld.%ld",
+                       appendfield(pathlast, "time=%lld.%09ld",
                            (long long)cur->st_mtimespec.tv_sec,
                            cur->st_mtimespec.tv_nsec);
                if (MATCHFLAG(F_CKSUM))
                        appendfield(pathlast, "cksum=%lu", cur->cksum);
                if (MATCHFLAG(F_MD5))
-                       appendfield(pathlast, "md5=%s", cur->md5digest);
+                       appendfield(pathlast, "%s=%s", MD5KEY, cur->md5digest);
                if (MATCHFLAG(F_RMD160))
-                       appendfield(pathlast, "rmd160=%s", cur->rmd160digest);
+                       appendfield(pathlast, "%s=%s", RMD160KEY,
+                           cur->rmd160digest);
                if (MATCHFLAG(F_SHA1))
-                       appendfield(pathlast, "sha1=%s", cur->sha1digest);
+                       appendfield(pathlast, "%s=%s", SHA1KEY,
+                           cur->sha1digest);
                if (MATCHFLAG(F_SHA256))
-                       appendfield(pathlast, "sha256=%s", cur->sha256digest);
+                       appendfield(pathlast, "%s=%s", SHA256KEY,
+                           cur->sha256digest);
                if (MATCHFLAG(F_SHA384))
-                       appendfield(pathlast, "sha384=%s", cur->sha384digest);
+                       appendfield(pathlast, "%s=%s", SHA384KEY,
+                           cur->sha384digest);
                if (MATCHFLAG(F_SHA512))
-                       appendfield(pathlast, "sha512=%s", cur->sha512digest);
+                       appendfield(pathlast, "%s=%s", SHA512KEY,
+                           cur->sha512digest);
                if (MATCHFLAG(F_FLAGS)) {
                        str = flags_to_string(cur->st_flags, "none");
                        appendfield(pathlast, "flags=%s", str);
@@ -410,7 +415,15 @@ dump_nodes(const char *dir, NODE *root, int pathlast)
 char *
 vispath(const char *path)
 {
-       const char extra[] = { ' ', '\t', '\n', '\\', '#', '\0' };
+       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 char pathbuf[4*MAXPATHLEN + 1];
 
        strsvis(pathbuf, path, VIS_CSTYLE, extra);
diff --git a/usr.sbin/mtree/specspec.c b/usr.sbin/mtree/specspec.c
new file mode 100644 (file)
index 0000000..2821fd1
--- /dev/null
@@ -0,0 +1,273 @@
+/*     $NetBSD: specspec.c,v 1.2 2012/10/05 01:27:29 christos Exp $    */
+
+/*-
+ * Copyright (c) 2003 Poul-Henning Kamp
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if HAVE_NBTOOL_CONFIG_H
+#include "nbtool_config.h"
+#endif
+
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: specspec.c,v 1.2 2012/10/05 01:27:29 christos Exp $");
+
+#include <err.h>
+#include <grp.h>
+#include <pwd.h>
+#include <time.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include "mtree.h"
+#include "extern.h"
+
+#define FF(a, b, c, d) \
+       (((a)->flags & (c)) && ((b)->flags & (c)) && ((a)->d) != ((b)->d))
+#define FS(a, b, c, d) \
+       (((a)->flags & (c)) && ((b)->flags & (c)) && strcmp((a)->d,(b)->d))
+#define FM(a, b, c, d) \
+       (((a)->flags & (c)) && ((b)->flags & (c)) && memcmp(&(a)->d,&(b)->d, sizeof (a)->d))
+
+static void
+shownode(NODE *n, int f, char const *path)
+{
+       struct group *gr;
+       struct passwd *pw;
+
+       printf("%s%s %s", path, n->name, inotype(nodetoino(n->type)));
+       if (f & F_CKSUM)
+               printf(" cksum=%lu", n->cksum);
+       if (f & F_GID)
+               printf(" gid=%d", n->st_gid);
+       if (f & F_GNAME) {
+               gr = getgrgid(n->st_gid);
+               if (gr == NULL)
+                       printf(" gid=%d", n->st_gid);
+               else
+                       printf(" gname=%s", gr->gr_name);
+       }
+       if (f & F_MODE)
+               printf(" mode=%o", n->st_mode);
+       if (f & F_NLINK)
+               printf(" nlink=%d", n->st_nlink);
+       if (f & F_SIZE)
+               printf(" size=%jd", (intmax_t)n->st_size);
+       if (f & F_UID)
+               printf(" uid=%d", n->st_uid);
+       if (f & F_UNAME) {
+               pw = getpwuid(n->st_uid);
+               if (pw == NULL)
+                       printf(" uid=%d", n->st_uid);
+               else
+                       printf(" uname=%s", pw->pw_name);
+       }
+       if (f & F_MD5)
+               printf(" %s=%s", MD5KEY, n->md5digest);
+       if (f & F_SHA1)
+               printf(" %s=%s", SHA1KEY, n->sha1digest);
+       if (f & F_RMD160)
+               printf(" %s=%s", RMD160KEY, n->rmd160digest);
+       if (f & F_SHA256)
+               printf(" %s=%s", SHA256KEY, n->sha256digest);
+       if (f & F_SHA384)
+               printf(" %s=%s", SHA384KEY, n->sha384digest);
+       if (f & F_SHA512)
+               printf(" %s=%s", SHA512KEY, n->sha512digest);
+       if (f & F_FLAGS)
+               printf(" flags=%s", flags_to_string(n->st_flags, "none"));
+       printf("\n");
+}
+
+static int
+mismatch(NODE *n1, NODE *n2, int differ, char const *path)
+{
+
+       if (n2 == NULL) {
+               shownode(n1, differ, path);
+               return (1);
+       }
+       if (n1 == NULL) {
+               printf("\t");
+               shownode(n2, differ, path);
+               return (1);
+       }
+       if (!(differ & keys))
+               return(0);
+       printf("\t\t");
+       shownode(n1, differ, path);
+       printf("\t\t");
+       shownode(n2, differ, path);
+       return (1);
+}
+
+static int
+compare_nodes(NODE *n1, NODE *n2, char const *path)
+{
+       int differs;
+       
+       if (n1 != NULL && n1->type == F_LINK)
+               n1->flags &= ~F_MODE;
+       if (n2 != NULL && n2->type == F_LINK)
+               n2->flags &= ~F_MODE;
+       differs = 0;
+       if (n1 == NULL && n2 != NULL) {
+               differs = n2->flags;
+               mismatch(n1, n2, differs, path);
+               return (1);
+       }
+       if (n1 != NULL && n2 == NULL) {
+               differs = n1->flags;
+               mismatch(n1, n2, differs, path);
+               return (1);
+       }
+       if (n1->type != n2->type) {
+               differs = 0;
+               mismatch(n1, n2, differs, path);
+               return (1);
+       }
+       if (FF(n1, n2, F_CKSUM, cksum))
+               differs |= F_CKSUM;
+       if (FF(n1, n2, F_GID, st_gid))
+               differs |= F_GID;
+       if (FF(n1, n2, F_GNAME, st_gid))
+               differs |= F_GNAME;
+       if (FF(n1, n2, F_MODE, st_mode))
+               differs |= F_MODE;
+       if (FF(n1, n2, F_NLINK, st_nlink))
+               differs |= F_NLINK;
+       if (FF(n1, n2, F_SIZE, st_size))
+               differs |= F_SIZE;
+       if (FS(n1, n2, F_SLINK, slink))
+               differs |= F_SLINK;
+       if (FM(n1, n2, F_TIME, st_mtimespec))
+               differs |= F_TIME;
+       if (FF(n1, n2, F_UID, st_uid))
+               differs |= F_UID;
+       if (FF(n1, n2, F_UNAME, st_uid))
+               differs |= F_UNAME;
+       if (FS(n1, n2, F_MD5, md5digest))
+               differs |= F_MD5;
+       if (FS(n1, n2, F_SHA1, sha1digest))
+               differs |= F_SHA1;
+       if (FS(n1, n2, F_RMD160, rmd160digest))
+               differs |= F_RMD160;
+       if (FS(n1, n2, F_SHA256, sha256digest))
+               differs |= F_SHA256;
+       if (FS(n1, n2, F_SHA384, sha384digest))
+               differs |= F_SHA384;
+       if (FS(n1, n2, F_SHA512, sha512digest))
+               differs |= F_SHA512;
+       if (FF(n1, n2, F_FLAGS, st_flags))
+               differs |= F_FLAGS;
+       if (differs) {
+               mismatch(n1, n2, differs, path);
+               return (1);
+       }
+       return (0);     
+}
+static int
+walk_in_the_forest(NODE *t1, NODE *t2, char const *path)
+{
+       int r, i;
+       NODE *c1, *c2, *n1, *n2;
+       char *np;
+
+       r = 0;
+
+       if (t1 != NULL)
+               c1 = t1->child;
+       else
+               c1 = NULL;
+       if (t2 != NULL)
+               c2 = t2->child;
+       else
+               c2 = NULL;
+       while (c1 != NULL || c2 != NULL) {
+               n1 = n2 = NULL;
+               if (c1 != NULL)
+                       n1 = c1->next;
+               if (c2 != NULL)
+                       n2 = c2->next;
+               if (c1 != NULL && c2 != NULL) {
+                       if (c1->type != F_DIR && c2->type == F_DIR) {
+                               n2 = c2;
+                               c2 = NULL;
+                       } else if (c1->type == F_DIR && c2->type != F_DIR) {
+                               n1 = c1;
+                               c1 = NULL;
+                       } else {
+                               i = strcmp(c1->name, c2->name);
+                               if (i > 0) {
+                                       n1 = c1;
+                                       c1 = NULL;
+                               } else if (i < 0) {
+                                       n2 = c2;
+                                       c2 = NULL;
+                               }
+                       }
+               }
+               if (c1 == NULL && c2->type == F_DIR) {
+                       asprintf(&np, "%s%s/", path, c2->name);
+                       i = walk_in_the_forest(c1, c2, np);
+                       free(np);
+                       i += compare_nodes(c1, c2, path);
+               } else if (c2 == NULL && c1->type == F_DIR) {
+                       asprintf(&np, "%s%s/", path, c1->name);
+                       i = walk_in_the_forest(c1, c2, np);
+                       free(np);
+                       i += compare_nodes(c1, c2, path);
+               } else if (c1 == NULL || c2 == NULL) {
+                       i = compare_nodes(c1, c2, path);
+               } else if (c1->type == F_DIR && c2->type == F_DIR) {
+                       asprintf(&np, "%s%s/", path, c1->name);
+                       i = walk_in_the_forest(c1, c2, np);
+                       free(np);
+                       i += compare_nodes(c1, c2, path);
+               } else {
+                       i = compare_nodes(c1, c2, path);
+               }
+               r += i;
+               c1 = n1;
+               c2 = n2;
+       }
+       return (r);     
+}
+
+int
+mtree_specspec(FILE *fi, FILE *fj)
+{
+       int rval;
+       NODE *root1, *root2;
+
+       root1 = spec(fi);
+       root2 = spec(fj);
+       rval = walk_in_the_forest(root1, root2, "");
+       rval += compare_nodes(root1, root2, "");
+       if (rval > 0)
+               return (MISMATCHEXIT);
+       return (0);
+}
index 9eb54510d1f09ecd1967936a28012c21e292fe31..54b704cbf5ba995587cecd4fd13c64b43b8ca3c3 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: verify.c,v 1.40 2012/03/25 16:07:04 christos Exp $     */
+/*     $NetBSD: verify.c,v 1.43 2012/10/05 01:31:05 christos Exp $     */
 
 /*-
  * Copyright (c) 1990, 1993
@@ -38,7 +38,7 @@
 #if 0
 static char sccsid[] = "@(#)verify.c   8.1 (Berkeley) 6/6/93";
 #else
-__RCSID("$NetBSD: verify.c,v 1.40 2012/03/25 16:07:04 christos Exp $");
+__RCSID("$NetBSD: verify.c,v 1.43 2012/10/05 01:31:05 christos Exp $");
 #endif
 #endif /* not lint */
 
@@ -64,11 +64,11 @@ static void miss(NODE *, char *);
 static int     vwalk(void);
 
 int
-verify(void)
+verify(FILE *fi)
 {
        int rval;
 
-       root = spec(stdin);
+       root = spec(fi);
        rval = vwalk();
        miss(root, path);
        return (rval);
@@ -124,7 +124,8 @@ vwalk(void)
                            !fnmatch(ep->name, p->fts_name, FNM_PATHNAME)) ||
                            !strcmp(ep->name, p->fts_name)) {
                                ep->flags |= F_VISIT;
-                               if (compare(ep, p))
+                               if ((ep->flags & F_NOCHANGE) == 0 &&
+                                   compare(ep, p))
                                        rval = MISMATCHEXIT;
                                if (!(ep->flags & F_IGN) &&
                                    ep->type == F_DIR &&
@@ -175,8 +176,17 @@ miss(NODE *p, char *tail)
                if (p->type != F_DIR && (dflag || p->flags & F_VISIT))
                        continue;
                strcpy(tail, p->name);
-               if (!(p->flags & F_VISIT))
-                       printf("missing: %s", path);
+               if (!(p->flags & F_VISIT)) {
+                       /* Don't print missing message if file exists as a 
+                          symbolic link and the -q flag is set. */
+                       struct stat statbuf;
+
+                       if (qflag && stat(path, &statbuf) == 0 &&
+                           S_ISDIR(statbuf.st_mode))
+                               p->flags |= F_VISIT;
+                       else
+                               (void)printf("%s missing", path);
+               }
                switch (p->type) {
                case F_BLOCK:
                case F_CHAR:
@@ -264,7 +274,6 @@ miss(NODE *p, char *tail)
 
                if (!create || mtree_Wflag)
                        continue;
-#ifndef __minix
                if ((p->flags & (F_UID | F_UNAME)) &&
                    (p->flags & (F_GID | F_GNAME)) &&
                    (lchown(path, p->st_uid, p->st_gid))) {
@@ -274,24 +283,12 @@ miss(NODE *p, char *tail)
                            (p->flags & F_FLAGS) ? "and file flags " : "");
                        continue;
                }
-#else
-               if ((p->flags & (F_UID | F_UNAME)) &&
-                   (p->flags & (F_GID | F_GNAME))) {
-                       printf("Warning: unable to change user/group/mode due "
-                           "to lack of lchown(3) support");
-               }
-#endif
                if (p->flags & F_MODE) {
-#ifndef __minix
                        if (lchmod(path, p->st_mode))
                                printf("%s: permissions not set: %s\n",
                                    path, strerror(errno));
-#else
-                       printf("Warning: unable to set permissions due "
-                           "to lack of lchmod(3) support");
-#endif
                }
-#if HAVE_STRUCT_STAT_ST_FLAGS && !defined(__minix)
+#if HAVE_STRUCT_STAT_ST_FLAGS
                if ((p->flags & F_FLAGS) && p->st_flags) {
                        if (iflag)
                                flags = p->st_flags;