MFhead@r324482
This commit is contained in:
commit
50896984cd
2
Makefile
2
Makefile
@ -435,7 +435,7 @@ worlds: .PHONY
|
||||
.if make(universe) || make(universe_kernels) || make(tinderbox) || make(targets)
|
||||
TARGETS?=amd64 arm arm64 i386 mips powerpc riscv sparc64
|
||||
_UNIVERSE_TARGETS= ${TARGETS}
|
||||
TARGET_ARCHES_arm?= arm armeb armv6
|
||||
TARGET_ARCHES_arm?= arm armeb armv6 armv7
|
||||
TARGET_ARCHES_arm64?= aarch64
|
||||
TARGET_ARCHES_mips?= mipsel mips mips64el mips64 mipsn32 mipselhf mipshf mips64elhf mips64hf
|
||||
TARGET_ARCHES_powerpc?= powerpc powerpc64 powerpcspe
|
||||
|
@ -398,6 +398,7 @@ KNOWN_ARCHES?= aarch64/arm64 \
|
||||
arm \
|
||||
armeb/arm \
|
||||
armv6/arm \
|
||||
armv7/arm \
|
||||
i386 \
|
||||
mips \
|
||||
mipsel/mips \
|
||||
@ -615,7 +616,7 @@ BFLAGS+= -B${CROSS_BINUTILS_PREFIX}
|
||||
BFLAGS+= -B${WORLDTMP}/usr/bin
|
||||
.endif
|
||||
.if ${TARGET} == "arm"
|
||||
.if ${TARGET_ARCH:Marmv6*} != "" && ${TARGET_CPUTYPE:M*soft*} == ""
|
||||
.if ${TARGET_ARCH:Marmv[67]*} != "" && ${TARGET_CPUTYPE:M*soft*} == ""
|
||||
TARGET_ABI= gnueabihf
|
||||
.else
|
||||
TARGET_ABI= gnueabi
|
||||
@ -651,7 +652,7 @@ XCFLAGS+= ${BFLAGS}
|
||||
${TARGET_ARCH} == "powerpc64" || ${TARGET_ARCH:Mmips64*} != "")
|
||||
LIBCOMPAT= 32
|
||||
.include "Makefile.libcompat"
|
||||
.elif ${MK_LIBSOFT} != "no" && ${TARGET_ARCH} == "armv6"
|
||||
.elif ${MK_LIBSOFT} != "no" && ${TARGET_ARCH:Marmv[67]*} != ""
|
||||
LIBCOMPAT= SOFT
|
||||
.include "Makefile.libcompat"
|
||||
.endif
|
||||
@ -1360,6 +1361,10 @@ BUILDKERNELS+= ${_kernel}
|
||||
.if empty(INSTALLKERNEL) && !defined(NO_INSTALLKERNEL)
|
||||
INSTALLKERNEL= ${_kernel}
|
||||
.endif
|
||||
.else
|
||||
.if make(buildkernel)
|
||||
.error Missing KERNCONF ${KERNCONFDIR}/${_kernel}
|
||||
.endif
|
||||
.endif
|
||||
.endfor
|
||||
|
||||
|
@ -59,10 +59,10 @@ LIB32WMAKEFLAGS+= -DCOMPAT_32BIT
|
||||
|
||||
# -------------------------------------------------------------------
|
||||
# soft-fp world
|
||||
.if ${TARGET_ARCH} == "armv6"
|
||||
.if ${TARGET_ARCH:Marmv[67]*} != ""
|
||||
LIBSOFTCFLAGS= -DCOMPAT_SOFTFP
|
||||
LIBSOFTCPUFLAGS= -mfloat-abi=softfp
|
||||
LIBSOFTWMAKEENV= CPUTYPE=soft MACHINE=arm MACHINE_ARCH=armv6
|
||||
LIBSOFTWMAKEENV= CPUTYPE=soft MACHINE=arm MACHINE_ARCH=${TARGET_ARCH}
|
||||
LIBSOFTWMAKEFLAGS= -DCOMPAT_SOFTFP
|
||||
.endif
|
||||
|
||||
|
@ -38,6 +38,23 @@
|
||||
# xargs -n1 | sort | uniq -d;
|
||||
# done
|
||||
|
||||
# 20161010: Remove libstand
|
||||
OLD_FILES+=usr/lib/libstand.a
|
||||
OLD_FILES+=usr/lib/libstand_p.a
|
||||
OLD_FILES+=usr/include/stand.h
|
||||
OLD_FILES+=usr/share/man/man3/libstand.3
|
||||
# 20171003: remove RCMDS
|
||||
OLD_FILES+=bin/rcp
|
||||
OLD_FILES+=rescue/rcp
|
||||
OLD_FILES+=usr/bin/rlogin
|
||||
OLD_FILES+=usr/bin/rsh
|
||||
OLD_FILES+=usr/libexec/rlogind
|
||||
OLD_FILES+=usr/libexec/rshd
|
||||
OLD_FILES+=usr/share/man/man1/rcp.1.gz
|
||||
OLD_FILES+=usr/share/man/man1/rlogin.1.gz
|
||||
OLD_FILES+=usr/share/man/man1/rsh.1.gz
|
||||
OLD_FILES+=usr/share/man/man8/rlogind.8.gz
|
||||
OLD_FILES+=usr/share/man/man8/rshd.8.gz
|
||||
# 20170927: crshared
|
||||
OLD_FILES+=usr/share/man/man9/crshared.9.gz
|
||||
# 20170927: procctl
|
||||
|
17
UPDATING
17
UPDATING
@ -51,6 +51,23 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 12.x IS SLOW:
|
||||
|
||||
****************************** SPECIAL WARNING: ******************************
|
||||
|
||||
20171010:
|
||||
libstand has turned into a private library for sys/boot use only.
|
||||
It is no longer supported as a public interface outside of sys/boot.
|
||||
|
||||
20171005:
|
||||
The arm port has split armv6 into armv6 and armv7. armv7 is now
|
||||
a valid TARGET_ARCH/MACHINE_ARCH setting. If you have an armv7 system
|
||||
and are running a kernel from before r324363, you will need to add
|
||||
MACHINE_ARCH=armv7 to 'make buildworld' to do a native build.
|
||||
|
||||
20171003:
|
||||
When building multiple kernels using KERNCONF, non-existent KERNCONF
|
||||
files will produce an error and buildkernel will fail. Previously
|
||||
missing KERNCONF files silently failed giving no indication as to
|
||||
why, only to subsequently discover during installkernel that the
|
||||
desired kernel was never built in the first place.
|
||||
|
||||
20170912:
|
||||
The default serial number format for CTL LUNs has changed. This will
|
||||
affect users who use /dev/diskid/* device nodes, or whose FibreChannel
|
||||
|
@ -40,7 +40,6 @@ SUBDIR= cat \
|
||||
test \
|
||||
uuidgen
|
||||
|
||||
SUBDIR.${MK_RCMDS}+= rcp
|
||||
SUBDIR.${MK_SENDMAIL}+= rmail
|
||||
SUBDIR.${MK_TCSH}+= csh
|
||||
SUBDIR.${MK_TESTS}+= tests
|
||||
|
@ -199,7 +199,8 @@ static VAR var[] = {
|
||||
{"tdaddr", "TDADDR", NULL, "thread-address", 0, kvar, KOFF(ki_tdaddr),
|
||||
KPTR, "lx", 0},
|
||||
{"tdev", "TDEV", NULL, "terminal-device", 0, tdev, 0, CHAR, NULL, 0},
|
||||
{"tdnam", "TDNAM", NULL, "terminal-device-name", LJUST, tdnam, 0, CHAR,
|
||||
{"tdnam", "", "tdname", NULL, 0, NULL, 0, CHAR, NULL, 0},
|
||||
{"tdname", "TDNAME", NULL, "thread-name", LJUST, tdnam, 0, CHAR,
|
||||
NULL, 0},
|
||||
{"time", "TIME", NULL, "cpu-time", USER, cputime, 0, CHAR, NULL, 0},
|
||||
{"tpgid", "TPGID", NULL, "terminal-process-gid", 0, kvar,
|
||||
|
@ -29,7 +29,7 @@
|
||||
.\" @(#)ps.1 8.3 (Berkeley) 4/18/94
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd September 7, 2017
|
||||
.Dd October 9, 2017
|
||||
.Dt PS 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -675,6 +675,8 @@ saved UID from a setuid executable
|
||||
accumulated system CPU time
|
||||
.It Cm tdaddr
|
||||
thread address
|
||||
.It Cm tdname
|
||||
thread name
|
||||
.It Cm tdev
|
||||
control terminal device number
|
||||
.It Cm time
|
||||
|
@ -523,7 +523,11 @@ main(int argc, char *argv[])
|
||||
*/
|
||||
nentries = -1;
|
||||
kp = kvm_getprocs(kd, what, flag, &nentries);
|
||||
if ((kp == NULL && nentries > 0) || (kp != NULL && nentries < 0))
|
||||
/*
|
||||
* Ignore ESRCH to preserve behaviour of "ps -p nonexistent-pid"
|
||||
* not reporting an error.
|
||||
*/
|
||||
if ((kp == NULL && errno != ESRCH) || (kp != NULL && nentries < 0))
|
||||
xo_errx(1, "%s", kvm_geterr(kd));
|
||||
nkept = 0;
|
||||
if (nentries > 0) {
|
||||
|
@ -1,19 +0,0 @@
|
||||
# @(#)Makefile 8.1 (Berkeley) 7/19/93
|
||||
# $FreeBSD$
|
||||
|
||||
.include <src.opts.mk>
|
||||
|
||||
PACKAGE=rcmds
|
||||
PROG= rcp
|
||||
SRCS= rcp.c util.c
|
||||
CFLAGS+=-DBINDIR=${BINDIR}
|
||||
|
||||
PACKAGE=rcmds
|
||||
|
||||
BINOWN= root
|
||||
BINMODE=4555
|
||||
|
||||
HAS_TESTS=
|
||||
SUBDIR.${MK_TESTS}+= tests
|
||||
|
||||
.include <bsd.prog.mk>
|
@ -1,18 +0,0 @@
|
||||
# $FreeBSD$
|
||||
# Autogenerated - do NOT edit!
|
||||
|
||||
DIRDEPS = \
|
||||
gnu/lib/csu \
|
||||
gnu/lib/libgcc \
|
||||
include \
|
||||
include/xlocale \
|
||||
lib/${CSU_DIR} \
|
||||
lib/libc \
|
||||
lib/libcompiler_rt \
|
||||
|
||||
|
||||
.include <dirdeps.mk>
|
||||
|
||||
.if ${DEP_RELDIR} == ${_DEP_RELDIR}
|
||||
# local dependencies - needed for -jN in clean tree
|
||||
.endif
|
@ -1,47 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 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.
|
||||
*
|
||||
* @(#)extern.h 8.1 (Berkeley) 5/31/93
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
size_t cnt;
|
||||
char *buf;
|
||||
} BUF;
|
||||
|
||||
extern int iamremote;
|
||||
|
||||
BUF *allocbuf(BUF *, int, int);
|
||||
char *colon(char *);
|
||||
void lostconn(int);
|
||||
void nospace(void);
|
||||
int okname(char *);
|
||||
void run_err(const char *, ...) __printflike(1, 2);
|
||||
int susystem(char *, int);
|
||||
void verifydir(char *);
|
160
bin/rcp/rcp.1
160
bin/rcp/rcp.1
@ -1,160 +0,0 @@
|
||||
.\"-
|
||||
.\" Copyright (c) 1983, 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.
|
||||
.\"
|
||||
.\" @(#)rcp.1 8.1 (Berkeley) 5/31/93
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd July 3, 2017
|
||||
.Dt RCP 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm rcp
|
||||
.Nd remote file copy
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl 46p
|
||||
.Ar file1 file2
|
||||
.Nm
|
||||
.Op Fl 46pr
|
||||
.Ar
|
||||
.Ar directory
|
||||
.Sh DEPRECATION NOTICE
|
||||
.Nm
|
||||
is deprecated and will be removed from future versions of the
|
||||
.Fx
|
||||
base system.
|
||||
If
|
||||
.Nm
|
||||
is still required, it can be installed from ports or packages
|
||||
(net/bsdrcmds).
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
utility copies files between machines.
|
||||
Each
|
||||
.Ar file
|
||||
or
|
||||
.Ar directory
|
||||
argument is either a remote file name of the
|
||||
form
|
||||
.Dq ruser@rhost:path ,
|
||||
or a local file name (containing no
|
||||
.Ql :\&
|
||||
characters,
|
||||
or a
|
||||
.Ql /
|
||||
before any
|
||||
.Ql :\& Ns
|
||||
s).
|
||||
.Pp
|
||||
The following options are available:
|
||||
.Bl -tag -width indent
|
||||
.It Fl 4
|
||||
Use IPv4 addresses only.
|
||||
.It Fl 6
|
||||
Use IPv6 addresses only.
|
||||
.It Fl p
|
||||
Cause
|
||||
.Nm
|
||||
to attempt to preserve (duplicate) in its copies the modification
|
||||
times and modes of the source files, ignoring the
|
||||
.Xr umask 2 .
|
||||
By default, the mode and owner of
|
||||
.Ar file2
|
||||
are preserved if it already existed; otherwise the mode of the source file
|
||||
modified by the
|
||||
.Xr umask 2
|
||||
on the destination host is used.
|
||||
.It Fl r
|
||||
If any of the source files are directories,
|
||||
.Nm
|
||||
copies each subtree rooted at that name; in this case
|
||||
the destination must be a directory.
|
||||
.El
|
||||
.Pp
|
||||
If
|
||||
.Ar path
|
||||
is not a full path name, it is interpreted relative to
|
||||
the login directory of the specified user
|
||||
.Ar ruser
|
||||
on
|
||||
.Ar rhost ,
|
||||
or your current user name if no other remote user name is specified.
|
||||
A
|
||||
.Ar path
|
||||
on a remote host may be quoted (using
|
||||
.Ql \e ,
|
||||
.Ql \&" ,
|
||||
or
|
||||
.Ql \(aa )
|
||||
so that the metacharacters are interpreted remotely.
|
||||
.Pp
|
||||
The
|
||||
.Nm
|
||||
utility does not prompt for passwords; it performs remote execution
|
||||
via
|
||||
.Xr rsh 1 ,
|
||||
and requires the same authorization.
|
||||
.Pp
|
||||
The
|
||||
.Nm
|
||||
utility handles third party copies, where neither source nor target files
|
||||
are on the current machine.
|
||||
.Sh SEE ALSO
|
||||
.Xr cp 1 ,
|
||||
.Xr ftp 1 ,
|
||||
.Xr rlogin 1 ,
|
||||
.Xr rsh 1 ,
|
||||
.Xr hosts.equiv 5
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
command appeared in
|
||||
.Bx 4.2 .
|
||||
The version of
|
||||
.Nm
|
||||
described here
|
||||
has been reimplemented with Kerberos in
|
||||
.Bx 4.3 Reno .
|
||||
.Sh BUGS
|
||||
Does not detect all cases where the target of a copy might
|
||||
be a file in cases where only a directory should be legal.
|
||||
.Pp
|
||||
Is confused by any output generated by commands in a
|
||||
.Pa .login ,
|
||||
.Pa .profile ,
|
||||
or
|
||||
.Pa .cshrc
|
||||
file on the remote host.
|
||||
.Pp
|
||||
The destination user and hostname may have to be specified as
|
||||
.Dq rhost.ruser
|
||||
when the destination machine is running the
|
||||
.Bx 4.2
|
||||
version of
|
||||
.Nm .
|
791
bin/rcp/rcp.c
791
bin/rcp/rcp.c
@ -1,791 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1983, 1990, 1992, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
* Copyright (c) 2002 Networks Associates Technology, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions of this software were developed for the FreeBSD Project by
|
||||
* ThinkSec AS and NAI Labs, the Security Research Division of Network
|
||||
* Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035
|
||||
* ("CBOSS"), as part of the DARPA CHATS research program.
|
||||
*
|
||||
* 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 0
|
||||
#ifndef lint
|
||||
static char const copyright[] =
|
||||
"@(#) Copyright (c) 1983, 1990, 1992, 1993\n\
|
||||
The Regents of the University of California. All rights reserved.\n";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)rcp.c 8.2 (Berkeley) 4/2/94";
|
||||
#endif /* not lint */
|
||||
#endif
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/ip.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <dirent.h>
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <netdb.h>
|
||||
#include <paths.h>
|
||||
#include <pwd.h>
|
||||
#include <signal.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "extern.h"
|
||||
|
||||
#define OPTIONS "46dfprt"
|
||||
|
||||
static struct passwd *pwd;
|
||||
static u_short port;
|
||||
static uid_t userid;
|
||||
static int errs, rem;
|
||||
int iamremote;
|
||||
static int pflag, iamrecursive, targetshouldbedirectory;
|
||||
static int family = PF_UNSPEC;
|
||||
|
||||
static int argc_copy;
|
||||
static const char **argv_copy;
|
||||
|
||||
static char period[] = ".";
|
||||
|
||||
#define CMDNEEDS 64
|
||||
static char cmd[CMDNEEDS]; /* must hold "rcp -r -p -d\0" */
|
||||
|
||||
int response(void);
|
||||
void rsource(char *, struct stat *);
|
||||
void sink(int, char *[]);
|
||||
void source(int, char *[]);
|
||||
void tolocal(int, char *[]);
|
||||
void toremote(char *, int, char *[]);
|
||||
void usage(void);
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
struct servent *sp;
|
||||
int ch, fflag, i, tflag;
|
||||
char *targ;
|
||||
|
||||
/*
|
||||
* Prepare for execing ourselves.
|
||||
*/
|
||||
argc_copy = argc + 1;
|
||||
argv_copy = malloc((argc_copy + 1) * sizeof(*argv_copy));
|
||||
if (argv_copy == NULL)
|
||||
err(1, "malloc");
|
||||
argv_copy[0] = argv[0];
|
||||
argv_copy[1] = "-K";
|
||||
for (i = 1; i < argc; ++i) {
|
||||
argv_copy[i + 1] = strdup(argv[i]);
|
||||
if (argv_copy[i + 1] == NULL)
|
||||
errx(1, "strdup: out of memory");
|
||||
}
|
||||
argv_copy[argc + 1] = NULL;
|
||||
|
||||
fflag = tflag = 0;
|
||||
while ((ch = getopt(argc, argv, OPTIONS)) != -1)
|
||||
switch(ch) { /* User-visible flags. */
|
||||
case '4':
|
||||
family = PF_INET;
|
||||
break;
|
||||
|
||||
case '6':
|
||||
family = PF_INET6;
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
pflag = 1;
|
||||
break;
|
||||
case 'r':
|
||||
iamrecursive = 1;
|
||||
break;
|
||||
/* Server options. */
|
||||
case 'd':
|
||||
targetshouldbedirectory = 1;
|
||||
break;
|
||||
case 'f': /* "from" */
|
||||
iamremote = 1;
|
||||
fflag = 1;
|
||||
break;
|
||||
case 't': /* "to" */
|
||||
iamremote = 1;
|
||||
tflag = 1;
|
||||
break;
|
||||
case '?':
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
sp = getservbyname("shell", "tcp");
|
||||
if (sp == NULL)
|
||||
errx(1, "shell/tcp: unknown service");
|
||||
port = sp->s_port;
|
||||
|
||||
if ((pwd = getpwuid(userid = getuid())) == NULL)
|
||||
errx(1, "unknown user %d", (int)userid);
|
||||
|
||||
rem = STDIN_FILENO; /* XXX */
|
||||
|
||||
if (fflag) { /* Follow "protocol", send data. */
|
||||
(void)response();
|
||||
(void)setuid(userid);
|
||||
source(argc, argv);
|
||||
exit(errs);
|
||||
}
|
||||
|
||||
if (tflag) { /* Receive data. */
|
||||
(void)setuid(userid);
|
||||
sink(argc, argv);
|
||||
exit(errs);
|
||||
}
|
||||
|
||||
if (argc < 2)
|
||||
usage();
|
||||
if (argc > 2)
|
||||
targetshouldbedirectory = 1;
|
||||
|
||||
rem = -1;
|
||||
/* Command to be executed on remote system using "rsh". */
|
||||
(void)snprintf(cmd, sizeof(cmd), "rcp%s%s%s",
|
||||
iamrecursive ? " -r" : "", pflag ? " -p" : "",
|
||||
targetshouldbedirectory ? " -d" : "");
|
||||
|
||||
(void)signal(SIGPIPE, lostconn);
|
||||
|
||||
if ((targ = colon(argv[argc - 1]))) /* Dest is remote host. */
|
||||
toremote(targ, argc, argv);
|
||||
else {
|
||||
tolocal(argc, argv); /* Dest is local host. */
|
||||
if (targetshouldbedirectory)
|
||||
verifydir(argv[argc - 1]);
|
||||
}
|
||||
exit(errs);
|
||||
}
|
||||
|
||||
void
|
||||
toremote(char *targ, int argc, char *argv[])
|
||||
{
|
||||
int i, tos;
|
||||
char *bp, *host, *src, *suser, *thost, *tuser;
|
||||
|
||||
*targ++ = 0;
|
||||
if (*targ == 0)
|
||||
targ = period;
|
||||
|
||||
if ((thost = strchr(argv[argc - 1], '@'))) {
|
||||
/* user@host */
|
||||
*thost++ = 0;
|
||||
tuser = argv[argc - 1];
|
||||
if (*tuser == '\0')
|
||||
tuser = NULL;
|
||||
else if (!okname(tuser))
|
||||
exit(1);
|
||||
} else {
|
||||
thost = argv[argc - 1];
|
||||
tuser = NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < argc - 1; i++) {
|
||||
src = colon(argv[i]);
|
||||
if (src) { /* remote to remote */
|
||||
*src++ = 0;
|
||||
if (*src == 0)
|
||||
src = period;
|
||||
host = strchr(argv[i], '@');
|
||||
if (host) {
|
||||
*host++ = 0;
|
||||
suser = argv[i];
|
||||
if (*suser == '\0')
|
||||
suser = pwd->pw_name;
|
||||
else if (!okname(suser)) {
|
||||
++errs;
|
||||
continue;
|
||||
}
|
||||
if (asprintf(&bp,
|
||||
"%s %s -l %s -n %s %s '%s%s%s:%s'",
|
||||
_PATH_RSH, host, suser, cmd, src,
|
||||
tuser ? tuser : "", tuser ? "@" : "",
|
||||
thost, targ) == -1)
|
||||
err(1, "asprintf");
|
||||
} else
|
||||
if (asprintf(&bp,
|
||||
"exec %s %s -n %s %s '%s%s%s:%s'",
|
||||
_PATH_RSH, argv[i], cmd, src,
|
||||
tuser ? tuser : "", tuser ? "@" : "",
|
||||
thost, targ) == -1)
|
||||
err(1, "asprintf");
|
||||
(void)susystem(bp, userid);
|
||||
(void)free(bp);
|
||||
} else { /* local to remote */
|
||||
if (rem == -1) {
|
||||
if (asprintf(&bp, "%s -t %s", cmd, targ)
|
||||
== -1)
|
||||
err(1, "asprintf");
|
||||
host = thost;
|
||||
rem = rcmd_af(&host, port,
|
||||
pwd->pw_name,
|
||||
tuser ? tuser : pwd->pw_name,
|
||||
bp, 0, family);
|
||||
if (rem < 0)
|
||||
exit(1);
|
||||
if (family == PF_INET) {
|
||||
tos = IPTOS_THROUGHPUT;
|
||||
if (setsockopt(rem, IPPROTO_IP, IP_TOS,
|
||||
&tos, sizeof(int)) < 0)
|
||||
warn("TOS (ignored)");
|
||||
}
|
||||
if (response() < 0)
|
||||
exit(1);
|
||||
(void)free(bp);
|
||||
(void)setuid(userid);
|
||||
}
|
||||
source(1, argv+i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
tolocal(int argc, char *argv[])
|
||||
{
|
||||
int i, len, tos;
|
||||
char *bp, *host, *src, *suser;
|
||||
|
||||
for (i = 0; i < argc - 1; i++) {
|
||||
if (!(src = colon(argv[i]))) { /* Local to local. */
|
||||
len = strlen(_PATH_CP) + strlen(argv[i]) +
|
||||
strlen(argv[argc - 1]) + 20;
|
||||
if (!(bp = malloc(len)))
|
||||
err(1, "malloc");
|
||||
(void)snprintf(bp, len, "exec %s%s%s %s %s", _PATH_CP,
|
||||
iamrecursive ? " -PR" : "", pflag ? " -p" : "",
|
||||
argv[i], argv[argc - 1]);
|
||||
if (susystem(bp, userid))
|
||||
++errs;
|
||||
(void)free(bp);
|
||||
continue;
|
||||
}
|
||||
*src++ = 0;
|
||||
if (*src == 0)
|
||||
src = period;
|
||||
if ((host = strchr(argv[i], '@')) == NULL) {
|
||||
host = argv[i];
|
||||
suser = pwd->pw_name;
|
||||
} else {
|
||||
*host++ = 0;
|
||||
suser = argv[i];
|
||||
if (*suser == '\0')
|
||||
suser = pwd->pw_name;
|
||||
else if (!okname(suser)) {
|
||||
++errs;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
len = strlen(src) + CMDNEEDS + 20;
|
||||
if ((bp = malloc(len)) == NULL)
|
||||
err(1, "malloc");
|
||||
(void)snprintf(bp, len, "%s -f %s", cmd, src);
|
||||
rem = rcmd_af(&host, port, pwd->pw_name, suser, bp, 0,
|
||||
family);
|
||||
(void)free(bp);
|
||||
if (rem < 0) {
|
||||
++errs;
|
||||
continue;
|
||||
}
|
||||
(void)seteuid(userid);
|
||||
if (family == PF_INET) {
|
||||
tos = IPTOS_THROUGHPUT;
|
||||
if (setsockopt(rem, IPPROTO_IP, IP_TOS, &tos,
|
||||
sizeof(int)) < 0)
|
||||
warn("TOS (ignored)");
|
||||
}
|
||||
sink(1, argv + argc - 1);
|
||||
(void)seteuid(0);
|
||||
(void)close(rem);
|
||||
rem = -1;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
source(int argc, char *argv[])
|
||||
{
|
||||
struct stat stb;
|
||||
static BUF buffer;
|
||||
BUF *bp;
|
||||
off_t i;
|
||||
int amt, fd, haderr, indx, result;
|
||||
char *last, *name, buf[BUFSIZ];
|
||||
|
||||
for (indx = 0; indx < argc; ++indx) {
|
||||
name = argv[indx];
|
||||
if ((fd = open(name, O_RDONLY, 0)) < 0)
|
||||
goto syserr;
|
||||
if (fstat(fd, &stb)) {
|
||||
syserr: run_err("%s: %s", name, strerror(errno));
|
||||
goto next;
|
||||
}
|
||||
switch (stb.st_mode & S_IFMT) {
|
||||
case S_IFREG:
|
||||
break;
|
||||
case S_IFDIR:
|
||||
if (iamrecursive) {
|
||||
rsource(name, &stb);
|
||||
goto next;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
default:
|
||||
run_err("%s: not a regular file", name);
|
||||
goto next;
|
||||
}
|
||||
if ((last = strrchr(name, '/')) == NULL)
|
||||
last = name;
|
||||
else
|
||||
++last;
|
||||
if (pflag) {
|
||||
/*
|
||||
* Make it compatible with possible future
|
||||
* versions expecting microseconds.
|
||||
*/
|
||||
(void)snprintf(buf, sizeof(buf), "T%ld 0 %ld 0\n",
|
||||
(long)stb.st_mtim.tv_sec,
|
||||
(long)stb.st_atim.tv_sec);
|
||||
(void)write(rem, buf, strlen(buf));
|
||||
if (response() < 0)
|
||||
goto next;
|
||||
}
|
||||
#define MODEMASK (S_ISUID|S_ISGID|S_ISTXT|S_IRWXU|S_IRWXG|S_IRWXO)
|
||||
(void)snprintf(buf, sizeof(buf), "C%04o %jd %s\n",
|
||||
stb.st_mode & MODEMASK, (intmax_t)stb.st_size, last);
|
||||
(void)write(rem, buf, strlen(buf));
|
||||
if (response() < 0)
|
||||
goto next;
|
||||
if ((bp = allocbuf(&buffer, fd, BUFSIZ)) == NULL) {
|
||||
next: if (fd >= 0)
|
||||
(void)close(fd);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Keep writing after an error so that we stay sync'd up. */
|
||||
for (haderr = i = 0; i < stb.st_size; i += bp->cnt) {
|
||||
amt = bp->cnt;
|
||||
if (i + amt > stb.st_size)
|
||||
amt = stb.st_size - i;
|
||||
if (!haderr) {
|
||||
result = read(fd, bp->buf, amt);
|
||||
if (result != amt)
|
||||
haderr = result >= 0 ? EIO : errno;
|
||||
}
|
||||
if (haderr)
|
||||
(void)write(rem, bp->buf, amt);
|
||||
else {
|
||||
result = write(rem, bp->buf, amt);
|
||||
if (result != amt)
|
||||
haderr = result >= 0 ? EIO : errno;
|
||||
}
|
||||
}
|
||||
if (close(fd) && !haderr)
|
||||
haderr = errno;
|
||||
if (!haderr)
|
||||
(void)write(rem, "", 1);
|
||||
else
|
||||
run_err("%s: %s", name, strerror(haderr));
|
||||
(void)response();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
rsource(char *name, struct stat *statp)
|
||||
{
|
||||
DIR *dirp;
|
||||
struct dirent *dp;
|
||||
char *last, *vect[1], path[PATH_MAX];
|
||||
|
||||
if (!(dirp = opendir(name))) {
|
||||
run_err("%s: %s", name, strerror(errno));
|
||||
return;
|
||||
}
|
||||
last = strrchr(name, '/');
|
||||
if (last == NULL)
|
||||
last = name;
|
||||
else
|
||||
last++;
|
||||
if (pflag) {
|
||||
(void)snprintf(path, sizeof(path), "T%ld 0 %ld 0\n",
|
||||
(long)statp->st_mtim.tv_sec,
|
||||
(long)statp->st_atim.tv_sec);
|
||||
(void)write(rem, path, strlen(path));
|
||||
if (response() < 0) {
|
||||
closedir(dirp);
|
||||
return;
|
||||
}
|
||||
}
|
||||
(void)snprintf(path, sizeof(path),
|
||||
"D%04o %d %s\n", statp->st_mode & MODEMASK, 0, last);
|
||||
(void)write(rem, path, strlen(path));
|
||||
if (response() < 0) {
|
||||
closedir(dirp);
|
||||
return;
|
||||
}
|
||||
while ((dp = readdir(dirp))) {
|
||||
if (dp->d_ino == 0)
|
||||
continue;
|
||||
if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, ".."))
|
||||
continue;
|
||||
if (strlen(name) + 1 + strlen(dp->d_name) >= sizeof(path)) {
|
||||
run_err("%s/%s: name too long", name, dp->d_name);
|
||||
continue;
|
||||
}
|
||||
(void)snprintf(path, sizeof(path), "%s/%s", name, dp->d_name);
|
||||
vect[0] = path;
|
||||
source(1, vect);
|
||||
}
|
||||
(void)closedir(dirp);
|
||||
(void)write(rem, "E\n", 2);
|
||||
(void)response();
|
||||
}
|
||||
|
||||
void
|
||||
sink(int argc, char *argv[])
|
||||
{
|
||||
static BUF buffer;
|
||||
struct stat stb;
|
||||
struct timeval tv[2];
|
||||
enum { YES, NO, DISPLAYED } wrerr;
|
||||
BUF *bp;
|
||||
off_t i, j, size;
|
||||
int amt, exists, first, mask, mode, ofd, omode;
|
||||
size_t count;
|
||||
int setimes, targisdir, wrerrno = 0;
|
||||
char ch, *cp, *np, *targ, *vect[1], buf[BUFSIZ], path[PATH_MAX];
|
||||
const char *why;
|
||||
|
||||
#define atime tv[0]
|
||||
#define mtime tv[1]
|
||||
#define SCREWUP(str) { why = str; goto screwup; }
|
||||
|
||||
setimes = targisdir = 0;
|
||||
mask = umask(0);
|
||||
if (!pflag)
|
||||
(void)umask(mask);
|
||||
if (argc != 1) {
|
||||
run_err("ambiguous target");
|
||||
exit(1);
|
||||
}
|
||||
targ = *argv;
|
||||
if (targetshouldbedirectory)
|
||||
verifydir(targ);
|
||||
(void)write(rem, "", 1);
|
||||
if (stat(targ, &stb) == 0 && S_ISDIR(stb.st_mode))
|
||||
targisdir = 1;
|
||||
for (first = 1;; first = 0) {
|
||||
cp = buf;
|
||||
if (read(rem, cp, 1) <= 0)
|
||||
return;
|
||||
if (*cp++ == '\n')
|
||||
SCREWUP("unexpected <newline>");
|
||||
do {
|
||||
if (read(rem, &ch, sizeof(ch)) != sizeof(ch))
|
||||
SCREWUP("lost connection");
|
||||
*cp++ = ch;
|
||||
} while (cp < &buf[BUFSIZ - 1] && ch != '\n');
|
||||
*cp = 0;
|
||||
|
||||
if (buf[0] == '\01' || buf[0] == '\02') {
|
||||
if (iamremote == 0)
|
||||
(void)write(STDERR_FILENO,
|
||||
buf + 1, strlen(buf + 1));
|
||||
if (buf[0] == '\02')
|
||||
exit(1);
|
||||
++errs;
|
||||
continue;
|
||||
}
|
||||
if (buf[0] == 'E') {
|
||||
(void)write(rem, "", 1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ch == '\n')
|
||||
*--cp = 0;
|
||||
|
||||
cp = buf;
|
||||
if (*cp == 'T') {
|
||||
setimes++;
|
||||
cp++;
|
||||
mtime.tv_sec = strtol(cp, &cp, 10);
|
||||
if (!cp || *cp++ != ' ')
|
||||
SCREWUP("mtime.sec not delimited");
|
||||
mtime.tv_usec = strtol(cp, &cp, 10);
|
||||
if (!cp || *cp++ != ' ')
|
||||
SCREWUP("mtime.usec not delimited");
|
||||
atime.tv_sec = strtol(cp, &cp, 10);
|
||||
if (!cp || *cp++ != ' ')
|
||||
SCREWUP("atime.sec not delimited");
|
||||
atime.tv_usec = strtol(cp, &cp, 10);
|
||||
if (!cp || *cp++ != '\0')
|
||||
SCREWUP("atime.usec not delimited");
|
||||
(void)write(rem, "", 1);
|
||||
continue;
|
||||
}
|
||||
if (*cp != 'C' && *cp != 'D') {
|
||||
/*
|
||||
* Check for the case "rcp remote:foo\* local:bar".
|
||||
* In this case, the line "No match." can be returned
|
||||
* by the shell before the rcp command on the remote is
|
||||
* executed so the ^Aerror_message convention isn't
|
||||
* followed.
|
||||
*/
|
||||
if (first) {
|
||||
run_err("%s", cp);
|
||||
exit(1);
|
||||
}
|
||||
SCREWUP("expected control record");
|
||||
}
|
||||
mode = 0;
|
||||
for (++cp; cp < buf + 5; cp++) {
|
||||
if (*cp < '0' || *cp > '7')
|
||||
SCREWUP("bad mode");
|
||||
mode = (mode << 3) | (*cp - '0');
|
||||
}
|
||||
if (*cp++ != ' ')
|
||||
SCREWUP("mode not delimited");
|
||||
|
||||
for (size = 0; isdigit(*cp);)
|
||||
size = size * 10 + (*cp++ - '0');
|
||||
if (*cp++ != ' ')
|
||||
SCREWUP("size not delimited");
|
||||
if (targisdir) {
|
||||
if (strlen(targ) + (*targ ? 1 : 0) + strlen(cp)
|
||||
>= sizeof(path)) {
|
||||
run_err("%s%s%s: name too long", targ,
|
||||
*targ ? "/" : "", cp);
|
||||
exit(1);
|
||||
}
|
||||
(void)snprintf(path, sizeof(path), "%s%s%s", targ,
|
||||
*targ ? "/" : "", cp);
|
||||
np = path;
|
||||
} else
|
||||
np = targ;
|
||||
exists = stat(np, &stb) == 0;
|
||||
if (buf[0] == 'D') {
|
||||
int mod_flag = pflag;
|
||||
if (exists) {
|
||||
if (!S_ISDIR(stb.st_mode)) {
|
||||
errno = ENOTDIR;
|
||||
goto bad;
|
||||
}
|
||||
if (pflag)
|
||||
(void)chmod(np, mode);
|
||||
} else {
|
||||
/* Handle copying from a read-only directory */
|
||||
mod_flag = 1;
|
||||
if (mkdir(np, mode | S_IRWXU) < 0)
|
||||
goto bad;
|
||||
}
|
||||
vect[0] = np;
|
||||
sink(1, vect);
|
||||
if (setimes) {
|
||||
setimes = 0;
|
||||
if (utimes(np, tv) < 0)
|
||||
run_err("%s: set times: %s",
|
||||
np, strerror(errno));
|
||||
}
|
||||
if (mod_flag)
|
||||
(void)chmod(np, mode);
|
||||
continue;
|
||||
}
|
||||
omode = mode;
|
||||
mode |= S_IWRITE;
|
||||
if ((ofd = open(np, O_WRONLY|O_CREAT, mode)) < 0) {
|
||||
bad: run_err("%s: %s", np, strerror(errno));
|
||||
continue;
|
||||
}
|
||||
(void)write(rem, "", 1);
|
||||
if ((bp = allocbuf(&buffer, ofd, BUFSIZ)) == NULL) {
|
||||
(void)close(ofd);
|
||||
continue;
|
||||
}
|
||||
cp = bp->buf;
|
||||
wrerr = NO;
|
||||
for (count = i = 0; i < size; i += BUFSIZ) {
|
||||
amt = BUFSIZ;
|
||||
if (i + amt > size)
|
||||
amt = size - i;
|
||||
count += amt;
|
||||
do {
|
||||
j = read(rem, cp, amt);
|
||||
if (j <= 0) {
|
||||
run_err("%s", j ? strerror(errno) :
|
||||
"dropped connection");
|
||||
exit(1);
|
||||
}
|
||||
amt -= j;
|
||||
cp += j;
|
||||
} while (amt > 0);
|
||||
if (count == bp->cnt) {
|
||||
/* Keep reading so we stay sync'd up. */
|
||||
if (wrerr == NO) {
|
||||
j = write(ofd, bp->buf, count);
|
||||
if (j != (off_t)count) {
|
||||
wrerr = YES;
|
||||
wrerrno = j >= 0 ? EIO : errno;
|
||||
}
|
||||
}
|
||||
count = 0;
|
||||
cp = bp->buf;
|
||||
}
|
||||
}
|
||||
if (count != 0 && wrerr == NO &&
|
||||
(j = write(ofd, bp->buf, count)) != (off_t)count) {
|
||||
wrerr = YES;
|
||||
wrerrno = j >= 0 ? EIO : errno;
|
||||
}
|
||||
if (ftruncate(ofd, size)) {
|
||||
run_err("%s: truncate: %s", np, strerror(errno));
|
||||
wrerr = DISPLAYED;
|
||||
}
|
||||
if (pflag) {
|
||||
if (exists || omode != mode)
|
||||
if (fchmod(ofd, omode))
|
||||
run_err("%s: set mode: %s",
|
||||
np, strerror(errno));
|
||||
} else {
|
||||
if (!exists && omode != mode)
|
||||
if (fchmod(ofd, omode & ~mask))
|
||||
run_err("%s: set mode: %s",
|
||||
np, strerror(errno));
|
||||
}
|
||||
(void)close(ofd);
|
||||
(void)response();
|
||||
if (setimes && wrerr == NO) {
|
||||
setimes = 0;
|
||||
if (utimes(np, tv) < 0) {
|
||||
run_err("%s: set times: %s",
|
||||
np, strerror(errno));
|
||||
wrerr = DISPLAYED;
|
||||
}
|
||||
}
|
||||
switch(wrerr) {
|
||||
case YES:
|
||||
run_err("%s: %s", np, strerror(wrerrno));
|
||||
break;
|
||||
case NO:
|
||||
(void)write(rem, "", 1);
|
||||
break;
|
||||
case DISPLAYED:
|
||||
break;
|
||||
}
|
||||
}
|
||||
screwup:
|
||||
run_err("protocol error: %s", why);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int
|
||||
response(void)
|
||||
{
|
||||
char ch, *cp, resp, rbuf[BUFSIZ];
|
||||
|
||||
if (read(rem, &resp, sizeof(resp)) != sizeof(resp))
|
||||
lostconn(0);
|
||||
|
||||
cp = rbuf;
|
||||
switch(resp) {
|
||||
case 0: /* ok */
|
||||
return (0);
|
||||
default:
|
||||
*cp++ = resp;
|
||||
/* FALLTHROUGH */
|
||||
case 1: /* error, followed by error msg */
|
||||
case 2: /* fatal error, "" */
|
||||
do {
|
||||
if (read(rem, &ch, sizeof(ch)) != sizeof(ch))
|
||||
lostconn(0);
|
||||
*cp++ = ch;
|
||||
} while (cp < &rbuf[BUFSIZ] && ch != '\n');
|
||||
|
||||
if (!iamremote)
|
||||
(void)write(STDERR_FILENO, rbuf, cp - rbuf);
|
||||
++errs;
|
||||
if (resp == 1)
|
||||
return (-1);
|
||||
exit(1);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
void
|
||||
usage(void)
|
||||
{
|
||||
(void)fprintf(stderr, "%s\n%s\n",
|
||||
"usage: rcp [-46p] file1 file2",
|
||||
" rcp [-46pr] file ... directory");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
void
|
||||
run_err(const char *fmt, ...)
|
||||
{
|
||||
static FILE *fp;
|
||||
va_list ap;
|
||||
|
||||
++errs;
|
||||
if (fp == NULL && !(fp = fdopen(rem, "w")))
|
||||
return;
|
||||
(void)fprintf(fp, "%c", 0x01);
|
||||
(void)fprintf(fp, "rcp: ");
|
||||
va_start(ap, fmt);
|
||||
(void)vfprintf(fp, fmt, ap);
|
||||
va_end(ap);
|
||||
(void)fprintf(fp, "\n");
|
||||
(void)fflush(fp);
|
||||
|
||||
if (!iamremote) {
|
||||
va_start(ap, fmt);
|
||||
vwarnx(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
# $FreeBSD$
|
||||
|
||||
ATF_TESTS_SH+= rcp_test
|
||||
|
||||
.include <bsd.test.mk>
|
@ -1,60 +0,0 @@
|
||||
#
|
||||
# Copyright 2017 Shivansh Rai
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
# SUCH DAMAGE.
|
||||
#
|
||||
# $FreeBSD$
|
||||
#
|
||||
|
||||
usage_output='usage: rcp'
|
||||
|
||||
atf_test_case invalid_usage
|
||||
invalid_usage_head()
|
||||
{
|
||||
atf_set "descr" "Verify that an invalid usage with a supported option produces a valid error message"
|
||||
}
|
||||
|
||||
invalid_usage_body()
|
||||
{
|
||||
atf_check -s not-exit:0 -e match:"$usage_output" rcp -4
|
||||
atf_check -s not-exit:0 -e match:"$usage_output" rcp -6
|
||||
atf_check -s not-exit:0 -e match:"$usage_output" rcp -p
|
||||
atf_check -s not-exit:0 -e match:"$usage_output" rcp -r
|
||||
}
|
||||
|
||||
atf_test_case no_arguments
|
||||
no_arguments_head()
|
||||
{
|
||||
atf_set "descr" "Verify that rcp(1) fails and generates a valid usage message when no arguments are supplied"
|
||||
}
|
||||
|
||||
no_arguments_body()
|
||||
{
|
||||
atf_check -s not-exit:0 -e match:"$usage_output" rcp
|
||||
}
|
||||
|
||||
atf_init_test_cases()
|
||||
{
|
||||
atf_add_test_case invalid_usage
|
||||
atf_add_test_case no_arguments
|
||||
}
|
159
bin/rcp/util.c
159
bin/rcp/util.c
@ -1,159 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 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.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static const char sccsid[] = "@(#)util.c 8.2 (Berkeley) 4/2/94";
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <paths.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "extern.h"
|
||||
|
||||
char *
|
||||
colon(char *cp)
|
||||
{
|
||||
if (*cp == ':') /* Leading colon is part of file name. */
|
||||
return (0);
|
||||
|
||||
for (; *cp; ++cp) {
|
||||
if (*cp == ':')
|
||||
return (cp);
|
||||
if (*cp == '/')
|
||||
return (0);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
verifydir(char *cp)
|
||||
{
|
||||
struct stat stb;
|
||||
|
||||
if (!stat(cp, &stb)) {
|
||||
if (S_ISDIR(stb.st_mode))
|
||||
return;
|
||||
errno = ENOTDIR;
|
||||
}
|
||||
run_err("%s: %s", cp, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int
|
||||
okname(char *cp0)
|
||||
{
|
||||
int c;
|
||||
char *cp;
|
||||
|
||||
cp = cp0;
|
||||
do {
|
||||
c = *cp;
|
||||
if (c & 0200)
|
||||
goto bad;
|
||||
if (!isalpha(c) && !isdigit(c) && c != '_' && c != '-' && c != '.')
|
||||
goto bad;
|
||||
} while (*++cp);
|
||||
return (1);
|
||||
|
||||
bad: warnx("%s: invalid user name", cp0);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
susystem(char *s, int userid)
|
||||
{
|
||||
sig_t istat, qstat;
|
||||
int status;
|
||||
pid_t pid;
|
||||
|
||||
pid = vfork();
|
||||
switch (pid) {
|
||||
case -1:
|
||||
return (127);
|
||||
|
||||
case 0:
|
||||
(void)setuid(userid);
|
||||
execl(_PATH_BSHELL, "sh", "-c", s, (char *)NULL);
|
||||
_exit(127);
|
||||
}
|
||||
istat = signal(SIGINT, SIG_IGN);
|
||||
qstat = signal(SIGQUIT, SIG_IGN);
|
||||
if (waitpid(pid, &status, 0) < 0)
|
||||
status = -1;
|
||||
(void)signal(SIGINT, istat);
|
||||
(void)signal(SIGQUIT, qstat);
|
||||
return (status);
|
||||
}
|
||||
|
||||
BUF *
|
||||
allocbuf(BUF *bp, int fd, int blksize)
|
||||
{
|
||||
struct stat stb;
|
||||
size_t size;
|
||||
|
||||
if (fstat(fd, &stb) < 0) {
|
||||
run_err("fstat: %s", strerror(errno));
|
||||
return (0);
|
||||
}
|
||||
size = roundup(stb.st_blksize, blksize);
|
||||
if (size == 0)
|
||||
size = blksize;
|
||||
if (bp->cnt >= size)
|
||||
return (bp);
|
||||
if ((bp->buf = realloc(bp->buf, size)) == NULL) {
|
||||
bp->cnt = 0;
|
||||
run_err("%s", strerror(errno));
|
||||
return (0);
|
||||
}
|
||||
bp->cnt = size;
|
||||
return (bp);
|
||||
}
|
||||
|
||||
void
|
||||
lostconn(int signo __unused)
|
||||
{
|
||||
if (!iamremote)
|
||||
warnx("lost connection");
|
||||
exit(1);
|
||||
}
|
@ -1,6 +1,3 @@
|
||||
'\" te
|
||||
.\" Copyright (c) 2012, Martin Matuska <mm@FreeBSD.org>.
|
||||
.\" All Rights Reserved.
|
||||
.\"
|
||||
.\" This file and its contents are supplied under the terms of the
|
||||
.\" Common Development and Distribution License ("CDDL"), version 1.0.
|
||||
@ -13,71 +10,75 @@
|
||||
.\"
|
||||
.\"
|
||||
.\" Copyright 2012, Richard Lowe.
|
||||
.\" Copyright (c) 2012, Marcelo Araujo <araujo@FreeBSD.org>.
|
||||
.\" Copyright (c) 2012, 2014 by Delphix. All rights reserved.
|
||||
.\" All Rights Reserved.
|
||||
.\" Copyright (c) 2012, 2017 by Delphix. All rights reserved.
|
||||
.\" Copyright 2017 Nexenta Systems, Inc.
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd July 26, 2014
|
||||
.Dd October 06, 2017
|
||||
.Dt ZDB 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm zdb
|
||||
.Nd Display zpool debugging and consistency information
|
||||
.Nd display zpool debugging and consistency information
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl CumdibcsDvhLMXFPA
|
||||
.Op Fl e Op Fl p Ar path...
|
||||
.Op Fl t Ar txg
|
||||
.Op Fl U Ar cache
|
||||
.Op Fl AbcdDFGhiLMPsvX
|
||||
.Op Fl e Oo Fl V Oc Op Fl p Ar path ...
|
||||
.Op Fl I Ar inflight I/Os
|
||||
.Op Fl x Ar dumpdir
|
||||
.Ar poolname
|
||||
.Op Ar object ...
|
||||
.Nm
|
||||
.Op Fl divPA
|
||||
.Op Fl e Op Fl p Ar path...
|
||||
.Op Fl U Ar cache
|
||||
.Ar dataset
|
||||
.Op Ar object ...
|
||||
.Nm
|
||||
.Fl m Op Fl MLXFPA
|
||||
.Oo Fl o Ar var Ns = Ns Ar value Oc Ns ...
|
||||
.Op Fl t Ar txg
|
||||
.Op Fl e Op Fl p Ar path...
|
||||
.Op Fl U Ar cache
|
||||
.Ar poolname
|
||||
.Op Fl x Ar dumpdir
|
||||
.Op Ar poolname Op Ar object ...
|
||||
.Nm
|
||||
.Fl R Op Fl A
|
||||
.Op Fl e Op Fl p Ar path...
|
||||
.Op Fl AdiPv
|
||||
.Op Fl e Oo Fl V Oc Op Fl p Ar path ...
|
||||
.Op Fl U Ar cache
|
||||
.Ar poolname
|
||||
.Ar poolname
|
||||
.Ar vdev Ns : Ns Ar offset Ns : Ns Ar size Ns Op Ns : Ns Ar flags
|
||||
.Nm
|
||||
.Fl S
|
||||
.Op Fl AP
|
||||
.Op Fl e Op Fl p Ar path...
|
||||
.Op Fl U Ar cache
|
||||
.Ar poolname
|
||||
.Ar poolname
|
||||
.Nm
|
||||
.Fl l
|
||||
.Op Fl uA
|
||||
.Ar device
|
||||
.Ar dataset Op Ar object ...
|
||||
.Nm
|
||||
.Fl C
|
||||
.Op Fl A
|
||||
.Op Fl U Ar cache
|
||||
.Nm
|
||||
.Fl E
|
||||
.Op Fl A
|
||||
.Ar word0 Ns \&: Ns Ar word1 Ns :...: Ns Ar word15
|
||||
.Nm
|
||||
.Fl l
|
||||
.Op Fl Aqu
|
||||
.Ar device
|
||||
.Nm
|
||||
.Fl m
|
||||
.Op Fl AFLPX
|
||||
.Op Fl e Oo Fl V Oc Op Fl p Ar path ...
|
||||
.Op Fl t Ar txg
|
||||
.Op Fl U Ar cache
|
||||
.Ar poolname Op Ar vdev Op Ar metaslab ...
|
||||
.Nm
|
||||
.Fl O
|
||||
.Ar dataset path
|
||||
.Nm
|
||||
.Fl R
|
||||
.Op Fl A
|
||||
.Op Fl e Oo Fl V Oc Op Fl p Ar path ...
|
||||
.Op Fl U Ar cache
|
||||
.Ar poolname vdev Ns \&: Ns Ar offset Ns \&: Ns Ar size Ns Op : Ns Ar flags
|
||||
.Nm
|
||||
.Fl S
|
||||
.Op Fl AP
|
||||
.Op Fl e Oo Fl V Oc Op Fl p Ar path ...
|
||||
.Op Fl U Ar cache
|
||||
.Ar poolname
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
utility displays information about a ZFS pool useful for debugging and
|
||||
performs some amount of consistency checking.
|
||||
It is a not a general purpose tool and options (and facilities) may change.
|
||||
utility displays information about a ZFS pool useful for debugging and performs
|
||||
some amount of consistency checking.
|
||||
It is a not a general purpose tool and options
|
||||
.Pq and facilities
|
||||
may change.
|
||||
This is neither a
|
||||
.Xr fsck 8
|
||||
nor a
|
||||
nor an
|
||||
.Xr fsdb 8
|
||||
utility.
|
||||
.Pp
|
||||
@ -89,73 +90,96 @@ internals is assumed.
|
||||
If the
|
||||
.Ar dataset
|
||||
argument does not contain any
|
||||
.Sy /
|
||||
.Qq Sy /
|
||||
or
|
||||
.Sy @
|
||||
.Qq Sy @
|
||||
characters, it is interpreted as a pool name.
|
||||
The root dataset can be specified as
|
||||
.Pa pool Ns Sy /
|
||||
(pool name followed by a slash).
|
||||
.Ar pool Ns /
|
||||
.Pq pool name followed by a slash .
|
||||
.Pp
|
||||
When operating on an imported and active pool it is possible, though unlikely,
|
||||
that zdb may interpret inconsistent pool data and behave erratically.
|
||||
.Sh OPTIONS
|
||||
Display options:
|
||||
.Bl -tag -width indent
|
||||
.Bl -tag -width Ds
|
||||
.It Fl b
|
||||
Display statistics regarding the number, size (logical, physical and
|
||||
allocated) and deduplication of blocks.
|
||||
Display statistics regarding the number, size
|
||||
.Pq logical, physical and allocated
|
||||
and deduplication of blocks.
|
||||
.It Fl c
|
||||
Verify the checksum of all metadata blocks while printing block statistics
|
||||
(see
|
||||
.Fl b Ns ).
|
||||
.Po see
|
||||
.Fl b
|
||||
.Pc .
|
||||
.Pp
|
||||
If specified multiple times, verify the checksums of all blocks.
|
||||
.It Fl C
|
||||
Display information about the configuration. If specified with no other
|
||||
options, instead display information about the cache file
|
||||
.Po Pa /etc/zfs/zpool.cache Pc .
|
||||
Display information about the configuration.
|
||||
If specified with no other options, instead display information about the cache
|
||||
file
|
||||
.Pq Pa /boot/zfs/zpool.cache .
|
||||
To specify the cache file to display, see
|
||||
.Fl U
|
||||
.Fl U .
|
||||
.Pp
|
||||
If specified multiple times, and a pool name is also specified display both
|
||||
the cached configuration and the on-disk configuration.
|
||||
If specified multiple times, and a pool name is also specified display both the
|
||||
cached configuration and the on-disk configuration.
|
||||
If specified multiple times with
|
||||
.Fl e
|
||||
also display the configuration that would be used were the pool to be
|
||||
imported.
|
||||
also display the configuration that would be used were the pool to be imported.
|
||||
.It Fl d
|
||||
Display information about datasets. Specified once, displays basic dataset
|
||||
information: ID, create transaction, size, and object count.
|
||||
Display information about datasets.
|
||||
Specified once, displays basic dataset information: ID, create transaction,
|
||||
size, and object count.
|
||||
.Pp
|
||||
If specified multiple times provides greater and greater verbosity.
|
||||
.Pp
|
||||
If object IDs are specified, display information about those specific objects only.
|
||||
If object IDs are specified, display information about those specific objects
|
||||
only.
|
||||
.It Fl D
|
||||
Display deduplication statistics, including the deduplication ratio (dedup),
|
||||
compression ratio (compress), inflation due to the zfs copies property
|
||||
(copies), and an overall effective ratio (dedup * compress / copies).
|
||||
.Pp
|
||||
If specified twice, display a histogram of deduplication statistics, showing
|
||||
the allocated (physically present on disk) and referenced (logically
|
||||
referenced in the pool) block counts and sizes by reference count.
|
||||
.Pp
|
||||
If specified a third time, display the statistics independently for each deduplication table.
|
||||
.Pp
|
||||
If specified a fourth time, dump the contents of the deduplication tables describing duplicate blocks.
|
||||
.Pp
|
||||
If specified a fifth time, also dump the contents of the deduplication tables describing unique blocks.
|
||||
Display deduplication statistics, including the deduplication ratio
|
||||
.Pq Sy dedup ,
|
||||
compression ratio
|
||||
.Pq Sy compress ,
|
||||
inflation due to the zfs copies property
|
||||
.Pq Sy copies ,
|
||||
and an overall effective ratio
|
||||
.Pq Sy dedup No * Sy compress No / Sy copies .
|
||||
.It Fl DD
|
||||
Display a histogram of deduplication statistics, showing the allocated
|
||||
.Pq physically present on disk
|
||||
and referenced
|
||||
.Pq logically referenced in the pool
|
||||
block counts and sizes by reference count.
|
||||
.It Fl DDD
|
||||
Display the statistics independently for each deduplication table.
|
||||
.It Fl DDDD
|
||||
Dump the contents of the deduplication tables describing duplicate blocks.
|
||||
.It Fl DDDDD
|
||||
Also dump the contents of the deduplication tables describing unique blocks.
|
||||
.It Fl E Ar word0 Ns \&: Ns Ar word1 Ns :...: Ns Ar word15
|
||||
Decode and display block from an embedded block pointer specified by the
|
||||
.Ar word
|
||||
arguments.
|
||||
.It Fl h
|
||||
Display pool history similar to
|
||||
.Cm zpool history ,
|
||||
.Nm zpool Cm history ,
|
||||
but include internal changes, transaction, and dataset information.
|
||||
.It Fl i
|
||||
Display information about intent log (ZIL) entries relating to each
|
||||
dataset.
|
||||
If specified multiple times, display counts of each intent log transaction
|
||||
type.
|
||||
Display information about intent log
|
||||
.Pq ZIL
|
||||
entries relating to each dataset.
|
||||
If specified multiple times, display counts of each intent log transaction type.
|
||||
.It Fl l Ar device
|
||||
Display the vdev labels from the specified device.
|
||||
Read the vdev labels from the specified device.
|
||||
.Nm Fl l
|
||||
will return 0 if valid label was found, 1 if error occurred, and 2 if no valid
|
||||
labels were found.
|
||||
.Pp
|
||||
If the
|
||||
.Fl q
|
||||
option is also specified, don't print the labels.
|
||||
.Pp
|
||||
If the
|
||||
.Fl u
|
||||
option is also specified, also display the uberblocks on this device.
|
||||
@ -166,36 +190,55 @@ By default,
|
||||
verifies that all non-free blocks are referenced, which can be very expensive.
|
||||
.It Fl m
|
||||
Display the offset, spacemap, and free space of each metaslab.
|
||||
When specified twice, also display information about the on-disk free
|
||||
space histogram associated with each metaslab. When specified three time,
|
||||
display the maximum contiguous free space, the in-core free space histogram,
|
||||
and the percentage of free space in each space map. When specified
|
||||
four times display every spacemap record.
|
||||
.It Fl mm
|
||||
Also display information about the on-disk free space histogram associated with
|
||||
each metaslab.
|
||||
.It Fl mmm
|
||||
Display the maximum contiguous free space, the in-core free space histogram, and
|
||||
the percentage of free space in each space map.
|
||||
.It Fl mmmm
|
||||
Display every spacemap record.
|
||||
.It Fl M
|
||||
Display the offset, spacemap, and free space of each metaslab.
|
||||
When specified twice, also display information about the maximum contiguous
|
||||
free space and the percentage of free space in each space map.
|
||||
When specified three times display every spacemap record.
|
||||
.It Fl MM
|
||||
Also display information about the maximum contiguous free space and the
|
||||
percentage of free space in each space map.
|
||||
.It Fl MMM
|
||||
Display every spacemap record.
|
||||
.It Fl O Ar dataset path
|
||||
Look up the specified
|
||||
.Ar path
|
||||
inside of the
|
||||
.Ar dataset
|
||||
and display its metadata and indirect blocks.
|
||||
Specified
|
||||
.Ar path
|
||||
must be relative to the root of
|
||||
.Ar dataset .
|
||||
This option can be combined with
|
||||
.Fl v
|
||||
for increasing verbosity.
|
||||
.It Xo
|
||||
.Fl R Ar poolname
|
||||
.Ar vdev Ns : Ns Ar offset Ns : Ns Ar size Ns Op Ns : Ns Ar flags
|
||||
.Fl R Ar poolname vdev Ns \&: Ns Ar offset Ns \&: Ns Ar size Ns Op : Ns Ar flags
|
||||
.Xc
|
||||
Read and display a block from the specified device. By default the block is
|
||||
displayed as a hex dump, but see the description of the
|
||||
.Fl r
|
||||
Read and display a block from the specified device.
|
||||
By default the block is displayed as a hex dump, but see the description of the
|
||||
.Sy r
|
||||
flag, below.
|
||||
.Pp
|
||||
The block is specified in terms of a colon-separated tuple
|
||||
.Ar vdev
|
||||
(an integer vdev identifier)
|
||||
.Pq an integer vdev identifier
|
||||
.Ar offset
|
||||
(the offset within the vdev)
|
||||
.Pq the offset within the vdev
|
||||
.Ar size
|
||||
(the size of the block to read) and, optionally,
|
||||
.Pq the size of the block to read
|
||||
and, optionally,
|
||||
.Ar flags
|
||||
(a set of flags, described below).
|
||||
.Bl -tag -width indent
|
||||
.It Sy b offset
|
||||
.Pq a set of flags, described below .
|
||||
.Pp
|
||||
.Bl -tag -compact -width "b offset"
|
||||
.It Sy b Ar offset
|
||||
Print block pointer
|
||||
.It Sy d
|
||||
Decompress the block
|
||||
@ -210,19 +253,20 @@ Dump raw uninterpreted block data
|
||||
.El
|
||||
.It Fl s
|
||||
Report statistics on
|
||||
.Nm Ns 's
|
||||
.Nm zdb
|
||||
I/O.
|
||||
Display operation counts, bandwidth, and error counts of I/O to the pool from
|
||||
.Nm .
|
||||
.It Fl S
|
||||
Simulate the effects of deduplication, constructing a DDT and then display
|
||||
that DDT as with \fB-DD\fR.
|
||||
that DDT as with
|
||||
.Fl DD .
|
||||
.It Fl u
|
||||
Display the current uberblock.
|
||||
.El
|
||||
.Pp
|
||||
Other options:
|
||||
.Bl -tag -width indent
|
||||
.Bl -tag -width Ds
|
||||
.It Fl A
|
||||
Do not abort should any assertion fail.
|
||||
.It Fl AA
|
||||
@ -230,28 +274,41 @@ Enable panic recovery, certain errors which would otherwise be fatal are
|
||||
demoted to warnings.
|
||||
.It Fl AAA
|
||||
Do not abort if asserts fail and also enable panic recovery.
|
||||
.It Fl e Op Fl p Ar path...
|
||||
.It Fl e Op Fl p Ar path ...
|
||||
Operate on an exported pool, not present in
|
||||
.Pa /etc/zfs/zpool.cache .
|
||||
.Pa /boot/zfs/zpool.cache .
|
||||
The
|
||||
.Fl p
|
||||
flag specifies the path under which devices are to be searched.
|
||||
.It Fl x Ar dumpdir
|
||||
All blocks accessed will be copied to files in the specified directory.
|
||||
The blocks will be placed in sparse files whose name is the same as
|
||||
that of the file or device read. zdb can be then run on the generated files.
|
||||
that of the file or device read.
|
||||
.Nm
|
||||
can be then run on the generated files.
|
||||
Note that the
|
||||
.Fl bbc
|
||||
flags are sufficient to access (and thus copy)
|
||||
flags are sufficient to access
|
||||
.Pq and thus copy
|
||||
all metadata on the pool.
|
||||
.It Fl F
|
||||
Attempt to make an unreadable pool readable by trying progressively older
|
||||
transactions.
|
||||
.It Fl G
|
||||
Dump the contents of the zfs_dbgmsg buffer before exiting
|
||||
.Nm .
|
||||
zfs_dbgmsg is a buffer used by ZFS to dump advanced debug information.
|
||||
.It Fl I Ar inflight I/Os
|
||||
Limit the number of outstanding checksum I/Os to the specified value.
|
||||
The default value is 200. This option affects the performance of the
|
||||
The default value is 200.
|
||||
This option affects the performance of the
|
||||
.Fl c
|
||||
option.
|
||||
.It Fl o Ar var Ns = Ns Ar value ...
|
||||
Set the given global libzpool variable to the provided value.
|
||||
The value must be an unsigned 32-bit integer.
|
||||
Currently only little-endian systems are supported to avoid accidentally setting
|
||||
the high 32 bits of 64-bit variables.
|
||||
.It Fl P
|
||||
Print numbers in an unscaled form more amenable to parsing, eg. 1000000 rather
|
||||
than 1M.
|
||||
@ -269,9 +326,14 @@ Use a cache file other than
|
||||
.It Fl v
|
||||
Enable verbosity.
|
||||
Specify multiple times for increased verbosity.
|
||||
.It Fl V
|
||||
Attempt verbatim import.
|
||||
This mimics the behavior of the kernel when loading a pool from a cachefile.
|
||||
Only usable with
|
||||
.Fl e .
|
||||
.It Fl X
|
||||
Attempt
|
||||
.Ql extreme
|
||||
.Qq extreme
|
||||
transaction rewind, that is attempt the same recovery as
|
||||
.Fl F
|
||||
but read transactions otherwise deemed too old.
|
||||
@ -283,46 +345,58 @@ option, with more occurrences enabling more verbosity.
|
||||
If no options are specified, all information about the named pool will be
|
||||
displayed at default verbosity.
|
||||
.Sh EXAMPLES
|
||||
.Bl -tag -width 0n
|
||||
.It Sy Example 1 Display the configuration of imported pool 'rpool'
|
||||
.Bd -literal -offset 2n
|
||||
.Li # Ic zdb -C rpool
|
||||
.Bl -tag -width Ds
|
||||
.It Xo
|
||||
.Sy Example 1
|
||||
Display the configuration of imported pool
|
||||
.Pa rpool
|
||||
.Xc
|
||||
.Bd -literal
|
||||
# zdb -C rpool
|
||||
|
||||
MOS Configuration:
|
||||
version: 28
|
||||
name: 'rpool'
|
||||
...
|
||||
.Ed
|
||||
.It Sy Example 2 Display basic dataset information about 'rpool'
|
||||
.Bd -literal -offset 2n
|
||||
.Li # Ic zdb -d rpool
|
||||
.It Xo
|
||||
.Sy Example 2
|
||||
Display basic dataset information about
|
||||
.Pa rpool
|
||||
.Xc
|
||||
.Bd -literal
|
||||
# zdb -d rpool
|
||||
Dataset mos [META], ID 0, cr_txg 4, 26.9M, 1051 objects
|
||||
Dataset rpool/swap [ZVOL], ID 59, cr_txg 356, 486M, 2 objects
|
||||
...
|
||||
.Ed
|
||||
.It Xo Sy Example 3 Display basic information about object 0 in
|
||||
.Sy 'rpool/export/home'
|
||||
.It Xo
|
||||
.Sy Example 3
|
||||
Display basic information about object 0 in
|
||||
.Pa rpool/export/home
|
||||
.Xc
|
||||
.Bd -literal -offset 2n
|
||||
.Li # Ic zdb -d rpool/export/home 0
|
||||
.Bd -literal
|
||||
# zdb -d rpool/export/home 0
|
||||
Dataset rpool/export/home [ZPL], ID 137, cr_txg 1546, 32K, 8 objects
|
||||
|
||||
Object lvl iblk dblk dsize lsize %full type
|
||||
0 7 16K 16K 15.0K 16K 25.00 DMU dnode
|
||||
.Ed
|
||||
.It Xo Sy Example 4 Display the predicted effect of enabling deduplication on
|
||||
.Sy 'rpool'
|
||||
.It Xo
|
||||
.Sy Example 4
|
||||
Display the predicted effect of enabling deduplication on
|
||||
.Pa rpool
|
||||
.Xc
|
||||
.Bd -literal -offset 2n
|
||||
.Li # Ic zdb -S rpool
|
||||
.Bd -literal
|
||||
# zdb -S rpool
|
||||
Simulated DDT histogram:
|
||||
|
||||
bucket allocated referenced
|
||||
______ ______________________________ ______________________________
|
||||
refcnt blocks LSIZE PSIZE DSIZE blocks LSIZE PSIZE DSIZE
|
||||
------ ------ ----- ----- ----- ------ ----- ----- -----
|
||||
1 694K 27.1G 15.0G 15.0G 694K 27.1G 15.0G 15.0G
|
||||
2 35.0K 1.33G 699M 699M 74.7K 2.79G 1.45G 1.45G
|
||||
bucket allocated referenced
|
||||
______ ______________________________ ______________________________
|
||||
refcnt blocks LSIZE PSIZE DSIZE blocks LSIZE PSIZE DSIZE
|
||||
------ ------ ----- ----- ----- ------ ----- ----- -----
|
||||
1 694K 27.1G 15.0G 15.0G 694K 27.1G 15.0G 15.0G
|
||||
2 35.0K 1.33G 699M 699M 74.7K 2.79G 1.45G 1.45G
|
||||
...
|
||||
dedup = 1.11, compress = 1.80, copies = 1.00, dedup * compress / copies = 2.00
|
||||
.Ed
|
||||
@ -330,22 +404,3 @@ dedup = 1.11, compress = 1.80, copies = 1.00, dedup * compress / copies = 2.00
|
||||
.Sh SEE ALSO
|
||||
.Xr zfs 8 ,
|
||||
.Xr zpool 8
|
||||
.Sh AUTHORS
|
||||
This manual page is a
|
||||
.Xr mdoc 7
|
||||
reimplementation of the
|
||||
.Tn illumos
|
||||
manual page
|
||||
.Em zdb(1M) ,
|
||||
modified and customized for
|
||||
.Fx
|
||||
and licensed under the
|
||||
Common Development and Distribution License
|
||||
.Pq Tn CDDL .
|
||||
.Pp
|
||||
The
|
||||
.Xr mdoc 7
|
||||
implementation of this manual page was initially written by
|
||||
.An Martin Matuska Aq mm@FreeBSD.org
|
||||
and
|
||||
.An Marcelo Araujo Aq araujo@FreeBSD.org .
|
||||
|
@ -23,6 +23,7 @@
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011, 2016 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2014 Integros [integros.com]
|
||||
* Copyright 2017 Nexenta Systems, Inc.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
@ -60,6 +61,7 @@
|
||||
#include <sys/ddt.h>
|
||||
#include <sys/zfeature.h>
|
||||
#include <sys/abd.h>
|
||||
#include <sys/blkptr.h>
|
||||
#include <zfs_comutil.h>
|
||||
#undef verify
|
||||
#include <libzfs.h>
|
||||
@ -120,18 +122,24 @@ static void
|
||||
usage(void)
|
||||
{
|
||||
(void) fprintf(stderr,
|
||||
"Usage: %s [-CumMdibcsDvhLXFPAG] [-t txg] [-e [-p path...]] "
|
||||
"[-U config] [-I inflight I/Os] [-x dumpdir] poolname [object...]\n"
|
||||
" %s [-divPA] [-e -p path...] [-U config] dataset "
|
||||
"[object...]\n"
|
||||
" %s -mM [-LXFPA] [-t txg] [-e [-p path...]] [-U config] "
|
||||
"poolname [vdev [metaslab...]]\n"
|
||||
" %s -R [-A] [-e [-p path...]] poolname "
|
||||
"vdev:offset:size[:flags]\n"
|
||||
" %s -S [-PA] [-e [-p path...]] [-U config] poolname\n"
|
||||
" %s -l [-uA] device\n"
|
||||
" %s -C [-A] [-U config]\n\n",
|
||||
cmdname, cmdname, cmdname, cmdname, cmdname, cmdname, cmdname);
|
||||
"Usage:\t%s [-AbcdDFGhiLMPsvX] [-e [-V] [-p <path> ...]] "
|
||||
"[-I <inflight I/Os>]\n"
|
||||
"\t\t[-o <var>=<value>]... [-t <txg>] [-U <cache>] [-x <dumpdir>]\n"
|
||||
"\t\t[<poolname> [<object> ...]]\n"
|
||||
"\t%s [-AdiPv] [-e [-V] [-p <path> ...]] [-U <cache>] <dataset> "
|
||||
"[<object> ...]\n"
|
||||
"\t%s -C [-A] [-U <cache>]\n"
|
||||
"\t%s -l [-Aqu] <device>\n"
|
||||
"\t%s -m [-AFLPX] [-e [-V] [-p <path> ...]] [-t <txg>] "
|
||||
"[-U <cache>]\n\t\t<poolname> [<vdev> [<metaslab> ...]]\n"
|
||||
"\t%s -O <dataset> <path>\n"
|
||||
"\t%s -R [-A] [-e [-V] [-p <path> ...]] [-U <cache>]\n"
|
||||
"\t\t<poolname> <vdev>:<offset>:<size>[:<flags>]\n"
|
||||
"\t%s -E [-A] word0:word1:...:word15\n"
|
||||
"\t%s -S [-AP] [-e [-V] [-p <path> ...]] [-U <cache>] "
|
||||
"<poolname>\n\n",
|
||||
cmdname, cmdname, cmdname, cmdname, cmdname, cmdname, cmdname,
|
||||
cmdname, cmdname);
|
||||
|
||||
(void) fprintf(stderr, " Dataset name must include at least one "
|
||||
"separator character '/' or '@'\n");
|
||||
@ -140,49 +148,57 @@ usage(void)
|
||||
(void) fprintf(stderr, " If object numbers are specified, only "
|
||||
"those objects are dumped\n\n");
|
||||
(void) fprintf(stderr, " Options to control amount of output:\n");
|
||||
(void) fprintf(stderr, " -u uberblock\n");
|
||||
(void) fprintf(stderr, " -d dataset(s)\n");
|
||||
(void) fprintf(stderr, " -i intent logs\n");
|
||||
(void) fprintf(stderr, " -C config (or cachefile if alone)\n");
|
||||
(void) fprintf(stderr, " -h pool history\n");
|
||||
(void) fprintf(stderr, " -b block statistics\n");
|
||||
(void) fprintf(stderr, " -m metaslabs\n");
|
||||
(void) fprintf(stderr, " -M metaslab groups\n");
|
||||
(void) fprintf(stderr, " -c checksum all metadata (twice for "
|
||||
"all data) blocks\n");
|
||||
(void) fprintf(stderr, " -s report stats on zdb's I/O\n");
|
||||
(void) fprintf(stderr, " -C config (or cachefile if alone)\n");
|
||||
(void) fprintf(stderr, " -d dataset(s)\n");
|
||||
(void) fprintf(stderr, " -D dedup statistics\n");
|
||||
(void) fprintf(stderr, " -S simulate dedup to measure effect\n");
|
||||
(void) fprintf(stderr, " -v verbose (applies to all others)\n");
|
||||
(void) fprintf(stderr, " -l dump label contents\n");
|
||||
(void) fprintf(stderr, " -E decode and display block from an "
|
||||
"embedded block pointer\n");
|
||||
(void) fprintf(stderr, " -h pool history\n");
|
||||
(void) fprintf(stderr, " -i intent logs\n");
|
||||
(void) fprintf(stderr, " -l read label contents\n");
|
||||
(void) fprintf(stderr, " -L disable leak tracking (do not "
|
||||
"load spacemaps)\n");
|
||||
(void) fprintf(stderr, " -m metaslabs\n");
|
||||
(void) fprintf(stderr, " -M metaslab groups\n");
|
||||
(void) fprintf(stderr, " -O perform object lookups by path\n");
|
||||
(void) fprintf(stderr, " -R read and display block from a "
|
||||
"device\n\n");
|
||||
"device\n");
|
||||
(void) fprintf(stderr, " -s report stats on zdb's I/O\n");
|
||||
(void) fprintf(stderr, " -S simulate dedup to measure effect\n");
|
||||
(void) fprintf(stderr, " -v verbose (applies to all "
|
||||
"others)\n\n");
|
||||
(void) fprintf(stderr, " Below options are intended for use "
|
||||
"with other options:\n");
|
||||
(void) fprintf(stderr, " -A ignore assertions (-A), enable "
|
||||
"panic recovery (-AA) or both (-AAA)\n");
|
||||
(void) fprintf(stderr, " -F attempt automatic rewind within "
|
||||
"safe range of transaction groups\n");
|
||||
(void) fprintf(stderr, " -U <cachefile_path> -- use alternate "
|
||||
"cachefile\n");
|
||||
(void) fprintf(stderr, " -X attempt extreme rewind (does not "
|
||||
"work with dataset)\n");
|
||||
(void) fprintf(stderr, " -e pool is exported/destroyed/"
|
||||
"has altroot/not in a cachefile\n");
|
||||
(void) fprintf(stderr, " -p <path> -- use one or more with "
|
||||
"-e to specify path to vdev dir\n");
|
||||
(void) fprintf(stderr, " -x <dumpdir> -- "
|
||||
"dump all read blocks into specified directory\n");
|
||||
(void) fprintf(stderr, " -P print numbers in parseable form\n");
|
||||
(void) fprintf(stderr, " -t <txg> -- highest txg to use when "
|
||||
"searching for uberblocks\n");
|
||||
(void) fprintf(stderr, " -F attempt automatic rewind within "
|
||||
"safe range of transaction groups\n");
|
||||
(void) fprintf(stderr, " -G dump zfs_dbgmsg buffer before "
|
||||
"exiting\n");
|
||||
(void) fprintf(stderr, " -I <number of inflight I/Os> -- "
|
||||
"specify the maximum number of "
|
||||
"checksumming I/Os [default is 200]\n");
|
||||
(void) fprintf(stderr, " -G dump zfs_dbgmsg buffer before "
|
||||
"exiting\n");
|
||||
(void) fprintf(stderr, " -o <variable>=<value> set global "
|
||||
"variable to an unsigned 32-bit integer value\n");
|
||||
(void) fprintf(stderr, " -p <path> -- use one or more with "
|
||||
"-e to specify path to vdev dir\n");
|
||||
(void) fprintf(stderr, " -P print numbers in parseable form\n");
|
||||
(void) fprintf(stderr, " -q don't print label contents\n");
|
||||
(void) fprintf(stderr, " -t <txg> -- highest txg to use when "
|
||||
"searching for uberblocks\n");
|
||||
(void) fprintf(stderr, " -u uberblock\n");
|
||||
(void) fprintf(stderr, " -U <cachefile_path> -- use alternate "
|
||||
"cachefile\n");
|
||||
(void) fprintf(stderr, " -V do verbatim import\n");
|
||||
(void) fprintf(stderr, " -x <dumpdir> -- "
|
||||
"dump all read blocks into specified directory\n");
|
||||
(void) fprintf(stderr, " -X attempt extreme rewind (does not "
|
||||
"work with dataset)\n\n");
|
||||
(void) fprintf(stderr, "Specify an option more than once (e.g. -bb) "
|
||||
"to make only that option verbose\n");
|
||||
(void) fprintf(stderr, "Default is to dump everything non-verbosely\n");
|
||||
@ -1582,8 +1598,9 @@ dump_deadlist(dsl_deadlist_t *dl)
|
||||
dle = AVL_NEXT(&dl->dl_tree, dle)) {
|
||||
if (dump_opt['d'] >= 5) {
|
||||
char buf[128];
|
||||
(void) snprintf(buf, sizeof (buf), "mintxg %llu -> "
|
||||
"obj %llu", (longlong_t)dle->dle_mintxg,
|
||||
(void) snprintf(buf, sizeof (buf),
|
||||
"mintxg %llu -> obj %llu",
|
||||
(longlong_t)dle->dle_mintxg,
|
||||
(longlong_t)dle->dle_bpobj.bpo_object);
|
||||
dump_full_bpobj(&dle->dle_bpobj, buf, 0);
|
||||
} else {
|
||||
@ -1597,8 +1614,55 @@ dump_deadlist(dsl_deadlist_t *dl)
|
||||
static avl_tree_t idx_tree;
|
||||
static avl_tree_t domain_tree;
|
||||
static boolean_t fuid_table_loaded;
|
||||
static boolean_t sa_loaded;
|
||||
sa_attr_type_t *sa_attr_table;
|
||||
static objset_t *sa_os = NULL;
|
||||
static sa_attr_type_t *sa_attr_table = NULL;
|
||||
|
||||
static int
|
||||
open_objset(const char *path, dmu_objset_type_t type, void *tag, objset_t **osp)
|
||||
{
|
||||
int err;
|
||||
uint64_t sa_attrs = 0;
|
||||
uint64_t version = 0;
|
||||
|
||||
VERIFY3P(sa_os, ==, NULL);
|
||||
err = dmu_objset_own(path, type, B_TRUE, tag, osp);
|
||||
if (err != 0) {
|
||||
(void) fprintf(stderr, "failed to own dataset '%s': %s\n", path,
|
||||
strerror(err));
|
||||
return (err);
|
||||
}
|
||||
|
||||
if (dmu_objset_type(*osp) == DMU_OST_ZFS) {
|
||||
(void) zap_lookup(*osp, MASTER_NODE_OBJ, ZPL_VERSION_STR,
|
||||
8, 1, &version);
|
||||
if (version >= ZPL_VERSION_SA) {
|
||||
(void) zap_lookup(*osp, MASTER_NODE_OBJ, ZFS_SA_ATTRS,
|
||||
8, 1, &sa_attrs);
|
||||
}
|
||||
err = sa_setup(*osp, sa_attrs, zfs_attr_table, ZPL_END,
|
||||
&sa_attr_table);
|
||||
if (err != 0) {
|
||||
(void) fprintf(stderr, "sa_setup failed: %s\n",
|
||||
strerror(err));
|
||||
dmu_objset_disown(*osp, tag);
|
||||
*osp = NULL;
|
||||
}
|
||||
}
|
||||
sa_os = *osp;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
close_objset(objset_t *os, void *tag)
|
||||
{
|
||||
VERIFY3P(os, ==, sa_os);
|
||||
if (os->os_sa != NULL)
|
||||
sa_tear_down(os);
|
||||
dmu_objset_disown(os, tag);
|
||||
sa_attr_table = NULL;
|
||||
sa_os = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
fuid_table_destroy()
|
||||
@ -1670,25 +1734,7 @@ dump_znode(objset_t *os, uint64_t object, void *data, size_t size)
|
||||
int idx = 0;
|
||||
int error;
|
||||
|
||||
if (!sa_loaded) {
|
||||
uint64_t sa_attrs = 0;
|
||||
uint64_t version;
|
||||
|
||||
VERIFY(zap_lookup(os, MASTER_NODE_OBJ, ZPL_VERSION_STR,
|
||||
8, 1, &version) == 0);
|
||||
if (version >= ZPL_VERSION_SA) {
|
||||
VERIFY(zap_lookup(os, MASTER_NODE_OBJ, ZFS_SA_ATTRS,
|
||||
8, 1, &sa_attrs) == 0);
|
||||
}
|
||||
if ((error = sa_setup(os, sa_attrs, zfs_attr_table,
|
||||
ZPL_END, &sa_attr_table)) != 0) {
|
||||
(void) printf("sa_setup failed errno %d, can't "
|
||||
"display znode contents\n", error);
|
||||
return;
|
||||
}
|
||||
sa_loaded = B_TRUE;
|
||||
}
|
||||
|
||||
VERIFY3P(os, ==, sa_os);
|
||||
if (sa_handle_get(os, object, NULL, SA_HDL_PRIVATE, &hdl)) {
|
||||
(void) printf("Failed to get handle for SA znode\n");
|
||||
return;
|
||||
@ -2156,44 +2202,154 @@ dump_label_uberblocks(vdev_label_t *lbl, uint64_t ashift)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
static char curpath[PATH_MAX];
|
||||
|
||||
/*
|
||||
* Iterate through the path components, recursively passing
|
||||
* current one's obj and remaining path until we find the obj
|
||||
* for the last one.
|
||||
*/
|
||||
static int
|
||||
dump_path_impl(objset_t *os, uint64_t obj, char *name)
|
||||
{
|
||||
int err;
|
||||
int header = 1;
|
||||
uint64_t child_obj;
|
||||
char *s;
|
||||
dmu_buf_t *db;
|
||||
dmu_object_info_t doi;
|
||||
|
||||
if ((s = strchr(name, '/')) != NULL)
|
||||
*s = '\0';
|
||||
err = zap_lookup(os, obj, name, 8, 1, &child_obj);
|
||||
|
||||
(void) strlcat(curpath, name, sizeof (curpath));
|
||||
|
||||
if (err != 0) {
|
||||
(void) fprintf(stderr, "failed to lookup %s: %s\n",
|
||||
curpath, strerror(err));
|
||||
return (err);
|
||||
}
|
||||
|
||||
child_obj = ZFS_DIRENT_OBJ(child_obj);
|
||||
err = sa_buf_hold(os, child_obj, FTAG, &db);
|
||||
if (err != 0) {
|
||||
(void) fprintf(stderr,
|
||||
"failed to get SA dbuf for obj %llu: %s\n",
|
||||
(u_longlong_t)child_obj, strerror(err));
|
||||
return (EINVAL);
|
||||
}
|
||||
dmu_object_info_from_db(db, &doi);
|
||||
sa_buf_rele(db, FTAG);
|
||||
|
||||
if (doi.doi_bonus_type != DMU_OT_SA &&
|
||||
doi.doi_bonus_type != DMU_OT_ZNODE) {
|
||||
(void) fprintf(stderr, "invalid bonus type %d for obj %llu\n",
|
||||
doi.doi_bonus_type, (u_longlong_t)child_obj);
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
if (dump_opt['v'] > 6) {
|
||||
(void) printf("obj=%llu %s type=%d bonustype=%d\n",
|
||||
(u_longlong_t)child_obj, curpath, doi.doi_type,
|
||||
doi.doi_bonus_type);
|
||||
}
|
||||
|
||||
(void) strlcat(curpath, "/", sizeof (curpath));
|
||||
|
||||
switch (doi.doi_type) {
|
||||
case DMU_OT_DIRECTORY_CONTENTS:
|
||||
if (s != NULL && *(s + 1) != '\0')
|
||||
return (dump_path_impl(os, child_obj, s + 1));
|
||||
/*FALLTHROUGH*/
|
||||
case DMU_OT_PLAIN_FILE_CONTENTS:
|
||||
dump_object(os, child_obj, dump_opt['v'], &header);
|
||||
return (0);
|
||||
default:
|
||||
(void) fprintf(stderr, "object %llu has non-file/directory "
|
||||
"type %d\n", (u_longlong_t)obj, doi.doi_type);
|
||||
break;
|
||||
}
|
||||
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Dump the blocks for the object specified by path inside the dataset.
|
||||
*/
|
||||
static int
|
||||
dump_path(char *ds, char *path)
|
||||
{
|
||||
int err;
|
||||
objset_t *os;
|
||||
uint64_t root_obj;
|
||||
|
||||
err = open_objset(ds, DMU_OST_ZFS, FTAG, &os);
|
||||
if (err != 0)
|
||||
return (err);
|
||||
|
||||
err = zap_lookup(os, MASTER_NODE_OBJ, ZFS_ROOT_OBJ, 8, 1, &root_obj);
|
||||
if (err != 0) {
|
||||
(void) fprintf(stderr, "can't lookup root znode: %s\n",
|
||||
strerror(err));
|
||||
dmu_objset_disown(os, FTAG);
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
(void) snprintf(curpath, sizeof (curpath), "dataset=%s path=/", ds);
|
||||
|
||||
err = dump_path_impl(os, root_obj, path);
|
||||
|
||||
close_objset(os, FTAG);
|
||||
return (err);
|
||||
}
|
||||
|
||||
static int
|
||||
dump_label(const char *dev)
|
||||
{
|
||||
int fd;
|
||||
vdev_label_t label;
|
||||
char *path, *buf = label.vl_vdev_phys.vp_nvlist;
|
||||
char path[MAXPATHLEN];
|
||||
char *buf = label.vl_vdev_phys.vp_nvlist;
|
||||
size_t buflen = sizeof (label.vl_vdev_phys.vp_nvlist);
|
||||
struct stat64 statbuf;
|
||||
uint64_t psize, ashift;
|
||||
int len = strlen(dev) + 1;
|
||||
boolean_t label_found = B_FALSE;
|
||||
|
||||
if (strncmp(dev, ZFS_DISK_ROOTD, strlen(ZFS_DISK_ROOTD)) == 0) {
|
||||
len++;
|
||||
path = malloc(len);
|
||||
(void) snprintf(path, len, "%s%s", ZFS_RDISK_ROOTD,
|
||||
dev + strlen(ZFS_DISK_ROOTD));
|
||||
} else {
|
||||
path = strdup(dev);
|
||||
(void) strlcpy(path, dev, sizeof (path));
|
||||
if (dev[0] == '/') {
|
||||
if (strncmp(dev, ZFS_DISK_ROOTD,
|
||||
strlen(ZFS_DISK_ROOTD)) == 0) {
|
||||
(void) snprintf(path, sizeof (path), "%s%s",
|
||||
ZFS_RDISK_ROOTD, dev + strlen(ZFS_DISK_ROOTD));
|
||||
}
|
||||
} else if (stat64(path, &statbuf) != 0) {
|
||||
char *s;
|
||||
|
||||
(void) snprintf(path, sizeof (path), "%s%s", ZFS_RDISK_ROOTD,
|
||||
dev);
|
||||
if (((s = strrchr(dev, 's')) == NULL &&
|
||||
(s = strchr(dev, 'p')) == NULL) ||
|
||||
!isdigit(*(s + 1)))
|
||||
(void) strlcat(path, "s0", sizeof (path));
|
||||
}
|
||||
|
||||
if ((fd = open64(path, O_RDONLY)) < 0) {
|
||||
(void) printf("cannot open '%s': %s\n", path, strerror(errno));
|
||||
free(path);
|
||||
(void) fprintf(stderr, "cannot open '%s': %s\n", path,
|
||||
strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (fstat64(fd, &statbuf) != 0) {
|
||||
(void) printf("failed to stat '%s': %s\n", path,
|
||||
(void) fprintf(stderr, "failed to stat '%s': %s\n", path,
|
||||
strerror(errno));
|
||||
free(path);
|
||||
(void) close(fd);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (S_ISBLK(statbuf.st_mode)) {
|
||||
(void) printf("cannot use '%s': character device required\n",
|
||||
path);
|
||||
free(path);
|
||||
(void) fprintf(stderr,
|
||||
"cannot use '%s': character device required\n", path);
|
||||
(void) close(fd);
|
||||
exit(1);
|
||||
}
|
||||
@ -2204,36 +2360,43 @@ dump_label(const char *dev)
|
||||
for (int l = 0; l < VDEV_LABELS; l++) {
|
||||
nvlist_t *config = NULL;
|
||||
|
||||
(void) printf("--------------------------------------------\n");
|
||||
(void) printf("LABEL %d\n", l);
|
||||
(void) printf("--------------------------------------------\n");
|
||||
if (!dump_opt['q']) {
|
||||
(void) printf("------------------------------------\n");
|
||||
(void) printf("LABEL %d\n", l);
|
||||
(void) printf("------------------------------------\n");
|
||||
}
|
||||
|
||||
if (pread64(fd, &label, sizeof (label),
|
||||
vdev_label_offset(psize, l, 0)) != sizeof (label)) {
|
||||
(void) printf("failed to read label %d\n", l);
|
||||
if (!dump_opt['q'])
|
||||
(void) printf("failed to read label %d\n", l);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (nvlist_unpack(buf, buflen, &config, 0) != 0) {
|
||||
(void) printf("failed to unpack label %d\n", l);
|
||||
if (!dump_opt['q'])
|
||||
(void) printf("failed to unpack label %d\n", l);
|
||||
ashift = SPA_MINBLOCKSHIFT;
|
||||
} else {
|
||||
nvlist_t *vdev_tree = NULL;
|
||||
|
||||
dump_nvlist(config, 4);
|
||||
if (!dump_opt['q'])
|
||||
dump_nvlist(config, 4);
|
||||
if ((nvlist_lookup_nvlist(config,
|
||||
ZPOOL_CONFIG_VDEV_TREE, &vdev_tree) != 0) ||
|
||||
(nvlist_lookup_uint64(vdev_tree,
|
||||
ZPOOL_CONFIG_ASHIFT, &ashift) != 0))
|
||||
ashift = SPA_MINBLOCKSHIFT;
|
||||
nvlist_free(config);
|
||||
label_found = B_TRUE;
|
||||
}
|
||||
if (dump_opt['u'])
|
||||
dump_label_uberblocks(&label, ashift);
|
||||
}
|
||||
|
||||
free(path);
|
||||
(void) close(fd);
|
||||
|
||||
return (label_found ? 0 : 2);
|
||||
}
|
||||
|
||||
static uint64_t dataset_feature_count[SPA_FEATURES];
|
||||
@ -2245,11 +2408,9 @@ dump_one_dir(const char *dsname, void *arg)
|
||||
int error;
|
||||
objset_t *os;
|
||||
|
||||
error = dmu_objset_own(dsname, DMU_OST_ANY, B_TRUE, FTAG, &os);
|
||||
if (error) {
|
||||
(void) printf("Could not open %s, error %d\n", dsname, error);
|
||||
error = open_objset(dsname, DMU_OST_ANY, FTAG, &os);
|
||||
if (error != 0)
|
||||
return (0);
|
||||
}
|
||||
|
||||
for (spa_feature_t f = 0; f < SPA_FEATURES; f++) {
|
||||
if (!dmu_objset_ds(os)->ds_feature_inuse[f])
|
||||
@ -2260,9 +2421,8 @@ dump_one_dir(const char *dsname, void *arg)
|
||||
}
|
||||
|
||||
dump_dir(os);
|
||||
dmu_objset_disown(os, FTAG);
|
||||
close_objset(os, FTAG);
|
||||
fuid_table_destroy();
|
||||
sa_loaded = B_FALSE;
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -3497,6 +3657,33 @@ zdb_read_block(char *thing, spa_t *spa)
|
||||
free(dup);
|
||||
}
|
||||
|
||||
static void
|
||||
zdb_embedded_block(char *thing)
|
||||
{
|
||||
blkptr_t bp = { 0 };
|
||||
unsigned long long *words = (void *)&bp;
|
||||
char buf[SPA_MAXBLOCKSIZE];
|
||||
int err;
|
||||
|
||||
err = sscanf(thing, "%llx:%llx:%llx:%llx:%llx:%llx:%llx:%llx:"
|
||||
"%llx:%llx:%llx:%llx:%llx:%llx:%llx:%llx",
|
||||
words + 0, words + 1, words + 2, words + 3,
|
||||
words + 4, words + 5, words + 6, words + 7,
|
||||
words + 8, words + 9, words + 10, words + 11,
|
||||
words + 12, words + 13, words + 14, words + 15);
|
||||
if (err != 16) {
|
||||
(void) printf("invalid input format\n");
|
||||
exit(1);
|
||||
}
|
||||
ASSERT3U(BPE_GET_LSIZE(&bp), <=, SPA_MAXBLOCKSIZE);
|
||||
err = decode_embedded_bp(&bp, buf, BPE_GET_LSIZE(&bp));
|
||||
if (err != 0) {
|
||||
(void) printf("decode failed: %u\n", err);
|
||||
exit(1);
|
||||
}
|
||||
zdb_dump_block_raw(buf, BPE_GET_LSIZE(&bp), 0);
|
||||
}
|
||||
|
||||
static boolean_t
|
||||
pool_match(nvlist_t *cfg, char *tgt)
|
||||
{
|
||||
@ -3595,6 +3782,7 @@ main(int argc, char **argv)
|
||||
char *target;
|
||||
nvlist_t *policy = NULL;
|
||||
uint64_t max_txg = UINT64_MAX;
|
||||
int flags = ZFS_IMPORT_MISSING_LOG;
|
||||
int rewind = ZPOOL_NEVER_REWIND;
|
||||
char *spa_config_path_env;
|
||||
boolean_t target_is_spa = B_TRUE;
|
||||
@ -3614,34 +3802,38 @@ main(int argc, char **argv)
|
||||
spa_config_path = spa_config_path_env;
|
||||
|
||||
while ((c = getopt(argc, argv,
|
||||
"bcdhilmMI:suCDRSAFLXx:evp:t:U:PG")) != -1) {
|
||||
"AbcCdDeEFGhiI:lLmMo:Op:PqRsSt:uU:vVx:X")) != -1) {
|
||||
switch (c) {
|
||||
case 'b':
|
||||
case 'c':
|
||||
case 'C':
|
||||
case 'd':
|
||||
case 'D':
|
||||
case 'E':
|
||||
case 'G':
|
||||
case 'h':
|
||||
case 'i':
|
||||
case 'l':
|
||||
case 'm':
|
||||
case 's':
|
||||
case 'u':
|
||||
case 'C':
|
||||
case 'D':
|
||||
case 'M':
|
||||
case 'O':
|
||||
case 'R':
|
||||
case 's':
|
||||
case 'S':
|
||||
case 'G':
|
||||
case 'u':
|
||||
dump_opt[c]++;
|
||||
dump_all = 0;
|
||||
break;
|
||||
case 'A':
|
||||
case 'e':
|
||||
case 'F':
|
||||
case 'L':
|
||||
case 'X':
|
||||
case 'e':
|
||||
case 'P':
|
||||
case 'q':
|
||||
case 'X':
|
||||
dump_opt[c]++;
|
||||
break;
|
||||
/* NB: Sort single match options below. */
|
||||
case 'I':
|
||||
max_inflight = strtoull(optarg, NULL, 0);
|
||||
if (max_inflight == 0) {
|
||||
@ -3651,6 +3843,11 @@ main(int argc, char **argv)
|
||||
usage();
|
||||
}
|
||||
break;
|
||||
case 'o':
|
||||
error = set_global_var(optarg);
|
||||
if (error != 0)
|
||||
usage();
|
||||
break;
|
||||
case 'p':
|
||||
if (searchdirs == NULL) {
|
||||
searchdirs = umem_alloc(sizeof (char *),
|
||||
@ -3676,10 +3873,19 @@ main(int argc, char **argv)
|
||||
break;
|
||||
case 'U':
|
||||
spa_config_path = optarg;
|
||||
if (spa_config_path[0] != '/') {
|
||||
(void) fprintf(stderr,
|
||||
"cachefile must be an absolute path "
|
||||
"(i.e. start with a slash)\n");
|
||||
usage();
|
||||
}
|
||||
break;
|
||||
case 'v':
|
||||
verbose++;
|
||||
break;
|
||||
case 'V':
|
||||
flags = ZFS_IMPORT_VERBATIM;
|
||||
break;
|
||||
case 'x':
|
||||
vn_dumpdir = optarg;
|
||||
break;
|
||||
@ -3721,7 +3927,7 @@ main(int argc, char **argv)
|
||||
verbose = MAX(verbose, 1);
|
||||
|
||||
for (c = 0; c < 256; c++) {
|
||||
if (dump_all && !strchr("elAFLRSXP", c))
|
||||
if (dump_all && strchr("AeEFlLOPRSX", c) == NULL)
|
||||
dump_opt[c] = 1;
|
||||
if (dump_opt[c])
|
||||
dump_opt[c] += verbose;
|
||||
@ -3735,6 +3941,14 @@ main(int argc, char **argv)
|
||||
|
||||
if (argc < 2 && dump_opt['R'])
|
||||
usage();
|
||||
|
||||
if (dump_opt['E']) {
|
||||
if (argc != 1)
|
||||
usage();
|
||||
zdb_embedded_block(argv[0]);
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (argc < 1) {
|
||||
if (!dump_opt['e'] && dump_opt['C']) {
|
||||
dump_cachefile(spa_config_path);
|
||||
@ -3743,9 +3957,14 @@ main(int argc, char **argv)
|
||||
usage();
|
||||
}
|
||||
|
||||
if (dump_opt['l']) {
|
||||
dump_label(argv[0]);
|
||||
return (0);
|
||||
if (dump_opt['l'])
|
||||
return (dump_label(argv[0]));
|
||||
|
||||
if (dump_opt['O']) {
|
||||
if (argc != 2)
|
||||
usage();
|
||||
dump_opt['v'] = verbose + 3;
|
||||
return (dump_path(argv[0], argv[1]));
|
||||
}
|
||||
|
||||
if (dump_opt['X'] || dump_opt['F'])
|
||||
@ -3775,11 +3994,7 @@ main(int argc, char **argv)
|
||||
fatal("can't open '%s': %s",
|
||||
target, strerror(ENOMEM));
|
||||
}
|
||||
if ((error = spa_import(name, cfg, NULL,
|
||||
ZFS_IMPORT_MISSING_LOG)) != 0) {
|
||||
error = spa_import(name, cfg, NULL,
|
||||
ZFS_IMPORT_VERBATIM);
|
||||
}
|
||||
error = spa_import(name, cfg, NULL, flags);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3822,8 +4037,7 @@ main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
error = dmu_objset_own(target, DMU_OST_ANY,
|
||||
B_TRUE, FTAG, &os);
|
||||
error = open_objset(target, DMU_OST_ANY, FTAG, &os);
|
||||
}
|
||||
}
|
||||
nvlist_free(policy);
|
||||
@ -3866,10 +4080,12 @@ main(int argc, char **argv)
|
||||
zdb_read_block(argv[i], spa);
|
||||
}
|
||||
|
||||
(os != NULL) ? dmu_objset_disown(os, FTAG) : spa_close(spa, FTAG);
|
||||
if (os != NULL)
|
||||
close_objset(os, FTAG);
|
||||
else
|
||||
spa_close(spa, FTAG);
|
||||
|
||||
fuid_table_destroy();
|
||||
sa_loaded = B_FALSE;
|
||||
|
||||
dump_debug_buffer();
|
||||
|
||||
|
536
cddl/contrib/opensolaris/cmd/zfs/zfs-program.8
Normal file
536
cddl/contrib/opensolaris/cmd/zfs/zfs-program.8
Normal file
@ -0,0 +1,536 @@
|
||||
.\" This file and its contents are supplied under the terms of the
|
||||
.\" Common Development and Distribution License ("CDDL"), version 1.0.
|
||||
.\" You may only use this file in accordance with the terms of version
|
||||
.\" 1.0 of the CDDL.
|
||||
.\"
|
||||
.\" A full copy of the text of the CDDL should have accompanied this
|
||||
.\" source. A copy of the CDDL is also available via the Internet at
|
||||
.\" http://www.illumos.org/license/CDDL.
|
||||
.\"
|
||||
.\"
|
||||
.\" Copyright (c) 2016, 2017 by Delphix. All rights reserved.
|
||||
.\"
|
||||
.Dd October 02, 2017
|
||||
.Dt ZFS-PROGRAM 1M
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm zfs program
|
||||
.Nd executes ZFS channel programs
|
||||
.Sh SYNOPSIS
|
||||
.Cm zfs program
|
||||
.Op Fl t Ar instruction-limit
|
||||
.Op Fl m Ar memory-limit
|
||||
.Ar pool
|
||||
.Ar script
|
||||
.\".Op Ar optional arguments to channel program
|
||||
.Sh DESCRIPTION
|
||||
The ZFS channel program interface allows ZFS administrative operations to be
|
||||
run programmatically as a Lua script.
|
||||
The entire script is executed atomically, with no other administrative
|
||||
operations taking effect concurrently.
|
||||
A library of ZFS calls is made available to channel program scripts.
|
||||
Channel programs may only be run with root privileges.
|
||||
.Pp
|
||||
A modified version of the Lua 5.2 interpreter is used to run channel program
|
||||
scripts.
|
||||
The Lua 5.2 manual can be found at:
|
||||
.Bd -centered -offset indent
|
||||
.Lk http://www.lua.org/manual/5.2/
|
||||
.Ed
|
||||
.Pp
|
||||
The channel program given by
|
||||
.Ar script
|
||||
will be run on
|
||||
.Ar pool ,
|
||||
and any attempts to access or modify other pools will cause an error.
|
||||
.Sh OPTIONS
|
||||
.Bl -tag -width "-t"
|
||||
.It Fl t Ar instruction-limit
|
||||
Execution time limit, in number of Lua instructions to execute.
|
||||
If a channel program executes more than the specified number of instructions,
|
||||
it will be stopped and an error will be returned.
|
||||
The default limit is 10 million instructions, and it can be set to a maximum of
|
||||
100 million instructions.
|
||||
.It Fl m Ar memory-limit
|
||||
Memory limit, in bytes.
|
||||
If a channel program attempts to allocate more memory than the given limit, it
|
||||
will be stopped and an error returned.
|
||||
The default memory limit is 10 MB, and can be set to a maximum of 100 MB.
|
||||
.El
|
||||
.Pp
|
||||
All remaining argument strings will be passed directly to the Lua script as
|
||||
described in the
|
||||
.Sx LUA INTERFACE
|
||||
section below.
|
||||
.Sh LUA INTERFACE
|
||||
A channel program can be invoked either from the command line, or via a library
|
||||
call to
|
||||
.Fn lzc_channel_program .
|
||||
.Ss Arguments
|
||||
Arguments passed to the channel program are converted to a Lua table.
|
||||
If invoked from the command line, extra arguments to the Lua script will be
|
||||
accessible as an array stored in the argument table with the key 'argv':
|
||||
.Bd -literal -offset indent
|
||||
args = ...
|
||||
argv = args["argv"]
|
||||
-- argv == {1="arg1", 2="arg2", ...}
|
||||
.Ed
|
||||
.Pp
|
||||
If invoked from the libZFS interface, an arbitrary argument list can be
|
||||
passed to the channel program, which is accessible via the same
|
||||
"..." syntax in Lua:
|
||||
.Bd -literal -offset indent
|
||||
args = ...
|
||||
-- args == {"foo"="bar", "baz"={...}, ...}
|
||||
.Ed
|
||||
.Pp
|
||||
Note that because Lua arrays are 1-indexed, arrays passed to Lua from the
|
||||
libZFS interface will have their indices incremented by 1.
|
||||
That is, the element
|
||||
in
|
||||
.Va arr[0]
|
||||
in a C array passed to a channel program will be stored in
|
||||
.Va arr[1]
|
||||
when accessed from Lua.
|
||||
.Ss Return Values
|
||||
Lua return statements take the form:
|
||||
.Bd -literal -offset indent
|
||||
return ret0, ret1, ret2, ...
|
||||
.Ed
|
||||
.Pp
|
||||
Return statements returning multiple values are permitted internally in a
|
||||
channel program script, but attempting to return more than one value from the
|
||||
top level of the channel program is not permitted and will throw an error.
|
||||
However, tables containing multiple values can still be returned.
|
||||
If invoked from the command line, a return statement:
|
||||
.Bd -literal -offset indent
|
||||
a = {foo="bar", baz=2}
|
||||
return a
|
||||
.Ed
|
||||
.Pp
|
||||
Will be output formatted as:
|
||||
.Bd -literal -offset indent
|
||||
Channel program fully executed with return value:
|
||||
return:
|
||||
baz: 2
|
||||
foo: 'bar'
|
||||
.Ed
|
||||
.Ss Fatal Errors
|
||||
If the channel program encounters a fatal error while running, a non-zero exit
|
||||
status will be returned.
|
||||
If more information about the error is available, a singleton list will be
|
||||
returned detailing the error:
|
||||
.Bd -literal -offset indent
|
||||
error: "error string, including Lua stack trace"
|
||||
.Ed
|
||||
.Pp
|
||||
If a fatal error is returned, the channel program may have not executed at all,
|
||||
may have partially executed, or may have fully executed but failed to pass a
|
||||
return value back to userland.
|
||||
.Pp
|
||||
If the channel program exhausts an instruction or memory limit, a fatal error
|
||||
will be generated and the program will be stopped, leaving the program partially
|
||||
executed.
|
||||
No attempt is made to reverse or undo any operations already performed.
|
||||
Note that because both the instruction count and amount of memory used by a
|
||||
channel program are deterministic when run against the same inputs and
|
||||
filesystem state, as long as a channel program has run successfully once, you
|
||||
can guarantee that it will finish successfully against a similar size system.
|
||||
.Pp
|
||||
If a channel program attempts to return too large a value, the program will
|
||||
fully execute but exit with a nonzero status code and no return value.
|
||||
.Pp
|
||||
.Em Note:
|
||||
ZFS API functions do not generate Fatal Errors when correctly invoked, they
|
||||
return an error code and the channel program continues executing.
|
||||
See the
|
||||
.Sx ZFS API
|
||||
section below for function-specific details on error return codes.
|
||||
.Ss Lua to C Value Conversion
|
||||
When invoking a channel program via the libZFS interface, it is necessary to
|
||||
translate arguments and return values from Lua values to their C equivalents,
|
||||
and vice-versa.
|
||||
.Pp
|
||||
There is a correspondence between nvlist values in C and Lua tables.
|
||||
A Lua table which is returned from the channel program will be recursively
|
||||
converted to an nvlist, with table values converted to their natural
|
||||
equivalents:
|
||||
.Bd -literal -offset indent
|
||||
string -> string
|
||||
number -> int64
|
||||
boolean -> boolean_value
|
||||
nil -> boolean (no value)
|
||||
table -> nvlist
|
||||
.Ed
|
||||
.Pp
|
||||
Likewise, table keys are replaced by string equivalents as follows:
|
||||
.Bd -literal -offset indent
|
||||
string -> no change
|
||||
number -> signed decimal string ("%lld")
|
||||
boolean -> "true" | "false"
|
||||
.Ed
|
||||
.Pp
|
||||
Any collision of table key strings (for example, the string "true" and a
|
||||
true boolean value) will cause a fatal error.
|
||||
.Pp
|
||||
Lua numbers are represented internally as signed 64-bit integers.
|
||||
.Sh LUA STANDARD LIBRARY
|
||||
The following Lua built-in base library functions are available:
|
||||
.Bd -literal -offset indent
|
||||
assert rawlen
|
||||
collectgarbage rawget
|
||||
error rawset
|
||||
getmetatable select
|
||||
ipairs setmetatable
|
||||
next tonumber
|
||||
pairs tostring
|
||||
rawequal type
|
||||
.Ed
|
||||
.Pp
|
||||
All functions in the
|
||||
.Em coroutine ,
|
||||
.Em string ,
|
||||
and
|
||||
.Em table
|
||||
built-in submodules are also available.
|
||||
A complete list and documentation of these modules is available in the Lua
|
||||
manual.
|
||||
.Pp
|
||||
The following functions base library functions have been disabled and are
|
||||
not available for use in channel programs:
|
||||
.Bd -literal -offset indent
|
||||
dofile
|
||||
loadfile
|
||||
load
|
||||
pcall
|
||||
print
|
||||
xpcall
|
||||
.Ed
|
||||
.Sh ZFS API
|
||||
.Ss Function Arguments
|
||||
Each API function takes a fixed set of required positional arguments and
|
||||
optional keyword arguments.
|
||||
For example, the destroy function takes a single positional string argument
|
||||
(the name of the dataset to destroy) and an optional "defer" keyword boolean
|
||||
argument.
|
||||
When using parentheses to specify the arguments to a Lua function, only
|
||||
positional arguments can be used:
|
||||
.Bd -literal -offset indent
|
||||
zfs.sync.destroy("rpool@snap")
|
||||
.Ed
|
||||
.Pp
|
||||
To use keyword arguments, functions must be called with a single argument that
|
||||
is a Lua table containing entries mapping integers to positional arguments and
|
||||
strings to keyword arguments:
|
||||
.Bd -literal -offset indent
|
||||
zfs.sync.destroy({1="rpool@snap", defer=true})
|
||||
.Ed
|
||||
.Pp
|
||||
The Lua language allows curly braces to be used in place of parenthesis as
|
||||
syntactic sugar for this calling convention:
|
||||
.Bd -literal -offset indent
|
||||
zfs.sync.snapshot{"rpool@snap", defer=true}
|
||||
.Ed
|
||||
.Ss Function Return Values
|
||||
If an API function succeeds, it returns 0.
|
||||
If it fails, it returns an error code and the channel program continues
|
||||
executing.
|
||||
API functions do not generate Fatal Errors except in the case of an
|
||||
unrecoverable internal file system error.
|
||||
.Pp
|
||||
In addition to returning an error code, some functions also return extra
|
||||
details describing what caused the error.
|
||||
This extra description is given as a second return value, and will always be a
|
||||
Lua table, or Nil if no error details were returned.
|
||||
Different keys will exist in the error details table depending on the function
|
||||
and error case.
|
||||
Any such function may be called expecting a single return value:
|
||||
.Bd -literal -offset indent
|
||||
errno = zfs.sync.promote(dataset)
|
||||
.Ed
|
||||
.Pp
|
||||
Or, the error details can be retrieved:
|
||||
.Bd -literal -offset indent
|
||||
errno, details = zfs.sync.promote(dataset)
|
||||
if (errno == EEXIST) then
|
||||
assert(details ~= Nil)
|
||||
list_of_conflicting_snapshots = details
|
||||
end
|
||||
.Ed
|
||||
.Pp
|
||||
The following global aliases for API function error return codes are defined
|
||||
for use in channel programs:
|
||||
.Bd -literal -offset indent
|
||||
EPERM ECHILD ENODEV ENOSPC
|
||||
ENOENT EAGAIN ENOTDIR ESPIPE
|
||||
ESRCH ENOMEM EISDIR EROFS
|
||||
EINTR EACCES EINVAL EMLINK
|
||||
EIO EFAULT ENFILE EPIPE
|
||||
ENXIO ENOTBLK EMFILE EDOM
|
||||
E2BIG EBUSY ENOTTY ERANGE
|
||||
ENOEXEC EEXIST ETXTBSY EDQUOT
|
||||
EBADF EXDEV EFBIG
|
||||
.Ed
|
||||
.Ss API Functions
|
||||
For detailed descriptions of the exact behavior of any zfs administrative
|
||||
operations, see the main
|
||||
.Xr zfs 1
|
||||
manual page.
|
||||
.Bl -tag -width "xx"
|
||||
.It Em zfs.debug(msg)
|
||||
Record a debug message in the zfs_dbgmsg log.
|
||||
A log of these messages can be printed via mdb's "::zfs_dbgmsg" command, or
|
||||
can be monitored live by running:
|
||||
.Bd -literal -offset indent
|
||||
dtrace -n 'zfs-dbgmsg{trace(stringof(arg0))}'
|
||||
.Ed
|
||||
.Pp
|
||||
msg (string)
|
||||
.Bd -ragged -compact -offset "xxxx"
|
||||
Debug message to be printed.
|
||||
.Ed
|
||||
.It Em zfs.exists(dataset)
|
||||
Returns true if the given dataset exists, or false if it doesn't.
|
||||
A fatal error will be thrown if the dataset is not in the target pool.
|
||||
That is, in a channel program running on rpool,
|
||||
zfs.exists("rpool/nonexistent_fs") returns false, but
|
||||
zfs.exists("somepool/fs_that_may_exist") will error.
|
||||
.Pp
|
||||
dataset (string)
|
||||
.Bd -ragged -compact -offset "xxxx"
|
||||
Dataset to check for existence.
|
||||
Must be in the target pool.
|
||||
.Ed
|
||||
.It Em zfs.get_prop(dataset, property)
|
||||
Returns two values.
|
||||
First, a string, number or table containing the property value for the given
|
||||
dataset.
|
||||
Second, a string containing the source of the property (i.e. the name of the
|
||||
dataset in which it was set or nil if it is readonly).
|
||||
Throws a Lua error if the dataset is invalid or the property doesn't exist.
|
||||
Note that Lua only supports int64 number types whereas ZFS number properties
|
||||
are uint64.
|
||||
This means very large values (like guid) may wrap around and appear negative.
|
||||
.Pp
|
||||
dataset (string)
|
||||
.Bd -ragged -compact -offset "xxxx"
|
||||
Filesystem or snapshot path to retrieve properties from.
|
||||
.Ed
|
||||
.Pp
|
||||
property (string)
|
||||
.Bd -ragged -compact -offset "xxxx"
|
||||
Name of property to retrieve.
|
||||
All filesystem, snapshot and volume properties are supported except
|
||||
for 'mounted' and 'iscsioptions.'
|
||||
Also supports the 'written@snap' and 'written#bookmark' properties and
|
||||
the '<user|group><quota|used>@id' properties, though the id must be in numeric
|
||||
form.
|
||||
.Ed
|
||||
.El
|
||||
.Bl -tag -width "xx"
|
||||
.It Sy zfs.sync submodule
|
||||
The sync submodule contains functions that modify the on-disk state.
|
||||
They are executed in "syncing context".
|
||||
.Pp
|
||||
The available sync submodule functions are as follows:
|
||||
.Bl -tag -width "xx"
|
||||
.It Em zfs.sync.destroy(dataset, [defer=true|false])
|
||||
Destroy the given dataset.
|
||||
Returns 0 on successful destroy, or a nonzero error code if the dataset could
|
||||
not be destroyed (for example, if the dataset has any active children or
|
||||
clones).
|
||||
.Pp
|
||||
dataset (string)
|
||||
.Bd -ragged -compact -offset "xxxx"
|
||||
Filesystem or snapshot to be destroyed.
|
||||
.Ed
|
||||
.Pp
|
||||
[optional] defer (boolean)
|
||||
.Bd -ragged -compact -offset "xxxx"
|
||||
Valid only for destroying snapshots.
|
||||
If set to true, and the snapshot has holds or clones, allows the snapshot to be
|
||||
marked for deferred deletion rather than failing.
|
||||
.Ed
|
||||
.It Em zfs.sync.promote(dataset)
|
||||
Promote the given clone to a filesystem.
|
||||
Returns 0 on successful promotion, or a nonzero error code otherwise.
|
||||
If EEXIST is returned, the second return value will be an array of the clone's
|
||||
snapshots whose names collide with snapshots of the parent filesystem.
|
||||
.Pp
|
||||
dataset (string)
|
||||
.Bd -ragged -compact -offset "xxxx"
|
||||
Clone to be promoted.
|
||||
.Ed
|
||||
.It Em zfs.sync.rollback(filesystem)
|
||||
Rollback to the previous snapshot for a dataset.
|
||||
Returns 0 on successful rollback, or a nonzero error code otherwise.
|
||||
Rollbacks can be performed on filesystems or zvols, but not on snapshots
|
||||
or mounted datasets.
|
||||
EBUSY is returned in the case where the filesystem is mounted.
|
||||
.Pp
|
||||
filesystem (string)
|
||||
.Bd -ragged -compact -offset "xxxx"
|
||||
Filesystem to rollback.
|
||||
.Ed
|
||||
.It Em zfs.sync.snapshot(dataset)
|
||||
Create a snapshot of a filesystem.
|
||||
Returns 0 if the snapshot was successfully created,
|
||||
and a nonzero error code otherwise.
|
||||
.Pp
|
||||
Note: Taking a snapshot will fail on any pool older than legacy version 27.
|
||||
To enable taking snapshots from ZCP scripts, the pool must be upgraded.
|
||||
.Pp
|
||||
dataset (string)
|
||||
.Bd -ragged -compact -offset "xxxx"
|
||||
Name of snapshot to create.
|
||||
.Ed
|
||||
.El
|
||||
.It Sy zfs.check submodule
|
||||
For each function in the zfs.sync submodule, there is a corresponding zfs.check
|
||||
function which performs a "dry run" of the same operation.
|
||||
Each takes the same arguments as its zfs.sync counterpart and returns 0 if the
|
||||
operation would succeed, or a non-zero error code if it would fail, along with
|
||||
any other error details.
|
||||
That is, each has the same behavior as the corresponding sync function except
|
||||
for actually executing the requested change.
|
||||
For example,
|
||||
.Em zfs.check.destroy("fs")
|
||||
returns 0 if
|
||||
.Em zfs.sync.destroy("fs")
|
||||
would successfully destroy the dataset.
|
||||
.Pp
|
||||
The available zfs.check functions are:
|
||||
.Bl -tag -width "xx"
|
||||
.It Em zfs.check.destroy(dataset, [defer=true|false])
|
||||
.It Em zfs.check.promote(dataset)
|
||||
.It Em zfs.check.rollback(filesystem)
|
||||
.It Em zfs.check.snapshot(dataset)
|
||||
.El
|
||||
.It Sy zfs.list submodule
|
||||
The zfs.list submodule provides functions for iterating over datasets and
|
||||
properties.
|
||||
Rather than returning tables, these functions act as Lua iterators, and are
|
||||
generally used as follows:
|
||||
.Bd -literal -offset indent
|
||||
for child in zfs.list.children("rpool") do
|
||||
...
|
||||
end
|
||||
.Ed
|
||||
.Pp
|
||||
The available zfs.list functions are:
|
||||
.Bl -tag -width "xx"
|
||||
.It Em zfs.list.clones(snapshot)
|
||||
Iterate through all clones of the given snapshot.
|
||||
.Pp
|
||||
snapshot (string)
|
||||
.Bd -ragged -compact -offset "xxxx"
|
||||
Must be a valid snapshot path in the current pool.
|
||||
.Ed
|
||||
.It Em zfs.list.snapshots(dataset)
|
||||
Iterate through all snapshots of the given dataset.
|
||||
Each snapshot is returned as a string containing the full dataset name, e.g.
|
||||
"pool/fs@snap".
|
||||
.Pp
|
||||
dataset (string)
|
||||
.Bd -ragged -compact -offset "xxxx"
|
||||
Must be a valid filesystem or volume.
|
||||
.Ed
|
||||
.It Em zfs.list.children(dataset)
|
||||
Iterate through all direct children of the given dataset.
|
||||
Each child is returned as a string containing the full dataset name, e.g.
|
||||
"pool/fs/child".
|
||||
.Pp
|
||||
dataset (string)
|
||||
.Bd -ragged -compact -offset "xxxx"
|
||||
Must be a valid filesystem or volume.
|
||||
.Ed
|
||||
.It Em zfs.list.properties(dataset)
|
||||
Iterate through all user properties for the given dataset.
|
||||
.Pp
|
||||
dataset (string)
|
||||
.Bd -ragged -compact -offset "xxxx"
|
||||
Must be a valid filesystem, snapshot, or volume.
|
||||
.Ed
|
||||
.It Em zfs.list.system_properties(dataset)
|
||||
Returns an array of strings, the names of the valid system (non-user defined)
|
||||
properties for the given dataset.
|
||||
Throws a Lua error if the dataset is invalid.
|
||||
.Pp
|
||||
dataset (string)
|
||||
.Bd -ragged -compact -offset "xxxx"
|
||||
Must be a valid filesystem, snapshot or volume.
|
||||
.Ed
|
||||
.El
|
||||
.El
|
||||
.Sh EXAMPLES
|
||||
.Ss Example 1
|
||||
The following channel program recursively destroys a filesystem and all its
|
||||
snapshots and children in a naive manner.
|
||||
Note that this does not involve any error handling or reporting.
|
||||
.Bd -literal -offset indent
|
||||
function destroy_recursive(root)
|
||||
for child in zfs.list.children(root) do
|
||||
destroy_recursive(child)
|
||||
end
|
||||
for snap in zfs.list.snapshots(root) do
|
||||
zfs.sync.destroy(snap)
|
||||
end
|
||||
zfs.sync.destroy(root)
|
||||
end
|
||||
destroy_recursive("pool/somefs")
|
||||
.Ed
|
||||
.Ss Example 2
|
||||
A more verbose and robust version of the same channel program, which
|
||||
properly detects and reports errors, and also takes the dataset to destroy
|
||||
as a command line argument, would be as follows:
|
||||
.Bd -literal -offset indent
|
||||
succeeded = {}
|
||||
failed = {}
|
||||
|
||||
function destroy_recursive(root)
|
||||
for child in zfs.list.children(root) do
|
||||
destroy_recursive(child)
|
||||
end
|
||||
for snap in zfs.list.snapshots(root) do
|
||||
err = zfs.sync.destroy(snap)
|
||||
if (err ~= 0) then
|
||||
failed[snap] = err
|
||||
else
|
||||
succeeded[snap] = err
|
||||
end
|
||||
end
|
||||
err = zfs.sync.destroy(root)
|
||||
if (err ~= 0) then
|
||||
failed[root] = err
|
||||
else
|
||||
succeeded[root] = err
|
||||
end
|
||||
end
|
||||
|
||||
args = ...
|
||||
argv = args["argv"]
|
||||
|
||||
destroy_recursive(argv[1])
|
||||
|
||||
results = {}
|
||||
results["succeeded"] = succeeded
|
||||
results["failed"] = failed
|
||||
return results
|
||||
.Ed
|
||||
.Ss Example 3
|
||||
The following function performs a forced promote operation by attempting to
|
||||
promote the given clone and destroying any conflicting snapshots.
|
||||
.Bd -literal -offset indent
|
||||
function force_promote(ds)
|
||||
errno, details = zfs.check.promote(ds)
|
||||
if (errno == EEXIST) then
|
||||
assert(details ~= Nil)
|
||||
for i, snap in ipairs(details) do
|
||||
zfs.sync.destroy(ds .. "@" .. snap)
|
||||
end
|
||||
elseif (errno ~= 0) then
|
||||
return errno
|
||||
end
|
||||
return zfs.sync.promote(ds)
|
||||
end
|
||||
.Ed
|
@ -286,6 +286,12 @@
|
||||
.Ar snapshot
|
||||
.Op Ar snapshot Ns | Ns Ar filesystem
|
||||
.Nm
|
||||
.Cm program
|
||||
.Op Fl t Ar timeout
|
||||
.Op Fl m Ar memory_limit
|
||||
.Ar pool script
|
||||
.Op Ar arg1 No ...
|
||||
.Nm
|
||||
.Cm jail
|
||||
.Ar jailid Ns | Ns Ar jailname filesystem
|
||||
.Nm
|
||||
@ -3287,6 +3293,48 @@ Display the path's inode change time as the first column of output.
|
||||
.El
|
||||
.It Xo
|
||||
.Nm
|
||||
.Cm program
|
||||
.Op Fl t Ar timeout
|
||||
.Op Fl m Ar memory_limit
|
||||
.Ar pool script
|
||||
.Op Ar arg1 No ...
|
||||
.Xc
|
||||
.Pp
|
||||
Executes
|
||||
.Ar script
|
||||
as a ZFS channel program on
|
||||
.Ar pool .
|
||||
The ZFS channel
|
||||
program interface allows ZFS administrative operations to be run
|
||||
programmatically via a Lua script.
|
||||
The entire script is executed atomically, with no other administrative
|
||||
operations taking effect concurrently.
|
||||
A library of ZFS calls is made available to channel program scripts.
|
||||
Channel programs may only be run with root privileges.
|
||||
.Pp
|
||||
For full documentation of the ZFS channel program interface, see the manual
|
||||
page for
|
||||
.Xr zfs-program 8 .
|
||||
.Bl -tag -width indent
|
||||
.It Fl t Ar timeout
|
||||
Execution time limit, in milliseconds.
|
||||
If a channel program executes for longer than the provided timeout, it will
|
||||
be stopped and an error will be returned.
|
||||
The default timeout is 1000 ms, and can be set to a maximum of 10000 ms.
|
||||
.It Fl m Ar memory-limit
|
||||
Memory limit, in bytes.
|
||||
If a channel program attempts to allocate more memory than the given limit,
|
||||
it will be stopped and an error returned.
|
||||
The default memory limit is 10 MB, and can be set to a maximum of 100 MB.
|
||||
.Pp
|
||||
All remaining argument strings are passed directly to the channel program as
|
||||
arguments.
|
||||
See
|
||||
.Xr zfs-program 8
|
||||
for more information.
|
||||
.El
|
||||
.It Xo
|
||||
.Nm
|
||||
.Cm jail
|
||||
.Ar jailid filesystem
|
||||
.Xc
|
||||
|
@ -21,7 +21,7 @@
|
||||
|
||||
/*
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011, 2015 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2011, 2016 by Delphix. All rights reserved.
|
||||
* Copyright 2012 Milan Jurik. All rights reserved.
|
||||
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
|
||||
* Copyright (c) 2011-2012 Pawel Jakub Dawidek. All rights reserved.
|
||||
@ -51,6 +51,7 @@
|
||||
#include <grp.h>
|
||||
#include <pwd.h>
|
||||
#include <signal.h>
|
||||
#include <sys/debug.h>
|
||||
#include <sys/list.h>
|
||||
#include <sys/mntent.h>
|
||||
#include <sys/mnttab.h>
|
||||
@ -111,6 +112,7 @@ static int zfs_do_diff(int argc, char **argv);
|
||||
static int zfs_do_jail(int argc, char **argv);
|
||||
static int zfs_do_unjail(int argc, char **argv);
|
||||
static int zfs_do_bookmark(int argc, char **argv);
|
||||
static int zfs_do_channel_program(int argc, char **argv);
|
||||
|
||||
/*
|
||||
* Enable a reasonable set of defaults for libumem debugging on DEBUG builds.
|
||||
@ -160,6 +162,7 @@ typedef enum {
|
||||
HELP_RELEASE,
|
||||
HELP_DIFF,
|
||||
HELP_BOOKMARK,
|
||||
HELP_CHANNEL_PROGRAM,
|
||||
} zfs_help_t;
|
||||
|
||||
typedef struct zfs_command {
|
||||
@ -187,6 +190,7 @@ static zfs_command_t command_table[] = {
|
||||
{ "promote", zfs_do_promote, HELP_PROMOTE },
|
||||
{ "rename", zfs_do_rename, HELP_RENAME },
|
||||
{ "bookmark", zfs_do_bookmark, HELP_BOOKMARK },
|
||||
{ "program", zfs_do_channel_program, HELP_CHANNEL_PROGRAM },
|
||||
{ NULL },
|
||||
{ "list", zfs_do_list, HELP_LIST },
|
||||
{ NULL },
|
||||
@ -340,6 +344,10 @@ get_usage(zfs_help_t idx)
|
||||
"[snapshot|filesystem]\n"));
|
||||
case HELP_BOOKMARK:
|
||||
return (gettext("\tbookmark <snapshot> <bookmark>\n"));
|
||||
case HELP_CHANNEL_PROGRAM:
|
||||
return (gettext("\tprogram [-t <instruction limit>] "
|
||||
"[-m <memory limit (b)>] <pool> <program file> "
|
||||
"[lua args...]\n"));
|
||||
}
|
||||
|
||||
abort();
|
||||
@ -368,6 +376,18 @@ safe_malloc(size_t size)
|
||||
return (data);
|
||||
}
|
||||
|
||||
void *
|
||||
safe_realloc(void *data, size_t size)
|
||||
{
|
||||
void *newp;
|
||||
if ((newp = realloc(data, size)) == NULL) {
|
||||
free(data);
|
||||
nomem();
|
||||
}
|
||||
|
||||
return (newp);
|
||||
}
|
||||
|
||||
static char *
|
||||
safe_strdup(char *str)
|
||||
{
|
||||
@ -7101,6 +7121,194 @@ zfs_do_bookmark(int argc, char **argv)
|
||||
return (-1);
|
||||
}
|
||||
|
||||
static int
|
||||
zfs_do_channel_program(int argc, char **argv)
|
||||
{
|
||||
int ret, fd;
|
||||
char c;
|
||||
char *progbuf, *filename, *poolname;
|
||||
size_t progsize, progread;
|
||||
nvlist_t *outnvl;
|
||||
uint64_t instrlimit = ZCP_DEFAULT_INSTRLIMIT;
|
||||
uint64_t memlimit = ZCP_DEFAULT_MEMLIMIT;
|
||||
zpool_handle_t *zhp;
|
||||
|
||||
/* check options */
|
||||
while (-1 !=
|
||||
(c = getopt(argc, argv, "t:(instr-limit)m:(memory-limit)"))) {
|
||||
switch (c) {
|
||||
case 't':
|
||||
case 'm': {
|
||||
uint64_t arg;
|
||||
char *endp;
|
||||
|
||||
errno = 0;
|
||||
arg = strtoull(optarg, &endp, 0);
|
||||
if (errno != 0 || *endp != '\0') {
|
||||
(void) fprintf(stderr, gettext(
|
||||
"invalid argument "
|
||||
"'%s': expected integer\n"), optarg);
|
||||
goto usage;
|
||||
}
|
||||
|
||||
if (c == 't') {
|
||||
if (arg > ZCP_MAX_INSTRLIMIT || arg == 0) {
|
||||
(void) fprintf(stderr, gettext(
|
||||
"Invalid instruction limit: "
|
||||
"%s\n"), optarg);
|
||||
return (1);
|
||||
} else {
|
||||
instrlimit = arg;
|
||||
}
|
||||
} else {
|
||||
ASSERT3U(c, ==, 'm');
|
||||
if (arg > ZCP_MAX_MEMLIMIT || arg == 0) {
|
||||
(void) fprintf(stderr, gettext(
|
||||
"Invalid memory limit: "
|
||||
"%s\n"), optarg);
|
||||
return (1);
|
||||
} else {
|
||||
memlimit = arg;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case '?':
|
||||
(void) fprintf(stderr, gettext("invalid option '%c'\n"),
|
||||
optopt);
|
||||
goto usage;
|
||||
}
|
||||
}
|
||||
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (argc < 2) {
|
||||
(void) fprintf(stderr,
|
||||
gettext("invalid number of arguments\n"));
|
||||
goto usage;
|
||||
}
|
||||
|
||||
poolname = argv[0];
|
||||
filename = argv[1];
|
||||
if (strcmp(filename, "-") == 0) {
|
||||
fd = 0;
|
||||
filename = "standard input";
|
||||
} else if ((fd = open(filename, O_RDONLY)) < 0) {
|
||||
(void) fprintf(stderr, gettext("cannot open '%s': %s\n"),
|
||||
filename, strerror(errno));
|
||||
return (1);
|
||||
}
|
||||
|
||||
if ((zhp = zpool_open(g_zfs, poolname)) == NULL) {
|
||||
(void) fprintf(stderr, gettext("cannot open pool '%s'"),
|
||||
poolname);
|
||||
return (1);
|
||||
}
|
||||
zpool_close(zhp);
|
||||
|
||||
/*
|
||||
* Read in the channel program, expanding the program buffer as
|
||||
* necessary.
|
||||
*/
|
||||
progread = 0;
|
||||
progsize = 1024;
|
||||
progbuf = safe_malloc(progsize);
|
||||
do {
|
||||
ret = read(fd, progbuf + progread, progsize - progread);
|
||||
progread += ret;
|
||||
if (progread == progsize && ret > 0) {
|
||||
progsize *= 2;
|
||||
progbuf = safe_realloc(progbuf, progsize);
|
||||
}
|
||||
} while (ret > 0);
|
||||
|
||||
if (fd != 0)
|
||||
(void) close(fd);
|
||||
if (ret < 0) {
|
||||
free(progbuf);
|
||||
(void) fprintf(stderr,
|
||||
gettext("cannot read '%s': %s\n"),
|
||||
filename, strerror(errno));
|
||||
return (1);
|
||||
}
|
||||
progbuf[progread] = '\0';
|
||||
|
||||
/*
|
||||
* Any remaining arguments are passed as arguments to the lua script as
|
||||
* a string array:
|
||||
* {
|
||||
* "argv" -> [ "arg 1", ... "arg n" ],
|
||||
* }
|
||||
*/
|
||||
nvlist_t *argnvl = fnvlist_alloc();
|
||||
fnvlist_add_string_array(argnvl, ZCP_ARG_CLIARGV, argv + 2, argc - 2);
|
||||
|
||||
ret = lzc_channel_program(poolname, progbuf, instrlimit, memlimit,
|
||||
argnvl, &outnvl);
|
||||
|
||||
if (ret != 0) {
|
||||
/*
|
||||
* On error, report the error message handed back by lua if one
|
||||
* exists. Otherwise, generate an appropriate error message,
|
||||
* falling back on strerror() for an unexpected return code.
|
||||
*/
|
||||
char *errstring = NULL;
|
||||
if (nvlist_exists(outnvl, ZCP_RET_ERROR)) {
|
||||
(void) nvlist_lookup_string(outnvl,
|
||||
ZCP_RET_ERROR, &errstring);
|
||||
if (errstring == NULL)
|
||||
errstring = strerror(ret);
|
||||
} else {
|
||||
switch (ret) {
|
||||
case EINVAL:
|
||||
errstring =
|
||||
"Invalid instruction or memory limit.";
|
||||
break;
|
||||
case ENOMEM:
|
||||
errstring = "Return value too large.";
|
||||
break;
|
||||
case ENOSPC:
|
||||
errstring = "Memory limit exhausted.";
|
||||
break;
|
||||
#ifdef illumos
|
||||
case ETIME:
|
||||
#else
|
||||
case ETIMEDOUT:
|
||||
#endif
|
||||
errstring = "Timed out.";
|
||||
break;
|
||||
case EPERM:
|
||||
errstring = "Permission denied. Channel "
|
||||
"programs must be run as root.";
|
||||
break;
|
||||
default:
|
||||
errstring = strerror(ret);
|
||||
}
|
||||
}
|
||||
(void) fprintf(stderr,
|
||||
gettext("Channel program execution failed:\n%s\n"),
|
||||
errstring);
|
||||
} else {
|
||||
(void) printf("Channel program fully executed ");
|
||||
if (nvlist_empty(outnvl)) {
|
||||
(void) printf("with no return value.\n");
|
||||
} else {
|
||||
(void) printf("with return value:\n");
|
||||
dump_nvlist(outnvl, 4);
|
||||
}
|
||||
}
|
||||
|
||||
free(progbuf);
|
||||
fnvlist_free(outnvl);
|
||||
fnvlist_free(argnvl);
|
||||
return (ret != 0);
|
||||
|
||||
usage:
|
||||
usage(B_FALSE);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
|
@ -21,7 +21,7 @@
|
||||
|
||||
/*
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011, 2015 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2011, 2016 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2012 by Frederik Wessels. All rights reserved.
|
||||
* Copyright (c) 2012 Martin Matuska <mm@FreeBSD.org>. All rights reserved.
|
||||
* Copyright (c) 2013 by Prasad Joshi (sTec). All rights reserved.
|
||||
@ -5254,6 +5254,11 @@ get_history_one(zpool_handle_t *zhp, void *data)
|
||||
dump_nvlist(fnvlist_lookup_nvlist(rec,
|
||||
ZPOOL_HIST_OUTPUT_NVL), 8);
|
||||
}
|
||||
if (nvlist_exists(rec, ZPOOL_HIST_ERRNO)) {
|
||||
(void) printf(" errno: %lld\n",
|
||||
fnvlist_lookup_int64(rec,
|
||||
ZPOOL_HIST_ERRNO));
|
||||
}
|
||||
} else {
|
||||
if (!cb->internal)
|
||||
continue;
|
||||
|
@ -583,6 +583,8 @@ usage(boolean_t requested)
|
||||
"\t[-F freezeloops (default: %llu)] max loops in spa_freeze()\n"
|
||||
"\t[-P passtime (default: %llu sec)] time per pass\n"
|
||||
"\t[-B alt_ztest (default: <none>)] alternate ztest path\n"
|
||||
"\t[-o variable=value] ... set global variable to an unsigned\n"
|
||||
"\t 32-bit integer value\n"
|
||||
"\t[-h] (print help)\n"
|
||||
"",
|
||||
zo->zo_pool,
|
||||
@ -618,7 +620,7 @@ process_options(int argc, char **argv)
|
||||
bcopy(&ztest_opts_defaults, zo, sizeof (*zo));
|
||||
|
||||
while ((opt = getopt(argc, argv,
|
||||
"v:s:a:m:r:R:d:t:g:i:k:p:f:VET:P:hF:B:")) != EOF) {
|
||||
"v:s:a:m:r:R:d:t:g:i:k:p:f:VET:P:hF:B:o:")) != EOF) {
|
||||
value = 0;
|
||||
switch (opt) {
|
||||
case 'v':
|
||||
@ -705,6 +707,10 @@ process_options(int argc, char **argv)
|
||||
case 'B':
|
||||
(void) strlcpy(altdir, optarg, sizeof (altdir));
|
||||
break;
|
||||
case 'o':
|
||||
if (set_global_var(optarg) != 0)
|
||||
usage(B_FALSE);
|
||||
break;
|
||||
case 'h':
|
||||
usage(B_TRUE);
|
||||
break;
|
||||
|
@ -434,7 +434,7 @@ dt_dis(const dtrace_difo_t *dp, FILE *fp)
|
||||
ulong_t i = 0;
|
||||
char type[DT_TYPE_NAMELEN];
|
||||
|
||||
(void) fprintf(fp, "\nDIFO 0x%p returns %s\n", (void *)dp,
|
||||
(void) fprintf(fp, "\nDIFO %p returns %s\n", (void *)dp,
|
||||
dt_dis_typestr(&dp->dtdo_rtype, type, sizeof (type)));
|
||||
|
||||
(void) fprintf(fp, "%-3s %-8s %s\n",
|
||||
|
@ -377,7 +377,7 @@ dt_print_array(ctf_id_t base, ulong_t off, dt_printarg_t *pap)
|
||||
ctf_id_t rtype;
|
||||
|
||||
if (ctf_array_info(ctfp, base, &car) == CTF_ERR) {
|
||||
(void) fprintf(fp, "0x%p", (void *)addr);
|
||||
(void) fprintf(fp, "%p", (void *)addr);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,7 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2013, Joyent, Inc. All rights reserved.
|
||||
* Copyright (c) 2011, 2015 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2011, 2016 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2012 DEY Storage Systems, Inc. All rights reserved.
|
||||
* Copyright (c) 2011-2012 Pawel Jakub Dawidek. All rights reserved.
|
||||
* Copyright (c) 2013 Martin Matuska. All rights reserved.
|
||||
@ -2166,6 +2166,7 @@ get_numeric_property(zfs_handle_t *zhp, zfs_prop_t prop, zprop_source_t *src,
|
||||
if (zfs_prop_readonly(prop) &&
|
||||
*source != NULL && (*source)[0] == '\0') {
|
||||
*source = NULL;
|
||||
return (-1);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -2354,6 +2355,74 @@ zfs_get_clones_nvl(zfs_handle_t *zhp)
|
||||
return (value);
|
||||
}
|
||||
|
||||
/*
|
||||
* Accepts a property and value and checks that the value
|
||||
* matches the one found by the channel program. If they are
|
||||
* not equal, print both of them.
|
||||
*/
|
||||
void
|
||||
zcp_check(zfs_handle_t *zhp, zfs_prop_t prop, uint64_t intval,
|
||||
const char *strval)
|
||||
{
|
||||
if (!zhp->zfs_hdl->libzfs_prop_debug)
|
||||
return;
|
||||
int error;
|
||||
char *poolname = zhp->zpool_hdl->zpool_name;
|
||||
const char *program =
|
||||
"args = ...\n"
|
||||
"ds = args['dataset']\n"
|
||||
"prop = args['property']\n"
|
||||
"value, setpoint = zfs.get_prop(ds, prop)\n"
|
||||
"return {value=value, setpoint=setpoint}\n";
|
||||
nvlist_t *outnvl;
|
||||
nvlist_t *retnvl;
|
||||
nvlist_t *argnvl = fnvlist_alloc();
|
||||
|
||||
fnvlist_add_string(argnvl, "dataset", zhp->zfs_name);
|
||||
fnvlist_add_string(argnvl, "property", zfs_prop_to_name(prop));
|
||||
|
||||
error = lzc_channel_program(poolname, program,
|
||||
10 * 1000 * 1000, 10 * 1024 * 1024, argnvl, &outnvl);
|
||||
|
||||
if (error == 0) {
|
||||
retnvl = fnvlist_lookup_nvlist(outnvl, "return");
|
||||
if (zfs_prop_get_type(prop) == PROP_TYPE_NUMBER) {
|
||||
int64_t ans;
|
||||
error = nvlist_lookup_int64(retnvl, "value", &ans);
|
||||
if (error != 0) {
|
||||
(void) fprintf(stderr, "zcp check error: %u\n",
|
||||
error);
|
||||
return;
|
||||
}
|
||||
if (ans != intval) {
|
||||
(void) fprintf(stderr,
|
||||
"%s: zfs found %lld, but zcp found %lld\n",
|
||||
zfs_prop_to_name(prop),
|
||||
(longlong_t)intval, (longlong_t)ans);
|
||||
}
|
||||
} else {
|
||||
char *str_ans;
|
||||
error = nvlist_lookup_string(retnvl, "value", &str_ans);
|
||||
if (error != 0) {
|
||||
(void) fprintf(stderr, "zcp check error: %u\n",
|
||||
error);
|
||||
return;
|
||||
}
|
||||
if (strcmp(strval, str_ans) != 0) {
|
||||
(void) fprintf(stderr,
|
||||
"%s: zfs found %s, but zcp found %s\n",
|
||||
zfs_prop_to_name(prop),
|
||||
strval, str_ans);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
(void) fprintf(stderr,
|
||||
"zcp check failed, channel program error: %u\n", error);
|
||||
}
|
||||
nvlist_free(argnvl);
|
||||
nvlist_free(outnvl);
|
||||
}
|
||||
|
||||
/*
|
||||
* Retrieve a property from the given object. If 'literal' is specified, then
|
||||
* numbers are left as exact values. Otherwise, numbers are converted to a
|
||||
@ -2400,6 +2469,7 @@ zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen,
|
||||
&t) == 0)
|
||||
(void) snprintf(propbuf, proplen, "%llu", val);
|
||||
}
|
||||
zcp_check(zhp, prop, val, NULL);
|
||||
break;
|
||||
|
||||
case ZFS_PROP_MOUNTPOINT:
|
||||
@ -2468,7 +2538,7 @@ zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen,
|
||||
/* 'legacy' or 'none' */
|
||||
(void) strlcpy(propbuf, str, proplen);
|
||||
}
|
||||
|
||||
zcp_check(zhp, prop, NULL, propbuf);
|
||||
break;
|
||||
|
||||
case ZFS_PROP_ORIGIN:
|
||||
@ -2476,6 +2546,7 @@ zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen,
|
||||
if (str == NULL)
|
||||
return (-1);
|
||||
(void) strlcpy(propbuf, str, proplen);
|
||||
zcp_check(zhp, prop, NULL, str);
|
||||
break;
|
||||
|
||||
case ZFS_PROP_CLONES:
|
||||
@ -2490,7 +2561,6 @@ zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen,
|
||||
|
||||
if (get_numeric_property(zhp, prop, src, &source, &val) != 0)
|
||||
return (-1);
|
||||
|
||||
/*
|
||||
* If quota or reservation is 0, we translate this into 'none'
|
||||
* (unless literal is set), and indicate that it's the default
|
||||
@ -2509,6 +2579,7 @@ zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen,
|
||||
else
|
||||
zfs_nicenum(val, propbuf, proplen);
|
||||
}
|
||||
zcp_check(zhp, prop, val, NULL);
|
||||
break;
|
||||
|
||||
case ZFS_PROP_FILESYSTEM_LIMIT:
|
||||
@ -2533,6 +2604,8 @@ zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen,
|
||||
} else {
|
||||
zfs_nicenum(val, propbuf, proplen);
|
||||
}
|
||||
|
||||
zcp_check(zhp, prop, val, NULL);
|
||||
break;
|
||||
|
||||
case ZFS_PROP_REFRATIO:
|
||||
@ -2542,6 +2615,7 @@ zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen,
|
||||
(void) snprintf(propbuf, proplen, "%llu.%02llux",
|
||||
(u_longlong_t)(val / 100),
|
||||
(u_longlong_t)(val % 100));
|
||||
zcp_check(zhp, prop, val, NULL);
|
||||
break;
|
||||
|
||||
case ZFS_PROP_TYPE:
|
||||
@ -2562,6 +2636,7 @@ zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen,
|
||||
abort();
|
||||
}
|
||||
(void) snprintf(propbuf, proplen, "%s", str);
|
||||
zcp_check(zhp, prop, NULL, propbuf);
|
||||
break;
|
||||
|
||||
case ZFS_PROP_MOUNTED:
|
||||
@ -2587,6 +2662,7 @@ zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen,
|
||||
* consumers.
|
||||
*/
|
||||
(void) strlcpy(propbuf, zhp->zfs_name, proplen);
|
||||
zcp_check(zhp, prop, NULL, propbuf);
|
||||
break;
|
||||
|
||||
case ZFS_PROP_MLSLABEL:
|
||||
@ -2640,26 +2716,33 @@ zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen,
|
||||
if (get_numeric_property(zhp, prop, src, &source, &val) != 0)
|
||||
return (-1);
|
||||
(void) snprintf(propbuf, proplen, "%llu", (u_longlong_t)val);
|
||||
zcp_check(zhp, prop, val, NULL);
|
||||
break;
|
||||
|
||||
default:
|
||||
switch (zfs_prop_get_type(prop)) {
|
||||
case PROP_TYPE_NUMBER:
|
||||
if (get_numeric_property(zhp, prop, src,
|
||||
&source, &val) != 0)
|
||||
&source, &val) != 0) {
|
||||
return (-1);
|
||||
if (literal)
|
||||
}
|
||||
|
||||
if (literal) {
|
||||
(void) snprintf(propbuf, proplen, "%llu",
|
||||
(u_longlong_t)val);
|
||||
else
|
||||
} else {
|
||||
zfs_nicenum(val, propbuf, proplen);
|
||||
}
|
||||
zcp_check(zhp, prop, val, NULL);
|
||||
break;
|
||||
|
||||
case PROP_TYPE_STRING:
|
||||
str = getprop_string(zhp, prop, &source);
|
||||
if (str == NULL)
|
||||
return (-1);
|
||||
|
||||
(void) strlcpy(propbuf, str, proplen);
|
||||
zcp_check(zhp, prop, NULL, str);
|
||||
break;
|
||||
|
||||
case PROP_TYPE_INDEX:
|
||||
@ -2668,7 +2751,9 @@ zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen,
|
||||
return (-1);
|
||||
if (zfs_prop_index_to_string(prop, val, &strval) != 0)
|
||||
return (-1);
|
||||
|
||||
(void) strlcpy(propbuf, strval, proplen);
|
||||
zcp_check(zhp, prop, NULL, strval);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -55,15 +55,6 @@
|
||||
#define ZDIFF_REMOVED '-'
|
||||
#define ZDIFF_RENAMED 'R'
|
||||
|
||||
static boolean_t
|
||||
do_name_cmp(const char *fpath, const char *tpath)
|
||||
{
|
||||
char *fname, *tname;
|
||||
fname = strrchr(fpath, '/') + 1;
|
||||
tname = strrchr(tpath, '/') + 1;
|
||||
return (strcmp(fname, tname) == 0);
|
||||
}
|
||||
|
||||
typedef struct differ_info {
|
||||
zfs_handle_t *zhp;
|
||||
char *fromsnap;
|
||||
@ -262,7 +253,6 @@ static int
|
||||
write_inuse_diffs_one(FILE *fp, differ_info_t *di, uint64_t dobj)
|
||||
{
|
||||
struct zfs_stat fsb, tsb;
|
||||
boolean_t same_name;
|
||||
mode_t fmode, tmode;
|
||||
char fobjname[MAXPATHLEN], tobjname[MAXPATHLEN];
|
||||
int fobjerr, tobjerr;
|
||||
@ -323,7 +313,6 @@ write_inuse_diffs_one(FILE *fp, differ_info_t *di, uint64_t dobj)
|
||||
|
||||
if (fmode != tmode && fsb.zs_gen == tsb.zs_gen)
|
||||
tsb.zs_gen++; /* Force a generational difference */
|
||||
same_name = do_name_cmp(fobjname, tobjname);
|
||||
|
||||
/* Simple modification or no change */
|
||||
if (fsb.zs_gen == tsb.zs_gen) {
|
||||
@ -334,7 +323,7 @@ write_inuse_diffs_one(FILE *fp, differ_info_t *di, uint64_t dobj)
|
||||
if (change) {
|
||||
print_link_change(fp, di, change,
|
||||
change > 0 ? fobjname : tobjname, &tsb);
|
||||
} else if (same_name) {
|
||||
} else if (strcmp(fobjname, tobjname) == 0) {
|
||||
print_file(fp, di, ZDIFF_MODIFIED, fobjname, &tsb);
|
||||
} else {
|
||||
print_rename(fp, di, fobjname, tobjname, &tsb);
|
||||
|
@ -79,6 +79,7 @@ struct libzfs_handle {
|
||||
libzfs_fru_t **libzfs_fru_hash;
|
||||
libzfs_fru_t *libzfs_fru_list;
|
||||
char libzfs_chassis_id[256];
|
||||
boolean_t libzfs_prop_debug;
|
||||
};
|
||||
|
||||
#define ZFSSHARE_MISS 0x01 /* Didn't find entry in cache */
|
||||
|
@ -2295,6 +2295,7 @@ vdev_get_physpaths(nvlist_t *nv, char *physpath, size_t phypath_size,
|
||||
return (ret);
|
||||
}
|
||||
} else if (strcmp(type, VDEV_TYPE_MIRROR) == 0 ||
|
||||
strcmp(type, VDEV_TYPE_RAIDZ) == 0 ||
|
||||
strcmp(type, VDEV_TYPE_REPLACING) == 0 ||
|
||||
(is_spare = (strcmp(type, VDEV_TYPE_SPARE) == 0))) {
|
||||
nvlist_t **child;
|
||||
|
@ -3212,7 +3212,12 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
|
||||
/*
|
||||
* Determine the name of the origin snapshot, store in zc_string.
|
||||
*/
|
||||
if (drrb->drr_flags & DRR_FLAG_CLONE) {
|
||||
if (originsnap) {
|
||||
(void) strncpy(zc.zc_string, originsnap, sizeof (zc.zc_string));
|
||||
if (flags->verbose)
|
||||
(void) printf("using provided clone origin %s\n",
|
||||
zc.zc_string);
|
||||
} else if (drrb->drr_flags & DRR_FLAG_CLONE) {
|
||||
if (guid_to_name(hdl, zc.zc_value,
|
||||
drrb->drr_fromguid, B_FALSE, zc.zc_string) != 0) {
|
||||
zcmd_free_nvlists(&zc);
|
||||
@ -3223,11 +3228,6 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
|
||||
}
|
||||
if (flags->verbose)
|
||||
(void) printf("found clone origin %s\n", zc.zc_string);
|
||||
} else if (originsnap) {
|
||||
(void) strncpy(zc.zc_string, originsnap, sizeof (zc.zc_string));
|
||||
if (flags->verbose)
|
||||
(void) printf("using provided clone origin %s\n",
|
||||
zc.zc_string);
|
||||
}
|
||||
|
||||
boolean_t resuming = DMU_GET_FEATUREFLAGS(drrb->drr_versioninfo) &
|
||||
|
@ -678,6 +678,10 @@ libzfs_init(void)
|
||||
zpool_feature_init();
|
||||
libzfs_mnttab_init(hdl);
|
||||
|
||||
if (getenv("ZFS_PROP_DEBUG") != NULL) {
|
||||
hdl->libzfs_prop_debug = B_TRUE;
|
||||
}
|
||||
|
||||
return (hdl);
|
||||
}
|
||||
|
||||
|
@ -20,7 +20,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2012, 2014 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2012, 2017 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2013 Steven Hartland. All rights reserved.
|
||||
* Copyright (c) 2014 Integros [integros.com]
|
||||
* Copyright 2017 RackTop Systems.
|
||||
@ -160,7 +160,12 @@ lzc_ioctl(zfs_ioc_t ioc, const char *name,
|
||||
|
||||
if (resultp != NULL) {
|
||||
*resultp = NULL;
|
||||
zc.zc_nvlist_dst_size = MAX(size * 2, 128 * 1024);
|
||||
if (ioc == ZFS_IOC_CHANNEL_PROGRAM) {
|
||||
zc.zc_nvlist_dst_size = fnvlist_lookup_uint64(source,
|
||||
ZCP_ARG_MEMLIMIT);
|
||||
} else {
|
||||
zc.zc_nvlist_dst_size = MAX(size * 2, 128 * 1024);
|
||||
}
|
||||
zc.zc_nvlist_dst = (uint64_t)(uintptr_t)
|
||||
malloc(zc.zc_nvlist_dst_size);
|
||||
#ifdef illumos
|
||||
@ -174,7 +179,15 @@ lzc_ioctl(zfs_ioc_t ioc, const char *name,
|
||||
}
|
||||
|
||||
while (ioctl(g_fd, ioc, &zc) != 0) {
|
||||
if (errno == ENOMEM && resultp != NULL) {
|
||||
/*
|
||||
* If ioctl exited with ENOMEM, we retry the ioctl after
|
||||
* increasing the size of the destination nvlist.
|
||||
*
|
||||
* Channel programs that exit with ENOMEM ran over the
|
||||
* lua memory sandbox; they should not be retried.
|
||||
*/
|
||||
if (errno == ENOMEM && resultp != NULL &&
|
||||
ioc != ZFS_IOC_CHANNEL_PROGRAM) {
|
||||
free((void *)(uintptr_t)zc.zc_nvlist_dst);
|
||||
zc.zc_nvlist_dst_size *= 2;
|
||||
zc.zc_nvlist_dst = (uint64_t)(uintptr_t)
|
||||
@ -904,3 +917,54 @@ lzc_destroy_bookmarks(nvlist_t *bmarks, nvlist_t **errlist)
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* Executes a channel program.
|
||||
*
|
||||
* If this function returns 0 the channel program was successfully loaded and
|
||||
* ran without failing. Note that individual commands the channel program ran
|
||||
* may have failed and the channel program is responsible for reporting such
|
||||
* errors through outnvl if they are important.
|
||||
*
|
||||
* This method may also return:
|
||||
*
|
||||
* EINVAL The program contains syntax errors, or an invalid memory or time
|
||||
* limit was given. No part of the channel program was executed.
|
||||
* If caused by syntax errors, 'outnvl' contains information about the
|
||||
* errors.
|
||||
*
|
||||
* EDOM The program was executed, but encountered a runtime error, such as
|
||||
* calling a function with incorrect arguments, invoking the error()
|
||||
* function directly, failing an assert() command, etc. Some portion
|
||||
* of the channel program may have executed and committed changes.
|
||||
* Information about the failure can be found in 'outnvl'.
|
||||
*
|
||||
* ENOMEM The program fully executed, but the output buffer was not large
|
||||
* enough to store the returned value. No output is returned through
|
||||
* 'outnvl'.
|
||||
*
|
||||
* ENOSPC The program was terminated because it exceeded its memory usage
|
||||
* limit. Some portion of the channel program may have executed and
|
||||
* committed changes to disk. No output is returned through 'outnvl'.
|
||||
*
|
||||
* ETIMEDOUT The program was terminated because it exceeded its Lua instruction
|
||||
* limit. Some portion of the channel program may have executed and
|
||||
* committed changes to disk. No output is returned through 'outnvl'.
|
||||
*/
|
||||
int
|
||||
lzc_channel_program(const char *pool, const char *program, uint64_t instrlimit,
|
||||
uint64_t memlimit, nvlist_t *argnvl, nvlist_t **outnvl)
|
||||
{
|
||||
int error;
|
||||
nvlist_t *args;
|
||||
|
||||
args = fnvlist_alloc();
|
||||
fnvlist_add_string(args, ZCP_ARG_PROGRAM, program);
|
||||
fnvlist_add_nvlist(args, ZCP_ARG_ARGLIST, argnvl);
|
||||
fnvlist_add_uint64(args, ZCP_ARG_INSTRLIMIT, instrlimit);
|
||||
fnvlist_add_uint64(args, ZCP_ARG_MEMLIMIT, memlimit);
|
||||
error = lzc_ioctl(ZFS_IOC_CHANNEL_PROGRAM, pool, args, outnvl);
|
||||
fnvlist_free(args);
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
@ -20,7 +20,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2012, 2014 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2012, 2016 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2013 by Martin Matuska <mm@FreeBSD.org>. All rights reserved.
|
||||
* Copyright 2017 RackTop Systems.
|
||||
*/
|
||||
@ -86,6 +86,9 @@ boolean_t lzc_exists(const char *);
|
||||
int lzc_rollback(const char *, char *, int);
|
||||
int lzc_rollback_to(const char *, const char *);
|
||||
|
||||
int lzc_channel_program(const char *, const char *, uint64_t, uint64_t,
|
||||
nvlist_t *, nvlist_t **);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -738,6 +738,7 @@ vpanic(const char *fmt, va_list adx)
|
||||
char buf[512];
|
||||
(void) vsnprintf(buf, 512, fmt, adx);
|
||||
assfail(buf, NULL, 0);
|
||||
abort(); /* necessary to make vpanic meet noreturn requirements */
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -20,7 +20,7 @@
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2015 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2012, 2016 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
|
||||
*/
|
||||
/*
|
||||
@ -66,6 +66,7 @@ extern "C" {
|
||||
#include <fsshare.h>
|
||||
#include <pthread.h>
|
||||
#include <sched.h>
|
||||
#include <setjmp.h>
|
||||
#include <sys/debug.h>
|
||||
#include <sys/note.h>
|
||||
#include <sys/types.h>
|
||||
@ -126,8 +127,8 @@ extern void dprintf_setup(int *argc, char **argv);
|
||||
|
||||
extern void cmn_err(int, const char *, ...);
|
||||
extern void vcmn_err(int, const char *, __va_list);
|
||||
extern void panic(const char *, ...);
|
||||
extern void vpanic(const char *, __va_list);
|
||||
extern void panic(const char *, ...) __NORETURN;
|
||||
extern void vpanic(const char *, __va_list) __NORETURN;
|
||||
|
||||
#define fm_panic panic
|
||||
|
||||
@ -349,6 +350,7 @@ extern void cv_broadcast(kcondvar_t *cv);
|
||||
#define KM_SLEEP UMEM_NOFAIL
|
||||
#define KM_PUSHPAGE KM_SLEEP
|
||||
#define KM_NOSLEEP UMEM_DEFAULT
|
||||
#define KM_NORMALPRI 0 /* not needed with UMEM_DEFAULT */
|
||||
#define KMC_NODEBUG UMC_NODEBUG
|
||||
#define KMC_NOTOUCH 0 /* not needed for userland caches */
|
||||
#define KM_NODEBUG 0
|
||||
@ -581,6 +583,7 @@ extern void kernel_fini(void);
|
||||
struct spa;
|
||||
extern void nicenum(uint64_t num, char *buf);
|
||||
extern void show_pool_stats(struct spa *);
|
||||
extern int set_global_var(char *arg);
|
||||
|
||||
typedef struct callb_cpr {
|
||||
kmutex_t *cc_lockp;
|
||||
|
@ -20,6 +20,7 @@
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016 by Delphix. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
@ -31,6 +32,7 @@
|
||||
#include <sys/spa.h>
|
||||
#include <sys/fs/zfs.h>
|
||||
#include <sys/refcount.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
/*
|
||||
* Routines needed by more than one client of libzpool.
|
||||
@ -153,3 +155,58 @@ show_pool_stats(spa_t *spa)
|
||||
|
||||
nvlist_free(config);
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets given global variable in libzpool to given unsigned 32-bit value.
|
||||
* arg: "<variable>=<value>"
|
||||
*/
|
||||
int
|
||||
set_global_var(char *arg)
|
||||
{
|
||||
void *zpoolhdl;
|
||||
char *varname = arg, *varval;
|
||||
u_longlong_t val;
|
||||
|
||||
#ifndef _LITTLE_ENDIAN
|
||||
/*
|
||||
* On big endian systems changing a 64-bit variable would set the high
|
||||
* 32 bits instead of the low 32 bits, which could cause unexpected
|
||||
* results.
|
||||
*/
|
||||
fprintf(stderr, "Setting global variables is only supported on "
|
||||
"little-endian systems\n", varname);
|
||||
return (ENOTSUP);
|
||||
#endif
|
||||
if ((varval = strchr(arg, '=')) != NULL) {
|
||||
*varval = '\0';
|
||||
varval++;
|
||||
val = strtoull(varval, NULL, 0);
|
||||
if (val > UINT32_MAX) {
|
||||
fprintf(stderr, "Value for global variable '%s' must "
|
||||
"be a 32-bit unsigned integer\n", varname);
|
||||
return (EOVERFLOW);
|
||||
}
|
||||
} else {
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
zpoolhdl = dlopen("libzpool.so", RTLD_LAZY);
|
||||
if (zpoolhdl != NULL) {
|
||||
uint32_t *var;
|
||||
var = dlsym(zpoolhdl, varname);
|
||||
if (var == NULL) {
|
||||
fprintf(stderr, "Global variable '%s' does not exist "
|
||||
"in libzpool.so\n", varname);
|
||||
return (EINVAL);
|
||||
}
|
||||
*var = (uint32_t)val;
|
||||
|
||||
dlclose(zpoolhdl);
|
||||
} else {
|
||||
fprintf(stderr, "Failed to open libzpool.so to set global "
|
||||
"variable\n");
|
||||
return (EIO);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
@ -4,6 +4,8 @@
|
||||
|
||||
# ZFS_COMMON_SRCS
|
||||
.PATH: ${SRCTOP}/sys/cddl/contrib/opensolaris/uts/common/fs/zfs
|
||||
# LUA_SRCS
|
||||
.PATH: ${SRCTOP}/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua
|
||||
# ZFS_SHARED_SRCS
|
||||
.PATH: ${SRCTOP}/sys/cddl/contrib/opensolaris/common/zfs
|
||||
# KERNEL_SRCS
|
||||
@ -28,11 +30,12 @@ LIB= zpool
|
||||
|
||||
ZFS_COMMON_SRCS= ${ZFS_COMMON_OBJS:C/.o$/.c/} trim_map.c
|
||||
ZFS_SHARED_SRCS= ${ZFS_SHARED_OBJS:C/.o$/.c/}
|
||||
LUA_SRCS= ${LUA_OBJS:C/.o$/.c/}
|
||||
KERNEL_SRCS= kernel.c taskq.c util.c
|
||||
LIST_SRCS= list.c
|
||||
UNICODE_SRCS= u8_textprep.c
|
||||
|
||||
SRCS= ${ZFS_COMMON_SRCS} ${ZFS_SHARED_SRCS} \
|
||||
SRCS= ${ZFS_COMMON_SRCS} ${ZFS_SHARED_SRCS} ${LUA_SRCS} \
|
||||
${KERNEL_SRCS} ${LIST_SRCS} ${ATOMIC_SRCS} \
|
||||
${UNICODE_SRCS}
|
||||
|
||||
@ -43,6 +46,7 @@ CFLAGS+= -I${SRCTOP}/cddl/compat/opensolaris/lib/libumem
|
||||
CFLAGS+= -I${SRCTOP}/cddl/contrib/opensolaris/lib/libzpool/common
|
||||
CFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/uts/common/sys
|
||||
CFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/uts/common/fs/zfs
|
||||
CFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua
|
||||
CFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/common/zfs
|
||||
CFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/uts/common
|
||||
CFLAGS+= -I${SRCTOP}/cddl/contrib/opensolaris/head
|
||||
|
@ -3,7 +3,7 @@
|
||||
.PATH: ${SRCTOP}/cddl/contrib/opensolaris/cmd/zfs
|
||||
|
||||
PROG= zfs
|
||||
MAN= zfs.8
|
||||
MAN= zfs.8 zfs-program.8
|
||||
SRCS= zfs_main.c zfs_iter.c
|
||||
|
||||
WARNS?= 0
|
||||
|
@ -15,7 +15,7 @@
|
||||
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
VERSION = 1.14.2
|
||||
VERSION = 1.14.3
|
||||
|
||||
# === LIST OF FILES ====================================================
|
||||
|
||||
|
@ -2,6 +2,21 @@ $Id: NEWS,v 1.26 2017/07/28 14:57:56 schwarze Exp $
|
||||
|
||||
This file lists the most important changes in the mandoc.bsd.lv distribution.
|
||||
|
||||
Changes in version 1.14.3, released on August 5, 2017
|
||||
|
||||
--- BUG FIXES ---
|
||||
* man(7): Do not crash with out-of-bounds read access to a constant
|
||||
array if .sp or a blank line immediately precedes .SS or .SH.
|
||||
* mdoc(7): Do not crash with out-of-bounds read access to a constant
|
||||
array if .sp or a blank line precede the first .Sh macro.
|
||||
* tbl(7): Ignore explicitly specified negative column widths rather than
|
||||
wrapping around to huge numbers and risking memory exhaustion.
|
||||
* man(1): No longer use names that only occur in the SYNOPSIS section.
|
||||
Gets rid of some surprising behaviour and bogus warnings.
|
||||
--- THANKS TO ---
|
||||
Leah Neukirchen (Void Linux), Markus Waldeck (Debian),
|
||||
Peter Bui (nd.edu), and Yuri Pankov (illumos) for bug reports.
|
||||
|
||||
Changes in version 1.14.2, released on July 28, 2017
|
||||
|
||||
--- MAJOR NEW FEATURES ---
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: man_term.c,v 1.208 2017/06/25 11:42:02 schwarze Exp $ */
|
||||
/* $Id: man_term.c,v 1.209 2017/07/31 15:19:06 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2010-2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -673,7 +673,7 @@ pre_SS(DECL_ARGS)
|
||||
|
||||
do {
|
||||
n = n->prev;
|
||||
} while (n != NULL && n->tok != TOKEN_NONE &&
|
||||
} while (n != NULL && n->tok >= MAN_TH &&
|
||||
termacts[n->tok].flags & MAN_NOTEXT);
|
||||
if (n == NULL || (n->tok == MAN_SS && n->body->child == NULL))
|
||||
break;
|
||||
@ -735,7 +735,7 @@ pre_SH(DECL_ARGS)
|
||||
|
||||
do {
|
||||
n = n->prev;
|
||||
} while (n != NULL && n->tok != TOKEN_NONE &&
|
||||
} while (n != NULL && n->tok >= MAN_TH &&
|
||||
termacts[n->tok].flags & MAN_NOTEXT);
|
||||
if (n == NULL || (n->tok == MAN_SH && n->body->child == NULL))
|
||||
break;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: mansearch.c,v 1.50 2016/07/09 15:23:36 schwarze Exp $ */
|
||||
/* $Id: mansearch.c,v 1.76 2017/08/02 13:29:04 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2013-2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -171,7 +171,9 @@ mansearch(const struct mansearch *search,
|
||||
page = dbm_page_get(rp->page);
|
||||
|
||||
if (lstmatch(search->sec, page->sect) == 0 ||
|
||||
lstmatch(search->arch, page->arch) == 0)
|
||||
lstmatch(search->arch, page->arch) == 0 ||
|
||||
(search->argmode == ARG_NAME &&
|
||||
rp->bits <= (int32_t)(NAME_SYN & NAME_MASK)))
|
||||
continue;
|
||||
|
||||
if (res == NULL) {
|
||||
@ -452,14 +454,28 @@ lstlen(const char *cp, size_t sep)
|
||||
{
|
||||
size_t sz;
|
||||
|
||||
for (sz = 0;; sz++) {
|
||||
if (cp[0] == '\0') {
|
||||
if (cp[1] == '\0')
|
||||
break;
|
||||
sz += sep - 1;
|
||||
} else if (cp[0] < ' ')
|
||||
sz--;
|
||||
cp++;
|
||||
for (sz = 0; *cp != '\0'; cp++) {
|
||||
|
||||
/* Skip names appearing only in the SYNOPSIS. */
|
||||
if (*cp <= (char)(NAME_SYN & NAME_MASK)) {
|
||||
while (*cp != '\0')
|
||||
cp++;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Skip name class markers. */
|
||||
if (*cp < ' ')
|
||||
cp++;
|
||||
|
||||
/* Print a separator before each but the first string. */
|
||||
if (sz)
|
||||
sz += sep;
|
||||
|
||||
/* Copy one string. */
|
||||
while (*cp != '\0') {
|
||||
sz++;
|
||||
cp++;
|
||||
}
|
||||
}
|
||||
return sz;
|
||||
}
|
||||
@ -471,19 +487,34 @@ lstlen(const char *cp, size_t sep)
|
||||
static void
|
||||
lstcat(char *buf, size_t *i, const char *cp, const char *sep)
|
||||
{
|
||||
const char *s;
|
||||
const char *s;
|
||||
size_t i_start;
|
||||
|
||||
for (;;) {
|
||||
if (cp[0] == '\0') {
|
||||
if (cp[1] == '\0')
|
||||
break;
|
||||
for (i_start = *i; *cp != '\0'; cp++) {
|
||||
|
||||
/* Skip names appearing only in the SYNOPSIS. */
|
||||
if (*cp <= (char)(NAME_SYN & NAME_MASK)) {
|
||||
while (*cp != '\0')
|
||||
cp++;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Skip name class markers. */
|
||||
if (*cp < ' ')
|
||||
cp++;
|
||||
|
||||
/* Print a separator before each but the first string. */
|
||||
if (*i > i_start) {
|
||||
s = sep;
|
||||
while (*s != '\0')
|
||||
buf[(*i)++] = *s++;
|
||||
} else if (cp[0] >= ' ')
|
||||
buf[(*i)++] = cp[0];
|
||||
cp++;
|
||||
}
|
||||
|
||||
/* Copy one string. */
|
||||
while (*cp != '\0')
|
||||
buf[(*i)++] = *cp++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: mdoc_validate.c,v 1.350 2017/07/20 12:54:02 schwarze Exp $ */
|
||||
/* $Id: mdoc_validate.c,v 1.352 2017/08/02 13:29:04 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2010-2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -1137,8 +1137,6 @@ post_fname(POST_ARGS)
|
||||
if ( ! (cp[0] == '\0' || (cp[0] == '(' && cp[1] == '*')))
|
||||
mandoc_msg(MANDOCERR_FN_PAREN, mdoc->parse,
|
||||
n->line, n->pos + pos, n->string);
|
||||
if (n->sec == SEC_SYNOPSIS && mdoc->meta.msec != NULL)
|
||||
mandoc_xr_add(mdoc->meta.msec, n->string, -1, -1);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1205,9 +1203,8 @@ post_nm(POST_ARGS)
|
||||
|
||||
n = mdoc->last;
|
||||
|
||||
if ((n->sec == SEC_NAME || n->sec == SEC_SYNOPSIS) &&
|
||||
n->child != NULL && n->child->type == ROFFT_TEXT &&
|
||||
mdoc->meta.msec != NULL)
|
||||
if (n->sec == SEC_NAME && n->child != NULL &&
|
||||
n->child->type == ROFFT_TEXT && mdoc->meta.msec != NULL)
|
||||
mandoc_xr_add(mdoc->meta.msec, n->child->string, -1, -1);
|
||||
|
||||
if (n->last != NULL &&
|
||||
@ -1931,7 +1928,7 @@ post_root(POST_ARGS)
|
||||
/* Check that we begin with a proper `Sh'. */
|
||||
|
||||
n = mdoc->first->child;
|
||||
while (n != NULL && n->tok != TOKEN_NONE &&
|
||||
while (n != NULL && n->tok >= MDOC_Dd &&
|
||||
mdoc_macros[n->tok].flags & MDOC_PROLOGUE)
|
||||
n = n->next;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: tbl_html.c,v 1.22 2017/06/12 20:14:18 schwarze Exp $ */
|
||||
/* $Id: tbl_html.c,v 1.23 2017/07/31 16:14:10 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -49,6 +49,9 @@ html_tbl_strlen(const char *p, void *arg)
|
||||
static size_t
|
||||
html_tbl_sulen(const struct roffsu *su, void *arg)
|
||||
{
|
||||
if (su->scale < 0.0)
|
||||
return 0;
|
||||
|
||||
switch (su->unit) {
|
||||
case SCALE_FS: /* 2^16 basic units */
|
||||
return su->scale * 65536.0 / 24.0;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: tbl_term.c,v 1.56 2017/07/08 13:43:15 schwarze Exp $ */
|
||||
/* $Id: tbl_term.c,v 1.57 2017/07/31 16:14:10 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2011,2012,2014,2015,2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -51,7 +51,10 @@ static void tbl_word(struct termp *, const struct tbl_dat *);
|
||||
static size_t
|
||||
term_tbl_sulen(const struct roffsu *su, void *arg)
|
||||
{
|
||||
return term_hen((const struct termp *)arg, su);
|
||||
int i;
|
||||
|
||||
i = term_hen((const struct termp *)arg, su);
|
||||
return i > 0 ? i : 0;
|
||||
}
|
||||
|
||||
static size_t
|
||||
|
@ -26,10 +26,10 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef WITH_CASPER
|
||||
#ifdef HAVE_CASPER
|
||||
#include <libcasper.h>
|
||||
#include <casper/cap_dns.h>
|
||||
#endif /* WITH_CASPER */
|
||||
#endif /* HAVE_CASPER */
|
||||
|
||||
#include <netdissect-stdinc.h>
|
||||
|
||||
@ -202,7 +202,7 @@ intoa(uint32_t addr)
|
||||
|
||||
static uint32_t f_netmask;
|
||||
static uint32_t f_localnet;
|
||||
#ifdef WITH_CASPER
|
||||
#ifdef HAVE_CASPER
|
||||
extern cap_channel_t *capdns;
|
||||
#endif
|
||||
|
||||
@ -250,7 +250,7 @@ getname(netdissect_options *ndo, const u_char *ap)
|
||||
*/
|
||||
if (!ndo->ndo_nflag &&
|
||||
(addr & f_netmask) == f_localnet) {
|
||||
#ifdef WITH_CASPER
|
||||
#ifdef HAVE_CASPER
|
||||
if (capdns != NULL) {
|
||||
hp = cap_gethostbyaddr(capdns, (char *)&addr, 4,
|
||||
AF_INET);
|
||||
@ -311,7 +311,7 @@ getname6(netdissect_options *ndo, const u_char *ap)
|
||||
* Do not print names if -n was given.
|
||||
*/
|
||||
if (!ndo->ndo_nflag) {
|
||||
#ifdef WITH_CASPER
|
||||
#ifdef HAVE_CASPER
|
||||
if (capdns != NULL) {
|
||||
hp = cap_gethostbyaddr(capdns, (char *)&addr,
|
||||
sizeof(addr), AF_INET6);
|
||||
|
@ -82,10 +82,10 @@ The Regents of the University of California. All rights reserved.\n";
|
||||
#include <sys/ioccom.h>
|
||||
#include <net/bpf.h>
|
||||
#include <libgen.h>
|
||||
#ifdef WITH_CASPER
|
||||
#ifdef HAVE_CASPER
|
||||
#include <libcasper.h>
|
||||
#include <casper/cap_dns.h>
|
||||
#endif /* WITH_CASPER */
|
||||
#endif /* HAVE_CASPER */
|
||||
#endif /* HAVE_CAPSICUM */
|
||||
#include <pcap.h>
|
||||
#include <signal.h>
|
||||
@ -176,7 +176,7 @@ static int infoprint;
|
||||
|
||||
char *program_name;
|
||||
|
||||
#ifdef WITH_CASPER
|
||||
#ifdef HAVE_CASPER
|
||||
cap_channel_t *capdns;
|
||||
#endif
|
||||
|
||||
@ -730,7 +730,7 @@ get_next_file(FILE *VFile, char *ptr)
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef WITH_CASPER
|
||||
#ifdef HAVE_CASPER
|
||||
static cap_channel_t *
|
||||
capdns_setup(void)
|
||||
{
|
||||
@ -757,7 +757,7 @@ capdns_setup(void)
|
||||
|
||||
return (capdnsloc);
|
||||
}
|
||||
#endif /* WITH_CASPER */
|
||||
#endif /* HAVE_CASPER */
|
||||
|
||||
#ifdef HAVE_PCAP_SET_TSTAMP_PRECISION
|
||||
static int
|
||||
@ -1839,10 +1839,10 @@ main(int argc, char **argv)
|
||||
exit_tcpdump(0);
|
||||
}
|
||||
|
||||
#ifdef WITH_CASPER
|
||||
#ifdef HAVE_CASPER
|
||||
if (!ndo->ndo_nflag)
|
||||
capdns = capdns_setup();
|
||||
#endif /* WITH_CASPER */
|
||||
#endif /* HAVE_CASPER */
|
||||
|
||||
init_print(ndo, localnet, netmask, timezone_offset);
|
||||
|
||||
@ -2066,11 +2066,11 @@ main(int argc, char **argv)
|
||||
|
||||
#ifdef HAVE_CAPSICUM
|
||||
cansandbox = (VFileName == NULL && zflag == NULL);
|
||||
#ifdef WITH_CASPER
|
||||
#ifdef HAVE_CASPER
|
||||
cansandbox = (cansandbox && (ndo->ndo_nflag || capdns != NULL));
|
||||
#else
|
||||
cansandbox = (cansandbox && ndo->ndo_nflag);
|
||||
#endif /* WITH_CASPER */
|
||||
#endif /* HAVE_CASPER */
|
||||
if (cansandbox && cap_enter() < 0 && errno != ENOSYS)
|
||||
error("unable to enter the capability mode");
|
||||
#endif /* HAVE_CAPSICUM */
|
||||
|
@ -5,73 +5,73 @@
|
||||
notify 10 {
|
||||
match "system" "ZFS";
|
||||
match "type" "fs.zfs.checksum";
|
||||
action "logger -p kern.warn -t ZFS 'checksum mismatch, zpool=$pool path=$vdev_path offset=$zio_offset size=$zio_size'";
|
||||
action "logger -p local7.warn -t ZFS 'checksum mismatch, zpool=$pool path=$vdev_path offset=$zio_offset size=$zio_size'";
|
||||
};
|
||||
|
||||
notify 10 {
|
||||
match "system" "ZFS";
|
||||
match "type" "fs.zfs.io";
|
||||
action "logger -p kern.warn -t ZFS 'vdev I/O failure, zpool=$pool path=$vdev_path offset=$zio_offset size=$zio_size error=$zio_err'";
|
||||
action "logger -p local7.warn -t ZFS 'vdev I/O failure, zpool=$pool path=$vdev_path offset=$zio_offset size=$zio_size error=$zio_err'";
|
||||
};
|
||||
|
||||
notify 10 {
|
||||
match "system" "ZFS";
|
||||
match "type" "fs.zfs.data";
|
||||
action "logger -p kern.warn -t ZFS 'pool I/O failure, zpool=$pool error=$zio_err'";
|
||||
action "logger -p local7.warn -t ZFS 'pool I/O failure, zpool=$pool error=$zio_err'";
|
||||
};
|
||||
|
||||
notify 10 {
|
||||
match "system" "ZFS";
|
||||
match "type" "fs.zfs.zpool";
|
||||
action "logger -p kern.err -t ZFS 'failed to load zpool $pool'";
|
||||
action "logger -p local7.err -t ZFS 'failed to load zpool $pool'";
|
||||
};
|
||||
|
||||
notify 10 {
|
||||
match "system" "ZFS";
|
||||
match "type" "fs.zfs.vdev\..*";
|
||||
action "logger -p kern.err -t ZFS 'vdev problem, zpool=$pool path=$vdev_path type=$type'";
|
||||
action "logger -p local7.err -t ZFS 'vdev problem, zpool=$pool path=$vdev_path type=$type'";
|
||||
};
|
||||
|
||||
notify 10 {
|
||||
match "system" "ZFS";
|
||||
match "type" "fs.zfs.io_failure";
|
||||
action "logger -p kern.alert -t ZFS 'catastrophic pool I/O failure, zpool=$pool'";
|
||||
action "logger -p local7.alert -t ZFS 'catastrophic pool I/O failure, zpool=$pool'";
|
||||
};
|
||||
|
||||
notify 10 {
|
||||
match "system" "ZFS";
|
||||
match "type" "fs.zfs.probe_failure";
|
||||
action "logger -p kern.err -t ZFS 'vdev probe failure, zpool=$pool path=$vdev_path'";
|
||||
action "logger -p local7.err -t ZFS 'vdev probe failure, zpool=$pool path=$vdev_path'";
|
||||
};
|
||||
|
||||
notify 10 {
|
||||
match "system" "ZFS";
|
||||
match "type" "fs.zfs.log_replay";
|
||||
action "logger -p kern.err -t ZFS 'pool log replay failure, zpool=$pool'";
|
||||
action "logger -p local7.err -t ZFS 'pool log replay failure, zpool=$pool'";
|
||||
};
|
||||
|
||||
notify 10 {
|
||||
match "system" "ZFS";
|
||||
match "type" "fs.zfs.config_cache_write";
|
||||
action "logger -p kern.warn -t ZFS 'failed to write zpool.cache, zpool=$pool'";
|
||||
action "logger -p local7.warn -t ZFS 'failed to write zpool.cache, zpool=$pool'";
|
||||
};
|
||||
|
||||
|
||||
notify 10 {
|
||||
match "system" "ZFS";
|
||||
match "type" "resource.fs.zfs.removed";
|
||||
action "logger -p kern.notice -t ZFS 'vdev is removed, pool_guid=$pool_guid vdev_guid=$vdev_guid'";
|
||||
action "logger -p local7.notice -t ZFS 'vdev is removed, pool_guid=$pool_guid vdev_guid=$vdev_guid'";
|
||||
};
|
||||
|
||||
notify 10 {
|
||||
match "system" "ZFS";
|
||||
match "type" "resource.fs.zfs.autoreplace";
|
||||
action "logger -p kern.info -t ZFS 'autoreplace is configured for vdev, pool_guid=$pool_guid vdev_guid=$vdev_guid'";
|
||||
action "logger -p local7.info -t ZFS 'autoreplace is configured for vdev, pool_guid=$pool_guid vdev_guid=$vdev_guid'";
|
||||
};
|
||||
|
||||
notify 10 {
|
||||
match "system" "ZFS";
|
||||
match "type" "resource.fs.zfs.statechange";
|
||||
action "logger -p kern.notice -t ZFS 'vdev state changed, pool_guid=$pool_guid vdev_guid=$vdev_guid'";
|
||||
action "logger -p local7.notice -t ZFS 'vdev state changed, pool_guid=$pool_guid vdev_guid=$vdev_guid'";
|
||||
};
|
||||
|
||||
|
@ -12,10 +12,10 @@
|
||||
#ssh stream tcp6 nowait root /usr/sbin/sshd sshd -i -6
|
||||
#telnet stream tcp nowait root /usr/libexec/telnetd telnetd
|
||||
#telnet stream tcp6 nowait root /usr/libexec/telnetd telnetd
|
||||
#shell stream tcp nowait root /usr/libexec/rshd rshd
|
||||
#shell stream tcp6 nowait root /usr/libexec/rshd rshd
|
||||
#login stream tcp nowait root /usr/libexec/rlogind rlogind
|
||||
#login stream tcp6 nowait root /usr/libexec/rlogind rlogind
|
||||
#shell stream tcp nowait root /usr/local/sbin/rshd rshd
|
||||
#shell stream tcp6 nowait root /usr/local/sbin/rshd rshd
|
||||
#login stream tcp nowait root /usr/local/sbin/rlogind rlogind
|
||||
#login stream tcp6 nowait root /usr/local/sbin/rlogind rlogind
|
||||
#finger stream tcp nowait/3/10 nobody /usr/libexec/fingerd fingerd -k -s
|
||||
#finger stream tcp6 nowait/3/10 nobody /usr/libexec/fingerd fingerd -k -s
|
||||
#
|
||||
|
@ -34,8 +34,6 @@
|
||||
..
|
||||
pwait
|
||||
..
|
||||
rcp
|
||||
..
|
||||
rmdir
|
||||
..
|
||||
sh
|
||||
@ -478,6 +476,10 @@
|
||||
..
|
||||
netinet
|
||||
..
|
||||
netpfil
|
||||
pf
|
||||
..
|
||||
..
|
||||
opencrypto
|
||||
..
|
||||
pjdfstest
|
||||
|
@ -35,14 +35,6 @@ FTPMODE= ${FILESMODE}
|
||||
LINKS= ${FILESDIR}/ftpd ${FILESDIR}/ftp
|
||||
.endif
|
||||
|
||||
.if ${MK_RCMDS} != "no"
|
||||
FILESGROUPS+= RCMDS
|
||||
RCMDS+= rsh
|
||||
RCMDSPACKAGE+= rcmds
|
||||
RCMDSDIR= ${FILESDIR}
|
||||
RCMDSMODE= ${FILESMODE}
|
||||
.endif
|
||||
|
||||
.if ${MK_TELNET} != "no"
|
||||
FILESGROUPS+= TELNET
|
||||
TELNET+= telnetd
|
||||
|
@ -1,18 +0,0 @@
|
||||
#
|
||||
# $FreeBSD$
|
||||
#
|
||||
# PAM configuration for the "rsh" service
|
||||
#
|
||||
|
||||
# auth
|
||||
auth required pam_rhosts.so no_warn
|
||||
|
||||
# account
|
||||
account required pam_nologin.so
|
||||
account required pam_unix.so
|
||||
|
||||
# session
|
||||
session required pam_permit.so
|
||||
|
||||
# password
|
||||
password required pam_deny.so
|
@ -46,9 +46,12 @@ SRCS+= app.c \
|
||||
# DEO: why not used?
|
||||
#SRCS+= itbl-ops.c
|
||||
|
||||
.if ${TARGET_ARCH} == "armv6" || ${TARGET_ARCH} == "armv6eb"
|
||||
.if ${TARGET_ARCH:Marmv6*} != ""
|
||||
CFLAGS+= -DCPU_DEFAULT=ARM_ARCH_V6K
|
||||
.endif
|
||||
.if ${TARGET_ARCH:Marmv7*} != ""
|
||||
CFLAGS+= -DCPU_DEFAULT=ARM_ARCH_V7A
|
||||
.endif
|
||||
|
||||
.if ${TARGET_CPUARCH} == "mips"
|
||||
SRCS+= itbl-ops.c itbl-parse.y itbl-lex.l
|
||||
|
@ -34,9 +34,12 @@ CFLAGS+= -DTARGET_ARM_EABI
|
||||
.if ${TARGET_ARCH:Marm*eb} != ""
|
||||
CFLAGS += -DTARGET_ENDIAN_DEFAULT=MASK_BIG_END
|
||||
.endif
|
||||
.if ${TARGET_ARCH} == "armv6" || ${TARGET_ARCH} == "armv6eb"
|
||||
.if ${TARGET_ARCH:Marmv6*} != ""
|
||||
CFLAGS += -DFREEBSD_ARCH_armv6
|
||||
.endif
|
||||
.if ${TARGET_ARCH:Marmv7*} != ""
|
||||
CFLAGS += -DFREEBSD_ARCH_armv7
|
||||
.endif
|
||||
|
||||
.if ${TARGET_CPUARCH} == "mips"
|
||||
.if ${TARGET_ARCH:Mmips*el*} != ""
|
||||
|
@ -75,7 +75,6 @@ SUBDIR= ${SUBDIR_BOOTSTRAP} \
|
||||
libsbuf \
|
||||
libsmb \
|
||||
libsqlite3 \
|
||||
libstand \
|
||||
libstdbuf \
|
||||
libstdthreads \
|
||||
libsysdecode \
|
||||
|
@ -20,10 +20,10 @@ CFLAGS+= -D__STDC_CONSTANT_MACROS
|
||||
TARGET_ARCH?= ${MACHINE_ARCH}
|
||||
BUILD_ARCH?= ${MACHINE_ARCH}
|
||||
|
||||
# Armv6 uses hard float abi, unless the CPUTYPE has soft in it.
|
||||
# Armv6 and armv7 uses hard float abi, unless the CPUTYPE has soft in it.
|
||||
# arm (for armv4 and armv5 CPUs) always uses the soft float ABI.
|
||||
# For all other targets, we stick with 'unknown'.
|
||||
.if ${TARGET_ARCH:Marmv6*} && (!defined(CPUTYPE) || ${CPUTYPE:M*soft*} == "")
|
||||
.if ${TARGET_ARCH:Marmv[67]*} && (!defined(CPUTYPE) || ${CPUTYPE:M*soft*} == "")
|
||||
TARGET_ABI= -gnueabihf
|
||||
.elif ${TARGET_ARCH:Marm*}
|
||||
TARGET_ABI= -gnueabi
|
||||
|
@ -110,7 +110,7 @@ NOASM=
|
||||
.include "${LIBC_SRCTOP}/uuid/Makefile.inc"
|
||||
.include "${LIBC_SRCTOP}/xdr/Makefile.inc"
|
||||
.if (${LIBC_ARCH} == "arm" && \
|
||||
(${MACHINE_ARCH:Marmv6*} == "" || (defined(CPUTYPE) && ${CPUTYPE:M*soft*}))) || \
|
||||
(${MACHINE_ARCH:Marmv[67]*} == "" || (defined(CPUTYPE) && ${CPUTYPE:M*soft*}))) || \
|
||||
(${LIBC_ARCH} == "mips" && ${MACHINE_ARCH:Mmips*hf} == "") || \
|
||||
(${LIBC_ARCH} == "riscv" && ${MACHINE_ARCH:Mriscv*sf} != "")
|
||||
.include "${LIBC_SRCTOP}/softfloat/Makefile.inc"
|
||||
|
@ -11,7 +11,7 @@ SYM_MAPS+=${LIBC_SRCTOP}/arm/Symbol.map
|
||||
|
||||
.include "${LIBC_SRCTOP}/arm/aeabi/Makefile.inc"
|
||||
|
||||
.if ${MACHINE_ARCH:Marmv6*} && (!defined(CPUTYPE) || ${CPUTYPE:M*soft*} == "")
|
||||
.if ${MACHINE_ARCH:Marmv[67]*} && (!defined(CPUTYPE) || ${CPUTYPE:M*soft*} == "")
|
||||
SYM_MAPS+=${LIBC_SRCTOP}/arm/Symbol_vfp.map
|
||||
.endif
|
||||
|
||||
|
@ -5,14 +5,14 @@
|
||||
SRCS+= aeabi_atexit.c \
|
||||
aeabi_unwind_cpp.c \
|
||||
aeabi_unwind_exidx.c
|
||||
.if (${MACHINE_ARCH:Marmv6*} && defined(CPUTYPE) && ${CPUTYPE:M*soft*} != "") || \
|
||||
${MACHINE_ARCH:Marmv6*} == ""
|
||||
.if (${MACHINE_ARCH:Marmv[67]*} && defined(CPUTYPE) && ${CPUTYPE:M*soft*} != "") || \
|
||||
${MACHINE_ARCH:Marmv[67]*} == ""
|
||||
SRCS+= aeabi_asm_double.S \
|
||||
aeabi_asm_float.S \
|
||||
aeabi_double.c \
|
||||
aeabi_float.c
|
||||
.endif
|
||||
.if ${MACHINE_ARCH:Marmv6*} && (!defined(CPUTYPE) || ${CPUTYPE:M*soft*} == "")
|
||||
.if ${MACHINE_ARCH:Marmv[67]*} && (!defined(CPUTYPE) || ${CPUTYPE:M*soft*} == "")
|
||||
SRCS+= aeabi_vfp_double.S \
|
||||
aeabi_vfp_float.S
|
||||
.endif
|
||||
|
@ -7,7 +7,7 @@ SRCS+= _ctx_start.S _setjmp.S _set_tp.c alloca.S fabs.c \
|
||||
arm_initfini.c \
|
||||
trivial-getcontextx.c
|
||||
|
||||
.if ${MACHINE_ARCH:Marmv6*} && (!defined(CPUTYPE) || ${CPUTYPE:M*soft*} == "")
|
||||
.if ${MACHINE_ARCH:Marmv[67]*} && (!defined(CPUTYPE) || ${CPUTYPE:M*soft*} == "")
|
||||
SRCS+= fpgetmask_vfp.c fpgetround_vfp.c fpgetsticky_vfp.c fpsetmask_vfp.c \
|
||||
fpsetround_vfp.c fpsetsticky_vfp.c
|
||||
.endif
|
||||
|
@ -160,9 +160,6 @@ __libc_allocate_tls(void *oldtcb, size_t tcbsize, size_t tcbalign __unused)
|
||||
|
||||
if (tls_init_size > 0)
|
||||
memcpy((void*)dtv[2], tls_init, tls_init_size);
|
||||
if (tls_static_space > tls_init_size)
|
||||
memset((void*)(dtv[2] + tls_init_size), 0,
|
||||
tls_static_space - tls_init_size);
|
||||
}
|
||||
|
||||
return(tcb);
|
||||
|
@ -28,7 +28,7 @@
|
||||
.\" From: @(#)gethostbyname.3 8.4 (Berkeley) 5/25/95
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd May 12, 2006
|
||||
.Dd October 4, 2017
|
||||
.Dt GETHOSTBYNAME 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -189,19 +189,20 @@ function
|
||||
may be used to request the use of a connected
|
||||
.Tn TCP
|
||||
socket for queries.
|
||||
Queries will by default use
|
||||
.Tn UDP
|
||||
datagrams.
|
||||
If the
|
||||
.Fa stayopen
|
||||
flag is non-zero,
|
||||
this sets the option to send all queries to the name server using
|
||||
flag is non-zero, a
|
||||
.Tn TCP
|
||||
and to retain the connection after each call to
|
||||
connection to the name server will be used.
|
||||
It will remain open after calls to
|
||||
.Fn gethostbyname ,
|
||||
.Fn gethostbyname2
|
||||
or
|
||||
.Fn gethostbyaddr .
|
||||
Otherwise, queries are performed using
|
||||
.Tn UDP
|
||||
datagrams.
|
||||
.Fn gethostbyaddr
|
||||
have completed.
|
||||
.Pp
|
||||
The
|
||||
.Fn endhostent
|
||||
|
@ -124,7 +124,7 @@ SYM_MAPS+= ${LIBC_SRCTOP}/sys/Symbol.map
|
||||
CLEANFILES+= ${SASM} ${SPSEUDO}
|
||||
|
||||
.if ${MACHINE_CPUARCH} == "amd64" || ${MACHINE_CPUARCH} == "i386" || \
|
||||
${MACHINE_CPUARCH} == "powerpc" || ${MACHINE_ARCH:Marmv6*}
|
||||
${MACHINE_CPUARCH} == "powerpc" || ${MACHINE_ARCH:Marmv[67]*}
|
||||
NOTE_GNU_STACK='\t.section .note.GNU-stack,"",%%progbits\n'
|
||||
.else
|
||||
NOTE_GNU_STACK=''
|
||||
|
@ -28,7 +28,7 @@
|
||||
.\" @(#)recv.2 8.3 (Berkeley) 2/21/94
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd February 3, 2017
|
||||
.Dd October 3, 2017
|
||||
.Dt RECV 2
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -230,7 +230,7 @@ Here
|
||||
.Fa msg_name
|
||||
and
|
||||
.Fa msg_namelen
|
||||
specify the destination address if the socket is unconnected;
|
||||
specify the source address if the socket is unconnected;
|
||||
.Fa msg_name
|
||||
may be given as a null pointer if no names are desired or required.
|
||||
The
|
||||
|
@ -50,7 +50,8 @@ caph_limit_stream(int fd, int flags)
|
||||
cap_rights_t rights;
|
||||
unsigned long cmds[] = { TIOCGETA, TIOCGWINSZ, FIODTYPE };
|
||||
|
||||
cap_rights_init(&rights, CAP_FCNTL, CAP_FSTAT, CAP_IOCTL, CAP_SEEK);
|
||||
cap_rights_init(&rights, CAP_EVENT, CAP_FCNTL, CAP_FSTAT,
|
||||
CAP_IOCTL, CAP_SEEK);
|
||||
|
||||
if ((flags & CAPH_READ) != 0)
|
||||
cap_rights_set(&rights, CAP_READ);
|
||||
|
@ -204,7 +204,7 @@ SRCF+= stdatomic
|
||||
.endif
|
||||
|
||||
.for file in ${SRCF}
|
||||
.if ${MACHINE_ARCH:Marmv6*} && (!defined(CPUTYPE) || ${CPUTYPE:M*soft*} == "") \
|
||||
.if ${MACHINE_ARCH:Marmv[67]*} && (!defined(CPUTYPE) || ${CPUTYPE:M*soft*} == "") \
|
||||
&& exists(${CRTSRC}/${CRTARCH}/${file}vfp.S)
|
||||
SRCS+= ${file}vfp.S
|
||||
. elif exists(${CRTSRC}/${CRTARCH}/${file}.S)
|
||||
|
@ -25,7 +25,7 @@
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd June 6, 2014
|
||||
.Dd October 5, 2017
|
||||
.Dt CUSE 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -292,6 +292,7 @@ enum {
|
||||
CUSE_ERR_SIGNAL
|
||||
CUSE_ERR_OTHER
|
||||
CUSE_ERR_NOT_LOADED
|
||||
CUSE_ERR_NO_DEVICE
|
||||
|
||||
CUSE_POLL_NONE
|
||||
CUSE_POLL_READ
|
||||
|
@ -48,10 +48,12 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/stat.h>
|
||||
#include <sys/vnode.h>
|
||||
#include <sys/socket.h>
|
||||
#define _WANT_SOCKET
|
||||
#include <sys/socketvar.h>
|
||||
#include <sys/domain.h>
|
||||
#include <sys/protosw.h>
|
||||
#include <sys/un.h>
|
||||
#define _WANT_UNPCB
|
||||
#include <sys/unpcb.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/tty.h>
|
||||
@ -580,6 +582,10 @@ procstat_getfiles_kvm(struct procstat *procstat, struct kinfo_proc *kp, int mmap
|
||||
type = PS_FST_TYPE_SHM;
|
||||
data = file.f_data;
|
||||
break;
|
||||
case DTYPE_PROCDESC:
|
||||
type = PS_FST_TYPE_PROCDESC;
|
||||
data = file.f_data;
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
@ -663,6 +669,7 @@ kinfo_type2fst(int kftype)
|
||||
int kf_type;
|
||||
int fst_type;
|
||||
} kftypes2fst[] = {
|
||||
{ KF_TYPE_PROCDESC, PS_FST_TYPE_PROCDESC },
|
||||
{ KF_TYPE_CRYPTO, PS_FST_TYPE_CRYPTO },
|
||||
{ KF_TYPE_FIFO, PS_FST_TYPE_FIFO },
|
||||
{ KF_TYPE_KQUEUE, PS_FST_TYPE_KQUEUE },
|
||||
|
@ -68,6 +68,7 @@
|
||||
#define PS_FST_TYPE_SEM 10
|
||||
#define PS_FST_TYPE_UNKNOWN 11
|
||||
#define PS_FST_TYPE_NONE 12
|
||||
#define PS_FST_TYPE_PROCDESC 13
|
||||
|
||||
/*
|
||||
* Special descriptor numbers.
|
||||
|
@ -719,6 +719,8 @@ extern char *_usrstack __hidden;
|
||||
extern int _libthr_debug;
|
||||
extern int _thread_event_mask;
|
||||
extern struct pthread *_thread_last_event;
|
||||
/* Used in symbol lookup of libthread_db */
|
||||
extern struct pthread_key _thread_keytable[];
|
||||
|
||||
/* List of all threads: */
|
||||
extern pthreadlist _thread_list;
|
||||
|
@ -42,7 +42,8 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include "thr_private.h"
|
||||
|
||||
static struct pthread_key _thread_keytable[PTHREAD_KEYS_MAX];
|
||||
/* Used in symbol lookup of libthread_db */
|
||||
struct pthread_key _thread_keytable[PTHREAD_KEYS_MAX];
|
||||
|
||||
__weak_reference(_pthread_key_create, pthread_key_create);
|
||||
__weak_reference(_pthread_key_delete, pthread_key_delete);
|
||||
|
@ -3,7 +3,7 @@
|
||||
LDBL_PREC = 53
|
||||
SYM_MAPS += ${.CURDIR}/arm/Symbol.map
|
||||
|
||||
.if ${MACHINE_ARCH:Marmv6*} && defined(CPUTYPE) && ${CPUTYPE:M*soft*} != ""
|
||||
.if ${MACHINE_ARCH:Marmv[67]*} && defined(CPUTYPE) && ${CPUTYPE:M*soft*} != ""
|
||||
ARCH_SRCS = fenv-softfp.c fenv-vfp.c
|
||||
.endif
|
||||
|
||||
|
@ -79,11 +79,6 @@ _rtld-elf= rtld-elf
|
||||
SUBDIR+= rbootd
|
||||
.endif
|
||||
|
||||
.if ${MK_RCMDS} != "no"
|
||||
_rlogind= rlogind
|
||||
_rshd= rshd
|
||||
.endif
|
||||
|
||||
.if ${MK_SENDMAIL} != "no"
|
||||
_mail.local= mail.local
|
||||
_smrsh= smrsh
|
||||
|
@ -430,6 +430,10 @@ main(int argc, char *argv[], char **envp)
|
||||
}
|
||||
}
|
||||
|
||||
/* handle filesize limit gracefully */
|
||||
sa.sa_handler = SIG_IGN;
|
||||
(void)sigaction(SIGXFSZ, &sa, NULL);
|
||||
|
||||
if (daemon_mode) {
|
||||
int *ctl_sock, fd, maxfd = -1, nfds, i;
|
||||
fd_set defreadfds, readfds;
|
||||
@ -1196,14 +1200,14 @@ end_login(void)
|
||||
#endif
|
||||
|
||||
(void) seteuid(0);
|
||||
if (logged_in && dowtmp)
|
||||
ftpd_logwtmp(wtmpid, NULL, NULL);
|
||||
pw = NULL;
|
||||
#ifdef LOGIN_CAP
|
||||
setusercontext(NULL, getpwuid(0), 0, LOGIN_SETALL & ~(LOGIN_SETLOGIN |
|
||||
LOGIN_SETUSER | LOGIN_SETGROUP | LOGIN_SETPATH |
|
||||
LOGIN_SETENV));
|
||||
#endif
|
||||
if (logged_in && dowtmp)
|
||||
ftpd_logwtmp(wtmpid, NULL, NULL);
|
||||
pw = NULL;
|
||||
#ifdef USE_PAM
|
||||
if (pamh) {
|
||||
if ((e = pam_setcred(pamh, PAM_DELETE_CRED)) != PAM_SUCCESS)
|
||||
@ -1478,7 +1482,7 @@ pass(char *passwd)
|
||||
}
|
||||
}
|
||||
setusercontext(lc, pw, 0, LOGIN_SETALL &
|
||||
~(LOGIN_SETUSER | LOGIN_SETPATH | LOGIN_SETENV));
|
||||
~(LOGIN_SETRESOURCES | LOGIN_SETUSER | LOGIN_SETPATH | LOGIN_SETENV));
|
||||
#else
|
||||
setlogin(pw->pw_name);
|
||||
(void) initgroups(pw->pw_name, pw->pw_gid);
|
||||
@ -1520,6 +1524,10 @@ pass(char *passwd)
|
||||
(struct sockaddr *)&his_addr);
|
||||
logged_in = 1;
|
||||
|
||||
#ifdef LOGIN_CAP
|
||||
setusercontext(lc, pw, 0, LOGIN_SETRESOURCES);
|
||||
#endif
|
||||
|
||||
if (guest && stats && statfd < 0)
|
||||
#ifdef VIRTUAL_HOSTING
|
||||
statfd = open(thishost->statfile, O_WRONLY|O_APPEND);
|
||||
@ -2770,6 +2778,11 @@ dologout(int status)
|
||||
|
||||
if (logged_in && dowtmp) {
|
||||
(void) seteuid(0);
|
||||
#ifdef LOGIN_CAP
|
||||
setusercontext(NULL, getpwuid(0), 0, LOGIN_SETALL & ~(LOGIN_SETLOGIN |
|
||||
LOGIN_SETUSER | LOGIN_SETGROUP | LOGIN_SETPATH |
|
||||
LOGIN_SETENV));
|
||||
#endif
|
||||
ftpd_logwtmp(wtmpid, NULL, NULL);
|
||||
}
|
||||
/* beware of flushing buffers after a SIGPIPE */
|
||||
|
@ -1,23 +0,0 @@
|
||||
# @(#)Makefile 8.1 (Berkeley) 6/4/93
|
||||
# $FreeBSD$
|
||||
|
||||
.include <src.opts.mk>
|
||||
|
||||
PACKAGE=rcmds
|
||||
PROG= rlogind
|
||||
MAN= rlogind.8
|
||||
PACKAGE=rcmds
|
||||
LIBADD= util
|
||||
WARNS?= 2
|
||||
|
||||
.if ${MK_INET6_SUPPORT} != "no"
|
||||
CFLAGS+= -DINET6
|
||||
.endif
|
||||
|
||||
.if ${MK_BLACKLIST_SUPPORT} != "no"
|
||||
CFLAGS+= -DUSE_BLACKLIST -I${SRCTOP}/contrib/blacklist/include
|
||||
LIBADD+= blacklist
|
||||
LDFLAGS+=-L${LIBBLACKLISTDIR}
|
||||
.endif
|
||||
|
||||
.include <bsd.prog.mk>
|
@ -1,22 +0,0 @@
|
||||
# $FreeBSD$
|
||||
# Autogenerated - do NOT edit!
|
||||
|
||||
DIRDEPS = \
|
||||
gnu/lib/csu \
|
||||
gnu/lib/libgcc \
|
||||
include \
|
||||
include/arpa \
|
||||
include/xlocale \
|
||||
lib/${CSU_DIR} \
|
||||
lib/libblacklist \
|
||||
lib/libc \
|
||||
lib/libcompiler_rt \
|
||||
lib/libthr \
|
||||
lib/libutil \
|
||||
|
||||
|
||||
.include <dirdeps.mk>
|
||||
|
||||
.if ${DEP_RELDIR} == ${_DEP_RELDIR}
|
||||
# local dependencies - needed for -jN in clean tree
|
||||
.endif
|
@ -1,202 +0,0 @@
|
||||
.\" Copyright (c) 1983, 1989, 1991, 1993
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\" 3. Neither the name of the University nor the names of its contributors
|
||||
.\" may be used to endorse or promote products derived from this software
|
||||
.\" without specific prior written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" @(#)rlogind.8 8.1 (Berkeley) 6/4/93
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd July 3, 2017
|
||||
.Dt RLOGIND 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm rlogind
|
||||
.Nd remote login server
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl Daln
|
||||
.Sh DEPRECATION NOTICE
|
||||
.Nm
|
||||
is deprecated and will be removed from future versions of the
|
||||
.Fx
|
||||
base system.
|
||||
If
|
||||
.Nm
|
||||
is still required, it can be installed from ports or packages
|
||||
(net/bsdrcmds).
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
utility is the server for the
|
||||
.Xr rlogin 1
|
||||
program.
|
||||
The server provides a remote login facility
|
||||
with authentication based on privileged port numbers from trusted hosts.
|
||||
.Pp
|
||||
Options supported by
|
||||
.Nm :
|
||||
.Bl -tag -width indent
|
||||
.It Fl D
|
||||
Set TCP_NODELAY socket option.
|
||||
This improves responsiveness at the expense of
|
||||
some additional network traffic.
|
||||
.It Fl a
|
||||
Ask hostname for verification.
|
||||
.It Fl l
|
||||
Prevent any authentication based on the user's
|
||||
.Dq Pa .rhosts
|
||||
file, unless the user is logging in as the superuser.
|
||||
.It Fl n
|
||||
Disable keep-alive messages.
|
||||
.El
|
||||
.Pp
|
||||
The
|
||||
.Nm
|
||||
utility listens for service requests at the port indicated in
|
||||
the
|
||||
.Dq login
|
||||
service specification; see
|
||||
.Xr services 5 .
|
||||
When a service request is received the following protocol
|
||||
is initiated:
|
||||
.Bl -enum
|
||||
.It
|
||||
The server checks the client's source port.
|
||||
If the port is not in the range 512-1023, the server
|
||||
aborts the connection.
|
||||
.It
|
||||
The server checks the client's source address
|
||||
and requests the corresponding host name (see
|
||||
.Xr gethostbyaddr 3 ,
|
||||
.Xr hosts 5
|
||||
and
|
||||
.Xr named 8 ) .
|
||||
If the hostname cannot be determined,
|
||||
the dot-notation representation of the host address is used.
|
||||
If the hostname is in the same domain as the server (according to
|
||||
the last two components of the domain name),
|
||||
or if the
|
||||
.Fl a
|
||||
option is given,
|
||||
the addresses for the hostname are requested,
|
||||
verifying that the name and address correspond.
|
||||
Normal authentication is bypassed if the address verification fails.
|
||||
.El
|
||||
.Pp
|
||||
Once the source port and address have been checked,
|
||||
.Nm
|
||||
proceeds with the authentication process described in
|
||||
.Xr rshd 8 .
|
||||
It then allocates a pseudo terminal (see
|
||||
.Xr pty 4 ) ,
|
||||
and manipulates file descriptors so that the slave
|
||||
half of the pseudo terminal becomes the
|
||||
.Em stdin ,
|
||||
.Em stdout ,
|
||||
and
|
||||
.Em stderr
|
||||
for a login process.
|
||||
The login process is an instance of the
|
||||
.Xr login 1
|
||||
program, invoked with the
|
||||
.Fl f
|
||||
option if authentication has succeeded.
|
||||
If automatic authentication fails, the user is
|
||||
prompted to log in as if on a standard terminal line.
|
||||
.Pp
|
||||
The parent of the login process manipulates the master side of
|
||||
the pseudo terminal, operating as an intermediary
|
||||
between the login process and the client instance of the
|
||||
.Xr rlogin 1
|
||||
program.
|
||||
In normal operation, the packet protocol described
|
||||
in
|
||||
.Xr pty 4
|
||||
is invoked to provide
|
||||
.Ql ^S/^Q
|
||||
type facilities and propagate
|
||||
interrupt signals to the remote programs.
|
||||
The login process
|
||||
propagates the client terminal's baud rate and terminal type,
|
||||
as found in the environment variable,
|
||||
.Ev TERM ;
|
||||
see
|
||||
.Xr environ 7 .
|
||||
The screen or window size of the terminal is requested from the client,
|
||||
and window size changes from the client are propagated to the pseudo terminal.
|
||||
.Pp
|
||||
Transport-level keepalive messages are enabled unless the
|
||||
.Fl n
|
||||
option is present.
|
||||
The use of keepalive messages allows sessions to be timed out
|
||||
if the client crashes or becomes unreachable.
|
||||
.Sh FILES
|
||||
.Bl -tag -width /etc/hostsxxxxxxxx -compact
|
||||
.It Pa /etc/hosts
|
||||
.It Pa /etc/hosts.equiv
|
||||
.It Ev $HOME Ns Pa /.rhosts
|
||||
.It Pa /var/run/nologin
|
||||
.El
|
||||
.Sh DIAGNOSTICS
|
||||
All initial diagnostic messages are indicated
|
||||
by a leading byte with a value of 1,
|
||||
after which any network connections are closed.
|
||||
If there are no errors before
|
||||
.Xr login 1
|
||||
is invoked, a null byte is returned as in indication of success.
|
||||
.Bl -tag -width Ds
|
||||
.It Sy Try again.
|
||||
A
|
||||
.Xr fork 2
|
||||
by the server failed.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr login 1 ,
|
||||
.Xr ruserok 3 ,
|
||||
.Xr hosts 5 ,
|
||||
.Xr hosts.equiv 5 ,
|
||||
.Xr login.conf 5 ,
|
||||
.Xr nologin 5 ,
|
||||
.Xr services 5 ,
|
||||
.Xr rshd 8
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
utility appeared in
|
||||
.Bx 4.2 .
|
||||
.Pp
|
||||
IPv6 support was added by WIDE/KAME project.
|
||||
.Sh BUGS
|
||||
The authentication procedure used here assumes the integrity
|
||||
of each client machine and the connecting medium.
|
||||
This is
|
||||
insecure, but is useful in an
|
||||
.Dq open
|
||||
environment.
|
||||
.Pp
|
||||
A facility to allow all data exchanges to be encrypted should be
|
||||
present.
|
||||
.Pp
|
||||
A more extensible protocol should be used.
|
@ -1,583 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1983, 1988, 1989, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
* Copyright (c) 2002 Networks Associates Technology, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions of this software were developed for the FreeBSD Project by
|
||||
* ThinkSec AS and NAI Labs, the Security Research Division of Network
|
||||
* Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035
|
||||
* ("CBOSS"), as part of the DARPA CHATS research program.
|
||||
*
|
||||
* 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 0
|
||||
#ifndef lint
|
||||
static const char copyright[] =
|
||||
"@(#) Copyright (c) 1983, 1988, 1989, 1993\n\
|
||||
The Regents of the University of California. All rights reserved.\n";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef lint
|
||||
static const char sccsid[] = "@(#)rlogind.c 8.1 (Berkeley) 6/4/93";
|
||||
#endif /* not lint */
|
||||
#endif
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
/*
|
||||
* remote login server:
|
||||
* \0
|
||||
* remuser\0
|
||||
* locuser\0
|
||||
* terminal_type/speed\0
|
||||
* data
|
||||
*/
|
||||
|
||||
#define FD_SETSIZE 16 /* don't need many bits for select */
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <signal.h>
|
||||
#include <termios.h>
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <libutil.h>
|
||||
#include <paths.h>
|
||||
#include <poll.h>
|
||||
#include <pwd.h>
|
||||
#include <syslog.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#ifdef USE_BLACKLIST
|
||||
#include <blacklist.h>
|
||||
#endif
|
||||
|
||||
#ifndef TIOCPKT_WINDOW
|
||||
#define TIOCPKT_WINDOW 0x80
|
||||
#endif
|
||||
|
||||
#define ARGSTR "Daln"
|
||||
|
||||
char *env[2];
|
||||
#define NMAX 30
|
||||
char lusername[NMAX+1], rusername[NMAX+1];
|
||||
static char term[64] = "TERM=";
|
||||
#define ENVSIZE (sizeof("TERM=")-1) /* skip null for concatenation */
|
||||
int keepalive = 1;
|
||||
int check_all = 0;
|
||||
int no_delay;
|
||||
|
||||
struct passwd *pwd;
|
||||
|
||||
union sockunion {
|
||||
struct sockinet {
|
||||
u_char si_len;
|
||||
u_char si_family;
|
||||
u_short si_port;
|
||||
} su_si;
|
||||
struct sockaddr_in su_sin;
|
||||
struct sockaddr_in6 su_sin6;
|
||||
};
|
||||
#define su_len su_si.si_len
|
||||
#define su_family su_si.si_family
|
||||
#define su_port su_si.si_port
|
||||
|
||||
void doit(int, union sockunion *);
|
||||
int control(int, char *, int);
|
||||
void protocol(int, int);
|
||||
void cleanup(int);
|
||||
void fatal(int, char *, int);
|
||||
int do_rlogin(union sockunion *);
|
||||
void getstr(char *, int, char *);
|
||||
void setup_term(int);
|
||||
int do_krb_login(struct sockaddr_in *);
|
||||
void usage(void);
|
||||
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
extern int __check_rhosts_file;
|
||||
union sockunion from;
|
||||
socklen_t fromlen;
|
||||
int ch, on;
|
||||
|
||||
openlog("rlogind", LOG_PID | LOG_CONS, LOG_AUTH);
|
||||
|
||||
opterr = 0;
|
||||
while ((ch = getopt(argc, argv, ARGSTR)) != -1)
|
||||
switch (ch) {
|
||||
case 'D':
|
||||
no_delay = 1;
|
||||
break;
|
||||
case 'a':
|
||||
check_all = 1;
|
||||
break;
|
||||
case 'l':
|
||||
__check_rhosts_file = 0;
|
||||
break;
|
||||
case 'n':
|
||||
keepalive = 0;
|
||||
break;
|
||||
case '?':
|
||||
default:
|
||||
usage();
|
||||
break;
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
fromlen = sizeof (from);
|
||||
if (getpeername(0, (struct sockaddr *)&from, &fromlen) < 0) {
|
||||
syslog(LOG_ERR,"Can't get peer name of remote host: %m");
|
||||
fatal(STDERR_FILENO, "Can't get peer name of remote host", 1);
|
||||
}
|
||||
on = 1;
|
||||
if (keepalive &&
|
||||
setsockopt(0, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof (on)) < 0)
|
||||
syslog(LOG_WARNING, "setsockopt (SO_KEEPALIVE): %m");
|
||||
if (no_delay &&
|
||||
setsockopt(0, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)) < 0)
|
||||
syslog(LOG_WARNING, "setsockopt (TCP_NODELAY): %m");
|
||||
if (from.su_family == AF_INET)
|
||||
{
|
||||
on = IPTOS_LOWDELAY;
|
||||
if (setsockopt(0, IPPROTO_IP, IP_TOS, (char *)&on, sizeof(int)) < 0)
|
||||
syslog(LOG_WARNING, "setsockopt (IP_TOS): %m");
|
||||
}
|
||||
|
||||
doit(0, &from);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int child;
|
||||
int netf;
|
||||
char line[MAXPATHLEN];
|
||||
int confirmed;
|
||||
|
||||
struct winsize win = { 0, 0, 0, 0 };
|
||||
|
||||
|
||||
void
|
||||
doit(int f, union sockunion *fromp)
|
||||
{
|
||||
int master, pid, on = 1;
|
||||
int authenticated = 0;
|
||||
char hostname[2 * MAXHOSTNAMELEN + 1];
|
||||
char nameinfo[2 * INET6_ADDRSTRLEN + 1];
|
||||
char c;
|
||||
|
||||
alarm(60);
|
||||
read(f, &c, 1);
|
||||
|
||||
if (c != 0)
|
||||
exit(1);
|
||||
|
||||
alarm(0);
|
||||
|
||||
realhostname_sa(hostname, sizeof(hostname) - 1,
|
||||
(struct sockaddr *)fromp, fromp->su_len);
|
||||
/* error check ? */
|
||||
fromp->su_port = ntohs((u_short)fromp->su_port);
|
||||
hostname[sizeof(hostname) - 1] = '\0';
|
||||
|
||||
{
|
||||
if ((fromp->su_family != AF_INET
|
||||
#ifdef INET6
|
||||
&& fromp->su_family != AF_INET6
|
||||
#endif
|
||||
) ||
|
||||
fromp->su_port >= IPPORT_RESERVED ||
|
||||
fromp->su_port < IPPORT_RESERVED/2) {
|
||||
getnameinfo((struct sockaddr *)fromp,
|
||||
fromp->su_len,
|
||||
nameinfo, sizeof(nameinfo), NULL, 0,
|
||||
NI_NUMERICHOST);
|
||||
/* error check ? */
|
||||
syslog(LOG_NOTICE, "Connection from %s on illegal port",
|
||||
nameinfo);
|
||||
#ifdef USE_BLACKLIST
|
||||
blacklist(1, STDIN_FILENO, "illegal port");
|
||||
#endif
|
||||
fatal(f, "Permission denied", 0);
|
||||
}
|
||||
#ifdef IP_OPTIONS
|
||||
if (fromp->su_family == AF_INET)
|
||||
{
|
||||
u_char optbuf[BUFSIZ/3];
|
||||
socklen_t optsize = sizeof(optbuf);
|
||||
int ipproto, i;
|
||||
struct protoent *ip;
|
||||
|
||||
if ((ip = getprotobyname("ip")) != NULL)
|
||||
ipproto = ip->p_proto;
|
||||
else
|
||||
ipproto = IPPROTO_IP;
|
||||
if (getsockopt(0, ipproto, IP_OPTIONS, (char *)optbuf,
|
||||
&optsize) == 0 && optsize != 0) {
|
||||
for (i = 0; i < optsize; ) {
|
||||
u_char c = optbuf[i];
|
||||
if (c == IPOPT_LSRR || c == IPOPT_SSRR) {
|
||||
syslog(LOG_NOTICE,
|
||||
"Connection refused from %s with IP option %s",
|
||||
inet_ntoa(fromp->su_sin.sin_addr),
|
||||
c == IPOPT_LSRR ? "LSRR" : "SSRR");
|
||||
#ifdef USE_BLACKLIST
|
||||
blacklist(1, STDIN_FILENO, "source routing present");
|
||||
#endif
|
||||
exit(1);
|
||||
}
|
||||
if (c == IPOPT_EOL)
|
||||
break;
|
||||
i += (c == IPOPT_NOP) ? 1 : optbuf[i+1];
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (do_rlogin(fromp) == 0)
|
||||
authenticated++;
|
||||
}
|
||||
if (confirmed == 0) {
|
||||
write(f, "", 1);
|
||||
confirmed = 1; /* we sent the null! */
|
||||
}
|
||||
netf = f;
|
||||
|
||||
pid = forkpty(&master, line, NULL, &win);
|
||||
if (pid < 0) {
|
||||
if (errno == ENOENT)
|
||||
fatal(f, "Out of ptys", 0);
|
||||
else
|
||||
fatal(f, "Forkpty", 1);
|
||||
}
|
||||
if (pid == 0) {
|
||||
if (f > 2) /* f should always be 0, but... */
|
||||
(void) close(f);
|
||||
setup_term(0);
|
||||
if (*lusername=='-') {
|
||||
syslog(LOG_ERR, "tried to pass user \"%s\" to login",
|
||||
lusername);
|
||||
#ifdef USE_BLACKLIST
|
||||
blacklist(1, STDIN_FILENO, "invalid user");
|
||||
#endif
|
||||
fatal(STDERR_FILENO, "invalid user", 0);
|
||||
}
|
||||
#ifdef USE_BLACKLIST
|
||||
blacklist(0, STDIN_FILENO, "success");
|
||||
#endif
|
||||
if (authenticated) {
|
||||
execl(_PATH_LOGIN, "login", "-p",
|
||||
"-h", hostname, "-f", lusername, (char *)NULL);
|
||||
} else
|
||||
execl(_PATH_LOGIN, "login", "-p",
|
||||
"-h", hostname, lusername, (char *)NULL);
|
||||
fatal(STDERR_FILENO, _PATH_LOGIN, 1);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
ioctl(f, FIONBIO, &on);
|
||||
ioctl(master, FIONBIO, &on);
|
||||
ioctl(master, TIOCPKT, &on);
|
||||
signal(SIGCHLD, cleanup);
|
||||
protocol(f, master);
|
||||
signal(SIGCHLD, SIG_IGN);
|
||||
cleanup(0);
|
||||
}
|
||||
|
||||
char magic[2] = { 0377, 0377 };
|
||||
char oobdata[] = {TIOCPKT_WINDOW};
|
||||
|
||||
/*
|
||||
* Handle a "control" request (signaled by magic being present)
|
||||
* in the data stream. For now, we are only willing to handle
|
||||
* window size changes.
|
||||
*/
|
||||
int
|
||||
control(int pty, char *cp, int n)
|
||||
{
|
||||
struct winsize w;
|
||||
|
||||
if (n < 4 + (int)sizeof(w) || cp[2] != 's' || cp[3] != 's')
|
||||
return (0);
|
||||
oobdata[0] &= ~TIOCPKT_WINDOW; /* we know he heard */
|
||||
bcopy(cp+4, (char *)&w, sizeof(w));
|
||||
w.ws_row = ntohs(w.ws_row);
|
||||
w.ws_col = ntohs(w.ws_col);
|
||||
w.ws_xpixel = ntohs(w.ws_xpixel);
|
||||
w.ws_ypixel = ntohs(w.ws_ypixel);
|
||||
(void)ioctl(pty, TIOCSWINSZ, &w);
|
||||
return (4+sizeof (w));
|
||||
}
|
||||
|
||||
/*
|
||||
* rlogin "protocol" machine.
|
||||
*/
|
||||
void
|
||||
protocol(int f, int p)
|
||||
{
|
||||
char pibuf[1024+1], fibuf[1024], *pbp = NULL, *fbp = NULL;
|
||||
int pcc = 0, fcc = 0;
|
||||
int cc, nfd, n;
|
||||
char cntl;
|
||||
|
||||
/*
|
||||
* Must ignore SIGTTOU, otherwise we'll stop
|
||||
* when we try and set slave pty's window shape
|
||||
* (our controlling tty is the master pty).
|
||||
*/
|
||||
(void) signal(SIGTTOU, SIG_IGN);
|
||||
send(f, oobdata, 1, MSG_OOB); /* indicate new rlogin */
|
||||
if (f > p)
|
||||
nfd = f + 1;
|
||||
else
|
||||
nfd = p + 1;
|
||||
for (;;) {
|
||||
struct pollfd set[2];
|
||||
|
||||
set[0].fd = p;
|
||||
set[0].events = POLLPRI;
|
||||
set[1].fd = f;
|
||||
set[1].events = 0;
|
||||
if (fcc)
|
||||
set[0].events |= POLLOUT;
|
||||
else
|
||||
set[1].events |= POLLIN;
|
||||
if (pcc >= 0) {
|
||||
if (pcc)
|
||||
set[1].events |= POLLOUT;
|
||||
else
|
||||
set[0].events |= POLLIN;
|
||||
}
|
||||
if ((n = poll(set, 2, INFTIM)) < 0) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
fatal(f, "poll", 1);
|
||||
}
|
||||
if (n == 0) {
|
||||
/* shouldn't happen... */
|
||||
sleep(5);
|
||||
continue;
|
||||
}
|
||||
#define pkcontrol(c) ((c)&(TIOCPKT_FLUSHWRITE|TIOCPKT_NOSTOP|TIOCPKT_DOSTOP))
|
||||
if (set[0].revents & POLLPRI) {
|
||||
cc = read(p, &cntl, 1);
|
||||
if (cc == 1 && pkcontrol(cntl)) {
|
||||
cntl |= oobdata[0];
|
||||
send(f, &cntl, 1, MSG_OOB);
|
||||
if (cntl & TIOCPKT_FLUSHWRITE)
|
||||
pcc = 0;
|
||||
}
|
||||
}
|
||||
if (set[1].revents & POLLIN) {
|
||||
fcc = read(f, fibuf, sizeof(fibuf));
|
||||
if (fcc < 0 && errno == EWOULDBLOCK)
|
||||
fcc = 0;
|
||||
else {
|
||||
char *cp;
|
||||
int left, n;
|
||||
|
||||
if (fcc <= 0)
|
||||
break;
|
||||
fbp = fibuf;
|
||||
|
||||
top:
|
||||
for (cp = fibuf; cp < fibuf+fcc-1; cp++)
|
||||
if (cp[0] == magic[0] &&
|
||||
cp[1] == magic[1]) {
|
||||
left = fcc - (cp-fibuf);
|
||||
n = control(p, cp, left);
|
||||
if (n) {
|
||||
left -= n;
|
||||
if (left > 0)
|
||||
bcopy(cp+n, cp, left);
|
||||
fcc -= n;
|
||||
goto top; /* n^2 */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (set[0].revents & POLLOUT && fcc > 0) {
|
||||
cc = write(p, fbp, fcc);
|
||||
if (cc > 0) {
|
||||
fcc -= cc;
|
||||
fbp += cc;
|
||||
}
|
||||
}
|
||||
|
||||
if (set[0].revents & POLLIN) {
|
||||
pcc = read(p, pibuf, sizeof (pibuf));
|
||||
pbp = pibuf;
|
||||
if (pcc < 0 && errno == EWOULDBLOCK)
|
||||
pcc = 0;
|
||||
else if (pcc <= 0)
|
||||
break;
|
||||
else if (pibuf[0] == 0) {
|
||||
pbp++, pcc--;
|
||||
} else {
|
||||
if (pkcontrol(pibuf[0])) {
|
||||
pibuf[0] |= oobdata[0];
|
||||
send(f, &pibuf[0], 1, MSG_OOB);
|
||||
}
|
||||
pcc = 0;
|
||||
}
|
||||
}
|
||||
if (set[1].revents & POLLOUT && pcc > 0) {
|
||||
cc = write(f, pbp, pcc);
|
||||
if (cc > 0) {
|
||||
pcc -= cc;
|
||||
pbp += cc;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
cleanup(int signo __unused)
|
||||
{
|
||||
|
||||
shutdown(netf, SHUT_RDWR);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void
|
||||
fatal(int f, char *msg, int syserr)
|
||||
{
|
||||
int len;
|
||||
char buf[BUFSIZ], *bp = buf;
|
||||
|
||||
/*
|
||||
* Prepend binary one to message if we haven't sent
|
||||
* the magic null as confirmation.
|
||||
*/
|
||||
if (!confirmed)
|
||||
*bp++ = '\01'; /* error indicator */
|
||||
if (syserr)
|
||||
len = snprintf(bp, sizeof(buf), "rlogind: %s: %s.\r\n",
|
||||
msg, strerror(errno));
|
||||
else
|
||||
len = snprintf(bp, sizeof(buf), "rlogind: %s.\r\n", msg);
|
||||
if (len < 0)
|
||||
len = 0;
|
||||
(void) write(f, buf, bp + len - buf);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int
|
||||
do_rlogin(union sockunion *dest)
|
||||
{
|
||||
|
||||
getstr(rusername, sizeof(rusername), "remuser too long");
|
||||
getstr(lusername, sizeof(lusername), "locuser too long");
|
||||
getstr(term+ENVSIZE, sizeof(term)-ENVSIZE, "Terminal type too long");
|
||||
|
||||
pwd = getpwnam(lusername);
|
||||
if (pwd == NULL)
|
||||
return (-1);
|
||||
/* XXX why don't we syslog() failure? */
|
||||
|
||||
return (iruserok_sa(dest, dest->su_len, pwd->pw_uid == 0, rusername,
|
||||
lusername));
|
||||
}
|
||||
|
||||
void
|
||||
getstr(char *buf, int cnt, char *errmsg)
|
||||
{
|
||||
char c;
|
||||
|
||||
do {
|
||||
if (read(STDIN_FILENO, &c, 1) != 1)
|
||||
exit(1);
|
||||
if (--cnt < 0) {
|
||||
#ifdef USE_BLACKLIST
|
||||
blacklist(1, STDIN_FILENO, "buffer overflow");
|
||||
#endif
|
||||
fatal(STDOUT_FILENO, errmsg, 0);
|
||||
}
|
||||
*buf++ = c;
|
||||
} while (c != 0);
|
||||
}
|
||||
|
||||
extern char **environ;
|
||||
|
||||
void
|
||||
setup_term(int fd)
|
||||
{
|
||||
char *cp;
|
||||
char *speed;
|
||||
struct termios tt, def;
|
||||
|
||||
cp = strchr(term + ENVSIZE, '/');
|
||||
#ifndef notyet
|
||||
tcgetattr(fd, &tt);
|
||||
if (cp) {
|
||||
*cp++ = '\0';
|
||||
speed = cp;
|
||||
cp = strchr(speed, '/');
|
||||
if (cp)
|
||||
*cp++ = '\0';
|
||||
cfsetspeed(&tt, atoi(speed));
|
||||
}
|
||||
|
||||
cfmakesane(&def);
|
||||
tt.c_iflag = def.c_iflag;
|
||||
tt.c_oflag = def.c_oflag;
|
||||
tt.c_lflag = def.c_lflag;
|
||||
tcsetattr(fd, TCSAFLUSH, &tt);
|
||||
#else
|
||||
if (cp) {
|
||||
*cp++ = '\0';
|
||||
speed = cp;
|
||||
cp = strchr(speed, '/');
|
||||
if (cp)
|
||||
*cp++ = '\0';
|
||||
tcgetattr(fd, &tt);
|
||||
cfsetspeed(&tt, atoi(speed));
|
||||
tcsetattr(fd, TCSAFLUSH, &tt);
|
||||
}
|
||||
#endif
|
||||
|
||||
env[0] = term;
|
||||
env[1] = 0;
|
||||
environ = env;
|
||||
}
|
||||
|
||||
void
|
||||
usage(void)
|
||||
{
|
||||
syslog(LOG_ERR, "usage: rlogind [-" ARGSTR "]");
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
# From: @(#)Makefile 8.1 (Berkeley) 6/4/93
|
||||
# $FreeBSD$
|
||||
|
||||
PACKAGE=rcmds
|
||||
|
||||
.include <src.opts.mk>
|
||||
|
||||
PROG= rshd
|
||||
MAN= rshd.8
|
||||
|
||||
PACKAGE=rcmds
|
||||
|
||||
WARNS?= 3
|
||||
WFORMAT=0
|
||||
|
||||
LIBADD= util pam
|
||||
|
||||
.if ${MK_BLACKLIST_SUPPORT} != "no"
|
||||
CFLAGS+= -DUSE_BLACKLIST -I${SRCTOP}/contrib/blacklist/include
|
||||
LIBADD+= blacklist
|
||||
LDFLAGS+=-L${LIBBLACKLISTDIR}
|
||||
.endif
|
||||
|
||||
.include <bsd.prog.mk>
|
@ -1,23 +0,0 @@
|
||||
# $FreeBSD$
|
||||
# Autogenerated - do NOT edit!
|
||||
|
||||
DIRDEPS = \
|
||||
gnu/lib/csu \
|
||||
gnu/lib/libgcc \
|
||||
include \
|
||||
include/arpa \
|
||||
include/xlocale \
|
||||
lib/${CSU_DIR} \
|
||||
lib/libblacklist \
|
||||
lib/libc \
|
||||
lib/libcompiler_rt \
|
||||
lib/libpam/libpam \
|
||||
lib/libthr \
|
||||
lib/libutil \
|
||||
|
||||
|
||||
.include <dirdeps.mk>
|
||||
|
||||
.if ${DEP_RELDIR} == ${_DEP_RELDIR}
|
||||
# local dependencies - needed for -jN in clean tree
|
||||
.endif
|
@ -1,277 +0,0 @@
|
||||
.\" Copyright (c) 1983, 1989, 1991, 1993
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\" 3. Neither the name of the University nor the names of its contributors
|
||||
.\" may be used to endorse or promote products derived from this software
|
||||
.\" without specific prior written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" @(#)rshd.8 8.1 (Berkeley) 6/4/93
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd July 3, 2017
|
||||
.Dt RSHD 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm rshd
|
||||
.Nd remote shell server
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl aDLln
|
||||
.Sh DEPRECATION NOTICE
|
||||
.Nm
|
||||
is deprecated and will be removed from future versions of the
|
||||
.Fx
|
||||
base system.
|
||||
If
|
||||
.Nm
|
||||
is still required, it can be installed from ports or packages
|
||||
(net/bsdrcmds).
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
utility
|
||||
is the server for the
|
||||
.Xr rcmd 3
|
||||
routine and, consequently, for the
|
||||
.Xr rsh 1
|
||||
utility.
|
||||
The server provides remote execution facilities
|
||||
with authentication based on privileged port numbers from trusted hosts.
|
||||
.Pp
|
||||
The
|
||||
.Nm
|
||||
utility listens for service requests at the port indicated in
|
||||
the
|
||||
.Dq cmd
|
||||
service specification; see
|
||||
.Xr services 5 .
|
||||
When a service request is received the following protocol
|
||||
is initiated:
|
||||
.Bl -enum
|
||||
.It
|
||||
The server checks the client's source port.
|
||||
If the port is not in the range 512-1023, the server
|
||||
aborts the connection.
|
||||
.It
|
||||
The server reads characters from the socket up
|
||||
to a
|
||||
.Tn NUL
|
||||
(`\e0') byte.
|
||||
The resultant string is
|
||||
interpreted as an
|
||||
.Tn ASCII
|
||||
number, base 10.
|
||||
.It
|
||||
If the number received in step 2 is non-zero,
|
||||
it is interpreted as the port number of a secondary
|
||||
stream to be used for the
|
||||
.Em stderr .
|
||||
A second connection is then created to the specified
|
||||
port on the client's machine.
|
||||
The source port of this
|
||||
second connection is also in the range 512-1023.
|
||||
.It
|
||||
The server checks the client's source address
|
||||
and requests the corresponding host name (see
|
||||
.Xr gethostbyaddr 3 ,
|
||||
.Xr hosts 5
|
||||
and
|
||||
.Xr named 8 ) .
|
||||
If the hostname cannot be determined or the hostname and address do
|
||||
not match after verification,
|
||||
the dot-notation representation of the host address is used.
|
||||
.It
|
||||
A null terminated user name of at most 16 characters
|
||||
is retrieved on the initial socket.
|
||||
This user name
|
||||
is interpreted as the user identity on the
|
||||
.Em client Ns 's
|
||||
machine.
|
||||
.It
|
||||
A null terminated user name of at most 16 characters
|
||||
is retrieved on the initial socket.
|
||||
This user name
|
||||
is interpreted as a user identity to use on the
|
||||
.Em server Ns 's
|
||||
machine.
|
||||
.It
|
||||
A null terminated command to be passed to a
|
||||
shell is retrieved on the initial socket.
|
||||
The length of
|
||||
the command is limited by the upper bound on the size of
|
||||
the system's argument list.
|
||||
.It
|
||||
The
|
||||
.Nm
|
||||
utility then validates the user using
|
||||
.Xr ruserok 3 ,
|
||||
which uses the file
|
||||
.Pa /etc/hosts.equiv
|
||||
and the
|
||||
.Pa .rhosts
|
||||
file found in the user's home directory.
|
||||
The
|
||||
.Fl l
|
||||
option prevents
|
||||
.Xr ruserok 3
|
||||
from doing any validation based on the user's
|
||||
.Pa .rhosts
|
||||
file,
|
||||
unless the user is the superuser.
|
||||
.It
|
||||
A
|
||||
.Tn NUL
|
||||
byte is returned on the initial socket
|
||||
and the command line is passed to the normal login
|
||||
shell of the user.
|
||||
The
|
||||
shell inherits the network connections established
|
||||
by
|
||||
.Nm .
|
||||
.El
|
||||
.Pp
|
||||
The options are as follows:
|
||||
.Bl -tag -width indent
|
||||
.It Fl a
|
||||
This flag is ignored, and is present for compatibility purposes.
|
||||
.It Fl D
|
||||
Sets the TCP_NODELAY socket option, which improves the performance
|
||||
of small back-to-back writes at the expense of additional network
|
||||
traffic.
|
||||
.It Fl L
|
||||
Causes all successful accesses to be logged to
|
||||
.Xr syslogd 8
|
||||
as
|
||||
.Li auth.info
|
||||
messages.
|
||||
.It Fl l
|
||||
Do not use the user's
|
||||
.Pa .rhosts
|
||||
file for authentication, unless the user is the superuser.
|
||||
.It Fl n
|
||||
Turn off transport level keepalive messages.
|
||||
This will prevent sessions
|
||||
from timing out if the client crashes or becomes unreachable.
|
||||
.El
|
||||
.Sh FILES
|
||||
.Bl -tag -width /var/run/nologin -compact
|
||||
.It Pa /etc/hosts
|
||||
.It Pa /etc/hosts.equiv
|
||||
.It Pa /etc/login.conf
|
||||
.It Ev $HOME Ns Pa /.rhosts
|
||||
.Pp
|
||||
.It Pa /etc/pam.conf
|
||||
.Nm
|
||||
uses
|
||||
.Pa /etc/pam.conf
|
||||
entries with service name
|
||||
.Dq rsh .
|
||||
Authentication modules requiring passwords (such as
|
||||
.Nm pam_unix )
|
||||
are not supported.
|
||||
.El
|
||||
.Sh DIAGNOSTICS
|
||||
Except for the last one listed below,
|
||||
all diagnostic messages
|
||||
are returned on the initial socket,
|
||||
after which any network connections are closed.
|
||||
An error is indicated by a leading byte with a value of
|
||||
1 (0 is returned in step 10 above upon successful completion
|
||||
of all the steps prior to the execution of the login shell).
|
||||
.Bl -tag -width indent
|
||||
.It Sy Locuser too long.
|
||||
The name of the user on the client's machine is
|
||||
longer than 16 characters.
|
||||
.It Sy Ruser too long.
|
||||
The name of the user on the remote machine is
|
||||
longer than 16 characters.
|
||||
.It Sy Command too long.
|
||||
The command line passed exceeds the size of the argument
|
||||
list (as configured into the system).
|
||||
.It Sy Login incorrect.
|
||||
No password file entry for the user name existed
|
||||
or the authentication procedure described above failed.
|
||||
.It Sy Remote directory.
|
||||
The
|
||||
.Xr chdir 2
|
||||
function to the home directory failed.
|
||||
.It Sy Logins not available right now.
|
||||
The
|
||||
.Xr rsh 1
|
||||
utility was attempted outside the allowed hours defined in
|
||||
.Pa /etc/login.conf
|
||||
for the local user's login class.
|
||||
.It Sy Can't make pipe.
|
||||
The pipe needed for the
|
||||
.Em stderr ,
|
||||
was not created.
|
||||
.It Sy Can't fork; try again.
|
||||
A
|
||||
.Xr fork 2
|
||||
by the server failed.
|
||||
.It Sy <shellname>: ...
|
||||
The user's login shell could not be started.
|
||||
This message is returned
|
||||
on the connection associated with the
|
||||
.Em stderr ,
|
||||
and is not preceded by a flag byte.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr rlogin 1 ,
|
||||
.Xr rsh 1 ,
|
||||
.Xr gethostbyaddr 3 ,
|
||||
.Xr rcmd 3 ,
|
||||
.Xr ruserok 3 ,
|
||||
.Xr hosts 5 ,
|
||||
.Xr hosts.equiv 5 ,
|
||||
.Xr login.conf 5 ,
|
||||
.Xr services 5 ,
|
||||
.Xr named 8 ,
|
||||
.Xr rlogind 8 ,
|
||||
.Xr syslogd 8
|
||||
.Sh HISTORY
|
||||
IPv6 support was added by WIDE/KAME project.
|
||||
.Sh BUGS
|
||||
The authentication procedure used here assumes the integrity
|
||||
of each client machine and the connecting medium.
|
||||
This is
|
||||
insecure, but is useful in an
|
||||
.Dq open
|
||||
environment.
|
||||
.Pp
|
||||
A facility to allow all data exchanges to be encrypted should be
|
||||
present.
|
||||
.Pp
|
||||
Post-PAM,
|
||||
.Fx
|
||||
also needs the following patch applied besides properly configuring
|
||||
.Pa .rhosts :
|
||||
.Bd -literal -offset indent
|
||||
--- etc/pam.d/rsh.orig Wed Dec 17 14:36:20 2003
|
||||
+++ etc/pam.d/rsh Wed Dec 17 14:30:43 2003
|
||||
@@ -9 +9 @@
|
||||
-auth required pam_rhosts.so no_warn
|
||||
+auth required pam_rhosts.so no_warn allow_root
|
||||
.Ed
|
||||
.Pp
|
||||
A more extensible protocol (such as Telnet) should be used.
|
@ -1,617 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1988, 1989, 1992, 1993, 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
* Copyright (c) 2002 Networks Associates Technology, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions of this software were developed for the FreeBSD Project by
|
||||
* ThinkSec AS and NAI Labs, the Security Research Division of Network
|
||||
* Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035
|
||||
* ("CBOSS"), as part of the DARPA CHATS research program.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static const char copyright[] =
|
||||
"@(#) Copyright (c) 1988, 1989, 1992, 1993, 1994\n\
|
||||
The Regents of the University of California. All rights reserved.\n";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static const char sccsid[] = "@(#)rshd.c 8.2 (Berkeley) 4/6/94";
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
/*
|
||||
* remote shell server:
|
||||
* [port]\0
|
||||
* ruser\0
|
||||
* luser\0
|
||||
* command\0
|
||||
* data
|
||||
*/
|
||||
#include <sys/param.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <libutil.h>
|
||||
#include <paths.h>
|
||||
#include <pwd.h>
|
||||
#include <signal.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <syslog.h>
|
||||
#include <unistd.h>
|
||||
#include <login_cap.h>
|
||||
|
||||
#include <security/pam_appl.h>
|
||||
#include <security/openpam.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#ifdef USE_BLACKLIST
|
||||
#include <blacklist.h>
|
||||
#endif
|
||||
|
||||
static struct pam_conv pamc = { openpam_nullconv, NULL };
|
||||
static pam_handle_t *pamh;
|
||||
static int pam_err;
|
||||
|
||||
#define PAM_END { \
|
||||
if ((pam_err = pam_setcred(pamh, PAM_DELETE_CRED)) != PAM_SUCCESS) \
|
||||
syslog(LOG_ERR|LOG_AUTH, "pam_setcred(): %s", pam_strerror(pamh, pam_err)); \
|
||||
if ((pam_err = pam_close_session(pamh,0)) != PAM_SUCCESS) \
|
||||
syslog(LOG_ERR|LOG_AUTH, "pam_close_session(): %s", pam_strerror(pamh, pam_err)); \
|
||||
if ((pam_err = pam_end(pamh, pam_err)) != PAM_SUCCESS) \
|
||||
syslog(LOG_ERR|LOG_AUTH, "pam_end(): %s", pam_strerror(pamh, pam_err)); \
|
||||
}
|
||||
|
||||
int keepalive = 1;
|
||||
int log_success; /* If TRUE, log all successful accesses */
|
||||
int sent_null;
|
||||
int no_delay;
|
||||
|
||||
void doit(struct sockaddr *);
|
||||
static void rshd_errx(int, const char *, ...) __printf0like(2, 3);
|
||||
void getstr(char *, int, const char *);
|
||||
int local_domain(char *);
|
||||
char *topdomain(char *);
|
||||
void usage(void);
|
||||
|
||||
char slash[] = "/";
|
||||
char bshell[] = _PATH_BSHELL;
|
||||
|
||||
#define OPTIONS "aDLln"
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
extern int __check_rhosts_file;
|
||||
struct linger linger;
|
||||
socklen_t fromlen;
|
||||
int ch, on = 1;
|
||||
struct sockaddr_storage from;
|
||||
|
||||
openlog("rshd", LOG_PID, LOG_DAEMON);
|
||||
|
||||
opterr = 0;
|
||||
while ((ch = getopt(argc, argv, OPTIONS)) != -1)
|
||||
switch (ch) {
|
||||
case 'a':
|
||||
/* ignored for compatibility */
|
||||
break;
|
||||
case 'l':
|
||||
__check_rhosts_file = 0;
|
||||
break;
|
||||
case 'n':
|
||||
keepalive = 0;
|
||||
break;
|
||||
case 'D':
|
||||
no_delay = 1;
|
||||
break;
|
||||
case 'L':
|
||||
log_success = 1;
|
||||
break;
|
||||
case '?':
|
||||
default:
|
||||
usage();
|
||||
break;
|
||||
}
|
||||
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
fromlen = sizeof (from);
|
||||
if (getpeername(0, (struct sockaddr *)&from, &fromlen) < 0) {
|
||||
syslog(LOG_ERR, "getpeername: %m");
|
||||
exit(1);
|
||||
}
|
||||
if (keepalive &&
|
||||
setsockopt(0, SOL_SOCKET, SO_KEEPALIVE, (char *)&on,
|
||||
sizeof(on)) < 0)
|
||||
syslog(LOG_WARNING, "setsockopt (SO_KEEPALIVE): %m");
|
||||
linger.l_onoff = 1;
|
||||
linger.l_linger = 60; /* XXX */
|
||||
if (setsockopt(0, SOL_SOCKET, SO_LINGER, (char *)&linger,
|
||||
sizeof (linger)) < 0)
|
||||
syslog(LOG_WARNING, "setsockopt (SO_LINGER): %m");
|
||||
if (no_delay &&
|
||||
setsockopt(0, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)) < 0)
|
||||
syslog(LOG_WARNING, "setsockopt (TCP_NODELAY): %m");
|
||||
doit((struct sockaddr *)&from);
|
||||
/* NOTREACHED */
|
||||
return(0);
|
||||
}
|
||||
|
||||
extern char **environ;
|
||||
|
||||
void
|
||||
doit(struct sockaddr *fromp)
|
||||
{
|
||||
extern char *__rcmd_errstr; /* syslog hook from libc/net/rcmd.c. */
|
||||
struct passwd *pwd;
|
||||
u_short port;
|
||||
fd_set ready, readfrom;
|
||||
int cc, nfd, pv[2], pid, s;
|
||||
int one = 1;
|
||||
const char *cp, *errorstr;
|
||||
char sig, buf[BUFSIZ];
|
||||
char *cmdbuf, luser[16], ruser[16];
|
||||
char rhost[2 * MAXHOSTNAMELEN + 1];
|
||||
char numericname[INET6_ADDRSTRLEN];
|
||||
int af, srcport;
|
||||
int maxcmdlen;
|
||||
login_cap_t *lc;
|
||||
|
||||
maxcmdlen = (int)sysconf(_SC_ARG_MAX);
|
||||
if (maxcmdlen <= 0 || (cmdbuf = malloc(maxcmdlen)) == NULL)
|
||||
exit(1);
|
||||
|
||||
(void) signal(SIGINT, SIG_DFL);
|
||||
(void) signal(SIGQUIT, SIG_DFL);
|
||||
(void) signal(SIGTERM, SIG_DFL);
|
||||
af = fromp->sa_family;
|
||||
srcport = ntohs(*((in_port_t *)&fromp->sa_data));
|
||||
if (af == AF_INET) {
|
||||
inet_ntop(af, &((struct sockaddr_in *)fromp)->sin_addr,
|
||||
numericname, sizeof numericname);
|
||||
} else if (af == AF_INET6) {
|
||||
inet_ntop(af, &((struct sockaddr_in6 *)fromp)->sin6_addr,
|
||||
numericname, sizeof numericname);
|
||||
} else {
|
||||
syslog(LOG_ERR, "malformed \"from\" address (af %d)", af);
|
||||
exit(1);
|
||||
}
|
||||
#ifdef IP_OPTIONS
|
||||
if (af == AF_INET) {
|
||||
u_char optbuf[BUFSIZ/3];
|
||||
socklen_t optsize = sizeof(optbuf), ipproto, i;
|
||||
struct protoent *ip;
|
||||
|
||||
if ((ip = getprotobyname("ip")) != NULL)
|
||||
ipproto = ip->p_proto;
|
||||
else
|
||||
ipproto = IPPROTO_IP;
|
||||
if (!getsockopt(0, ipproto, IP_OPTIONS, optbuf, &optsize) &&
|
||||
optsize != 0) {
|
||||
for (i = 0; i < optsize; ) {
|
||||
u_char c = optbuf[i];
|
||||
if (c == IPOPT_LSRR || c == IPOPT_SSRR) {
|
||||
syslog(LOG_NOTICE,
|
||||
"connection refused from %s with IP option %s",
|
||||
numericname,
|
||||
c == IPOPT_LSRR ? "LSRR" : "SSRR");
|
||||
exit(1);
|
||||
}
|
||||
if (c == IPOPT_EOL)
|
||||
break;
|
||||
i += (c == IPOPT_NOP) ? 1 : optbuf[i+1];
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (srcport >= IPPORT_RESERVED ||
|
||||
srcport < IPPORT_RESERVED/2) {
|
||||
syslog(LOG_NOTICE|LOG_AUTH,
|
||||
"connection from %s on illegal port %u",
|
||||
numericname,
|
||||
srcport);
|
||||
#ifdef USE_BLACKLIST
|
||||
blacklist(1, STDIN_FILENO, "illegal port");
|
||||
#endif
|
||||
exit(1);
|
||||
}
|
||||
|
||||
(void) alarm(60);
|
||||
port = 0;
|
||||
s = 0; /* not set or used if port == 0 */
|
||||
for (;;) {
|
||||
char c;
|
||||
if ((cc = read(STDIN_FILENO, &c, 1)) != 1) {
|
||||
if (cc < 0)
|
||||
syslog(LOG_NOTICE, "read: %m");
|
||||
shutdown(0, SHUT_RDWR);
|
||||
exit(1);
|
||||
}
|
||||
if (c == 0)
|
||||
break;
|
||||
port = port * 10 + c - '0';
|
||||
}
|
||||
|
||||
(void) alarm(0);
|
||||
if (port != 0) {
|
||||
int lport = IPPORT_RESERVED - 1;
|
||||
s = rresvport_af(&lport, af);
|
||||
if (s < 0) {
|
||||
syslog(LOG_ERR, "can't get stderr port: %m");
|
||||
exit(1);
|
||||
}
|
||||
if (port >= IPPORT_RESERVED ||
|
||||
port < IPPORT_RESERVED/2) {
|
||||
syslog(LOG_NOTICE|LOG_AUTH,
|
||||
"2nd socket from %s on unreserved port %u",
|
||||
numericname,
|
||||
port);
|
||||
#ifdef USE_BLACKLIST
|
||||
blacklist(1, STDIN_FILENO, "unreserved port");
|
||||
#endif
|
||||
exit(1);
|
||||
}
|
||||
*((in_port_t *)&fromp->sa_data) = htons(port);
|
||||
if (connect(s, fromp, fromp->sa_len) < 0) {
|
||||
syslog(LOG_INFO, "connect second port %d: %m", port);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
errorstr = NULL;
|
||||
realhostname_sa(rhost, sizeof(rhost) - 1, fromp, fromp->sa_len);
|
||||
rhost[sizeof(rhost) - 1] = '\0';
|
||||
/* XXX truncation! */
|
||||
|
||||
(void) alarm(60);
|
||||
getstr(ruser, sizeof(ruser), "ruser");
|
||||
getstr(luser, sizeof(luser), "luser");
|
||||
getstr(cmdbuf, maxcmdlen, "command");
|
||||
(void) alarm(0);
|
||||
|
||||
pam_err = pam_start("rsh", luser, &pamc, &pamh);
|
||||
if (pam_err != PAM_SUCCESS) {
|
||||
syslog(LOG_ERR|LOG_AUTH, "pam_start(): %s",
|
||||
pam_strerror(pamh, pam_err));
|
||||
#ifdef USE_BLACKLIST
|
||||
blacklist(1, STDIN_FILENO, "login incorrect");
|
||||
#endif
|
||||
rshd_errx(1, "Login incorrect.");
|
||||
}
|
||||
|
||||
if ((pam_err = pam_set_item(pamh, PAM_RUSER, ruser)) != PAM_SUCCESS ||
|
||||
(pam_err = pam_set_item(pamh, PAM_RHOST, rhost)) != PAM_SUCCESS) {
|
||||
syslog(LOG_ERR|LOG_AUTH, "pam_set_item(): %s",
|
||||
pam_strerror(pamh, pam_err));
|
||||
#ifdef USE_BLACKLIST
|
||||
blacklist(1, STDIN_FILENO, "login incorrect");
|
||||
#endif
|
||||
rshd_errx(1, "Login incorrect.");
|
||||
}
|
||||
|
||||
pam_err = pam_authenticate(pamh, 0);
|
||||
if (pam_err == PAM_SUCCESS) {
|
||||
if ((pam_err = pam_get_user(pamh, &cp, NULL)) == PAM_SUCCESS) {
|
||||
strlcpy(luser, cp, sizeof(luser));
|
||||
/* XXX truncation! */
|
||||
}
|
||||
pam_err = pam_acct_mgmt(pamh, 0);
|
||||
}
|
||||
if (pam_err != PAM_SUCCESS) {
|
||||
syslog(LOG_INFO|LOG_AUTH,
|
||||
"%s@%s as %s: permission denied (%s). cmd='%.80s'",
|
||||
ruser, rhost, luser, pam_strerror(pamh, pam_err), cmdbuf);
|
||||
#ifdef USE_BLACKLIST
|
||||
blacklist(1, STDIN_FILENO, "permission denied");
|
||||
#endif
|
||||
rshd_errx(1, "Login incorrect.");
|
||||
}
|
||||
|
||||
setpwent();
|
||||
pwd = getpwnam(luser);
|
||||
if (pwd == NULL) {
|
||||
syslog(LOG_INFO|LOG_AUTH,
|
||||
"%s@%s as %s: unknown login. cmd='%.80s'",
|
||||
ruser, rhost, luser, cmdbuf);
|
||||
#ifdef USE_BLACKLIST
|
||||
blacklist(1, STDIN_FILENO, "unknown login");
|
||||
#endif
|
||||
if (errorstr == NULL)
|
||||
errorstr = "Login incorrect.";
|
||||
rshd_errx(1, errorstr, rhost);
|
||||
}
|
||||
|
||||
lc = login_getpwclass(pwd);
|
||||
if (pwd->pw_uid)
|
||||
auth_checknologin(lc);
|
||||
|
||||
if (chdir(pwd->pw_dir) < 0) {
|
||||
if (chdir("/") < 0 ||
|
||||
login_getcapbool(lc, "requirehome", !!pwd->pw_uid)) {
|
||||
syslog(LOG_INFO|LOG_AUTH,
|
||||
"%s@%s as %s: no home directory. cmd='%.80s'",
|
||||
ruser, rhost, luser, cmdbuf);
|
||||
rshd_errx(0, "No remote home directory.");
|
||||
}
|
||||
pwd->pw_dir = slash;
|
||||
}
|
||||
|
||||
if (lc != NULL && fromp->sa_family == AF_INET) { /*XXX*/
|
||||
char remote_ip[MAXHOSTNAMELEN];
|
||||
|
||||
strlcpy(remote_ip, numericname, sizeof(remote_ip));
|
||||
/* XXX truncation! */
|
||||
if (!auth_hostok(lc, rhost, remote_ip)) {
|
||||
syslog(LOG_INFO|LOG_AUTH,
|
||||
"%s@%s as %s: permission denied (%s). cmd='%.80s'",
|
||||
ruser, rhost, luser, __rcmd_errstr,
|
||||
cmdbuf);
|
||||
#ifdef USE_BLACKLIST
|
||||
blacklist(1, STDIN_FILENO, "permission denied");
|
||||
#endif
|
||||
rshd_errx(1, "Login incorrect.");
|
||||
}
|
||||
if (!auth_timeok(lc, time(NULL)))
|
||||
rshd_errx(1, "Logins not available right now");
|
||||
}
|
||||
|
||||
/*
|
||||
* PAM modules might add supplementary groups in
|
||||
* pam_setcred(), so initialize them first.
|
||||
* But we need to open the session as root.
|
||||
*/
|
||||
if (setusercontext(lc, pwd, pwd->pw_uid, LOGIN_SETGROUP) != 0) {
|
||||
syslog(LOG_ERR, "setusercontext: %m");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if ((pam_err = pam_open_session(pamh, 0)) != PAM_SUCCESS) {
|
||||
syslog(LOG_ERR, "pam_open_session: %s", pam_strerror(pamh, pam_err));
|
||||
} else if ((pam_err = pam_setcred(pamh, PAM_ESTABLISH_CRED)) != PAM_SUCCESS) {
|
||||
syslog(LOG_ERR, "pam_setcred: %s", pam_strerror(pamh, pam_err));
|
||||
}
|
||||
|
||||
(void) write(STDERR_FILENO, "\0", 1);
|
||||
sent_null = 1;
|
||||
|
||||
if (port) {
|
||||
if (pipe(pv) < 0)
|
||||
rshd_errx(1, "Can't make pipe.");
|
||||
pid = fork();
|
||||
if (pid == -1)
|
||||
rshd_errx(1, "Can't fork; try again.");
|
||||
if (pid) {
|
||||
(void) close(0);
|
||||
(void) close(1);
|
||||
(void) close(2);
|
||||
(void) close(pv[1]);
|
||||
|
||||
FD_ZERO(&readfrom);
|
||||
FD_SET(s, &readfrom);
|
||||
FD_SET(pv[0], &readfrom);
|
||||
if (pv[0] > s)
|
||||
nfd = pv[0];
|
||||
else
|
||||
nfd = s;
|
||||
ioctl(pv[0], FIONBIO, (char *)&one);
|
||||
|
||||
/* should set s nbio! */
|
||||
nfd++;
|
||||
do {
|
||||
ready = readfrom;
|
||||
if (select(nfd, &ready, (fd_set *)0,
|
||||
(fd_set *)0, (struct timeval *)0) < 0)
|
||||
break;
|
||||
if (FD_ISSET(s, &ready)) {
|
||||
int ret;
|
||||
ret = read(s, &sig, 1);
|
||||
if (ret <= 0)
|
||||
FD_CLR(s, &readfrom);
|
||||
else
|
||||
killpg(pid, sig);
|
||||
}
|
||||
if (FD_ISSET(pv[0], &ready)) {
|
||||
errno = 0;
|
||||
cc = read(pv[0], buf, sizeof(buf));
|
||||
if (cc <= 0) {
|
||||
shutdown(s, SHUT_RDWR);
|
||||
FD_CLR(pv[0], &readfrom);
|
||||
} else {
|
||||
(void)write(s, buf, cc);
|
||||
}
|
||||
}
|
||||
|
||||
} while (FD_ISSET(s, &readfrom) ||
|
||||
FD_ISSET(pv[0], &readfrom));
|
||||
PAM_END;
|
||||
exit(0);
|
||||
}
|
||||
(void) close(s);
|
||||
(void) close(pv[0]);
|
||||
dup2(pv[1], 2);
|
||||
close(pv[1]);
|
||||
}
|
||||
else {
|
||||
pid = fork();
|
||||
if (pid == -1)
|
||||
rshd_errx(1, "Can't fork; try again.");
|
||||
if (pid) {
|
||||
/* Parent. */
|
||||
while (wait(NULL) > 0 || errno == EINTR)
|
||||
/* nothing */ ;
|
||||
PAM_END;
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef USE_BLACKLIST
|
||||
blacklist(0, STDIN_FILENO, "success");
|
||||
#endif
|
||||
closefrom(3);
|
||||
if (setsid() == -1)
|
||||
syslog(LOG_ERR, "setsid() failed: %m");
|
||||
if (setlogin(pwd->pw_name) < 0)
|
||||
syslog(LOG_ERR, "setlogin() failed: %m");
|
||||
|
||||
if (*pwd->pw_shell == '\0')
|
||||
pwd->pw_shell = bshell;
|
||||
(void) pam_setenv(pamh, "HOME", pwd->pw_dir, 1);
|
||||
(void) pam_setenv(pamh, "SHELL", pwd->pw_shell, 1);
|
||||
(void) pam_setenv(pamh, "USER", pwd->pw_name, 1);
|
||||
(void) pam_setenv(pamh, "PATH", _PATH_DEFPATH, 1);
|
||||
environ = pam_getenvlist(pamh);
|
||||
(void) pam_end(pamh, pam_err);
|
||||
cp = strrchr(pwd->pw_shell, '/');
|
||||
if (cp)
|
||||
cp++;
|
||||
else
|
||||
cp = pwd->pw_shell;
|
||||
|
||||
if (setusercontext(lc, pwd, pwd->pw_uid,
|
||||
LOGIN_SETALL & ~LOGIN_SETGROUP) < 0) {
|
||||
syslog(LOG_ERR, "setusercontext(): %m");
|
||||
exit(1);
|
||||
}
|
||||
login_close(lc);
|
||||
endpwent();
|
||||
if (log_success || pwd->pw_uid == 0) {
|
||||
syslog(LOG_INFO|LOG_AUTH, "%s@%s as %s: cmd='%.80s'",
|
||||
ruser, rhost, luser, cmdbuf);
|
||||
}
|
||||
execl(pwd->pw_shell, cp, "-c", cmdbuf, (char *)NULL);
|
||||
err(1, "%s", pwd->pw_shell);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Report error to client. Note: can't be used until second socket has
|
||||
* connected to client, or older clients will hang waiting for that
|
||||
* connection first.
|
||||
*/
|
||||
|
||||
static void
|
||||
rshd_errx(int errcode, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
|
||||
if (sent_null == 0)
|
||||
write(STDERR_FILENO, "\1", 1);
|
||||
|
||||
verrx(errcode, fmt, ap);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
void
|
||||
getstr(char *buf, int cnt, const char *error)
|
||||
{
|
||||
char c;
|
||||
|
||||
do {
|
||||
if (read(STDIN_FILENO, &c, 1) != 1)
|
||||
exit(1);
|
||||
*buf++ = c;
|
||||
if (--cnt == 0) {
|
||||
#ifdef USE_BLACKLIST
|
||||
blacklist(1, STDIN_FILENO, "buffer overflow");
|
||||
#endif
|
||||
rshd_errx(1, "%s too long", error);
|
||||
}
|
||||
} while (c != 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check whether host h is in our local domain,
|
||||
* defined as sharing the last two components of the domain part,
|
||||
* or the entire domain part if the local domain has only one component.
|
||||
* If either name is unqualified (contains no '.'),
|
||||
* assume that the host is local, as it will be
|
||||
* interpreted as such.
|
||||
*/
|
||||
int
|
||||
local_domain(char *h)
|
||||
{
|
||||
char localhost[MAXHOSTNAMELEN];
|
||||
char *p1, *p2;
|
||||
|
||||
localhost[0] = 0;
|
||||
(void) gethostname(localhost, sizeof(localhost) - 1);
|
||||
localhost[sizeof(localhost) - 1] = '\0';
|
||||
/* XXX truncation! */
|
||||
p1 = topdomain(localhost);
|
||||
p2 = topdomain(h);
|
||||
if (p1 == NULL || p2 == NULL || !strcasecmp(p1, p2))
|
||||
return (1);
|
||||
return (0);
|
||||
}
|
||||
|
||||
char *
|
||||
topdomain(char *h)
|
||||
{
|
||||
char *p, *maybe = NULL;
|
||||
int dots = 0;
|
||||
|
||||
for (p = h + strlen(h); p >= h; p--) {
|
||||
if (*p == '.') {
|
||||
if (++dots == 2)
|
||||
return (p);
|
||||
maybe = p;
|
||||
}
|
||||
}
|
||||
return (maybe);
|
||||
}
|
||||
|
||||
void
|
||||
usage(void)
|
||||
{
|
||||
|
||||
syslog(LOG_ERR, "usage: rshd [-%s]", OPTIONS);
|
||||
exit(2);
|
||||
}
|
@ -161,14 +161,18 @@ ports.txz:
|
||||
${XZ_CMD} > ${.OBJDIR}/ports.txz
|
||||
|
||||
reldoc:
|
||||
cd ${.CURDIR}/doc && ${MAKE} all install clean 'FORMATS=html txt' \
|
||||
cd ${DOCDIR}/en_US.ISO8859-1/htdocs/releases/${REVISION}R && \
|
||||
${MAKE} all install clean 'FORMATS=html txt' \
|
||||
INSTALL_COMPRESSED='' URLS_ABSOLUTE=YES DOCDIR=${.OBJDIR}/rdoc
|
||||
mkdir -p reldoc
|
||||
.for i in hardware readme relnotes errata
|
||||
ln -f rdoc/${RELNOTES_LANG}/${i}/article.txt reldoc/${i:tu}.TXT
|
||||
ln -f rdoc/${RELNOTES_LANG}/${i}/article.html reldoc/${i:tu}.HTM
|
||||
ln -f ${DOCDIR}/${RELNOTES_LANG}/htdocs/releases/${REVISION}R/${i}/${i:tl}.txt \
|
||||
reldoc/${i:tu}.TXT
|
||||
ln -f ${DOCDIR}/${RELNOTES_LANG}/htdocs/releases/${REVISION}R/${i}/${i:tl}.html \
|
||||
reldoc/${i:tu}.HTM
|
||||
.endfor
|
||||
cp rdoc/${RELNOTES_LANG}/readme/docbook.css reldoc
|
||||
cp ${DOCDIR}/${RELNOTES_LANG}/htdocs/releases/${REVISION}R/readme/docbook.css \
|
||||
reldoc
|
||||
|
||||
disc1: packagesystem
|
||||
# Install system
|
||||
|
@ -57,7 +57,7 @@ TLD?= ${FTPDIR}/releases
|
||||
.endif
|
||||
|
||||
.if defined(EMBEDDED) && !empty(EMBEDDED)
|
||||
. if ${TARGET:Marm*} != "" && (${TARGET_ARCH} == "armv6" || ${TARGET_ARCH} == "aarch64")
|
||||
. if ${TARGET:Marm*} != "" && (${TARGET_ARCH:Marmv[67]} != "" || ${TARGET_ARCH} == "aarch64")
|
||||
. if !defined(BOARDNAME) && empty(BOARDNAME)
|
||||
BOARDNAME:= ${KERNCONF}
|
||||
. else
|
||||
|
@ -5,11 +5,11 @@
|
||||
|
||||
EMBEDDEDBUILD=1
|
||||
EMBEDDED_TARGET="arm"
|
||||
EMBEDDED_TARGET_ARCH="armv6"
|
||||
EMBEDDED_TARGET_ARCH="armv7"
|
||||
EMBEDDEDPORTS="sysutils/u-boot-bananapi"
|
||||
KERNEL="GENERIC"
|
||||
WORLD_FLAGS="${WORLD_FLAGS} UBLDR_LOADADDR=0x42000000"
|
||||
IMAGE_SIZE="1536M"
|
||||
IMAGE_SIZE="2560M"
|
||||
PART_SCHEME="MBR"
|
||||
FAT_SIZE="32m -b 1m"
|
||||
FAT_TYPE="16"
|
||||
|
@ -5,16 +5,17 @@
|
||||
|
||||
EMBEDDEDBUILD=1
|
||||
EMBEDDED_TARGET="arm"
|
||||
EMBEDDED_TARGET_ARCH="armv6"
|
||||
EMBEDDED_TARGET_ARCH="armv7"
|
||||
EMBEDDEDPORTS="sysutils/u-boot-beaglebone"
|
||||
KERNEL="BEAGLEBONE"
|
||||
KERNEL="GENERIC"
|
||||
WORLD_FLAGS="${WORLD_FLAGS} UBLDR_LOADADDR=0x88000000"
|
||||
IMAGE_SIZE="1536M"
|
||||
IMAGE_SIZE="2560M"
|
||||
PART_SCHEME="MBR"
|
||||
FAT_SIZE="2m"
|
||||
FAT_TYPE="12"
|
||||
MD_ARGS="-x 63 -y 255"
|
||||
NODOC=1
|
||||
export BOARDNAME="BEAGLEBONE"
|
||||
|
||||
arm_install_uboot() {
|
||||
UBOOT_DIR="/usr/local/share/u-boot/u-boot-beaglebone"
|
||||
|
@ -5,16 +5,17 @@
|
||||
|
||||
EMBEDDEDBUILD=1
|
||||
EMBEDDED_TARGET="arm"
|
||||
EMBEDDED_TARGET_ARCH="armv6"
|
||||
EMBEDDED_TARGET_ARCH="armv7"
|
||||
EMBEDDEDPORTS="sysutils/u-boot-cubieboard"
|
||||
KERNEL="ALLWINNER_UP"
|
||||
KERNEL="GENERIC"
|
||||
WORLD_FLAGS="${WORLD_FLAGS} UBLDR_LOADADDR=0x42000000"
|
||||
IMAGE_SIZE="1536M"
|
||||
IMAGE_SIZE="2560M"
|
||||
PART_SCHEME="MBR"
|
||||
FAT_SIZE="32m -b 1m"
|
||||
FAT_TYPE="16"
|
||||
MD_ARGS="-x 63 -y 255"
|
||||
NODOC=1
|
||||
export BOARDNAME="CUBIEBOARD"
|
||||
|
||||
arm_install_uboot() {
|
||||
UBOOT_DIR="/usr/local/share/u-boot/u-boot-cubieboard"
|
||||
|
@ -5,11 +5,11 @@
|
||||
|
||||
EMBEDDEDBUILD=1
|
||||
EMBEDDED_TARGET="arm"
|
||||
EMBEDDED_TARGET_ARCH="armv6"
|
||||
EMBEDDED_TARGET_ARCH="armv7"
|
||||
EMBEDDEDPORTS="sysutils/u-boot-cubieboard2"
|
||||
KERNEL="GENERIC"
|
||||
WORLD_FLAGS="${WORLD_FLAGS} UBLDR_LOADADDR=0x42000000"
|
||||
IMAGE_SIZE="1536M"
|
||||
IMAGE_SIZE="2560M"
|
||||
PART_SCHEME="MBR"
|
||||
FAT_SIZE="32m -b 1m"
|
||||
FAT_TYPE="16"
|
||||
|
@ -5,11 +5,11 @@
|
||||
|
||||
EMBEDDEDBUILD=1
|
||||
EMBEDDED_TARGET="arm"
|
||||
EMBEDDED_TARGET_ARCH="armv6"
|
||||
EMBEDDED_TARGET_ARCH="armv7"
|
||||
EMBEDDEDPORTS="sysutils/u-boot-cubox-hummingboard"
|
||||
KERNEL="IMX6"
|
||||
WORLD_FLAGS="${WORLD_FLAGS} UBLDR_LOADADDR=0x12000000"
|
||||
IMAGE_SIZE="1536M"
|
||||
IMAGE_SIZE="2560M"
|
||||
PART_SCHEME="MBR"
|
||||
FAT_SIZE="50m -b 16384"
|
||||
FAT_TYPE="16"
|
||||
|
@ -9,7 +9,7 @@ EMBEDDED_TARGET_ARCH="armv6"
|
||||
EMBEDDEDPORTS="sysutils/u-boot-duovero"
|
||||
KERNEL="GUMSTIX"
|
||||
WORLD_FLAGS="${WORLD_FLAGS} UBLDR_LOADADDR=0x88000000"
|
||||
IMAGE_SIZE="1536M"
|
||||
IMAGE_SIZE="2560M"
|
||||
PART_SCHEME="MBR"
|
||||
FAT_SIZE="2m"
|
||||
FAT_TYPE="12"
|
||||
|
@ -5,16 +5,17 @@
|
||||
|
||||
EMBEDDEDBUILD=1
|
||||
EMBEDDED_TARGET="arm"
|
||||
EMBEDDED_TARGET_ARCH="armv6"
|
||||
EMBEDDED_TARGET_ARCH="armv7"
|
||||
EMBEDDEDPORTS="sysutils/u-boot-pandaboard"
|
||||
KERNEL="PANDABOARD"
|
||||
KERNEL="GENERIC"
|
||||
WORLD_FLAGS="${WORLD_FLAGS} UBLDR_LOADADDR=0x88000000"
|
||||
IMAGE_SIZE="1536M"
|
||||
IMAGE_SIZE="2560M"
|
||||
PART_SCHEME="MBR"
|
||||
FAT_SIZE="2m"
|
||||
FAT_TYPE="12"
|
||||
MD_ARGS="-x 63 -y 255"
|
||||
NODOC=1
|
||||
export BOARDNAME="PANDABOARD"
|
||||
|
||||
arm_install_uboot() {
|
||||
UBOOT_DIR="/usr/local/share/u-boot/u-boot-pandaboard"
|
||||
|
@ -9,7 +9,7 @@ EMBEDDED_TARGET_ARCH="armv6"
|
||||
EMBEDDEDPORTS="sysutils/u-boot-rpi"
|
||||
KERNEL="RPI-B"
|
||||
WORLD_FLAGS="${WORLD_FLAGS} UBLDR_LOADADDR=0x2000000"
|
||||
IMAGE_SIZE="1536M"
|
||||
IMAGE_SIZE="2560M"
|
||||
PART_SCHEME="MBR"
|
||||
FAT_SIZE="17m"
|
||||
FAT_TYPE="16"
|
||||
|
@ -5,11 +5,11 @@
|
||||
|
||||
EMBEDDEDBUILD=1
|
||||
EMBEDDED_TARGET="arm"
|
||||
EMBEDDED_TARGET_ARCH="armv6"
|
||||
EMBEDDED_TARGET_ARCH="armv7"
|
||||
EMBEDDEDPORTS="sysutils/u-boot-rpi2"
|
||||
KERNEL="GENERIC"
|
||||
WORLD_FLAGS="${WORLD_FLAGS} UBLDR_LOADADDR=0x2000000"
|
||||
IMAGE_SIZE="1536M"
|
||||
IMAGE_SIZE="2560M"
|
||||
PART_SCHEME="MBR"
|
||||
FAT_SIZE="50m"
|
||||
FAT_TYPE="16"
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
EMBEDDEDBUILD=1
|
||||
EMBEDDED_TARGET="arm"
|
||||
EMBEDDED_TARGET_ARCH="armv6"
|
||||
EMBEDDED_TARGET_ARCH="armv7"
|
||||
EMBEDDEDPORTS="sysutils/u-boot-wandboard"
|
||||
KERNEL="IMX6"
|
||||
WORLD_FLAGS="${WORLD_FLAGS} UBLDR_LOADADDR=0x12000000"
|
||||
|
@ -1,38 +0,0 @@
|
||||
# $FreeBSD$
|
||||
#
|
||||
# The user can override the default language to build and install
|
||||
# with the RELNOTES_LANG variable.
|
||||
#
|
||||
.if defined(RELNOTES_LANG) && !empty(RELNOTES_LANG)
|
||||
SUBDIR+= ${RELNOTES_LANG}
|
||||
.else
|
||||
SUBDIR+= en_US.ISO8859-1
|
||||
.endif
|
||||
SUBDIR+= share/xml
|
||||
|
||||
RELN_ROOT?= ${.CURDIR}
|
||||
|
||||
.if exists(/usr/local/bin/svn)
|
||||
SVN?= /usr/local/bin/svn
|
||||
.elif exists(/usr/bin/svn)
|
||||
SVN?= /usr/bin/svn
|
||||
.else
|
||||
SVN?= /usr/bin/svnlite
|
||||
.endif
|
||||
|
||||
SVNFLAGS?= -r HEAD
|
||||
|
||||
update:
|
||||
.if !exists(${SVN})
|
||||
@echo "--------------------------------------------------------------"
|
||||
@echo ">>> Updating ${RELN_ROOT} requires ${SVN}."
|
||||
@echo "--------------------------------------------------------------"
|
||||
@exit 1
|
||||
.endif
|
||||
@echo "--------------------------------------------------------------"
|
||||
@echo ">>> Updating ${.CURDIR}"
|
||||
@echo "--------------------------------------------------------------"
|
||||
@(cd ${.CURDIR} && ${SVN} update ${SVNFLAGS})
|
||||
|
||||
.include "${RELN_ROOT}/share/mk/doc.relnotes.mk"
|
||||
.include "${DOC_PREFIX}/share/mk/doc.subdir.mk"
|
@ -1,127 +0,0 @@
|
||||
-*- text -*-
|
||||
RELNOTESng README
|
||||
Bruce A. Mah <bmah@freebsd.org>
|
||||
$FreeBSD$
|
||||
|
||||
This is the top-level directory for RELNOTESng, a re-write of
|
||||
FreeBSD's *.TXT documentation files. They have been converted to
|
||||
DocBook, and versions of the documents can be now be built for various
|
||||
supported architectures. The output files can be rendered in any
|
||||
format supported by the FreeBSD Documentation Project (for example,
|
||||
ASCII text, PDF, PS, HTML).
|
||||
|
||||
RELNOTESng requires that the FreeBSD doc/ sources are installed; it
|
||||
leverages off of much of the DocProj build infrastructure, including
|
||||
DocBook extensions and stylesheets. If the doc/ sources are not
|
||||
installed in /usr/src, their location should be specified with the
|
||||
DOC_PREFIX Makefile variable. RELNOTESng also requires the DocProj
|
||||
build tools, which can easily be installed with the textproc/docproj
|
||||
port in the Ports Collection.
|
||||
|
||||
Notable files and directories:
|
||||
|
||||
share/mk/doc.relnotes.mk
|
||||
Common Makefile definitions for RELNOTESng. These definitions
|
||||
mostly accommodate the fact that we're building DocProj-like
|
||||
documents outside the doc/ tree.
|
||||
share/xml/catalog
|
||||
Main SGML catalog for all language-neutral (and default EN)
|
||||
stylesheet and entity files. Can be overridden if needed for
|
||||
translations.
|
||||
share/xml/default.dsl
|
||||
All documents build with this file as a stylesheet. All it
|
||||
does is to make it possible to use the document catalogs to
|
||||
locate the "real" stylesheet by reference, rather than having
|
||||
to specify it by pathname.
|
||||
share/xml/release.dsl
|
||||
Language-neutral stylesheet. This stylesheet supports
|
||||
the arch= attribute on (all?) DocBook elements; elements with
|
||||
an arch= attribute are only included in the output if their
|
||||
value is equal to the value of the &arch; entity. In the
|
||||
future, arch= could be a list of possible &arch; entity values
|
||||
that match, such as "i386,sparc64".
|
||||
share/xml/release.ent
|
||||
Release information. Need to update the entry definitions in
|
||||
this file when rolling new revisions; these should take effect
|
||||
in all documents.
|
||||
|
||||
en_US.ISO8859-1/share/xml/release.dsl
|
||||
Language-dependent stylesheet for en, but also the default for
|
||||
translations if they don't override the settings here. This
|
||||
stylesheet sets the email footer at the bottom of HTML pages,
|
||||
as well as a few other parameters. If necessary for
|
||||
translations, this file can be overridden with
|
||||
*/share/xml/release.dsl and */share/xml/catalog.
|
||||
|
||||
*/relnotes/common/
|
||||
Directory for multi-architecture release notes files.
|
||||
*/relnotes/*/
|
||||
Directories for architecture-specific release notes files.
|
||||
|
||||
*/hardware/common/
|
||||
Directory for multi-architecture hardware notes files.
|
||||
*/hardware/*/
|
||||
Directories for architecture-specific hardware notes files.
|
||||
|
||||
*/installation/common/
|
||||
Directory for multi-architecture installation notes files.
|
||||
Note that the FreeBSD DocProj build infrastructure does
|
||||
not handle documents (or subdirectories) named "install"
|
||||
well, so we call our document "installation" and do
|
||||
a hack when it gets installed into a distribution to fix
|
||||
this up.
|
||||
*/installation/*/
|
||||
Directories for architecture-specific release notes files.
|
||||
|
||||
*/errata/
|
||||
Directory for errata document.
|
||||
|
||||
*/readme/
|
||||
Directory for (introductory) document.
|
||||
|
||||
If building the release notes "standalone" (in other words, not part
|
||||
of a release), it may be necessary (depending on the relative
|
||||
locations of the checked-out src/ and doc/ directories) to set the
|
||||
DOC_PREFIX Makefile variable to point to the top directory of the doc/
|
||||
tree. For example:
|
||||
|
||||
% make DOC_PREFIX=/usr/doc all
|
||||
|
||||
All definition of the "current" version of FreeBSD is contained in the
|
||||
share/xml/release.ent file; release engineers should peruse the
|
||||
contents of this file carefully when doing version number bumps.
|
||||
|
||||
When creating content for the architecture-dependent files, authors
|
||||
should use the arch= attribute to elements that are specific to a
|
||||
particular machine architecture. The value of this attribute should
|
||||
be a single word that indicates for which architecture the current
|
||||
element will be included. For example:
|
||||
|
||||
<para arch="sparc64">SPARC64-specific text</para>
|
||||
|
||||
The currently-supported architectures are amd64, arm, i386,
|
||||
powerpc and sparc64. An element may appear for multiple architectures
|
||||
by specifying a comma-separated list of architectures
|
||||
(i.e. arch="sparc64,amd64").
|
||||
|
||||
When creating a translation, make a new directory under this
|
||||
directory with a language code (paralleling the DocProj directory
|
||||
structure). If necessary, new language-dependent HTML footers can be
|
||||
generated by making a new language-dependent
|
||||
${LANG}/share/xml/release.dsl, a ${LANG}/share/xml/catalog that
|
||||
points to it, and a new definition in the Makefiles that adds
|
||||
${LANG}/share/xml/catalog to EXTRA_CATALOGS. Except for the Makefile
|
||||
changes, this is the same procedure that is used for creating a new
|
||||
translation for DocProj files.
|
||||
|
||||
RELNOTESng is now enabled by default in the FreeBSD release-build
|
||||
process. It can be disabled by setting NODOC=YES when building a
|
||||
release (note that this is the same variable that disables DocProj
|
||||
documentation builds).
|
||||
|
||||
Release builders can set which language gets built with the
|
||||
RELNOTES_LANG variable; note that this is different from the
|
||||
DOC_LANG variable because (at least initially) most languages
|
||||
will have localized DocProj files but not localized release notes.
|
||||
The default language, if none is specified, is en_US.ISO8859-1.
|
||||
|
@ -1,16 +0,0 @@
|
||||
# $FreeBSD$
|
||||
|
||||
RELN_ROOT?= ${.CURDIR}/..
|
||||
|
||||
SUBDIR = relnotes
|
||||
SUBDIR+= hardware
|
||||
SUBDIR+= readme
|
||||
SUBDIR+= errata
|
||||
|
||||
COMPAT_SYMLINK = en
|
||||
|
||||
LANGCODE=en_US.ISO8859-1
|
||||
_LANGCODE=en_US.ISO8859-1
|
||||
|
||||
.include "${RELN_ROOT}/share/mk/doc.relnotes.mk"
|
||||
.include "${DOC_PREFIX}/share/mk/doc.project.mk"
|
@ -1,19 +0,0 @@
|
||||
# $FreeBSD$
|
||||
|
||||
RELN_ROOT?= ${.CURDIR}/../..
|
||||
.ifdef NO_LANGCODE_IN_DESTDIR
|
||||
DESTDIR?= ${DOCDIR}/errata
|
||||
.else
|
||||
DESTDIR?= ${DOCDIR}/en_US.ISO8859-1/errata
|
||||
.endif
|
||||
|
||||
DOC?= article
|
||||
FORMATS?= html
|
||||
INSTALL_COMPRESSED?= gz
|
||||
INSTALL_ONLY_COMPRESSED?=
|
||||
|
||||
# SGML content
|
||||
SRCS+= article.xml
|
||||
|
||||
.include "${RELN_ROOT}/share/mk/doc.relnotes.mk"
|
||||
.include "${DOC_PREFIX}/share/mk/doc.project.mk"
|
@ -1,100 +0,0 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!DOCTYPE article PUBLIC "-//FreeBSD//DTD DocBook XML V5.0-Based Extension//EN"
|
||||
"http://www.FreeBSD.org/XML/share/xml/freebsd50.dtd" [
|
||||
<!ENTITY % release PUBLIC "-//FreeBSD//ENTITIES Release Specification//EN"
|
||||
"http://www.FreeBSD.org/release/XML/release.ent">
|
||||
%release;
|
||||
<!ENTITY security SYSTEM "../../share/xml/security.xml">
|
||||
<!ENTITY errata SYSTEM "../../share/xml/errata.xml">
|
||||
]>
|
||||
|
||||
<article xmlns="http://docbook.org/ns/docbook"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
version="5.0">
|
||||
<info>
|
||||
<title>&os; &release; Errata </title>
|
||||
|
||||
<author><orgname>The &os; Project</orgname></author>
|
||||
|
||||
<pubdate>$FreeBSD$</pubdate>
|
||||
|
||||
<copyright>
|
||||
<year>2015</year>
|
||||
|
||||
<holder role="mailto:doc@FreeBSD.org">The &os; Documentation Project</holder>
|
||||
</copyright>
|
||||
|
||||
<legalnotice xml:id="trademarks" role="trademarks">
|
||||
&tm-attrib.freebsd;
|
||||
&tm-attrib.intel;
|
||||
&tm-attrib.sparc;
|
||||
&tm-attrib.general;
|
||||
</legalnotice>
|
||||
|
||||
<abstract>
|
||||
<para>This document lists errata items for &os; &release;,
|
||||
containing significant information discovered after the release
|
||||
or too late in the release cycle to be otherwise included in the
|
||||
release documentation.
|
||||
This information includes security advisories, as well as news
|
||||
relating to the software or documentation that could affect its
|
||||
operation or usability. An up-to-date version of this document
|
||||
should always be consulted before installing this version of
|
||||
&os;.</para>
|
||||
|
||||
<para>This errata document for &os; &release;
|
||||
will be maintained until the release of &os; &release.next;.</para>
|
||||
</abstract>
|
||||
</info>
|
||||
|
||||
<sect1 xml:id="intro">
|
||||
<title>Introduction</title>
|
||||
|
||||
<para>This errata document contains <quote>late-breaking news</quote>
|
||||
about &os; &release;
|
||||
Before installing this version, it is important to consult this
|
||||
document to learn about any post-release discoveries or problems
|
||||
that may already have been found and fixed.</para>
|
||||
|
||||
<para>Any version of this errata document actually distributed
|
||||
with the release (for example, on a CDROM distribution) will be
|
||||
out of date by definition, but other copies are kept updated on
|
||||
the Internet and should be consulted as the <quote>current
|
||||
errata</quote> for this release. These other copies of the
|
||||
errata are located at
|
||||
<link xlink:href="https://www.FreeBSD.org/releases/" />,
|
||||
plus any sites
|
||||
which keep up-to-date mirrors of this location.</para>
|
||||
|
||||
<para>Source and binary snapshots of &os; &release.branch; also
|
||||
contain up-to-date copies of this document (as of the time of
|
||||
the snapshot).</para>
|
||||
|
||||
<para>For a list of all &os; CERT security advisories, see
|
||||
<link xlink:href="https://www.FreeBSD.org/security/"/>.</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 xml:id="security">
|
||||
<title>Security Advisories</title>
|
||||
|
||||
&security;
|
||||
</sect1>
|
||||
|
||||
<sect1 xml:id="errata">
|
||||
<title>Errata Notices</title>
|
||||
|
||||
&errata;
|
||||
</sect1>
|
||||
|
||||
<sect1 xml:id="open-issues">
|
||||
<title>Open Issues</title>
|
||||
|
||||
<para>No open issues.</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 xml:id="late-news">
|
||||
<title>Late-Breaking News</title>
|
||||
|
||||
<para>No news.</para>
|
||||
</sect1>
|
||||
</article>
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user