mtree mknod

Change-Id: I887437c7b84839fc644da4c55bd59b6a414408ef
This commit is contained in:
Ben Gras 2012-10-10 17:20:17 +02:00 committed by Lionel Sambuc
parent 7dd6189cc7
commit a8ef09103d
25 changed files with 1580 additions and 291 deletions

View 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 \

View file

@ -1,4 +0,0 @@
PROG= mknod
MAN=
.include <bsd.prog.mk>

View file

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

View 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 \

View file

@ -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).

View 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

View 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>

8
sbin/mknod/Makefile Normal file
View file

@ -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>

229
sbin/mknod/mknod.8 Normal file
View file

@ -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 .

393
sbin/mknod/mknod.c Normal file
View file

@ -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

290
sbin/mknod/pack_dev.c Normal file
View file

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

52
sbin/mknod/pack_dev.h Normal file
View file

@ -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 */

View 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>

View 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

View 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
@ -38,11 +38,12 @@
#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);

View 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

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

View 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
@ -36,8 +36,10 @@
#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;

View 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},

View 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 ,

View 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());

View 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] == '/' ? \

View 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);

273
usr.sbin/mtree/specspec.c Normal file
View file

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

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