Started merging with cpio into paxutils.
This commit is contained in:
35
ChangeLog
35
ChangeLog
@@ -1,3 +1,38 @@
|
||||
2004-09-06 Sergey Poznyakoff <gray@Mirddin.farlep.net>
|
||||
|
||||
Started merging with cpio into paxutils. Sources before
|
||||
this point are tagged alpha-1_14_90
|
||||
|
||||
* Makefile.am: Updated for use with paxutils
|
||||
* README-alpha: Likewise
|
||||
* bootstrap: Likewise
|
||||
* configure.ac: Likewise
|
||||
* lib/Makefile.tmpl: Likewise
|
||||
* po/POTFILES.in: Likewise
|
||||
* src/Makefile.am: Likewise
|
||||
* src/buffer.c: Likewise
|
||||
* src/common.h: Likewise
|
||||
* src/compare.c: Likewise
|
||||
* src/create.c: Likewise
|
||||
* src/delete.c: Likewise
|
||||
* src/extract.c: Likewise
|
||||
* src/incremen.c: Likewise
|
||||
* src/list.c: Likewise
|
||||
* src/mangle.c: Likewise
|
||||
* src/misc.c: Likewise
|
||||
* src/names.c: Likewise
|
||||
* src/sparse.c: Likewise
|
||||
* src/system.c: Likewise
|
||||
* src/tar.c: Likewise
|
||||
* src/update.c: Likewise
|
||||
* src/utf8.c: Likewise
|
||||
* src/xheader.c: Likewise
|
||||
|
||||
* src/system.h: Removed
|
||||
* src/rmt.c: Removed
|
||||
* src/rmt.h: Removed
|
||||
* src/rtapelib.c: Removed
|
||||
|
||||
2004-09-03 Sergey Poznyakoff <gray@Mirddin.farlep.net>
|
||||
|
||||
* tests/listed02.sh: Do not depend on any particular ordering
|
||||
|
||||
@@ -20,4 +20,5 @@
|
||||
|
||||
ACLOCAL_AMFLAGS = -I m4
|
||||
EXTRA_DIST = ChangeLog.1 PORTS
|
||||
SUBDIRS = doc lib src scripts po tests
|
||||
SUBDIRS = doc lib rmt src scripts po tests
|
||||
|
||||
|
||||
22
README-alpha
22
README-alpha
@@ -24,25 +24,33 @@ Before building the package, run "bootstrap". It obtains various
|
||||
additional files from the CVS repository and the Translation Project
|
||||
site and prepares the source directory for building.
|
||||
|
||||
When run without arguments, bootstrap will try to obtain gnulib files
|
||||
from CVS repository on savannah using anonymous SSH access. Then, it
|
||||
will fetch the po files from tar page at Translation Project, and,
|
||||
finally, it will start autoconfiguration process. Simply running
|
||||
it without arguments should do in most cases. Several options
|
||||
allow to control the behavior of bootstrap:
|
||||
|
||||
When run without arguments, bootstrap will try to obtain gnulib and
|
||||
paxutils files from their corresponding CVS repositories on Savannah
|
||||
using anonymous SSH access. Then, it will fetch the po files from tar
|
||||
page at Translation Project, and, finally, it will start autoconfiguration
|
||||
process. Simply running it without arguments should do in most cases.
|
||||
Several options allow to control the behavior of bootstrap:
|
||||
|
||||
--gnulib-srcdir=DIRNAME Specify the local directory where gnulib
|
||||
sources reside. Use this if you already
|
||||
have gnulib sources on your machine, and
|
||||
do not want to waste your bandwidth dowloading
|
||||
them again.
|
||||
|
||||
--paxutils-srcdir=DIRNAME Specify the local directory where paxutils
|
||||
sources reside. Use this if you already
|
||||
have paxutils sources on your machine, and
|
||||
do not want to waste your bandwidth dowloading
|
||||
them again.
|
||||
|
||||
--cvs-auth=METHOD Set the CVS access method used for downloading
|
||||
gnulib files. METHOD is one of the keywords
|
||||
accepted by cvs -d option (see info cvs
|
||||
repository).
|
||||
|
||||
--cvs-user=USERNAME Set the CVS username to be used when accessing
|
||||
the gnulib repository.
|
||||
|
||||
--no-po Do not download po files.
|
||||
|
||||
Notice also that when using CVS authentication method "ext", bootstrap
|
||||
|
||||
77
bootstrap
77
bootstrap
@@ -19,7 +19,7 @@
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
# 02111-1307, USA.
|
||||
|
||||
# Written by Paul Eggert.
|
||||
# Written by Paul Eggert and Sergey Poznyakoff.
|
||||
|
||||
# URL of our text domain page in Translation Project
|
||||
TP_URL="http://www2.iro.umontreal.ca/~gnutra/po/maint/tar/"
|
||||
@@ -31,8 +31,13 @@ export LC_ALL
|
||||
|
||||
usage() {
|
||||
cat <<EOF
|
||||
usage: $0 [--gnulib-srcdir=DIR][--cvs-auth=AUTH-METHOD][--cvs-user=USERNAME][--no-po]
|
||||
usage: $0 [--gnulib-srcdir=DIR][--paxutils-srcdir=DIR][--cvs-auth=AUTH-METHOD][--cvs-user=USERNAME][--no-po]
|
||||
Options are:
|
||||
--paxutils-srcdir=DIRNAME Specify the local directory where paxutils
|
||||
sources reside. Use this if you already
|
||||
have paxutils sources on your machine, and
|
||||
do not want to waste your bandwidth dowloading
|
||||
them again.
|
||||
--gnulib-srcdir=DIRNAME Specify the local directory where gnulib
|
||||
sources reside. Use this if you already
|
||||
have gnulib sources on your machine, and
|
||||
@@ -84,6 +89,8 @@ do
|
||||
exit;;
|
||||
--gnulib-srcdir=*)
|
||||
GNULIB_SRCDIR=`expr "$option" : '--gnulib-srcdir=\(.*\)'`;;
|
||||
--paxutils-srcdir=*)
|
||||
PAXUTILS_SRCDIR=`expr "$option" : '--paxutils-srcdir=\(.*\)'`;;
|
||||
--cvs-auth=*)
|
||||
CVS_AUTH=`expr "$option" : '--cvs-auth=\(.*\)'`;;
|
||||
--cvs-user=*)
|
||||
@@ -124,33 +131,41 @@ build_cvs_prefix() {
|
||||
fi
|
||||
}
|
||||
|
||||
# Get gnulib files.
|
||||
|
||||
case ${GNULIB_SRCDIR--} in
|
||||
-)
|
||||
if [ ! -d gnulib ]; then
|
||||
echo "$0: getting gnulib files..."
|
||||
# checkout package
|
||||
checkout() {
|
||||
if [ ! -d $1 ]; then
|
||||
echo "$0: getting $1 files..."
|
||||
|
||||
trap exit 1 2 13 15
|
||||
trap 'rm -fr gnulib; exit 1' 0
|
||||
trap 'rm -fr $1; exit 1' 0
|
||||
|
||||
case "${CVS_AUTH--}" in
|
||||
-) build_cvs_prefix ext anoncvs;;
|
||||
pserver) build_cvs_prefix $CVS_AUTH ${CVS_USER:-anoncvs};;
|
||||
-) build_cvs_prefix ext anoncvs
|
||||
;;
|
||||
pserver) build_cvs_prefix $CVS_AUTH ${CVS_USER:-anoncvs}
|
||||
;;
|
||||
gserver|server)
|
||||
build_cvs_prefix $CVS_AUTH ${CVS_USER--};;
|
||||
ext) build_cvs_prefix $CVS_AUTH ${CVS_USER--};;
|
||||
build_cvs_prefix $CVS_AUTH ${CVS_USER--}
|
||||
;;
|
||||
ext) build_cvs_prefix $CVS_AUTH ${CVS_USER--}
|
||||
;;
|
||||
*) echo "$0: Unknown CVS access method" >&2
|
||||
exit 1;;
|
||||
esac
|
||||
if [ "${CVS_AUTH--}" = "pserver" ]; then
|
||||
cvs -d ${CVS_PREFIX}subversions.gnu.org:/cvsroot/gnulib login || exit
|
||||
cvs -d ${CVS_PREFIX}subversions.gnu.org:/cvsroot/$1 login || exit
|
||||
fi
|
||||
cvs -q -d ${CVS_PREFIX}subversions.gnu.org:/cvsroot/gnulib co gnulib || exit
|
||||
cvs -q -d ${CVS_PREFIX}subversions.gnu.org:/cvsroot/$1 co $1 || exit
|
||||
|
||||
trap 0
|
||||
fi
|
||||
GNULIB_SRCDIR=gnulib
|
||||
}
|
||||
|
||||
# Get gnulib files.
|
||||
|
||||
case ${GNULIB_SRCDIR--} in
|
||||
-) checkout gnulib
|
||||
GNULIB_SRCDIR=gnulib
|
||||
esac
|
||||
|
||||
<$GNULIB_SRCDIR/gnulib-tool || exit
|
||||
@@ -259,6 +274,36 @@ echo "$0: Creating lib/Makefile.am"
|
||||
$GNULIB_SRCDIR/gnulib-tool --extract-automake-snippet $gnulib_module
|
||||
done | sed 's/lib_SOURCES/libtar_a_SOURCES/g' ) > lib/Makefile.am
|
||||
|
||||
# Get paxutils files
|
||||
case ${PAXUTILS_SRCDIR--} in
|
||||
-) checkout paxutils
|
||||
PAXUTILS_SRCDIR=paxutils
|
||||
esac
|
||||
|
||||
# copy_files srcdir dstdir
|
||||
copy_files() {
|
||||
for file in `cat $1/DISTFILES`
|
||||
do
|
||||
case $file in
|
||||
"#*") continue;;
|
||||
esac
|
||||
echo "$0: Copying file $1/$file"
|
||||
cp -p $1/$file $2/`expr $file : '.*/\(.*\)'`
|
||||
done
|
||||
}
|
||||
|
||||
copy_files ${PAXUTILS_SRCDIR}/m4 m4
|
||||
|
||||
if [ -d rmt ]; then
|
||||
:
|
||||
else
|
||||
mkdir rmt
|
||||
fi
|
||||
|
||||
copy_files ${PAXUTILS_SRCDIR}/rmt rmt
|
||||
|
||||
copy_files ${PAXUTILS_SRCDIR}/lib lib
|
||||
|
||||
# Get translations.
|
||||
if test "$DOWNLOAD_PO" = "yes"; then
|
||||
update_po
|
||||
|
||||
54
configure.ac
54
configure.ac
@@ -49,28 +49,6 @@ AC_CHECK_HEADERS([sys/buf.h], [], [],
|
||||
AC_HEADER_SYS_WAIT
|
||||
AM_STDBOOL_H
|
||||
|
||||
enable_rmt() {
|
||||
if test $ac_cv_header_sys_mtio_h = yes; then
|
||||
AC_CACHE_CHECK(for remote tape header files, tar_cv_header_rmt,
|
||||
[AC_TRY_CPP([
|
||||
#if HAVE_SGTTY_H
|
||||
# include <sgtty.h>
|
||||
#endif
|
||||
#include <sys/socket.h>],
|
||||
tar_cv_header_rmt=yes, tar_cv_header_rmt=no)])
|
||||
test $tar_cv_header_rmt = yes && RMT='rmt'
|
||||
AC_SUBST(RMT)
|
||||
fi
|
||||
}
|
||||
|
||||
AC_CACHE_CHECK(which ioctl field to test for reversed bytes,
|
||||
tar_cv_header_mtio_check_field,
|
||||
[AC_EGREP_HEADER(mt_model, sys/mtio.h,
|
||||
tar_cv_header_mtio_check_field=mt_model,
|
||||
tar_cv_header_mtio_check_field=mt_type)])
|
||||
AC_DEFINE_UNQUOTED(MTIO_CHECK_FIELD, $tar_cv_header_mtio_check_field,
|
||||
[Define to mt_model (v.g., for DG/UX), else to mt_type.])
|
||||
|
||||
AC_HEADER_DIRENT
|
||||
AC_HEADER_MAJOR
|
||||
AC_HEADER_STAT
|
||||
@@ -240,36 +218,7 @@ AC_DEFINE_UNQUOTED(DEFAULT_BLOCKING, $DEFAULT_BLOCKING,
|
||||
[Define to a number giving the default blocking size for archives.])
|
||||
AC_MSG_RESULT($DEFAULT_BLOCKING)
|
||||
|
||||
AC_ARG_VAR([DEFAULT_RMT_DIR],
|
||||
[Define full file name of the directory where to install `rmt'. (default: $(libexecdir))])
|
||||
if test "x$DEFAULT_RMT_DIR" != x; then
|
||||
DEFAULT_RMT_COMMAND=$DEFAULT_RMT_DIR/rmt
|
||||
else
|
||||
DEFAULT_RMT_DIR='$(libexecdir)'
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING([whether to build rmt])
|
||||
AC_ARG_WITH([rmt],
|
||||
AC_HELP_STRING([--with-rmt=FILE],
|
||||
[Use FILE as the default `rmt' program. Do not build included copy of `rmt'.]),
|
||||
[case $withval in
|
||||
yes|no) AC_MSG_ERROR([Invalid argument to --with-rmt]);;
|
||||
/*) DEFAULT_RMT_COMMAND=$withval
|
||||
AC_MSG_RESULT([no, use $withval instead]);;
|
||||
*) AC_MSG_ERROR([Argument to --with-rmt must be an absolute file name]);;
|
||||
esac],
|
||||
[AC_MSG_RESULT([yes])
|
||||
enable_rmt
|
||||
if test "$RMT" = ""; then
|
||||
AC_MSG_WARN([not building rmt, required header files are missing])
|
||||
fi])
|
||||
|
||||
AC_SUBST(DEFAULT_RMT_COMMAND)
|
||||
if test "x$DEFAULT_RMT_COMMAND" != x; then
|
||||
AC_DEFINE_UNQUOTED(DEFAULT_RMT_COMMAND, "$DEFAULT_RMT_COMMAND",
|
||||
[Define full file name of rmt program.])
|
||||
fi
|
||||
|
||||
PU_RMT
|
||||
|
||||
# Gettext.
|
||||
AM_GNU_GETTEXT([external], [need-ngettext])
|
||||
@@ -311,6 +260,7 @@ AC_OUTPUT([Makefile\
|
||||
lib/Makefile\
|
||||
po/Makefile.in\
|
||||
scripts/Makefile\
|
||||
rmt/Makefile\
|
||||
src/Makefile\
|
||||
tests/Makefile\
|
||||
tests/preset])
|
||||
|
||||
@@ -19,8 +19,17 @@
|
||||
## 02111-1307, USA.
|
||||
|
||||
noinst_LIBRARIES = libtar.a
|
||||
noinst_HEADERS = system.h localedir.h rmt.h
|
||||
libtar_a_SOURCES = prepargs.c prepargs.h rtapelib.c
|
||||
|
||||
libtar_a_SOURCES = prepargs.c prepargs.h
|
||||
localedir = $(datadir)/locale
|
||||
|
||||
DISTCLEANFILES = localedir.h
|
||||
localedir.h : Makefile
|
||||
echo '#define LOCALEDIR "$(localedir)"' >$@
|
||||
echo "#ifndef DEFAULT_RMT_COMMAND" >> $@
|
||||
echo "# define DEFAULT_RMT_COMMAND \"$(DEFAULT_RMT_DIR)/`echo \"rmt\" | sed 's,^.*/,,;$(transform)'`$(EXEEXT)\"" >> $@
|
||||
echo "#endif" >> $@
|
||||
|
||||
libtar_a_LIBADD = $(LIBOBJS) $(ALLOCA)
|
||||
libtar_a_DEPENDENCIES = $(libtar_a_LIBADD)
|
||||
|
||||
@@ -24,6 +24,9 @@ lib/getopt.c
|
||||
lib/human.c
|
||||
lib/quotearg.c
|
||||
lib/xmalloc.c
|
||||
lib/rtapelib.c
|
||||
|
||||
rmt/rmt.c
|
||||
|
||||
# Package source files
|
||||
src/buffer.c
|
||||
@@ -37,8 +40,6 @@ src/list.c
|
||||
src/mangle.c
|
||||
src/misc.c
|
||||
src/names.c
|
||||
src/rmt.c
|
||||
src/rtapelib.c
|
||||
src/tar.c
|
||||
src/update.c
|
||||
src/xheader.c
|
||||
|
||||
@@ -19,12 +19,8 @@
|
||||
## 02111-1307, USA.
|
||||
|
||||
bin_PROGRAMS = tar
|
||||
rmtdir=$(DEFAULT_RMT_DIR)
|
||||
rmt_PROGRAMS = @RMT@
|
||||
EXTRA_PROGRAMS = rmt
|
||||
|
||||
noinst_HEADERS = arith.h common.h rmt.h system.h tar.h
|
||||
rmt_SOURCES = rmt.c
|
||||
noinst_HEADERS = arith.h common.h tar.h
|
||||
tar_SOURCES = \
|
||||
buffer.c\
|
||||
compare.c\
|
||||
@@ -37,26 +33,16 @@ tar_SOURCES = \
|
||||
mangle.c\
|
||||
misc.c\
|
||||
names.c\
|
||||
rtapelib.c\
|
||||
sparse.c\
|
||||
system.c\
|
||||
tar.c\
|
||||
update.c\
|
||||
utf8.c
|
||||
|
||||
localedir = $(datadir)/locale
|
||||
INCLUDES = -I$(top_srcdir)/lib -I../lib
|
||||
INCLUDES = -I$(top_srcdir)/lib -I../ -I../lib
|
||||
|
||||
DISTCLEANFILES = localedir.h
|
||||
localedir.h : Makefile
|
||||
echo '#define LOCALEDIR "$(localedir)"' >$@
|
||||
echo "#ifndef DEFAULT_RMT_COMMAND" >> $@
|
||||
echo "# define DEFAULT_RMT_COMMAND \"$(rmtdir)/`echo \"rmt\" | sed 's,^.*/,,;$(transform)'`$(EXEEXT)\"" >> $@
|
||||
echo "#endif" >> $@
|
||||
|
||||
rmt.o tar.o : localedir.h
|
||||
tar.o: ../lib/localedir.h
|
||||
|
||||
LDADD = ../lib/libtar.a $(LIBINTL)
|
||||
|
||||
rmt_LDADD = $(LDADD) $(LIB_SETSOCKOPT)
|
||||
tar_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME)
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include "system.h"
|
||||
#include <system.h>
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
#include <quotearg.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "rmt.h"
|
||||
#include <rmt.h>
|
||||
|
||||
/* Number of retries before giving up on read. */
|
||||
#define READ_ERROR_MAX 10
|
||||
|
||||
10
src/common.h
10
src/common.h
@@ -38,11 +38,6 @@
|
||||
/* Some various global definitions. */
|
||||
|
||||
/* Name of file to use for interacting with user. */
|
||||
#if MSDOS
|
||||
# define TTY_NAME "con"
|
||||
#else
|
||||
# define TTY_NAME "/dev/tty"
|
||||
#endif
|
||||
|
||||
/* GLOBAL is defined to empty in tar.c only, and left alone in other *.c
|
||||
modules. Here, we merely set it to "extern" if it is not already set.
|
||||
@@ -163,8 +158,6 @@ GLOBAL struct exclude *excluded;
|
||||
/* Specified file containing names to work on. */
|
||||
GLOBAL const char *files_from_option;
|
||||
|
||||
GLOBAL bool force_local_option;
|
||||
|
||||
/* Specified value to be put into tar file in place of stat () results, or
|
||||
just -1 if such an override should not take place. */
|
||||
GLOBAL gid_t group_option;
|
||||
@@ -678,13 +671,10 @@ bool sys_compare_gid (struct stat *a, struct stat *b);
|
||||
bool sys_file_is_archive (struct tar_stat_info *p);
|
||||
bool sys_compare_links (struct stat *link_data, struct stat *stat_data);
|
||||
int sys_truncate (int fd);
|
||||
void sys_reset_uid_gid (void);
|
||||
pid_t sys_child_open_for_compress (void);
|
||||
pid_t sys_child_open_for_uncompress (void);
|
||||
void sys_reset_uid_gid (void);
|
||||
size_t sys_write_archive_buffer (void);
|
||||
bool sys_get_archive_stat (void);
|
||||
void sys_reset_uid_gid (void);
|
||||
|
||||
/* Module compare.c */
|
||||
void report_difference (struct tar_stat_info *st, const char *message, ...);
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include "system.h"
|
||||
#include <system.h>
|
||||
|
||||
#if HAVE_UTIME_H
|
||||
# include <utime.h>
|
||||
@@ -38,7 +38,7 @@ struct utimbuf
|
||||
#include <quotearg.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "rmt.h"
|
||||
#include <rmt.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
/* Nonzero if we are verifying at the moment. */
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include "system.h"
|
||||
#include <system.h>
|
||||
|
||||
#if HAVE_UTIME_H
|
||||
# include <utime.h>
|
||||
|
||||
@@ -17,10 +17,10 @@
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include "system.h"
|
||||
#include <system.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "rmt.h"
|
||||
#include <rmt.h>
|
||||
|
||||
static union block *new_record;
|
||||
static int new_blocks;
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include "system.h"
|
||||
#include <system.h>
|
||||
#include <quotearg.h>
|
||||
#include <errno.h>
|
||||
#include <xgetcwd.h>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include "system.h"
|
||||
#include <system.h>
|
||||
#include <getline.h>
|
||||
#include <hash.h>
|
||||
#include <quotearg.h>
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
/* Define to non-zero for forcing old ctime format instead of ISO format. */
|
||||
#undef USE_OLD_CTIME
|
||||
|
||||
#include "system.h"
|
||||
#include <system.h>
|
||||
#include <quotearg.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include "system.h"
|
||||
#include <system.h>
|
||||
#include "common.h"
|
||||
#include <quotearg.h>
|
||||
|
||||
|
||||
@@ -17,8 +17,8 @@
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include "system.h"
|
||||
#include "rmt.h"
|
||||
#include <system.h>
|
||||
#include <rmt.h>
|
||||
#include "common.h"
|
||||
#include <quotearg.h>
|
||||
#include <save-cwd.h>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include "system.h"
|
||||
#include <system.h>
|
||||
|
||||
#include <fnmatch.h>
|
||||
#include <hash.h>
|
||||
|
||||
577
src/rmt.c
577
src/rmt.c
@@ -1,577 +0,0 @@
|
||||
/* Remote connection server.
|
||||
|
||||
Copyright (C) 1994, 1995, 1996, 1997, 1999, 2000, 2001, 2003, 2004
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation; either version 2, or (at your option) any later
|
||||
version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* Copyright (C) 1983 Regents of the University of California.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms are permitted provided
|
||||
that the above copyright notice and this paragraph are duplicated in all
|
||||
such forms and that any documentation, advertising materials, and other
|
||||
materials related to such distribution and use acknowledge that the
|
||||
software was developed by the University of California, Berkeley. The
|
||||
name of the University may not be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */
|
||||
|
||||
#include "system.h"
|
||||
#include <localedir.h>
|
||||
#include <safe-read.h>
|
||||
#include <full-write.h>
|
||||
|
||||
#include <getopt.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#ifndef EXIT_FAILURE
|
||||
# define EXIT_FAILURE 1
|
||||
#endif
|
||||
#ifndef EXIT_SUCCESS
|
||||
# define EXIT_SUCCESS 0
|
||||
#endif
|
||||
|
||||
/* Maximum size of a string from the requesting program. */
|
||||
#define STRING_SIZE 64
|
||||
|
||||
/* Name of executing program. */
|
||||
const char *program_name;
|
||||
|
||||
/* File descriptor of the tape device, or negative if none open. */
|
||||
static int tape = -1;
|
||||
|
||||
/* Buffer containing transferred data, and its allocated size. */
|
||||
static char *record_buffer;
|
||||
static size_t allocated_size;
|
||||
|
||||
/* Buffer for constructing the reply. */
|
||||
static char reply_buffer[BUFSIZ];
|
||||
|
||||
/* Debugging tools. */
|
||||
|
||||
static FILE *debug_file;
|
||||
|
||||
#define DEBUG(File) \
|
||||
if (debug_file) fprintf(debug_file, File)
|
||||
|
||||
#define DEBUG1(File, Arg) \
|
||||
if (debug_file) fprintf(debug_file, File, Arg)
|
||||
|
||||
#define DEBUG2(File, Arg1, Arg2) \
|
||||
if (debug_file) fprintf(debug_file, File, Arg1, Arg2)
|
||||
|
||||
/* Return an error string, given an error number. */
|
||||
#if HAVE_STRERROR
|
||||
# ifndef strerror
|
||||
char *strerror ();
|
||||
# endif
|
||||
#else
|
||||
static char *
|
||||
private_strerror (int errnum)
|
||||
{
|
||||
extern char *sys_errlist[];
|
||||
extern int sys_nerr;
|
||||
|
||||
if (errnum > 0 && errnum <= sys_nerr)
|
||||
return _(sys_errlist[errnum]);
|
||||
return _("Unknown system error");
|
||||
}
|
||||
# define strerror private_strerror
|
||||
#endif
|
||||
|
||||
static void
|
||||
report_error_message (const char *string)
|
||||
{
|
||||
DEBUG1 ("rmtd: E 0 (%s)\n", string);
|
||||
|
||||
sprintf (reply_buffer, "E0\n%s\n", string);
|
||||
full_write (STDOUT_FILENO, reply_buffer, strlen (reply_buffer));
|
||||
}
|
||||
|
||||
static void
|
||||
report_numbered_error (int num)
|
||||
{
|
||||
DEBUG2 ("rmtd: E %d (%s)\n", num, strerror (num));
|
||||
|
||||
sprintf (reply_buffer, "E%d\n%s\n", num, strerror (num));
|
||||
full_write (STDOUT_FILENO, reply_buffer, strlen (reply_buffer));
|
||||
}
|
||||
|
||||
static void
|
||||
get_string (char *string)
|
||||
{
|
||||
int counter;
|
||||
|
||||
for (counter = 0; ; counter++)
|
||||
{
|
||||
if (safe_read (STDIN_FILENO, string + counter, 1) != 1)
|
||||
exit (EXIT_SUCCESS);
|
||||
|
||||
if (string[counter] == '\n' || counter == STRING_SIZE - 1)
|
||||
break;
|
||||
}
|
||||
string[counter] = '\0';
|
||||
}
|
||||
|
||||
static void
|
||||
prepare_input_buffer (int fd, size_t size)
|
||||
{
|
||||
if (size <= allocated_size)
|
||||
return;
|
||||
|
||||
if (record_buffer)
|
||||
free (record_buffer);
|
||||
|
||||
record_buffer = malloc (size);
|
||||
|
||||
if (! record_buffer)
|
||||
{
|
||||
DEBUG (_("rmtd: Cannot allocate buffer space\n"));
|
||||
|
||||
report_error_message (N_("Cannot allocate buffer space"));
|
||||
exit (EXIT_FAILURE); /* exit status used to be 4 */
|
||||
}
|
||||
|
||||
allocated_size = size;
|
||||
|
||||
#ifdef SO_RCVBUF
|
||||
if (0 <= fd)
|
||||
{
|
||||
int isize = size < INT_MAX ? size : INT_MAX;
|
||||
while (setsockopt (fd, SOL_SOCKET, SO_RCVBUF,
|
||||
(char *) &isize, sizeof isize)
|
||||
&& 1024 < isize)
|
||||
isize >>= 1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Decode OFLAG_STRING, which represents the 2nd argument to `open'.
|
||||
OFLAG_STRING should contain an optional integer, followed by an optional
|
||||
symbolic representation of an open flag using only '|' to separate its
|
||||
components (e.g. "O_WRONLY|O_CREAT|O_TRUNC"). Prefer the symbolic
|
||||
representation if available, falling back on the numeric
|
||||
representation, or to zero if both formats are absent.
|
||||
|
||||
This function should be the inverse of encode_oflag. The numeric
|
||||
representation is not portable from one host to another, but it is
|
||||
for backward compatibility with old-fashioned clients that do not
|
||||
emit symbolic open flags. */
|
||||
|
||||
static int
|
||||
decode_oflag (char const *oflag_string)
|
||||
{
|
||||
char *oflag_num_end;
|
||||
int numeric_oflag = strtol (oflag_string, &oflag_num_end, 10);
|
||||
int symbolic_oflag = 0;
|
||||
|
||||
oflag_string = oflag_num_end;
|
||||
while (ISSPACE ((unsigned char) *oflag_string))
|
||||
oflag_string++;
|
||||
|
||||
do
|
||||
{
|
||||
struct name_value_pair { char const *name; int value; };
|
||||
static struct name_value_pair const table[] =
|
||||
{
|
||||
#ifdef O_APPEND
|
||||
{"APPEND", O_APPEND},
|
||||
#endif
|
||||
{"CREAT", O_CREAT},
|
||||
#ifdef O_DSYNC
|
||||
{"DSYNC", O_DSYNC},
|
||||
#endif
|
||||
{"EXCL", O_EXCL},
|
||||
#ifdef O_LARGEFILE
|
||||
{"LARGEFILE", O_LARGEFILE}, /* LFS extension for opening large files */
|
||||
#endif
|
||||
#ifdef O_NOCTTY
|
||||
{"NOCTTY", O_NOCTTY},
|
||||
#endif
|
||||
#ifdef O_NONBLOCK
|
||||
{"NONBLOCK", O_NONBLOCK},
|
||||
#endif
|
||||
{"RDONLY", O_RDONLY},
|
||||
{"RDWR", O_RDWR},
|
||||
#ifdef O_RSYNC
|
||||
{"RSYNC", O_RSYNC},
|
||||
#endif
|
||||
#ifdef O_SYNC
|
||||
{"SYNC", O_SYNC},
|
||||
#endif
|
||||
{"TRUNC", O_TRUNC},
|
||||
{"WRONLY", O_WRONLY}
|
||||
};
|
||||
struct name_value_pair const *t;
|
||||
size_t s;
|
||||
|
||||
if (*oflag_string++ != 'O' || *oflag_string++ != '_')
|
||||
return numeric_oflag;
|
||||
|
||||
for (t = table;
|
||||
(strncmp (oflag_string, t->name, s = strlen (t->name)) != 0
|
||||
|| (oflag_string[s]
|
||||
&& strchr ("ABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789",
|
||||
oflag_string[s])));
|
||||
t++)
|
||||
if (t == table + sizeof table / sizeof *table - 1)
|
||||
return numeric_oflag;
|
||||
|
||||
symbolic_oflag |= t->value;
|
||||
oflag_string += s;
|
||||
}
|
||||
while (*oflag_string++ == '|');
|
||||
|
||||
return symbolic_oflag;
|
||||
}
|
||||
|
||||
static struct option const long_opts[] =
|
||||
{
|
||||
{"help", no_argument, 0, 'h'},
|
||||
{"version", no_argument, 0, 'v'},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
static void usage (int) __attribute__ ((noreturn));
|
||||
|
||||
static void
|
||||
usage (int status)
|
||||
{
|
||||
if (status != EXIT_SUCCESS)
|
||||
fprintf (stderr, _("Try `%s --help' for more information.\n"),
|
||||
program_name);
|
||||
else
|
||||
{
|
||||
printf (_("\
|
||||
Usage: %s [OPTION]\n\
|
||||
Manipulate a tape drive, accepting commands from a remote process.\n\
|
||||
\n\
|
||||
--version Output version info.\n\
|
||||
--help Output this help.\n"),
|
||||
program_name);
|
||||
printf (_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
|
||||
}
|
||||
|
||||
exit (status);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *const *argv)
|
||||
{
|
||||
char command;
|
||||
size_t status;
|
||||
|
||||
/* FIXME: Localization is meaningless, unless --help and --version are
|
||||
locally used. Localization would be best accomplished by the calling
|
||||
tar, on messages found within error packets. */
|
||||
|
||||
program_name = argv[0];
|
||||
setlocale (LC_ALL, "");
|
||||
bindtextdomain (PACKAGE, LOCALEDIR);
|
||||
textdomain (PACKAGE);
|
||||
|
||||
switch (getopt_long (argc, argv, "", long_opts, NULL))
|
||||
{
|
||||
default:
|
||||
usage (EXIT_FAILURE);
|
||||
|
||||
case 'h':
|
||||
usage (EXIT_SUCCESS);
|
||||
|
||||
case 'v':
|
||||
{
|
||||
printf ("rmt (%s) %s\n%s\n", PACKAGE_NAME, PACKAGE_VERSION,
|
||||
"Copyright (C) 2004 Free Software Foundation, Inc.");
|
||||
puts (_("\
|
||||
This program comes with NO WARRANTY, to the extent permitted by law.\n\
|
||||
You may redistribute it under the terms of the GNU General Public License;\n\
|
||||
see the file named COPYING for details."));
|
||||
}
|
||||
return EXIT_SUCCESS;
|
||||
|
||||
case -1:
|
||||
break;
|
||||
}
|
||||
|
||||
if (optind < argc)
|
||||
{
|
||||
if (optind != argc - 1)
|
||||
usage (EXIT_FAILURE);
|
||||
debug_file = fopen (argv[optind], "w");
|
||||
if (debug_file == 0)
|
||||
{
|
||||
report_numbered_error (errno);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
setbuf (debug_file, 0);
|
||||
}
|
||||
|
||||
top:
|
||||
errno = 0;
|
||||
status = 0;
|
||||
if (safe_read (STDIN_FILENO, &command, 1) != 1)
|
||||
return EXIT_SUCCESS;
|
||||
|
||||
switch (command)
|
||||
{
|
||||
/* FIXME: Maybe 'H' and 'V' for --help and --version output? */
|
||||
|
||||
case 'O':
|
||||
{
|
||||
char device_string[STRING_SIZE];
|
||||
char oflag_string[STRING_SIZE];
|
||||
|
||||
get_string (device_string);
|
||||
get_string (oflag_string);
|
||||
DEBUG2 ("rmtd: O %s %s\n", device_string, oflag_string);
|
||||
|
||||
if (tape >= 0)
|
||||
close (tape);
|
||||
|
||||
tape = open (device_string, decode_oflag (oflag_string), MODE_RW);
|
||||
if (tape < 0)
|
||||
goto ioerror;
|
||||
goto respond;
|
||||
}
|
||||
|
||||
case 'C':
|
||||
{
|
||||
char device_string[STRING_SIZE];
|
||||
|
||||
get_string (device_string); /* discard */
|
||||
DEBUG ("rmtd: C\n");
|
||||
|
||||
if (close (tape) < 0)
|
||||
goto ioerror;
|
||||
tape = -1;
|
||||
goto respond;
|
||||
}
|
||||
|
||||
case 'L':
|
||||
{
|
||||
char count_string[STRING_SIZE];
|
||||
char position_string[STRING_SIZE];
|
||||
off_t count = 0;
|
||||
int negative;
|
||||
int whence;
|
||||
char *p;
|
||||
|
||||
get_string (count_string);
|
||||
get_string (position_string);
|
||||
DEBUG2 ("rmtd: L %s %s\n", count_string, position_string);
|
||||
|
||||
/* Parse count_string, taking care to check for overflow.
|
||||
We can't use standard functions,
|
||||
since off_t might be longer than long. */
|
||||
|
||||
for (p = count_string; *p == ' ' || *p == '\t'; p++)
|
||||
continue;
|
||||
|
||||
negative = *p == '-';
|
||||
p += negative || *p == '+';
|
||||
|
||||
for (;;)
|
||||
{
|
||||
int digit = *p++ - '0';
|
||||
if (9 < (unsigned) digit)
|
||||
break;
|
||||
else
|
||||
{
|
||||
off_t c10 = 10 * count;
|
||||
off_t nc = negative ? c10 - digit : c10 + digit;
|
||||
if (c10 / 10 != count || (negative ? c10 < nc : nc < c10))
|
||||
{
|
||||
report_error_message (N_("Seek offset out of range"));
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
count = nc;
|
||||
}
|
||||
}
|
||||
|
||||
switch (atoi (position_string))
|
||||
{
|
||||
case 0: whence = SEEK_SET; break;
|
||||
case 1: whence = SEEK_CUR; break;
|
||||
case 2: whence = SEEK_END; break;
|
||||
default:
|
||||
report_error_message (N_("Seek direction out of range"));
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
count = lseek (tape, count, whence);
|
||||
if (count < 0)
|
||||
goto ioerror;
|
||||
|
||||
/* Convert count back to string for reply.
|
||||
We can't use sprintf, since off_t might be longer than long. */
|
||||
p = count_string + sizeof count_string;
|
||||
*--p = '\0';
|
||||
do
|
||||
*--p = '0' + (int) (count % 10);
|
||||
while ((count /= 10) != 0);
|
||||
|
||||
DEBUG1 ("rmtd: A %s\n", p);
|
||||
|
||||
sprintf (reply_buffer, "A%s\n", p);
|
||||
full_write (STDOUT_FILENO, reply_buffer, strlen (reply_buffer));
|
||||
goto top;
|
||||
}
|
||||
|
||||
case 'W':
|
||||
{
|
||||
char count_string[STRING_SIZE];
|
||||
size_t size;
|
||||
size_t counter;
|
||||
|
||||
get_string (count_string);
|
||||
size = atol (count_string);
|
||||
DEBUG1 ("rmtd: W %s\n", count_string);
|
||||
|
||||
prepare_input_buffer (STDIN_FILENO, size);
|
||||
for (counter = 0; counter < size; counter += status)
|
||||
{
|
||||
status = safe_read (STDIN_FILENO, &record_buffer[counter],
|
||||
size - counter);
|
||||
if (status == SAFE_READ_ERROR || status == 0)
|
||||
{
|
||||
DEBUG (_("rmtd: Premature eof\n"));
|
||||
|
||||
report_error_message (N_("Premature end of file"));
|
||||
return EXIT_FAILURE; /* exit status used to be 2 */
|
||||
}
|
||||
}
|
||||
status = full_write (tape, record_buffer, size);
|
||||
if (status != size)
|
||||
goto ioerror;
|
||||
goto respond;
|
||||
}
|
||||
|
||||
case 'R':
|
||||
{
|
||||
char count_string[STRING_SIZE];
|
||||
size_t size;
|
||||
|
||||
get_string (count_string);
|
||||
DEBUG1 ("rmtd: R %s\n", count_string);
|
||||
|
||||
size = atol (count_string);
|
||||
prepare_input_buffer (-1, size);
|
||||
status = safe_read (tape, record_buffer, size);
|
||||
if (status == SAFE_READ_ERROR)
|
||||
goto ioerror;
|
||||
sprintf (reply_buffer, "A%lu\n", (unsigned long int) status);
|
||||
full_write (STDOUT_FILENO, reply_buffer, strlen (reply_buffer));
|
||||
full_write (STDOUT_FILENO, record_buffer, status);
|
||||
goto top;
|
||||
}
|
||||
|
||||
case 'I':
|
||||
{
|
||||
char operation_string[STRING_SIZE];
|
||||
char count_string[STRING_SIZE];
|
||||
|
||||
get_string (operation_string);
|
||||
get_string (count_string);
|
||||
DEBUG2 ("rmtd: I %s %s\n", operation_string, count_string);
|
||||
|
||||
#ifdef MTIOCTOP
|
||||
{
|
||||
struct mtop mtop;
|
||||
const char *p;
|
||||
off_t count = 0;
|
||||
int negative;
|
||||
|
||||
/* Parse count_string, taking care to check for overflow.
|
||||
We can't use standard functions,
|
||||
since off_t might be longer than long. */
|
||||
|
||||
for (p = count_string; *p == ' ' || *p == '\t'; p++)
|
||||
continue;
|
||||
|
||||
negative = *p == '-';
|
||||
p += negative || *p == '+';
|
||||
|
||||
for (;;)
|
||||
{
|
||||
int digit = *p++ - '0';
|
||||
if (9 < (unsigned) digit)
|
||||
break;
|
||||
else
|
||||
{
|
||||
off_t c10 = 10 * count;
|
||||
off_t nc = negative ? c10 - digit : c10 + digit;
|
||||
if (c10 / 10 != count || (negative ? c10 < nc : nc < c10))
|
||||
{
|
||||
report_error_message (N_("Seek offset out of range"));
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
count = nc;
|
||||
}
|
||||
}
|
||||
|
||||
mtop.mt_count = count;
|
||||
if (mtop.mt_count != count)
|
||||
{
|
||||
report_error_message (N_("Seek offset out of range"));
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
mtop.mt_op = atoi (operation_string);
|
||||
|
||||
if (ioctl (tape, MTIOCTOP, (char *) &mtop) < 0)
|
||||
goto ioerror;
|
||||
}
|
||||
#endif
|
||||
goto respond;
|
||||
}
|
||||
|
||||
case 'S': /* status */
|
||||
{
|
||||
DEBUG ("rmtd: S\n");
|
||||
|
||||
#ifdef MTIOCGET
|
||||
{
|
||||
struct mtget operation;
|
||||
|
||||
if (ioctl (tape, MTIOCGET, (char *) &operation) < 0)
|
||||
goto ioerror;
|
||||
status = sizeof operation;
|
||||
sprintf (reply_buffer, "A%ld\n", (long) status);
|
||||
full_write (STDOUT_FILENO, reply_buffer, strlen (reply_buffer));
|
||||
full_write (STDOUT_FILENO, (char *) &operation, sizeof operation);
|
||||
}
|
||||
#endif
|
||||
goto top;
|
||||
}
|
||||
|
||||
default:
|
||||
DEBUG1 (_("rmtd: Garbage command %c\n"), command);
|
||||
|
||||
report_error_message (N_("Garbage command"));
|
||||
return EXIT_FAILURE; /* exit status used to be 3 */
|
||||
}
|
||||
|
||||
respond:
|
||||
DEBUG1 ("rmtd: A %ld\n", (long) status);
|
||||
|
||||
sprintf (reply_buffer, "A%ld\n", (long) status);
|
||||
full_write (STDOUT_FILENO, reply_buffer, strlen (reply_buffer));
|
||||
goto top;
|
||||
|
||||
ioerror:
|
||||
report_numbered_error (errno);
|
||||
goto top;
|
||||
}
|
||||
96
src/rmt.h
96
src/rmt.h
@@ -1,96 +0,0 @@
|
||||
/* Definitions for communicating with a remote tape drive.
|
||||
|
||||
Copyright (C) 1988, 1992, 1996, 1997, 2001, 2003, 2004 Free
|
||||
Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
extern char *rmt_dev_name__;
|
||||
|
||||
int rmt_open__ (const char *, int, int, const char *);
|
||||
int rmt_close__ (int);
|
||||
size_t rmt_read__ (int, char *, size_t);
|
||||
size_t rmt_write__ (int, char *, size_t);
|
||||
off_t rmt_lseek__ (int, off_t, int);
|
||||
int rmt_ioctl__ (int, int, char *);
|
||||
|
||||
/* A filename is remote if it contains a colon not preceded by a slash,
|
||||
to take care of `/:/' which is a shorthand for `/.../<CELL-NAME>/fs'
|
||||
on machines running OSF's Distributing Computing Environment (DCE) and
|
||||
Distributed File System (DFS). However, when --force-local, a
|
||||
filename is never remote. */
|
||||
|
||||
#define _remdev(dev_name) \
|
||||
(!force_local_option && (rmt_dev_name__ = strchr (dev_name, ':')) \
|
||||
&& rmt_dev_name__ > (dev_name) \
|
||||
&& ! memchr (dev_name, '/', rmt_dev_name__ - (dev_name)))
|
||||
|
||||
#define _isrmt(fd) \
|
||||
((fd) >= __REM_BIAS)
|
||||
|
||||
#define __REM_BIAS (1 << 30)
|
||||
|
||||
#ifndef O_CREAT
|
||||
# define O_CREAT 01000
|
||||
#endif
|
||||
|
||||
#define rmtopen(dev_name, oflag, mode, command) \
|
||||
(_remdev (dev_name) ? rmt_open__ (dev_name, oflag, __REM_BIAS, command) \
|
||||
: open (dev_name, oflag, mode))
|
||||
|
||||
#define rmtaccess(dev_name, amode) \
|
||||
(_remdev (dev_name) ? 0 : access (dev_name, amode))
|
||||
|
||||
#define rmtstat(dev_name, buffer) \
|
||||
(_remdev (dev_name) ? (errno = EOPNOTSUPP), -1 : stat (dev_name, buffer))
|
||||
|
||||
#define rmtcreat(dev_name, mode, command) \
|
||||
(_remdev (dev_name) \
|
||||
? rmt_open__ (dev_name, 1 | O_CREAT, __REM_BIAS, command) \
|
||||
: creat (dev_name, mode))
|
||||
|
||||
#define rmtlstat(dev_name, muffer) \
|
||||
(_remdev (dev_name) ? (errno = EOPNOTSUPP), -1 : lstat (dev_name, buffer))
|
||||
|
||||
#define rmtread(fd, buffer, length) \
|
||||
(_isrmt (fd) ? rmt_read__ (fd - __REM_BIAS, buffer, length) \
|
||||
: safe_read (fd, buffer, length))
|
||||
|
||||
#define rmtwrite(fd, buffer, length) \
|
||||
(_isrmt (fd) ? rmt_write__ (fd - __REM_BIAS, buffer, length) \
|
||||
: full_write (fd, buffer, length))
|
||||
|
||||
#define rmtlseek(fd, offset, where) \
|
||||
(_isrmt (fd) ? rmt_lseek__ (fd - __REM_BIAS, offset, where) \
|
||||
: lseek (fd, offset, where))
|
||||
|
||||
#define rmtclose(fd) \
|
||||
(_isrmt (fd) ? rmt_close__ (fd - __REM_BIAS) : close (fd))
|
||||
|
||||
#define rmtioctl(fd, request, argument) \
|
||||
(_isrmt (fd) ? rmt_ioctl__ (fd - __REM_BIAS, request, argument) \
|
||||
: ioctl (fd, request, argument))
|
||||
|
||||
#define rmtdup(fd) \
|
||||
(_isrmt (fd) ? (errno = EOPNOTSUPP), -1 : dup (fd))
|
||||
|
||||
#define rmtfstat(fd, buffer) \
|
||||
(_isrmt (fd) ? (errno = EOPNOTSUPP), -1 : fstat (fd, buffer))
|
||||
|
||||
#define rmtfcntl(cd, command, argument) \
|
||||
(_isrmt (fd) ? (errno = EOPNOTSUPP), -1 : fcntl (fd, command, argument))
|
||||
|
||||
#define rmtisatty(fd) \
|
||||
(_isrmt (fd) ? 0 : isatty (fd))
|
||||
735
src/rtapelib.c
735
src/rtapelib.c
@@ -1,735 +0,0 @@
|
||||
/* Functions for communicating with a remote tape drive.
|
||||
|
||||
Copyright 1988, 1992, 1994, 1996, 1997, 1999, 2000, 2001, 2004 Free
|
||||
Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* The man page rmt(8) for /etc/rmt documents the remote mag tape protocol
|
||||
which rdump and rrestore use. Unfortunately, the man page is *WRONG*.
|
||||
The author of the routines I'm including originally wrote his code just
|
||||
based on the man page, and it didn't work, so he went to the rdump source
|
||||
to figure out why. The only thing he had to change was to check for the
|
||||
'F' return code in addition to the 'E', and to separate the various
|
||||
arguments with \n instead of a space. I personally don't think that this
|
||||
is much of a problem, but I wanted to point it out. -- Arnold Robbins
|
||||
|
||||
Originally written by Jeff Lee, modified some by Arnold Robbins. Redone
|
||||
as a library that can replace open, read, write, etc., by Fred Fish, with
|
||||
some additional work by Arnold Robbins. Modified to make all rmt* calls
|
||||
into macros for speed by Jay Fenlason. Use -DWITH_REXEC for rexec
|
||||
code, courtesy of Dan Kegel. */
|
||||
|
||||
#include "system.h"
|
||||
#include "common.h"
|
||||
#include <safe-read.h>
|
||||
#include <full-write.h>
|
||||
|
||||
/* Try hard to get EOPNOTSUPP defined. 486/ISC has it in net/errno.h,
|
||||
3B2/SVR3 has it in sys/inet.h. Otherwise, like on MSDOS, use EINVAL. */
|
||||
|
||||
#ifndef EOPNOTSUPP
|
||||
# if HAVE_NET_ERRNO_H
|
||||
# include <net/errno.h>
|
||||
# endif
|
||||
# if HAVE_SYS_INET_H
|
||||
# include <sys/inet.h>
|
||||
# endif
|
||||
# ifndef EOPNOTSUPP
|
||||
# define EOPNOTSUPP EINVAL
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
#if HAVE_NETDB_H
|
||||
# include <netdb.h>
|
||||
#endif
|
||||
|
||||
#include "rmt.h"
|
||||
|
||||
/* Exit status if exec errors. */
|
||||
#define EXIT_ON_EXEC_ERROR 128
|
||||
|
||||
/* FIXME: Size of buffers for reading and writing commands to rmt. */
|
||||
#define COMMAND_BUFFER_SIZE 64
|
||||
|
||||
#ifndef RETSIGTYPE
|
||||
# define RETSIGTYPE void
|
||||
#endif
|
||||
|
||||
/* FIXME: Maximum number of simultaneous remote tape connections. */
|
||||
#define MAXUNIT 4
|
||||
|
||||
#define PREAD 0 /* read file descriptor from pipe() */
|
||||
#define PWRITE 1 /* write file descriptor from pipe() */
|
||||
|
||||
/* Return the parent's read side of remote tape connection Fd. */
|
||||
#define READ_SIDE(Fd) (from_remote[Fd][PREAD])
|
||||
|
||||
/* Return the parent's write side of remote tape connection Fd. */
|
||||
#define WRITE_SIDE(Fd) (to_remote[Fd][PWRITE])
|
||||
|
||||
/* The pipes for receiving data from remote tape drives. */
|
||||
static int from_remote[MAXUNIT][2] = {{-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}};
|
||||
|
||||
/* The pipes for sending data to remote tape drives. */
|
||||
static int to_remote[MAXUNIT][2] = {{-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}};
|
||||
|
||||
#define RMT_COMMAND (rmt_command_option ? rmt_command_option : "/etc/rmt")
|
||||
|
||||
/* Temporary variable used by macros in rmt.h. */
|
||||
char *rmt_dev_name__;
|
||||
|
||||
|
||||
/* Close remote tape connection HANDLE, and reset errno to ERRNO_VALUE. */
|
||||
static void
|
||||
_rmt_shutdown (int handle, int errno_value)
|
||||
{
|
||||
close (READ_SIDE (handle));
|
||||
close (WRITE_SIDE (handle));
|
||||
READ_SIDE (handle) = -1;
|
||||
WRITE_SIDE (handle) = -1;
|
||||
errno = errno_value;
|
||||
}
|
||||
|
||||
/* Attempt to perform the remote tape command specified in BUFFER on
|
||||
remote tape connection HANDLE. Return 0 if successful, -1 on
|
||||
error. */
|
||||
static int
|
||||
do_command (int handle, const char *buffer)
|
||||
{
|
||||
/* Save the current pipe handler and try to make the request. */
|
||||
|
||||
size_t length = strlen (buffer);
|
||||
RETSIGTYPE (*pipe_handler) () = signal (SIGPIPE, SIG_IGN);
|
||||
ssize_t written = full_write (WRITE_SIDE (handle), buffer, length);
|
||||
signal (SIGPIPE, pipe_handler);
|
||||
|
||||
if (written == length)
|
||||
return 0;
|
||||
|
||||
/* Something went wrong. Close down and go home. */
|
||||
|
||||
_rmt_shutdown (handle, EIO);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static char *
|
||||
get_status_string (int handle, char *command_buffer)
|
||||
{
|
||||
char *cursor;
|
||||
int counter;
|
||||
|
||||
/* Read the reply command line. */
|
||||
|
||||
for (counter = 0, cursor = command_buffer;
|
||||
counter < COMMAND_BUFFER_SIZE;
|
||||
counter++, cursor++)
|
||||
{
|
||||
if (safe_read (READ_SIDE (handle), cursor, 1) != 1)
|
||||
{
|
||||
_rmt_shutdown (handle, EIO);
|
||||
return 0;
|
||||
}
|
||||
if (*cursor == '\n')
|
||||
{
|
||||
*cursor = '\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (counter == COMMAND_BUFFER_SIZE)
|
||||
{
|
||||
_rmt_shutdown (handle, EIO);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Check the return status. */
|
||||
|
||||
for (cursor = command_buffer; *cursor; cursor++)
|
||||
if (*cursor != ' ')
|
||||
break;
|
||||
|
||||
if (*cursor == 'E' || *cursor == 'F')
|
||||
{
|
||||
/* Skip the error message line. */
|
||||
|
||||
/* FIXME: there is better to do than merely ignoring error messages
|
||||
coming from the remote end. Translate them, too... */
|
||||
|
||||
{
|
||||
char character;
|
||||
|
||||
while (safe_read (READ_SIDE (handle), &character, 1) == 1)
|
||||
if (character == '\n')
|
||||
break;
|
||||
}
|
||||
|
||||
errno = atoi (cursor + 1);
|
||||
|
||||
if (*cursor == 'F')
|
||||
_rmt_shutdown (handle, errno);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Check for mis-synced pipes. */
|
||||
|
||||
if (*cursor != 'A')
|
||||
{
|
||||
_rmt_shutdown (handle, EIO);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Got an `A' (success) response. */
|
||||
|
||||
return cursor + 1;
|
||||
}
|
||||
|
||||
/* Read and return the status from remote tape connection HANDLE. If
|
||||
an error occurred, return -1 and set errno. */
|
||||
static long int
|
||||
get_status (int handle)
|
||||
{
|
||||
char command_buffer[COMMAND_BUFFER_SIZE];
|
||||
const char *status = get_status_string (handle, command_buffer);
|
||||
if (status)
|
||||
{
|
||||
long int result = atol (status);
|
||||
if (0 <= result)
|
||||
return result;
|
||||
errno = EIO;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static off_t
|
||||
get_status_off (int handle)
|
||||
{
|
||||
char command_buffer[COMMAND_BUFFER_SIZE];
|
||||
const char *status = get_status_string (handle, command_buffer);
|
||||
|
||||
if (! status)
|
||||
return -1;
|
||||
else
|
||||
{
|
||||
/* Parse status, taking care to check for overflow.
|
||||
We can't use standard functions,
|
||||
since off_t might be longer than long. */
|
||||
|
||||
off_t count = 0;
|
||||
int negative;
|
||||
|
||||
for (; *status == ' ' || *status == '\t'; status++)
|
||||
continue;
|
||||
|
||||
negative = *status == '-';
|
||||
status += negative || *status == '+';
|
||||
|
||||
for (;;)
|
||||
{
|
||||
int digit = *status++ - '0';
|
||||
if (9 < (unsigned) digit)
|
||||
break;
|
||||
else
|
||||
{
|
||||
off_t c10 = 10 * count;
|
||||
off_t nc = negative ? c10 - digit : c10 + digit;
|
||||
if (c10 / 10 != count || (negative ? c10 < nc : nc < c10))
|
||||
return -1;
|
||||
count = nc;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
}
|
||||
|
||||
#if WITH_REXEC
|
||||
|
||||
/* Execute /etc/rmt as user USER on remote system HOST using rexec.
|
||||
Return a file descriptor of a bidirectional socket for stdin and
|
||||
stdout. If USER is zero, use the current username.
|
||||
|
||||
By default, this code is not used, since it requires that the user
|
||||
have a .netrc file in his/her home directory, or that the
|
||||
application designer be willing to have rexec prompt for login and
|
||||
password info. This may be unacceptable, and .rhosts files for use
|
||||
with rsh are much more common on BSD systems. */
|
||||
static int
|
||||
_rmt_rexec (char *host, char *user)
|
||||
{
|
||||
int saved_stdin = dup (STDIN_FILENO);
|
||||
int saved_stdout = dup (STDOUT_FILENO);
|
||||
struct servent *rexecserv;
|
||||
int result;
|
||||
|
||||
/* When using cpio -o < filename, stdin is no longer the tty. But the
|
||||
rexec subroutine reads the login and the passwd on stdin, to allow
|
||||
remote execution of the command. So, reopen stdin and stdout on
|
||||
/dev/tty before the rexec and give them back their original value
|
||||
after. */
|
||||
|
||||
if (! freopen ("/dev/tty", "r", stdin))
|
||||
freopen ("/dev/null", "r", stdin);
|
||||
if (! freopen ("/dev/tty", "w", stdout))
|
||||
freopen ("/dev/null", "w", stdout);
|
||||
|
||||
if (rexecserv = getservbyname ("exec", "tcp"), !rexecserv)
|
||||
error (EXIT_ON_EXEC_ERROR, 0, _("exec/tcp: Service not available"));
|
||||
|
||||
result = rexec (&host, rexecserv->s_port, user, 0, RMT_COMMAND, 0);
|
||||
if (fclose (stdin) == EOF)
|
||||
error (0, errno, _("stdin"));
|
||||
fdopen (saved_stdin, "r");
|
||||
if (fclose (stdout) == EOF)
|
||||
error (0, errno, _("stdout"));
|
||||
fdopen (saved_stdout, "w");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif /* WITH_REXEC */
|
||||
|
||||
/* Place into BUF a string representing OFLAG, which must be suitable
|
||||
as argument 2 of `open'. BUF must be large enough to hold the
|
||||
result. This function should generate a string that decode_oflag
|
||||
can parse. */
|
||||
static void
|
||||
encode_oflag (char *buf, int oflag)
|
||||
{
|
||||
sprintf (buf, "%d ", oflag);
|
||||
|
||||
switch (oflag & O_ACCMODE)
|
||||
{
|
||||
case O_RDONLY: strcat (buf, "O_RDONLY"); break;
|
||||
case O_RDWR: strcat (buf, "O_RDWR"); break;
|
||||
case O_WRONLY: strcat (buf, "O_WRONLY"); break;
|
||||
default: abort ();
|
||||
}
|
||||
|
||||
#ifdef O_APPEND
|
||||
if (oflag & O_APPEND) strcat (buf, "|O_APPEND");
|
||||
#endif
|
||||
if (oflag & O_CREAT) strcat (buf, "|O_CREAT");
|
||||
#ifdef O_DSYNC
|
||||
if (oflag & O_DSYNC) strcat (buf, "|O_DSYNC");
|
||||
#endif
|
||||
if (oflag & O_EXCL) strcat (buf, "|O_EXCL");
|
||||
#ifdef O_LARGEFILE
|
||||
if (oflag & O_LARGEFILE) strcat (buf, "|O_LARGEFILE");
|
||||
#endif
|
||||
#ifdef O_NOCTTY
|
||||
if (oflag & O_NOCTTY) strcat (buf, "|O_NOCTTY");
|
||||
#endif
|
||||
#ifdef O_NONBLOCK
|
||||
if (oflag & O_NONBLOCK) strcat (buf, "|O_NONBLOCK");
|
||||
#endif
|
||||
#ifdef O_RSYNC
|
||||
if (oflag & O_RSYNC) strcat (buf, "|O_RSYNC");
|
||||
#endif
|
||||
#ifdef O_SYNC
|
||||
if (oflag & O_SYNC) strcat (buf, "|O_SYNC");
|
||||
#endif
|
||||
if (oflag & O_TRUNC) strcat (buf, "|O_TRUNC");
|
||||
}
|
||||
|
||||
/* Open a file (a magnetic tape device?) on the system specified in
|
||||
FILE_NAME, as the given user. FILE_NAME has the form `[USER@]HOST:FILE'.
|
||||
OPEN_MODE is O_RDONLY, O_WRONLY, etc. If successful, return the
|
||||
remote pipe number plus BIAS. REMOTE_SHELL may be overridden. On
|
||||
error, return -1. */
|
||||
int
|
||||
rmt_open__ (const char *file_name, int open_mode, int bias,
|
||||
const char *remote_shell)
|
||||
{
|
||||
int remote_pipe_number; /* pseudo, biased file descriptor */
|
||||
char *file_name_copy; /* copy of file_name string */
|
||||
char *remote_host; /* remote host name */
|
||||
char *remote_file; /* remote file name (often a device) */
|
||||
char *remote_user; /* remote user name */
|
||||
|
||||
/* Find an unused pair of file descriptors. */
|
||||
|
||||
for (remote_pipe_number = 0;
|
||||
remote_pipe_number < MAXUNIT;
|
||||
remote_pipe_number++)
|
||||
if (READ_SIDE (remote_pipe_number) == -1
|
||||
&& WRITE_SIDE (remote_pipe_number) == -1)
|
||||
break;
|
||||
|
||||
if (remote_pipe_number == MAXUNIT)
|
||||
{
|
||||
errno = EMFILE;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Pull apart the system and device, and optional user. */
|
||||
|
||||
{
|
||||
char *cursor;
|
||||
|
||||
file_name_copy = xstrdup (file_name);
|
||||
remote_host = file_name_copy;
|
||||
remote_user = 0;
|
||||
remote_file = 0;
|
||||
|
||||
for (cursor = file_name_copy; *cursor; cursor++)
|
||||
switch (*cursor)
|
||||
{
|
||||
default:
|
||||
break;
|
||||
|
||||
case '\n':
|
||||
/* Do not allow newlines in the file_name, since the protocol
|
||||
uses newline delimiters. */
|
||||
free (file_name_copy);
|
||||
errno = ENOENT;
|
||||
return -1;
|
||||
|
||||
case '@':
|
||||
if (!remote_user)
|
||||
{
|
||||
remote_user = remote_host;
|
||||
*cursor = '\0';
|
||||
remote_host = cursor + 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case ':':
|
||||
if (!remote_file)
|
||||
{
|
||||
*cursor = '\0';
|
||||
remote_file = cursor + 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* FIXME: Should somewhat validate the decoding, here. */
|
||||
|
||||
if (remote_user && *remote_user == '\0')
|
||||
remote_user = 0;
|
||||
|
||||
#if WITH_REXEC
|
||||
|
||||
/* Execute the remote command using rexec. */
|
||||
|
||||
READ_SIDE (remote_pipe_number) = _rmt_rexec (remote_host, remote_user);
|
||||
if (READ_SIDE (remote_pipe_number) < 0)
|
||||
{
|
||||
int e = errno;
|
||||
free (file_name_copy);
|
||||
errno = e;
|
||||
return -1;
|
||||
}
|
||||
|
||||
WRITE_SIDE (remote_pipe_number) = READ_SIDE (remote_pipe_number);
|
||||
|
||||
#else /* not WITH_REXEC */
|
||||
{
|
||||
const char *remote_shell_basename;
|
||||
pid_t status;
|
||||
|
||||
/* Identify the remote command to be executed. */
|
||||
|
||||
if (!remote_shell)
|
||||
{
|
||||
#ifdef REMOTE_SHELL
|
||||
remote_shell = REMOTE_SHELL;
|
||||
#else
|
||||
free (file_name_copy);
|
||||
errno = EIO;
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
remote_shell_basename = base_name (remote_shell);
|
||||
|
||||
/* Set up the pipes for the `rsh' command, and fork. */
|
||||
|
||||
if (pipe (to_remote[remote_pipe_number]) == -1
|
||||
|| pipe (from_remote[remote_pipe_number]) == -1)
|
||||
{
|
||||
int e = errno;
|
||||
free (file_name_copy);
|
||||
errno = e;
|
||||
return -1;
|
||||
}
|
||||
|
||||
status = fork ();
|
||||
if (status == -1)
|
||||
{
|
||||
int e = errno;
|
||||
free (file_name_copy);
|
||||
errno = e;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (status == 0)
|
||||
{
|
||||
/* Child. */
|
||||
|
||||
close (STDIN_FILENO);
|
||||
dup (to_remote[remote_pipe_number][PREAD]);
|
||||
close (to_remote[remote_pipe_number][PREAD]);
|
||||
close (to_remote[remote_pipe_number][PWRITE]);
|
||||
|
||||
close (STDOUT_FILENO);
|
||||
dup (from_remote[remote_pipe_number][PWRITE]);
|
||||
close (from_remote[remote_pipe_number][PREAD]);
|
||||
close (from_remote[remote_pipe_number][PWRITE]);
|
||||
|
||||
sys_reset_uid_gid ();
|
||||
|
||||
if (remote_user)
|
||||
execl (remote_shell, remote_shell_basename, remote_host,
|
||||
"-l", remote_user, RMT_COMMAND, (char *) 0);
|
||||
else
|
||||
execl (remote_shell, remote_shell_basename, remote_host,
|
||||
RMT_COMMAND, (char *) 0);
|
||||
|
||||
/* Bad problems if we get here. */
|
||||
|
||||
/* In a previous version, _exit was used here instead of exit. */
|
||||
error (EXIT_ON_EXEC_ERROR, errno, _("Cannot execute remote shell"));
|
||||
}
|
||||
|
||||
/* Parent. */
|
||||
|
||||
close (from_remote[remote_pipe_number][PWRITE]);
|
||||
close (to_remote[remote_pipe_number][PREAD]);
|
||||
}
|
||||
#endif /* not WITH_REXEC */
|
||||
|
||||
/* Attempt to open the tape device. */
|
||||
|
||||
{
|
||||
size_t remote_file_len = strlen (remote_file);
|
||||
char *command_buffer = xmalloc (remote_file_len + 1000);
|
||||
sprintf (command_buffer, "O%s\n", remote_file);
|
||||
encode_oflag (command_buffer + remote_file_len + 2, open_mode);
|
||||
strcat (command_buffer, "\n");
|
||||
if (do_command (remote_pipe_number, command_buffer) == -1
|
||||
|| get_status (remote_pipe_number) == -1)
|
||||
{
|
||||
int e = errno;
|
||||
free (command_buffer);
|
||||
free (file_name_copy);
|
||||
_rmt_shutdown (remote_pipe_number, e);
|
||||
return -1;
|
||||
}
|
||||
free (command_buffer);
|
||||
}
|
||||
|
||||
free (file_name_copy);
|
||||
return remote_pipe_number + bias;
|
||||
}
|
||||
|
||||
/* Close remote tape connection HANDLE and shut down. Return 0 if
|
||||
successful, -1 on error. */
|
||||
int
|
||||
rmt_close__ (int handle)
|
||||
{
|
||||
long int status;
|
||||
|
||||
if (do_command (handle, "C\n") == -1)
|
||||
return -1;
|
||||
|
||||
status = get_status (handle);
|
||||
_rmt_shutdown (handle, errno);
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Read up to LENGTH bytes into BUFFER from remote tape connection HANDLE.
|
||||
Return the number of bytes read on success, SAFE_READ_ERROR on error. */
|
||||
size_t
|
||||
rmt_read__ (int handle, char *buffer, size_t length)
|
||||
{
|
||||
char command_buffer[COMMAND_BUFFER_SIZE];
|
||||
size_t status;
|
||||
size_t rlen;
|
||||
size_t counter;
|
||||
|
||||
sprintf (command_buffer, "R%lu\n", (unsigned long) length);
|
||||
if (do_command (handle, command_buffer) == -1
|
||||
|| (status = get_status (handle)) == SAFE_READ_ERROR)
|
||||
return SAFE_READ_ERROR;
|
||||
|
||||
for (counter = 0; counter < status; counter += rlen, buffer += rlen)
|
||||
{
|
||||
rlen = safe_read (READ_SIDE (handle), buffer, status - counter);
|
||||
if (rlen == SAFE_READ_ERROR || rlen == 0)
|
||||
{
|
||||
_rmt_shutdown (handle, EIO);
|
||||
return SAFE_READ_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Write LENGTH bytes from BUFFER to remote tape connection HANDLE.
|
||||
Return the number of bytes written. */
|
||||
size_t
|
||||
rmt_write__ (int handle, char *buffer, size_t length)
|
||||
{
|
||||
char command_buffer[COMMAND_BUFFER_SIZE];
|
||||
RETSIGTYPE (*pipe_handler) ();
|
||||
size_t written;
|
||||
|
||||
sprintf (command_buffer, "W%lu\n", (unsigned long) length);
|
||||
if (do_command (handle, command_buffer) == -1)
|
||||
return 0;
|
||||
|
||||
pipe_handler = signal (SIGPIPE, SIG_IGN);
|
||||
written = full_write (WRITE_SIDE (handle), buffer, length);
|
||||
signal (SIGPIPE, pipe_handler);
|
||||
if (written == length)
|
||||
{
|
||||
long int r = get_status (handle);
|
||||
if (r < 0)
|
||||
return 0;
|
||||
if (r == length)
|
||||
return length;
|
||||
written = r;
|
||||
}
|
||||
|
||||
/* Write error. */
|
||||
|
||||
_rmt_shutdown (handle, EIO);
|
||||
return written;
|
||||
}
|
||||
|
||||
/* Perform an imitation lseek operation on remote tape connection
|
||||
HANDLE. Return the new file offset if successful, -1 if on error. */
|
||||
off_t
|
||||
rmt_lseek__ (int handle, off_t offset, int whence)
|
||||
{
|
||||
char command_buffer[COMMAND_BUFFER_SIZE];
|
||||
char operand_buffer[UINTMAX_STRSIZE_BOUND];
|
||||
uintmax_t u = offset < 0 ? - (uintmax_t) offset : (uintmax_t) offset;
|
||||
char *p = operand_buffer + sizeof operand_buffer;
|
||||
|
||||
*--p = 0;
|
||||
do
|
||||
*--p = '0' + (int) (u % 10);
|
||||
while ((u /= 10) != 0);
|
||||
if (offset < 0)
|
||||
*--p = '-';
|
||||
|
||||
switch (whence)
|
||||
{
|
||||
case SEEK_SET: whence = 0; break;
|
||||
case SEEK_CUR: whence = 1; break;
|
||||
case SEEK_END: whence = 2; break;
|
||||
default: abort ();
|
||||
}
|
||||
|
||||
sprintf (command_buffer, "L%s\n%d\n", p, whence);
|
||||
|
||||
if (do_command (handle, command_buffer) == -1)
|
||||
return -1;
|
||||
|
||||
return get_status_off (handle);
|
||||
}
|
||||
|
||||
/* Perform a raw tape operation on remote tape connection HANDLE.
|
||||
Return the results of the ioctl, or -1 on error. */
|
||||
int
|
||||
rmt_ioctl__ (int handle, int operation, char *argument)
|
||||
{
|
||||
switch (operation)
|
||||
{
|
||||
default:
|
||||
errno = EOPNOTSUPP;
|
||||
return -1;
|
||||
|
||||
#ifdef MTIOCTOP
|
||||
case MTIOCTOP:
|
||||
{
|
||||
char command_buffer[COMMAND_BUFFER_SIZE];
|
||||
char operand_buffer[UINTMAX_STRSIZE_BOUND];
|
||||
uintmax_t u = (((struct mtop *) argument)->mt_count < 0
|
||||
? - (uintmax_t) ((struct mtop *) argument)->mt_count
|
||||
: (uintmax_t) ((struct mtop *) argument)->mt_count);
|
||||
char *p = operand_buffer + sizeof operand_buffer;
|
||||
|
||||
*--p = 0;
|
||||
do
|
||||
*--p = '0' + (int) (u % 10);
|
||||
while ((u /= 10) != 0);
|
||||
if (((struct mtop *) argument)->mt_count < 0)
|
||||
*--p = '-';
|
||||
|
||||
/* MTIOCTOP is the easy one. Nothing is transferred in binary. */
|
||||
|
||||
sprintf (command_buffer, "I%d\n%s\n",
|
||||
((struct mtop *) argument)->mt_op, p);
|
||||
if (do_command (handle, command_buffer) == -1)
|
||||
return -1;
|
||||
|
||||
return get_status (handle);
|
||||
}
|
||||
#endif /* MTIOCTOP */
|
||||
|
||||
#ifdef MTIOCGET
|
||||
case MTIOCGET:
|
||||
{
|
||||
ssize_t status;
|
||||
size_t counter;
|
||||
|
||||
/* Grab the status and read it directly into the structure. This
|
||||
assumes that the status buffer is not padded and that 2 shorts
|
||||
fit in a long without any word alignment problems; i.e., the
|
||||
whole struct is contiguous. NOTE - this is probably NOT a good
|
||||
assumption. */
|
||||
|
||||
if (do_command (handle, "S") == -1
|
||||
|| (status = get_status (handle), status == -1))
|
||||
return -1;
|
||||
|
||||
for (; status > 0; status -= counter, argument += counter)
|
||||
{
|
||||
counter = safe_read (READ_SIDE (handle), argument, status);
|
||||
if (counter == SAFE_READ_ERROR || counter == 0)
|
||||
{
|
||||
_rmt_shutdown (handle, EIO);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check for byte position. mt_type (or mt_model) is a small integer
|
||||
field (normally) so we will check its magnitude. If it is larger
|
||||
than 256, we will assume that the bytes are swapped and go through
|
||||
and reverse all the bytes. */
|
||||
|
||||
if (((struct mtget *) argument)->MTIO_CHECK_FIELD < 256)
|
||||
return 0;
|
||||
|
||||
for (counter = 0; counter < status; counter += 2)
|
||||
{
|
||||
char copy = argument[counter];
|
||||
|
||||
argument[counter] = argument[counter + 1];
|
||||
argument[counter + 1] = copy;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* MTIOCGET */
|
||||
|
||||
}
|
||||
}
|
||||
@@ -16,7 +16,7 @@
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include "system.h"
|
||||
#include <system.h>
|
||||
#include <quotearg.h>
|
||||
#include "common.h"
|
||||
|
||||
|
||||
16
src/system.c
16
src/system.c
@@ -16,10 +16,10 @@
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include "system.h"
|
||||
#include <system.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "rmt.h"
|
||||
#include <rmt.h>
|
||||
#include <signal.h>
|
||||
|
||||
void
|
||||
@@ -118,11 +118,6 @@ sys_truncate (int fd)
|
||||
return write (fd, "", 0);
|
||||
}
|
||||
|
||||
void
|
||||
sys_reset_uid_gid (void)
|
||||
{
|
||||
}
|
||||
|
||||
size_t
|
||||
sys_write_archive_buffer (void)
|
||||
{
|
||||
@@ -281,13 +276,6 @@ sys_truncate (int fd)
|
||||
return pos < 0 ? -1 : ftruncate (fd, pos);
|
||||
}
|
||||
|
||||
void
|
||||
sys_reset_uid_gid (void)
|
||||
{
|
||||
setuid (getuid ());
|
||||
setgid (getgid ());
|
||||
}
|
||||
|
||||
/* Return nonzero if NAME is the name of a regular file, or if the file
|
||||
does not exist (so it would be created as a regular file). */
|
||||
static int
|
||||
|
||||
519
src/system.h
519
src/system.h
@@ -1,519 +0,0 @@
|
||||
/* System dependent definitions for GNU tar.
|
||||
|
||||
Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2003,
|
||||
2004 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <alloca.h>
|
||||
|
||||
#ifndef __attribute__
|
||||
/* This feature is available in gcc versions 2.5 and later. */
|
||||
# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) || __STRICT_ANSI__
|
||||
# define __attribute__(spec) /* empty */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <ctype.h>
|
||||
|
||||
/* IN_CTYPE_DOMAIN (C) is nonzero if the unsigned char C can safely be given
|
||||
as an argument to <ctype.h> macros like `isspace'. */
|
||||
#if STDC_HEADERS
|
||||
# define IN_CTYPE_DOMAIN(c) 1
|
||||
#else
|
||||
# define IN_CTYPE_DOMAIN(c) ((unsigned) (c) <= 0177)
|
||||
#endif
|
||||
|
||||
#define ISDIGIT(c) ((unsigned) (c) - '0' <= 9)
|
||||
#define ISODIGIT(c) ((unsigned) (c) - '0' <= 7)
|
||||
#define ISPRINT(c) (IN_CTYPE_DOMAIN (c) && isprint (c))
|
||||
#define ISSPACE(c) (IN_CTYPE_DOMAIN (c) && isspace (c))
|
||||
|
||||
/* Declare string and memory handling routines. Take care that an ANSI
|
||||
string.h and pre-ANSI memory.h might conflict, and that memory.h and
|
||||
strings.h conflict on some systems. */
|
||||
|
||||
#if STDC_HEADERS || HAVE_STRING_H
|
||||
# include <string.h>
|
||||
# if !STDC_HEADERS && HAVE_MEMORY_H
|
||||
# include <memory.h>
|
||||
# endif
|
||||
#else
|
||||
# include <strings.h>
|
||||
# ifndef strchr
|
||||
# define strchr index
|
||||
# endif
|
||||
# ifndef strrchr
|
||||
# define strrchr rindex
|
||||
# endif
|
||||
# ifndef memcpy
|
||||
# define memcpy(d, s, n) bcopy ((char const *) (s), (char *) (d), n)
|
||||
# endif
|
||||
# ifndef memcmp
|
||||
# define memcmp(a, b, n) bcmp ((char const *) (a), (char const *) (b), n)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Declare errno. */
|
||||
|
||||
#include <errno.h>
|
||||
#ifndef errno
|
||||
extern int errno;
|
||||
#endif
|
||||
|
||||
/* Declare open parameters. */
|
||||
|
||||
#if HAVE_FCNTL_H
|
||||
# include <fcntl.h>
|
||||
#else
|
||||
# include <sys/file.h>
|
||||
#endif
|
||||
/* Pick only one of the next three: */
|
||||
#ifndef O_RDONLY
|
||||
# define O_RDONLY 0 /* only allow read */
|
||||
#endif
|
||||
#ifndef O_WRONLY
|
||||
# define O_WRONLY 1 /* only allow write */
|
||||
#endif
|
||||
#ifndef O_RDWR
|
||||
# define O_RDWR 2 /* both are allowed */
|
||||
#endif
|
||||
#ifndef O_ACCMODE
|
||||
# define O_ACCMODE (O_RDONLY | O_RDWR | O_WRONLY)
|
||||
#endif
|
||||
/* The rest can be OR-ed in to the above: */
|
||||
#ifndef O_CREAT
|
||||
# define O_CREAT 8 /* create file if needed */
|
||||
#endif
|
||||
#ifndef O_EXCL
|
||||
# define O_EXCL 16 /* file cannot already exist */
|
||||
#endif
|
||||
#ifndef O_TRUNC
|
||||
# define O_TRUNC 32 /* truncate file on open */
|
||||
#endif
|
||||
/* MS-DOG forever, with my love! */
|
||||
#ifndef O_BINARY
|
||||
# define O_BINARY 0
|
||||
#endif
|
||||
|
||||
/* Declare file status routines and bits. */
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
#if !HAVE_LSTAT && !defined lstat
|
||||
# define lstat stat
|
||||
#endif
|
||||
|
||||
#if STX_HIDDEN && !_LARGE_FILES /* AIX */
|
||||
# ifdef stat
|
||||
# undef stat
|
||||
# endif
|
||||
# define stat(file_name, buf) statx (file_name, buf, STATSIZE, STX_HIDDEN)
|
||||
# ifdef lstat
|
||||
# undef lstat
|
||||
# endif
|
||||
# define lstat(file_name, buf) statx (file_name, buf, STATSIZE, STX_HIDDEN | STX_LINK)
|
||||
#endif
|
||||
|
||||
#if STAT_MACROS_BROKEN
|
||||
# undef S_ISBLK
|
||||
# undef S_ISCHR
|
||||
# undef S_ISCTG
|
||||
# undef S_ISDIR
|
||||
# undef S_ISFIFO
|
||||
# undef S_ISLNK
|
||||
# undef S_ISREG
|
||||
# undef S_ISSOCK
|
||||
#endif
|
||||
|
||||
/* On MSDOS, there are missing things from <sys/stat.h>. */
|
||||
#if MSDOS
|
||||
# define S_ISUID 0
|
||||
# define S_ISGID 0
|
||||
# define S_ISVTX 0
|
||||
#endif
|
||||
|
||||
#ifndef S_ISDIR
|
||||
# define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
|
||||
#endif
|
||||
#ifndef S_ISREG
|
||||
# define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
|
||||
#endif
|
||||
|
||||
#ifndef S_ISBLK
|
||||
# ifdef S_IFBLK
|
||||
# define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK)
|
||||
# else
|
||||
# define S_ISBLK(mode) 0
|
||||
# endif
|
||||
#endif
|
||||
#ifndef S_ISCHR
|
||||
# ifdef S_IFCHR
|
||||
# define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR)
|
||||
# else
|
||||
# define S_ISCHR(mode) 0
|
||||
# endif
|
||||
#endif
|
||||
#ifndef S_ISCTG
|
||||
# ifdef S_IFCTG
|
||||
# define S_ISCTG(mode) (((mode) & S_IFMT) == S_IFCTG)
|
||||
# else
|
||||
# define S_ISCTG(mode) 0
|
||||
# endif
|
||||
#endif
|
||||
#ifndef S_ISDOOR
|
||||
# define S_ISDOOR(mode) 0
|
||||
#endif
|
||||
#ifndef S_ISFIFO
|
||||
# ifdef S_IFIFO
|
||||
# define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO)
|
||||
# else
|
||||
# define S_ISFIFO(mode) 0
|
||||
# endif
|
||||
#endif
|
||||
#ifndef S_ISLNK
|
||||
# ifdef S_IFLNK
|
||||
# define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK)
|
||||
# else
|
||||
# define S_ISLNK(mode) 0
|
||||
# endif
|
||||
#endif
|
||||
#ifndef S_ISSOCK
|
||||
# ifdef S_IFSOCK
|
||||
# define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK)
|
||||
# else
|
||||
# define S_ISSOCK(mode) 0
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !HAVE_MKFIFO && !defined mkfifo && defined S_IFIFO
|
||||
# define mkfifo(file_name, mode) (mknod (file_name, (mode) | S_IFIFO, 0))
|
||||
#endif
|
||||
|
||||
#ifndef S_ISUID
|
||||
# define S_ISUID 0004000
|
||||
#endif
|
||||
#ifndef S_ISGID
|
||||
# define S_ISGID 0002000
|
||||
#endif
|
||||
#ifndef S_ISVTX
|
||||
# define S_ISVTX 0001000
|
||||
#endif
|
||||
#ifndef S_IRUSR
|
||||
# define S_IRUSR 0000400
|
||||
#endif
|
||||
#ifndef S_IWUSR
|
||||
# define S_IWUSR 0000200
|
||||
#endif
|
||||
#ifndef S_IXUSR
|
||||
# define S_IXUSR 0000100
|
||||
#endif
|
||||
#ifndef S_IRGRP
|
||||
# define S_IRGRP 0000040
|
||||
#endif
|
||||
#ifndef S_IWGRP
|
||||
# define S_IWGRP 0000020
|
||||
#endif
|
||||
#ifndef S_IXGRP
|
||||
# define S_IXGRP 0000010
|
||||
#endif
|
||||
#ifndef S_IROTH
|
||||
# define S_IROTH 0000004
|
||||
#endif
|
||||
#ifndef S_IWOTH
|
||||
# define S_IWOTH 0000002
|
||||
#endif
|
||||
#ifndef S_IXOTH
|
||||
# define S_IXOTH 0000001
|
||||
#endif
|
||||
|
||||
#define MODE_WXUSR (S_IWUSR | S_IXUSR)
|
||||
#define MODE_R (S_IRUSR | S_IRGRP | S_IROTH)
|
||||
#define MODE_RW (S_IWUSR | S_IWGRP | S_IWOTH | MODE_R)
|
||||
#define MODE_RWX (S_IXUSR | S_IXGRP | S_IXOTH | MODE_RW)
|
||||
#define MODE_ALL (S_ISUID | S_ISGID | S_ISVTX | MODE_RWX)
|
||||
|
||||
/* Include <unistd.h> before any preprocessor test of _POSIX_VERSION. */
|
||||
#if HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifndef SEEK_SET
|
||||
# define SEEK_SET 0
|
||||
#endif
|
||||
#ifndef SEEK_CUR
|
||||
# define SEEK_CUR 1
|
||||
#endif
|
||||
#ifndef SEEK_END
|
||||
# define SEEK_END 2
|
||||
#endif
|
||||
|
||||
#ifndef STDIN_FILENO
|
||||
# define STDIN_FILENO 0
|
||||
#endif
|
||||
#ifndef STDOUT_FILENO
|
||||
# define STDOUT_FILENO 1
|
||||
#endif
|
||||
#ifndef STDERR_FILENO
|
||||
# define STDERR_FILENO 2
|
||||
#endif
|
||||
|
||||
/* Declare make device, major and minor. Since major is a function on
|
||||
SVR4, we have to resort to GOT_MAJOR instead of just testing if
|
||||
major is #define'd. */
|
||||
|
||||
#if MAJOR_IN_MKDEV
|
||||
# include <sys/mkdev.h>
|
||||
# define GOT_MAJOR
|
||||
#endif
|
||||
|
||||
#if MAJOR_IN_SYSMACROS
|
||||
# include <sys/sysmacros.h>
|
||||
# define GOT_MAJOR
|
||||
#endif
|
||||
|
||||
/* Some <sys/types.h> defines the macros. */
|
||||
#ifdef major
|
||||
# define GOT_MAJOR
|
||||
#endif
|
||||
|
||||
#ifndef GOT_MAJOR
|
||||
# if MSDOS
|
||||
# define major(device) (device)
|
||||
# define minor(device) (device)
|
||||
# define makedev(major, minor) (((major) << 8) | (minor))
|
||||
# define GOT_MAJOR
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* For HP-UX before HP-UX 8, major/minor are not in <sys/sysmacros.h>. */
|
||||
#ifndef GOT_MAJOR
|
||||
# if defined(hpux) || defined(__hpux__) || defined(__hpux)
|
||||
# include <sys/mknod.h>
|
||||
# define GOT_MAJOR
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef GOT_MAJOR
|
||||
# define major(device) (((device) >> 8) & 0xff)
|
||||
# define minor(device) ((device) & 0xff)
|
||||
# define makedev(major, minor) (((major) << 8) | (minor))
|
||||
#endif
|
||||
|
||||
#undef GOT_MAJOR
|
||||
|
||||
/* Declare wait status. */
|
||||
|
||||
#if HAVE_SYS_WAIT_H
|
||||
# include <sys/wait.h>
|
||||
#endif
|
||||
#ifndef WEXITSTATUS
|
||||
# define WEXITSTATUS(s) (((s) >> 8) & 0xff)
|
||||
#endif
|
||||
#ifndef WIFSIGNALED
|
||||
# define WIFSIGNALED(s) (((s) & 0xffff) - 1 < (unsigned) 0xff)
|
||||
#endif
|
||||
#ifndef WTERMSIG
|
||||
# define WTERMSIG(s) ((s) & 0x7f)
|
||||
#endif
|
||||
|
||||
/* FIXME: It is wrong to use BLOCKSIZE for buffers when the logical block
|
||||
size is greater than 512 bytes; so ST_BLKSIZE code below, in preparation
|
||||
for some cleanup in this area, later. */
|
||||
|
||||
/* Extract or fake data from a `struct stat'. ST_BLKSIZE gives the
|
||||
optimal I/O blocksize for the file, in bytes. Some systems, like
|
||||
Sequents, return st_blksize of 0 on pipes. */
|
||||
|
||||
#define DEFAULT_ST_BLKSIZE 512
|
||||
|
||||
#if !HAVE_ST_BLKSIZE
|
||||
# define ST_BLKSIZE(statbuf) DEFAULT_ST_BLKSIZE
|
||||
#else
|
||||
# define ST_BLKSIZE(statbuf) \
|
||||
((statbuf).st_blksize > 0 ? (statbuf).st_blksize : DEFAULT_ST_BLKSIZE)
|
||||
#endif
|
||||
|
||||
/* Extract or fake data from a `struct stat'. ST_NBLOCKS gives the
|
||||
number of ST_NBLOCKSIZE-byte blocks in the file (including indirect blocks).
|
||||
HP-UX counts st_blocks in 1024-byte units,
|
||||
this loses when mixing HP-UX and BSD filesystems with NFS. AIX PS/2
|
||||
counts st_blocks in 4K units. */
|
||||
|
||||
#if !HAVE_ST_BLOCKS
|
||||
# if defined(_POSIX_SOURCE) || !defined(BSIZE)
|
||||
# define ST_NBLOCKS(statbuf) ((statbuf).st_size / ST_NBLOCKSIZE + ((statbuf).st_size % ST_NBLOCKSIZE != 0))
|
||||
# else
|
||||
off_t st_blocks ();
|
||||
# define ST_NBLOCKS(statbuf) (st_blocks ((statbuf).st_size))
|
||||
# endif
|
||||
#else
|
||||
# define ST_NBLOCKS(statbuf) ((statbuf).st_blocks)
|
||||
# if defined(hpux) || defined(__hpux__) || defined(__hpux)
|
||||
# define ST_NBLOCKSIZE 1024
|
||||
# else
|
||||
# if defined(_AIX) && defined(_I386)
|
||||
# define ST_NBLOCKSIZE (4 * 1024)
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef ST_NBLOCKSIZE
|
||||
#define ST_NBLOCKSIZE 512
|
||||
#endif
|
||||
|
||||
/* This is a real challenge to properly get MTIO* symbols :-(. ISC uses
|
||||
<sys/gentape.h>. SCO and BSDi uses <sys/tape.h>; BSDi also requires
|
||||
<sys/tprintf.h> and <sys/device.h> for defining tp_dev and tpr_t. It
|
||||
seems that the rest use <sys/mtio.h>, which itself requires other files,
|
||||
depending on systems. Pyramid defines _IOW in <sgtty.h>, for example. */
|
||||
|
||||
#if HAVE_SYS_GENTAPE_H
|
||||
# include <sys/gentape.h>
|
||||
#else
|
||||
# if HAVE_SYS_TAPE_H
|
||||
# if HAVE_SYS_DEVICE_H
|
||||
# include <sys/device.h>
|
||||
# endif
|
||||
# if HAVE_SYS_PARAM_H
|
||||
# include <sys/param.h>
|
||||
# endif
|
||||
# if HAVE_SYS_BUF_H
|
||||
# include <sys/buf.h>
|
||||
# endif
|
||||
# if HAVE_SYS_TPRINTF_H
|
||||
# include <sys/tprintf.h>
|
||||
# endif
|
||||
# include <sys/tape.h>
|
||||
# else
|
||||
# if HAVE_SYS_MTIO_H
|
||||
# include <sys/ioctl.h>
|
||||
# if HAVE_SGTTY_H
|
||||
# include <sgtty.h>
|
||||
# endif
|
||||
# if HAVE_SYS_IO_TRIOCTL_H
|
||||
# include <sys/io/trioctl.h>
|
||||
# endif
|
||||
# include <sys/mtio.h>
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Declare standard functions. */
|
||||
|
||||
#if STDC_HEADERS
|
||||
# include <stdlib.h>
|
||||
#else
|
||||
void *malloc ();
|
||||
char *getenv ();
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#if !defined _POSIX_VERSION && MSDOS
|
||||
# include <io.h>
|
||||
#endif
|
||||
|
||||
#if WITH_DMALLOC
|
||||
# undef HAVE_DECL_VALLOC
|
||||
# define DMALLOC_FUNC_CHECK
|
||||
# include <dmalloc.h>
|
||||
#endif
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#ifndef MB_LEN_MAX
|
||||
# define MB_LEN_MAX 1
|
||||
#endif
|
||||
|
||||
#if HAVE_INTTYPES_H
|
||||
# include <inttypes.h>
|
||||
#endif
|
||||
|
||||
/* These macros work even on ones'-complement hosts (!).
|
||||
The extra casts work around common compiler bugs. */
|
||||
#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
|
||||
#define TYPE_MINIMUM(t) (TYPE_SIGNED (t) \
|
||||
? ~ (t) 0 << (sizeof (t) * CHAR_BIT - 1) \
|
||||
: (t) 0)
|
||||
#define TYPE_MAXIMUM(t) ((t) (~ (t) 0 - TYPE_MINIMUM (t)))
|
||||
|
||||
/* Bound on length of the string representing an integer value of type t.
|
||||
Subtract one for the sign bit if t is signed;
|
||||
302 / 1000 is log10 (2) rounded up;
|
||||
add one for integer division truncation;
|
||||
add one more for a minus sign if t is signed. */
|
||||
#define INT_STRLEN_BOUND(t) \
|
||||
((sizeof (t) * CHAR_BIT - TYPE_SIGNED (t)) * 302 / 1000 \
|
||||
+ 1 + TYPE_SIGNED (t))
|
||||
|
||||
#define UINTMAX_STRSIZE_BOUND (INT_STRLEN_BOUND (uintmax_t) + 1)
|
||||
|
||||
/* Prototypes for external functions. */
|
||||
|
||||
#if HAVE_LOCALE_H
|
||||
# include <locale.h>
|
||||
#endif
|
||||
#if !HAVE_SETLOCALE
|
||||
# define setlocale(category, locale) /* empty */
|
||||
#endif
|
||||
|
||||
#include <time.h>
|
||||
#if defined(HAVE_SYS_TIME_H) && defined(TIME_WITH_SYS_TIME)
|
||||
# include <sys/time.h>
|
||||
#endif
|
||||
#if ! HAVE_DECL_TIME
|
||||
time_t time ();
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_UTIME_H
|
||||
# include <utime.h>
|
||||
#endif
|
||||
|
||||
/* Library modules. */
|
||||
|
||||
#include <dirname.h>
|
||||
#include <error.h>
|
||||
#include <savedir.h>
|
||||
#include <unlocked-io.h>
|
||||
#include <xalloc.h>
|
||||
|
||||
#include <gettext.h>
|
||||
#define _(msgid) gettext (msgid)
|
||||
#define N_(msgid) msgid
|
||||
|
||||
#if MSDOS
|
||||
# include <process.h>
|
||||
# define SET_BINARY_MODE(arc) setmode(arc, O_BINARY)
|
||||
# define ERRNO_IS_EACCES errno == EACCES
|
||||
# define mkdir(file, mode) (mkdir) (file)
|
||||
#else
|
||||
# include <pwd.h>
|
||||
# include <grp.h>
|
||||
# define SET_BINARY_MODE(arc)
|
||||
# define ERRNO_IS_EACCES 0
|
||||
#endif
|
||||
|
||||
#if XENIX
|
||||
# include <sys/inode.h>
|
||||
#endif
|
||||
@@ -19,7 +19,7 @@
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include "system.h"
|
||||
#include <system.h>
|
||||
|
||||
#include <fnmatch.h>
|
||||
#include <argp.h>
|
||||
@@ -38,6 +38,7 @@
|
||||
|
||||
#include <getdate.h>
|
||||
#include <localedir.h>
|
||||
#include <rmt.h>
|
||||
#include <prepargs.h>
|
||||
#include <quotearg.h>
|
||||
#include <xstrtol.h>
|
||||
@@ -1060,7 +1061,7 @@ parse_opt(int key, char *arg, struct argp_state *state)
|
||||
break;
|
||||
|
||||
case RMT_COMMAND_OPTION:
|
||||
rmt_command_option = arg;
|
||||
rmt_command = arg;
|
||||
break;
|
||||
|
||||
case RSH_COMMAND_OPTION:
|
||||
@@ -1510,9 +1511,6 @@ decode_options (int argc, char **argv)
|
||||
if (utc_option)
|
||||
verbose_option = 2;
|
||||
|
||||
if (!rmt_command_option)
|
||||
rmt_command_option = DEFAULT_RMT_COMMAND;
|
||||
|
||||
/* Forbid using -c with no input files whatsoever. Check that `-f -',
|
||||
explicit or implied, is used correctly. */
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
of the archive. No attempt is made to record the reads from the args; if
|
||||
they're on raw tape or something like that, it'll probably lose... */
|
||||
|
||||
#include "system.h"
|
||||
#include <system.h>
|
||||
#include <quotearg.h>
|
||||
#include "common.h"
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include "system.h"
|
||||
#include <system.h>
|
||||
#include <quotearg.h>
|
||||
#include "common.h"
|
||||
#ifdef HAVE_ICONV_H
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include "system.h"
|
||||
#include <system.h>
|
||||
|
||||
#include <fnmatch.h>
|
||||
#include <hash.h>
|
||||
|
||||
Reference in New Issue
Block a user