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