Merge pull request #14 from Oichkatzelesfrettschen/eirikr/remove-netbsd-files-and-keep-microkernel
This commit is contained in:
commit
433c9b3cc6
|
|
@ -1,11 +0,0 @@
|
||||||
# $NetBSD: Makefile.inc,v 1.17 2012/03/21 05:47:53 matt Exp $
|
|
||||||
# @(#)Makefile.inc 8.1 (Berkeley) 5/31/93
|
|
||||||
|
|
||||||
.include <bsd.own.mk> # for MKDYNAMICROOT definition
|
|
||||||
|
|
||||||
WARNS?= 5
|
|
||||||
BINDIR?= /bin
|
|
||||||
|
|
||||||
.if (${MKDYNAMICROOT} == "no")
|
|
||||||
LDSTATIC?= -static
|
|
||||||
.endif
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
# $NetBSD: Makefile,v 1.9 1997/07/20 22:36:37 christos Exp $
|
|
||||||
# @(#)Makefile 8.1 (Berkeley) 5/31/93
|
|
||||||
|
|
||||||
PROG= cp
|
|
||||||
SRCS= cp.c utils.c
|
|
||||||
|
|
||||||
.include <bsd.prog.mk>
|
|
||||||
262
bin/cp/cp.1
262
bin/cp/cp.1
|
|
@ -1,262 +0,0 @@
|
||||||
.\" $NetBSD: cp.1,v 1.45 2016/08/11 00:17:23 sevan Exp $
|
|
||||||
.\"
|
|
||||||
.\" Copyright (c) 1989, 1990, 1993, 1994
|
|
||||||
.\" The Regents of the University of California. All rights reserved.
|
|
||||||
.\"
|
|
||||||
.\" This code is derived from software contributed to Berkeley by
|
|
||||||
.\" the Institute of Electrical and Electronics Engineers, Inc.
|
|
||||||
.\"
|
|
||||||
.\" 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.
|
|
||||||
.\"
|
|
||||||
.\" @(#)cp.1 8.3 (Berkeley) 4/18/94
|
|
||||||
.\"
|
|
||||||
.Dd August 11, 2016
|
|
||||||
.Dt CP 1
|
|
||||||
.Os
|
|
||||||
.Sh NAME
|
|
||||||
.Nm cp
|
|
||||||
.Nd copy files
|
|
||||||
.Sh SYNOPSIS
|
|
||||||
.Nm
|
|
||||||
.Oo
|
|
||||||
.Fl R
|
|
||||||
.Op Fl H | Fl L | Fl P
|
|
||||||
.Oc
|
|
||||||
.Op Fl f | i
|
|
||||||
.Op Fl alNpv
|
|
||||||
.Ar source_file target_file
|
|
||||||
.Nm cp
|
|
||||||
.Oo
|
|
||||||
.Fl R
|
|
||||||
.Op Fl H | Fl L | Fl P
|
|
||||||
.Oc
|
|
||||||
.Op Fl f | i
|
|
||||||
.Op Fl alNpv
|
|
||||||
.Ar source_file ... target_directory
|
|
||||||
.Sh DESCRIPTION
|
|
||||||
In the first synopsis form, the
|
|
||||||
.Nm
|
|
||||||
utility copies the contents of the
|
|
||||||
.Ar source_file
|
|
||||||
to the
|
|
||||||
.Ar target_file .
|
|
||||||
In the second synopsis form,
|
|
||||||
the contents of each named
|
|
||||||
.Ar source_file
|
|
||||||
is copied to the destination
|
|
||||||
.Ar target_directory .
|
|
||||||
The names of the files themselves are not changed.
|
|
||||||
If
|
|
||||||
.Nm
|
|
||||||
detects an attempt to copy a file to itself, the copy will fail.
|
|
||||||
.Pp
|
|
||||||
The following options are available:
|
|
||||||
.Bl -tag -width flag
|
|
||||||
.It Fl a
|
|
||||||
Archive mode.
|
|
||||||
Same as
|
|
||||||
.Fl RpP .
|
|
||||||
.It Fl f
|
|
||||||
For each existing destination pathname, attempt to overwrite it.
|
|
||||||
If permissions do not allow copy to succeed, remove it and create a new
|
|
||||||
file, without prompting for confirmation.
|
|
||||||
(The
|
|
||||||
.Fl i
|
|
||||||
option is ignored if the
|
|
||||||
.Fl f
|
|
||||||
option is specified.)
|
|
||||||
.It Fl H
|
|
||||||
If the
|
|
||||||
.Fl R
|
|
||||||
option is specified, symbolic links on the command line are followed.
|
|
||||||
(Symbolic links encountered in the tree traversal are not followed.)
|
|
||||||
.It Fl i
|
|
||||||
Causes
|
|
||||||
.Nm
|
|
||||||
to write a prompt to the standard error output before copying a file
|
|
||||||
that would overwrite an existing file.
|
|
||||||
If the response from the standard input begins with the character
|
|
||||||
.Sq Li y ,
|
|
||||||
the file copy is attempted.
|
|
||||||
.It Fl L
|
|
||||||
If the
|
|
||||||
.Fl R
|
|
||||||
option is specified, all symbolic links are followed.
|
|
||||||
.It Fl l
|
|
||||||
Create hard links to regular files in a hierarchy instead of copying.
|
|
||||||
.It Fl N
|
|
||||||
When used with
|
|
||||||
.Fl p ,
|
|
||||||
don't copy file flags.
|
|
||||||
.It Fl P
|
|
||||||
No symbolic links are followed.
|
|
||||||
This is the default.
|
|
||||||
.It Fl p
|
|
||||||
Causes
|
|
||||||
.Nm
|
|
||||||
to preserve in the copy as many of the modification time, access time,
|
|
||||||
file flags, file mode, user ID, group ID, and extended attributes,
|
|
||||||
as allowed by permissions.
|
|
||||||
.Pp
|
|
||||||
If the user ID and group ID cannot be preserved, no error message
|
|
||||||
is displayed and the exit value is not altered.
|
|
||||||
.Pp
|
|
||||||
If the source file has its set user ID bit on and the user ID cannot
|
|
||||||
be preserved, the set user ID bit is not preserved
|
|
||||||
in the copy's permissions.
|
|
||||||
If the source file has its set group ID bit on and the group ID cannot
|
|
||||||
be preserved, the set group ID bit is not preserved
|
|
||||||
in the copy's permissions.
|
|
||||||
If the source file has both its set user ID and set group ID bits on,
|
|
||||||
and either the user ID or group ID cannot be preserved, neither
|
|
||||||
the set user ID or set group ID bits are preserved in the copy's
|
|
||||||
permissions.
|
|
||||||
.Pp
|
|
||||||
Extended attributes from all accessible namespaces are copied;
|
|
||||||
others are ignored.
|
|
||||||
If an error occurs during this copy, a message is displayed and
|
|
||||||
.Nm
|
|
||||||
skips the other extended attributes for that file.
|
|
||||||
.It Fl R
|
|
||||||
If
|
|
||||||
.Ar source_file
|
|
||||||
designates a directory,
|
|
||||||
.Nm
|
|
||||||
copies the directory and the entire subtree connected at that point.
|
|
||||||
This option also causes symbolic links to be copied, rather than
|
|
||||||
followed, and for
|
|
||||||
.Nm
|
|
||||||
to create special files rather than copying them as normal files.
|
|
||||||
Created directories have the same mode as the corresponding source
|
|
||||||
directory, unmodified by the process's umask.
|
|
||||||
.Pp
|
|
||||||
Note that
|
|
||||||
.Nm
|
|
||||||
copies hard linked files as separate files.
|
|
||||||
If you need to preserve hard links, consider using a utility like
|
|
||||||
.Xr pax 1
|
|
||||||
instead.
|
|
||||||
.It Fl v
|
|
||||||
Causes
|
|
||||||
.Nm
|
|
||||||
to be verbose, showing files as they are copied.
|
|
||||||
.El
|
|
||||||
.Pp
|
|
||||||
For each destination file that already exists, its contents are
|
|
||||||
overwritten if permissions allow, but its mode, user ID, and group
|
|
||||||
ID are unchanged.
|
|
||||||
.Pp
|
|
||||||
In the second synopsis form,
|
|
||||||
.Ar target_directory
|
|
||||||
must exist unless there is only one named
|
|
||||||
.Ar source_file
|
|
||||||
which is a directory and the
|
|
||||||
.Fl R
|
|
||||||
flag is specified.
|
|
||||||
.Pp
|
|
||||||
If the destination file does not exist, the mode of the source file is
|
|
||||||
used as modified by the file mode creation mask
|
|
||||||
.Ic ( umask ,
|
|
||||||
see
|
|
||||||
.Xr csh 1 ) .
|
|
||||||
If the source file has its set user ID bit on, that bit is removed
|
|
||||||
unless both the source file and the destination file are owned by the
|
|
||||||
same user.
|
|
||||||
If the source file has its set group ID bit on, that bit is removed
|
|
||||||
unless both the source file and the destination file are in the same
|
|
||||||
group and the user is a member of that group.
|
|
||||||
If both the set user ID and set group ID bits are set, all of the above
|
|
||||||
conditions must be fulfilled or both bits are removed.
|
|
||||||
.Pp
|
|
||||||
Appropriate permissions are required for file creation or overwriting.
|
|
||||||
.Pp
|
|
||||||
Symbolic links are always followed unless the
|
|
||||||
.Fl R
|
|
||||||
flag is set, in which case symbolic links are not followed, by default.
|
|
||||||
The
|
|
||||||
.Fl H
|
|
||||||
or
|
|
||||||
.Fl L
|
|
||||||
flags (in conjunction with the
|
|
||||||
.Fl R
|
|
||||||
flag), as well as the
|
|
||||||
.Fl P
|
|
||||||
flag cause symbolic links to be followed as described above.
|
|
||||||
The
|
|
||||||
.Fl H
|
|
||||||
and
|
|
||||||
.Fl L
|
|
||||||
options are ignored unless the
|
|
||||||
.Fl R
|
|
||||||
option is specified.
|
|
||||||
In addition, these options override each other and the
|
|
||||||
command's actions are determined by the last one specified.
|
|
||||||
The default is as if the
|
|
||||||
.Fl P
|
|
||||||
option had been specified.
|
|
||||||
.Sh EXIT STATUS
|
|
||||||
.Ex -std cp
|
|
||||||
.Sh COMPATIBILITY
|
|
||||||
Historic versions of the
|
|
||||||
.Nm
|
|
||||||
utility had a
|
|
||||||
.Fl r
|
|
||||||
option.
|
|
||||||
This implementation supports that option, however, its use is strongly
|
|
||||||
discouraged, as it does not correctly copy special files, symbolic links,
|
|
||||||
or FIFOs.
|
|
||||||
.Sh SEE ALSO
|
|
||||||
.Xr mv 1 ,
|
|
||||||
.Xr pax 1 ,
|
|
||||||
.Xr rcp 1 ,
|
|
||||||
.Xr umask 2 ,
|
|
||||||
.Xr fts 3 ,
|
|
||||||
.Xr symlink 7
|
|
||||||
.Sh STANDARDS
|
|
||||||
The
|
|
||||||
.Nm
|
|
||||||
utility is expected to be
|
|
||||||
.St -p1003.2
|
|
||||||
compatible.
|
|
||||||
.Pp
|
|
||||||
The
|
|
||||||
.Fl a
|
|
||||||
and
|
|
||||||
.Fl l
|
|
||||||
flags are non-standard extensions.
|
|
||||||
They are intended to be compatible with the same options which
|
|
||||||
other implementations, namely GNU coreutils and
|
|
||||||
.Fx ,
|
|
||||||
of this utility have.
|
|
||||||
.Pp
|
|
||||||
The
|
|
||||||
.Fl v
|
|
||||||
option is an extension to
|
|
||||||
.St -p1003.2 .
|
|
||||||
.Sh HISTORY
|
|
||||||
A
|
|
||||||
.Nm
|
|
||||||
utility appeared in
|
|
||||||
.At v1 .
|
|
||||||
548
bin/cp/cp.c
548
bin/cp/cp.c
|
|
@ -1,548 +0,0 @@
|
||||||
/* $NetBSD: cp.c,v 1.58 2012/01/04 15:58:37 christos Exp $ */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (c) 1988, 1993, 1994
|
|
||||||
* The Regents of the University of California. All rights reserved.
|
|
||||||
*
|
|
||||||
* This code is derived from software contributed to Berkeley by
|
|
||||||
* David Hitz of Auspex Systems Inc.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
|
||||||
#ifndef lint
|
|
||||||
__COPYRIGHT(
|
|
||||||
"@(#) Copyright (c) 1988, 1993, 1994\
|
|
||||||
The Regents of the University of California. All rights reserved.");
|
|
||||||
#endif /* not lint */
|
|
||||||
|
|
||||||
#ifndef lint
|
|
||||||
#if 0
|
|
||||||
static char sccsid[] = "@(#)cp.c 8.5 (Berkeley) 4/29/95";
|
|
||||||
#else
|
|
||||||
__RCSID("$NetBSD: cp.c,v 1.58 2012/01/04 15:58:37 christos Exp $");
|
|
||||||
#endif
|
|
||||||
#endif /* not lint */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Cp copies source files to target files.
|
|
||||||
*
|
|
||||||
* The global PATH_T structure "to" always contains the path to the
|
|
||||||
* current target file. Since fts(3) does not change directories,
|
|
||||||
* this path can be either absolute or dot-relative.
|
|
||||||
*
|
|
||||||
* The basic algorithm is to initialize "to" and use fts(3) to traverse
|
|
||||||
* the file hierarchy rooted in the argument list. A trivial case is the
|
|
||||||
* case of 'cp file1 file2'. The more interesting case is the case of
|
|
||||||
* 'cp file1 file2 ... fileN dir' where the hierarchy is traversed and the
|
|
||||||
* path (relative to the root of the traversal) is appended to dir (stored
|
|
||||||
* in "to") to form the final target path.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <sys/param.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <err.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <fts.h>
|
|
||||||
#include <locale.h>
|
|
||||||
#include <signal.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include "extern.h"
|
|
||||||
|
|
||||||
#define STRIP_TRAILING_SLASH(p) { \
|
|
||||||
while ((p).p_end > (p).p_path + 1 && (p).p_end[-1] == '/') \
|
|
||||||
*--(p).p_end = '\0'; \
|
|
||||||
}
|
|
||||||
|
|
||||||
static char empty[] = "";
|
|
||||||
PATH_T to = { .p_end = to.p_path, .target_end = empty };
|
|
||||||
|
|
||||||
uid_t myuid;
|
|
||||||
int Hflag, Lflag, Rflag, Pflag, fflag, iflag, lflag, pflag, rflag, vflag, Nflag;
|
|
||||||
mode_t myumask;
|
|
||||||
sig_atomic_t pinfo;
|
|
||||||
|
|
||||||
enum op { FILE_TO_FILE, FILE_TO_DIR, DIR_TO_DNE };
|
|
||||||
|
|
||||||
static int copy(char *[], enum op, int);
|
|
||||||
|
|
||||||
static void
|
|
||||||
progress(int sig __unused)
|
|
||||||
{
|
|
||||||
|
|
||||||
pinfo++;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
struct stat to_stat, tmp_stat;
|
|
||||||
enum op type;
|
|
||||||
int ch, fts_options, r, have_trailing_slash;
|
|
||||||
char *target, **src;
|
|
||||||
|
|
||||||
setprogname(argv[0]);
|
|
||||||
(void)setlocale(LC_ALL, "");
|
|
||||||
|
|
||||||
Hflag = Lflag = Pflag = Rflag = 0;
|
|
||||||
while ((ch = getopt(argc, argv, "HLNPRfailprv")) != -1)
|
|
||||||
switch (ch) {
|
|
||||||
case 'H':
|
|
||||||
Hflag = 1;
|
|
||||||
Lflag = Pflag = 0;
|
|
||||||
break;
|
|
||||||
case 'L':
|
|
||||||
Lflag = 1;
|
|
||||||
Hflag = Pflag = 0;
|
|
||||||
break;
|
|
||||||
case 'N':
|
|
||||||
Nflag = 1;
|
|
||||||
break;
|
|
||||||
case 'P':
|
|
||||||
Pflag = 1;
|
|
||||||
Hflag = Lflag = 0;
|
|
||||||
break;
|
|
||||||
case 'R':
|
|
||||||
Rflag = 1;
|
|
||||||
break;
|
|
||||||
case 'a':
|
|
||||||
Pflag = 1;
|
|
||||||
pflag = 1;
|
|
||||||
Rflag = 1;
|
|
||||||
Hflag = Lflag = 0;
|
|
||||||
break;
|
|
||||||
case 'f':
|
|
||||||
fflag = 1;
|
|
||||||
iflag = 0;
|
|
||||||
break;
|
|
||||||
case 'i':
|
|
||||||
iflag = isatty(fileno(stdin));
|
|
||||||
fflag = 0;
|
|
||||||
break;
|
|
||||||
case 'l':
|
|
||||||
lflag = 1;
|
|
||||||
break;
|
|
||||||
case 'p':
|
|
||||||
pflag = 1;
|
|
||||||
break;
|
|
||||||
case 'r':
|
|
||||||
rflag = 1;
|
|
||||||
break;
|
|
||||||
case 'v':
|
|
||||||
vflag = 1;
|
|
||||||
break;
|
|
||||||
case '?':
|
|
||||||
default:
|
|
||||||
usage();
|
|
||||||
/* NOTREACHED */
|
|
||||||
}
|
|
||||||
argc -= optind;
|
|
||||||
argv += optind;
|
|
||||||
|
|
||||||
if (argc < 2)
|
|
||||||
usage();
|
|
||||||
|
|
||||||
fts_options = FTS_NOCHDIR | FTS_PHYSICAL;
|
|
||||||
if (rflag) {
|
|
||||||
if (Rflag) {
|
|
||||||
errx(EXIT_FAILURE,
|
|
||||||
"the -R and -r options may not be specified together.");
|
|
||||||
/* NOTREACHED */
|
|
||||||
}
|
|
||||||
if (Hflag || Lflag || Pflag) {
|
|
||||||
errx(EXIT_FAILURE,
|
|
||||||
"the -H, -L, and -P options may not be specified with the -r option.");
|
|
||||||
/* NOTREACHED */
|
|
||||||
}
|
|
||||||
fts_options &= ~FTS_PHYSICAL;
|
|
||||||
fts_options |= FTS_LOGICAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Rflag) {
|
|
||||||
if (Hflag)
|
|
||||||
fts_options |= FTS_COMFOLLOW;
|
|
||||||
if (Lflag) {
|
|
||||||
fts_options &= ~FTS_PHYSICAL;
|
|
||||||
fts_options |= FTS_LOGICAL;
|
|
||||||
}
|
|
||||||
} else if (!Pflag) {
|
|
||||||
fts_options &= ~FTS_PHYSICAL;
|
|
||||||
fts_options |= FTS_LOGICAL | FTS_COMFOLLOW;
|
|
||||||
}
|
|
||||||
|
|
||||||
myuid = getuid();
|
|
||||||
|
|
||||||
/* Copy the umask for explicit mode setting. */
|
|
||||||
myumask = umask(0);
|
|
||||||
(void)umask(myumask);
|
|
||||||
|
|
||||||
/* Save the target base in "to". */
|
|
||||||
target = argv[--argc];
|
|
||||||
if (strlcpy(to.p_path, target, sizeof(to.p_path)) >= sizeof(to.p_path))
|
|
||||||
errx(EXIT_FAILURE, "%s: name too long", target);
|
|
||||||
to.p_end = to.p_path + strlen(to.p_path);
|
|
||||||
have_trailing_slash = (to.p_end[-1] == '/');
|
|
||||||
if (have_trailing_slash)
|
|
||||||
STRIP_TRAILING_SLASH(to);
|
|
||||||
to.target_end = to.p_end;
|
|
||||||
|
|
||||||
/* Set end of argument list for fts(3). */
|
|
||||||
argv[argc] = NULL;
|
|
||||||
|
|
||||||
(void)signal(SIGINFO, progress);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Cp has two distinct cases:
|
|
||||||
*
|
|
||||||
* cp [-R] source target
|
|
||||||
* cp [-R] source1 ... sourceN directory
|
|
||||||
*
|
|
||||||
* In both cases, source can be either a file or a directory.
|
|
||||||
*
|
|
||||||
* In (1), the target becomes a copy of the source. That is, if the
|
|
||||||
* source is a file, the target will be a file, and likewise for
|
|
||||||
* directories.
|
|
||||||
*
|
|
||||||
* In (2), the real target is not directory, but "directory/source".
|
|
||||||
*/
|
|
||||||
if (Pflag)
|
|
||||||
r = lstat(to.p_path, &to_stat);
|
|
||||||
else
|
|
||||||
r = stat(to.p_path, &to_stat);
|
|
||||||
if (r == -1 && errno != ENOENT) {
|
|
||||||
err(EXIT_FAILURE, "%s", to.p_path);
|
|
||||||
/* NOTREACHED */
|
|
||||||
}
|
|
||||||
if (r == -1 || !S_ISDIR(to_stat.st_mode)) {
|
|
||||||
/*
|
|
||||||
* Case (1). Target is not a directory.
|
|
||||||
*/
|
|
||||||
if (argc > 1)
|
|
||||||
usage();
|
|
||||||
/*
|
|
||||||
* Need to detect the case:
|
|
||||||
* cp -R dir foo
|
|
||||||
* Where dir is a directory and foo does not exist, where
|
|
||||||
* we want pathname concatenations turned on but not for
|
|
||||||
* the initial mkdir().
|
|
||||||
*/
|
|
||||||
if (r == -1) {
|
|
||||||
if (rflag || (Rflag && (Lflag || Hflag)))
|
|
||||||
r = stat(*argv, &tmp_stat);
|
|
||||||
else
|
|
||||||
r = lstat(*argv, &tmp_stat);
|
|
||||||
if (r == -1) {
|
|
||||||
err(EXIT_FAILURE, "%s", *argv);
|
|
||||||
/* NOTREACHED */
|
|
||||||
}
|
|
||||||
|
|
||||||
if (S_ISDIR(tmp_stat.st_mode) && (Rflag || rflag))
|
|
||||||
type = DIR_TO_DNE;
|
|
||||||
else
|
|
||||||
type = FILE_TO_FILE;
|
|
||||||
} else
|
|
||||||
type = FILE_TO_FILE;
|
|
||||||
|
|
||||||
if (have_trailing_slash && type == FILE_TO_FILE) {
|
|
||||||
if (r == -1)
|
|
||||||
errx(1, "directory %s does not exist",
|
|
||||||
to.p_path);
|
|
||||||
else
|
|
||||||
errx(1, "%s is not a directory", to.p_path);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/*
|
|
||||||
* Case (2). Target is a directory.
|
|
||||||
*/
|
|
||||||
type = FILE_TO_DIR;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* make "cp -rp src/ dst" behave like "cp -rp src dst" not
|
|
||||||
* like "cp -rp src/. dst"
|
|
||||||
*/
|
|
||||||
for (src = argv; *src; src++) {
|
|
||||||
size_t len = strlen(*src);
|
|
||||||
while (len-- > 1 && (*src)[len] == '/')
|
|
||||||
(*src)[len] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
exit(copy(argv, type, fts_options));
|
|
||||||
/* NOTREACHED */
|
|
||||||
}
|
|
||||||
|
|
||||||
static int dnestack[MAXPATHLEN]; /* unlikely we'll have more nested dirs */
|
|
||||||
static ssize_t dnesp;
|
|
||||||
static void
|
|
||||||
pushdne(int dne)
|
|
||||||
{
|
|
||||||
|
|
||||||
dnestack[dnesp++] = dne;
|
|
||||||
assert(dnesp < MAXPATHLEN);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
popdne(void)
|
|
||||||
{
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
rv = dnestack[--dnesp];
|
|
||||||
assert(dnesp >= 0);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
copy(char *argv[], enum op type, int fts_options)
|
|
||||||
{
|
|
||||||
struct stat to_stat;
|
|
||||||
FTS *ftsp;
|
|
||||||
FTSENT *curr;
|
|
||||||
int base, dne, sval;
|
|
||||||
int this_failed, any_failed;
|
|
||||||
size_t nlen;
|
|
||||||
char *p, *target_mid;
|
|
||||||
|
|
||||||
base = 0; /* XXX gcc -Wuninitialized (see comment below) */
|
|
||||||
|
|
||||||
if ((ftsp = fts_open(argv, fts_options, NULL)) == NULL)
|
|
||||||
err(EXIT_FAILURE, "%s", argv[0]);
|
|
||||||
/* NOTREACHED */
|
|
||||||
for (any_failed = 0; (curr = fts_read(ftsp)) != NULL;) {
|
|
||||||
this_failed = 0;
|
|
||||||
switch (curr->fts_info) {
|
|
||||||
case FTS_NS:
|
|
||||||
case FTS_DNR:
|
|
||||||
case FTS_ERR:
|
|
||||||
warnx("%s: %s", curr->fts_path,
|
|
||||||
strerror(curr->fts_errno));
|
|
||||||
this_failed = any_failed = 1;
|
|
||||||
continue;
|
|
||||||
case FTS_DC: /* Warn, continue. */
|
|
||||||
warnx("%s: directory causes a cycle", curr->fts_path);
|
|
||||||
this_failed = any_failed = 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If we are in case (2) or (3) above, we need to append the
|
|
||||||
* source name to the target name.
|
|
||||||
*/
|
|
||||||
if (type != FILE_TO_FILE) {
|
|
||||||
if ((curr->fts_namelen +
|
|
||||||
to.target_end - to.p_path + 1) > MAXPATHLEN) {
|
|
||||||
warnx("%s/%s: name too long (not copied)",
|
|
||||||
to.p_path, curr->fts_name);
|
|
||||||
this_failed = any_failed = 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Need to remember the roots of traversals to create
|
|
||||||
* correct pathnames. If there's a directory being
|
|
||||||
* copied to a non-existent directory, e.g.
|
|
||||||
* cp -R a/dir noexist
|
|
||||||
* the resulting path name should be noexist/foo, not
|
|
||||||
* noexist/dir/foo (where foo is a file in dir), which
|
|
||||||
* is the case where the target exists.
|
|
||||||
*
|
|
||||||
* Also, check for "..". This is for correct path
|
|
||||||
* concatentation for paths ending in "..", e.g.
|
|
||||||
* cp -R .. /tmp
|
|
||||||
* Paths ending in ".." are changed to ".". This is
|
|
||||||
* tricky, but seems the easiest way to fix the problem.
|
|
||||||
*
|
|
||||||
* XXX
|
|
||||||
* Since the first level MUST be FTS_ROOTLEVEL, base
|
|
||||||
* is always initialized.
|
|
||||||
*/
|
|
||||||
if (curr->fts_level == FTS_ROOTLEVEL) {
|
|
||||||
if (type != DIR_TO_DNE) {
|
|
||||||
p = strrchr(curr->fts_path, '/');
|
|
||||||
base = (p == NULL) ? 0 :
|
|
||||||
(int)(p - curr->fts_path + 1);
|
|
||||||
|
|
||||||
if (!strcmp(&curr->fts_path[base],
|
|
||||||
".."))
|
|
||||||
base += 1;
|
|
||||||
} else
|
|
||||||
base = curr->fts_pathlen;
|
|
||||||
}
|
|
||||||
|
|
||||||
p = &curr->fts_path[base];
|
|
||||||
nlen = curr->fts_pathlen - base;
|
|
||||||
target_mid = to.target_end;
|
|
||||||
if (*p != '/' && target_mid[-1] != '/')
|
|
||||||
*target_mid++ = '/';
|
|
||||||
*target_mid = 0;
|
|
||||||
|
|
||||||
if (target_mid - to.p_path + nlen >= PATH_MAX) {
|
|
||||||
warnx("%s%s: name too long (not copied)",
|
|
||||||
to.p_path, p);
|
|
||||||
this_failed = any_failed = 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
(void)strncat(target_mid, p, nlen);
|
|
||||||
to.p_end = target_mid + nlen;
|
|
||||||
*to.p_end = 0;
|
|
||||||
STRIP_TRAILING_SLASH(to);
|
|
||||||
}
|
|
||||||
|
|
||||||
sval = Pflag ? lstat(to.p_path, &to_stat) : stat(to.p_path, &to_stat);
|
|
||||||
/* Not an error but need to remember it happened */
|
|
||||||
if (sval == -1)
|
|
||||||
dne = 1;
|
|
||||||
else {
|
|
||||||
if (to_stat.st_dev == curr->fts_statp->st_dev &&
|
|
||||||
to_stat.st_ino == curr->fts_statp->st_ino) {
|
|
||||||
warnx("%s and %s are identical (not copied).",
|
|
||||||
to.p_path, curr->fts_path);
|
|
||||||
this_failed = any_failed = 1;
|
|
||||||
if (S_ISDIR(curr->fts_statp->st_mode))
|
|
||||||
(void)fts_set(ftsp, curr, FTS_SKIP);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!S_ISDIR(curr->fts_statp->st_mode) &&
|
|
||||||
S_ISDIR(to_stat.st_mode)) {
|
|
||||||
warnx("cannot overwrite directory %s with non-directory %s",
|
|
||||||
to.p_path, curr->fts_path);
|
|
||||||
this_failed = any_failed = 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
dne = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (curr->fts_statp->st_mode & S_IFMT) {
|
|
||||||
case S_IFLNK:
|
|
||||||
/* Catch special case of a non dangling symlink */
|
|
||||||
if((fts_options & FTS_LOGICAL) ||
|
|
||||||
((fts_options & FTS_COMFOLLOW) && curr->fts_level == 0)) {
|
|
||||||
if (copy_file(curr, dne))
|
|
||||||
this_failed = any_failed = 1;
|
|
||||||
} else {
|
|
||||||
if (copy_link(curr, !dne))
|
|
||||||
this_failed = any_failed = 1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case S_IFDIR:
|
|
||||||
if (!Rflag && !rflag) {
|
|
||||||
if (curr->fts_info == FTS_D)
|
|
||||||
warnx("%s is a directory (not copied).",
|
|
||||||
curr->fts_path);
|
|
||||||
(void)fts_set(ftsp, curr, FTS_SKIP);
|
|
||||||
this_failed = any_failed = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Directories get noticed twice:
|
|
||||||
* In the first pass, create it if needed.
|
|
||||||
* In the second pass, after the children have been copied, set the permissions.
|
|
||||||
*/
|
|
||||||
if (curr->fts_info == FTS_D) /* First pass */
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* If the directory doesn't exist, create the new
|
|
||||||
* one with the from file mode plus owner RWX bits,
|
|
||||||
* modified by the umask. Trade-off between being
|
|
||||||
* able to write the directory (if from directory is
|
|
||||||
* 555) and not causing a permissions race. If the
|
|
||||||
* umask blocks owner writes, we fail..
|
|
||||||
*/
|
|
||||||
pushdne(dne);
|
|
||||||
if (dne) {
|
|
||||||
if (mkdir(to.p_path,
|
|
||||||
curr->fts_statp->st_mode | S_IRWXU) < 0)
|
|
||||||
err(EXIT_FAILURE, "%s",
|
|
||||||
to.p_path);
|
|
||||||
/* NOTREACHED */
|
|
||||||
} else if (!S_ISDIR(to_stat.st_mode)) {
|
|
||||||
errno = ENOTDIR;
|
|
||||||
err(EXIT_FAILURE, "%s",
|
|
||||||
to.p_path);
|
|
||||||
/* NOTREACHED */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (curr->fts_info == FTS_DP) /* Second pass */
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* If not -p and directory didn't exist, set it to be
|
|
||||||
* the same as the from directory, umodified by the
|
|
||||||
* umask; arguably wrong, but it's been that way
|
|
||||||
* forever.
|
|
||||||
*/
|
|
||||||
if (pflag && setfile(curr->fts_statp, 0))
|
|
||||||
this_failed = any_failed = 1;
|
|
||||||
else if ((dne = popdne()))
|
|
||||||
(void)chmod(to.p_path,
|
|
||||||
curr->fts_statp->st_mode);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
warnx("directory %s encountered when not expected.",
|
|
||||||
curr->fts_path);
|
|
||||||
this_failed = any_failed = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
case S_IFBLK:
|
|
||||||
case S_IFCHR:
|
|
||||||
if (Rflag) {
|
|
||||||
if (copy_special(curr->fts_statp, !dne))
|
|
||||||
this_failed = any_failed = 1;
|
|
||||||
} else
|
|
||||||
if (copy_file(curr, dne))
|
|
||||||
this_failed = any_failed = 1;
|
|
||||||
break;
|
|
||||||
case S_IFIFO:
|
|
||||||
if (Rflag) {
|
|
||||||
if (copy_fifo(curr->fts_statp, !dne))
|
|
||||||
this_failed = any_failed = 1;
|
|
||||||
} else
|
|
||||||
if (copy_file(curr, dne))
|
|
||||||
this_failed = any_failed = 1;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
if (copy_file(curr, dne))
|
|
||||||
this_failed = any_failed = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (vflag && !this_failed)
|
|
||||||
(void)printf("%s -> %s\n", curr->fts_path, to.p_path);
|
|
||||||
}
|
|
||||||
if (errno) {
|
|
||||||
err(EXIT_FAILURE, "fts_read");
|
|
||||||
/* NOTREACHED */
|
|
||||||
}
|
|
||||||
(void)fts_close(ftsp);
|
|
||||||
return (any_failed);
|
|
||||||
}
|
|
||||||
|
|
@ -1,61 +0,0 @@
|
||||||
/* $NetBSD: extern.h,v 1.17 2012/01/04 15:58:37 christos Exp $ */
|
|
||||||
|
|
||||||
/*-
|
|
||||||
* Copyright (c) 1991, 1993, 1994
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* @(#)extern.h 8.2 (Berkeley) 4/1/94
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _EXTERN_H_
|
|
||||||
#define _EXTERN_H_
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
char *p_end; /* pointer to NULL at end of path */
|
|
||||||
char *target_end; /* pointer to end of target base */
|
|
||||||
char p_path[MAXPATHLEN + 1]; /* pointer to the start of a path */
|
|
||||||
} PATH_T;
|
|
||||||
|
|
||||||
extern PATH_T to;
|
|
||||||
extern uid_t myuid;
|
|
||||||
extern int Rflag, rflag, Hflag, Lflag, Pflag, fflag, iflag, lflag, pflag, Nflag;
|
|
||||||
extern mode_t myumask;
|
|
||||||
extern sig_atomic_t pinfo;
|
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
|
||||||
|
|
||||||
__BEGIN_DECLS
|
|
||||||
int copy_fifo(struct stat *, int);
|
|
||||||
int copy_file(FTSENT *, int);
|
|
||||||
int copy_link(FTSENT *, int);
|
|
||||||
int copy_special(struct stat *, int);
|
|
||||||
int set_utimes(const char *, struct stat *);
|
|
||||||
int setfile(struct stat *, int);
|
|
||||||
void usage(void) __attribute__((__noreturn__));
|
|
||||||
__END_DECLS
|
|
||||||
|
|
||||||
#endif /* !_EXTERN_H_ */
|
|
||||||
431
bin/cp/utils.c
431
bin/cp/utils.c
|
|
@ -1,431 +0,0 @@
|
||||||
/* $NetBSD: utils.c,v 1.44 2015/03/03 00:20:38 enami Exp $ */
|
|
||||||
|
|
||||||
/*-
|
|
||||||
* Copyright (c) 1991, 1993, 1994
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
|
||||||
#ifndef lint
|
|
||||||
#if 0
|
|
||||||
static char sccsid[] = "@(#)utils.c 8.3 (Berkeley) 4/1/94";
|
|
||||||
#else
|
|
||||||
__RCSID("$NetBSD: utils.c,v 1.44 2015/03/03 00:20:38 enami Exp $");
|
|
||||||
#endif
|
|
||||||
#endif /* not lint */
|
|
||||||
|
|
||||||
#include <sys/mman.h>
|
|
||||||
#include <sys/param.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/time.h>
|
|
||||||
#include <sys/extattr.h>
|
|
||||||
|
|
||||||
#include <err.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <fts.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include "extern.h"
|
|
||||||
|
|
||||||
#define MMAP_MAX_SIZE (8 * 1048576)
|
|
||||||
#define MMAP_MAX_WRITE (64 * 1024)
|
|
||||||
|
|
||||||
int
|
|
||||||
set_utimes(const char *file, struct stat *fs)
|
|
||||||
{
|
|
||||||
struct timespec ts[2];
|
|
||||||
|
|
||||||
ts[0] = fs->st_atimespec;
|
|
||||||
ts[1] = fs->st_mtimespec;
|
|
||||||
|
|
||||||
if (lutimens(file, ts)) {
|
|
||||||
warn("lutimens: %s", file);
|
|
||||||
return (1);
|
|
||||||
}
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct finfo {
|
|
||||||
const char *from;
|
|
||||||
const char *to;
|
|
||||||
size_t size;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void
|
|
||||||
progress(const struct finfo *fi, size_t written)
|
|
||||||
{
|
|
||||||
int pcent = (int)((100.0 * written) / fi->size);
|
|
||||||
|
|
||||||
pinfo = 0;
|
|
||||||
(void)fprintf(stderr, "%s => %s %zu/%zu bytes %d%% written\n",
|
|
||||||
fi->from, fi->to, written, fi->size, pcent);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
copy_file(FTSENT *entp, int dne)
|
|
||||||
{
|
|
||||||
static char buf[MAXBSIZE];
|
|
||||||
struct stat to_stat, *fs;
|
|
||||||
int ch, checkch, from_fd, rcount, rval, to_fd, tolnk, wcount;
|
|
||||||
char *p;
|
|
||||||
size_t ptotal = 0;
|
|
||||||
|
|
||||||
if ((from_fd = open(entp->fts_path, O_RDONLY, 0)) == -1) {
|
|
||||||
warn("%s", entp->fts_path);
|
|
||||||
return (1);
|
|
||||||
}
|
|
||||||
|
|
||||||
to_fd = -1;
|
|
||||||
fs = entp->fts_statp;
|
|
||||||
tolnk = ((Rflag && !(Lflag || Hflag)) || Pflag);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If the file exists and we're interactive, verify with the user.
|
|
||||||
* If the file DNE, set the mode to be the from file, minus setuid
|
|
||||||
* bits, modified by the umask; arguably wrong, but it makes copying
|
|
||||||
* executables work right and it's been that way forever. (The
|
|
||||||
* other choice is 666 or'ed with the execute bits on the from file
|
|
||||||
* modified by the umask.)
|
|
||||||
*/
|
|
||||||
if (!dne) {
|
|
||||||
struct stat sb;
|
|
||||||
int sval;
|
|
||||||
|
|
||||||
if (iflag) {
|
|
||||||
(void)fprintf(stderr, "overwrite %s? ", to.p_path);
|
|
||||||
checkch = ch = getchar();
|
|
||||||
while (ch != '\n' && ch != EOF)
|
|
||||||
ch = getchar();
|
|
||||||
if (checkch != 'y' && checkch != 'Y') {
|
|
||||||
(void)close(from_fd);
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sval = tolnk ?
|
|
||||||
lstat(to.p_path, &sb) : stat(to.p_path, &sb);
|
|
||||||
if (sval == -1) {
|
|
||||||
warn("stat: %s", to.p_path);
|
|
||||||
(void)close(from_fd);
|
|
||||||
return (1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(tolnk && S_ISLNK(sb.st_mode)))
|
|
||||||
to_fd = open(to.p_path, O_WRONLY | O_TRUNC, 0);
|
|
||||||
} else
|
|
||||||
to_fd = open(to.p_path, O_WRONLY | O_TRUNC | O_CREAT,
|
|
||||||
fs->st_mode & ~(S_ISUID | S_ISGID));
|
|
||||||
|
|
||||||
if (to_fd == -1 && (fflag || tolnk)) {
|
|
||||||
/*
|
|
||||||
* attempt to remove existing destination file name and
|
|
||||||
* create a new file
|
|
||||||
*/
|
|
||||||
(void)unlink(to.p_path);
|
|
||||||
to_fd = open(to.p_path, O_WRONLY | O_TRUNC | O_CREAT,
|
|
||||||
fs->st_mode & ~(S_ISUID | S_ISGID));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (to_fd == -1) {
|
|
||||||
warn("%s", to.p_path);
|
|
||||||
(void)close(from_fd);
|
|
||||||
return (1);
|
|
||||||
}
|
|
||||||
|
|
||||||
rval = 0;
|
|
||||||
|
|
||||||
/* if hard linking then simply close the open fds, link and return */
|
|
||||||
if (lflag) {
|
|
||||||
(void)close(from_fd);
|
|
||||||
(void)close(to_fd);
|
|
||||||
(void)unlink(to.p_path);
|
|
||||||
if (link(entp->fts_path, to.p_path)) {
|
|
||||||
warn("%s", to.p_path);
|
|
||||||
return (1);
|
|
||||||
}
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
/* NOTREACHED */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* There's no reason to do anything other than close the file
|
|
||||||
* now if it's empty, so let's not bother.
|
|
||||||
*/
|
|
||||||
if (fs->st_size > 0) {
|
|
||||||
struct finfo fi;
|
|
||||||
|
|
||||||
fi.from = entp->fts_path;
|
|
||||||
fi.to = to.p_path;
|
|
||||||
fi.size = (size_t)fs->st_size;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Mmap and write if less than 8M (the limit is so
|
|
||||||
* we don't totally trash memory on big files).
|
|
||||||
* This is really a minor hack, but it wins some CPU back.
|
|
||||||
*/
|
|
||||||
bool use_read;
|
|
||||||
|
|
||||||
use_read = true;
|
|
||||||
if (fs->st_size <= MMAP_MAX_SIZE) {
|
|
||||||
size_t fsize = (size_t)fs->st_size;
|
|
||||||
p = mmap(NULL, fsize, PROT_READ, MAP_FILE|MAP_SHARED,
|
|
||||||
from_fd, (off_t)0);
|
|
||||||
if (p != MAP_FAILED) {
|
|
||||||
size_t remainder;
|
|
||||||
|
|
||||||
use_read = false;
|
|
||||||
|
|
||||||
#if !defined(__minix)
|
|
||||||
(void) madvise(p, (size_t)fs->st_size,
|
|
||||||
MADV_SEQUENTIAL);
|
|
||||||
#endif /* !defined(__minix) */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Write out the data in small chunks to
|
|
||||||
* avoid locking the output file for a
|
|
||||||
* long time if the reading the data from
|
|
||||||
* the source is slow.
|
|
||||||
*/
|
|
||||||
remainder = fsize;
|
|
||||||
do {
|
|
||||||
ssize_t chunk;
|
|
||||||
|
|
||||||
chunk = (remainder > MMAP_MAX_WRITE) ?
|
|
||||||
MMAP_MAX_WRITE : remainder;
|
|
||||||
if (write(to_fd, &p[fsize - remainder],
|
|
||||||
chunk) != chunk) {
|
|
||||||
warn("%s", to.p_path);
|
|
||||||
rval = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
remainder -= chunk;
|
|
||||||
ptotal += chunk;
|
|
||||||
if (pinfo)
|
|
||||||
progress(&fi, ptotal);
|
|
||||||
} while (remainder > 0);
|
|
||||||
|
|
||||||
if (munmap(p, fsize) < 0) {
|
|
||||||
warn("%s", entp->fts_path);
|
|
||||||
rval = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (use_read) {
|
|
||||||
while ((rcount = read(from_fd, buf, MAXBSIZE)) > 0) {
|
|
||||||
wcount = write(to_fd, buf, (size_t)rcount);
|
|
||||||
if (rcount != wcount || wcount == -1) {
|
|
||||||
warn("%s", to.p_path);
|
|
||||||
rval = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
ptotal += wcount;
|
|
||||||
if (pinfo)
|
|
||||||
progress(&fi, ptotal);
|
|
||||||
}
|
|
||||||
if (rcount < 0) {
|
|
||||||
warn("%s", entp->fts_path);
|
|
||||||
rval = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if !defined(__minix)
|
|
||||||
if (pflag && (fcpxattr(from_fd, to_fd) != 0))
|
|
||||||
warn("%s: error copying extended attributes", to.p_path);
|
|
||||||
#endif /* !defined(__minix) */
|
|
||||||
|
|
||||||
(void)close(from_fd);
|
|
||||||
|
|
||||||
if (rval == 1) {
|
|
||||||
(void)close(to_fd);
|
|
||||||
return (1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pflag && setfile(fs, to_fd))
|
|
||||||
rval = 1;
|
|
||||||
/*
|
|
||||||
* If the source was setuid or setgid, lose the bits unless the
|
|
||||||
* copy is owned by the same user and group.
|
|
||||||
*/
|
|
||||||
#define RETAINBITS \
|
|
||||||
(S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO)
|
|
||||||
if (!pflag && dne
|
|
||||||
&& fs->st_mode & (S_ISUID | S_ISGID) && fs->st_uid == myuid) {
|
|
||||||
if (fstat(to_fd, &to_stat)) {
|
|
||||||
warn("%s", to.p_path);
|
|
||||||
rval = 1;
|
|
||||||
} else if (fs->st_gid == to_stat.st_gid &&
|
|
||||||
fchmod(to_fd, fs->st_mode & RETAINBITS & ~myumask)) {
|
|
||||||
warn("%s", to.p_path);
|
|
||||||
rval = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (close(to_fd)) {
|
|
||||||
warn("%s", to.p_path);
|
|
||||||
rval = 1;
|
|
||||||
}
|
|
||||||
/* set the mod/access times now after close of the fd */
|
|
||||||
if (pflag && set_utimes(to.p_path, fs)) {
|
|
||||||
rval = 1;
|
|
||||||
}
|
|
||||||
return (rval);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
copy_link(FTSENT *p, int exists)
|
|
||||||
{
|
|
||||||
int len;
|
|
||||||
char target[MAXPATHLEN];
|
|
||||||
|
|
||||||
if ((len = readlink(p->fts_path, target, sizeof(target)-1)) == -1) {
|
|
||||||
warn("readlink: %s", p->fts_path);
|
|
||||||
return (1);
|
|
||||||
}
|
|
||||||
target[len] = '\0';
|
|
||||||
if (exists && unlink(to.p_path)) {
|
|
||||||
warn("unlink: %s", to.p_path);
|
|
||||||
return (1);
|
|
||||||
}
|
|
||||||
if (symlink(target, to.p_path)) {
|
|
||||||
warn("symlink: %s", target);
|
|
||||||
return (1);
|
|
||||||
}
|
|
||||||
return (pflag ? setfile(p->fts_statp, 0) : 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
copy_fifo(struct stat *from_stat, int exists)
|
|
||||||
{
|
|
||||||
if (exists && unlink(to.p_path)) {
|
|
||||||
warn("unlink: %s", to.p_path);
|
|
||||||
return (1);
|
|
||||||
}
|
|
||||||
if (mkfifo(to.p_path, from_stat->st_mode)) {
|
|
||||||
warn("mkfifo: %s", to.p_path);
|
|
||||||
return (1);
|
|
||||||
}
|
|
||||||
return (pflag ? setfile(from_stat, 0) : 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
copy_special(struct stat *from_stat, int exists)
|
|
||||||
{
|
|
||||||
if (exists && unlink(to.p_path)) {
|
|
||||||
warn("unlink: %s", to.p_path);
|
|
||||||
return (1);
|
|
||||||
}
|
|
||||||
if (mknod(to.p_path, from_stat->st_mode, from_stat->st_rdev)) {
|
|
||||||
warn("mknod: %s", to.p_path);
|
|
||||||
return (1);
|
|
||||||
}
|
|
||||||
return (pflag ? setfile(from_stat, 0) : 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Function: setfile
|
|
||||||
*
|
|
||||||
* Purpose:
|
|
||||||
* Set the owner/group/permissions for the "to" file to the information
|
|
||||||
* in the stat structure. If fd is zero, also call set_utimes() to set
|
|
||||||
* the mod/access times. If fd is non-zero, the caller must do a utimes
|
|
||||||
* itself after close(fd).
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
setfile(struct stat *fs, int fd)
|
|
||||||
{
|
|
||||||
int rval/* MINIX:, islink*/;
|
|
||||||
|
|
||||||
rval = 0;
|
|
||||||
#if !defined(__minix)
|
|
||||||
islink = S_ISLNK(fs->st_mode);
|
|
||||||
#endif /* !defined(__minix) */
|
|
||||||
fs->st_mode &= S_ISUID | S_ISGID | S_IRWXU | S_IRWXG | S_IRWXO;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Changing the ownership probably won't succeed, unless we're root
|
|
||||||
* or POSIX_CHOWN_RESTRICTED is not set. Set uid/gid before setting
|
|
||||||
* the mode; current BSD behavior is to remove all setuid bits on
|
|
||||||
* chown. If chown fails, lose setuid/setgid bits.
|
|
||||||
*/
|
|
||||||
if (fd ? fchown(fd, fs->st_uid, fs->st_gid) :
|
|
||||||
lchown(to.p_path, fs->st_uid, fs->st_gid)) {
|
|
||||||
if (errno != EPERM) {
|
|
||||||
warn("chown: %s", to.p_path);
|
|
||||||
rval = 1;
|
|
||||||
}
|
|
||||||
fs->st_mode &= ~(S_ISUID | S_ISGID);
|
|
||||||
}
|
|
||||||
if (fd ? fchmod(fd, fs->st_mode) : lchmod(to.p_path, fs->st_mode)) {
|
|
||||||
warn("chmod: %s", to.p_path);
|
|
||||||
rval = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if !defined(__minix)
|
|
||||||
if (!islink && !Nflag) {
|
|
||||||
unsigned long fflags = fs->st_flags;
|
|
||||||
/*
|
|
||||||
* XXX
|
|
||||||
* NFS doesn't support chflags; ignore errors unless
|
|
||||||
* there's reason to believe we're losing bits.
|
|
||||||
* (Note, this still won't be right if the server
|
|
||||||
* supports flags and we were trying to *remove* flags
|
|
||||||
* on a file that we copied, i.e., that we didn't create.)
|
|
||||||
*/
|
|
||||||
errno = 0;
|
|
||||||
|
|
||||||
if ((fd ? fchflags(fd, fflags) :
|
|
||||||
chflags(to.p_path, fflags)) == -1)
|
|
||||||
if (errno != EOPNOTSUPP || fs->st_flags != 0) {
|
|
||||||
warn("chflags: %s", to.p_path);
|
|
||||||
rval = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif /* !defined(__minix) */
|
|
||||||
|
|
||||||
/* if fd is non-zero, caller must call set_utimes() after close() */
|
|
||||||
if (fd == 0 && set_utimes(to.p_path, fs))
|
|
||||||
rval = 1;
|
|
||||||
return (rval);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
usage(void)
|
|
||||||
{
|
|
||||||
(void)fprintf(stderr,
|
|
||||||
"usage: %s [-R [-H | -L | -P]] [-f | -i] [-alNpv] src target\n"
|
|
||||||
" %s [-R [-H | -L | -P]] [-f | -i] [-alNpv] src1 ... srcN directory\n",
|
|
||||||
getprogname(), getprogname());
|
|
||||||
exit(1);
|
|
||||||
/* NOTREACHED */
|
|
||||||
}
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
# $NetBSD: Makefile,v 1.15 2011/08/14 10:53:16 christos Exp $
|
|
||||||
# @(#)Makefile 8.1 (Berkeley) 5/31/93
|
|
||||||
|
|
||||||
PROG= date
|
|
||||||
SRCS= date.c netdate.c
|
|
||||||
DPADD+= ${LIBUTIL}
|
|
||||||
LDADD+= -lutil
|
|
||||||
CPPFLAGS+=-I${.CURDIR}
|
|
||||||
|
|
||||||
COPTS.date.c = -Wno-format-nonliteral
|
|
||||||
|
|
||||||
.include <bsd.prog.mk>
|
|
||||||
251
bin/date/date.1
251
bin/date/date.1
|
|
@ -1,251 +0,0 @@
|
||||||
.\" $NetBSD: date.1,v 1.44 2017/01/03 16:01:05 abhinav Exp $
|
|
||||||
.\"
|
|
||||||
.\" Copyright (c) 1980, 1990, 1993
|
|
||||||
.\" The Regents of the University of California. All rights reserved.
|
|
||||||
.\"
|
|
||||||
.\" This code is derived from software contributed to Berkeley by
|
|
||||||
.\" the Institute of Electrical and Electronics Engineers, Inc.
|
|
||||||
.\"
|
|
||||||
.\" 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.
|
|
||||||
.\"
|
|
||||||
.\" @(#)date.1 8.3 (Berkeley) 4/28/95
|
|
||||||
.\"
|
|
||||||
.Dd August 11, 2016
|
|
||||||
.Dt DATE 1
|
|
||||||
.Os
|
|
||||||
.Sh NAME
|
|
||||||
.Nm date
|
|
||||||
.Nd display or set date and time
|
|
||||||
.Sh SYNOPSIS
|
|
||||||
.Nm
|
|
||||||
.Op Fl ajnu
|
|
||||||
.Op Fl d Ar date
|
|
||||||
.Op Fl r Ar seconds
|
|
||||||
.Op Cm + Ns Ar format
|
|
||||||
.Sm off
|
|
||||||
.Oo Oo Oo Oo Oo Oo
|
|
||||||
.Ar CC Oc
|
|
||||||
.Ar yy Oc
|
|
||||||
.Ar mm Oc
|
|
||||||
.Ar dd Oc
|
|
||||||
.Ar HH Oc Ar MM Oo
|
|
||||||
.Li \&. Ar SS Oc Oc
|
|
||||||
.Sm on
|
|
||||||
.Sh DESCRIPTION
|
|
||||||
.Nm
|
|
||||||
displays the current date and time when invoked without arguments.
|
|
||||||
Providing arguments will format the date and time in a user-defined
|
|
||||||
way or set the date.
|
|
||||||
Only the superuser may set the date.
|
|
||||||
.Pp
|
|
||||||
The options are as follows:
|
|
||||||
.Bl -tag -width Ds
|
|
||||||
.It Fl a
|
|
||||||
Use
|
|
||||||
.Xr adjtime 2
|
|
||||||
to change the local system time slowly,
|
|
||||||
maintaining it as a monotonically increasing function.
|
|
||||||
.Fl a
|
|
||||||
implies
|
|
||||||
.Fl n .
|
|
||||||
.It Fl d Ar date
|
|
||||||
Parse the provided human-described date and time and display the result without
|
|
||||||
actually changing the system clock.
|
|
||||||
(See
|
|
||||||
.Xr parsedate 3
|
|
||||||
for examples.)
|
|
||||||
.It Fl j
|
|
||||||
Parse the provided canonical representation of date and time (described below)
|
|
||||||
and display the result without actually changing the system clock.
|
|
||||||
.It Fl n
|
|
||||||
The utility
|
|
||||||
.Xr timed 8
|
|
||||||
is used to synchronize the clocks on groups of machines.
|
|
||||||
By default, if
|
|
||||||
.Xr timed 8
|
|
||||||
is running,
|
|
||||||
.Nm
|
|
||||||
will set the time on all of the machines in the local group.
|
|
||||||
The
|
|
||||||
.Fl n
|
|
||||||
option stops
|
|
||||||
.Nm
|
|
||||||
from setting the time for other than the current machine.
|
|
||||||
.It Fl r Ar seconds
|
|
||||||
Print out the date and time that is
|
|
||||||
.Ar seconds
|
|
||||||
from the Epoch.
|
|
||||||
.It Fl u
|
|
||||||
Display or set the date in
|
|
||||||
.Tn UTC
|
|
||||||
(universal) time.
|
|
||||||
.El
|
|
||||||
.Pp
|
|
||||||
An operand with a leading plus
|
|
||||||
.Pq Cm +
|
|
||||||
sign signals a user-defined format
|
|
||||||
string which specifies the format in which to display the date and time.
|
|
||||||
The format string may contain any of the conversion specifications described
|
|
||||||
in the
|
|
||||||
.Xr strftime 3
|
|
||||||
manual page, as well as any arbitrary text.
|
|
||||||
A \*[Lt]newline\*[Gt] character is always output after the characters
|
|
||||||
specified by the format string.
|
|
||||||
The format string for the default display is:
|
|
||||||
.Bd -literal -offset indent
|
|
||||||
%a %b %e %H:%M:%S %Z %Y
|
|
||||||
.Ed
|
|
||||||
.Pp
|
|
||||||
If an operand does not have a leading plus sign, it is interpreted as
|
|
||||||
a value for setting the system's notion of the current date and time.
|
|
||||||
The canonical representation for setting the date and time is:
|
|
||||||
.Pp
|
|
||||||
.Bl -tag -width Ds -compact -offset indent
|
|
||||||
.It Ar CC
|
|
||||||
The first two digits of the year (the century).
|
|
||||||
.It Ar yy
|
|
||||||
The second two digits of the year.
|
|
||||||
If
|
|
||||||
.Ar yy
|
|
||||||
is specified, but
|
|
||||||
.Ar CC
|
|
||||||
is not, a value for
|
|
||||||
.Ar yy
|
|
||||||
between 69 and 99 results in a
|
|
||||||
.Ar CC
|
|
||||||
value of 19.
|
|
||||||
Otherwise, a
|
|
||||||
.Ar CC
|
|
||||||
value of 20 is used.
|
|
||||||
.It Ar mm
|
|
||||||
The month of the year, from 01 to 12.
|
|
||||||
.It Ar dd
|
|
||||||
The day of the month, from 01 to 31.
|
|
||||||
.It Ar HH
|
|
||||||
The hour of the day, from 00 to 23.
|
|
||||||
.It Ar MM
|
|
||||||
The minute of the hour, from 00 to 59.
|
|
||||||
.It Ar SS
|
|
||||||
The second of the minute, from 00 to 60.
|
|
||||||
.El
|
|
||||||
.Pp
|
|
||||||
Everything but the minutes is optional.
|
|
||||||
.Pp
|
|
||||||
Time changes for Daylight Saving and Standard Time and leap seconds
|
|
||||||
and years are handled automatically.
|
|
||||||
.Sh ENVIRONMENT
|
|
||||||
The following environment variables affect the execution of
|
|
||||||
.Nm :
|
|
||||||
.Bl -tag -width iTZ
|
|
||||||
.It Ev TZ
|
|
||||||
The timezone to use when displaying dates.
|
|
||||||
See
|
|
||||||
.Xr environ 7
|
|
||||||
for more information.
|
|
||||||
.El
|
|
||||||
.Sh FILES
|
|
||||||
.Bl -tag -width /var/log/messages -compact
|
|
||||||
.It Pa /etc/localtime
|
|
||||||
Symlink pointing to system's default timezone information file in
|
|
||||||
.Pa /usr/share/zoneinfo
|
|
||||||
directory.
|
|
||||||
.It Pa /var/log/wtmp
|
|
||||||
A record of date resets and time changes.
|
|
||||||
.It Pa /var/log/messages
|
|
||||||
A record of the user setting the time.
|
|
||||||
.El
|
|
||||||
.Sh EXAMPLES
|
|
||||||
The command:
|
|
||||||
.Bd -literal -offset indent
|
|
||||||
date '+DATE: %m/%d/%y%nTIME: %H:%M:%S'
|
|
||||||
.Ed
|
|
||||||
.Pp
|
|
||||||
will display:
|
|
||||||
.Bd -literal -offset indent
|
|
||||||
DATE: 11/21/87
|
|
||||||
TIME: 13:36:16
|
|
||||||
.Ed
|
|
||||||
.Pp
|
|
||||||
The command:
|
|
||||||
.Bd -literal -offset indent
|
|
||||||
date 8506131627
|
|
||||||
.Ed
|
|
||||||
.Pp
|
|
||||||
sets the date to
|
|
||||||
.Dq Li "June 13, 1985, 4:27 PM" .
|
|
||||||
.Pp
|
|
||||||
The command:
|
|
||||||
.Bd -literal -offset indent
|
|
||||||
date 1432
|
|
||||||
.Ed
|
|
||||||
.Pp
|
|
||||||
sets the time to
|
|
||||||
.Li "2:32 PM" ,
|
|
||||||
without modifying the date.
|
|
||||||
.Sh DIAGNOSTICS
|
|
||||||
Exit status is 0 on success, 1 if unable to set the date, and 2
|
|
||||||
if able to set the local date, but unable to set it globally.
|
|
||||||
.Pp
|
|
||||||
Occasionally, when
|
|
||||||
.Xr timed 8
|
|
||||||
synchronizes the time on many hosts, the setting of a new time value may
|
|
||||||
require more than a few seconds.
|
|
||||||
On these occasions,
|
|
||||||
.Nm
|
|
||||||
prints:
|
|
||||||
.Ql Network time being set .
|
|
||||||
The message
|
|
||||||
.Ql Communication error with
|
|
||||||
.Xr timed 8
|
|
||||||
occurs when the communication
|
|
||||||
between
|
|
||||||
.Nm
|
|
||||||
and
|
|
||||||
.Xr timed 8
|
|
||||||
fails.
|
|
||||||
.Sh SEE ALSO
|
|
||||||
.Xr adjtime 2 ,
|
|
||||||
.Xr gettimeofday 2 ,
|
|
||||||
.Xr settimeofday 2 ,
|
|
||||||
.Xr parsedate 3 ,
|
|
||||||
.Xr strftime 3 ,
|
|
||||||
.Xr utmp 5 ,
|
|
||||||
.Xr environ 7 ,
|
|
||||||
.Xr timed 8
|
|
||||||
.Rs
|
|
||||||
.%T "TSP: The Time Synchronization Protocol for UNIX 4.3BSD"
|
|
||||||
.%A R. Gusella
|
|
||||||
.%A S. Zatti
|
|
||||||
.Re
|
|
||||||
.Sh STANDARDS
|
|
||||||
The
|
|
||||||
.Nm
|
|
||||||
utility is expected to be compatible with
|
|
||||||
.St -p1003.2 .
|
|
||||||
.Sh HISTORY
|
|
||||||
A
|
|
||||||
.Nm
|
|
||||||
utility appeared in
|
|
||||||
.At v1 .
|
|
||||||
369
bin/date/date.c
369
bin/date/date.c
|
|
@ -1,369 +0,0 @@
|
||||||
/* $NetBSD: date.c,v 1.61 2014/09/01 21:42:21 dholland Exp $ */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (c) 1985, 1987, 1988, 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
|
||||||
#ifndef lint
|
|
||||||
__COPYRIGHT(
|
|
||||||
"@(#) Copyright (c) 1985, 1987, 1988, 1993\
|
|
||||||
The Regents of the University of California. All rights reserved.");
|
|
||||||
#endif /* not lint */
|
|
||||||
|
|
||||||
#ifndef lint
|
|
||||||
#if 0
|
|
||||||
static char sccsid[] = "@(#)date.c 8.2 (Berkeley) 4/28/95";
|
|
||||||
#else
|
|
||||||
__RCSID("$NetBSD: date.c,v 1.61 2014/09/01 21:42:21 dholland Exp $");
|
|
||||||
#endif
|
|
||||||
#endif /* not lint */
|
|
||||||
|
|
||||||
#include <sys/param.h>
|
|
||||||
#include <sys/time.h>
|
|
||||||
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <err.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <locale.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <syslog.h>
|
|
||||||
#include <time.h>
|
|
||||||
#include <tzfile.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <util.h>
|
|
||||||
|
|
||||||
#include "extern.h"
|
|
||||||
|
|
||||||
static time_t tval;
|
|
||||||
static int aflag, jflag, rflag, nflag;
|
|
||||||
|
|
||||||
__dead static void badcanotime(const char *, const char *, size_t);
|
|
||||||
static void setthetime(const char *);
|
|
||||||
__dead static void usage(void);
|
|
||||||
|
|
||||||
int
|
|
||||||
main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
char *buf;
|
|
||||||
size_t bufsiz;
|
|
||||||
const char *format;
|
|
||||||
int ch;
|
|
||||||
long long val;
|
|
||||||
struct tm *tm;
|
|
||||||
|
|
||||||
setprogname(argv[0]);
|
|
||||||
(void)setlocale(LC_ALL, "");
|
|
||||||
|
|
||||||
while ((ch = getopt(argc, argv, "ad:jnr:u")) != -1) {
|
|
||||||
switch (ch) {
|
|
||||||
case 'a': /* adjust time slowly */
|
|
||||||
aflag = 1;
|
|
||||||
nflag = 1;
|
|
||||||
break;
|
|
||||||
case 'd':
|
|
||||||
#if !defined(__minix)
|
|
||||||
rflag = 1;
|
|
||||||
tval = parsedate(optarg, NULL, NULL);
|
|
||||||
if (tval == -1) {
|
|
||||||
errx(EXIT_FAILURE,
|
|
||||||
"%s: Unrecognized date format", optarg);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
errx(EXIT_FAILURE,
|
|
||||||
"%s: Unrecognized date format", optarg);
|
|
||||||
#endif /* !defined(__minix) */
|
|
||||||
break;
|
|
||||||
case 'j': /* don't set time */
|
|
||||||
jflag = 1;
|
|
||||||
break;
|
|
||||||
case 'n': /* don't set network */
|
|
||||||
nflag = 1;
|
|
||||||
break;
|
|
||||||
case 'r': /* user specified seconds */
|
|
||||||
if (optarg[0] == '\0') {
|
|
||||||
errx(EXIT_FAILURE, "<empty>: Invalid number");
|
|
||||||
}
|
|
||||||
errno = 0;
|
|
||||||
val = strtoll(optarg, &buf, 0);
|
|
||||||
if (errno) {
|
|
||||||
err(EXIT_FAILURE, "%s", optarg);
|
|
||||||
}
|
|
||||||
if (optarg[0] == '\0' || *buf != '\0') {
|
|
||||||
errx(EXIT_FAILURE,
|
|
||||||
"%s: Invalid number", optarg);
|
|
||||||
}
|
|
||||||
rflag = 1;
|
|
||||||
tval = (time_t)val;
|
|
||||||
break;
|
|
||||||
case 'u': /* do everything in UTC */
|
|
||||||
(void)setenv("TZ", "UTC0", 1);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
usage();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
argc -= optind;
|
|
||||||
argv += optind;
|
|
||||||
|
|
||||||
if (!rflag && time(&tval) == -1)
|
|
||||||
err(EXIT_FAILURE, "time");
|
|
||||||
|
|
||||||
|
|
||||||
/* allow the operands in any order */
|
|
||||||
if (*argv && **argv == '+') {
|
|
||||||
format = *argv;
|
|
||||||
++argv;
|
|
||||||
} else
|
|
||||||
format = "+%a %b %e %H:%M:%S %Z %Y";
|
|
||||||
|
|
||||||
if (*argv) {
|
|
||||||
setthetime(*argv);
|
|
||||||
++argv;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*argv && **argv == '+')
|
|
||||||
format = *argv;
|
|
||||||
|
|
||||||
if ((buf = malloc(bufsiz = 1024)) == NULL)
|
|
||||||
goto bad;
|
|
||||||
|
|
||||||
if ((tm = localtime(&tval)) == NULL)
|
|
||||||
err(EXIT_FAILURE, "%lld: localtime", (long long)tval);
|
|
||||||
|
|
||||||
while (strftime(buf, bufsiz, format, tm) == 0)
|
|
||||||
if ((buf = realloc(buf, bufsiz <<= 1)) == NULL)
|
|
||||||
goto bad;
|
|
||||||
|
|
||||||
(void)printf("%s\n", buf + 1);
|
|
||||||
free(buf);
|
|
||||||
return 0;
|
|
||||||
bad:
|
|
||||||
err(EXIT_FAILURE, "Cannot allocate format buffer");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
badcanotime(const char *msg, const char *val, size_t where)
|
|
||||||
{
|
|
||||||
warnx("%s in canonical time", msg);
|
|
||||||
warnx("%s", val);
|
|
||||||
warnx("%*s", (int)where + 1, "^");
|
|
||||||
usage();
|
|
||||||
}
|
|
||||||
|
|
||||||
#define ATOI2(s) ((s) += 2, ((s)[-2] - '0') * 10 + ((s)[-1] - '0'))
|
|
||||||
|
|
||||||
static void
|
|
||||||
setthetime(const char *p)
|
|
||||||
{
|
|
||||||
struct timeval tv;
|
|
||||||
time_t new_time;
|
|
||||||
struct tm *lt;
|
|
||||||
const char *dot, *t, *op;
|
|
||||||
size_t len;
|
|
||||||
int yearset;
|
|
||||||
|
|
||||||
for (t = p, dot = NULL; *t; ++t) {
|
|
||||||
if (*t == '.') {
|
|
||||||
if (dot == NULL) {
|
|
||||||
dot = t;
|
|
||||||
} else {
|
|
||||||
badcanotime("Unexpected dot", p, t - p);
|
|
||||||
}
|
|
||||||
} else if (!isdigit((unsigned char)*t)) {
|
|
||||||
badcanotime("Expected digit", p, t - p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((lt = localtime(&tval)) == NULL)
|
|
||||||
err(EXIT_FAILURE, "%lld: localtime", (long long)tval);
|
|
||||||
|
|
||||||
lt->tm_isdst = -1; /* Divine correct DST */
|
|
||||||
|
|
||||||
if (dot != NULL) { /* .ss */
|
|
||||||
len = strlen(dot);
|
|
||||||
if (len > 3) {
|
|
||||||
badcanotime("Unexpected digit after seconds field",
|
|
||||||
p, strlen(p) - 1);
|
|
||||||
} else if (len < 3) {
|
|
||||||
badcanotime("Expected digit in seconds field",
|
|
||||||
p, strlen(p));
|
|
||||||
}
|
|
||||||
++dot;
|
|
||||||
lt->tm_sec = ATOI2(dot);
|
|
||||||
if (lt->tm_sec > 61)
|
|
||||||
badcanotime("Seconds out of range", p, strlen(p) - 1);
|
|
||||||
} else {
|
|
||||||
len = 0;
|
|
||||||
lt->tm_sec = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
op = p;
|
|
||||||
yearset = 0;
|
|
||||||
switch (strlen(p) - len) {
|
|
||||||
case 12: /* cc */
|
|
||||||
lt->tm_year = ATOI2(p) * 100 - TM_YEAR_BASE;
|
|
||||||
if (lt->tm_year < 0)
|
|
||||||
badcanotime("Year before 1900", op, p - op + 1);
|
|
||||||
yearset = 1;
|
|
||||||
/* FALLTHROUGH */
|
|
||||||
case 10: /* yy */
|
|
||||||
if (yearset) {
|
|
||||||
lt->tm_year += ATOI2(p);
|
|
||||||
} else {
|
|
||||||
yearset = ATOI2(p);
|
|
||||||
if (yearset < 69)
|
|
||||||
lt->tm_year = yearset + 2000 - TM_YEAR_BASE;
|
|
||||||
else
|
|
||||||
lt->tm_year = yearset + 1900 - TM_YEAR_BASE;
|
|
||||||
}
|
|
||||||
/* FALLTHROUGH */
|
|
||||||
case 8: /* mm */
|
|
||||||
lt->tm_mon = ATOI2(p);
|
|
||||||
if (lt->tm_mon > 12 || lt->tm_mon == 0)
|
|
||||||
badcanotime("Month out of range", op, p - op - 1);
|
|
||||||
--lt->tm_mon; /* time struct is 0 - 11 */
|
|
||||||
/* FALLTHROUGH */
|
|
||||||
case 6: /* dd */
|
|
||||||
lt->tm_mday = ATOI2(p);
|
|
||||||
switch (lt->tm_mon) {
|
|
||||||
case 0:
|
|
||||||
case 2:
|
|
||||||
case 4:
|
|
||||||
case 6:
|
|
||||||
case 7:
|
|
||||||
case 9:
|
|
||||||
case 11:
|
|
||||||
if (lt->tm_mday > 31 || lt->tm_mday == 0)
|
|
||||||
badcanotime("Day out of range (max 31)",
|
|
||||||
op, p - op - 1);
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
case 5:
|
|
||||||
case 8:
|
|
||||||
case 10:
|
|
||||||
if (lt->tm_mday > 30 || lt->tm_mday == 0)
|
|
||||||
badcanotime("Day out of range (max 30)",
|
|
||||||
op, p - op - 1);
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
if (isleap(lt->tm_year + TM_YEAR_BASE)) {
|
|
||||||
if (lt->tm_mday > 29 || lt->tm_mday == 0) {
|
|
||||||
badcanotime("Day out of range "
|
|
||||||
"(max 29)",
|
|
||||||
op, p - op - 1);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (lt->tm_mday > 28 || lt->tm_mday == 0) {
|
|
||||||
badcanotime("Day out of range "
|
|
||||||
"(max 28)",
|
|
||||||
op, p - op - 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
/*
|
|
||||||
* If the month was given, it's already been
|
|
||||||
* checked. If a bad value came back from
|
|
||||||
* localtime, something's badly broken.
|
|
||||||
* (make this an assertion?)
|
|
||||||
*/
|
|
||||||
errx(EXIT_FAILURE, "localtime gave invalid month %d",
|
|
||||||
lt->tm_mon);
|
|
||||||
}
|
|
||||||
/* FALLTHROUGH */
|
|
||||||
case 4: /* hh */
|
|
||||||
lt->tm_hour = ATOI2(p);
|
|
||||||
if (lt->tm_hour > 23)
|
|
||||||
badcanotime("Hour out of range", op, p - op - 1);
|
|
||||||
/* FALLTHROUGH */
|
|
||||||
case 2: /* mm */
|
|
||||||
lt->tm_min = ATOI2(p);
|
|
||||||
if (lt->tm_min > 59)
|
|
||||||
badcanotime("Minute out of range", op, p - op - 1);
|
|
||||||
break;
|
|
||||||
case 0: /* was just .sss */
|
|
||||||
if (len != 0)
|
|
||||||
break;
|
|
||||||
/* FALLTHROUGH */
|
|
||||||
default:
|
|
||||||
if (strlen(p) - len > 12) {
|
|
||||||
badcanotime("Too many digits", p, 12);
|
|
||||||
} else {
|
|
||||||
badcanotime("Not enough digits", p, strlen(p) - len);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* convert broken-down time to UTC clock time */
|
|
||||||
if ((new_time = mktime(lt)) == -1) {
|
|
||||||
/* Can this actually happen? */
|
|
||||||
err(EXIT_FAILURE, "%s: mktime", op);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* if jflag is set, don't actually change the time, just return */
|
|
||||||
if (jflag) {
|
|
||||||
tval = new_time;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* set the time */
|
|
||||||
if (nflag || netsettime(new_time)) {
|
|
||||||
logwtmp("|", "date", "");
|
|
||||||
if (aflag) {
|
|
||||||
tv.tv_sec = new_time - tval;
|
|
||||||
tv.tv_usec = 0;
|
|
||||||
if (adjtime(&tv, NULL))
|
|
||||||
err(EXIT_FAILURE, "adjtime");
|
|
||||||
} else {
|
|
||||||
tval = new_time;
|
|
||||||
tv.tv_sec = tval;
|
|
||||||
tv.tv_usec = 0;
|
|
||||||
if (settimeofday(&tv, NULL))
|
|
||||||
err(EXIT_FAILURE, "settimeofday");
|
|
||||||
}
|
|
||||||
logwtmp("{", "date", "");
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((p = getlogin()) == NULL)
|
|
||||||
p = "???";
|
|
||||||
syslog(LOG_AUTH | LOG_NOTICE, "date set by %s", p);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
usage(void)
|
|
||||||
{
|
|
||||||
(void)fprintf(stderr,
|
|
||||||
"Usage: %s [-ajnu] [-d date] [-r seconds] [+format]",
|
|
||||||
getprogname());
|
|
||||||
(void)fprintf(stderr, " [[[[[[CC]yy]mm]dd]HH]MM[.SS]]\n");
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
/* NOTREACHED */
|
|
||||||
}
|
|
||||||
|
|
@ -1,39 +0,0 @@
|
||||||
/* $NetBSD: extern.h,v 1.8 2006/11/17 22:11:28 christos Exp $ */
|
|
||||||
|
|
||||||
/*-
|
|
||||||
* Copyright (c) 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.
|
|
||||||
*
|
|
||||||
* @(#)extern.h 8.1 (Berkeley) 5/31/93
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _EXTERN_H_
|
|
||||||
#define _EXTERN_H_
|
|
||||||
|
|
||||||
int netsettime(time_t);
|
|
||||||
|
|
||||||
#endif /* !_EXTERN_H_ */
|
|
||||||
|
|
@ -1,200 +0,0 @@
|
||||||
/* $NetBSD: netdate.c,v 1.30 2011/01/29 02:16:52 christos Exp $ */
|
|
||||||
|
|
||||||
/*-
|
|
||||||
* Copyright (c) 1990, 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
|
||||||
#ifndef lint
|
|
||||||
#if 0
|
|
||||||
static char sccsid[] = "@(#)netdate.c 8.2 (Berkeley) 4/28/95";
|
|
||||||
#else
|
|
||||||
__RCSID("$NetBSD: netdate.c,v 1.30 2011/01/29 02:16:52 christos Exp $");
|
|
||||||
#endif
|
|
||||||
#endif /* not lint */
|
|
||||||
|
|
||||||
#include <sys/param.h>
|
|
||||||
#include <sys/time.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#include <netdb.h>
|
|
||||||
#define TSPTYPES
|
|
||||||
#include <protocols/timed.h>
|
|
||||||
|
|
||||||
#include <err.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <poll.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include "extern.h"
|
|
||||||
|
|
||||||
#define WAITACK 2000 /* milliseconds */
|
|
||||||
#define WAITDATEACK 5000 /* milliseconds */
|
|
||||||
|
|
||||||
static const char *
|
|
||||||
tsp_type_to_string(const struct tsp *msg)
|
|
||||||
{
|
|
||||||
unsigned i;
|
|
||||||
|
|
||||||
i = msg->tsp_type;
|
|
||||||
return i < TSPTYPENUMBER ? tsptype[i] : "unknown";
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set the date in the machines controlled by timedaemons by communicating the
|
|
||||||
* new date to the local timedaemon. If the timedaemon is in the master state,
|
|
||||||
* it performs the correction on all slaves. If it is in the slave state, it
|
|
||||||
* notifies the master that a correction is needed.
|
|
||||||
* Returns 0 on success. Returns > 0 on failure.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
netsettime(time_t tval)
|
|
||||||
{
|
|
||||||
struct sockaddr_in dest;
|
|
||||||
struct tsp msg;
|
|
||||||
char hostname[MAXHOSTNAMELEN];
|
|
||||||
struct servent *sp;
|
|
||||||
struct pollfd ready;
|
|
||||||
int found, s, timed_ack, waittime;
|
|
||||||
|
|
||||||
if ((sp = getservbyname("timed", "udp")) == NULL) {
|
|
||||||
warnx("udp/timed: unknown service");
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
(void)memset(&dest, 0, sizeof(dest));
|
|
||||||
#ifdef BSD4_4
|
|
||||||
dest.sin_len = sizeof(dest);
|
|
||||||
#endif
|
|
||||||
dest.sin_family = AF_INET;
|
|
||||||
dest.sin_port = sp->s_port;
|
|
||||||
dest.sin_addr.s_addr = htonl(INADDR_ANY);
|
|
||||||
s = socket(AF_INET, SOCK_DGRAM, 0);
|
|
||||||
if (s == -1) {
|
|
||||||
if (errno != EAFNOSUPPORT)
|
|
||||||
warn("timed");
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef IP_PORTRANGE
|
|
||||||
{
|
|
||||||
static const int on = IP_PORTRANGE_LOW;
|
|
||||||
|
|
||||||
if (setsockopt(s, IPPROTO_IP, IP_PORTRANGE, &on,
|
|
||||||
sizeof(on)) == -1) {
|
|
||||||
warn("setsockopt");
|
|
||||||
goto bad;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
msg.tsp_type = TSP_SETDATE;
|
|
||||||
msg.tsp_vers = TSPVERSION;
|
|
||||||
if (gethostname(hostname, sizeof(hostname)) == -1) {
|
|
||||||
warn("gethostname");
|
|
||||||
goto bad;
|
|
||||||
}
|
|
||||||
(void)strlcpy(msg.tsp_name, hostname, sizeof(msg.tsp_name));
|
|
||||||
msg.tsp_seq = htons((in_port_t)0);
|
|
||||||
msg.tsp_time.tv_sec = htonl((in_addr_t)tval); /* XXX: y2038 */
|
|
||||||
msg.tsp_time.tv_usec = htonl((in_addr_t)0);
|
|
||||||
if (connect(s, (const void *)&dest, sizeof(dest)) == -1) {
|
|
||||||
warn("connect");
|
|
||||||
goto bad;
|
|
||||||
}
|
|
||||||
if (send(s, &msg, sizeof(msg), 0) == -1) {
|
|
||||||
if (errno != ECONNREFUSED)
|
|
||||||
warn("send");
|
|
||||||
goto bad;
|
|
||||||
}
|
|
||||||
|
|
||||||
timed_ack = -1;
|
|
||||||
waittime = WAITACK;
|
|
||||||
ready.fd = s;
|
|
||||||
ready.events = POLLIN;
|
|
||||||
loop:
|
|
||||||
found = poll(&ready, 1, waittime);
|
|
||||||
|
|
||||||
{
|
|
||||||
socklen_t len;
|
|
||||||
int error;
|
|
||||||
|
|
||||||
len = sizeof(error);
|
|
||||||
if (getsockopt(s, SOL_SOCKET, SO_ERROR, &error, &len) == -1) {
|
|
||||||
warn("getsockopt");
|
|
||||||
goto bad;
|
|
||||||
}
|
|
||||||
if (error) {
|
|
||||||
if (error != ECONNREFUSED) {
|
|
||||||
errno = error;
|
|
||||||
warn("send (delayed error)");
|
|
||||||
}
|
|
||||||
goto bad;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (found > 0 && ready.revents & POLLIN) {
|
|
||||||
ssize_t ret;
|
|
||||||
|
|
||||||
if ((ret = recv(s, &msg, sizeof(msg), 0)) == -1) {
|
|
||||||
if (errno != ECONNREFUSED)
|
|
||||||
warn("recv");
|
|
||||||
goto bad;
|
|
||||||
} else if ((size_t)ret < sizeof(msg)) {
|
|
||||||
warnx("recv: incomplete packet");
|
|
||||||
goto bad;
|
|
||||||
}
|
|
||||||
|
|
||||||
msg.tsp_seq = ntohs(msg.tsp_seq);
|
|
||||||
msg.tsp_time.tv_sec = ntohl(msg.tsp_time.tv_sec);
|
|
||||||
msg.tsp_time.tv_usec = ntohl(msg.tsp_time.tv_usec);
|
|
||||||
switch (msg.tsp_type) {
|
|
||||||
case TSP_ACK:
|
|
||||||
timed_ack = TSP_ACK;
|
|
||||||
waittime = WAITDATEACK;
|
|
||||||
goto loop;
|
|
||||||
case TSP_DATEACK:
|
|
||||||
(void)close(s);
|
|
||||||
return 0;
|
|
||||||
default:
|
|
||||||
warnx("wrong ack received from timed: %s",
|
|
||||||
tsp_type_to_string(&msg));
|
|
||||||
timed_ack = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (timed_ack == -1)
|
|
||||||
warnx("can't reach time daemon, time set locally");
|
|
||||||
|
|
||||||
bad:
|
|
||||||
(void)close(s);
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
505
bin/dd/args.c
505
bin/dd/args.c
|
|
@ -1,505 +0,0 @@
|
||||||
/* $NetBSD: args.c,v 1.39 2015/03/18 13:23:49 manu Exp $ */
|
|
||||||
|
|
||||||
/*-
|
|
||||||
* Copyright (c) 1991, 1993, 1994
|
|
||||||
* The Regents of the University of California. All rights reserved.
|
|
||||||
*
|
|
||||||
* This code is derived from software contributed to Berkeley by
|
|
||||||
* Keith Muller of the University of California, San Diego and Lance
|
|
||||||
* Visser of Convex Computer Corporation.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
|
||||||
#ifndef lint
|
|
||||||
#if 0
|
|
||||||
static char sccsid[] = "@(#)args.c 8.3 (Berkeley) 4/2/94";
|
|
||||||
#else
|
|
||||||
__RCSID("$NetBSD: args.c,v 1.39 2015/03/18 13:23:49 manu Exp $");
|
|
||||||
#endif
|
|
||||||
#endif /* not lint */
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/time.h>
|
|
||||||
|
|
||||||
#ifndef NO_IOFLAG
|
|
||||||
#include <fcntl.h>
|
|
||||||
#endif /* NO_IOFLAG */
|
|
||||||
#include <err.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <limits.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "dd.h"
|
|
||||||
#include "extern.h"
|
|
||||||
|
|
||||||
static int c_arg(const void *, const void *);
|
|
||||||
|
|
||||||
#ifdef NO_MSGFMT
|
|
||||||
static void f_msgfmt(char *) __dead;
|
|
||||||
#else
|
|
||||||
static void f_msgfmt(char *);
|
|
||||||
#endif /* NO_MSGFMT */
|
|
||||||
|
|
||||||
#ifdef NO_CONV
|
|
||||||
static void f_conv(char *) __dead;
|
|
||||||
#else
|
|
||||||
static void f_conv(char *);
|
|
||||||
static int c_conv(const void *, const void *);
|
|
||||||
#endif /* NO_CONV */
|
|
||||||
|
|
||||||
#ifdef NO_IOFLAG
|
|
||||||
static void f_iflag(char *) __dead;
|
|
||||||
static void f_oflag(char *) __dead;
|
|
||||||
#else
|
|
||||||
static void f_iflag(char *);
|
|
||||||
static void f_oflag(char *);
|
|
||||||
static u_int f_ioflag(char *, u_int);
|
|
||||||
static int c_ioflag(const void *, const void *);
|
|
||||||
#endif /* NO_IOFLAG */
|
|
||||||
|
|
||||||
static void f_bs(char *);
|
|
||||||
static void f_cbs(char *);
|
|
||||||
static void f_count(char *);
|
|
||||||
static void f_files(char *);
|
|
||||||
static void f_ibs(char *);
|
|
||||||
static void f_if(char *);
|
|
||||||
static void f_obs(char *);
|
|
||||||
static void f_of(char *);
|
|
||||||
static void f_seek(char *);
|
|
||||||
static void f_skip(char *);
|
|
||||||
static void f_progress(char *);
|
|
||||||
|
|
||||||
static const struct arg {
|
|
||||||
const char *name;
|
|
||||||
void (*f)(char *);
|
|
||||||
u_int set, noset;
|
|
||||||
} args[] = {
|
|
||||||
/* the array needs to be sorted by the first column so
|
|
||||||
bsearch() can be used to find commands quickly */
|
|
||||||
{ "bs", f_bs, C_BS, C_BS|C_IBS|C_OBS|C_OSYNC },
|
|
||||||
{ "cbs", f_cbs, C_CBS, C_CBS },
|
|
||||||
{ "conv", f_conv, 0, 0 },
|
|
||||||
{ "count", f_count, C_COUNT, C_COUNT },
|
|
||||||
{ "files", f_files, C_FILES, C_FILES },
|
|
||||||
{ "ibs", f_ibs, C_IBS, C_BS|C_IBS },
|
|
||||||
{ "if", f_if, C_IF, C_IF },
|
|
||||||
{ "iflag", f_iflag, C_IFLAG, C_IFLAG },
|
|
||||||
{ "iseek", f_skip, C_SKIP, C_SKIP },
|
|
||||||
{ "msgfmt", f_msgfmt, 0, 0 },
|
|
||||||
{ "obs", f_obs, C_OBS, C_BS|C_OBS },
|
|
||||||
{ "of", f_of, C_OF, C_OF },
|
|
||||||
{ "oflag", f_oflag, C_OFLAG, C_OFLAG },
|
|
||||||
{ "oseek", f_seek, C_SEEK, C_SEEK },
|
|
||||||
{ "progress", f_progress, 0, 0 },
|
|
||||||
{ "seek", f_seek, C_SEEK, C_SEEK },
|
|
||||||
{ "skip", f_skip, C_SKIP, C_SKIP },
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* args -- parse JCL syntax of dd.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
jcl(char **argv)
|
|
||||||
{
|
|
||||||
struct arg *ap, tmp;
|
|
||||||
char *oper, *arg;
|
|
||||||
|
|
||||||
in.dbsz = out.dbsz = 512;
|
|
||||||
|
|
||||||
while ((oper = *++argv) != NULL) {
|
|
||||||
if ((oper = strdup(oper)) == NULL) {
|
|
||||||
errx(EXIT_FAILURE,
|
|
||||||
"unable to allocate space for the argument %s",
|
|
||||||
*argv);
|
|
||||||
/* NOTREACHED */
|
|
||||||
}
|
|
||||||
if ((arg = strchr(oper, '=')) == NULL) {
|
|
||||||
errx(EXIT_FAILURE, "unknown operand %s", oper);
|
|
||||||
/* NOTREACHED */
|
|
||||||
}
|
|
||||||
*arg++ = '\0';
|
|
||||||
if (!*arg) {
|
|
||||||
errx(EXIT_FAILURE, "no value specified for %s", oper);
|
|
||||||
/* NOTREACHED */
|
|
||||||
}
|
|
||||||
tmp.name = oper;
|
|
||||||
if (!(ap = bsearch(&tmp, args,
|
|
||||||
__arraycount(args), sizeof(*args), c_arg))) {
|
|
||||||
errx(EXIT_FAILURE, "unknown operand %s", tmp.name);
|
|
||||||
/* NOTREACHED */
|
|
||||||
}
|
|
||||||
if (ddflags & ap->noset) {
|
|
||||||
errx(EXIT_FAILURE,
|
|
||||||
"%s: illegal argument combination or already set",
|
|
||||||
tmp.name);
|
|
||||||
/* NOTREACHED */
|
|
||||||
}
|
|
||||||
ddflags |= ap->set;
|
|
||||||
ap->f(arg);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Final sanity checks. */
|
|
||||||
|
|
||||||
if (ddflags & C_BS) {
|
|
||||||
/*
|
|
||||||
* Bs is turned off by any conversion -- we assume the user
|
|
||||||
* just wanted to set both the input and output block sizes
|
|
||||||
* and didn't want the bs semantics, so we don't warn.
|
|
||||||
*/
|
|
||||||
if (ddflags & (C_BLOCK | C_LCASE | C_SWAB | C_UCASE |
|
|
||||||
C_UNBLOCK | C_OSYNC | C_ASCII | C_EBCDIC | C_SPARSE)) {
|
|
||||||
ddflags &= ~C_BS;
|
|
||||||
ddflags |= C_IBS|C_OBS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Bs supersedes ibs and obs. */
|
|
||||||
if (ddflags & C_BS && ddflags & (C_IBS|C_OBS))
|
|
||||||
warnx("bs supersedes ibs and obs");
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Ascii/ebcdic and cbs implies block/unblock.
|
|
||||||
* Block/unblock requires cbs and vice-versa.
|
|
||||||
*/
|
|
||||||
if (ddflags & (C_BLOCK|C_UNBLOCK)) {
|
|
||||||
if (!(ddflags & C_CBS)) {
|
|
||||||
errx(EXIT_FAILURE, "record operations require cbs");
|
|
||||||
/* NOTREACHED */
|
|
||||||
}
|
|
||||||
cfunc = ddflags & C_BLOCK ? block : unblock;
|
|
||||||
} else if (ddflags & C_CBS) {
|
|
||||||
if (ddflags & (C_ASCII|C_EBCDIC)) {
|
|
||||||
if (ddflags & C_ASCII) {
|
|
||||||
ddflags |= C_UNBLOCK;
|
|
||||||
cfunc = unblock;
|
|
||||||
} else {
|
|
||||||
ddflags |= C_BLOCK;
|
|
||||||
cfunc = block;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
errx(EXIT_FAILURE,
|
|
||||||
"cbs meaningless if not doing record operations");
|
|
||||||
/* NOTREACHED */
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
cfunc = def;
|
|
||||||
|
|
||||||
/* Read, write and seek calls take off_t as arguments.
|
|
||||||
*
|
|
||||||
* The following check is not done because an off_t is a quad
|
|
||||||
* for current NetBSD implementations.
|
|
||||||
*
|
|
||||||
* if (in.offset > INT_MAX/in.dbsz || out.offset > INT_MAX/out.dbsz)
|
|
||||||
* errx(1, "seek offsets cannot be larger than %d", INT_MAX);
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
c_arg(const void *a, const void *b)
|
|
||||||
{
|
|
||||||
|
|
||||||
return (strcmp(((const struct arg *)a)->name,
|
|
||||||
((const struct arg *)b)->name));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
f_bs(char *arg)
|
|
||||||
{
|
|
||||||
|
|
||||||
in.dbsz = out.dbsz = strsuftoll("block size", arg, 1, UINT_MAX);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
f_cbs(char *arg)
|
|
||||||
{
|
|
||||||
|
|
||||||
cbsz = strsuftoll("conversion record size", arg, 1, UINT_MAX);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
f_count(char *arg)
|
|
||||||
{
|
|
||||||
|
|
||||||
cpy_cnt = strsuftoll("block count", arg, 0, LLONG_MAX);
|
|
||||||
if (!cpy_cnt)
|
|
||||||
terminate(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
f_files(char *arg)
|
|
||||||
{
|
|
||||||
|
|
||||||
files_cnt = (u_int)strsuftoll("file count", arg, 0, UINT_MAX);
|
|
||||||
if (!files_cnt)
|
|
||||||
terminate(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
f_ibs(char *arg)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (!(ddflags & C_BS))
|
|
||||||
in.dbsz = strsuftoll("input block size", arg, 1, UINT_MAX);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
f_if(char *arg)
|
|
||||||
{
|
|
||||||
|
|
||||||
in.name = arg;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef NO_MSGFMT
|
|
||||||
/* Build a small version (i.e. for a ramdisk root) */
|
|
||||||
static void
|
|
||||||
f_msgfmt(char *arg)
|
|
||||||
{
|
|
||||||
|
|
||||||
errx(EXIT_FAILURE, "msgfmt option disabled");
|
|
||||||
/* NOTREACHED */
|
|
||||||
}
|
|
||||||
#else /* NO_MSGFMT */
|
|
||||||
static void
|
|
||||||
f_msgfmt(char *arg)
|
|
||||||
{
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If the format string is not valid, dd_write_msg() will print
|
|
||||||
* an error and exit.
|
|
||||||
*/
|
|
||||||
dd_write_msg(arg, 0);
|
|
||||||
|
|
||||||
msgfmt = arg;
|
|
||||||
}
|
|
||||||
#endif /* NO_MSGFMT */
|
|
||||||
|
|
||||||
static void
|
|
||||||
f_obs(char *arg)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (!(ddflags & C_BS))
|
|
||||||
out.dbsz = strsuftoll("output block size", arg, 1, UINT_MAX);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
f_of(char *arg)
|
|
||||||
{
|
|
||||||
|
|
||||||
out.name = arg;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
f_seek(char *arg)
|
|
||||||
{
|
|
||||||
|
|
||||||
out.offset = strsuftoll("seek blocks", arg, 0, LLONG_MAX);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
f_skip(char *arg)
|
|
||||||
{
|
|
||||||
|
|
||||||
in.offset = strsuftoll("skip blocks", arg, 0, LLONG_MAX);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
f_progress(char *arg)
|
|
||||||
{
|
|
||||||
|
|
||||||
progress = strsuftoll("progress blocks", arg, 0, LLONG_MAX);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef NO_CONV
|
|
||||||
/* Build a small version (i.e. for a ramdisk root) */
|
|
||||||
static void
|
|
||||||
f_conv(char *arg)
|
|
||||||
{
|
|
||||||
|
|
||||||
errx(EXIT_FAILURE, "conv option disabled");
|
|
||||||
/* NOTREACHED */
|
|
||||||
}
|
|
||||||
#else /* NO_CONV */
|
|
||||||
|
|
||||||
static const struct conv {
|
|
||||||
const char *name;
|
|
||||||
u_int set, noset;
|
|
||||||
const u_char *ctab;
|
|
||||||
} clist[] = {
|
|
||||||
{ "ascii", C_ASCII, C_EBCDIC, e2a_POSIX },
|
|
||||||
{ "block", C_BLOCK, C_UNBLOCK, NULL },
|
|
||||||
{ "ebcdic", C_EBCDIC, C_ASCII, a2e_POSIX },
|
|
||||||
{ "ibm", C_EBCDIC, C_ASCII, a2ibm_POSIX },
|
|
||||||
{ "lcase", C_LCASE, C_UCASE, NULL },
|
|
||||||
{ "noerror", C_NOERROR, 0, NULL },
|
|
||||||
{ "notrunc", C_NOTRUNC, 0, NULL },
|
|
||||||
{ "oldascii", C_ASCII, C_EBCDIC, e2a_32V },
|
|
||||||
{ "oldebcdic", C_EBCDIC, C_ASCII, a2e_32V },
|
|
||||||
{ "oldibm", C_EBCDIC, C_ASCII, a2ibm_32V },
|
|
||||||
{ "osync", C_OSYNC, C_BS, NULL },
|
|
||||||
{ "sparse", C_SPARSE, 0, NULL },
|
|
||||||
{ "swab", C_SWAB, 0, NULL },
|
|
||||||
{ "sync", C_SYNC, 0, NULL },
|
|
||||||
{ "ucase", C_UCASE, C_LCASE, NULL },
|
|
||||||
{ "unblock", C_UNBLOCK, C_BLOCK, NULL },
|
|
||||||
/* If you add items to this table, be sure to add the
|
|
||||||
* conversions to the C_BS check in the jcl routine above.
|
|
||||||
*/
|
|
||||||
};
|
|
||||||
|
|
||||||
static void
|
|
||||||
f_conv(char *arg)
|
|
||||||
{
|
|
||||||
struct conv *cp, tmp;
|
|
||||||
|
|
||||||
while (arg != NULL) {
|
|
||||||
tmp.name = strsep(&arg, ",");
|
|
||||||
if (!(cp = bsearch(&tmp, clist,
|
|
||||||
__arraycount(clist), sizeof(*clist), c_conv))) {
|
|
||||||
errx(EXIT_FAILURE, "unknown conversion %s", tmp.name);
|
|
||||||
/* NOTREACHED */
|
|
||||||
}
|
|
||||||
if (ddflags & cp->noset) {
|
|
||||||
errx(EXIT_FAILURE,
|
|
||||||
"%s: illegal conversion combination", tmp.name);
|
|
||||||
/* NOTREACHED */
|
|
||||||
}
|
|
||||||
ddflags |= cp->set;
|
|
||||||
if (cp->ctab)
|
|
||||||
ctab = cp->ctab;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
c_conv(const void *a, const void *b)
|
|
||||||
{
|
|
||||||
|
|
||||||
return (strcmp(((const struct conv *)a)->name,
|
|
||||||
((const struct conv *)b)->name));
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* NO_CONV */
|
|
||||||
|
|
||||||
static void
|
|
||||||
f_iflag(char *arg)
|
|
||||||
{
|
|
||||||
/* Build a small version (i.e. for a ramdisk root) */
|
|
||||||
#ifdef NO_IOFLAG
|
|
||||||
errx(EXIT_FAILURE, "iflag option disabled");
|
|
||||||
/* NOTREACHED */
|
|
||||||
#else
|
|
||||||
iflag = f_ioflag(arg, C_IFLAG);
|
|
||||||
return;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
f_oflag(char *arg)
|
|
||||||
{
|
|
||||||
/* Build a small version (i.e. for a ramdisk root) */
|
|
||||||
#ifdef NO_IOFLAG
|
|
||||||
errx(EXIT_FAILURE, "oflag option disabled");
|
|
||||||
/* NOTREACHED */
|
|
||||||
#else
|
|
||||||
oflag = f_ioflag(arg, C_OFLAG);
|
|
||||||
return;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef NO_IOFLAG
|
|
||||||
static const struct ioflag {
|
|
||||||
const char *name;
|
|
||||||
u_int set;
|
|
||||||
u_int allowed;
|
|
||||||
} olist[] = {
|
|
||||||
/* the array needs to be sorted by the first column so
|
|
||||||
bsearch() can be used to find commands quickly */
|
|
||||||
{ "alt_io", O_ALT_IO, C_IFLAG|C_OFLAG },
|
|
||||||
{ "append", O_APPEND, C_OFLAG },
|
|
||||||
{ "async", O_ASYNC, C_IFLAG|C_OFLAG },
|
|
||||||
{ "cloexec", O_CLOEXEC, C_IFLAG|C_OFLAG },
|
|
||||||
{ "creat", O_CREAT, C_OFLAG },
|
|
||||||
{ "direct", O_DIRECT, C_IFLAG|C_OFLAG },
|
|
||||||
{ "directory", O_DIRECTORY, C_NONE },
|
|
||||||
{ "dsync", O_DSYNC, C_OFLAG },
|
|
||||||
{ "excl", O_EXCL, C_IFLAG|C_OFLAG },
|
|
||||||
{ "exlock", O_EXLOCK, C_IFLAG|C_OFLAG },
|
|
||||||
{ "noctty", O_NOCTTY, C_IFLAG|C_OFLAG },
|
|
||||||
{ "nofollow", O_NOFOLLOW, C_IFLAG|C_OFLAG },
|
|
||||||
{ "nonblock", O_NONBLOCK, C_IFLAG|C_OFLAG },
|
|
||||||
{ "nosigpipe", O_NOSIGPIPE, C_IFLAG|C_OFLAG },
|
|
||||||
{ "rdonly", O_RDONLY, C_IFLAG },
|
|
||||||
{ "rdwr", O_RDWR, C_IFLAG },
|
|
||||||
{ "rsync", O_RSYNC, C_IFLAG },
|
|
||||||
{ "search", O_SEARCH, C_IFLAG|C_OFLAG },
|
|
||||||
{ "shlock", O_SHLOCK, C_IFLAG|C_OFLAG },
|
|
||||||
{ "sync", O_SYNC, C_IFLAG|C_OFLAG },
|
|
||||||
{ "trunc", O_TRUNC, C_IFLAG|C_OFLAG },
|
|
||||||
{ "wronly", O_WRONLY, C_NONE },
|
|
||||||
};
|
|
||||||
|
|
||||||
static u_int
|
|
||||||
f_ioflag(char *arg, u_int flagtype)
|
|
||||||
{
|
|
||||||
u_int ioflag = 0;
|
|
||||||
struct ioflag *cp, tmp;
|
|
||||||
const char *flagstr = (flagtype == C_IFLAG) ? "iflag" : "oflag";
|
|
||||||
|
|
||||||
while (arg != NULL) {
|
|
||||||
tmp.name = strsep(&arg, ",");
|
|
||||||
if (!(cp = bsearch(&tmp, olist,
|
|
||||||
__arraycount(olist), sizeof(*olist), c_ioflag))) {
|
|
||||||
errx(EXIT_FAILURE, "unknown %s %s", flagstr, tmp.name);
|
|
||||||
/* NOTREACHED */
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((cp->set & O_ACCMODE) && (flagtype == C_OFLAG)) {
|
|
||||||
warnx("rdonly, rdwr and wronly are ignored for oflag");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((cp->allowed & flagtype) == 0) {
|
|
||||||
warnx("%s set for %s but makes no sense",
|
|
||||||
cp->name, flagstr);
|
|
||||||
}
|
|
||||||
|
|
||||||
ioflag |= cp->set;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return ioflag;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
c_ioflag(const void *a, const void *b)
|
|
||||||
{
|
|
||||||
|
|
||||||
return (strcmp(((const struct ioflag *)a)->name,
|
|
||||||
((const struct ioflag *)b)->name));
|
|
||||||
}
|
|
||||||
#endif /* NO_IOFLAG */
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
# $NetBSD: Makefile,v 1.8 1997/07/20 22:36:53 christos Exp $
|
|
||||||
# @(#)Makefile 8.1 (Berkeley) 5/31/93
|
|
||||||
|
|
||||||
PROG= echo
|
|
||||||
|
|
||||||
.include <bsd.prog.mk>
|
|
||||||
|
|
@ -1,73 +0,0 @@
|
||||||
.\" $NetBSD: echo.1,v 1.15 2016/08/14 22:59:22 sevan Exp $
|
|
||||||
.\"
|
|
||||||
.\" Copyright (c) 1990, 1993
|
|
||||||
.\" The Regents of the University of California. All rights reserved.
|
|
||||||
.\"
|
|
||||||
.\" This code is derived from software contributed to Berkeley by
|
|
||||||
.\" the Institute of Electrical and Electronics Engineers, Inc.
|
|
||||||
.\"
|
|
||||||
.\" 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.
|
|
||||||
.\"
|
|
||||||
.\" @(#)echo.1 8.1 (Berkeley) 7/22/93
|
|
||||||
.\"
|
|
||||||
.Dd August 14, 2016
|
|
||||||
.Dt ECHO 1
|
|
||||||
.Os
|
|
||||||
.Sh NAME
|
|
||||||
.Nm echo
|
|
||||||
.Nd write arguments to the standard output
|
|
||||||
.Sh SYNOPSIS
|
|
||||||
.Nm
|
|
||||||
.Op Fl n
|
|
||||||
.Op Ar string ...
|
|
||||||
.Sh DESCRIPTION
|
|
||||||
The
|
|
||||||
.Nm
|
|
||||||
utility writes any specified operands, separated by single blank (`` '')
|
|
||||||
characters and followed by a newline (``\en'') character, to the standard
|
|
||||||
output.
|
|
||||||
.Pp
|
|
||||||
The following option is available:
|
|
||||||
.Bl -tag -width flag
|
|
||||||
.It Fl n
|
|
||||||
Do not print the trailing newline character.
|
|
||||||
.El
|
|
||||||
.Sh EXIT STATUS
|
|
||||||
The
|
|
||||||
.Nm
|
|
||||||
utility exits 0 on success, and \*[Gt]0 if an error occurs.
|
|
||||||
.Sh SEE ALSO
|
|
||||||
.Xr printf 1
|
|
||||||
.Sh STANDARDS
|
|
||||||
The
|
|
||||||
.Nm
|
|
||||||
utility is expected to be
|
|
||||||
.St -p1003.2
|
|
||||||
compatible.
|
|
||||||
.Sh HISTORY
|
|
||||||
An
|
|
||||||
.Nm
|
|
||||||
utility appeared in
|
|
||||||
.At v2 .
|
|
||||||
|
|
@ -1,81 +0,0 @@
|
||||||
/* $NetBSD: echo.c,v 1.19 2016/09/05 01:00:07 sevan Exp $ */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (c) 1989, 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
|
||||||
#ifndef lint
|
|
||||||
__COPYRIGHT(
|
|
||||||
"@(#) Copyright (c) 1989, 1993\
|
|
||||||
The Regents of the University of California. All rights reserved.");
|
|
||||||
#endif /* not lint */
|
|
||||||
|
|
||||||
#ifndef lint
|
|
||||||
#if 0
|
|
||||||
static char sccsid[] = "@(#)echo.c 8.1 (Berkeley) 5/31/93";
|
|
||||||
#else
|
|
||||||
__RCSID("$NetBSD: echo.c,v 1.19 2016/09/05 01:00:07 sevan Exp $");
|
|
||||||
#endif
|
|
||||||
#endif /* not lint */
|
|
||||||
|
|
||||||
#include <locale.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
/* ARGSUSED */
|
|
||||||
int
|
|
||||||
main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
int nflag;
|
|
||||||
|
|
||||||
setprogname(argv[0]);
|
|
||||||
(void)setlocale(LC_ALL, "");
|
|
||||||
|
|
||||||
/* This utility may NOT do getopt(3) option parsing. */
|
|
||||||
if (*++argv && !strcmp(*argv, "-n")) {
|
|
||||||
++argv;
|
|
||||||
nflag = 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
nflag = 0;
|
|
||||||
|
|
||||||
while (*argv) {
|
|
||||||
(void)printf("%s", *argv);
|
|
||||||
if (*++argv)
|
|
||||||
(void)putchar(' ');
|
|
||||||
}
|
|
||||||
if (nflag == 0)
|
|
||||||
(void)putchar('\n');
|
|
||||||
fflush(stdout);
|
|
||||||
if (ferror(stdout))
|
|
||||||
exit(1);
|
|
||||||
exit(0);
|
|
||||||
/* NOTREACHED */
|
|
||||||
}
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
# $NetBSD: Makefile,v 1.8 1997/07/20 22:37:21 christos Exp $
|
|
||||||
# @(#)Makefile 8.1 (Berkeley) 5/31/93
|
|
||||||
|
|
||||||
PROG= mkdir
|
|
||||||
|
|
||||||
.include <bsd.prog.mk>
|
|
||||||
|
|
@ -1,99 +0,0 @@
|
||||||
.\" $NetBSD: mkdir.1,v 1.19 2016/08/10 18:42:00 sevan Exp $
|
|
||||||
.\"
|
|
||||||
.\" Copyright (c) 1989, 1990, 1993
|
|
||||||
.\" The Regents of the University of California. All rights reserved.
|
|
||||||
.\"
|
|
||||||
.\" This code is derived from software contributed to Berkeley by
|
|
||||||
.\" the Institute of Electrical and Electronics Engineers, Inc.
|
|
||||||
.\"
|
|
||||||
.\" 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.
|
|
||||||
.\"
|
|
||||||
.\" @(#)mkdir.1 8.2 (Berkeley) 1/25/94
|
|
||||||
.\"
|
|
||||||
.Dd August 10, 2016
|
|
||||||
.Dt MKDIR 1
|
|
||||||
.Os
|
|
||||||
.Sh NAME
|
|
||||||
.Nm mkdir
|
|
||||||
.Nd make directories
|
|
||||||
.Sh SYNOPSIS
|
|
||||||
.Nm
|
|
||||||
.Op Fl p
|
|
||||||
.Op Fl m Ar mode
|
|
||||||
.Ar directory_name ...
|
|
||||||
.Sh DESCRIPTION
|
|
||||||
.Nm
|
|
||||||
creates the directories named as operands, in the order specified,
|
|
||||||
using mode
|
|
||||||
.Li rwxrwxrwx (\&0777)
|
|
||||||
as modified by the current
|
|
||||||
.Xr umask 2 .
|
|
||||||
.Pp
|
|
||||||
The options are as follows:
|
|
||||||
.Pp
|
|
||||||
.Bl -tag -width indent
|
|
||||||
.It Fl m
|
|
||||||
Set the file permission bits of the final created directory to
|
|
||||||
the specified mode.
|
|
||||||
The mode argument can be in any of the formats specified to the
|
|
||||||
.Xr chmod 1
|
|
||||||
utility.
|
|
||||||
If a symbolic mode is specified, the operation characters
|
|
||||||
.Dq +
|
|
||||||
and
|
|
||||||
.Dq -
|
|
||||||
are interpreted relative to an initial mode of
|
|
||||||
.Dq a=rwx .
|
|
||||||
.It Fl p
|
|
||||||
Create intermediate directories as required.
|
|
||||||
If this option is not specified, the full path prefix of each
|
|
||||||
operand must already exist.
|
|
||||||
Intermediate directories are created with permission bits of
|
|
||||||
.Li rwxrwxrwx (\&0777)
|
|
||||||
as modified by the current umask, plus write and search
|
|
||||||
permission for the owner.
|
|
||||||
Do not consider it an error if the argument directory already exists.
|
|
||||||
.El
|
|
||||||
.Pp
|
|
||||||
The user must have write permission in the parent directory.
|
|
||||||
.Sh EXIT STATUS
|
|
||||||
.Nm
|
|
||||||
exits 0 if successful, and \*[Gt]0 if an error occurred.
|
|
||||||
.Sh SEE ALSO
|
|
||||||
.Xr chmod 1 ,
|
|
||||||
.Xr rmdir 1 ,
|
|
||||||
.Xr mkdir 2 ,
|
|
||||||
.Xr umask 2
|
|
||||||
.Sh STANDARDS
|
|
||||||
The
|
|
||||||
.Nm
|
|
||||||
utility is expected to be
|
|
||||||
.St -p1003.2
|
|
||||||
compatible.
|
|
||||||
.Sh HISTORY
|
|
||||||
A
|
|
||||||
.Nm
|
|
||||||
utility appeared in
|
|
||||||
.At v1 .
|
|
||||||
|
|
@ -1,223 +0,0 @@
|
||||||
/* $NetBSD: mkdir.c,v 1.38 2011/08/29 14:45:28 joerg Exp $ */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (c) 1983, 1992, 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
|
||||||
#ifndef lint
|
|
||||||
__COPYRIGHT("@(#) Copyright (c) 1983, 1992, 1993\
|
|
||||||
The Regents of the University of California. All rights reserved.");
|
|
||||||
#endif /* not lint */
|
|
||||||
|
|
||||||
#ifndef lint
|
|
||||||
#if 0
|
|
||||||
static char sccsid[] = "@(#)mkdir.c 8.2 (Berkeley) 1/25/94";
|
|
||||||
#else
|
|
||||||
__RCSID("$NetBSD: mkdir.c,v 1.38 2011/08/29 14:45:28 joerg Exp $");
|
|
||||||
#endif
|
|
||||||
#endif /* not lint */
|
|
||||||
|
|
||||||
#include <sys/param.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
|
|
||||||
#include <err.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <locale.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
static int mkpath(char *, mode_t, mode_t);
|
|
||||||
__dead static void usage(void);
|
|
||||||
|
|
||||||
int
|
|
||||||
main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
int ch, exitval, pflag;
|
|
||||||
void *set;
|
|
||||||
mode_t mode, dir_mode;
|
|
||||||
|
|
||||||
setprogname(argv[0]);
|
|
||||||
(void)setlocale(LC_ALL, "");
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The default file mode is a=rwx (0777) with selected permissions
|
|
||||||
* removed in accordance with the file mode creation mask. For
|
|
||||||
* intermediate path name components, the mode is the default modified
|
|
||||||
* by u+wx so that the subdirectories can always be created.
|
|
||||||
*/
|
|
||||||
mode = (S_IRWXU | S_IRWXG | S_IRWXO) & ~umask(0);
|
|
||||||
dir_mode = mode | S_IWUSR | S_IXUSR;
|
|
||||||
|
|
||||||
pflag = 0;
|
|
||||||
while ((ch = getopt(argc, argv, "m:p")) != -1)
|
|
||||||
switch (ch) {
|
|
||||||
case 'p':
|
|
||||||
pflag = 1;
|
|
||||||
break;
|
|
||||||
case 'm':
|
|
||||||
if ((set = setmode(optarg)) == NULL) {
|
|
||||||
err(EXIT_FAILURE, "Cannot set file mode `%s'",
|
|
||||||
optarg);
|
|
||||||
/* NOTREACHED */
|
|
||||||
}
|
|
||||||
mode = getmode(set, S_IRWXU | S_IRWXG | S_IRWXO);
|
|
||||||
free(set);
|
|
||||||
break;
|
|
||||||
case '?':
|
|
||||||
default:
|
|
||||||
usage();
|
|
||||||
/* NOTREACHED */
|
|
||||||
}
|
|
||||||
argc -= optind;
|
|
||||||
argv += optind;
|
|
||||||
|
|
||||||
if (*argv == NULL) {
|
|
||||||
usage();
|
|
||||||
/* NOTREACHED */
|
|
||||||
}
|
|
||||||
|
|
||||||
for (exitval = EXIT_SUCCESS; *argv != NULL; ++argv) {
|
|
||||||
#ifdef notdef
|
|
||||||
char *slash;
|
|
||||||
|
|
||||||
/* Kernel takes care of this */
|
|
||||||
/* Remove trailing slashes, per POSIX. */
|
|
||||||
slash = strrchr(*argv, '\0');
|
|
||||||
while (--slash > *argv && *slash == '/')
|
|
||||||
*slash = '\0';
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (pflag) {
|
|
||||||
if (mkpath(*argv, mode, dir_mode) < 0)
|
|
||||||
exitval = EXIT_FAILURE;
|
|
||||||
} else {
|
|
||||||
if (mkdir(*argv, mode) < 0) {
|
|
||||||
warn("%s", *argv);
|
|
||||||
exitval = EXIT_FAILURE;
|
|
||||||
} else {
|
|
||||||
/*
|
|
||||||
* The mkdir() and umask() calls both honor
|
|
||||||
* only the file permission bits, so if you try
|
|
||||||
* to set a mode including the sticky, setuid,
|
|
||||||
* setgid bits you lose them. So chmod().
|
|
||||||
*/
|
|
||||||
if ((mode & ~(S_IRWXU|S_IRWXG|S_IRWXO)) != 0 &&
|
|
||||||
chmod(*argv, mode) == -1) {
|
|
||||||
warn("%s", *argv);
|
|
||||||
exitval = EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
exit(exitval);
|
|
||||||
/* NOTREACHED */
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* mkpath -- create directories.
|
|
||||||
* path - path
|
|
||||||
* mode - file mode of terminal directory
|
|
||||||
* dir_mode - file mode of intermediate directories
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
mkpath(char *path, mode_t mode, mode_t dir_mode)
|
|
||||||
{
|
|
||||||
struct stat sb;
|
|
||||||
char *slash;
|
|
||||||
int done, rv;
|
|
||||||
|
|
||||||
done = 0;
|
|
||||||
slash = path;
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
slash += strspn(slash, "/");
|
|
||||||
slash += strcspn(slash, "/");
|
|
||||||
|
|
||||||
done = (*slash == '\0');
|
|
||||||
*slash = '\0';
|
|
||||||
|
|
||||||
rv = mkdir(path, done ? mode : dir_mode);
|
|
||||||
if (rv < 0) {
|
|
||||||
/*
|
|
||||||
* Can't create; path exists or no perms.
|
|
||||||
* stat() path to determine what's there now.
|
|
||||||
*/
|
|
||||||
int sverrno;
|
|
||||||
|
|
||||||
sverrno = errno;
|
|
||||||
if (stat(path, &sb) < 0) {
|
|
||||||
/* Not there; use mkdir()s error */
|
|
||||||
errno = sverrno;
|
|
||||||
warn("%s", path);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (!S_ISDIR(sb.st_mode)) {
|
|
||||||
/* Is there, but isn't a directory */
|
|
||||||
errno = ENOTDIR;
|
|
||||||
warn("%s", path);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
} else if (done) {
|
|
||||||
/*
|
|
||||||
* Created ok, and this is the last element
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* The mkdir() and umask() calls both honor only the
|
|
||||||
* file permission bits, so if you try to set a mode
|
|
||||||
* including the sticky, setuid, setgid bits you lose
|
|
||||||
* them. So chmod().
|
|
||||||
*/
|
|
||||||
if ((mode & ~(S_IRWXU|S_IRWXG|S_IRWXO)) != 0 &&
|
|
||||||
chmod(path, mode) == -1) {
|
|
||||||
warn("%s", path);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (done) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
*slash = '/';
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
usage(void)
|
|
||||||
{
|
|
||||||
|
|
||||||
(void)fprintf(stderr, "usage: %s [-p] [-m mode] dirname ...\n",
|
|
||||||
getprogname());
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
/* NOTREACHED */
|
|
||||||
}
|
|
||||||
|
|
@ -1,60 +0,0 @@
|
||||||
# $NetBSD: Makefile,v 1.39 2010/04/23 19:41:02 joerg Exp $
|
|
||||||
# @(#)Makefile 8.1 (Berkeley) 5/31/93
|
|
||||||
|
|
||||||
.include <bsd.own.mk>
|
|
||||||
|
|
||||||
PROG= pax
|
|
||||||
SRCS= ar_io.c ar_subs.c buf_subs.c file_subs.c ftree.c\
|
|
||||||
gen_subs.c getoldopt.c options.c pat_rep.c pax.c sel_subs.c tables.c\
|
|
||||||
tar.c tty_subs.c
|
|
||||||
|
|
||||||
.if defined(SMALLPROG)
|
|
||||||
CPPFLAGS+= -DSMALL -DNO_CPIO
|
|
||||||
.else
|
|
||||||
SRCS+= getid.c spec.c misc.c pack_dev.c cpio.c
|
|
||||||
CPPFLAGS+= -I${NETBSDSRCDIR}/usr.sbin/mtree \
|
|
||||||
-I${NETBSDSRCDIR}/sbin/mknod
|
|
||||||
.PATH: ${NETBSDSRCDIR}/usr.sbin/mtree \
|
|
||||||
${NETBSDSRCDIR}/sbin/mknod
|
|
||||||
|
|
||||||
.if (${HOSTPROG:U} == "")
|
|
||||||
DPADD+= ${LIBUTIL}
|
|
||||||
LDADD+= -lutil
|
|
||||||
.endif
|
|
||||||
.endif
|
|
||||||
|
|
||||||
MAN= pax.1 tar.1 cpio.1
|
|
||||||
|
|
||||||
.if defined(HOSTPROG)
|
|
||||||
CPPFLAGS+= -DHOSTPROG
|
|
||||||
.else # { ! HOSTPROG
|
|
||||||
|
|
||||||
# XXX: Interix does not have it; we need a conditional for it.
|
|
||||||
CPPFLAGS+= -DHAVE_SYS_MTIO_H
|
|
||||||
|
|
||||||
.if ${MKBSDTAR} == "no"
|
|
||||||
LINKS+= ${BINDIR}/pax ${BINDIR}/tar
|
|
||||||
SYMLINKS+=${BINDIR}/tar /usr/bin/tar
|
|
||||||
.if defined(__MINIX)
|
|
||||||
SYMLINKS+=${BINDIR}/tar /usr/bin/bsdtar
|
|
||||||
.endif
|
|
||||||
|
|
||||||
LINKS+= ${BINDIR}/pax ${BINDIR}/cpio
|
|
||||||
SYMLINKS+=${BINDIR}/cpio /usr/bin/cpio
|
|
||||||
.endif
|
|
||||||
.endif # } ! HOSTPROG
|
|
||||||
|
|
||||||
.if !defined(HOSTPROG) && !defined(SMALLPROG)
|
|
||||||
CPPFLAGS+= -DSUPPORT_RMT
|
|
||||||
|
|
||||||
LDADD+= -lrmt
|
|
||||||
DPADD+= ${LIBRMT}
|
|
||||||
.endif
|
|
||||||
|
|
||||||
.if defined(__MINIX)
|
|
||||||
CPPFLAGS+= -DHOSTPROG
|
|
||||||
|
|
||||||
MLINKS+= pax.1 bsdtar.1
|
|
||||||
.endif # defined(__MINIX)
|
|
||||||
|
|
||||||
.include <bsd.prog.mk>
|
|
||||||
1727
bin/pax/ar_io.c
1727
bin/pax/ar_io.c
File diff suppressed because it is too large
Load Diff
1449
bin/pax/ar_subs.c
1449
bin/pax/ar_subs.c
File diff suppressed because it is too large
Load Diff
1022
bin/pax/buf_subs.c
1022
bin/pax/buf_subs.c
File diff suppressed because it is too large
Load Diff
307
bin/pax/cpio.1
307
bin/pax/cpio.1
|
|
@ -1,307 +0,0 @@
|
||||||
.\" $NetBSD: cpio.1,v 1.14 2015/12/19 18:48:33 wiz Exp $
|
|
||||||
.\"
|
|
||||||
.\" Copyright (c) 1997 SigmaSoft, Th. Lockert
|
|
||||||
.\" 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 ``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 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.
|
|
||||||
.\"
|
|
||||||
.\" OpenBSD: cpio.1,v 1.14 2000/11/10 17:52:02 aaron Exp
|
|
||||||
.\"
|
|
||||||
.Dd June 18, 2011
|
|
||||||
.Dt CPIO 1
|
|
||||||
.Os
|
|
||||||
.Sh NAME
|
|
||||||
.Nm cpio
|
|
||||||
.Nd copy file archives in and out
|
|
||||||
.Sh SYNOPSIS
|
|
||||||
.Nm cpio
|
|
||||||
.Fl o
|
|
||||||
.Op Fl AaBcLvZz
|
|
||||||
.Op Fl C Ar bytes
|
|
||||||
.Op Fl F Ar archive
|
|
||||||
.Op Fl H Ar format
|
|
||||||
.Op Fl O Ar archive
|
|
||||||
.Ar "\*[Lt] name-list"
|
|
||||||
.Op Ar "\*[Gt] archive"
|
|
||||||
.Nm cpio
|
|
||||||
.Fl i
|
|
||||||
.Op Fl 6BbcdfmrSstuvZz
|
|
||||||
.Op Fl C Ar bytes
|
|
||||||
.Op Fl E Ar file
|
|
||||||
.Op Fl F Ar archive
|
|
||||||
.Op Fl H Ar format
|
|
||||||
.Op Fl I Ar archive
|
|
||||||
.Op Ar "pattern ..."
|
|
||||||
.Op Ar "\*[Lt] archive"
|
|
||||||
.Nm cpio
|
|
||||||
.Fl p
|
|
||||||
.Op Fl adLlmuv
|
|
||||||
.Ar destination-directory
|
|
||||||
.Ar "\*[Lt] name-list"
|
|
||||||
.Sh DESCRIPTION
|
|
||||||
The
|
|
||||||
.Nm
|
|
||||||
command copies files to and from a
|
|
||||||
.Nm
|
|
||||||
archive.
|
|
||||||
If the archive is of the form:
|
|
||||||
.Ar [[user@]host:]file
|
|
||||||
then the archive will be processed using
|
|
||||||
.Xr rmt 8 .
|
|
||||||
.Pp
|
|
||||||
The options are as follows:
|
|
||||||
.Bl -tag -width Ds
|
|
||||||
.It Fl o , Fl Fl create
|
|
||||||
Create an archive.
|
|
||||||
Reads the list of files to store in the
|
|
||||||
archive from standard input, and writes the archive on standard
|
|
||||||
output.
|
|
||||||
.Bl -tag -width Ds
|
|
||||||
.It Fl a , Fl Fl reset-access-time
|
|
||||||
Reset the access times on files that have been copied to the
|
|
||||||
archive.
|
|
||||||
.It Fl A , Fl Fl append
|
|
||||||
Append to the specified archive.
|
|
||||||
.It Fl B
|
|
||||||
Set block size of output to 5120 bytes.
|
|
||||||
.It Fl c
|
|
||||||
Use ASCII format for
|
|
||||||
.Nm
|
|
||||||
header for portability.
|
|
||||||
.It Fl C Ar bytes
|
|
||||||
Set the block size of output to
|
|
||||||
.Ar bytes .
|
|
||||||
.It Fl F Ar archive
|
|
||||||
.It Fl O Ar archive
|
|
||||||
Use the specified file name as the archive to write to.
|
|
||||||
.It Fl H Ar format
|
|
||||||
Write the archive in the specified format.
|
|
||||||
Recognized formats are:
|
|
||||||
.Pp
|
|
||||||
.Bl -tag -width sv4cpio -compact
|
|
||||||
.It Ar bcpio
|
|
||||||
Old binary
|
|
||||||
.Nm
|
|
||||||
format.
|
|
||||||
.It Ar cpio
|
|
||||||
Old octal character
|
|
||||||
.Nm
|
|
||||||
format.
|
|
||||||
.It Ar sv4cpio
|
|
||||||
SVR4 hex
|
|
||||||
.Nm
|
|
||||||
format.
|
|
||||||
.It Ar tar
|
|
||||||
Old tar format.
|
|
||||||
.It Ar ustar
|
|
||||||
POSIX ustar format.
|
|
||||||
.El
|
|
||||||
.It Fl L
|
|
||||||
Follow symbolic links.
|
|
||||||
.It Fl v
|
|
||||||
Be verbose about operations.
|
|
||||||
List filenames as they are written to the archive.
|
|
||||||
.It Fl Fl xz
|
|
||||||
Compress/decompress archive using
|
|
||||||
.Xr xz 1
|
|
||||||
format.
|
|
||||||
.It Fl Z
|
|
||||||
Compress archive using
|
|
||||||
.Xr compress 1
|
|
||||||
format.
|
|
||||||
.It Fl z
|
|
||||||
Compress/decompress archive using
|
|
||||||
.Xr gzip 1
|
|
||||||
format.
|
|
||||||
.El
|
|
||||||
.It Fl i , Fl Fl extract
|
|
||||||
Restore files from an archive.
|
|
||||||
Reads the archive file from
|
|
||||||
standard input and extracts files matching the
|
|
||||||
.Ar patterns
|
|
||||||
that were specified on the command line.
|
|
||||||
.Bl -tag -width Ds
|
|
||||||
.It Fl b
|
|
||||||
Do byte and word swapping after reading in data from the
|
|
||||||
archive, for restoring archives created on systems with
|
|
||||||
a different byte order.
|
|
||||||
.It Fl B
|
|
||||||
Set the block size of the archive being read to 5120 bytes.
|
|
||||||
.It Fl c
|
|
||||||
Expect the archive headers to be in ASCII format.
|
|
||||||
.It Fl C Ar bytes
|
|
||||||
Read archive written with a block size of
|
|
||||||
.Ar bytes .
|
|
||||||
.It Fl d , Fl Fl make-directories
|
|
||||||
Create any intermediate directories as needed during
|
|
||||||
restore.
|
|
||||||
.It Fl E Ar file , Fl Fl pattern-file Ar file
|
|
||||||
Read list of file name patterns to extract or list from
|
|
||||||
.Ar file .
|
|
||||||
.It Fl f , Fl Fl nonmatching
|
|
||||||
Restore all files except those matching the
|
|
||||||
.Ar patterns
|
|
||||||
given on the command line.
|
|
||||||
.It Fl F Ar archive , Fl Fl file Ar archive
|
|
||||||
.It Fl I Ar archive
|
|
||||||
Use the specified file as the input for the archive.
|
|
||||||
.It Fl H Ar format , Fl Fl format Ar format
|
|
||||||
Read an archive of the specified format.
|
|
||||||
Recognized formats are:
|
|
||||||
.Pp
|
|
||||||
.Bl -tag -width sv4cpio -compact
|
|
||||||
.It Ar bcpio
|
|
||||||
Old binary
|
|
||||||
.Nm
|
|
||||||
format.
|
|
||||||
.It Ar cpio
|
|
||||||
Old octal character
|
|
||||||
.Nm
|
|
||||||
format.
|
|
||||||
.It Ar sv4cpio
|
|
||||||
SVR4 hex
|
|
||||||
.Nm
|
|
||||||
format.
|
|
||||||
.It Ar tar
|
|
||||||
Old tar format.
|
|
||||||
.It Ar ustar
|
|
||||||
POSIX ustar format.
|
|
||||||
.El
|
|
||||||
.It Fl m
|
|
||||||
Restore modification times on files.
|
|
||||||
.It Fl r , Fl Fl rename
|
|
||||||
Rename restored files interactively.
|
|
||||||
.It Fl s
|
|
||||||
Swap bytes after reading data from the archive.
|
|
||||||
.It Fl S , Fl Fl swap-halfwords
|
|
||||||
Swap words after reading data from the archive.
|
|
||||||
.It Fl t , Fl Fl list
|
|
||||||
Only list the contents of the archive, no files or
|
|
||||||
directories will be created.
|
|
||||||
.It Fl u , Fl Fl unconditional
|
|
||||||
Overwrite files even when the file in the archive is
|
|
||||||
older than the one that will be overwritten.
|
|
||||||
.It Fl v , Fl Fl verbose
|
|
||||||
Be verbose about operations.
|
|
||||||
List filenames as they are copied in from the archive.
|
|
||||||
.It Fl z
|
|
||||||
Uncompress archive using
|
|
||||||
.Xr gzip 1
|
|
||||||
format.
|
|
||||||
.It Fl Z
|
|
||||||
Uncompress archive using
|
|
||||||
.Xr compress 1
|
|
||||||
format.
|
|
||||||
.It Fl 6
|
|
||||||
Process old-style
|
|
||||||
.Nm
|
|
||||||
format archives.
|
|
||||||
.El
|
|
||||||
.It Fl p , Fl Fl pass-through
|
|
||||||
Copy files from one location to another in a single pass.
|
|
||||||
The list of files to copy are read from standard input and
|
|
||||||
written out to a directory relative to the specified
|
|
||||||
.Ar directory
|
|
||||||
argument.
|
|
||||||
.Bl -tag -width Ds
|
|
||||||
.It Fl a
|
|
||||||
Reset the access times on files that have been copied.
|
|
||||||
.It Fl d
|
|
||||||
Create any intermediate directories as needed to write
|
|
||||||
the files at the new location.
|
|
||||||
.It Fl l , Fl Fl link
|
|
||||||
When possible, link files rather than creating an
|
|
||||||
extra copy.
|
|
||||||
.It Fl L , Fl Fl dereference
|
|
||||||
Follow symbolic links.
|
|
||||||
.It Fl m , Fl Fl preserve-modification-time
|
|
||||||
Restore modification times on files.
|
|
||||||
.It Fl u , Fl Fl unconditional
|
|
||||||
Overwrite files even when the original file being copied is
|
|
||||||
older than the one that will be overwritten.
|
|
||||||
.It Fl v , Fl Fl verbose
|
|
||||||
Be verbose about operations.
|
|
||||||
List filenames as they are copied.
|
|
||||||
.It Fl Fl force-local
|
|
||||||
Do not interpret filenames that contain a
|
|
||||||
.Sq \&:
|
|
||||||
as remote files.
|
|
||||||
.It Fl Fl insecure
|
|
||||||
Normally
|
|
||||||
.Nm
|
|
||||||
ignores filenames that contain
|
|
||||||
.Dq ..
|
|
||||||
as a path component.
|
|
||||||
With this option, files that contain
|
|
||||||
.Dq ..
|
|
||||||
can be processed.
|
|
||||||
.El
|
|
||||||
.El
|
|
||||||
.Sh EXIT STATUS
|
|
||||||
.Nm
|
|
||||||
will exit with one of the following values:
|
|
||||||
.Bl -tag -width 2n
|
|
||||||
.It 0
|
|
||||||
All files were processed successfully.
|
|
||||||
.It 1
|
|
||||||
An error occurred.
|
|
||||||
.El
|
|
||||||
.Pp
|
|
||||||
Whenever
|
|
||||||
.Nm
|
|
||||||
cannot create a file or a link when extracting an archive or cannot
|
|
||||||
find a file while writing an archive, or cannot preserve the user
|
|
||||||
ID, group ID, file mode, or access and modification times when the
|
|
||||||
.Fl p
|
|
||||||
option is specified, a diagnostic message is written to standard
|
|
||||||
error and a non-zero exit value will be returned, but processing
|
|
||||||
will continue.
|
|
||||||
In the case where
|
|
||||||
.Nm
|
|
||||||
cannot create a link to a file,
|
|
||||||
.Nm
|
|
||||||
will not create a second copy of the file.
|
|
||||||
.Pp
|
|
||||||
If the extraction of a file from an archive is prematurely terminated
|
|
||||||
by a signal or error,
|
|
||||||
.Nm
|
|
||||||
may have only partially extracted the file the user wanted.
|
|
||||||
Additionally, the file modes of extracted files and directories may
|
|
||||||
have incorrect file bits, and the modification and access times may
|
|
||||||
be wrong.
|
|
||||||
.Pp
|
|
||||||
If the creation of an archive is prematurely terminated by a signal
|
|
||||||
or error,
|
|
||||||
.Nm
|
|
||||||
may have only partially created the archive which may violate the
|
|
||||||
specific archive format specification.
|
|
||||||
.Sh SEE ALSO
|
|
||||||
.Xr pax 1 ,
|
|
||||||
.Xr tar 1
|
|
||||||
.Sh AUTHORS
|
|
||||||
.An Keith Muller
|
|
||||||
at the University of California, San Diego.
|
|
||||||
.Sh BUGS
|
|
||||||
The
|
|
||||||
.Fl s
|
|
||||||
and
|
|
||||||
.Fl S
|
|
||||||
options are currently not implemented.
|
|
||||||
1134
bin/pax/cpio.c
1134
bin/pax/cpio.c
File diff suppressed because it is too large
Load Diff
149
bin/pax/cpio.h
149
bin/pax/cpio.h
|
|
@ -1,149 +0,0 @@
|
||||||
/* $NetBSD: cpio.h,v 1.6 2003/10/13 07:41:22 agc Exp $ */
|
|
||||||
|
|
||||||
/*-
|
|
||||||
* Copyright (c) 1992 Keith Muller.
|
|
||||||
* Copyright (c) 1992, 1993
|
|
||||||
* The Regents of the University of California. All rights reserved.
|
|
||||||
*
|
|
||||||
* This code is derived from software contributed to Berkeley by
|
|
||||||
* Keith Muller of the University of California, San Diego.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* @(#)cpio.h 8.1 (Berkeley) 5/31/93
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Defines common to all versions of cpio
|
|
||||||
*/
|
|
||||||
#define TRAILER "TRAILER!!!" /* name in last archive record */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Header encoding of the different file types
|
|
||||||
*/
|
|
||||||
#define C_ISDIR 040000 /* Directory */
|
|
||||||
#define C_ISFIFO 010000 /* FIFO */
|
|
||||||
#define C_ISREG 0100000 /* Regular file */
|
|
||||||
#define C_ISBLK 060000 /* Block special file */
|
|
||||||
#define C_ISCHR 020000 /* Character special file */
|
|
||||||
#define C_ISCTG 0110000 /* Reserved for contiguous files */
|
|
||||||
#define C_ISLNK 0120000 /* Reserved for symbolic links */
|
|
||||||
#define C_ISOCK 0140000 /* Reserved for sockets */
|
|
||||||
#define C_IFMT 0170000 /* type of file */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Data Interchange Format - Extended cpio header format - POSIX 1003.1-1990
|
|
||||||
*/
|
|
||||||
typedef struct {
|
|
||||||
char c_magic[6]; /* magic cookie */
|
|
||||||
char c_dev[6]; /* device number */
|
|
||||||
char c_ino[6]; /* inode number */
|
|
||||||
char c_mode[6]; /* file type/access */
|
|
||||||
char c_uid[6]; /* owners uid */
|
|
||||||
char c_gid[6]; /* owners gid */
|
|
||||||
char c_nlink[6]; /* # of links at archive creation */
|
|
||||||
char c_rdev[6]; /* block/char major/minor # */
|
|
||||||
char c_mtime[11]; /* modification time */
|
|
||||||
char c_namesize[6]; /* length of pathname */
|
|
||||||
char c_filesize[11]; /* length of file in bytes */
|
|
||||||
} HD_CPIO;
|
|
||||||
|
|
||||||
#define MAGIC 070707 /* transportable archive id */
|
|
||||||
|
|
||||||
#ifdef _PAX_
|
|
||||||
#define AMAGIC "070707" /* ascii equivalent string of MAGIC */
|
|
||||||
#define CPIO_MASK 0x3ffff /* bits valid in the dev/ino fields */
|
|
||||||
/* used for dev/inode remaps */
|
|
||||||
#endif /* _PAX_ */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Binary cpio header structure
|
|
||||||
*
|
|
||||||
* CAUTION! CAUTION! CAUTION!
|
|
||||||
* Each field really represents a 16 bit short (NOT ASCII). Described as
|
|
||||||
* an array of chars in an attempt to improve portability!!
|
|
||||||
*/
|
|
||||||
typedef struct {
|
|
||||||
u_char h_magic[2];
|
|
||||||
u_char h_dev[2];
|
|
||||||
u_char h_ino[2];
|
|
||||||
u_char h_mode[2];
|
|
||||||
u_char h_uid[2];
|
|
||||||
u_char h_gid[2];
|
|
||||||
u_char h_nlink[2];
|
|
||||||
u_char h_rdev[2];
|
|
||||||
u_char h_mtime_1[2];
|
|
||||||
u_char h_mtime_2[2];
|
|
||||||
u_char h_namesize[2];
|
|
||||||
u_char h_filesize_1[2];
|
|
||||||
u_char h_filesize_2[2];
|
|
||||||
} HD_BCPIO;
|
|
||||||
|
|
||||||
#ifdef _PAX_
|
|
||||||
/*
|
|
||||||
* extraction and creation macros for binary cpio
|
|
||||||
*/
|
|
||||||
#define SHRT_EXT(ch) ((((unsigned)(ch)[0])<<8) | (((unsigned)(ch)[1])&0xff))
|
|
||||||
#define RSHRT_EXT(ch) ((((unsigned)(ch)[1])<<8) | (((unsigned)(ch)[0])&0xff))
|
|
||||||
#define CHR_WR_0(val) ((char)(((val) >> 24) & 0xff))
|
|
||||||
#define CHR_WR_1(val) ((char)(((val) >> 16) & 0xff))
|
|
||||||
#define CHR_WR_2(val) ((char)(((val) >> 8) & 0xff))
|
|
||||||
#define CHR_WR_3(val) ((char)((val) & 0xff))
|
|
||||||
|
|
||||||
/*
|
|
||||||
* binary cpio masks and pads
|
|
||||||
*/
|
|
||||||
#define BCPIO_PAD(x) ((2 - ((x) & 1)) & 1) /* pad to next 2 byte word */
|
|
||||||
#define BCPIO_MASK 0xffff /* mask for dev/ino fields */
|
|
||||||
#endif /* _PAX_ */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* System VR4 cpio header structure (with/without file data crc)
|
|
||||||
*/
|
|
||||||
typedef struct {
|
|
||||||
char c_magic[6]; /* magic cookie */
|
|
||||||
char c_ino[8]; /* inode number */
|
|
||||||
char c_mode[8]; /* file type/access */
|
|
||||||
char c_uid[8]; /* owners uid */
|
|
||||||
char c_gid[8]; /* owners gid */
|
|
||||||
char c_nlink[8]; /* # of links at archive creation */
|
|
||||||
char c_mtime[8]; /* modification time */
|
|
||||||
char c_filesize[8]; /* length of file in bytes */
|
|
||||||
char c_maj[8]; /* block/char major # */
|
|
||||||
char c_min[8]; /* block/char minor # */
|
|
||||||
char c_rmaj[8]; /* special file major # */
|
|
||||||
char c_rmin[8]; /* special file minor # */
|
|
||||||
char c_namesize[8]; /* length of pathname */
|
|
||||||
char c_chksum[8]; /* 0 OR CRC of bytes of FILE data */
|
|
||||||
} HD_VCPIO;
|
|
||||||
|
|
||||||
#define VMAGIC 070701 /* sVr4 new portable archive id */
|
|
||||||
#define VCMAGIC 070702 /* sVr4 new portable archive id CRC */
|
|
||||||
#ifdef _PAX_
|
|
||||||
#define AVMAGIC "070701" /* ascii string of above */
|
|
||||||
#define AVCMAGIC "070702" /* ascii string of above */
|
|
||||||
#define VCPIO_PAD(x) ((4 - ((x) & 3)) & 3) /* pad to next 4 byte word */
|
|
||||||
#define VCPIO_MASK 0xffffffff /* mask for dev/ino fields */
|
|
||||||
#endif /* _PAX_ */
|
|
||||||
|
|
@ -1,122 +0,0 @@
|
||||||
/* $NetBSD: dumptar.c,v 1.2 2008/04/28 20:22:51 martin Exp $ */
|
|
||||||
|
|
||||||
/*-
|
|
||||||
* Copyright (c) 2004 The NetBSD Foundation, Inc.
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* This code is derived from software contributed to The NetBSD Foundation
|
|
||||||
* by Christos Zoulas.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <err.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/mman.h>
|
|
||||||
|
|
||||||
#include "tar.h"
|
|
||||||
|
|
||||||
#define ussum(a) 1
|
|
||||||
|
|
||||||
static char *
|
|
||||||
buf(const char *p, size_t s)
|
|
||||||
{
|
|
||||||
static char buf[1024];
|
|
||||||
(void)snprintf(buf, sizeof(buf), "%s", p);
|
|
||||||
buf[s] = '\0';
|
|
||||||
return buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
intarg(const char *p, size_t s)
|
|
||||||
{
|
|
||||||
char *ep, *b = buf(p, s);
|
|
||||||
int r = (int)strtol(p, &ep, 8);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
usdump(void *p)
|
|
||||||
{
|
|
||||||
HD_USTAR *t = p;
|
|
||||||
int size = intarg(t->size, sizeof(t->size));
|
|
||||||
size = ((size + 511) / 512) * 512 + 512;
|
|
||||||
|
|
||||||
(void)fprintf(stdout, "*****\n");
|
|
||||||
#define PR(a) \
|
|
||||||
(void)fprintf(stdout, #a "=%s\n", buf(t->a, sizeof(t->a)));
|
|
||||||
#define IPR(a) \
|
|
||||||
(void)fprintf(stdout, #a "=%d\n", intarg(t->a, sizeof(t->a)));
|
|
||||||
#define OPR(a) \
|
|
||||||
(void)fprintf(stdout, #a "=%o\n", intarg(t->a, sizeof(t->a)));
|
|
||||||
PR(name);
|
|
||||||
OPR(mode);
|
|
||||||
IPR(uid);
|
|
||||||
IPR(gid);
|
|
||||||
IPR(size);
|
|
||||||
OPR(mtime);
|
|
||||||
OPR(chksum);
|
|
||||||
(void)fprintf(stdout, "typeflag=%c\n", t->typeflag);
|
|
||||||
PR(linkname);
|
|
||||||
PR(magic);
|
|
||||||
PR(version);
|
|
||||||
PR(uname);
|
|
||||||
PR(gname);
|
|
||||||
OPR(devmajor);
|
|
||||||
OPR(devminor);
|
|
||||||
PR(prefix);
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
int fd;
|
|
||||||
struct stat st;
|
|
||||||
char *p, *ep;
|
|
||||||
|
|
||||||
if (argc != 2) {
|
|
||||||
(void)fprintf(stderr, "Usage: %s <filename>\n", getprogname());
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((fd = open(argv[1], O_RDONLY)) == -1)
|
|
||||||
err(1, "Cannot open `%s'", argv[1]);
|
|
||||||
|
|
||||||
if (fstat(fd, &st) == -1)
|
|
||||||
err(1, "Cannot fstat `%s'", argv[1]);
|
|
||||||
|
|
||||||
if ((p = mmap(NULL, (size_t)st.st_size, PROT_READ,
|
|
||||||
MAP_FILE|MAP_PRIVATE, fd, (off_t)0)) == MAP_FAILED)
|
|
||||||
err(1, "Cannot mmap `%s'", argv[1]);
|
|
||||||
(void)close(fd);
|
|
||||||
|
|
||||||
ep = (char *)p + (size_t)st.st_size;
|
|
||||||
|
|
||||||
for (; p < ep + sizeof(HD_USTAR);) {
|
|
||||||
if (ussum(p))
|
|
||||||
p += usdump(p);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
326
bin/pax/extern.h
326
bin/pax/extern.h
|
|
@ -1,326 +0,0 @@
|
||||||
/* $NetBSD: extern.h,v 1.59 2012/08/09 08:09:21 christos Exp $ */
|
|
||||||
|
|
||||||
/*-
|
|
||||||
* Copyright (c) 1992 Keith Muller.
|
|
||||||
* Copyright (c) 1992, 1993
|
|
||||||
* The Regents of the University of California. All rights reserved.
|
|
||||||
*
|
|
||||||
* This code is derived from software contributed to Berkeley by
|
|
||||||
* Keith Muller of the University of California, San Diego.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* @(#)extern.h 8.2 (Berkeley) 4/18/94
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* External references from each source file
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
|
||||||
#include <err.h>
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ar_io.c
|
|
||||||
*/
|
|
||||||
extern const char *arcname;
|
|
||||||
extern int curdirfd;
|
|
||||||
extern const char *gzip_program;
|
|
||||||
extern time_t starttime;
|
|
||||||
extern int force_one_volume;
|
|
||||||
extern char *chdname;
|
|
||||||
extern int forcelocal;
|
|
||||||
extern int secure;
|
|
||||||
|
|
||||||
int ar_open(const char *);
|
|
||||||
void ar_close(void);
|
|
||||||
void ar_drain(void);
|
|
||||||
int ar_set_wr(void);
|
|
||||||
int ar_app_ok(void);
|
|
||||||
#ifdef SYS_NO_RESTART
|
|
||||||
int read_with_restart(int, void *, int);
|
|
||||||
int write_with_restart(int, void *, int);
|
|
||||||
#else
|
|
||||||
#define read_with_restart read
|
|
||||||
#define write_with_restart write
|
|
||||||
#endif
|
|
||||||
int xread(int, void *, int);
|
|
||||||
int xwrite(int, void *, int);
|
|
||||||
int ar_read(char *, int);
|
|
||||||
int ar_write(char *, int);
|
|
||||||
int ar_rdsync(void);
|
|
||||||
int ar_fow(off_t, off_t *);
|
|
||||||
int ar_rev(off_t );
|
|
||||||
int ar_next(void);
|
|
||||||
void ar_summary(int);
|
|
||||||
int ar_dochdir(const char *);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ar_subs.c
|
|
||||||
*/
|
|
||||||
extern u_long flcnt;
|
|
||||||
extern ARCHD archd;
|
|
||||||
int updatepath(void);
|
|
||||||
int dochdir(const char *);
|
|
||||||
int fdochdir(int);
|
|
||||||
int domkdir(const char *, mode_t);
|
|
||||||
int list(void);
|
|
||||||
int extract(void);
|
|
||||||
int append(void);
|
|
||||||
int archive(void);
|
|
||||||
int copy(void);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* buf_subs.c
|
|
||||||
*/
|
|
||||||
extern int blksz;
|
|
||||||
extern int wrblksz;
|
|
||||||
extern int maxflt;
|
|
||||||
extern int rdblksz;
|
|
||||||
extern off_t wrlimit;
|
|
||||||
extern off_t rdcnt;
|
|
||||||
extern off_t wrcnt;
|
|
||||||
int wr_start(void);
|
|
||||||
int rd_start(void);
|
|
||||||
void cp_start(void);
|
|
||||||
int appnd_start(off_t);
|
|
||||||
int rd_sync(void);
|
|
||||||
void pback(char *, int);
|
|
||||||
int rd_skip(off_t);
|
|
||||||
void wr_fin(void);
|
|
||||||
int wr_rdbuf(char *, int);
|
|
||||||
int rd_wrbuf(char *, int);
|
|
||||||
int wr_skip(off_t);
|
|
||||||
int wr_rdfile(ARCHD *, int, off_t *);
|
|
||||||
int rd_wrfile(ARCHD *, int, off_t *);
|
|
||||||
void cp_file(ARCHD *, int, int);
|
|
||||||
int buf_fill(void);
|
|
||||||
int buf_flush(int);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* cpio.c
|
|
||||||
*/
|
|
||||||
extern int cpio_swp_head;
|
|
||||||
int cpio_strd(void);
|
|
||||||
int cpio_subtrail(ARCHD *);
|
|
||||||
int cpio_endwr(void);
|
|
||||||
int cpio_id(char *, int);
|
|
||||||
int cpio_rd(ARCHD *, char *);
|
|
||||||
off_t cpio_endrd(void);
|
|
||||||
int cpio_stwr(void);
|
|
||||||
int cpio_wr(ARCHD *);
|
|
||||||
int vcpio_id(char *, int);
|
|
||||||
int crc_id(char *, int);
|
|
||||||
int crc_strd(void);
|
|
||||||
int vcpio_rd(ARCHD *, char *);
|
|
||||||
off_t vcpio_endrd(void);
|
|
||||||
int crc_stwr(void);
|
|
||||||
int vcpio_wr(ARCHD *);
|
|
||||||
int bcpio_id(char *, int);
|
|
||||||
int bcpio_rd(ARCHD *, char *);
|
|
||||||
off_t bcpio_endrd(void);
|
|
||||||
int bcpio_wr(ARCHD *);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* file_subs.c
|
|
||||||
*/
|
|
||||||
extern char *gnu_name_string, *gnu_link_string;
|
|
||||||
extern size_t gnu_name_length, gnu_link_length;
|
|
||||||
extern char *xtmp_name;
|
|
||||||
int file_creat(ARCHD *, int);
|
|
||||||
void file_close(ARCHD *, int);
|
|
||||||
int lnk_creat(ARCHD *, int *);
|
|
||||||
int cross_lnk(ARCHD *);
|
|
||||||
int chk_same(ARCHD *);
|
|
||||||
int node_creat(ARCHD *);
|
|
||||||
int unlnk_exist(char *, int);
|
|
||||||
int chk_path(char *, uid_t, gid_t);
|
|
||||||
void set_ftime(char *fnm, time_t mtime, time_t atime, int frc, int slk);
|
|
||||||
int set_ids(char *, uid_t, gid_t);
|
|
||||||
void set_pmode(char *, mode_t);
|
|
||||||
void set_chflags(char *fnm, u_int32_t flags);
|
|
||||||
int file_write(int, char *, int, int *, int *, int, char *);
|
|
||||||
void file_flush(int, char *, int);
|
|
||||||
void rdfile_close(ARCHD *, int *);
|
|
||||||
int set_crc(ARCHD *, int);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ftree.c
|
|
||||||
*/
|
|
||||||
int ftree_start(void);
|
|
||||||
int ftree_add(char *, int);
|
|
||||||
void ftree_sel(ARCHD *);
|
|
||||||
void ftree_chk(void);
|
|
||||||
int next_file(ARCHD *);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* gen_subs.c
|
|
||||||
*/
|
|
||||||
void ls_list(ARCHD *, time_t, FILE *);
|
|
||||||
void ls_tty(ARCHD *);
|
|
||||||
void safe_print(const char *, FILE *);
|
|
||||||
uint32_t asc_u32(char *, int, int);
|
|
||||||
int u32_asc(uintmax_t, char *, int, int);
|
|
||||||
uintmax_t asc_umax(char *, int, int);
|
|
||||||
int umax_asc(uintmax_t, char *, int, int);
|
|
||||||
int check_Aflag(void);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* getoldopt.c
|
|
||||||
*/
|
|
||||||
struct option;
|
|
||||||
int getoldopt(int, char **, const char *, struct option *, int *);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* options.c
|
|
||||||
*/
|
|
||||||
extern FSUB fsub[];
|
|
||||||
extern int ford[];
|
|
||||||
extern int sep;
|
|
||||||
extern int havechd;
|
|
||||||
void options(int, char **);
|
|
||||||
OPLIST * opt_next(void);
|
|
||||||
int bad_opt(void);
|
|
||||||
int mkpath(char *);
|
|
||||||
char *chdname;
|
|
||||||
#if !HAVE_NBTOOL_CONFIG_H
|
|
||||||
int do_chroot;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* pat_rep.c
|
|
||||||
*/
|
|
||||||
int rep_add(char *);
|
|
||||||
int pat_add(char *, char *, int);
|
|
||||||
void pat_chk(void);
|
|
||||||
int pat_sel(ARCHD *);
|
|
||||||
int pat_match(ARCHD *);
|
|
||||||
int mod_name(ARCHD *, int);
|
|
||||||
int set_dest(ARCHD *, char *, int);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* pax.c
|
|
||||||
*/
|
|
||||||
extern int act;
|
|
||||||
extern FSUB *frmt;
|
|
||||||
extern int Aflag;
|
|
||||||
extern int cflag;
|
|
||||||
extern int cwdfd;
|
|
||||||
extern int dflag;
|
|
||||||
extern int iflag;
|
|
||||||
extern int kflag;
|
|
||||||
extern int lflag;
|
|
||||||
extern int nflag;
|
|
||||||
extern int tflag;
|
|
||||||
extern int uflag;
|
|
||||||
extern int vflag;
|
|
||||||
extern int Dflag;
|
|
||||||
extern int Hflag;
|
|
||||||
extern int Lflag;
|
|
||||||
extern int Mflag;
|
|
||||||
extern int Vflag;
|
|
||||||
extern int Xflag;
|
|
||||||
extern int Yflag;
|
|
||||||
extern int Zflag;
|
|
||||||
extern int vfpart;
|
|
||||||
extern int patime;
|
|
||||||
extern int pmtime;
|
|
||||||
extern int nodirs;
|
|
||||||
extern int pfflags;
|
|
||||||
extern int pmode;
|
|
||||||
extern int pids;
|
|
||||||
extern int rmleadslash;
|
|
||||||
extern int exit_val;
|
|
||||||
extern int docrc;
|
|
||||||
extern int to_stdout;
|
|
||||||
extern char *dirptr;
|
|
||||||
extern char *ltmfrmt;
|
|
||||||
extern const char *argv0;
|
|
||||||
extern FILE *listf;
|
|
||||||
extern char *tempfile;
|
|
||||||
extern char *tempbase;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* sel_subs.c
|
|
||||||
*/
|
|
||||||
int sel_chk(ARCHD *);
|
|
||||||
int grp_add(char *);
|
|
||||||
int usr_add(char *);
|
|
||||||
int trng_add(char *);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* tables.c
|
|
||||||
*/
|
|
||||||
int lnk_start(void);
|
|
||||||
int chk_lnk(ARCHD *);
|
|
||||||
void purg_lnk(ARCHD *);
|
|
||||||
void lnk_end(void);
|
|
||||||
int ftime_start(void);
|
|
||||||
int chk_ftime(ARCHD *);
|
|
||||||
int name_start(void);
|
|
||||||
int add_name(char *, int, char *);
|
|
||||||
void sub_name(char *, int *, size_t);
|
|
||||||
int dev_start(void);
|
|
||||||
int add_dev(ARCHD *);
|
|
||||||
int map_dev(ARCHD *, u_long, u_long);
|
|
||||||
int atdir_start(void);
|
|
||||||
void atdir_end(void);
|
|
||||||
void add_atdir(char *, dev_t, ino_t, time_t, time_t);
|
|
||||||
int get_atdir(dev_t, ino_t, time_t *, time_t *);
|
|
||||||
int dir_start(void);
|
|
||||||
void add_dir(char *, int, struct stat *, int);
|
|
||||||
void proc_dir(void);
|
|
||||||
u_int st_hash(char *, int, int);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* tar.c
|
|
||||||
*/
|
|
||||||
extern int is_gnutar;
|
|
||||||
int tar_endwr(void);
|
|
||||||
off_t tar_endrd(void);
|
|
||||||
int tar_trail(char *, int, int *);
|
|
||||||
int tar_id(char *, int);
|
|
||||||
int tar_opt(void);
|
|
||||||
int tar_rd(ARCHD *, char *);
|
|
||||||
int tar_wr(ARCHD *);
|
|
||||||
int ustar_strd(void);
|
|
||||||
int ustar_stwr(void);
|
|
||||||
int ustar_id(char *, int);
|
|
||||||
int ustar_rd(ARCHD *, char *);
|
|
||||||
int ustar_wr(ARCHD *);
|
|
||||||
int tar_gnutar_X_compat(const char *);
|
|
||||||
int tar_gnutar_minus_minus_exclude(const char *);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* tty_subs.c
|
|
||||||
*/
|
|
||||||
int tty_init(void);
|
|
||||||
void tty_prnt(const char *, ...)
|
|
||||||
__attribute__((format (printf, 1, 2)));
|
|
||||||
int tty_read(char *, int);
|
|
||||||
void tty_warn(int, const char *, ...)
|
|
||||||
__attribute__((format (printf, 2, 3)));
|
|
||||||
void syswarn(int, int, const char *, ...)
|
|
||||||
__attribute__((format (printf, 3, 4)));
|
|
||||||
1174
bin/pax/file_subs.c
1174
bin/pax/file_subs.c
File diff suppressed because it is too large
Load Diff
741
bin/pax/ftree.c
741
bin/pax/ftree.c
|
|
@ -1,741 +0,0 @@
|
||||||
/* $NetBSD: ftree.c,v 1.42 2012/09/27 00:44:59 christos Exp $ */
|
|
||||||
|
|
||||||
/*-
|
|
||||||
* Copyright (c) 1992 Keith Muller.
|
|
||||||
* Copyright (c) 1992, 1993
|
|
||||||
* The Regents of the University of California. All rights reserved.
|
|
||||||
*
|
|
||||||
* This code is derived from software contributed to Berkeley by
|
|
||||||
* Keith Muller of the University of California, San Diego.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*-
|
|
||||||
* Copyright (c) 2001 The NetBSD Foundation, Inc.
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* This code is derived from software contributed to The NetBSD Foundation
|
|
||||||
* by Luke Mewburn of Wasabi Systems.
|
|
||||||
*
|
|
||||||
* 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)
|
|
||||||
#if 0
|
|
||||||
static char sccsid[] = "@(#)ftree.c 8.2 (Berkeley) 4/18/94";
|
|
||||||
#else
|
|
||||||
__RCSID("$NetBSD: ftree.c,v 1.42 2012/09/27 00:44:59 christos Exp $");
|
|
||||||
#endif
|
|
||||||
#endif /* not lint */
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/time.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/param.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <fts.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include "pax.h"
|
|
||||||
#include "ftree.h"
|
|
||||||
#include "extern.h"
|
|
||||||
#include "options.h"
|
|
||||||
#ifndef SMALL
|
|
||||||
#include "mtree.h"
|
|
||||||
#endif /* SMALL */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* routines to interface with the fts library function.
|
|
||||||
*
|
|
||||||
* file args supplied to pax are stored on a single linked list (of type FTREE)
|
|
||||||
* and given to fts to be processed one at a time. pax "selects" files from
|
|
||||||
* the expansion of each arg into the corresponding file tree (if the arg is a
|
|
||||||
* directory, otherwise the node itself is just passed to pax). The selection
|
|
||||||
* is modified by the -n and -u flags. The user is informed when a specific
|
|
||||||
* file arg does not generate any selected files. -n keeps expanding the file
|
|
||||||
* tree arg until one of its files is selected, then skips to the next file
|
|
||||||
* arg. when the user does not supply the file trees as command line args to
|
|
||||||
* pax, they are read from stdin
|
|
||||||
*/
|
|
||||||
|
|
||||||
static FTS *ftsp = NULL; /* current FTS handle */
|
|
||||||
static int ftsopts; /* options to be used on fts_open */
|
|
||||||
static char *farray[2]; /* array for passing each arg to fts */
|
|
||||||
static FTREE *fthead = NULL; /* head of linked list of file args */
|
|
||||||
static FTREE *fttail = NULL; /* tail of linked list of file args */
|
|
||||||
static FTREE *ftcur = NULL; /* current file arg being processed */
|
|
||||||
static FTSENT *ftent = NULL; /* current file tree entry */
|
|
||||||
static int ftree_skip; /* when set skip to next file arg */
|
|
||||||
#ifndef SMALL
|
|
||||||
static NODE *ftnode = NULL; /* mtree(8) specfile; used by -M */
|
|
||||||
#endif /* SMALL */
|
|
||||||
|
|
||||||
static int ftree_arg(void);
|
|
||||||
|
|
||||||
#define FTS_ERRNO(x) (x)->fts_errno
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ftree_start()
|
|
||||||
* initialize the options passed to fts_open() during this run of pax
|
|
||||||
* options are based on the selection of pax options by the user
|
|
||||||
* fts_start() also calls fts_arg() to open the first valid file arg. We
|
|
||||||
* also attempt to reset directory access times when -t (tflag) is set.
|
|
||||||
* Return:
|
|
||||||
* 0 if there is at least one valid file arg to process, -1 otherwise
|
|
||||||
*/
|
|
||||||
|
|
||||||
int
|
|
||||||
ftree_start(void)
|
|
||||||
{
|
|
||||||
|
|
||||||
#ifndef SMALL
|
|
||||||
/*
|
|
||||||
* if -M is given, the list of filenames on stdin is actually
|
|
||||||
* an mtree(8) specfile, so parse the specfile into a NODE *
|
|
||||||
* tree at ftnode, for use by next_file()
|
|
||||||
*/
|
|
||||||
if (Mflag) {
|
|
||||||
if (fthead != NULL) {
|
|
||||||
tty_warn(1,
|
|
||||||
"The -M flag is only supported when reading file list from stdin");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
ftnode = spec(stdin);
|
|
||||||
if (ftnode != NULL &&
|
|
||||||
(ftnode->type != F_DIR || strcmp(ftnode->name, ".") != 0)) {
|
|
||||||
tty_warn(1,
|
|
||||||
"First node of specfile is not `.' directory");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif /* SMALL */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* set up the operation mode of fts, open the first file arg. We must
|
|
||||||
* use FTS_NOCHDIR, as the user may have to open multiple archives and
|
|
||||||
* if fts did a chdir off into the boondocks, we may create an archive
|
|
||||||
* volume in an place where the user did not expect to.
|
|
||||||
*/
|
|
||||||
ftsopts = FTS_NOCHDIR;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* optional user flags that effect file traversal
|
|
||||||
* -H command line symlink follow only (half follow)
|
|
||||||
* -L follow sylinks (logical)
|
|
||||||
* -P do not follow sylinks (physical). This is the default.
|
|
||||||
* -X do not cross over mount points
|
|
||||||
* -t preserve access times on files read.
|
|
||||||
* -n select only the first member of a file tree when a match is found
|
|
||||||
* -d do not extract subtrees rooted at a directory arg.
|
|
||||||
*/
|
|
||||||
if (Lflag)
|
|
||||||
ftsopts |= FTS_LOGICAL;
|
|
||||||
else
|
|
||||||
ftsopts |= FTS_PHYSICAL;
|
|
||||||
if (Hflag)
|
|
||||||
ftsopts |= FTS_COMFOLLOW;
|
|
||||||
if (Xflag)
|
|
||||||
ftsopts |= FTS_XDEV;
|
|
||||||
|
|
||||||
if ((fthead == NULL) && ((farray[0] = malloc(PAXPATHLEN+2)) == NULL)) {
|
|
||||||
tty_warn(1, "Unable to allocate memory for file name buffer");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ftree_arg() < 0)
|
|
||||||
return -1;
|
|
||||||
if (tflag && (atdir_start() < 0))
|
|
||||||
return -1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ftree_add()
|
|
||||||
* add the arg to the linked list of files to process. Each will be
|
|
||||||
* processed by fts one at a time
|
|
||||||
* Return:
|
|
||||||
* 0 if added to the linked list, -1 if failed
|
|
||||||
*/
|
|
||||||
|
|
||||||
int
|
|
||||||
ftree_add(char *str, int isdir)
|
|
||||||
{
|
|
||||||
FTREE *ft;
|
|
||||||
int len;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* simple check for bad args
|
|
||||||
*/
|
|
||||||
if ((str == NULL) || (*str == '\0')) {
|
|
||||||
tty_warn(0, "Invalid file name argument");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* allocate FTREE node and add to the end of the linked list (args are
|
|
||||||
* processed in the same order they were passed to pax). Get rid of any
|
|
||||||
* trailing / the user may pass us. (watch out for / by itself).
|
|
||||||
*/
|
|
||||||
if ((ft = (FTREE *)malloc(sizeof(FTREE))) == NULL) {
|
|
||||||
tty_warn(0, "Unable to allocate memory for filename");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (((len = strlen(str) - 1) > 0) && (str[len] == '/'))
|
|
||||||
str[len] = '\0';
|
|
||||||
ft->fname = str;
|
|
||||||
ft->refcnt = -isdir;
|
|
||||||
ft->fow = NULL;
|
|
||||||
if (fthead == NULL) {
|
|
||||||
fttail = fthead = ft;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
fttail->fow = ft;
|
|
||||||
fttail = ft;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ftree_sel()
|
|
||||||
* this entry has been selected by pax. bump up reference count and handle
|
|
||||||
* -n and -d processing.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void
|
|
||||||
ftree_sel(ARCHD *arcn)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* set reference bit for this pattern. This linked list is only used
|
|
||||||
* when file trees are supplied pax as args. The list is not used when
|
|
||||||
* the trees are read from stdin.
|
|
||||||
*/
|
|
||||||
if (ftcur != NULL)
|
|
||||||
ftcur->refcnt = 1;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* if -n we are done with this arg, force a skip to the next arg when
|
|
||||||
* pax asks for the next file in next_file().
|
|
||||||
* if -M we don't use fts(3), so the rest of this function is moot.
|
|
||||||
* if -d we tell fts only to match the directory (if the arg is a dir)
|
|
||||||
* and not the entire file tree rooted at that point.
|
|
||||||
*/
|
|
||||||
if (nflag)
|
|
||||||
ftree_skip = 1;
|
|
||||||
|
|
||||||
if (Mflag || !dflag || (arcn->type != PAX_DIR))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (ftent != NULL)
|
|
||||||
(void)fts_set(ftsp, ftent, FTS_SKIP);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ftree_chk()
|
|
||||||
* called at end on pax execution. Prints all those file args that did not
|
|
||||||
* have a selected member (reference count still 0)
|
|
||||||
*/
|
|
||||||
|
|
||||||
void
|
|
||||||
ftree_chk(void)
|
|
||||||
{
|
|
||||||
FTREE *ft;
|
|
||||||
int wban = 0;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* make sure all dir access times were reset.
|
|
||||||
*/
|
|
||||||
if (tflag)
|
|
||||||
atdir_end();
|
|
||||||
|
|
||||||
/*
|
|
||||||
* walk down list and check reference count. Print out those members
|
|
||||||
* that never had a match
|
|
||||||
*/
|
|
||||||
for (ft = fthead; ft != NULL; ft = ft->fow) {
|
|
||||||
if (ft->refcnt != 0)
|
|
||||||
continue;
|
|
||||||
if (wban == 0) {
|
|
||||||
tty_warn(1,
|
|
||||||
"WARNING! These file names were not selected:");
|
|
||||||
++wban;
|
|
||||||
}
|
|
||||||
(void)fprintf(stderr, "%s\n", ft->fname);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ftree_arg()
|
|
||||||
* Get the next file arg for fts to process. Can be from either the linked
|
|
||||||
* list or read from stdin when the user did not them as args to pax. Each
|
|
||||||
* arg is processed until the first successful fts_open().
|
|
||||||
* Return:
|
|
||||||
* 0 when the next arg is ready to go, -1 if out of file args (or EOF on
|
|
||||||
* stdin).
|
|
||||||
*/
|
|
||||||
|
|
||||||
static int
|
|
||||||
ftree_arg(void)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* close off the current file tree
|
|
||||||
*/
|
|
||||||
if (ftsp != NULL) {
|
|
||||||
(void)fts_close(ftsp);
|
|
||||||
ftsp = NULL;
|
|
||||||
ftent = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* keep looping until we get a valid file tree to process. Stop when we
|
|
||||||
* reach the end of the list (or get an eof on stdin)
|
|
||||||
*/
|
|
||||||
for(;;) {
|
|
||||||
if (fthead == NULL) {
|
|
||||||
int i, c = EOF;
|
|
||||||
/*
|
|
||||||
* the user didn't supply any args, get the file trees
|
|
||||||
* to process from stdin;
|
|
||||||
*/
|
|
||||||
for (i = 0; i < PAXPATHLEN + 2;) {
|
|
||||||
c = getchar();
|
|
||||||
if (c == EOF)
|
|
||||||
break;
|
|
||||||
else if (c == sep) {
|
|
||||||
if (i != 0)
|
|
||||||
break;
|
|
||||||
} else
|
|
||||||
farray[0][i++] = c;
|
|
||||||
}
|
|
||||||
if (i == 0)
|
|
||||||
return -1;
|
|
||||||
farray[0][i] = '\0';
|
|
||||||
} else {
|
|
||||||
/*
|
|
||||||
* the user supplied the file args as arguments to pax
|
|
||||||
*/
|
|
||||||
if (ftcur == NULL)
|
|
||||||
ftcur = fthead;
|
|
||||||
else if ((ftcur = ftcur->fow) == NULL)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (ftcur->refcnt < 0) {
|
|
||||||
/*
|
|
||||||
* chdir entry.
|
|
||||||
* Change directory and retry loop.
|
|
||||||
*/
|
|
||||||
if (ar_dochdir(ftcur->fname))
|
|
||||||
return (-1);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
farray[0] = ftcur->fname;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* watch it, fts wants the file arg stored in a array of char
|
|
||||||
* ptrs, with the last one a null. we use a two element array
|
|
||||||
* and set farray[0] to point at the buffer with the file name
|
|
||||||
* in it. We cannot pass all the file args to fts at one shot
|
|
||||||
* as we need to keep a handle on which file arg generates what
|
|
||||||
* files (the -n and -d flags need this). If the open is
|
|
||||||
* successful, return a 0.
|
|
||||||
*/
|
|
||||||
if ((ftsp = fts_open(farray, ftsopts, NULL)) != NULL)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* next_file()
|
|
||||||
* supplies the next file to process in the supplied archd structure.
|
|
||||||
* Return:
|
|
||||||
* 0 when contents of arcn have been set with the next file, -1 when done.
|
|
||||||
*/
|
|
||||||
|
|
||||||
int
|
|
||||||
next_file(ARCHD *arcn)
|
|
||||||
{
|
|
||||||
#ifndef SMALL
|
|
||||||
static char curdir[PAXPATHLEN+2], curpath[PAXPATHLEN+2];
|
|
||||||
static int curdirlen;
|
|
||||||
|
|
||||||
struct stat statbuf;
|
|
||||||
FTSENT Mftent;
|
|
||||||
#endif /* SMALL */
|
|
||||||
int cnt;
|
|
||||||
time_t atime, mtime;
|
|
||||||
char *curlink;
|
|
||||||
#define MFTENT_DUMMY_DEV UINT_MAX
|
|
||||||
|
|
||||||
curlink = NULL;
|
|
||||||
#ifndef SMALL
|
|
||||||
/*
|
|
||||||
* if parsing an mtree(8) specfile, build up `dummy' ftsent
|
|
||||||
* from specfile info, and jump below to complete setup of arcn.
|
|
||||||
*/
|
|
||||||
if (Mflag) {
|
|
||||||
int skipoptional;
|
|
||||||
|
|
||||||
next_ftnode:
|
|
||||||
skipoptional = 0;
|
|
||||||
if (ftnode == NULL) /* tree is empty */
|
|
||||||
return (-1);
|
|
||||||
|
|
||||||
/* get current name */
|
|
||||||
if (snprintf(curpath, sizeof(curpath), "%s%s%s",
|
|
||||||
curdir, curdirlen ? "/" : "", ftnode->name)
|
|
||||||
>= (int)sizeof(curpath)) {
|
|
||||||
tty_warn(1, "line %lu: %s: %s", (u_long)ftnode->lineno,
|
|
||||||
curdir, strerror(ENAMETOOLONG));
|
|
||||||
return (-1);
|
|
||||||
}
|
|
||||||
ftnode->flags |= F_VISIT; /* mark node visited */
|
|
||||||
|
|
||||||
/* construct dummy FTSENT */
|
|
||||||
Mftent.fts_path = curpath;
|
|
||||||
Mftent.fts_statp = &statbuf;
|
|
||||||
Mftent.fts_pointer = ftnode;
|
|
||||||
ftent = &Mftent;
|
|
||||||
/* look for existing file */
|
|
||||||
if (lstat(Mftent.fts_path, &statbuf) == -1) {
|
|
||||||
if (ftnode->flags & F_OPT)
|
|
||||||
skipoptional = 1;
|
|
||||||
|
|
||||||
/* missing: fake up stat info */
|
|
||||||
memset(&statbuf, 0, sizeof(statbuf));
|
|
||||||
statbuf.st_dev = MFTENT_DUMMY_DEV;
|
|
||||||
statbuf.st_ino = ftnode->lineno;
|
|
||||||
statbuf.st_size = 0;
|
|
||||||
#define NODETEST(t, m) \
|
|
||||||
if (!(t)) { \
|
|
||||||
tty_warn(1, "line %lu: %s: %s not specified", \
|
|
||||||
(u_long)ftnode->lineno, \
|
|
||||||
ftent->fts_path, m); \
|
|
||||||
return -1; \
|
|
||||||
}
|
|
||||||
statbuf.st_mode = nodetoino(ftnode->type);
|
|
||||||
NODETEST(ftnode->flags & F_TYPE, "type");
|
|
||||||
NODETEST(ftnode->flags & F_MODE, "mode");
|
|
||||||
if (!(ftnode->flags & F_TIME))
|
|
||||||
statbuf.st_mtime = starttime;
|
|
||||||
NODETEST(ftnode->flags & (F_GID | F_GNAME), "group");
|
|
||||||
NODETEST(ftnode->flags & (F_UID | F_UNAME), "user");
|
|
||||||
if (ftnode->type == F_BLOCK || ftnode->type == F_CHAR)
|
|
||||||
NODETEST(ftnode->flags & F_DEV,
|
|
||||||
"device number");
|
|
||||||
if (ftnode->type == F_LINK)
|
|
||||||
NODETEST(ftnode->flags & F_SLINK, "symlink");
|
|
||||||
/* don't require F_FLAGS or F_SIZE */
|
|
||||||
#undef NODETEST
|
|
||||||
} else {
|
|
||||||
if (ftnode->flags & F_TYPE && nodetoino(ftnode->type)
|
|
||||||
!= (statbuf.st_mode & S_IFMT)) {
|
|
||||||
tty_warn(1,
|
|
||||||
"line %lu: %s: type mismatch: specfile %s, tree %s",
|
|
||||||
(u_long)ftnode->lineno, ftent->fts_path,
|
|
||||||
inotype(nodetoino(ftnode->type)),
|
|
||||||
inotype(statbuf.st_mode));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (ftnode->type == F_DIR && (ftnode->flags & F_OPT))
|
|
||||||
skipoptional = 1;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* override settings with those from specfile
|
|
||||||
*/
|
|
||||||
if (ftnode->flags & F_MODE) {
|
|
||||||
statbuf.st_mode &= ~ALLPERMS;
|
|
||||||
statbuf.st_mode |= (ftnode->st_mode & ALLPERMS);
|
|
||||||
}
|
|
||||||
if (ftnode->flags & (F_GID | F_GNAME))
|
|
||||||
statbuf.st_gid = ftnode->st_gid;
|
|
||||||
if (ftnode->flags & (F_UID | F_UNAME))
|
|
||||||
statbuf.st_uid = ftnode->st_uid;
|
|
||||||
#if HAVE_STRUCT_STAT_ST_FLAGS
|
|
||||||
if (ftnode->flags & F_FLAGS)
|
|
||||||
statbuf.st_flags = ftnode->st_flags;
|
|
||||||
#endif
|
|
||||||
if (ftnode->flags & F_TIME)
|
|
||||||
#if BSD4_4 && !HAVE_NBTOOL_CONFIG_H
|
|
||||||
statbuf.st_mtimespec = ftnode->st_mtimespec;
|
|
||||||
#else
|
|
||||||
statbuf.st_mtime = ftnode->st_mtimespec.tv_sec;
|
|
||||||
#endif
|
|
||||||
if (ftnode->flags & F_DEV)
|
|
||||||
statbuf.st_rdev = ftnode->st_rdev;
|
|
||||||
if (ftnode->flags & F_SLINK)
|
|
||||||
curlink = ftnode->slink;
|
|
||||||
/* ignore F_SIZE */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* find next node
|
|
||||||
*/
|
|
||||||
if (ftnode->type == F_DIR && ftnode->child != NULL) {
|
|
||||||
/* directory with unseen child */
|
|
||||||
ftnode = ftnode->child;
|
|
||||||
curdirlen = strlcpy(curdir, curpath, sizeof(curdir));
|
|
||||||
} else do {
|
|
||||||
if (ftnode->next != NULL) {
|
|
||||||
/* next node at current level */
|
|
||||||
ftnode = ftnode->next;
|
|
||||||
} else { /* move back to parent */
|
|
||||||
/* reset time only on first cd.. */
|
|
||||||
if (Mftent.fts_pointer == ftnode && tflag &&
|
|
||||||
(get_atdir(MFTENT_DUMMY_DEV, ftnode->lineno,
|
|
||||||
&mtime, &atime) == 0)) {
|
|
||||||
set_ftime(ftent->fts_path,
|
|
||||||
mtime, atime, 1, 0);
|
|
||||||
}
|
|
||||||
ftnode = ftnode->parent;
|
|
||||||
if (ftnode->parent == ftnode)
|
|
||||||
ftnode = NULL;
|
|
||||||
else {
|
|
||||||
curdirlen -= strlen(ftnode->name) + 1;
|
|
||||||
curdir[curdirlen] = '\0';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} while (ftnode != NULL && ftnode->flags & F_VISIT);
|
|
||||||
if (skipoptional) /* skip optional entries */
|
|
||||||
goto next_ftnode;
|
|
||||||
goto got_ftent;
|
|
||||||
}
|
|
||||||
#endif /* SMALL */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ftree_sel() might have set the ftree_skip flag if the user has the
|
|
||||||
* -n option and a file was selected from this file arg tree. (-n says
|
|
||||||
* only one member is matched for each pattern) ftree_skip being 1
|
|
||||||
* forces us to go to the next arg now.
|
|
||||||
*/
|
|
||||||
if (ftree_skip) {
|
|
||||||
/*
|
|
||||||
* clear and go to next arg
|
|
||||||
*/
|
|
||||||
ftree_skip = 0;
|
|
||||||
if (ftree_arg() < 0)
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ftsp == NULL)
|
|
||||||
return -1;
|
|
||||||
/*
|
|
||||||
* loop until we get a valid file to process
|
|
||||||
*/
|
|
||||||
for(;;) {
|
|
||||||
if ((ftent = fts_read(ftsp)) == NULL) {
|
|
||||||
/*
|
|
||||||
* out of files in this tree, go to next arg, if none
|
|
||||||
* we are done
|
|
||||||
*/
|
|
||||||
if (ftree_arg() < 0)
|
|
||||||
return -1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* handle each type of fts_read() flag
|
|
||||||
*/
|
|
||||||
switch(ftent->fts_info) {
|
|
||||||
case FTS_D:
|
|
||||||
case FTS_DEFAULT:
|
|
||||||
case FTS_F:
|
|
||||||
case FTS_SL:
|
|
||||||
case FTS_SLNONE:
|
|
||||||
/*
|
|
||||||
* these are all ok
|
|
||||||
*/
|
|
||||||
break;
|
|
||||||
case FTS_DP:
|
|
||||||
/*
|
|
||||||
* already saw this directory. If the user wants file
|
|
||||||
* access times reset, we use this to restore the
|
|
||||||
* access time for this directory since this is the
|
|
||||||
* last time we will see it in this file subtree
|
|
||||||
* remember to force the time (this is -t on a read
|
|
||||||
* directory, not a created directory).
|
|
||||||
*/
|
|
||||||
if (!tflag || (get_atdir(
|
|
||||||
ftent->fts_statp->st_dev, ftent->fts_statp->st_ino,
|
|
||||||
&mtime, &atime) < 0))
|
|
||||||
continue;
|
|
||||||
set_ftime(ftent->fts_path, mtime, atime, 1, 0);
|
|
||||||
continue;
|
|
||||||
case FTS_DC:
|
|
||||||
/*
|
|
||||||
* fts claims a file system cycle
|
|
||||||
*/
|
|
||||||
tty_warn(1,"File system cycle found at %s",
|
|
||||||
ftent->fts_path);
|
|
||||||
continue;
|
|
||||||
case FTS_DNR:
|
|
||||||
syswarn(1, FTS_ERRNO(ftent),
|
|
||||||
"Unable to read directory %s", ftent->fts_path);
|
|
||||||
continue;
|
|
||||||
case FTS_ERR:
|
|
||||||
syswarn(1, FTS_ERRNO(ftent),
|
|
||||||
"File system traversal error");
|
|
||||||
continue;
|
|
||||||
case FTS_NS:
|
|
||||||
case FTS_NSOK:
|
|
||||||
syswarn(1, FTS_ERRNO(ftent),
|
|
||||||
"Unable to access %s", ftent->fts_path);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef SMALL
|
|
||||||
got_ftent:
|
|
||||||
#endif /* SMALL */
|
|
||||||
/*
|
|
||||||
* ok got a file tree node to process. copy info into arcn
|
|
||||||
* structure (initialize as required)
|
|
||||||
*/
|
|
||||||
arcn->skip = 0;
|
|
||||||
arcn->pad = 0;
|
|
||||||
arcn->ln_nlen = 0;
|
|
||||||
arcn->ln_name[0] = '\0';
|
|
||||||
arcn->sb = *(ftent->fts_statp);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* file type based set up and copy into the arcn struct
|
|
||||||
* SIDE NOTE:
|
|
||||||
* we try to reset the access time on all files and directories
|
|
||||||
* we may read when the -t flag is specified. files are reset
|
|
||||||
* when we close them after copying. we reset the directories
|
|
||||||
* when we are done with their file tree (we also clean up at
|
|
||||||
* end in case we cut short a file tree traversal). However
|
|
||||||
* there is no way to reset access times on symlinks.
|
|
||||||
*/
|
|
||||||
switch(S_IFMT & arcn->sb.st_mode) {
|
|
||||||
case S_IFDIR:
|
|
||||||
arcn->type = PAX_DIR;
|
|
||||||
if (!tflag)
|
|
||||||
break;
|
|
||||||
add_atdir(ftent->fts_path, arcn->sb.st_dev,
|
|
||||||
arcn->sb.st_ino, arcn->sb.st_mtime,
|
|
||||||
arcn->sb.st_atime);
|
|
||||||
break;
|
|
||||||
case S_IFCHR:
|
|
||||||
arcn->type = PAX_CHR;
|
|
||||||
break;
|
|
||||||
case S_IFBLK:
|
|
||||||
arcn->type = PAX_BLK;
|
|
||||||
break;
|
|
||||||
case S_IFREG:
|
|
||||||
/*
|
|
||||||
* only regular files with have data to store on the
|
|
||||||
* archive. all others will store a zero length skip.
|
|
||||||
* the skip field is used by pax for actual data it has
|
|
||||||
* to read (or skip over).
|
|
||||||
*/
|
|
||||||
arcn->type = PAX_REG;
|
|
||||||
arcn->skip = arcn->sb.st_size;
|
|
||||||
break;
|
|
||||||
case S_IFLNK:
|
|
||||||
arcn->type = PAX_SLK;
|
|
||||||
if (curlink != NULL) {
|
|
||||||
cnt = strlcpy(arcn->ln_name, curlink,
|
|
||||||
sizeof(arcn->ln_name));
|
|
||||||
/*
|
|
||||||
* have to read the symlink path from the file
|
|
||||||
*/
|
|
||||||
} else if ((cnt =
|
|
||||||
readlink(ftent->fts_path, arcn->ln_name,
|
|
||||||
sizeof(arcn->ln_name) - 1)) < 0) {
|
|
||||||
syswarn(1, errno, "Unable to read symlink %s",
|
|
||||||
ftent->fts_path);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* set link name length, watch out readlink does not
|
|
||||||
* always null terminate the link path
|
|
||||||
*/
|
|
||||||
arcn->ln_name[cnt] = '\0';
|
|
||||||
arcn->ln_nlen = cnt;
|
|
||||||
break;
|
|
||||||
#ifdef S_IFSOCK
|
|
||||||
case S_IFSOCK:
|
|
||||||
/*
|
|
||||||
* under BSD storing a socket is senseless but we will
|
|
||||||
* let the format specific write function make the
|
|
||||||
* decision of what to do with it.
|
|
||||||
*/
|
|
||||||
arcn->type = PAX_SCK;
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
case S_IFIFO:
|
|
||||||
arcn->type = PAX_FIF;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* copy file name, set file name length
|
|
||||||
*/
|
|
||||||
arcn->nlen = strlcpy(arcn->name, ftent->fts_path, sizeof(arcn->name));
|
|
||||||
arcn->org_name = arcn->fts_name;
|
|
||||||
strlcpy(arcn->fts_name, ftent->fts_path, sizeof arcn->fts_name);
|
|
||||||
if (strcmp(NM_CPIO, argv0) == 0) {
|
|
||||||
/*
|
|
||||||
* cpio does *not* descend directories listed in the
|
|
||||||
* arguments, unlike pax/tar, so needs special handling
|
|
||||||
* here. failure to do so results in massive amounts
|
|
||||||
* of duplicated files in the output. We kill fts after
|
|
||||||
* the first name is extracted, what a waste.
|
|
||||||
*/
|
|
||||||
ftcur->refcnt = 1;
|
|
||||||
(void)ftree_arg();
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
@ -1,48 +0,0 @@
|
||||||
/* $NetBSD: ftree.h,v 1.5 2003/10/13 07:41:22 agc Exp $ */
|
|
||||||
|
|
||||||
/*-
|
|
||||||
* Copyright (c) 1992 Keith Muller.
|
|
||||||
* Copyright (c) 1992, 1993
|
|
||||||
* The Regents of the University of California. All rights reserved.
|
|
||||||
*
|
|
||||||
* This code is derived from software contributed to Berkeley by
|
|
||||||
* Keith Muller of the University of California, San Diego.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* @(#)ftree.h 8.1 (Berkeley) 5/31/93
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Data structure used by the ftree.c routines to store the file args to be
|
|
||||||
* handed to fts(). It keeps a reference count of which args generated a
|
|
||||||
* "selected" member
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef struct ftree {
|
|
||||||
char *fname; /* file tree name */
|
|
||||||
int refcnt; /* has tree had a selected file? */
|
|
||||||
struct ftree *fow; /* pointer to next entry on list */
|
|
||||||
} FTREE;
|
|
||||||
|
|
@ -1,415 +0,0 @@
|
||||||
/* $NetBSD: gen_subs.c,v 1.36 2012/08/09 08:09:21 christos Exp $ */
|
|
||||||
|
|
||||||
/*-
|
|
||||||
* Copyright (c) 1992 Keith Muller.
|
|
||||||
* Copyright (c) 1992, 1993
|
|
||||||
* The Regents of the University of California. All rights reserved.
|
|
||||||
*
|
|
||||||
* This code is derived from software contributed to Berkeley by
|
|
||||||
* Keith Muller of the University of California, San Diego.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if HAVE_NBTOOL_CONFIG_H
|
|
||||||
#include "nbtool_config.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
|
||||||
#if !defined(lint)
|
|
||||||
#if 0
|
|
||||||
static char sccsid[] = "@(#)gen_subs.c 8.1 (Berkeley) 5/31/93";
|
|
||||||
#else
|
|
||||||
__RCSID("$NetBSD: gen_subs.c,v 1.36 2012/08/09 08:09:21 christos Exp $");
|
|
||||||
#endif
|
|
||||||
#endif /* not lint */
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/time.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/param.h>
|
|
||||||
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <grp.h>
|
|
||||||
#include <pwd.h>
|
|
||||||
#include <vis.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <time.h>
|
|
||||||
#include <tzfile.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include "pax.h"
|
|
||||||
#include "extern.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
* a collection of general purpose subroutines used by pax
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* constants used by ls_list() when printing out archive members
|
|
||||||
*/
|
|
||||||
#define MODELEN 20
|
|
||||||
#define DATELEN 64
|
|
||||||
#define SIXMONTHS ((DAYSPERNYEAR / 2) * SECSPERDAY)
|
|
||||||
#define CURFRMT "%b %e %H:%M"
|
|
||||||
#define OLDFRMT "%b %e %Y"
|
|
||||||
#ifndef UT_NAMESIZE
|
|
||||||
#define UT_NAMESIZE 8
|
|
||||||
#endif
|
|
||||||
#define UT_GRPSIZE 6
|
|
||||||
|
|
||||||
/*
|
|
||||||
* convert time to string
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
formattime(char *buf, size_t buflen, time_t when)
|
|
||||||
{
|
|
||||||
int error;
|
|
||||||
struct tm tm;
|
|
||||||
(void)localtime_r(&when, &tm);
|
|
||||||
|
|
||||||
if (when + SIXMONTHS <= time(NULL))
|
|
||||||
error = strftime(buf, buflen, OLDFRMT, &tm);
|
|
||||||
else
|
|
||||||
error = strftime(buf, buflen, CURFRMT, &tm);
|
|
||||||
|
|
||||||
if (error == 0)
|
|
||||||
buf[0] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ls_list()
|
|
||||||
* list the members of an archive in ls format
|
|
||||||
*/
|
|
||||||
|
|
||||||
void
|
|
||||||
ls_list(ARCHD *arcn, time_t now, FILE *fp)
|
|
||||||
{
|
|
||||||
struct stat *sbp;
|
|
||||||
char f_mode[MODELEN];
|
|
||||||
char f_date[DATELEN];
|
|
||||||
const char *user, *group;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* if not verbose, just print the file name
|
|
||||||
*/
|
|
||||||
if (!vflag) {
|
|
||||||
(void)fprintf(fp, "%s\n", arcn->name);
|
|
||||||
(void)fflush(fp);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* user wants long mode
|
|
||||||
*/
|
|
||||||
sbp = &(arcn->sb);
|
|
||||||
strmode(sbp->st_mode, f_mode);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* time format based on age compared to the time pax was started.
|
|
||||||
*/
|
|
||||||
formattime(f_date, sizeof(f_date), arcn->sb.st_mtime);
|
|
||||||
/*
|
|
||||||
* print file mode, link count, uid, gid and time
|
|
||||||
*/
|
|
||||||
user = user_from_uid(sbp->st_uid, 0);
|
|
||||||
group = group_from_gid(sbp->st_gid, 0);
|
|
||||||
(void)fprintf(fp, "%s%2lu %-*s %-*s ", f_mode,
|
|
||||||
(unsigned long)sbp->st_nlink,
|
|
||||||
UT_NAMESIZE, user ? user : "", UT_GRPSIZE, group ? group : "");
|
|
||||||
|
|
||||||
/*
|
|
||||||
* print device id's for devices, or sizes for other nodes
|
|
||||||
*/
|
|
||||||
if ((arcn->type == PAX_CHR) || (arcn->type == PAX_BLK))
|
|
||||||
(void)fprintf(fp, "%4lu,%4lu ", (long) MAJOR(sbp->st_rdev),
|
|
||||||
(long) MINOR(sbp->st_rdev));
|
|
||||||
else {
|
|
||||||
(void)fprintf(fp, OFFT_FP("9") " ", (OFFT_T)sbp->st_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* print name and link info for hard and soft links
|
|
||||||
*/
|
|
||||||
(void)fprintf(fp, "%s %s", f_date, arcn->name);
|
|
||||||
if ((arcn->type == PAX_HLK) || (arcn->type == PAX_HRG))
|
|
||||||
(void)fprintf(fp, " == %s\n", arcn->ln_name);
|
|
||||||
else if (arcn->type == PAX_SLK)
|
|
||||||
(void)fprintf(fp, " -> %s\n", arcn->ln_name);
|
|
||||||
else
|
|
||||||
(void)fputc('\n', fp);
|
|
||||||
(void)fflush(fp);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* tty_ls()
|
|
||||||
* print a short summary of file to tty.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void
|
|
||||||
ls_tty(ARCHD *arcn)
|
|
||||||
{
|
|
||||||
char f_date[DATELEN];
|
|
||||||
char f_mode[MODELEN];
|
|
||||||
|
|
||||||
formattime(f_date, sizeof(f_date), arcn->sb.st_mtime);
|
|
||||||
strmode(arcn->sb.st_mode, f_mode);
|
|
||||||
tty_prnt("%s%s %s\n", f_mode, f_date, arcn->name);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
safe_print(const char *str, FILE *fp)
|
|
||||||
{
|
|
||||||
char visbuf[5];
|
|
||||||
const char *cp;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* if printing to a tty, use vis(3) to print special characters.
|
|
||||||
*/
|
|
||||||
if (isatty(fileno(fp))) {
|
|
||||||
for (cp = str; *cp; cp++) {
|
|
||||||
(void)vis(visbuf, cp[0], VIS_CSTYLE, cp[1]);
|
|
||||||
(void)fputs(visbuf, fp);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
(void)fputs(str, fp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* asc_u32()
|
|
||||||
* convert hex/octal character string into a uint32_t. We do not have to
|
|
||||||
* check for overflow! (the headers in all supported formats are not large
|
|
||||||
* enough to create an overflow).
|
|
||||||
* NOTE: strings passed to us are NOT TERMINATED.
|
|
||||||
* Return:
|
|
||||||
* uint32_t value
|
|
||||||
*/
|
|
||||||
|
|
||||||
uint32_t
|
|
||||||
asc_u32(char *str, int len, int base)
|
|
||||||
{
|
|
||||||
char *stop;
|
|
||||||
uint32_t tval = 0;
|
|
||||||
|
|
||||||
stop = str + len;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* skip over leading blanks and zeros
|
|
||||||
*/
|
|
||||||
while ((str < stop) && ((*str == ' ') || (*str == '0')))
|
|
||||||
++str;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* for each valid digit, shift running value (tval) over to next digit
|
|
||||||
* and add next digit
|
|
||||||
*/
|
|
||||||
if (base == HEX) {
|
|
||||||
while (str < stop) {
|
|
||||||
if ((*str >= '0') && (*str <= '9'))
|
|
||||||
tval = (tval << 4) + (*str++ - '0');
|
|
||||||
else if ((*str >= 'A') && (*str <= 'F'))
|
|
||||||
tval = (tval << 4) + 10 + (*str++ - 'A');
|
|
||||||
else if ((*str >= 'a') && (*str <= 'f'))
|
|
||||||
tval = (tval << 4) + 10 + (*str++ - 'a');
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
while ((str < stop) && (*str >= '0') && (*str <= '7'))
|
|
||||||
tval = (tval << 3) + (*str++ - '0');
|
|
||||||
}
|
|
||||||
return tval;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* u32_asc()
|
|
||||||
* convert an uintmax_t into an hex/oct ascii string. pads with LEADING
|
|
||||||
* ascii 0's to fill string completely
|
|
||||||
* NOTE: the string created is NOT TERMINATED.
|
|
||||||
*/
|
|
||||||
|
|
||||||
int
|
|
||||||
u32_asc(uintmax_t val, char *str, int len, int base)
|
|
||||||
{
|
|
||||||
char *pt;
|
|
||||||
uint32_t digit;
|
|
||||||
uintmax_t p;
|
|
||||||
|
|
||||||
p = val & TOP_HALF;
|
|
||||||
if (p && p != TOP_HALF)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
val &= BOTTOM_HALF;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* WARNING str is not '\0' terminated by this routine
|
|
||||||
*/
|
|
||||||
pt = str + len - 1;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* do a tailwise conversion (start at right most end of string to place
|
|
||||||
* least significant digit). Keep shifting until conversion value goes
|
|
||||||
* to zero (all digits were converted)
|
|
||||||
*/
|
|
||||||
if (base == HEX) {
|
|
||||||
while (pt >= str) {
|
|
||||||
if ((digit = (val & 0xf)) < 10)
|
|
||||||
*pt-- = '0' + (char)digit;
|
|
||||||
else
|
|
||||||
*pt-- = 'a' + (char)(digit - 10);
|
|
||||||
if ((val = (val >> 4)) == (u_long)0)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
while (pt >= str) {
|
|
||||||
*pt-- = '0' + (char)(val & 0x7);
|
|
||||||
if ((val = (val >> 3)) == 0)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* pad with leading ascii ZEROS. We return -1 if we ran out of space.
|
|
||||||
*/
|
|
||||||
while (pt >= str)
|
|
||||||
*pt-- = '0';
|
|
||||||
if (val != 0)
|
|
||||||
return -1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* asc_umax()
|
|
||||||
* convert hex/octal character string into a uintmax. We do
|
|
||||||
* not have to to check for overflow! (the headers in all supported
|
|
||||||
* formats are not large enough to create an overflow).
|
|
||||||
* NOTE: strings passed to us are NOT TERMINATED.
|
|
||||||
* Return:
|
|
||||||
* uintmax_t value
|
|
||||||
*/
|
|
||||||
|
|
||||||
uintmax_t
|
|
||||||
asc_umax(char *str, int len, int base)
|
|
||||||
{
|
|
||||||
char *stop;
|
|
||||||
uintmax_t tval = 0;
|
|
||||||
|
|
||||||
stop = str + len;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* skip over leading blanks and zeros
|
|
||||||
*/
|
|
||||||
while ((str < stop) && ((*str == ' ') || (*str == '0')))
|
|
||||||
++str;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* for each valid digit, shift running value (tval) over to next digit
|
|
||||||
* and add next digit
|
|
||||||
*/
|
|
||||||
if (base == HEX) {
|
|
||||||
while (str < stop) {
|
|
||||||
if ((*str >= '0') && (*str <= '9'))
|
|
||||||
tval = (tval << 4) + (*str++ - '0');
|
|
||||||
else if ((*str >= 'A') && (*str <= 'F'))
|
|
||||||
tval = (tval << 4) + 10 + (*str++ - 'A');
|
|
||||||
else if ((*str >= 'a') && (*str <= 'f'))
|
|
||||||
tval = (tval << 4) + 10 + (*str++ - 'a');
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
while ((str < stop) && (*str >= '0') && (*str <= '7'))
|
|
||||||
tval = (tval << 3) + (*str++ - '0');
|
|
||||||
}
|
|
||||||
return tval;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* umax_asc()
|
|
||||||
* convert an uintmax_t into a hex/oct ascii string. pads with
|
|
||||||
* LEADING ascii 0's to fill string completely
|
|
||||||
* NOTE: the string created is NOT TERMINATED.
|
|
||||||
*/
|
|
||||||
|
|
||||||
int
|
|
||||||
umax_asc(uintmax_t val, char *str, int len, int base)
|
|
||||||
{
|
|
||||||
char *pt;
|
|
||||||
uintmax_t digit;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* WARNING str is not '\0' terminated by this routine
|
|
||||||
*/
|
|
||||||
pt = str + len - 1;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* do a tailwise conversion (start at right most end of string to place
|
|
||||||
* least significant digit). Keep shifting until conversion value goes
|
|
||||||
* to zero (all digits were converted)
|
|
||||||
*/
|
|
||||||
if (base == HEX) {
|
|
||||||
while (pt >= str) {
|
|
||||||
if ((digit = (val & 0xf)) < 10)
|
|
||||||
*pt-- = '0' + (char)digit;
|
|
||||||
else
|
|
||||||
*pt-- = 'a' + (char)(digit - 10);
|
|
||||||
if ((val = (val >> 4)) == 0)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
while (pt >= str) {
|
|
||||||
*pt-- = '0' + (char)(val & 0x7);
|
|
||||||
if ((val = (val >> 3)) == 0)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* pad with leading ascii ZEROS. We return -1 if we ran out of space.
|
|
||||||
*/
|
|
||||||
while (pt >= str)
|
|
||||||
*pt-- = '0';
|
|
||||||
if (val != 0)
|
|
||||||
return -1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
check_Aflag(void)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (Aflag > 0)
|
|
||||||
return 1;
|
|
||||||
if (Aflag == 0) {
|
|
||||||
Aflag = -1;
|
|
||||||
tty_warn(0,
|
|
||||||
"Removing leading / from absolute path names in the archive");
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
@ -1,92 +0,0 @@
|
||||||
/* $NetBSD: getoldopt.c,v 1.23 2012/08/09 11:05:59 christos Exp $ */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Plug-compatible replacement for getopt() for parsing tar-like
|
|
||||||
* arguments. If the first argument begins with "-", it uses getopt;
|
|
||||||
* otherwise, it uses the old rules used by tar, dump, and ps.
|
|
||||||
*
|
|
||||||
* Written 25 August 1985 by John Gilmore (ihnp4!hoptoad!gnu) and placed
|
|
||||||
* in the Public Domain for your edification and enjoyment.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if HAVE_NBTOOL_CONFIG_H
|
|
||||||
#include "nbtool_config.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
|
||||||
#if !defined(lint)
|
|
||||||
__RCSID("$NetBSD: getoldopt.c,v 1.23 2012/08/09 11:05:59 christos Exp $");
|
|
||||||
#endif /* not lint */
|
|
||||||
|
|
||||||
#if HAVE_NBTOOL_CONFIG_H
|
|
||||||
#include "compat_getopt.h"
|
|
||||||
#else
|
|
||||||
#include <getopt.h>
|
|
||||||
#endif
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include "pax.h"
|
|
||||||
#include "extern.h"
|
|
||||||
|
|
||||||
int
|
|
||||||
getoldopt(int argc, char **argv, const char *optstring,
|
|
||||||
struct option *longopts, int *idx)
|
|
||||||
{
|
|
||||||
static char *key; /* Points to next keyletter */
|
|
||||||
static char use_getopt; /* !=0 if argv[1][0] was '-' */
|
|
||||||
char c;
|
|
||||||
char *place;
|
|
||||||
|
|
||||||
optarg = NULL;
|
|
||||||
|
|
||||||
if (key == NULL) { /* First time */
|
|
||||||
if (argc < 2) return -1;
|
|
||||||
key = argv[1];
|
|
||||||
if (*key == '-')
|
|
||||||
use_getopt++;
|
|
||||||
else
|
|
||||||
optind = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
c = '\0';
|
|
||||||
if (!use_getopt) {
|
|
||||||
c = *key++;
|
|
||||||
if (c == '\0') {
|
|
||||||
key--;
|
|
||||||
use_getopt = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (use_getopt) {
|
|
||||||
if (longopts != NULL) {
|
|
||||||
return getopt_long(argc, argv, optstring,
|
|
||||||
longopts, idx);
|
|
||||||
} else {
|
|
||||||
return getopt(argc, argv, optstring);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
place = strchr(optstring, c);
|
|
||||||
|
|
||||||
if (place == NULL || c == ':') {
|
|
||||||
fprintf(stderr, "%s: unknown option %c\n", argv[0], c);
|
|
||||||
return '?';
|
|
||||||
}
|
|
||||||
|
|
||||||
place++;
|
|
||||||
if (*place == ':') {
|
|
||||||
if (optind < argc) {
|
|
||||||
optarg = argv[optind];
|
|
||||||
optind++;
|
|
||||||
} else {
|
|
||||||
fprintf(stderr, "%s: %c argument missing\n",
|
|
||||||
argv[0], c);
|
|
||||||
return '?';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
2166
bin/pax/options.c
2166
bin/pax/options.c
File diff suppressed because it is too large
Load Diff
|
|
@ -1,116 +0,0 @@
|
||||||
/* $NetBSD: options.h,v 1.11 2007/04/23 18:40:22 christos Exp $ */
|
|
||||||
|
|
||||||
/*-
|
|
||||||
* Copyright (c) 1992 Keith Muller.
|
|
||||||
* Copyright (c) 1992, 1993
|
|
||||||
* The Regents of the University of California. All rights reserved.
|
|
||||||
*
|
|
||||||
* This code is derived from software contributed to Berkeley by
|
|
||||||
* Keith Muller of the University of California, San Diego.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* @(#)options.h 8.2 (Berkeley) 4/18/94
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* argv[0] names. Used for tar and cpio emulation
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define NM_TAR "tar"
|
|
||||||
#define NM_CPIO "cpio"
|
|
||||||
#define NM_PAX "pax"
|
|
||||||
|
|
||||||
/* special value for -E */
|
|
||||||
#define none "none"
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Constants used to specify the legal sets of flags in pax. For each major
|
|
||||||
* operation mode of pax, a set of illegal flags is defined. If any one of
|
|
||||||
* those illegal flags are found set, we scream and exit
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* flags (one for each option).
|
|
||||||
*/
|
|
||||||
#define AF 0x000000001ULL
|
|
||||||
#define BF 0x000000002ULL
|
|
||||||
#define CF 0x000000004ULL
|
|
||||||
#define DF 0x000000008ULL
|
|
||||||
#define FF 0x000000010ULL
|
|
||||||
#define IF 0x000000020ULL
|
|
||||||
#define KF 0x000000040ULL
|
|
||||||
#define LF 0x000000080ULL
|
|
||||||
#define NF 0x000000100ULL
|
|
||||||
#define OF 0x000000200ULL
|
|
||||||
#define PF 0x000000400ULL
|
|
||||||
#define RF 0x000000800ULL
|
|
||||||
#define SF 0x000001000ULL
|
|
||||||
#define TF 0x000002000ULL
|
|
||||||
#define UF 0x000004000ULL
|
|
||||||
#define VF 0x000008000ULL
|
|
||||||
#define WF 0x000010000ULL
|
|
||||||
#define XF 0x000020000ULL
|
|
||||||
#define CAF 0x000040000ULL /* nonstandard extension */
|
|
||||||
#define CBF 0x000080000ULL /* nonstandard extension */
|
|
||||||
#define CDF 0x000100000ULL /* nonstandard extension */
|
|
||||||
#define CEF 0x000200000ULL /* nonstandard extension */
|
|
||||||
#define CGF 0x000400000ULL /* nonstandard extension */
|
|
||||||
#define CHF 0x000800000ULL /* nonstandard extension */
|
|
||||||
#define CLF 0x001000000ULL /* nonstandard extension */
|
|
||||||
#define CMF 0x002000000ULL /* nonstandard extension */
|
|
||||||
#define CPF 0x004000000ULL /* nonstandard extension */
|
|
||||||
#define CTF 0x008000000ULL /* nonstandard extension */
|
|
||||||
#define CUF 0x010000000ULL /* nonstandard extension */
|
|
||||||
#define VSF 0x020000000ULL /* non-standard */
|
|
||||||
#define CXF 0x040000000ULL
|
|
||||||
#define CYF 0x080000000ULL /* nonstandard extension */
|
|
||||||
#define CZF 0x100000000ULL /* nonstandard extension */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ascii string indexed by bit position above (alter the above and you must
|
|
||||||
* alter this string) used to tell the user what flags caused us to complain
|
|
||||||
*/
|
|
||||||
#define FLGCH "abcdfiklnoprstuvwxABDEGHLMPTUVXYZ"
|
|
||||||
|
|
||||||
/*
|
|
||||||
* legal pax operation bit patterns
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define ISLIST(x) (((x) & (RF|WF)) == 0)
|
|
||||||
#define ISEXTRACT(x) (((x) & (RF|WF)) == RF)
|
|
||||||
#define ISARCHIVE(x) (((x) & (AF|RF|WF)) == WF)
|
|
||||||
#define ISAPPND(x) (((x) & (AF|RF|WF)) == (AF|WF))
|
|
||||||
#define ISCOPY(x) (((x) & (RF|WF)) == (RF|WF))
|
|
||||||
#define ISWRITE(x) (((x) & (RF|WF)) == WF)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Illegal option flag subsets based on pax operation
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define BDEXTR (AF|BF|LF|TF|WF|XF|CBF|CHF|CLF|CMF|CPF|CXF)
|
|
||||||
#define BDARCH (CF|KF|LF|NF|PF|RF|CDF|CEF|CYF|CZF)
|
|
||||||
#define BDCOPY (AF|BF|FF|OF|XF|CAF|CBF|CEF)
|
|
||||||
#define BDLIST (AF|BF|IF|KF|LF|OF|PF|RF|TF|UF|WF|XF|CBF|CDF|CHF|CLF|CMF|CPF|CXF|CYF|CZF)
|
|
||||||
1139
bin/pax/pat_rep.c
1139
bin/pax/pat_rep.c
File diff suppressed because it is too large
Load Diff
|
|
@ -1,51 +0,0 @@
|
||||||
/* $NetBSD: pat_rep.h,v 1.7 2008/02/24 20:42:46 joerg Exp $ */
|
|
||||||
|
|
||||||
/*-
|
|
||||||
* Copyright (c) 1992 Keith Muller.
|
|
||||||
* Copyright (c) 1992, 1993
|
|
||||||
* The Regents of the University of California. All rights reserved.
|
|
||||||
*
|
|
||||||
* This code is derived from software contributed to Berkeley by
|
|
||||||
* Keith Muller of the University of California, San Diego.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* @(#)pat_rep.h 8.1 (Berkeley) 5/31/93
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <regex.h>
|
|
||||||
/*
|
|
||||||
* data structure for storing user supplied replacement strings (-s)
|
|
||||||
*/
|
|
||||||
typedef struct replace {
|
|
||||||
char *nstr; /* the new string we will substitute with */
|
|
||||||
regex_t rcmp; /* compiled regular expression used to match */
|
|
||||||
int flgs; /* print conversions? global in operation? */
|
|
||||||
#define PRNT 0x1
|
|
||||||
#define GLOB 0x2
|
|
||||||
#define RENM 0x4
|
|
||||||
#define SYML 0x8
|
|
||||||
struct replace *fow; /* pointer to next pattern */
|
|
||||||
} REPLACE;
|
|
||||||
1283
bin/pax/pax.1
1283
bin/pax/pax.1
File diff suppressed because it is too large
Load Diff
492
bin/pax/pax.c
492
bin/pax/pax.c
|
|
@ -1,492 +0,0 @@
|
||||||
/* $NetBSD: pax.c,v 1.47 2011/08/29 14:47:48 joerg Exp $ */
|
|
||||||
|
|
||||||
/*-
|
|
||||||
* Copyright (c) 1992 Keith Muller.
|
|
||||||
* Copyright (c) 1992, 1993
|
|
||||||
* The Regents of the University of California. All rights reserved.
|
|
||||||
*
|
|
||||||
* This code is derived from software contributed to Berkeley by
|
|
||||||
* Keith Muller of the University of California, San Diego.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if HAVE_NBTOOL_CONFIG_H
|
|
||||||
#include "nbtool_config.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
|
||||||
#if !defined(lint)
|
|
||||||
__COPYRIGHT("@(#) Copyright (c) 1992, 1993\
|
|
||||||
The Regents of the University of California. All rights reserved.");
|
|
||||||
#if 0
|
|
||||||
static char sccsid[] = "@(#)pax.c 8.2 (Berkeley) 4/18/94";
|
|
||||||
#else
|
|
||||||
__RCSID("$NetBSD: pax.c,v 1.47 2011/08/29 14:47:48 joerg Exp $");
|
|
||||||
#endif
|
|
||||||
#endif /* not lint */
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/param.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/time.h>
|
|
||||||
#include <sys/resource.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <signal.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <paths.h>
|
|
||||||
#include <util.h>
|
|
||||||
#include "pax.h"
|
|
||||||
#include "extern.h"
|
|
||||||
static int gen_init(void);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* PAX main routines, general globals and some simple start up routines
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Variables that can be accessed by any routine within pax
|
|
||||||
*/
|
|
||||||
int act = ERROR; /* read/write/append/copy */
|
|
||||||
FSUB *frmt = NULL; /* archive format type */
|
|
||||||
int cflag; /* match all EXCEPT pattern/file */
|
|
||||||
int cwdfd = -1; /* starting cwd */
|
|
||||||
int dflag; /* directory member match only */
|
|
||||||
int iflag; /* interactive file/archive rename */
|
|
||||||
int kflag; /* do not overwrite existing files */
|
|
||||||
int lflag; /* use hard links when possible */
|
|
||||||
int nflag; /* select first archive member match */
|
|
||||||
int tflag; /* restore access time after read */
|
|
||||||
int uflag; /* ignore older modification time files */
|
|
||||||
int vflag; /* produce verbose output */
|
|
||||||
int Aflag; /* honor absolute path */
|
|
||||||
int Dflag; /* same as uflag except inode change time */
|
|
||||||
int Hflag; /* follow command line symlinks (write only) */
|
|
||||||
int Lflag; /* follow symlinks when writing */
|
|
||||||
int Mflag; /* treat stdin as an mtree(8) specfile */
|
|
||||||
int Vflag; /* produce somewhat verbose output (no listing) */
|
|
||||||
int Xflag; /* archive files with same device id only */
|
|
||||||
int Yflag; /* same as Dflg except after name mode */
|
|
||||||
int Zflag; /* same as uflg except after name mode */
|
|
||||||
int vfpart; /* is partial verbose output in progress */
|
|
||||||
int patime = 1; /* preserve file access time */
|
|
||||||
int pmtime = 1; /* preserve file modification times */
|
|
||||||
int nodirs; /* do not create directories as needed */
|
|
||||||
int pfflags = 1; /* preserve file flags */
|
|
||||||
int pmode; /* preserve file mode bits */
|
|
||||||
int pids; /* preserve file uid/gid */
|
|
||||||
int rmleadslash = 0; /* remove leading '/' from pathnames */
|
|
||||||
int exit_val; /* exit value */
|
|
||||||
int docrc; /* check/create file crc */
|
|
||||||
int to_stdout; /* extract to stdout */
|
|
||||||
char *dirptr; /* destination dir in a copy */
|
|
||||||
char *ltmfrmt; /* -v locale time format (if any) */
|
|
||||||
const char *argv0; /* root of argv[0] */
|
|
||||||
sigset_t s_mask; /* signal mask for cleanup critical sect */
|
|
||||||
FILE *listf; /* file pointer to print file list to */
|
|
||||||
char *tempfile; /* tempfile to use for mkstemp(3) */
|
|
||||||
char *tempbase; /* basename of tempfile to use for mkstemp(3) */
|
|
||||||
int forcelocal; /* force local operation even if the name
|
|
||||||
* contains a :
|
|
||||||
*/
|
|
||||||
int secure = 1; /* don't extract names that contain .. */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* PAX - Portable Archive Interchange
|
|
||||||
*
|
|
||||||
* A utility to read, write, and write lists of the members of archive
|
|
||||||
* files and copy directory hierarchies. A variety of archive formats
|
|
||||||
* are supported (some are described in POSIX 1003.1 10.1):
|
|
||||||
*
|
|
||||||
* ustar - 10.1.1 extended tar interchange format
|
|
||||||
* cpio - 10.1.2 extended cpio interchange format
|
|
||||||
* tar - old BSD 4.3 tar format
|
|
||||||
* binary cpio - old cpio with binary header format
|
|
||||||
* sysVR4 cpio - with and without CRC
|
|
||||||
*
|
|
||||||
* This version is a superset of IEEE Std 1003.2b-d3
|
|
||||||
*
|
|
||||||
* Summary of Extensions to the IEEE Standard:
|
|
||||||
*
|
|
||||||
* 1 READ ENHANCEMENTS
|
|
||||||
* 1.1 Operations which read archives will continue to operate even when
|
|
||||||
* processing archives which may be damaged, truncated, or fail to meet
|
|
||||||
* format specs in several different ways. Damaged sections of archives
|
|
||||||
* are detected and avoided if possible. Attempts will be made to resync
|
|
||||||
* archive read operations even with badly damaged media.
|
|
||||||
* 1.2 Blocksize requirements are not strictly enforced on archive read.
|
|
||||||
* Tapes which have variable sized records can be read without errors.
|
|
||||||
* 1.3 The user can specify via the non-standard option flag -E if error
|
|
||||||
* resync operation should stop on a media error, try a specified number
|
|
||||||
* of times to correct, or try to correct forever.
|
|
||||||
* 1.4 Sparse files (lseek holes) stored on the archive (but stored with blocks
|
|
||||||
* of all zeros will be restored with holes appropriate for the target
|
|
||||||
* filesystem
|
|
||||||
* 1.5 The user is notified whenever something is found during archive
|
|
||||||
* read operations which violates spec (but the read will continue).
|
|
||||||
* 1.6 Multiple archive volumes can be read and may span over different
|
|
||||||
* archive devices
|
|
||||||
* 1.7 Rigidly restores all file attributes exactly as they are stored on the
|
|
||||||
* archive.
|
|
||||||
* 1.8 Modification change time ranges can be specified via multiple -T
|
|
||||||
* options. These allow a user to select files whose modification time
|
|
||||||
* lies within a specific time range.
|
|
||||||
* 1.9 Files can be selected based on owner (user name or uid) via one or more
|
|
||||||
* -U options.
|
|
||||||
* 1.10 Files can be selected based on group (group name or gid) via one o
|
|
||||||
* more -G options.
|
|
||||||
* 1.11 File modification time can be checked against existing file after
|
|
||||||
* name modification (-Z)
|
|
||||||
*
|
|
||||||
* 2 WRITE ENHANCEMENTS
|
|
||||||
* 2.1 Write operation will stop instead of allowing a user to create a flawed
|
|
||||||
* flawed archive (due to any problem).
|
|
||||||
* 2.2 Archives written by pax are forced to strictly conform to both the
|
|
||||||
* archive and pax the specific format specifications.
|
|
||||||
* 2.3 Blocking size and format is rigidly enforced on writes.
|
|
||||||
* 2.4 Formats which may exhibit header overflow problems (they have fields
|
|
||||||
* too small for large file systems, such as inode number storage), use
|
|
||||||
* routines designed to repair this problem. These techniques still
|
|
||||||
* conform to both pax and format specifications, but no longer truncate
|
|
||||||
* these fields. This removes any restrictions on using these archive
|
|
||||||
* formats on large file systems.
|
|
||||||
* 2.5 Multiple archive volumes can be written and may span over different
|
|
||||||
* archive devices
|
|
||||||
* 2.6 A archive volume record limit allows the user to specify the number
|
|
||||||
* of bytes stored on an archive volume. When reached the user is
|
|
||||||
* prompted for the next archive volume. This is specified with the
|
|
||||||
* non-standard -B flag. The limit is rounded up to the next blocksize.
|
|
||||||
* 2.7 All archive padding during write use zero filled sections. This makes
|
|
||||||
* it much easier to pull data out of flawed archive during read
|
|
||||||
* operations.
|
|
||||||
* 2.8 Access time reset with the -t applies to all file nodes (including
|
|
||||||
* directories).
|
|
||||||
* 2.9 Symbolic links can be followed with -L (optional in the spec).
|
|
||||||
* 2.10 Modification or inode change time ranges can be specified via
|
|
||||||
* multiple -T options. These allow a user to select files whose
|
|
||||||
* modification or inode change time lies within a specific time range.
|
|
||||||
* 2.11 Files can be selected based on owner (user name or uid) via one or more
|
|
||||||
* -U options.
|
|
||||||
* 2.12 Files can be selected based on group (group name or gid) via one o
|
|
||||||
* more -G options.
|
|
||||||
* 2.13 Symlinks which appear on the command line can be followed (without
|
|
||||||
* following other symlinks; -H flag)
|
|
||||||
*
|
|
||||||
* 3 COPY ENHANCEMENTS
|
|
||||||
* 3.1 Sparse files (lseek holes) can be copied without expanding the holes
|
|
||||||
* into zero filled blocks. The file copy is created with holes which are
|
|
||||||
* appropriate for the target filesystem
|
|
||||||
* 3.2 Access time as well as modification time on copied file trees can be
|
|
||||||
* preserved with the appropriate -p options.
|
|
||||||
* 3.3 Access time reset with the -t applies to all file nodes (including
|
|
||||||
* directories).
|
|
||||||
* 3.4 Symbolic links can be followed with -L (optional in the spec).
|
|
||||||
* 3.5 Modification or inode change time ranges can be specified via
|
|
||||||
* multiple -T options. These allow a user to select files whose
|
|
||||||
* modification or inode change time lies within a specific time range.
|
|
||||||
* 3.6 Files can be selected based on owner (user name or uid) via one or more
|
|
||||||
* -U options.
|
|
||||||
* 3.7 Files can be selected based on group (group name or gid) via one o
|
|
||||||
* more -G options.
|
|
||||||
* 3.8 Symlinks which appear on the command line can be followed (without
|
|
||||||
* following other symlinks; -H flag)
|
|
||||||
* 3.9 File inode change time can be checked against existing file before
|
|
||||||
* name modification (-D)
|
|
||||||
* 3.10 File inode change time can be checked against existing file after
|
|
||||||
* name modification (-Y)
|
|
||||||
* 3.11 File modification time can be checked against existing file after
|
|
||||||
* name modification (-Z)
|
|
||||||
*
|
|
||||||
* 4 GENERAL ENHANCEMENTS
|
|
||||||
* 4.1 Internal structure is designed to isolate format dependent and
|
|
||||||
* independent functions. Formats are selected via a format driver table.
|
|
||||||
* This encourages the addition of new archive formats by only having to
|
|
||||||
* write those routines which id, read and write the archive header.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* main()
|
|
||||||
* parse options, set up and operate as specified by the user.
|
|
||||||
* any operational flaw will set exit_val to non-zero
|
|
||||||
* Return: 0 if ok, 1 otherwise
|
|
||||||
*/
|
|
||||||
|
|
||||||
int
|
|
||||||
main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
const char *tmpdir;
|
|
||||||
size_t tdlen;
|
|
||||||
int rval;
|
|
||||||
|
|
||||||
setprogname(argv[0]);
|
|
||||||
|
|
||||||
listf = stderr;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* parse options, determine operational mode
|
|
||||||
*/
|
|
||||||
options(argc, argv);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* general init
|
|
||||||
*/
|
|
||||||
if ((gen_init() < 0) || (tty_init() < 0))
|
|
||||||
return exit_val;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Keep a reference to cwd, so we can always come back home.
|
|
||||||
*/
|
|
||||||
cwdfd = open(".", O_RDONLY);
|
|
||||||
if (cwdfd < 0) {
|
|
||||||
syswarn(1, errno, "Can't open current working directory.");
|
|
||||||
return exit_val;
|
|
||||||
}
|
|
||||||
if (updatepath() == -1)
|
|
||||||
return exit_val;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Where should we put temporary files?
|
|
||||||
*/
|
|
||||||
if ((tmpdir = getenv("TMPDIR")) == NULL || *tmpdir == '\0')
|
|
||||||
tmpdir = _PATH_TMP;
|
|
||||||
tdlen = strlen(tmpdir);
|
|
||||||
while(tdlen > 0 && tmpdir[tdlen - 1] == '/')
|
|
||||||
tdlen--;
|
|
||||||
tempfile = malloc(tdlen + 1 + sizeof(_TFILE_BASE));
|
|
||||||
if (tempfile == NULL) {
|
|
||||||
tty_warn(1, "Cannot allocate memory for temp file name.");
|
|
||||||
return exit_val;
|
|
||||||
}
|
|
||||||
if (tdlen)
|
|
||||||
memcpy(tempfile, tmpdir, tdlen);
|
|
||||||
tempbase = tempfile + tdlen;
|
|
||||||
*tempbase++ = '/';
|
|
||||||
|
|
||||||
(void)time(&starttime);
|
|
||||||
#ifdef SIGINFO
|
|
||||||
(void)signal(SIGINFO, ar_summary);
|
|
||||||
#endif
|
|
||||||
/*
|
|
||||||
* select a primary operation mode
|
|
||||||
*/
|
|
||||||
switch (act) {
|
|
||||||
case EXTRACT:
|
|
||||||
rval = extract();
|
|
||||||
break;
|
|
||||||
case ARCHIVE:
|
|
||||||
rval = archive();
|
|
||||||
break;
|
|
||||||
case APPND:
|
|
||||||
if (gzip_program != NULL)
|
|
||||||
err(1, "cannot gzip while appending");
|
|
||||||
rval = append();
|
|
||||||
/*
|
|
||||||
* Check if we tried to append on an empty file and
|
|
||||||
* turned into ARCHIVE mode.
|
|
||||||
*/
|
|
||||||
if (act == -ARCHIVE) {
|
|
||||||
act = ARCHIVE;
|
|
||||||
rval = archive();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case COPY:
|
|
||||||
rval = copy();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
case LIST:
|
|
||||||
rval = list();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (rval != 0)
|
|
||||||
exit_val = 1;
|
|
||||||
return exit_val;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* sig_cleanup()
|
|
||||||
* when interrupted we try to do whatever delayed processing we can.
|
|
||||||
* This is not critical, but we really ought to limit our damage when we
|
|
||||||
* are aborted by the user.
|
|
||||||
* Return:
|
|
||||||
* never....
|
|
||||||
*/
|
|
||||||
|
|
||||||
__dead static void
|
|
||||||
sig_cleanup(int which_sig)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* restore modes and times for any dirs we may have created
|
|
||||||
* or any dirs we may have read. Set vflag and vfpart so the user
|
|
||||||
* will clearly see the message on a line by itself.
|
|
||||||
*/
|
|
||||||
vflag = vfpart = 1;
|
|
||||||
#ifdef SIGXCPU
|
|
||||||
if (which_sig == SIGXCPU)
|
|
||||||
tty_warn(1, "CPU time limit reached, cleaning up.");
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
tty_warn(1, "Signal caught, cleaning up.");
|
|
||||||
|
|
||||||
/* delete any open temporary file */
|
|
||||||
if (xtmp_name)
|
|
||||||
(void)unlink(xtmp_name);
|
|
||||||
ar_close();
|
|
||||||
proc_dir();
|
|
||||||
if (tflag)
|
|
||||||
atdir_end();
|
|
||||||
|
|
||||||
(void)raise_default_signal(which_sig);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* gen_init()
|
|
||||||
* general setup routines. Not all are required, but they really help
|
|
||||||
* when dealing with a medium to large sized archives.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static int
|
|
||||||
gen_init(void)
|
|
||||||
{
|
|
||||||
struct rlimit reslimit;
|
|
||||||
struct sigaction n_hand;
|
|
||||||
struct sigaction o_hand;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Really needed to handle large archives. We can run out of memory for
|
|
||||||
* internal tables really fast when we have a whole lot of files...
|
|
||||||
*/
|
|
||||||
if (getrlimit(RLIMIT_DATA , &reslimit) == 0){
|
|
||||||
reslimit.rlim_cur = reslimit.rlim_max;
|
|
||||||
(void)setrlimit(RLIMIT_DATA , &reslimit);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* should file size limits be waived? if the os limits us, this is
|
|
||||||
* needed if we want to write a large archive
|
|
||||||
*/
|
|
||||||
if (getrlimit(RLIMIT_FSIZE , &reslimit) == 0){
|
|
||||||
reslimit.rlim_cur = reslimit.rlim_max;
|
|
||||||
(void)setrlimit(RLIMIT_FSIZE , &reslimit);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* increase the size the stack can grow to
|
|
||||||
*/
|
|
||||||
if (getrlimit(RLIMIT_STACK , &reslimit) == 0){
|
|
||||||
reslimit.rlim_cur = reslimit.rlim_max;
|
|
||||||
(void)setrlimit(RLIMIT_STACK , &reslimit);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef RLIMIT_RSS
|
|
||||||
/*
|
|
||||||
* not really needed, but doesn't hurt
|
|
||||||
*/
|
|
||||||
if (getrlimit(RLIMIT_RSS , &reslimit) == 0){
|
|
||||||
reslimit.rlim_cur = reslimit.rlim_max;
|
|
||||||
(void)setrlimit(RLIMIT_RSS , &reslimit);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Handle posix locale
|
|
||||||
*
|
|
||||||
* set user defines time printing format for -v option
|
|
||||||
*/
|
|
||||||
ltmfrmt = getenv("LC_TIME");
|
|
||||||
|
|
||||||
/*
|
|
||||||
* signal handling to reset stored directory times and modes. Since
|
|
||||||
* we deal with broken pipes via failed writes we ignore it. We also
|
|
||||||
* deal with any file size limit through failed writes. CPU time
|
|
||||||
* limits are caught and a cleanup is forced.
|
|
||||||
*/
|
|
||||||
if ((sigemptyset(&s_mask) < 0) || (sigaddset(&s_mask, SIGTERM) < 0) ||
|
|
||||||
(sigaddset(&s_mask,SIGINT) < 0)||(sigaddset(&s_mask,SIGHUP) < 0) ||
|
|
||||||
(sigaddset(&s_mask,SIGPIPE) < 0)||(sigaddset(&s_mask,SIGQUIT)<0)){
|
|
||||||
tty_warn(1, "Unable to set up signal mask");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
#ifdef SIGXCPU
|
|
||||||
if (sigaddset(&s_mask,SIGXCPU) < 0) {
|
|
||||||
tty_warn(1, "Unable to set up signal mask");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef SIGXFSZ
|
|
||||||
if (sigaddset(&s_mask,SIGXFSZ) < 0) {
|
|
||||||
tty_warn(1, "Unable to set up signal mask");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
memset(&n_hand, 0, sizeof n_hand);
|
|
||||||
n_hand.sa_mask = s_mask;
|
|
||||||
n_hand.sa_flags = 0;
|
|
||||||
n_hand.sa_handler = sig_cleanup;
|
|
||||||
|
|
||||||
if ((sigaction(SIGHUP, &n_hand, &o_hand) < 0) &&
|
|
||||||
(o_hand.sa_handler == SIG_IGN) &&
|
|
||||||
(sigaction(SIGHUP, &o_hand, &o_hand) < 0))
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
if ((sigaction(SIGTERM, &n_hand, &o_hand) < 0) &&
|
|
||||||
(o_hand.sa_handler == SIG_IGN) &&
|
|
||||||
(sigaction(SIGTERM, &o_hand, &o_hand) < 0))
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
if ((sigaction(SIGINT, &n_hand, &o_hand) < 0) &&
|
|
||||||
(o_hand.sa_handler == SIG_IGN) &&
|
|
||||||
(sigaction(SIGINT, &o_hand, &o_hand) < 0))
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
if ((sigaction(SIGQUIT, &n_hand, &o_hand) < 0) &&
|
|
||||||
(o_hand.sa_handler == SIG_IGN) &&
|
|
||||||
(sigaction(SIGQUIT, &o_hand, &o_hand) < 0))
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
#ifdef SIGXCPU
|
|
||||||
if ((sigaction(SIGXCPU, &n_hand, &o_hand) < 0) &&
|
|
||||||
(o_hand.sa_handler == SIG_IGN) &&
|
|
||||||
(sigaction(SIGXCPU, &o_hand, &o_hand) < 0))
|
|
||||||
goto out;
|
|
||||||
#endif
|
|
||||||
n_hand.sa_handler = SIG_IGN;
|
|
||||||
if (sigaction(SIGPIPE, &n_hand, &o_hand) < 0)
|
|
||||||
goto out;
|
|
||||||
#ifdef SIGXFSZ
|
|
||||||
if (sigaction(SIGXFSZ, &n_hand, &o_hand) < 0)
|
|
||||||
goto out;
|
|
||||||
#endif
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
out:
|
|
||||||
syswarn(1, errno, "Unable to set up signal handler");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
285
bin/pax/pax.h
285
bin/pax/pax.h
|
|
@ -1,285 +0,0 @@
|
||||||
/* $NetBSD: pax.h,v 1.31 2012/08/09 08:09:21 christos Exp $ */
|
|
||||||
|
|
||||||
/*-
|
|
||||||
* Copyright (c) 1992 Keith Muller.
|
|
||||||
* Copyright (c) 1992, 1993
|
|
||||||
* The Regents of the University of California. All rights reserved.
|
|
||||||
*
|
|
||||||
* This code is derived from software contributed to Berkeley by
|
|
||||||
* Keith Muller of the University of California, San Diego.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* @(#)pax.h 8.2 (Berkeley) 4/18/94
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if ! HAVE_NBTOOL_CONFIG_H
|
|
||||||
#define HAVE_LUTIMES 1
|
|
||||||
#if !defined(__minix)
|
|
||||||
#define HAVE_STRUCT_STAT_ST_FLAGS 1
|
|
||||||
#endif /* !defined(__minix) */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* BSD PAX global data structures and constants.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define MAXBLK 32256 /* MAX blocksize supported (posix SPEC) */
|
|
||||||
/* WARNING: increasing MAXBLK past 32256 */
|
|
||||||
/* will violate posix spec. */
|
|
||||||
#define BLKMULT 512 /* blocksize must be even mult of 512 bytes */
|
|
||||||
/* Don't even think of changing this */
|
|
||||||
#define DEVBLK 8192 /* default read blksize for devices */
|
|
||||||
#define FILEBLK 10240 /* default read blksize for files */
|
|
||||||
#define PAXPATHLEN 3072 /* maximum path length for pax. MUST be */
|
|
||||||
/* longer than the system MAXPATHLEN */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Pax modes of operation
|
|
||||||
*/
|
|
||||||
#define ERROR -1 /* nothing selected */
|
|
||||||
#define LIST 0 /* List the file in an archive */
|
|
||||||
#define EXTRACT 1 /* extract the files in an archive */
|
|
||||||
#define ARCHIVE 2 /* write a new archive */
|
|
||||||
#define APPND 3 /* append to the end of an archive */
|
|
||||||
#define COPY 4 /* copy files to destination dir */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Device type of the current archive volume
|
|
||||||
*/
|
|
||||||
#define ISREG 0 /* regular file */
|
|
||||||
#define ISCHR 1 /* character device */
|
|
||||||
#define ISBLK 2 /* block device */
|
|
||||||
#define ISTAPE 3 /* tape drive */
|
|
||||||
#define ISPIPE 4 /* pipe/socket */
|
|
||||||
#ifdef SUPPORT_RMT
|
|
||||||
#define ISRMT 5 /* rmt */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Pattern matching structure
|
|
||||||
*
|
|
||||||
* Used to store command line patterns
|
|
||||||
*/
|
|
||||||
typedef struct pattern {
|
|
||||||
char *pstr; /* pattern to match, user supplied */
|
|
||||||
char *pend; /* end of a prefix match */
|
|
||||||
char *chdname; /* the dir to change to if not NULL. */
|
|
||||||
int plen; /* length of pstr */
|
|
||||||
int flgs; /* processing/state flags */
|
|
||||||
#define MTCH 0x1 /* pattern has been matched */
|
|
||||||
#define DIR_MTCH 0x2 /* pattern matched a directory */
|
|
||||||
#define NOGLOB_MTCH 0x4 /* non-globbing match */
|
|
||||||
struct pattern *fow; /* next pattern */
|
|
||||||
} PATTERN;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* General Archive Structure (used internal to pax)
|
|
||||||
*
|
|
||||||
* This structure is used to pass information about archive members between
|
|
||||||
* the format independent routines and the format specific routines. When
|
|
||||||
* new archive formats are added, they must accept requests and supply info
|
|
||||||
* encoded in a structure of this type. The name fields are declared statically
|
|
||||||
* here, as there is only ONE of these floating around, size is not a major
|
|
||||||
* consideration. Eventually converting the name fields to a dynamic length
|
|
||||||
* may be required if and when the supporting operating system removes all
|
|
||||||
* restrictions on the length of pathnames it will resolve.
|
|
||||||
*/
|
|
||||||
typedef struct {
|
|
||||||
int nlen; /* file name length */
|
|
||||||
char name[PAXPATHLEN+1]; /* file name */
|
|
||||||
int ln_nlen; /* link name length */
|
|
||||||
char ln_name[PAXPATHLEN+1]; /* name to link to (if any) */
|
|
||||||
char *org_name; /* orig name in file system */
|
|
||||||
char fts_name[PAXPATHLEN+1]; /* name from fts (for *org_name) */
|
|
||||||
char *tmp_name; /* tmp name used to restore */
|
|
||||||
PATTERN *pat; /* ptr to pattern match (if any) */
|
|
||||||
struct stat sb; /* stat buffer see stat(2) */
|
|
||||||
off_t pad; /* bytes of padding after file xfer */
|
|
||||||
off_t skip; /* bytes of real data after header */
|
|
||||||
/* IMPORTANT. The st_size field does */
|
|
||||||
/* not always indicate the amount of */
|
|
||||||
/* data following the header. */
|
|
||||||
u_long crc; /* file crc */
|
|
||||||
int type; /* type of file node */
|
|
||||||
#define PAX_DIR 1 /* directory */
|
|
||||||
#define PAX_CHR 2 /* character device */
|
|
||||||
#define PAX_BLK 3 /* block device */
|
|
||||||
#define PAX_REG 4 /* regular file */
|
|
||||||
#define PAX_SLK 5 /* symbolic link */
|
|
||||||
#define PAX_SCK 6 /* socket */
|
|
||||||
#define PAX_FIF 7 /* fifo */
|
|
||||||
#define PAX_HLK 8 /* hard link */
|
|
||||||
#define PAX_HRG 9 /* hard link to a regular file */
|
|
||||||
#define PAX_CTG 10 /* high performance file */
|
|
||||||
#define PAX_GLL 11 /* GNU long symlink */
|
|
||||||
#define PAX_GLF 12 /* GNU long file */
|
|
||||||
} ARCHD;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Format Specific Routine Table
|
|
||||||
*
|
|
||||||
* The format specific routine table allows new archive formats to be quickly
|
|
||||||
* added. Overall pax operation is independent of the actual format used to
|
|
||||||
* form the archive. Only those routines which deal directly with the archive
|
|
||||||
* are tailored to the oddities of the specific format. All other routines are
|
|
||||||
* independent of the archive format. Data flow in and out of the format
|
|
||||||
* dependent routines pass pointers to ARCHD structure (described below).
|
|
||||||
*/
|
|
||||||
typedef struct {
|
|
||||||
const char *name; /* name of format, this is the name the user */
|
|
||||||
/* gives to -x option to select it. */
|
|
||||||
int bsz; /* default block size. used when the user */
|
|
||||||
/* does not specify a blocksize for writing */
|
|
||||||
/* Appends continue to with the blocksize */
|
|
||||||
/* the archive is currently using.*/
|
|
||||||
int hsz; /* Header size in bytes. this is the size of */
|
|
||||||
/* the smallest header this format supports. */
|
|
||||||
/* Headers are assumed to fit in a BLKMULT. */
|
|
||||||
/* If they are bigger, get_head() and */
|
|
||||||
/* get_arc() must be adjusted */
|
|
||||||
int udev; /* does append require unique dev/ino? some */
|
|
||||||
/* formats use the device and inode fields */
|
|
||||||
/* to specify hard links. when members in */
|
|
||||||
/* the archive have the same inode/dev they */
|
|
||||||
/* are assumed to be hard links. During */
|
|
||||||
/* append we may have to generate unique ids */
|
|
||||||
/* to avoid creating incorrect hard links */
|
|
||||||
int hlk; /* does archive store hard links info? if */
|
|
||||||
/* not, we do not bother to look for them */
|
|
||||||
/* during archive write operations */
|
|
||||||
int blkalgn; /* writes must be aligned to blkalgn boundary */
|
|
||||||
int inhead; /* is the trailer encoded in a valid header? */
|
|
||||||
/* if not, trailers are assumed to be found */
|
|
||||||
/* in invalid headers (i.e like tar) */
|
|
||||||
int (*id)(char *, int); /* checks if a buffer is a valid header */
|
|
||||||
/* returns 1 if it is, o.w. returns a 0 */
|
|
||||||
int (*st_rd)(void); /* initialize routine for read. so format */
|
|
||||||
/* can set up tables etc before it starts */
|
|
||||||
/* reading an archive */
|
|
||||||
int (*rd) /* read header routine. passed a pointer to */
|
|
||||||
(ARCHD *, char *); /* ARCHD. It must extract the info */
|
|
||||||
/* from the format and store it in the ARCHD */
|
|
||||||
/* struct. This routine is expected to fill */
|
|
||||||
/* all the fields in the ARCHD (including */
|
|
||||||
/* stat buf). 0 is returned when a valid */
|
|
||||||
/* header is found. -1 when not valid. This */
|
|
||||||
/* routine set the skip and pad fields so the */
|
|
||||||
/* format independent routines know the */
|
|
||||||
/* amount of padding and the number of bytes */
|
|
||||||
/* of data which follow the header. This info */
|
|
||||||
/* is used to skip to the next file header */
|
|
||||||
off_t (*end_rd)(void); /* read cleanup. Allows format to clean up */
|
|
||||||
/* and MUST RETURN THE LENGTH OF THE TRAILER */
|
|
||||||
/* RECORD (so append knows how many bytes */
|
|
||||||
/* to move back to rewrite the trailer) */
|
|
||||||
int (*st_wr)(void); /* initialize routine for write operations */
|
|
||||||
int (*wr)(ARCHD *); /* write archive header. Passed an ARCHD */
|
|
||||||
/* filled with the specs on the next file to */
|
|
||||||
/* archived. Returns a 1 if no file data is */
|
|
||||||
/* is to be stored; 0 if file data is to be */
|
|
||||||
/* added. A -1 is returned if a write */
|
|
||||||
/* operation to the archive failed. this */
|
|
||||||
/* function sets the skip and pad fields so */
|
|
||||||
/* the proper padding can be added after */
|
|
||||||
/* file data. This routine must NEVER write */
|
|
||||||
/* a flawed archive header. */
|
|
||||||
int (*end_wr)(void); /* end write. write the trailer and do any */
|
|
||||||
/* other format specific functions needed */
|
|
||||||
/* at the end of an archive write */
|
|
||||||
int (*trail) /* returns 0 if a valid trailer, -1 if not */
|
|
||||||
(char *, int, int *); /* For formats which encode the */
|
|
||||||
/* trailer outside of a valid header, a */
|
|
||||||
/* return value of 1 indicates that the block */
|
|
||||||
/* passed to it can never contain a valid */
|
|
||||||
/* header (skip this block, no point in */
|
|
||||||
/* looking at it) */
|
|
||||||
int (*subtrail) /* read/process file data from the archive */
|
|
||||||
(ARCHD *); /* this function is called for trailers */
|
|
||||||
/* inside headers. */
|
|
||||||
int (*rd_data) /* read/process file data from the archive */
|
|
||||||
(ARCHD *, int, off_t *);
|
|
||||||
int (*wr_data) /* write/process file data to the archive */
|
|
||||||
(ARCHD *, int, off_t *);
|
|
||||||
int (*options)(void); /* process format specific options (-o) */
|
|
||||||
} FSUB;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Format Specific Options List
|
|
||||||
*
|
|
||||||
* Used to pass format options to the format options handler
|
|
||||||
*/
|
|
||||||
typedef struct oplist {
|
|
||||||
char *name; /* option variable name e.g. name= */
|
|
||||||
char *value; /* value for option variable */
|
|
||||||
struct oplist *fow; /* next option */
|
|
||||||
} OPLIST;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* General Macros
|
|
||||||
*/
|
|
||||||
#ifndef MIN
|
|
||||||
#define MIN(a,b) (((a)<(b))?(a):(b))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HOSTPROG
|
|
||||||
# include "pack_dev.h" /* explicitly use NetBSD's macros */
|
|
||||||
# define MAJOR(x) major_netbsd(x)
|
|
||||||
# define MINOR(x) minor_netbsd(x)
|
|
||||||
# define TODEV(x, y) makedev_netbsd((x), (y))
|
|
||||||
#else
|
|
||||||
# define MAJOR(x) major(x)
|
|
||||||
# define MINOR(x) minor(x)
|
|
||||||
# define TODEV(x, y) makedev((x), (y))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* General Defines
|
|
||||||
*/
|
|
||||||
#define HEX 16
|
|
||||||
#define OCT 8
|
|
||||||
#define _PAX_ 1
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Pathname base component of the temporary file template, to be created in
|
|
||||||
* ${TMPDIR} or, as a fall-back, _PATH_TMP.
|
|
||||||
*/
|
|
||||||
#define _TFILE_BASE "paxXXXXXXXXXX"
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Macros to manipulate off_t as uintmax_t
|
|
||||||
*/
|
|
||||||
#define OFFT_F "%" PRIuMAX
|
|
||||||
#define OFFT_FP(x) "%" x PRIuMAX
|
|
||||||
#define OFFT_T uintmax_t
|
|
||||||
#define ASC_OFFT(x,y,z) asc_umax(x,y,z)
|
|
||||||
#define OFFT_ASC(w,x,y,z) umax_asc((uintmax_t)w,x,y,z)
|
|
||||||
#define OFFT_OCT(w,x,y,z) umax_oct((uintmax_t)w,x,y,z)
|
|
||||||
#define STRTOOFFT(x,y,z) strtoimax(x,y,z)
|
|
||||||
#define OFFT_MAX INTMAX_MAX
|
|
||||||
|
|
||||||
#define TOP_HALF 0xffffffff00000000ULL
|
|
||||||
#define BOTTOM_HALF 0x00000000ffffffffULL
|
|
||||||
|
|
||||||
|
|
@ -1,617 +0,0 @@
|
||||||
/* $NetBSD: sel_subs.c,v 1.24 2011/08/31 16:24:54 plunky Exp $ */
|
|
||||||
|
|
||||||
/*-
|
|
||||||
* Copyright (c) 1992 Keith Muller.
|
|
||||||
* Copyright (c) 1992, 1993
|
|
||||||
* The Regents of the University of California. All rights reserved.
|
|
||||||
*
|
|
||||||
* This code is derived from software contributed to Berkeley by
|
|
||||||
* Keith Muller of the University of California, San Diego.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if HAVE_NBTOOL_CONFIG_H
|
|
||||||
#include "nbtool_config.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
|
||||||
#if !defined(lint)
|
|
||||||
#if 0
|
|
||||||
static char sccsid[] = "@(#)sel_subs.c 8.1 (Berkeley) 5/31/93";
|
|
||||||
#else
|
|
||||||
__RCSID("$NetBSD: sel_subs.c,v 1.24 2011/08/31 16:24:54 plunky Exp $");
|
|
||||||
#endif
|
|
||||||
#endif /* not lint */
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/time.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/param.h>
|
|
||||||
|
|
||||||
#include <pwd.h>
|
|
||||||
#include <grp.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <strings.h>
|
|
||||||
#include <time.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <tzfile.h>
|
|
||||||
|
|
||||||
#include "pax.h"
|
|
||||||
#include "sel_subs.h"
|
|
||||||
#include "extern.h"
|
|
||||||
|
|
||||||
static int str_sec(const char *, time_t *);
|
|
||||||
static int usr_match(ARCHD *);
|
|
||||||
static int grp_match(ARCHD *);
|
|
||||||
static int trng_match(ARCHD *);
|
|
||||||
|
|
||||||
static TIME_RNG *trhead = NULL; /* time range list head */
|
|
||||||
static TIME_RNG *trtail = NULL; /* time range list tail */
|
|
||||||
static USRT **usrtb = NULL; /* user selection table */
|
|
||||||
static GRPT **grptb = NULL; /* group selection table */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Routines for selection of archive members
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* sel_chk()
|
|
||||||
* check if this file matches a specified uid, gid or time range
|
|
||||||
* Return:
|
|
||||||
* 0 if this archive member should be processed, 1 if it should be skipped
|
|
||||||
*/
|
|
||||||
|
|
||||||
int
|
|
||||||
sel_chk(ARCHD *arcn)
|
|
||||||
{
|
|
||||||
if (((usrtb != NULL) && usr_match(arcn)) ||
|
|
||||||
((grptb != NULL) && grp_match(arcn)) ||
|
|
||||||
((trhead != NULL) && trng_match(arcn)))
|
|
||||||
return 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* User/group selection routines
|
|
||||||
*
|
|
||||||
* Routines to handle user selection of files based on the file uid/gid. To
|
|
||||||
* add an entry, the user supplies either the name or the uid/gid starting with
|
|
||||||
* a # on the command line. A \# will escape the #.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* usr_add()
|
|
||||||
* add a user match to the user match hash table
|
|
||||||
* Return:
|
|
||||||
* 0 if added ok, -1 otherwise;
|
|
||||||
*/
|
|
||||||
|
|
||||||
int
|
|
||||||
usr_add(char *str)
|
|
||||||
{
|
|
||||||
u_int indx;
|
|
||||||
USRT *pt;
|
|
||||||
struct passwd *pw;
|
|
||||||
uid_t uid;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* create the table if it doesn't exist
|
|
||||||
*/
|
|
||||||
if ((str == NULL) || (*str == '\0'))
|
|
||||||
return -1;
|
|
||||||
if ((usrtb == NULL) &&
|
|
||||||
((usrtb = (USRT **)calloc(USR_TB_SZ, sizeof(USRT *))) == NULL)) {
|
|
||||||
tty_warn(1,
|
|
||||||
"Unable to allocate memory for user selection table");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* figure out user spec
|
|
||||||
*/
|
|
||||||
if (str[0] != '#') {
|
|
||||||
/*
|
|
||||||
* it is a user name, \# escapes # as first char in user name
|
|
||||||
*/
|
|
||||||
if ((str[0] == '\\') && (str[1] == '#'))
|
|
||||||
++str;
|
|
||||||
if ((pw = getpwnam(str)) == NULL) {
|
|
||||||
tty_warn(1, "Unable to find uid for user: %s", str);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
uid = (uid_t)pw->pw_uid;
|
|
||||||
} else
|
|
||||||
uid = (uid_t)strtoul(str+1, NULL, 10);
|
|
||||||
endpwent();
|
|
||||||
|
|
||||||
/*
|
|
||||||
* hash it and go down the hash chain (if any) looking for it
|
|
||||||
*/
|
|
||||||
indx = ((unsigned)uid) % USR_TB_SZ;
|
|
||||||
if ((pt = usrtb[indx]) != NULL) {
|
|
||||||
while (pt != NULL) {
|
|
||||||
if (pt->uid == uid)
|
|
||||||
return 0;
|
|
||||||
pt = pt->fow;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* uid is not yet in the table, add it to the front of the chain
|
|
||||||
*/
|
|
||||||
if ((pt = (USRT *)malloc(sizeof(USRT))) != NULL) {
|
|
||||||
pt->uid = uid;
|
|
||||||
pt->fow = usrtb[indx];
|
|
||||||
usrtb[indx] = pt;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
tty_warn(1, "User selection table out of memory");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* usr_match()
|
|
||||||
* check if this files uid matches a selected uid.
|
|
||||||
* Return:
|
|
||||||
* 0 if this archive member should be processed, 1 if it should be skipped
|
|
||||||
*/
|
|
||||||
|
|
||||||
static int
|
|
||||||
usr_match(ARCHD *arcn)
|
|
||||||
{
|
|
||||||
USRT *pt;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* hash and look for it in the table
|
|
||||||
*/
|
|
||||||
pt = usrtb[((unsigned)arcn->sb.st_uid) % USR_TB_SZ];
|
|
||||||
while (pt != NULL) {
|
|
||||||
if (pt->uid == arcn->sb.st_uid)
|
|
||||||
return 0;
|
|
||||||
pt = pt->fow;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* not found
|
|
||||||
*/
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* grp_add()
|
|
||||||
* add a group match to the group match hash table
|
|
||||||
* Return:
|
|
||||||
* 0 if added ok, -1 otherwise;
|
|
||||||
*/
|
|
||||||
|
|
||||||
int
|
|
||||||
grp_add(char *str)
|
|
||||||
{
|
|
||||||
u_int indx;
|
|
||||||
GRPT *pt;
|
|
||||||
struct group *gr;
|
|
||||||
gid_t gid;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* create the table if it doesn't exist
|
|
||||||
*/
|
|
||||||
if ((str == NULL) || (*str == '\0'))
|
|
||||||
return -1;
|
|
||||||
if ((grptb == NULL) &&
|
|
||||||
((grptb = (GRPT **)calloc(GRP_TB_SZ, sizeof(GRPT *))) == NULL)) {
|
|
||||||
tty_warn(1,
|
|
||||||
"Unable to allocate memory fo group selection table");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* figure out user spec
|
|
||||||
*/
|
|
||||||
if (str[0] != '#') {
|
|
||||||
/*
|
|
||||||
* it is a group name, \# escapes # as first char in group name
|
|
||||||
*/
|
|
||||||
if ((str[0] == '\\') && (str[1] == '#'))
|
|
||||||
++str;
|
|
||||||
if ((gr = getgrnam(str)) == NULL) {
|
|
||||||
tty_warn(1,
|
|
||||||
"Cannot determine gid for group name: %s", str);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
gid = (gid_t)gr->gr_gid;
|
|
||||||
} else
|
|
||||||
gid = (gid_t)strtoul(str+1, NULL, 10);
|
|
||||||
endgrent();
|
|
||||||
|
|
||||||
/*
|
|
||||||
* hash it and go down the hash chain (if any) looking for it
|
|
||||||
*/
|
|
||||||
indx = ((unsigned)gid) % GRP_TB_SZ;
|
|
||||||
if ((pt = grptb[indx]) != NULL) {
|
|
||||||
while (pt != NULL) {
|
|
||||||
if (pt->gid == gid)
|
|
||||||
return 0;
|
|
||||||
pt = pt->fow;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* gid not in the table, add it to the front of the chain
|
|
||||||
*/
|
|
||||||
if ((pt = (GRPT *)malloc(sizeof(GRPT))) != NULL) {
|
|
||||||
pt->gid = gid;
|
|
||||||
pt->fow = grptb[indx];
|
|
||||||
grptb[indx] = pt;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
tty_warn(1, "Group selection table out of memory");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* grp_match()
|
|
||||||
* check if this files gid matches a selected gid.
|
|
||||||
* Return:
|
|
||||||
* 0 if this archive member should be processed, 1 if it should be skipped
|
|
||||||
*/
|
|
||||||
|
|
||||||
static int
|
|
||||||
grp_match(ARCHD *arcn)
|
|
||||||
{
|
|
||||||
GRPT *pt;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* hash and look for it in the table
|
|
||||||
*/
|
|
||||||
pt = grptb[((unsigned)arcn->sb.st_gid) % GRP_TB_SZ];
|
|
||||||
while (pt != NULL) {
|
|
||||||
if (pt->gid == arcn->sb.st_gid)
|
|
||||||
return 0;
|
|
||||||
pt = pt->fow;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* not found
|
|
||||||
*/
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Time range selection routines
|
|
||||||
*
|
|
||||||
* Routines to handle user selection of files based on the modification and/or
|
|
||||||
* inode change time falling within a specified time range (the non-standard
|
|
||||||
* -T flag). The user may specify any number of different file time ranges.
|
|
||||||
* Time ranges are checked one at a time until a match is found (if at all).
|
|
||||||
* If the file has a mtime (and/or ctime) which lies within one of the time
|
|
||||||
* ranges, the file is selected. Time ranges may have a lower and/or a upper
|
|
||||||
* value. These ranges are inclusive. When no time ranges are supplied to pax
|
|
||||||
* with the -T option, all members in the archive will be selected by the time
|
|
||||||
* range routines. When only a lower range is supplied, only files with a
|
|
||||||
* mtime (and/or ctime) equal to or younger are selected. When only a upper
|
|
||||||
* range is supplied, only files with a mtime (and/or ctime) equal to or older
|
|
||||||
* are selected. When the lower time range is equal to the upper time range,
|
|
||||||
* only files with a mtime (or ctime) of exactly that time are selected.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* trng_add()
|
|
||||||
* add a time range match to the time range list.
|
|
||||||
* This is a non-standard pax option. Lower and upper ranges are in the
|
|
||||||
* format: [yy[mm[dd[hh]]]]mm[.ss] and are comma separated.
|
|
||||||
* Time ranges are based on current time, so 1234 would specify a time of
|
|
||||||
* 12:34 today.
|
|
||||||
* Return:
|
|
||||||
* 0 if the time range was added to the list, -1 otherwise
|
|
||||||
*/
|
|
||||||
|
|
||||||
int
|
|
||||||
trng_add(char *str)
|
|
||||||
{
|
|
||||||
TIME_RNG *pt;
|
|
||||||
char *up_pt = NULL;
|
|
||||||
char *stpt;
|
|
||||||
char *flgpt;
|
|
||||||
int dot = 0;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* throw out the badly formed time ranges
|
|
||||||
*/
|
|
||||||
if ((str == NULL) || (*str == '\0')) {
|
|
||||||
tty_warn(1, "Empty time range string");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* locate optional flags suffix /{cm}.
|
|
||||||
*/
|
|
||||||
if ((flgpt = strrchr(str, '/')) != NULL)
|
|
||||||
*flgpt++ = '\0';
|
|
||||||
|
|
||||||
for (stpt = str; *stpt != '\0'; ++stpt) {
|
|
||||||
if ((*stpt >= '0') && (*stpt <= '9'))
|
|
||||||
continue;
|
|
||||||
if ((*stpt == ',') && (up_pt == NULL)) {
|
|
||||||
*stpt = '\0';
|
|
||||||
up_pt = stpt + 1;
|
|
||||||
dot = 0;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* allow only one dot per range (secs)
|
|
||||||
*/
|
|
||||||
if ((*stpt == '.') && (!dot)) {
|
|
||||||
++dot;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
tty_warn(1, "Improperly specified time range: %s", str);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* allocate space for the time range and store the limits
|
|
||||||
*/
|
|
||||||
if ((pt = malloc(sizeof(TIME_RNG))) == NULL) {
|
|
||||||
tty_warn(1, "Unable to allocate memory for time range");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* by default we only will check file mtime, but user can specify
|
|
||||||
* mtime, ctime (inode change time) or both.
|
|
||||||
*/
|
|
||||||
if ((flgpt == NULL) || (*flgpt == '\0'))
|
|
||||||
pt->flgs = CMPMTME;
|
|
||||||
else {
|
|
||||||
pt->flgs = 0;
|
|
||||||
while (*flgpt != '\0') {
|
|
||||||
switch(*flgpt) {
|
|
||||||
case 'M':
|
|
||||||
case 'm':
|
|
||||||
pt->flgs |= CMPMTME;
|
|
||||||
break;
|
|
||||||
case 'C':
|
|
||||||
case 'c':
|
|
||||||
pt->flgs |= CMPCTME;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
tty_warn(1, "Bad option %c with time range %s",
|
|
||||||
*flgpt, str);
|
|
||||||
free(pt);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
++flgpt;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* start off with the current time
|
|
||||||
*/
|
|
||||||
pt->low_time = pt->high_time = time(NULL);
|
|
||||||
if (*str != '\0') {
|
|
||||||
/*
|
|
||||||
* add lower limit
|
|
||||||
*/
|
|
||||||
if (str_sec(str, &(pt->low_time)) < 0) {
|
|
||||||
tty_warn(1, "Illegal lower time range %s", str);
|
|
||||||
free(pt);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
pt->flgs |= HASLOW;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((up_pt != NULL) && (*up_pt != '\0')) {
|
|
||||||
/*
|
|
||||||
* add upper limit
|
|
||||||
*/
|
|
||||||
if (str_sec(up_pt, &(pt->high_time)) < 0) {
|
|
||||||
tty_warn(1, "Illegal upper time range %s", up_pt);
|
|
||||||
free(pt);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
pt->flgs |= HASHIGH;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* check that the upper and lower do not overlap
|
|
||||||
*/
|
|
||||||
if (pt->flgs & HASLOW) {
|
|
||||||
if (pt->low_time > pt->high_time) {
|
|
||||||
tty_warn(1,
|
|
||||||
"Upper %s and lower %s time overlap",
|
|
||||||
up_pt, str);
|
|
||||||
free(pt);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pt->fow = NULL;
|
|
||||||
if (trhead == NULL) {
|
|
||||||
trtail = trhead = pt;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
trtail->fow = pt;
|
|
||||||
trtail = pt;
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
out:
|
|
||||||
tty_warn(1, "Time range format is: [yy[mm[dd[hh]]]]mm[.ss][/[c][m]]");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* trng_match()
|
|
||||||
* check if this files mtime/ctime falls within any supplied time range.
|
|
||||||
* Return:
|
|
||||||
* 0 if this archive member should be processed, 1 if it should be skipped
|
|
||||||
*/
|
|
||||||
|
|
||||||
static int
|
|
||||||
trng_match(ARCHD *arcn)
|
|
||||||
{
|
|
||||||
TIME_RNG *pt;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* have to search down the list one at a time looking for a match.
|
|
||||||
* remember time range limits are inclusive.
|
|
||||||
*/
|
|
||||||
pt = trhead;
|
|
||||||
while (pt != NULL) {
|
|
||||||
switch(pt->flgs & CMPBOTH) {
|
|
||||||
case CMPBOTH:
|
|
||||||
/*
|
|
||||||
* user wants both mtime and ctime checked for this
|
|
||||||
* time range
|
|
||||||
*/
|
|
||||||
if (((pt->flgs & HASLOW) &&
|
|
||||||
(arcn->sb.st_mtime < pt->low_time) &&
|
|
||||||
(arcn->sb.st_ctime < pt->low_time)) ||
|
|
||||||
((pt->flgs & HASHIGH) &&
|
|
||||||
(arcn->sb.st_mtime > pt->high_time) &&
|
|
||||||
(arcn->sb.st_ctime > pt->high_time))) {
|
|
||||||
pt = pt->fow;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case CMPCTME:
|
|
||||||
/*
|
|
||||||
* user wants only ctime checked for this time range
|
|
||||||
*/
|
|
||||||
if (((pt->flgs & HASLOW) &&
|
|
||||||
(arcn->sb.st_ctime < pt->low_time)) ||
|
|
||||||
((pt->flgs & HASHIGH) &&
|
|
||||||
(arcn->sb.st_ctime > pt->high_time))) {
|
|
||||||
pt = pt->fow;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case CMPMTME:
|
|
||||||
default:
|
|
||||||
/*
|
|
||||||
* user wants only mtime checked for this time range
|
|
||||||
*/
|
|
||||||
if (((pt->flgs & HASLOW) &&
|
|
||||||
(arcn->sb.st_mtime < pt->low_time)) ||
|
|
||||||
((pt->flgs & HASHIGH) &&
|
|
||||||
(arcn->sb.st_mtime > pt->high_time))) {
|
|
||||||
pt = pt->fow;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pt == NULL)
|
|
||||||
return 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* str_sec()
|
|
||||||
* Convert a time string in the format of [yy[mm[dd[hh]]]]mm[.ss] to gmt
|
|
||||||
* seconds. Tval already has current time loaded into it at entry.
|
|
||||||
* Return:
|
|
||||||
* 0 if converted ok, -1 otherwise
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define ATOI2(s) ((s) += 2, ((s)[-2] - '0') * 10 + ((s)[-1] - '0'))
|
|
||||||
|
|
||||||
static int
|
|
||||||
str_sec(const char *p, time_t *tval)
|
|
||||||
{
|
|
||||||
struct tm *lt;
|
|
||||||
const char *dot, *t;
|
|
||||||
int yearset, len;
|
|
||||||
|
|
||||||
for (t = p, dot = NULL; *t; ++t) {
|
|
||||||
if (isdigit((unsigned char)*t))
|
|
||||||
continue;
|
|
||||||
if (*t == '.' && dot == NULL) {
|
|
||||||
dot = t;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
lt = localtime(tval);
|
|
||||||
|
|
||||||
if (dot != NULL) {
|
|
||||||
len = strlen(dot);
|
|
||||||
if (len != 3)
|
|
||||||
return -1;
|
|
||||||
++dot;
|
|
||||||
lt->tm_sec = ATOI2(dot);
|
|
||||||
} else {
|
|
||||||
len = 0;
|
|
||||||
lt->tm_sec = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
yearset = 0;
|
|
||||||
switch (strlen(p) - len) {
|
|
||||||
case 12:
|
|
||||||
lt->tm_year = ATOI2(p) * 100 - TM_YEAR_BASE;
|
|
||||||
yearset = 1;
|
|
||||||
/* FALLTHROUGH */
|
|
||||||
case 10:
|
|
||||||
if (yearset) {
|
|
||||||
lt->tm_year += ATOI2(p);
|
|
||||||
} else {
|
|
||||||
yearset = ATOI2(p);
|
|
||||||
if (yearset < 69)
|
|
||||||
lt->tm_year = yearset + 2000 - TM_YEAR_BASE;
|
|
||||||
else
|
|
||||||
lt->tm_year = yearset + 1900 - TM_YEAR_BASE;
|
|
||||||
}
|
|
||||||
/* FALLTHROUGH */
|
|
||||||
case 8:
|
|
||||||
lt->tm_mon = ATOI2(p);
|
|
||||||
--lt->tm_mon;
|
|
||||||
/* FALLTHROUGH */
|
|
||||||
case 6:
|
|
||||||
lt->tm_mday = ATOI2(p);
|
|
||||||
/* FALLTHROUGH */
|
|
||||||
case 4:
|
|
||||||
lt->tm_hour = ATOI2(p);
|
|
||||||
/* FALLTHROUGH */
|
|
||||||
case 2:
|
|
||||||
lt->tm_min = ATOI2(p);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* convert broken-down time to GMT clock time seconds
|
|
||||||
*/
|
|
||||||
if ((*tval = mktime(lt)) == -1)
|
|
||||||
return -1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
@ -1,69 +0,0 @@
|
||||||
/* $NetBSD: sel_subs.h,v 1.6 2003/10/13 07:41:22 agc Exp $ */
|
|
||||||
|
|
||||||
/*-
|
|
||||||
* Copyright (c) 1992 Keith Muller.
|
|
||||||
* Copyright (c) 1992, 1993
|
|
||||||
* The Regents of the University of California. All rights reserved.
|
|
||||||
*
|
|
||||||
* This code is derived from software contributed to Berkeley by
|
|
||||||
* Keith Muller of the University of California, San Diego.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* @(#)sel_subs.h 8.1 (Berkeley) 5/31/93
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* data structure for storing uid/grp selects (-U, -G non standard options)
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define USR_TB_SZ 317 /* user selection table size */
|
|
||||||
#define GRP_TB_SZ 317 /* user selection table size */
|
|
||||||
|
|
||||||
typedef struct usrt {
|
|
||||||
uid_t uid;
|
|
||||||
struct usrt *fow; /* next uid */
|
|
||||||
} USRT;
|
|
||||||
|
|
||||||
typedef struct grpt {
|
|
||||||
gid_t gid;
|
|
||||||
struct grpt *fow; /* next gid */
|
|
||||||
} GRPT;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* data structure for storing user supplied time ranges (-T option)
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef struct time_rng {
|
|
||||||
time_t low_time; /* lower inclusive time limit */
|
|
||||||
time_t high_time; /* higher inclusive time limit */
|
|
||||||
int flgs; /* option flags */
|
|
||||||
#define HASLOW 0x01 /* has lower time limit */
|
|
||||||
#define HASHIGH 0x02 /* has higher time limit */
|
|
||||||
#define CMPMTME 0x04 /* compare file modification time */
|
|
||||||
#define CMPCTME 0x08 /* compare inode change time */
|
|
||||||
#define CMPBOTH (CMPMTME|CMPCTME) /* compare inode and mod time */
|
|
||||||
struct time_rng *fow; /* next pattern */
|
|
||||||
} TIME_RNG;
|
|
||||||
1379
bin/pax/tables.c
1379
bin/pax/tables.c
File diff suppressed because it is too large
Load Diff
176
bin/pax/tables.h
176
bin/pax/tables.h
|
|
@ -1,176 +0,0 @@
|
||||||
/* $NetBSD: tables.h,v 1.10 2007/04/29 20:23:34 msaitoh Exp $ */
|
|
||||||
|
|
||||||
/*-
|
|
||||||
* Copyright (c) 1992 Keith Muller.
|
|
||||||
* Copyright (c) 1992, 1993
|
|
||||||
* The Regents of the University of California. All rights reserved.
|
|
||||||
*
|
|
||||||
* This code is derived from software contributed to Berkeley by
|
|
||||||
* Keith Muller of the University of California, San Diego.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* @(#)tables.h 8.1 (Berkeley) 5/31/93
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* data structures and constants used by the different databases kept by pax
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Hash Table Sizes MUST BE PRIME, if set too small performance suffers.
|
|
||||||
* Probably safe to expect 500000 inodes per tape. Assuming good key
|
|
||||||
* distribution (inodes) chains of under 50 long (worse case) is ok.
|
|
||||||
*/
|
|
||||||
#define L_TAB_SZ 2503 /* hard link hash table size */
|
|
||||||
#define F_TAB_SZ 50503 /* file time hash table size */
|
|
||||||
#define N_TAB_SZ 541 /* interactive rename hash table */
|
|
||||||
#define D_TAB_SZ 317 /* unique device mapping table */
|
|
||||||
#define A_TAB_SZ 317 /* ftree dir access time reset table */
|
|
||||||
#define MAXKEYLEN 64 /* max number of chars for hash */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* file hard link structure (hashed by dev/ino and chained) used to find the
|
|
||||||
* hard links in a file system or with some archive formats (cpio)
|
|
||||||
*/
|
|
||||||
typedef struct hrdlnk {
|
|
||||||
char *name; /* name of first file seen with this ino/dev */
|
|
||||||
dev_t dev; /* files device number */
|
|
||||||
ino_t ino; /* files inode number */
|
|
||||||
u_long nlink; /* expected link count */
|
|
||||||
struct hrdlnk *fow;
|
|
||||||
} HRDLNK;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Archive write update file time table (the -u, -C flag), hashed by filename.
|
|
||||||
* Filenames are stored in a scratch file at seek offset into the file. The
|
|
||||||
* file time (mod time) and the file name length (for a quick check) are
|
|
||||||
* stored in a hash table node. We were forced to use a scratch file because
|
|
||||||
* with -u, the mtime for every node in the archive must always be available
|
|
||||||
* to compare against (and this data can get REALLY large with big archives).
|
|
||||||
* By being careful to read only when we have a good chance of a match, the
|
|
||||||
* performance loss is not measurable (and the size of the archive we can
|
|
||||||
* handle is greatly increased).
|
|
||||||
*/
|
|
||||||
typedef struct ftm {
|
|
||||||
int namelen; /* file name length */
|
|
||||||
time_t mtime; /* files last modification time */
|
|
||||||
off_t seek; /* location in scratch file */
|
|
||||||
struct ftm *fow;
|
|
||||||
} FTM;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Interactive rename table (-i flag), hashed by orig filename.
|
|
||||||
* We assume this will not be a large table as this mapping data can only be
|
|
||||||
* obtained through interactive input by the user. Nobody is going to type in
|
|
||||||
* changes for 500000 files? We use chaining to resolve collisions.
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef struct namt {
|
|
||||||
char *oname; /* old name */
|
|
||||||
char *nname; /* new name typed in by the user */
|
|
||||||
struct namt *fow;
|
|
||||||
} NAMT;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Unique device mapping tables. Some protocols (e.g. cpio) require that the
|
|
||||||
* <c_dev,c_ino> pair will uniquely identify a file in an archive unless they
|
|
||||||
* are links to the same file. Appending to archives can break this. For those
|
|
||||||
* protocols that have this requirement we map c_dev to a unique value not seen
|
|
||||||
* in the archive when we append. We also try to handle inode truncation with
|
|
||||||
* this table. (When the inode field in the archive header are too small, we
|
|
||||||
* remap the dev on writes to remove accidental collisions).
|
|
||||||
*
|
|
||||||
* The list is hashed by device number using chain collision resolution. Off of
|
|
||||||
* each DEVT are linked the various remaps for this device based on those bits
|
|
||||||
* in the inode which were truncated. For example if we are just remapping to
|
|
||||||
* avoid a device number during an update append, off the DEVT we would have
|
|
||||||
* only a single DLIST that has a truncation id of 0 (no inode bits were
|
|
||||||
* stripped for this device so far). When we spot inode truncation we create
|
|
||||||
* a new mapping based on the set of bits in the inode which were stripped off.
|
|
||||||
* so if the top four bits of the inode are stripped and they have a pattern of
|
|
||||||
* 0110...... (where . are those bits not truncated) we would have a mapping
|
|
||||||
* assigned for all inodes that has the same 0110.... pattern (with this dev
|
|
||||||
* number of course). This keeps the mapping sparse and should be able to store
|
|
||||||
* close to the limit of files which can be represented by the optimal
|
|
||||||
* combination of dev and inode bits, and without creating a fouled up archive.
|
|
||||||
* Note we also remap truncated devs in the same way (an exercise for the
|
|
||||||
* dedicated reader; always wanted to say that...:)
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef struct devt {
|
|
||||||
dev_t dev; /* the orig device number we now have to map */
|
|
||||||
struct devt *fow; /* new device map list */
|
|
||||||
struct dlist *list; /* map list based on inode truncation bits */
|
|
||||||
} DEVT;
|
|
||||||
|
|
||||||
typedef struct dlist {
|
|
||||||
ino_t trunc_bits; /* truncation pattern for a specific map */
|
|
||||||
dev_t dev; /* the new device id we use */
|
|
||||||
struct dlist *fow;
|
|
||||||
} DLIST;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ftree directory access time reset table. When we are done with a
|
|
||||||
* subtree we reset the access and mod time of the directory when the tflag is
|
|
||||||
* set. Not really explicitly specified in the pax spec, but easy and fast to
|
|
||||||
* do (and this may have even been intended in the spec, it is not clear).
|
|
||||||
* table is hashed by inode with chaining.
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef struct atdir {
|
|
||||||
char *name; /* name of directory to reset */
|
|
||||||
dev_t dev; /* dev and inode for fast lookup */
|
|
||||||
ino_t ino;
|
|
||||||
time_t mtime; /* access and mod time to reset to */
|
|
||||||
time_t atime;
|
|
||||||
struct atdir *fow;
|
|
||||||
} ATDIR;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* created directory time and mode storage entry. After pax is finished during
|
|
||||||
* extraction or copy, we must reset directory access modes and times that
|
|
||||||
* may have been modified after creation (they no longer have the specified
|
|
||||||
* times and/or modes). We must reset time in the reverse order of creation,
|
|
||||||
* because entries are added from the top of the file tree to the bottom.
|
|
||||||
* We MUST reset times from leaf to root (it will not work the other
|
|
||||||
* direction). Entries are recorded into a spool file to make reverse
|
|
||||||
* reading faster.
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef struct dirdata {
|
|
||||||
#ifdef DIRS_USE_FILE
|
|
||||||
int nlen; /* length of the directory name (includes \0) */
|
|
||||||
off_t npos; /* position in file where this dir name starts */
|
|
||||||
#else
|
|
||||||
char *name; /* file name */
|
|
||||||
struct dirdata *next;
|
|
||||||
#endif
|
|
||||||
mode_t mode; /* file mode to restore */
|
|
||||||
time_t mtime; /* mtime to set */
|
|
||||||
time_t atime; /* atime to set */
|
|
||||||
long fflags; /* file flags to set */
|
|
||||||
int frc_mode; /* do we force mode settings? */
|
|
||||||
} DIRDATA;
|
|
||||||
359
bin/pax/tar.1
359
bin/pax/tar.1
|
|
@ -1,359 +0,0 @@
|
||||||
.\" $NetBSD: tar.1,v 1.35 2015/04/11 16:22:07 wiz Exp $
|
|
||||||
.\"
|
|
||||||
.\" Copyright (c) 1996 SigmaSoft, Th. Lockert
|
|
||||||
.\" 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 ``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 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.
|
|
||||||
.\"
|
|
||||||
.\" OpenBSD: tar.1,v 1.28 2000/11/09 23:58:56 aaron Exp
|
|
||||||
.\"
|
|
||||||
.Dd April 11, 2015
|
|
||||||
.Dt TAR 1
|
|
||||||
.Os
|
|
||||||
.Sh NAME
|
|
||||||
.Nm tar
|
|
||||||
.Nd tape archiver
|
|
||||||
.Sh SYNOPSIS
|
|
||||||
.Nm tar
|
|
||||||
.Sm off
|
|
||||||
.Oo \&- Oc {crtux} Op Fl 014578befHhJjklmOoPpqSvwXZz
|
|
||||||
.Sm on
|
|
||||||
.Op Ar archive
|
|
||||||
.Op Ar blocksize
|
|
||||||
.\" XXX how to do this right?
|
|
||||||
.Op Fl C Ar directory
|
|
||||||
.Op Fl s Ar replstr
|
|
||||||
.Op Fl T Ar file
|
|
||||||
.Op Ar file ...
|
|
||||||
.Sh DESCRIPTION
|
|
||||||
The
|
|
||||||
.Nm
|
|
||||||
command creates, adds files to, or extracts files from an
|
|
||||||
archive file in
|
|
||||||
.Dq tar
|
|
||||||
format.
|
|
||||||
A tar archive is often stored on a magnetic tape, but can be
|
|
||||||
stored equally well on a floppy, CD-ROM, or in a regular disk file.
|
|
||||||
.Pp
|
|
||||||
One of the following flags must be present:
|
|
||||||
.Bl -tag -width Ar
|
|
||||||
.It Fl c , Fl Fl create
|
|
||||||
Create new archive, or overwrite an existing archive,
|
|
||||||
adding the specified files to it.
|
|
||||||
.It Fl r , Fl Fl append
|
|
||||||
Append the named new files to existing archive.
|
|
||||||
Note that this will only work on media on which an end-of-file mark
|
|
||||||
can be overwritten.
|
|
||||||
.It Fl t , Fl Fl list
|
|
||||||
List contents of archive.
|
|
||||||
If any files are named on the
|
|
||||||
command line, only those files will be listed.
|
|
||||||
.It Fl u , Fl Fl update
|
|
||||||
Alias for
|
|
||||||
.Fl r .
|
|
||||||
.It Fl x , Fl Fl extract , Fl Fl get
|
|
||||||
Extract files from archive.
|
|
||||||
If any files are named on the
|
|
||||||
command line, only those files will be extracted from the
|
|
||||||
archive.
|
|
||||||
If more than one copy of a file exists in the
|
|
||||||
archive, later copies will overwrite earlier copies during
|
|
||||||
extraction.
|
|
||||||
The file mode and modification time are preserved
|
|
||||||
if possible.
|
|
||||||
The file mode is subject to modification by the
|
|
||||||
.Xr umask 2 .
|
|
||||||
.El
|
|
||||||
.Pp
|
|
||||||
In addition to the flags mentioned above, any of the following
|
|
||||||
flags may be used:
|
|
||||||
.Bl -tag -width Ar
|
|
||||||
.It Fl b Ar "blocking factor" , Fl Fl block-size Ar "blocking factor"
|
|
||||||
Set blocking factor to use for the archive.
|
|
||||||
.Nm
|
|
||||||
uses 512 byte blocks.
|
|
||||||
The default is 20, the maximum is 126.
|
|
||||||
Archives with a blocking factor larger 63 violate the
|
|
||||||
.Tn POSIX
|
|
||||||
standard and will not be portable to all systems.
|
|
||||||
.It Fl e
|
|
||||||
Stop after first error.
|
|
||||||
.It Fl f Ar archive , Fl Fl file Ar archive
|
|
||||||
Filename where the archive is stored.
|
|
||||||
Defaults to
|
|
||||||
.Pa /dev/rst0 .
|
|
||||||
If the archive is of the form:
|
|
||||||
.Ar [[user@]host:]file
|
|
||||||
then the archive will be processed using
|
|
||||||
.Xr rmt 8 .
|
|
||||||
.It Fl h , Fl Fl dereference
|
|
||||||
Follow symbolic links as if they were normal files
|
|
||||||
or directories.
|
|
||||||
.It Fl J, Fl Fl xz
|
|
||||||
Compress/decompress archive using
|
|
||||||
.Xr xz 1 .
|
|
||||||
.It Fl j, Fl Fl bzip2, Fl Fl bunzip2
|
|
||||||
Use
|
|
||||||
.Xr bzip2 1
|
|
||||||
for compression of the archive.
|
|
||||||
This option is a GNU extension.
|
|
||||||
.It Fl k , Fl Fl keep-old-files
|
|
||||||
Keep existing files; don't overwrite them from archive.
|
|
||||||
.It Fl l , Fl Fl one-file-system
|
|
||||||
Do not descend across mount points.
|
|
||||||
.\" should be '-X'
|
|
||||||
.It Fl m , Fl Fl modification-time
|
|
||||||
Do not preserve modification time.
|
|
||||||
.It Fl O
|
|
||||||
When creating and appending to an archive, write old-style (non-POSIX) archives.
|
|
||||||
When extracting from an archive, extract to standard output.
|
|
||||||
.It Fl o , Fl Fl portability , Fl Fl old-archive
|
|
||||||
Don't write directory information that the older (V7) style
|
|
||||||
.Nm
|
|
||||||
is unable to decode.
|
|
||||||
This implies the
|
|
||||||
.Fl O
|
|
||||||
flag.
|
|
||||||
.It Fl p , Fl Fl preserve-permissions , Fl Fl preserve
|
|
||||||
Preserve user and group ID as well as file mode regardless of
|
|
||||||
the current
|
|
||||||
.Xr umask 2 .
|
|
||||||
The setuid and setgid bits are only preserved if the user is
|
|
||||||
the superuser.
|
|
||||||
Only meaningful in conjunction with the
|
|
||||||
.Fl x
|
|
||||||
flag.
|
|
||||||
.It Fl q , Fl Fl fast-read
|
|
||||||
Select the first archive member that matches each
|
|
||||||
.Ar pattern
|
|
||||||
operand.
|
|
||||||
No more than one archive member is matched for each
|
|
||||||
.Ar pattern .
|
|
||||||
When members of type directory are matched, the file hierarchy rooted at that
|
|
||||||
directory is also matched.
|
|
||||||
.It Fl S , Fl Fl sparse
|
|
||||||
This flag has no effect as
|
|
||||||
.Nm
|
|
||||||
always generates sparse files.
|
|
||||||
.It Fl s Ar replstr
|
|
||||||
Modify the file or archive member names specified by the
|
|
||||||
.Ar pattern
|
|
||||||
or
|
|
||||||
.Ar file
|
|
||||||
operands according to the substitution expression
|
|
||||||
.Ar replstr ,
|
|
||||||
using the syntax of the
|
|
||||||
.Xr ed 1
|
|
||||||
utility regular expressions.
|
|
||||||
The format of these regular expressions are:
|
|
||||||
.Dl /old/new/[gps]
|
|
||||||
As in
|
|
||||||
.Xr ed 1 ,
|
|
||||||
.Cm old
|
|
||||||
is a basic regular expression and
|
|
||||||
.Cm new
|
|
||||||
can contain an ampersand (\*[Am]), \en (where n is a digit) back-references,
|
|
||||||
or subexpression matching.
|
|
||||||
The
|
|
||||||
.Cm old
|
|
||||||
string may also contain
|
|
||||||
.Aq Dv newline
|
|
||||||
characters.
|
|
||||||
Any non-null character can be used as a delimiter (/ is shown here).
|
|
||||||
Multiple
|
|
||||||
.Fl s
|
|
||||||
expressions can be specified.
|
|
||||||
The expressions are applied in the order they are specified on the
|
|
||||||
command line, terminating with the first successful substitution.
|
|
||||||
The optional trailing
|
|
||||||
.Cm g
|
|
||||||
continues to apply the substitution expression to the pathname substring
|
|
||||||
which starts with the first character following the end of the last successful
|
|
||||||
substitution.
|
|
||||||
The first unsuccessful substitution stops the operation of the
|
|
||||||
.Cm g
|
|
||||||
option.
|
|
||||||
The optional trailing
|
|
||||||
.Cm p
|
|
||||||
will cause the final result of a successful substitution to be written to
|
|
||||||
.Dv standard error
|
|
||||||
in the following format:
|
|
||||||
.Dl \*[Lt]original pathname\*[Gt] \*[Gt]\*[Gt] \*[Lt]new pathname\*[Gt]
|
|
||||||
File or archive member names that substitute to the empty string
|
|
||||||
are not selected and will be skipped.
|
|
||||||
The substitutions are applied by default to the destination hard and symbolic
|
|
||||||
links.
|
|
||||||
The optional trailing
|
|
||||||
.Cm s
|
|
||||||
prevents the substitutions from being performed on symbolic link destinations.
|
|
||||||
.It Fl v
|
|
||||||
Verbose operation mode.
|
|
||||||
.It Fl w , Fl Fl interactive , Fl Fl confirmation
|
|
||||||
Interactively rename files.
|
|
||||||
This option causes
|
|
||||||
.Nm
|
|
||||||
to prompt the user for the filename to use when storing or
|
|
||||||
extracting files in an archive.
|
|
||||||
.It Fl z , Fl Fl gzip , Fl Fl gunzip
|
|
||||||
Compress/decompress archive using
|
|
||||||
.Xr gzip 1 .
|
|
||||||
.It Fl B , Fl Fl read-full-blocks
|
|
||||||
Reassemble small reads into full blocks (For reading from 4.2BSD pipes).
|
|
||||||
.It Fl C Ar directory , Fl Fl directory Ar directory
|
|
||||||
This is a positional argument which sets the working directory for the
|
|
||||||
following files.
|
|
||||||
When extracting, files will be extracted into
|
|
||||||
the specified directory; when creating, the specified files will be matched
|
|
||||||
from the directory.
|
|
||||||
This argument and its parameter may also appear in a file list specified by
|
|
||||||
.Fl T .
|
|
||||||
.It Fl H
|
|
||||||
Only follow symlinks given on command line.
|
|
||||||
.Pp
|
|
||||||
Note SysVr3/i386 picked up ISC/SCO UNIX compatibility which implemented
|
|
||||||
.Dq Fl F Ar file
|
|
||||||
which was defined as obtaining a list of command line switches and files
|
|
||||||
on which to operate from the specified file,
|
|
||||||
but SunOS-5 uses
|
|
||||||
.Dq Fl I Ar file
|
|
||||||
because they use
|
|
||||||
.Sq Fl F
|
|
||||||
to mean something else.
|
|
||||||
We might someday provide SunOS-5 compatibility
|
|
||||||
but it makes little sense to confuse things with ISC/SCO compatibility.
|
|
||||||
.\".It Fl L
|
|
||||||
.\"Do not follow any symlinks (do the opposite of
|
|
||||||
.\".Fl h ).
|
|
||||||
.It Fl P , Fl Fl absolute-paths
|
|
||||||
Do not strip leading slashes
|
|
||||||
.Pq Sq /
|
|
||||||
from pathnames.
|
|
||||||
The default is to strip leading slashes.
|
|
||||||
.It Fl T Ar file , Fl Fl files-from Ar file
|
|
||||||
Read the names of files to archive or extract from the given file, one
|
|
||||||
per line.
|
|
||||||
A line may also specify the positional argument
|
|
||||||
.Dq Fl C Ar directory .
|
|
||||||
.It Fl X Ar file , Fl Fl exclude-from Ar file
|
|
||||||
Exclude files matching the shell glob patterns listed in the given file.
|
|
||||||
.\" exclude should be '-E' and '-X' should be one-file-system
|
|
||||||
.Pp
|
|
||||||
Note that it would be more standard to use this option to mean ``do not
|
|
||||||
cross filesystem mount points.''
|
|
||||||
.It Fl Z , Fl Fl compress , Fl Fl uncompress
|
|
||||||
Compress archive using compress.
|
|
||||||
.It Fl Fl strict
|
|
||||||
Do not enable GNU tar extensions such as long filenames and long link names.
|
|
||||||
.It Fl Fl atime-preserve
|
|
||||||
Preserve file access times.
|
|
||||||
.It Fl Fl chroot
|
|
||||||
.Fn chroot
|
|
||||||
to the current directory before extracting files.
|
|
||||||
Use with
|
|
||||||
.Fl x
|
|
||||||
and
|
|
||||||
.Fl h
|
|
||||||
to make absolute symlinks relative to the current directory.
|
|
||||||
.It Fl Fl unlink
|
|
||||||
Ignored, only accepted for compatibility with other
|
|
||||||
.Nm
|
|
||||||
implementations.
|
|
||||||
.Nm
|
|
||||||
always unlinks files before creating them.
|
|
||||||
.It Fl Fl use-compress-program Ar program
|
|
||||||
Use the named program as the program to decompress the input.
|
|
||||||
.It Fl Fl force-local
|
|
||||||
Do not interpret filenames that contain a
|
|
||||||
.Sq \&:
|
|
||||||
as remote files.
|
|
||||||
.It Fl Fl insecure
|
|
||||||
Normally
|
|
||||||
.Nm
|
|
||||||
ignores filenames that contain
|
|
||||||
.Dq ..
|
|
||||||
as a path component.
|
|
||||||
With this option, files that contain
|
|
||||||
.Dq ..
|
|
||||||
can be processed.
|
|
||||||
.It Fl Fl no-recursion
|
|
||||||
Cause files of type directory being copied or archived, or archive members of
|
|
||||||
type directory being extracted, to match only the directory file or archive
|
|
||||||
member and not the file hierarchy rooted at the directory.
|
|
||||||
.El
|
|
||||||
.Pp
|
|
||||||
The options
|
|
||||||
.Op Fl 014578
|
|
||||||
can be used to select one of the compiled-in backup devices,
|
|
||||||
.Pa /dev/rstN .
|
|
||||||
.Sh FILES
|
|
||||||
.Bl -tag -width "/dev/rst0"
|
|
||||||
.It Pa /dev/rst0
|
|
||||||
default archive name
|
|
||||||
.El
|
|
||||||
.Sh DIAGNOSTICS
|
|
||||||
.Nm
|
|
||||||
will exit with one of the following values:
|
|
||||||
.Bl -tag -width 2n
|
|
||||||
.It 0
|
|
||||||
All files were processed successfully.
|
|
||||||
.It 1
|
|
||||||
An error occurred.
|
|
||||||
.El
|
|
||||||
.Pp
|
|
||||||
Whenever
|
|
||||||
.Nm
|
|
||||||
cannot create a file or a link when extracting an archive or cannot
|
|
||||||
find a file while writing an archive, or cannot preserve the user
|
|
||||||
ID, group ID, file mode, or access and modification times when the
|
|
||||||
.Fl p
|
|
||||||
option is specified, a diagnostic message is written to standard
|
|
||||||
error and a non-zero exit value will be returned, but processing
|
|
||||||
will continue.
|
|
||||||
In the case where
|
|
||||||
.Nm
|
|
||||||
cannot create a link to a file,
|
|
||||||
.Nm
|
|
||||||
will not create a second copy of the file.
|
|
||||||
.Pp
|
|
||||||
If the extraction of a file from an archive is prematurely terminated
|
|
||||||
by a signal or error,
|
|
||||||
.Nm
|
|
||||||
may have only partially extracted the file the user wanted.
|
|
||||||
Additionally, the file modes of extracted files and directories may
|
|
||||||
have incorrect file bits, and the modification and access times may
|
|
||||||
be wrong.
|
|
||||||
.Pp
|
|
||||||
If the creation of an archive is prematurely terminated by a signal
|
|
||||||
or error,
|
|
||||||
.Nm
|
|
||||||
may have only partially created the archive which may violate the
|
|
||||||
specific archive format specification.
|
|
||||||
.Sh SEE ALSO
|
|
||||||
.Xr cpio 1 ,
|
|
||||||
.Xr pax 1
|
|
||||||
.Sh HISTORY
|
|
||||||
A
|
|
||||||
.Nm
|
|
||||||
command first appeared in
|
|
||||||
.At v7 .
|
|
||||||
.Sh AUTHORS
|
|
||||||
.An Keith Muller
|
|
||||||
at the University of California, San Diego.
|
|
||||||
1420
bin/pax/tar.c
1420
bin/pax/tar.c
File diff suppressed because it is too large
Load Diff
154
bin/pax/tar.h
154
bin/pax/tar.h
|
|
@ -1,154 +0,0 @@
|
||||||
/* $NetBSD: tar.h,v 1.10 2013/01/24 17:43:44 christos Exp $ */
|
|
||||||
|
|
||||||
/*-
|
|
||||||
* Copyright (c) 1992 Keith Muller.
|
|
||||||
* Copyright (c) 1992, 1993
|
|
||||||
* The Regents of the University of California. All rights reserved.
|
|
||||||
*
|
|
||||||
* This code is derived from software contributed to Berkeley by
|
|
||||||
* Keith Muller of the University of California, San Diego.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* @(#)tar.h 8.2 (Berkeley) 4/18/94
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* defines and data structures common to all tar formats
|
|
||||||
*/
|
|
||||||
#define CHK_LEN 8 /* length of checksum field */
|
|
||||||
#define TNMSZ 100 /* size of name field */
|
|
||||||
#ifdef _PAX_
|
|
||||||
#define NULLCNT 2 /* number of null blocks in trailer */
|
|
||||||
#define CHK_OFFSET 148 /* start of chksum field */
|
|
||||||
#define BLNKSUM 256L /* sum of checksum field using ' ' */
|
|
||||||
#endif /* _PAX_ */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Values used in typeflag field in all tar formats
|
|
||||||
* (only REGTYPE, LNKTYPE and SYMTYPE are used in old bsd tar headers)
|
|
||||||
*/
|
|
||||||
#define REGTYPE '0' /* Regular File */
|
|
||||||
#define AREGTYPE '\0' /* Regular File */
|
|
||||||
#define LNKTYPE '1' /* Link */
|
|
||||||
#define SYMTYPE '2' /* Symlink */
|
|
||||||
#define CHRTYPE '3' /* Character Special File */
|
|
||||||
#define BLKTYPE '4' /* Block Special File */
|
|
||||||
#define DIRTYPE '5' /* Directory */
|
|
||||||
#define FIFOTYPE '6' /* FIFO */
|
|
||||||
#define CONTTYPE '7' /* high perf file */
|
|
||||||
#define GLOBXTYPE 'g' /* global extended header */
|
|
||||||
#define FILEXTYPE 'x' /* file extended header */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* GNU tar compatibility;
|
|
||||||
*/
|
|
||||||
#define LONGLINKTYPE 'K' /* Long Symlink */
|
|
||||||
#define LONGNAMETYPE 'L' /* Long File */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Mode field encoding of the different file types - values in octal
|
|
||||||
*/
|
|
||||||
#define TSUID 04000 /* Set UID on execution */
|
|
||||||
#define TSGID 02000 /* Set GID on execution */
|
|
||||||
#define TSVTX 01000 /* Reserved */
|
|
||||||
#define TUREAD 00400 /* Read by owner */
|
|
||||||
#define TUWRITE 00200 /* Write by owner */
|
|
||||||
#define TUEXEC 00100 /* Execute/Search by owner */
|
|
||||||
#define TGREAD 00040 /* Read by group */
|
|
||||||
#define TGWRITE 00020 /* Write by group */
|
|
||||||
#define TGEXEC 00010 /* Execute/Search by group */
|
|
||||||
#define TOREAD 00004 /* Read by other */
|
|
||||||
#define TOWRITE 00002 /* Write by other */
|
|
||||||
#define TOEXEC 00001 /* Execute/Search by other */
|
|
||||||
|
|
||||||
#ifdef _PAX_
|
|
||||||
/*
|
|
||||||
* Pad with a bit mask, much faster than doing a mod but only works on powers
|
|
||||||
* of 2. Macro below is for block of 512 bytes.
|
|
||||||
*/
|
|
||||||
#define TAR_PAD(x) ((512 - ((x) & 511)) & 511)
|
|
||||||
#endif /* _PAX_ */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* structure of an old tar header as it appeared in BSD releases
|
|
||||||
*/
|
|
||||||
typedef struct {
|
|
||||||
char name[TNMSZ]; /* name of entry */
|
|
||||||
char mode[8]; /* mode */
|
|
||||||
char uid[8]; /* uid */
|
|
||||||
char gid[8]; /* gid */
|
|
||||||
char size[12]; /* size */
|
|
||||||
char mtime[12]; /* modification time */
|
|
||||||
char chksum[CHK_LEN]; /* checksum */
|
|
||||||
char linkflag; /* norm, hard, or sym. */
|
|
||||||
char linkname[TNMSZ]; /* linked to name */
|
|
||||||
} HD_TAR;
|
|
||||||
|
|
||||||
#ifdef _PAX_
|
|
||||||
/*
|
|
||||||
* -o options for BSD tar to not write directories to the archive
|
|
||||||
*/
|
|
||||||
#define TAR_NODIR "nodir"
|
|
||||||
#define TAR_OPTION "write_opt"
|
|
||||||
|
|
||||||
/*
|
|
||||||
* default device names
|
|
||||||
*/
|
|
||||||
extern char DEV_0[];
|
|
||||||
extern char DEV_1[];
|
|
||||||
extern char DEV_4[];
|
|
||||||
extern char DEV_5[];
|
|
||||||
extern char DEV_7[];
|
|
||||||
extern char DEV_8[];
|
|
||||||
#endif /* _PAX_ */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Data Interchange Format - Extended tar header format - POSIX 1003.1-1990
|
|
||||||
*/
|
|
||||||
#define TPFSZ 155
|
|
||||||
#define TMAGIC "ustar" /* ustar and a null */
|
|
||||||
#define TMAGLEN 6
|
|
||||||
#define TVERSION "00" /* 00 and no null */
|
|
||||||
#define TVERSLEN 2
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
char name[TNMSZ]; /* name of entry */
|
|
||||||
char mode[8]; /* mode */
|
|
||||||
char uid[8]; /* uid */
|
|
||||||
char gid[8]; /* gid */
|
|
||||||
char size[12]; /* size */
|
|
||||||
char mtime[12]; /* modification time */
|
|
||||||
char chksum[CHK_LEN]; /* checksum */
|
|
||||||
char typeflag; /* type of file. */
|
|
||||||
char linkname[TNMSZ]; /* linked to name */
|
|
||||||
char magic[TMAGLEN]; /* magic cookie */
|
|
||||||
char version[TVERSLEN]; /* version */
|
|
||||||
char uname[32]; /* ascii owner name */
|
|
||||||
char gname[32]; /* ascii group name */
|
|
||||||
char devmajor[8]; /* major device number */
|
|
||||||
char devminor[8]; /* minor device number */
|
|
||||||
char prefix[TPFSZ]; /* linked to name */
|
|
||||||
} HD_USTAR;
|
|
||||||
|
|
@ -1,200 +0,0 @@
|
||||||
/* $NetBSD: tty_subs.c,v 1.19 2007/04/23 18:40:22 christos Exp $ */
|
|
||||||
|
|
||||||
/*-
|
|
||||||
* Copyright (c) 1992 Keith Muller.
|
|
||||||
* Copyright (c) 1992, 1993
|
|
||||||
* The Regents of the University of California. All rights reserved.
|
|
||||||
*
|
|
||||||
* This code is derived from software contributed to Berkeley by
|
|
||||||
* Keith Muller of the University of California, San Diego.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if HAVE_NBTOOL_CONFIG_H
|
|
||||||
#include "nbtool_config.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
|
||||||
#if !defined(lint)
|
|
||||||
#if 0
|
|
||||||
static char sccsid[] = "@(#)tty_subs.c 8.2 (Berkeley) 4/18/94";
|
|
||||||
#else
|
|
||||||
__RCSID("$NetBSD: tty_subs.c,v 1.19 2007/04/23 18:40:22 christos Exp $");
|
|
||||||
#endif
|
|
||||||
#endif /* not lint */
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/time.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/param.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include "pax.h"
|
|
||||||
#include "extern.h"
|
|
||||||
#include <stdarg.h>
|
|
||||||
|
|
||||||
/*
|
|
||||||
* routines that deal with I/O to and from the user
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define DEVTTY "/dev/tty" /* device for interactive i/o */
|
|
||||||
static FILE *ttyoutf = NULL; /* output pointing at control tty */
|
|
||||||
static FILE *ttyinf = NULL; /* input pointing at control tty */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* tty_init()
|
|
||||||
* Try to open the controlling terminal (if any) for this process. If the
|
|
||||||
* open fails, future ops that require user input will get an EOF.
|
|
||||||
*/
|
|
||||||
|
|
||||||
int
|
|
||||||
tty_init(void)
|
|
||||||
{
|
|
||||||
int ttyfd;
|
|
||||||
|
|
||||||
if ((ttyfd = open(DEVTTY, O_RDWR)) >= 0) {
|
|
||||||
if ((ttyoutf = fdopen(ttyfd, "w")) != NULL) {
|
|
||||||
if ((ttyinf = fdopen(ttyfd, "r")) != NULL)
|
|
||||||
return 0;
|
|
||||||
(void)fclose(ttyoutf);
|
|
||||||
}
|
|
||||||
(void)close(ttyfd);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (iflag) {
|
|
||||||
tty_warn(1, "Fatal error, cannot open %s", DEVTTY);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* tty_prnt()
|
|
||||||
* print a message using the specified format to the controlling tty
|
|
||||||
* if there is no controlling terminal, just return.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void
|
|
||||||
tty_prnt(const char *fmt, ...)
|
|
||||||
{
|
|
||||||
va_list ap;
|
|
||||||
if (ttyoutf == NULL)
|
|
||||||
return;
|
|
||||||
va_start(ap, fmt);
|
|
||||||
(void)vfprintf(ttyoutf, fmt, ap);
|
|
||||||
va_end(ap);
|
|
||||||
(void)fflush(ttyoutf);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* tty_read()
|
|
||||||
* read a string from the controlling terminal if it is open into the
|
|
||||||
* supplied buffer
|
|
||||||
* Return:
|
|
||||||
* 0 if data was read, -1 otherwise.
|
|
||||||
*/
|
|
||||||
|
|
||||||
int
|
|
||||||
tty_read(char *str, int len)
|
|
||||||
{
|
|
||||||
char *pt;
|
|
||||||
|
|
||||||
if ((--len <= 0) || (ttyinf == NULL) || (fgets(str,len,ttyinf) == NULL))
|
|
||||||
return -1;
|
|
||||||
*(str + len) = '\0';
|
|
||||||
|
|
||||||
/*
|
|
||||||
* strip off that trailing newline
|
|
||||||
*/
|
|
||||||
if ((pt = strchr(str, '\n')) != NULL)
|
|
||||||
*pt = '\0';
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* tty_warn()
|
|
||||||
* write a warning message to stderr. if "set" the exit value of pax
|
|
||||||
* will be non-zero.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void
|
|
||||||
tty_warn(int set, const char *fmt, ...)
|
|
||||||
{
|
|
||||||
va_list ap;
|
|
||||||
va_start(ap, fmt);
|
|
||||||
if (set)
|
|
||||||
exit_val = 1;
|
|
||||||
/*
|
|
||||||
* when vflag we better ship out an extra \n to get this message on a
|
|
||||||
* line by itself
|
|
||||||
*/
|
|
||||||
if ((Vflag || vflag) && vfpart) {
|
|
||||||
(void)fputc('\n', stderr);
|
|
||||||
vfpart = 0;
|
|
||||||
}
|
|
||||||
(void)fprintf(stderr, "%s: ", argv0);
|
|
||||||
(void)vfprintf(stderr, fmt, ap);
|
|
||||||
va_end(ap);
|
|
||||||
(void)fputc('\n', stderr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* syswarn()
|
|
||||||
* write a warning message to stderr. if "set" the exit value of pax
|
|
||||||
* will be non-zero.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void
|
|
||||||
syswarn(int set, int errnum, const char *fmt, ...)
|
|
||||||
{
|
|
||||||
va_list ap;
|
|
||||||
va_start(ap, fmt);
|
|
||||||
if (set)
|
|
||||||
exit_val = 1;
|
|
||||||
/*
|
|
||||||
* when vflag we better ship out an extra \n to get this message on a
|
|
||||||
* line by itself
|
|
||||||
*/
|
|
||||||
if ((Vflag || vflag) && vfpart) {
|
|
||||||
(void)fputc('\n', stdout);
|
|
||||||
vfpart = 0;
|
|
||||||
}
|
|
||||||
(void)fprintf(stderr, "%s: ", argv0);
|
|
||||||
(void)vfprintf(stderr, fmt, ap);
|
|
||||||
va_end(ap);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* format and print the errno
|
|
||||||
*/
|
|
||||||
if (errnum > 0)
|
|
||||||
(void)fprintf(stderr, " (%s)", strerror(errnum));
|
|
||||||
(void)fputc('\n', stderr);
|
|
||||||
}
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
# $NetBSD: Makefile,v 1.8 1997/07/20 22:37:41 christos Exp $
|
|
||||||
# @(#)Makefile 8.1 (Berkeley) 5/31/93
|
|
||||||
|
|
||||||
PROG= pwd
|
|
||||||
|
|
||||||
.include <bsd.prog.mk>
|
|
||||||
112
bin/pwd/pwd.1
112
bin/pwd/pwd.1
|
|
@ -1,112 +0,0 @@
|
||||||
.\" $NetBSD: pwd.1,v 1.25 2016/08/12 02:03:26 sevan Exp $
|
|
||||||
.\"
|
|
||||||
.\" Copyright (c) 1990, 1993
|
|
||||||
.\" The Regents of the University of California. All rights reserved.
|
|
||||||
.\"
|
|
||||||
.\" This code is derived from software contributed to Berkeley by
|
|
||||||
.\" the Institute of Electrical and Electronics Engineers, Inc.
|
|
||||||
.\"
|
|
||||||
.\" 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.
|
|
||||||
.\"
|
|
||||||
.\" @(#)pwd.1 8.2 (Berkeley) 4/28/95
|
|
||||||
.\"
|
|
||||||
.Dd August 12, 2016
|
|
||||||
.Dt PWD 1
|
|
||||||
.Os
|
|
||||||
.Sh NAME
|
|
||||||
.Nm pwd
|
|
||||||
.Nd return working directory name
|
|
||||||
.Sh SYNOPSIS
|
|
||||||
.Nm
|
|
||||||
.Op Fl LP
|
|
||||||
.Sh DESCRIPTION
|
|
||||||
.Nm
|
|
||||||
writes the absolute pathname of the current working directory to
|
|
||||||
the standard output.
|
|
||||||
.Pp
|
|
||||||
The following options are available:
|
|
||||||
.Bl -tag -width indent
|
|
||||||
.It Fl L
|
|
||||||
If the
|
|
||||||
.Ev PWD
|
|
||||||
environment variable is an absolute pathname that contains
|
|
||||||
neither "/./" nor "/../" and references the current directory, then
|
|
||||||
.Ev PWD
|
|
||||||
is assumed to be the name of the current directory.
|
|
||||||
.It Fl P
|
|
||||||
Print the physical path to the current working directory, with symbolic
|
|
||||||
links in the path resolved.
|
|
||||||
.El
|
|
||||||
.Pp
|
|
||||||
The default for the
|
|
||||||
.Nm
|
|
||||||
command is
|
|
||||||
.Fl P .
|
|
||||||
.Pp
|
|
||||||
.Nm
|
|
||||||
is usually provided as a shell builtin (which may have a different
|
|
||||||
default).
|
|
||||||
.Sh EXIT STATUS
|
|
||||||
The
|
|
||||||
.Nm
|
|
||||||
utility exits 0 on success, and \*[Gt]0 if an error occurs.
|
|
||||||
.Sh SEE ALSO
|
|
||||||
.Xr cd 1 ,
|
|
||||||
.Xr csh 1 ,
|
|
||||||
.Xr ksh 1 ,
|
|
||||||
.Xr sh 1 ,
|
|
||||||
.Xr getcwd 3
|
|
||||||
.Sh STANDARDS
|
|
||||||
The
|
|
||||||
.Nm
|
|
||||||
utility is expected to be conforming to
|
|
||||||
.St -p1003.1 ,
|
|
||||||
except that the default is
|
|
||||||
.Fl P
|
|
||||||
not
|
|
||||||
.Fl L .
|
|
||||||
.Sh HISTORY
|
|
||||||
A
|
|
||||||
.Nm
|
|
||||||
utility appeared in
|
|
||||||
.At v5 .
|
|
||||||
.Sh BUGS
|
|
||||||
In
|
|
||||||
.Xr csh 1
|
|
||||||
the command
|
|
||||||
.Ic dirs
|
|
||||||
is always faster (although it can give a different answer in the rare case
|
|
||||||
that the current directory or a containing directory was moved after
|
|
||||||
the shell descended into it).
|
|
||||||
.Pp
|
|
||||||
.Nm
|
|
||||||
.Fl L
|
|
||||||
relies on the file system having unique inode numbers.
|
|
||||||
If this is not true (e.g., on FAT file systems) then
|
|
||||||
.Nm
|
|
||||||
.Fl L
|
|
||||||
may fail to detect that
|
|
||||||
.Ev PWD
|
|
||||||
is incorrect.
|
|
||||||
143
bin/pwd/pwd.c
143
bin/pwd/pwd.c
|
|
@ -1,143 +0,0 @@
|
||||||
/* $NetBSD: pwd.c,v 1.22 2011/08/29 14:51:19 joerg Exp $ */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (c) 1991, 1993, 1994
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
|
||||||
#ifndef lint
|
|
||||||
__COPYRIGHT("@(#) Copyright (c) 1991, 1993, 1994\
|
|
||||||
The Regents of the University of California. All rights reserved.");
|
|
||||||
#endif /* not lint */
|
|
||||||
|
|
||||||
#ifndef lint
|
|
||||||
#if 0
|
|
||||||
static char sccsid[] = "@(#)pwd.c 8.3 (Berkeley) 4/1/94";
|
|
||||||
#else
|
|
||||||
__RCSID("$NetBSD: pwd.c,v 1.22 2011/08/29 14:51:19 joerg Exp $");
|
|
||||||
#endif
|
|
||||||
#endif /* not lint */
|
|
||||||
|
|
||||||
#include <sys/param.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
|
|
||||||
#include <err.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <locale.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
static char *getcwd_logical(void);
|
|
||||||
__dead static void usage(void);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Note that EEE Std 1003.1, 2003 requires that the default be -L.
|
|
||||||
* This is inconsistent with the historic behaviour of everything
|
|
||||||
* except the ksh builtin.
|
|
||||||
* To avoid breaking scripts the default has been kept as -P.
|
|
||||||
* (Some scripts run /bin/pwd in order to get 'pwd -P'.)
|
|
||||||
*/
|
|
||||||
|
|
||||||
int
|
|
||||||
main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
int ch, lFlag;
|
|
||||||
const char *p;
|
|
||||||
|
|
||||||
setprogname(argv[0]);
|
|
||||||
(void)setlocale(LC_ALL, "");
|
|
||||||
|
|
||||||
lFlag = 0;
|
|
||||||
while ((ch = getopt(argc, argv, "LP")) != -1) {
|
|
||||||
switch (ch) {
|
|
||||||
case 'L':
|
|
||||||
lFlag = 1;
|
|
||||||
break;
|
|
||||||
case 'P':
|
|
||||||
lFlag = 0;
|
|
||||||
break;
|
|
||||||
case '?':
|
|
||||||
default:
|
|
||||||
usage();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
argc -= optind;
|
|
||||||
argv += optind;
|
|
||||||
|
|
||||||
if (argc != 0)
|
|
||||||
usage();
|
|
||||||
|
|
||||||
if (lFlag)
|
|
||||||
p = getcwd_logical();
|
|
||||||
else
|
|
||||||
p = NULL;
|
|
||||||
if (p == NULL)
|
|
||||||
p = getcwd(NULL, 0);
|
|
||||||
|
|
||||||
if (p == NULL)
|
|
||||||
err(EXIT_FAILURE, NULL);
|
|
||||||
|
|
||||||
(void)printf("%s\n", p);
|
|
||||||
|
|
||||||
exit(EXIT_SUCCESS);
|
|
||||||
/* NOTREACHED */
|
|
||||||
}
|
|
||||||
|
|
||||||
static char *
|
|
||||||
getcwd_logical(void)
|
|
||||||
{
|
|
||||||
char *pwd;
|
|
||||||
struct stat s_pwd, s_dot;
|
|
||||||
|
|
||||||
/* Check $PWD -- if it's right, it's fast. */
|
|
||||||
pwd = getenv("PWD");
|
|
||||||
if (pwd == NULL)
|
|
||||||
return NULL;
|
|
||||||
if (pwd[0] != '/')
|
|
||||||
return NULL;
|
|
||||||
if (strstr(pwd, "/./") != NULL)
|
|
||||||
return NULL;
|
|
||||||
if (strstr(pwd, "/../") != NULL)
|
|
||||||
return NULL;
|
|
||||||
if (stat(pwd, &s_pwd) == -1 || stat(".", &s_dot) == -1)
|
|
||||||
return NULL;
|
|
||||||
if (s_pwd.st_dev != s_dot.st_dev || s_pwd.st_ino != s_dot.st_ino)
|
|
||||||
return NULL;
|
|
||||||
return pwd;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
usage(void)
|
|
||||||
{
|
|
||||||
(void)fprintf(stderr, "usage: %s [-LP]\n", getprogname());
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
/* NOTREACHED */
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue
Block a user