diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2004-09-06 13:49:41 +0000 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2004-09-06 13:49:41 +0000 |
commit | 73e17c725e53395dcf3c68a8920c105ada87fd85 (patch) | |
tree | 1327032cf3936285837c04db765c0ebf8d265e83 | |
parent | 8109596484d8910dd790b96f362095ee9de9e617 (diff) | |
download | paxutils.tar.gz |
-rw-r--r-- | ChangeLog | 434 | ||||
-rw-r--r-- | README | 76 | ||||
-rw-r--r-- | lib/DISTFILES | 1 | ||||
-rw-r--r-- | lib/rmt.h | 6 | ||||
-rw-r--r-- | lib/rtapelib.c | 18 | ||||
-rw-r--r-- | lib/system.h | 110 | ||||
-rw-r--r-- | m4/DISTFILES | 2 | ||||
-rw-r--r-- | m4/rmt.m4 | 17 | ||||
-rw-r--r-- | rmt/Makefile.am | 4 | ||||
-rw-r--r-- | rmt/rmt.c | 657 |
10 files changed, 384 insertions, 941 deletions
@@ -1,440 +1,8 @@ -2008-05-20 Sergey Poznyakoff <gray@gnu.org.ua> - - * tests/genfile.c (verify_file): Improve error diagnostics. - -2008-02-18 Sergey Poznyakoff <gray@gnu.org.ua> - - * tests/genfile.c: Remove setenv.h - -2007-12-05 Sergey Poznyakoff <gray@gnu.org.ua> - - Changes needed for cpio mingw build: - - * lib/system.h: Include pwd.h and grp.h if the corresponding HAVE_ - preprocessor symbols are defined. - * m4/system.m4 (AC_CHECK_HEADERS_ONCE): Add pwd.h and grp.h. - -2007-11-07 Sergey Poznyakoff <gray@gnu.org.ua> - - * gnulib.modules: Add fseeko. - -2007-10-11 Paul Eggert <eggert@cs.ucla.edu> - - * gnulib.modules: Add strerror. - * configure.ac: Don't test for strerror any more; the gnulib - strerror module handles this. - * m4/rmt.m4 (PU_RMT): Likewise. - -2007-08-19 Sergey Poznyakoff <gray@gnu.org.ua> - - * paxlib/names.c (safer_name_suffix): Fix variable type - -2007-08-17 Sergey Poznyakoff <gray@gnu.org.ua> - - * paxlib/names.c (hash_string_insert_prefix): New function - (hash_string_insert): Rewrite using hash_string_insert_prefix - (safer_name_suffix): Use hash_string_insert_prefix to avoid - stack allocation. Bug reported by Dmitry V. Levin; - -2007-08-12 Sergey Poznyakoff <gray@gnu.org.ua> - - * lib/rtapelib.c, paxlib/rtape.c: Use last_component instead of - base_name. Patch by Eric Blake. - -2007-06-27 Sergey Poznyakoff <gray@gnu.org.ua> - - Relicense under GPLv3 - -2007-06-21 Sergey Poznyakoff <gray@gnu.org.ua> - - * tests/genfile.c: Print errno status on errors. - -2007-06-21 Eric Blake <ebb9@byu.net> - - Resolve testsuite failures on cygwin. - * tests/genfile.c (generate_simple_file): Force binary - mode. - (generate_files_from_list, generate_sparse_file) - (exec_checkpoint, exec_command): Likewise. - -2006-12-18 Sergey Poznyakoff <gray@gnu.org.ua> - - * gnulib.modules: Add configmake - -2006-12-12 Paul Eggert <eggert@cs.ucla.edu> - - * rmt/rmt.c (status_device) [!defined MTIOCGET]: - Fix bracketing typo. Problem reported by Yutaka Furubayashi. - -2006-12-07 Sergey Poznyakoff <gray@gnu.org.ua> - - * doc/genfile.texi (Generate Mode): Document --seek option. - * paxlib/error.c (read_fatal_details): Fix wording of the error - message. - * tests/genfile.c: Implement new option --seek (similar - to `dd seek=') - -2006-11-29 Paul Eggert <eggert@cs.ucla.edu> - - * lib/rtapelib.c: Include <rmt-command.h> rather than <localedir.h>, - to accommodate recent changes to gnulib and tar. - * rmt/rmt.c: Likewise. - * rmt/Makefile.am (rmt.o): Depend on configmake.h, not localedir.h. - * m4/system.m4 (PU_SUSTEM): Put AC_REQUIRE wrappers around - AC_HEADER_STDC, etc. This avoids a warning from automake, - with the latest gnulib. - -2006-09-27 Sergey Poznyakoff <gray@gnu.org.ua> - - * tests/genfile.c (exec_command): Add extra spaces. - -2006-09-08 Sergey Poznyakoff <gray@gnu.org.ua> - - * tests/genfile.c (exec_command): Fix memory reallocation. - -2006-08-07 Paul Eggert <eggert@cs.ucla.edu> - - * lib/system.h: Include <inttypes.h> unconditionally. - The latest gnulib lets us do this. - * m4/system.m4 (PU_SYSTEM): Don't check for inttypes.h - Don't require gl_AC_TYPE_UINTMAX_T. - Require gl_INTTYPES_H, gl_STDINT_H. - - * tests/genfile.c (reg_action): Return void, not int. - (generate_simple_file, exec_command): Remove unused var. - (print_stat): Avoid GCC warning about uninitialized var. - -2006-07-09 Sergey Poznyakoff <gray@gnu.org.ua> - - * THANKS: Add Ralf Wildenhues - -2006-07-09 Ralf Wildenhues <Ralf.Wildenhues@gmx.de> - - * doc/genfile.texi: Fix some typos. - -2006-07-03 Sergey Poznyakoff <gray@gnu.org.ua> - - * tests/genfile.c (get_size): Rewrite to avoid numeric overflow. - -2006-06-25 Sergey Poznyakoff <gray@gnu.org.ua> - - * lib/system.h (ST_IS_SPARSE): New macro - * tests/genfile.c: Use ST_IS_SPARSE instead of IS_SPARSE_FILE - -2006-06-21 Sergey Poznyakoff <gray@gnu.org.ua> - - * paxlib/exit.c: Initialize the variable to avoid bogus errors - when linking on Darwin. Reported by EXCOFFIER, Denis - <denis.excoffier@airbus.com>. - -2006-06-02 Sergey Poznyakoff <gray@gnu.org.ua> - - * tests/genfile.c: New options --files-from and --null (same as in - tar). - * doc/genfile.texi: Document --files-from and --null options - -2006-04-25 Sergey Poznyakoff <gray@gnu.org.ua> - - * doc/genfile.texi: Document exit codes in create mode. Fix file - size calculation in the example of genfile --sparse. - * tests/genfile.c: Behave as described in the docs in sparse file - creation mode. Verify created file, unless it goes to stdout. - -2006-04-11 Sergey Poznyakoff <gray@gnu.org.ua> - - * tests/genfile.c (print_stat): mode keyword can be optionally - followed by a punctuation sign and a number, specifying the mask - to be applied to the mode before printing. - - * doc/genfile.texi: Update - -2006-03-11 Paul Eggert <eggert@cs.ucla.edu> - - * rmt/rmt.c (STRING_SIZE): Now UINTMAX_STRSIZE_BOUND + 1, since - bounded strings are used only for integers now. - (get_string): Use a prototype. Remove unused local var 'counter'. - (get_long): Arg is now char const *, not char *. - Check for integer overflow in arg. - Check for empty arg. - (open_device): Use get_string for oflags, too, since the existing - limits were uncomfortably close to being too small. - Don't assume free_string does not affect errno. - -2006-03-12 Sergey Poznyakoff <gray@gnu.org.ua> - - * gnulib.modules: Add obstack - * rmt/rmt.c (get_string): Renamed to get_string_n. All callers - changed. - (get_string,free_string,i18n_setup): New function. - (usage): Call i18n_setup - (open_device): Use new get_string function to remove the - limitation on the device name length. - * tests/genfile.c: Properly initialize i18n. - -2006-03-07 Paul Eggert <eggert@cs.ucla.edu> - - * configure.ac (AC_CHECK_HEADERS): Don't check for sys/time.h, - since we no longer use HAVE_SYS_TIME_H. - (AC_CHECK_DECLS): Don't check for 'time', since we assume - C89 or better. - * lib/system.h: Include <unistd.h> unconditionally, since we now - assume the unistd module. - (time): Remove decl; not needed, since we assume C89 or better. - Don't bother checking for HAVE_SYS_TIME_H when deciding whether - to include <sys/time.h>, since TIME_WITH_SYS_TIME implies sys/time.h - exists. - (HAVE_DECL_VALLOC) [WITH_DMALLOC]: Remove #undef, since this symbol - is no longer used. - - * m4/system.m4 (PU_SYSTEM): Don't check for unistd.h or sys/time.h, - or for time or valloc. - -2006-02-20 Sergey Poznyakoff <gray@gnu.org.ua> - - * m4/system.m4: Remove sys/buf.h from AC_CHECK_HEADERS_ONCE, check - for it separately (needs sys/param.h on some systems). - -2006-02-20 Paul Eggert <eggert@cs.ucla.edu> - - * lib/DISTFILES: Add system-ioctl.h. - * lib/system.h: Move the MTIO* stuff into.... - * lib/system-ioctl.h: New file. That way, the symbols defined - by these includes won't collide with the symbols defined by - <sys/filio.h> on Solaris when compiling misc.c. - * lib/rtapelib.c: Include system-ioctl.h. - * paxlib/rtape.c: Likewise. - * rmt/rmt.c: Likewise. - -2006-02-07 Paul Eggert <eggert@cs.ucla.edu> - - * gnulib.modules: Add closeout. - * rmt/rmt.c: Include closeout.h. - (main, usage): Use close_stdout to report write errors properly. - - * gnulib.modules: Add version-etc-fsf. - * rmt/rmt.c: Include <version-etc.h>. - (main): Use version_etc rather than rolling our own. - -2005-12-08 Sergey Poznyakoff <gray@gnu.org.ua> - - * tests/genfile.c: Fix creation of large files - -2005-11-29 Paul Eggert <eggert@cs.ucla.edu> - - * lib/rtapelib.c (encode_oflag): Simplify code, since O_NONBLOCK - is always defined now. - * paxlib/rtape.c (encode_oflag): Likewise. - * lib/system.h (O_DIRCTORY, O_NOATIME, O_NONBLOCK): Define to 0 - if not already defined. - * paxlib/error.c (rmdir_error): New function. - * paxlib/error.h (rmdir_error): New decl. - * rmt/rmt.c (decode_oflag): Use '#if O_NONBLOCK", not ifdef. - -2005-11-06 Paul Eggert <eggert@cs.ucla.edu> - - * lib/system.h (strtoimax, strtoumax): Declare if the system - headers don't. - -2005-09-16 Paul Eggert <eggert@cs.ucla.edu> - - Merge changes from gnulib for file system sub-second time stamps. - * configure.ac: Remove checks for struct stat.st_spare1, struct - stat.st_atim.tv_nsec, struct stat.st_atimespec.tv_nsec, struct - stat.st_atimensec, as gnulib now does this for us. - Similarly for LIB_CLOCK_GETTIME. - -2005-06-23 Sergey Poznyakoff <gray@Mirddin.farlep.net> - - * tests/genfile.c (print_stat): Use umaxstr. - -2005-06-21 Paul Eggert <eggert@cs.ucla.edu> - - Improve support for wide time stamps and other wide integers. - * gnulib.modules: Add inttostr, quote, quotearg. - * lib/system.h (TYPE_SIGNED, TYPE_MINIMUM, TYPE_MAXIMUM): Remove. - (INT_STRLEN_BOUND): Remove. - Include "intprops.h" instead. - (UINTMAX_STRSIZE_BOUND): Define in terms of INT_BUFSIZE_BOUND, - not INT_STRLEN_BOUND. - [HAVE_UTIME_H]: Don't include utime.h. - * paxlib/DISTFILES: Remove convert.c. - * paxlib/convert.c: Remove. - * paxlib/error.c: Include quote.h, quotearg.h. - * paxlib/paxlib.h: Include inttostr.h. - (STRINGIFY_BIGINT): Define in terms of umaxtostr. - (stringify_uintmax_t_backwards): Remove decl. - * tests/genfile.c: Include <utimens.h> instead of rolling our own. - (exec_checkpoint): Use utimens instead of rolling our own. - Don't pass extra args to error. - (main): Wrap message inside _(). - - * tests/genfile.c: Port to Solaris 8. - Include <signal.h>, for 'signal'. - (SIGCHLD) [! defined SIGCHLD && defined SIGCLD]: Define. - (child_exited, sig_child): Remove; not needed. - (exec_command): Use a prototype. - (main): Set SIGCHLD handler to default, not to sig_child. - And do this only if SIGCHLD is defined. This uses the - same pattern that src/tar.c uses. - -2005-06-13 Sergey Poznyakoff <gray@Mirddin.farlep.net> - - * m4/rmt.m4 (PU_RMT): Fix building on Cygwin. Proposed by Corinna - Vinschen <vinschen@redhat.com>. - * m4/system.m4 (PU_SYSTEM): Add AC_STRUCT_ST_BLKSIZE. - Require gl_AC_TYPE_UINTMAX_T (this means that uintmax_t.m4 from - gnulibs should be used). - -2005-05-22 Sergey Poznyakoff <gray@Mirddin.farlep.net> - - * paxlib/paxerror.h: Removed - * paxlib/names.c: New file - * paxlib/paxlib.h: New file - * paxlib/DISTFILES: Add names.c,paxlib.h; remove paxerror.h - * paxlib/Makefile.am: Likewise - * paxlib/error.c: Rename paxerror.h to paxlib.h - * paxlib/exit.c: Likewise. - -2005-05-19 Sergey Poznyakoff <gray@Mirddin.farlep.net> - - * paxlib/DISTFILES: New file - * paxlib/convert.c: New file - * paxlib/error.c: New file - * paxlib/exit.c: New file - * paxlib/paxerror.h: New file - * paxlib/Makefile.am (libpax_a_SOURCES): Add new files. - - * gnulib.modules: Add getdate. Needed by genfile. - * m4/rmt.m4 (PU_RMT): Check for LIB_SETSOCKOPT - -2005-05-14 Paul Eggert <eggert@cs.ucla.edu> - - * COPYING, Makefile.am, configure.ac, build-aux/bootstrap, - lib/Makefile.tmpl, lib/rmt.h, lib/rtapelib.c, lib/system.h, - paxlib/Makefile.am, paxlib/pax.h, paxlib/paxbuf.c, - paxlib/paxbuf.h, paxlib/rtape.c, paxlib/tar.h, paxlib/tarbuf.c, - paxlib/tardef.h, paxtest/Makefile.am, paxtest/paxtest.c, - paxtest/paxtest.h, rmt/rmt.c, tests/argcv.c, tests/argcv.h, - tests/genfile.c: - Update FSF postal mail address. - -2005-05-14 Sergey Poznyakoff <gray@Mirddin.farlep.net> - - * AUTHORS: New file - * COPYING: New file - * NEWS: New file - * THANKS: New file - * README-alpha: New file - * README: Updated - * Makefile.am: New file - * configure.ac: New file - * .cvsignore: New file - - * paxlib: New directory - * paxlib/Makefile.am: New file - * paxlib/pax.h: Likewise - * paxlib/paxbuf.c: Likewise - * paxlib/paxbuf.h: Likewise - * paxlib/rtape.c: Likewise - * paxlib/tar.h: Likewise - * paxlib/tarbuf.c: Likewise - * paxlib/tardef.h: Likewise - * paxlib/.cvsignore: New file - - * po: New directory - * po/.cvsignore: New file - * po/Makevars: Likewise - * po/POTFILES.in: Likewise - - * paxtest: New directory - * paxtest/Makefile.am: New file - * paxtest/.cvsignore: New file - * paxtest/paxtest.c: New file - * paxtest/paxtest.h: New file - - * lib/Makefile.tmpl: New file - * lib/.cvsignore: New file - * lib/paxbuf.c: Removed - * lib/paxbuf.h: Removed - * m4/.cvsignore: New file - - * build-aux: New directory - * build-aux/bootstrap: New file - * build-aux/gnulib.modules: New file - * build-aux/.cvsignore: New file - - * doc/genfile.texi: Minor fixes - -2005-05-12 Sergey Poznyakoff <gray@Mirddin.farlep.net> - - * lib/system.h: If mkdev is defined, use it as makedev. Proposed - by Todd Vierling. - * rmt/rmt.c (main): Remove unused variable. - * tests/DISTFILES: Add new files - * tests/argcv.c: New file - * tests/argcv.h: New file - * tests/genfile.c: Major rewrite. Add new operation mode: --run. - * doc: New directory - * doc/DISTFILES: New file. - * doc/genfile.texi: New file. - -2005-03-21 Sergey Poznyakoff <gray@Mirddin.farlep.net> - - * tests/genfile.c (main): Allow --length=0 - -2005-02-07 Sergey Poznyakoff <gray@Mirddin.farlep.net> - - * lib/paxbuf.c: New file - * lib/paxbuf.h: Likewise - -2005-02-06 Sergey Poznyakoff <gray@Mirddin.farlep.net> - - * gnulib.modules: New file. List of required gnulib - modules. - -2005-02-04 Sergey Poznyakoff <gray@Mirddin.farlep.net> - - * rmt/rmt.c: Cleaned up the mess. Fixed error reporting. - -2005-02-03 Sergey Poznyakoff <gray@Mirddin.farlep.net> - - * tests/genfile.c: New mode `--stat' prints selected - fields from struct stat for existing files. - Improved help output. - -2005-01-06 Sergey Poznyakoff <gray@Mirddin.farlep.net> - - * m4/rtapelib.m4: New file - * m4/system.m4: New file - * m4/rmt.m4 (PU_RMT): Check for strerror - * m4/DISTFILES: Added new files - * rmt/rmt.c (main): Fixed declaration - -2004-12-22 Sergey Poznyakoff <gray@Mirddin.farlep.net> - - * rmt/rmt.c (main): Reverted changes. setlocale() - is handled by system.h. - -2004-12-21 Sergey Poznyakoff <gray@Mirddin.farlep.net> - - * rmt/rmt.c (main): Protect NLS initialization by - #ifdef ENABLE_NLS. - -2004-09-08 Sergey Poznyakoff <gray@Mirddin.farlep.net> - - * tests/genfile.c (parse_opt): Allow --length=0 - -2004-09-07 Sergey Poznyakoff <gray@Mirddin.farlep.net> - - * tests: New directory - * tests/DISTFILES: New file - * tests/genfile.c: New file - 2004-09-06 Sergey Poznyakoff <gray@Mirddin.farlep.net> Initial import. - + Local Variables: mode: change-log version-control: never @@ -1,66 +1,10 @@ -README for GNU paxutils -See the end of file for copying conditions. - -* Introduction - -GNU paxutils aims to provide: - - 1. tar implementation, replacing current GNU tar, - 2. cpio implementation, replacing current GNU cpio, - 3. pax implementation, conforming to POSIX standard. - -All three implementations will be built around a common (presumably -shared) library. - -See files HISTORY and TODO for the information about background of GNU -paxutils and its future plans. - -* Interaction with GNU tar and cpio - -Development of GNU paxutils evolves in sync with that of GNU tar -and cpio. New features of both projects are being moved to paxutils, -so that the project also serves as a code base repository for both tar -and cpio. - -Each subdirectory in the repository that contains files required by -any of these projects, contains a file named DISTFILES that lists the -files to be exported from this subdirectory. Such file consists of a -list of filenames, each on a separate line. Empty lines and comments -(beginning with #) are allowed. Comments must occupy a separate line. - -* Interaction with gnulib - -File gnulib.modules contains a list of gnulib modules needed by -exportable paxutils files. The build system of both projects uses this -file to create a list of necessary gnulib modules. - -A similar file, build-aux/gnulib.modules, contains a list of gnulib -modules needed by paxutils itself. It is used by build-aux/bootstrap -to bootstrap the package. - -* Current status - -Currently paxutils provides initial version of pax library, containing -internal buffering support. The 'paxtest' utility is provided for -testing the library. - - -* Copying - -Copyright (C) 2005 Free Software Foundation, Inc. - - Permission is granted to anyone to make or distribute verbatim copies - of this document as received, in any medium, provided that the - copyright notice and this permission notice are preserved, - thus giving the recipient permission to redistribute in turn. - - Permission is granted to distribute modified versions - of this document, or of portions of it, - under the above conditions, provided also that they - carry prominent notices stating who last changed them. - -Local Variables: -mode: outline -paragraph-separate: "[ ]*$" -version-control: never -End: +Currently the contents of this repository is used by GNU tar +and cpio build systems. See files HISTORY and TODO for +the information about background of GNU paxutils and its future +plans. + +Each subdirectory in the repository contains file DISTFILES that +lists the files to be exported from this subdirectory to the +above projects. The file consists of a list of filenames, each +on a separate line. Empty lines and comments (beginning with #) +are allowed. Comments must occupy a separate line. diff --git a/lib/DISTFILES b/lib/DISTFILES index 6d310f4..65bab61 100644 --- a/lib/DISTFILES +++ b/lib/DISTFILES @@ -1,4 +1,3 @@ rmt.h rtapelib.c system.h -system-ioctl.h @@ -1,11 +1,11 @@ /* Definitions for communicating with a remote tape drive. - Copyright (C) 1988, 1992, 1996, 1997, 2001, 2003, 2004, 2007 Free + 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 3, or (at your option) + 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, @@ -15,7 +15,7 @@ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ extern char *rmt_command; extern char *rmt_dev_name__; diff --git a/lib/rtapelib.c b/lib/rtapelib.c index 51faf3c..0e499b6 100644 --- a/lib/rtapelib.c +++ b/lib/rtapelib.c @@ -1,11 +1,11 @@ /* Functions for communicating with a remote tape drive. - Copyright (C) 1988, 1992, 1994, 1996, 1997, 1999, 2000, 2001, 2004, - 2005, 2006, 2007 Free Software Foundation, Inc. + 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 3, or (at your option) + 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, @@ -15,7 +15,7 @@ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + 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*. @@ -33,8 +33,6 @@ code, courtesy of Dan Kegel. */ #include "system.h" -#include "system-ioctl.h" - #include <safe-read.h> #include <full-write.h> @@ -60,7 +58,7 @@ #endif #include <rmt.h> -#include <rmt-command.h> +#include <localedir.h> /* Exit status if exec errors. */ #define EXIT_ON_EXEC_ERROR 128 @@ -342,7 +340,9 @@ encode_oflag (char *buf, int oflag) #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 @@ -358,7 +358,7 @@ encode_oflag (char *buf, int oflag) 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, +rmt_open__ (const char *file_name, int open_mode, int bias, const char *remote_shell) { int remote_pipe_number; /* pseudo, biased file descriptor */ @@ -461,7 +461,7 @@ rmt_open__ (const char *file_name, int open_mode, int bias, return -1; #endif } - remote_shell_basename = last_component (remote_shell); + remote_shell_basename = base_name (remote_shell); /* Set up the pipes for the `rsh' command, and fork. */ diff --git a/lib/system.h b/lib/system.h index 2deb585..0914195 100644 --- a/lib/system.h +++ b/lib/system.h @@ -1,11 +1,11 @@ /* System dependent definitions for GNU tar. Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2003, - 2004, 2005, 2006, 2007 Free Software Foundation, Inc. + 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 3, or (at your option) + 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, @@ -15,7 +15,8 @@ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ #if HAVE_CONFIG_H # include <config.h> @@ -108,19 +109,10 @@ extern int errno; #ifndef O_TRUNC # define O_TRUNC 32 /* truncate file on open */ #endif - -#ifndef O_BINARY + /* MS-DOG forever, with my love! */ +#ifndef O_BINARY # define O_BINARY 0 #endif -#ifndef O_DIRECTORY -# define O_DIRECTORY 0 -#endif -#ifndef O_NOATIME -# define O_NOATIME 0 -#endif -#ifndef O_NONBLOCK -# define O_NONBLOCK 0 -#endif /* Declare file status routines and bits. */ @@ -260,7 +252,9 @@ extern int errno; #define MODE_ALL (S_ISUID | S_ISGID | S_ISVTX | MODE_RWX) /* Include <unistd.h> before any preprocessor test of _POSIX_VERSION. */ -#include <unistd.h> +#if HAVE_UNISTD_H +# include <unistd.h> +#endif #ifndef SEEK_SET # define SEEK_SET 0 @@ -288,9 +282,6 @@ extern int errno; #if MAJOR_IN_MKDEV # include <sys/mkdev.h> -# if !defined(makedev) && defined(mkdev) -# define makedev(a,b) mkdev((a),(b)) -# endif # define GOT_MAJOR #endif @@ -386,12 +377,45 @@ extern int errno; #endif #ifndef ST_NBLOCKSIZE -# define ST_NBLOCKSIZE 512 +#define ST_NBLOCKSIZE 512 #endif -#define ST_IS_SPARSE(st) \ - (ST_NBLOCKS (st) \ - < ((st).st_size / ST_NBLOCKSIZE + ((st).st_size % ST_NBLOCKSIZE != 0))) +/* 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. */ @@ -411,6 +435,7 @@ char *getenv (); #endif #if WITH_DMALLOC +# undef HAVE_DECL_VALLOC # define DMALLOC_FUNC_CHECK # include <dmalloc.h> #endif @@ -421,11 +446,28 @@ char *getenv (); # define MB_LEN_MAX 1 #endif -#include <inttypes.h> +#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))) -#include <intprops.h> +/* 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_BUFSIZE_BOUND (uintmax_t) +#define UINTMAX_STRSIZE_BOUND (INT_STRLEN_BOUND (uintmax_t) + 1) /* Prototypes for external functions. */ @@ -437,9 +479,16 @@ char *getenv (); #endif #include <time.h> -#ifdef TIME_WITH_SYS_TIME +#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. */ @@ -453,13 +502,6 @@ char *getenv (); #define _(msgid) gettext (msgid) #define N_(msgid) msgid -#ifdef HAVE_PWD_H -# include <pwd.h> -#endif -#ifdef HAVE_GRP_H -# include <grp.h> -#endif - #if MSDOS # include <process.h> # define SET_BINARY_MODE(arc) setmode(arc, O_BINARY) @@ -468,6 +510,8 @@ char *getenv (); # define TTY_NAME "con" # define sys_reset_uid_gid() #else +# include <pwd.h> +# include <grp.h> # define SET_BINARY_MODE(arc) # define ERRNO_IS_EACCES 0 # define TTY_NAME "/dev/tty" diff --git a/m4/DISTFILES b/m4/DISTFILES index 2639531..4092bd2 100644 --- a/m4/DISTFILES +++ b/m4/DISTFILES @@ -1,3 +1 @@ rmt.m4 -rtapelib.m4 -system.m4 @@ -1,18 +1,5 @@ AC_DEFUN([PU_RMT],[ - # Set LIB_SETSOCKOPT to -lnsl -lsocket if necessary. - pu_save_LIBS=$LIBS - LIB_SETSOCKOPT= - AC_SEARCH_LIBS(setsockopt, [socket], , - [AC_SEARCH_LIBS(setsockopt, [socket], , , [-lnsl])]) - AC_SEARCH_LIBS(setsockopt, [nsl]) - - case "$ac_cv_search_setsockopt" in - -l*) LIB_SETSOCKOPT=$ac_cv_search_setsockopt - esac - AC_SUBST(LIB_SETSOCKOPT) - LIBS=$pu_save_LIBS - enable_rmt() { if test $ac_cv_header_sys_mtio_h = yes; then AC_CACHE_CHECK(for remote tape header files, pu_cv_header_rmt, @@ -23,7 +10,7 @@ AC_DEFUN([PU_RMT],[ #include <sys/socket.h>], pu_cv_header_rmt=yes, pu_cv_header_rmt=no)]) - test $pu_cv_header_rmt = yes && PU_RMT_PROG='rmt$(EXEEXT)' + test $pu_cv_header_rmt = yes && PU_RMT_PROG='rmt' AC_SUBST(PU_RMT_PROG) fi } @@ -69,3 +56,5 @@ AC_DEFUN([PU_RMT],[ [Define full file name of rmt program.]) fi ]) + + diff --git a/rmt/Makefile.am b/rmt/Makefile.am index b455212..c6ba2e3 100644 --- a/rmt/Makefile.am +++ b/rmt/Makefile.am @@ -4,10 +4,10 @@ EXTRA_PROGRAMS = rmt rmt_SOURCES = rmt.c -INCLUDES = -I$(top_srcdir)/lib -I../ -I../lib +INCLUDES = -I$(top_srcdir)/lib -I../ -I../lib LDADD = ../lib/lib$(PACKAGE).a $(LIBINTL) rmt_LDADD = $(LDADD) $(LIB_SETSOCKOPT) -rmt.o: ../lib/configmake.h +rmt.o: ../lib/localedir.h @@ -1,11 +1,11 @@ /* Remote connection server. - Copyright (C) 1994, 1995, 1996, 1997, 1999, 2000, 2001, 2003, 2004, - 2005, 2006, 2007 Free Software Foundation, Inc. + 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 3, or (at your option) any later + 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 @@ -15,7 +15,7 @@ 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* Copyright (C) 1983 Regents of the University of California. All rights reserved. @@ -32,15 +32,10 @@ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "system.h" -#include "system-ioctl.h" -#include <closeout.h> -#include <configmake.h> +#include <localedir.h> #include <safe-read.h> #include <full-write.h> -#include <version-etc.h> -#define obstack_chunk_alloc malloc -#define obstack_chunk_free free -#include <obstack.h> + #include <getopt.h> #include <sys/socket.h> @@ -51,10 +46,10 @@ # define EXIT_SUCCESS 0 #endif -/* Maximum size of a string from the requesting program. - It must hold enough for any integer, possibly with a sign. */ -#define STRING_SIZE (UINTMAX_STRSIZE_BOUND + 1) +/* 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. */ @@ -67,9 +62,6 @@ static size_t allocated_size; /* Buffer for constructing the reply. */ static char reply_buffer[BUFSIZ]; -/* Obstack for arbitrary-sized strings */ -struct obstack string_stk; - /* Debugging tools. */ static FILE *debug_file; @@ -83,6 +75,25 @@ static FILE *debug_file; #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) { @@ -101,69 +112,22 @@ report_numbered_error (int num) full_write (STDOUT_FILENO, reply_buffer, strlen (reply_buffer)); } -static char * -get_string (void) -{ - for (;;) - { - char c; - if (safe_read (STDIN_FILENO, &c, 1) != 1) - exit (EXIT_SUCCESS); - - if (c == '\n') - break; - - obstack_1grow (&string_stk, c); - } - obstack_1grow (&string_stk, 0); - return obstack_finish (&string_stk); -} - -static void -free_string (char *string) -{ - obstack_free (&string_stk, string); -} - static void -get_string_n (char *string) +get_string (char *string) { - size_t counter; + int counter; for (counter = 0; ; counter++) { if (safe_read (STDIN_FILENO, string + counter, 1) != 1) exit (EXIT_SUCCESS); - if (string[counter] == '\n') + if (string[counter] == '\n' || counter == STRING_SIZE - 1) break; - - if (counter == STRING_SIZE - 1) - report_error_message (N_("Input string too long")); } string[counter] = '\0'; } -static long int -get_long (char const *string) -{ - char *p; - long int n; - errno = 0; - n = strtol (string, &p, 10); - if (errno == ERANGE) - { - report_numbered_error (errno); - exit (EXIT_FAILURE); - } - if (!*string || *p) - { - report_error_message (N_("Number syntax error")); - exit (EXIT_FAILURE); - } - return n; -} - static void prepare_input_buffer (int fd, size_t size) { @@ -239,7 +203,7 @@ decode_oflag (char const *oflag_string) #ifdef O_NOCTTY {"NOCTTY", O_NOCTTY}, #endif -#if O_NONBLOCK +#ifdef O_NONBLOCK {"NONBLOCK", O_NONBLOCK}, #endif {"RDONLY", O_RDONLY}, @@ -283,23 +247,11 @@ static struct option const long_opts[] = {0, 0, 0, 0} }; -/* In-line localization is used only if --help or --version are - locally used. Otherwise, the localization burden lies with tar. */ -static void -i18n_setup () -{ - setlocale (LC_ALL, ""); - bindtextdomain (PACKAGE, LOCALEDIR); - textdomain (PACKAGE); -} - static void usage (int) __attribute__ ((noreturn)); static void usage (int status) { - i18n_setup (); - if (status != EXIT_SUCCESS) fprintf (stderr, _("Try `%s --help' for more information.\n"), program_name); @@ -310,367 +262,316 @@ 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"), + --help Output this help.\n"), program_name); printf (_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT); - close_stdout (); } exit (status); } -static void -respond (long int status) -{ - DEBUG1 ("rmtd: A %ld\n", status); - - sprintf (reply_buffer, "A%ld\n", status); - full_write (STDOUT_FILENO, reply_buffer, strlen (reply_buffer)); -} - - - -static void -open_device (void) +int +main (int argc, char *const *argv) { - char *device_string = get_string (); - char *oflag_string = get_string (); - - DEBUG2 ("rmtd: O %s %s\n", device_string, oflag_string); - - if (tape >= 0) - close (tape); + char command; + size_t status; - tape = open (device_string, decode_oflag (oflag_string), MODE_RW); - if (tape < 0) - report_numbered_error (errno); - else - respond (0); - free_string (device_string); - free_string (oflag_string); -} + /* 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. */ -static void -close_device (void) -{ - free_string (get_string ()); /* discard */ - DEBUG ("rmtd: C\n"); + program_name = argv[0]; + setlocale (LC_ALL, ""); + bindtextdomain (PACKAGE, LOCALEDIR); + textdomain (PACKAGE); - if (close (tape) < 0) - report_numbered_error (errno); - else + switch (getopt_long (argc, argv, "", long_opts, NULL)) { - tape = -1; - respond (0); - } -} - -static void -lseek_device (void) -{ - char count_string[STRING_SIZE]; - char position_string[STRING_SIZE]; - off_t count = 0; - int negative; - int whence; - char *p; - - get_string_n (count_string); - get_string_n (position_string); - DEBUG2 ("rmtd: L %s %s\n", count_string, position_string); + default: + usage (EXIT_FAILURE); - /* Parse count_string, taking care to check for overflow. - We can't use standard functions, - since off_t might be longer than long. */ + case 'h': + usage (EXIT_SUCCESS); - for (p = count_string; *p == ' ' || *p == '\t'; p++) - ; + 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; - negative = *p == '-'; - p += negative || *p == '+'; + case -1: + break; + } - for (; *p; p++) + if (optind < argc) { - int digit = *p - '0'; - if (9 < (unsigned) digit) - { - report_error_message (N_("Seek offset error")); - exit (EXIT_FAILURE); - } - else + if (optind != argc - 1) + usage (EXIT_FAILURE); + debug_file = fopen (argv[optind], "w"); + if (debug_file == 0) { - 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")); - exit (EXIT_FAILURE); - } - count = nc; + report_numbered_error (errno); + return EXIT_FAILURE; } + setbuf (debug_file, 0); } - switch (get_long (position_string)) - { - case 0: - whence = SEEK_SET; - break; +top: + errno = 0; + status = 0; + if (safe_read (STDIN_FILENO, &command, 1) != 1) + return EXIT_SUCCESS; - case 1: - whence = SEEK_CUR; - break; + switch (command) + { + /* FIXME: Maybe 'H' and 'V' for --help and --version output? */ - case 2: - whence = SEEK_END; - break; + case 'O': + { + char device_string[STRING_SIZE]; + char oflag_string[STRING_SIZE]; - default: - report_error_message (N_("Seek direction out of range")); - exit (EXIT_FAILURE); - } + get_string (device_string); + get_string (oflag_string); + DEBUG2 ("rmtd: O %s %s\n", device_string, oflag_string); - count = lseek (tape, count, whence); - if (count < 0) - report_numbered_error (errno); - else - { - /* 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)); - } -} + if (tape >= 0) + close (tape); -static void -write_device (void) -{ - char count_string[STRING_SIZE]; - size_t size; - size_t counter; - size_t status = 0; + tape = open (device_string, decode_oflag (oflag_string), MODE_RW); + if (tape < 0) + goto ioerror; + goto respond; + } - get_string_n (count_string); - size = get_long (count_string); - DEBUG1 ("rmtd: W %s\n", count_string); + case 'C': + { + char device_string[STRING_SIZE]; - 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")); + get_string (device_string); /* discard */ + DEBUG ("rmtd: C\n"); - report_error_message (N_("Premature end of file")); - exit (EXIT_FAILURE); /* exit status used to be 2 */ - } - } - status = full_write (tape, record_buffer, size); - if (status != size) - report_numbered_error (errno); - else - respond (status); -} + if (close (tape) < 0) + goto ioerror; + tape = -1; + goto respond; + } -static void -read_device (void) -{ - char count_string[STRING_SIZE]; - size_t size; - size_t status; + case 'L': + { + char count_string[STRING_SIZE]; + char position_string[STRING_SIZE]; + off_t count = 0; + int negative; + int whence; + char *p; - get_string_n (count_string); - DEBUG1 ("rmtd: R %s\n", count_string); + get_string (count_string); + get_string (position_string); + DEBUG2 ("rmtd: L %s %s\n", count_string, position_string); - size = get_long (count_string); - prepare_input_buffer (-1, size); - status = safe_read (tape, record_buffer, size); - if (status == SAFE_READ_ERROR) - report_numbered_error (errno); - else - { - 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); - } -} + /* Parse count_string, taking care to check for overflow. + We can't use standard functions, + since off_t might be longer than long. */ -static void -mtioctop (void) -{ - char operation_string[STRING_SIZE]; - char count_string[STRING_SIZE]; + for (p = count_string; *p == ' ' || *p == '\t'; p++) + continue; - get_string_n (operation_string); - get_string_n (count_string); - DEBUG2 ("rmtd: I %s %s\n", operation_string, count_string); + negative = *p == '-'; + p += negative || *p == '+'; -#ifdef MTIOCTOP - { - struct mtop mtop; - const char *p; - off_t count = 0; - int negative; + 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; + } + } - /* Parse count_string, taking care to check for overflow. - We can't use standard functions, - since off_t might be longer than long. */ + 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; + } - for (p = count_string; *p == ' ' || *p == '\t'; p++) - ; + case 'W': + { + char count_string[STRING_SIZE]; + size_t size; + size_t counter; - negative = *p == '-'; - p += negative || *p == '+'; + get_string (count_string); + size = atol (count_string); + DEBUG1 ("rmtd: W %s\n", count_string); - for (;;) - { - int digit = *p++ - '0'; - if (9 < (unsigned) digit) - break; - else + prepare_input_buffer (STDIN_FILENO, size); + for (counter = 0; counter < size; counter += status) { - off_t c10 = 10 * count; - off_t nc = negative ? c10 - digit : c10 + digit; - if (c10 / 10 != count - || (negative ? c10 < nc : nc < c10)) + status = safe_read (STDIN_FILENO, &record_buffer[counter], + size - counter); + if (status == SAFE_READ_ERROR || status == 0) { - report_error_message (N_("Seek offset out of range")); - exit (EXIT_FAILURE); + DEBUG (_("rmtd: Premature eof\n")); + + report_error_message (N_("Premature end of file")); + return EXIT_FAILURE; /* exit status used to be 2 */ } - count = nc; } + status = full_write (tape, record_buffer, size); + if (status != size) + goto ioerror; + goto respond; } - mtop.mt_count = count; - if (mtop.mt_count != count) + case 'R': { - report_error_message (N_("Seek offset out of range")); - exit (EXIT_FAILURE); + 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; } - mtop.mt_op = get_long (operation_string); - if (ioctl (tape, MTIOCTOP, (char *) &mtop) < 0) + case 'I': { - report_numbered_error (errno); - return; - } - } -#endif - respond (0); -} + char operation_string[STRING_SIZE]; + char count_string[STRING_SIZE]; -static void -status_device (void) -{ - DEBUG ("rmtd: S\n"); - -#ifdef MTIOCGET - { - struct mtget operation; + get_string (operation_string); + get_string (count_string); + DEBUG2 ("rmtd: I %s %s\n", operation_string, count_string); - if (ioctl (tape, MTIOCGET, (char *) &operation) < 0) - report_numbered_error (errno); - else - { - respond (sizeof operation); - full_write (STDOUT_FILENO, (char *) &operation, sizeof operation); - } - } -#endif -} +#ifdef MTIOCTOP + { + struct mtop mtop; + const char *p; + off_t count = 0; + int negative; -int -main (int argc, char **argv) -{ - char command; + /* Parse count_string, taking care to check for overflow. + We can't use standard functions, + since off_t might be longer than long. */ - program_name = argv[0]; + for (p = count_string; *p == ' ' || *p == '\t'; p++) + continue; - obstack_init (&string_stk); + negative = *p == '-'; + p += negative || *p == '+'; - switch (getopt_long (argc, argv, "", long_opts, NULL)) - { - default: - usage (EXIT_FAILURE); + 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; + } + } - case 'h': - usage (EXIT_SUCCESS); + 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); - case 'v': - i18n_setup (); - version_etc (stdout, "rmt", PACKAGE_NAME, PACKAGE_VERSION, - "John Gilmore", "Jay Fenlason", (char *) NULL); - close_stdout (); - return EXIT_SUCCESS; + if (ioctl (tape, MTIOCTOP, (char *) &mtop) < 0) + goto ioerror; + } +#endif + goto respond; + } - case -1: - break; - } + case 'S': /* status */ + { + DEBUG ("rmtd: S\n"); - if (optind < argc) - { - if (optind != argc - 1) - usage (EXIT_FAILURE); - debug_file = fopen (argv[optind], "w"); - if (debug_file == 0) +#ifdef MTIOCGET { - report_numbered_error (errno); - return EXIT_FAILURE; + 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); } - setbuf (debug_file, 0); +#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 */ } - while (1) - { - errno = 0; +respond: + DEBUG1 ("rmtd: A %ld\n", (long) status); - if (safe_read (STDIN_FILENO, &command, 1) != 1) - return EXIT_SUCCESS; + sprintf (reply_buffer, "A%ld\n", (long) status); + full_write (STDOUT_FILENO, reply_buffer, strlen (reply_buffer)); + goto top; - switch (command) - { - case 'O': - open_device (); - break; - - case 'C': - close_device (); - break; - - case 'L': - lseek_device (); - break; - - case 'W': - write_device (); - break; - - case 'R': - read_device (); - break; - - case 'I': - mtioctop (); - break; - - case 'S': - status_device (); - break; - - default: - DEBUG1 ("rmtd: Garbage command %c\n", command); - report_error_message (N_("Garbage command")); - return EXIT_FAILURE; /* exit status used to be 3 */ - } - } +ioerror: + report_numbered_error (errno); + goto top; } |