mtree mknod
Change-Id: I887437c7b84839fc644da4c55bd59b6a414408ef
This commit is contained in:
parent
7dd6189cc7
commit
a8ef09103d
25 changed files with 1580 additions and 291 deletions
|
@ -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 \
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
PROG= mknod
|
||||
MAN=
|
||||
|
||||
.include <bsd.prog.mk>
|
|
@ -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);
|
||||
}
|
|
@ -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 \
|
||||
|
|
|
@ -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).
|
|
@ -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
|
||||
|
|
|
@ -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
8
sbin/mknod/Makefile
Normal 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
229
sbin/mknod/mknod.8
Normal 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
393
sbin/mknod/mknod.c
Normal 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
290
sbin/mknod/pack_dev.c
Normal 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
52
sbin/mknod/pack_dev.h
Normal 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 */
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>";
|
||||
}
|
||||
|
||||
if (!nflag)
|
||||
printf(
|
||||
"#\t user: %s\n#\tmachine: %s\n#\t tree: %s\n#\t date: %s",
|
||||
"#\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:
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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},
|
||||
|
|
|
@ -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 ,
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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] == '/' ? \
|
||||
|
|
|
@ -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
273
usr.sbin/mtree/specspec.c
Normal 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);
|
||||
}
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue