summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid E. O'Brien <obrien@FreeBSD.org>1997-03-29 22:40:46 +0000
committerDavid E. O'Brien <obrien@FreeBSD.org>1997-03-29 22:40:46 +0000
commite7fc40c22fe83484c200f11d3ee417d1b9c1cff7 (patch)
tree465c4207a9b3bcfa3a659c6a9f8833e478a4896f
parent67adaf175dbce89d27e081e055e126b0bb6d19cf (diff)
Notes
-rw-r--r--contrib/cpio/COPYING (renamed from gnu/usr.bin/cpio/COPYING)0
-rw-r--r--contrib/cpio/COPYING.LIB (renamed from gnu/usr.bin/cpio/COPYING.LIB)2
-rw-r--r--contrib/cpio/ChangeLog (renamed from gnu/usr.bin/cpio/ChangeLog)187
-rw-r--r--contrib/cpio/NEWS (renamed from gnu/usr.bin/cpio/NEWS)9
-rw-r--r--contrib/cpio/README (renamed from gnu/usr.bin/cpio/README)0
-rw-r--r--contrib/cpio/alloca.c (renamed from gnu/usr.bin/cpio/alloca.c)30
-rw-r--r--contrib/cpio/copyin.c (renamed from gnu/usr.bin/cpio/copyin.c)200
-rw-r--r--contrib/cpio/copyout.c (renamed from gnu/usr.bin/cpio/copyout.c)78
-rw-r--r--contrib/cpio/copypass.c (renamed from gnu/usr.bin/cpio/copypass.c)39
-rw-r--r--contrib/cpio/cpio.1 (renamed from gnu/usr.bin/cpio/cpio.1)52
-rw-r--r--contrib/cpio/cpio.h (renamed from gnu/usr.bin/cpio/cpio.h)0
-rw-r--r--contrib/cpio/cpiohdr.h (renamed from gnu/usr.bin/cpio/cpiohdr.h)0
-rw-r--r--contrib/cpio/defer.c (renamed from gnu/usr.bin/cpio/defer.c)0
-rw-r--r--contrib/cpio/defer.h (renamed from gnu/usr.bin/cpio/defer.h)0
-rw-r--r--contrib/cpio/dirname.c (renamed from gnu/usr.bin/cpio/dirname.c)14
-rw-r--r--contrib/cpio/dstring.c (renamed from gnu/usr.bin/cpio/dstring.c)0
-rw-r--r--contrib/cpio/dstring.h (renamed from gnu/usr.bin/cpio/dstring.h)0
-rw-r--r--contrib/cpio/error.c (renamed from gnu/usr.bin/cpio/error.c)110
-rw-r--r--contrib/cpio/extern.h (renamed from gnu/usr.bin/cpio/extern.h)34
-rw-r--r--contrib/cpio/filemode.c (renamed from gnu/usr.bin/cpio/filemode.c)74
-rw-r--r--contrib/cpio/filetypes.h (renamed from gnu/usr.bin/cpio/filetypes.h)0
-rw-r--r--contrib/cpio/getopt.c (renamed from gnu/usr.bin/cpio/getopt.c)259
-rw-r--r--contrib/cpio/getopt.h (renamed from gnu/usr.bin/cpio/getopt.h)12
-rw-r--r--contrib/cpio/getopt1.c (renamed from gnu/usr.bin/cpio/getopt1.c)10
-rw-r--r--contrib/cpio/global.c (renamed from gnu/usr.bin/cpio/global.c)31
-rw-r--r--contrib/cpio/idcache.c (renamed from gnu/usr.bin/cpio/idcache.c)6
-rw-r--r--contrib/cpio/main.c (renamed from gnu/usr.bin/cpio/main.c)80
-rw-r--r--contrib/cpio/makepath.c (renamed from gnu/usr.bin/cpio/makepath.c)22
-rw-r--r--contrib/cpio/rmt.h (renamed from gnu/usr.bin/cpio/rmt.h)0
-rw-r--r--contrib/cpio/rtapelib.c (renamed from gnu/usr.bin/cpio/rtapelib.c)0
-rw-r--r--contrib/cpio/safe-stat.h1
-rw-r--r--contrib/cpio/stripslash.c (renamed from gnu/usr.bin/cpio/stripslash.c)4
-rw-r--r--contrib/cpio/system.h (renamed from gnu/usr.bin/cpio/system.h)5
-rw-r--r--contrib/cpio/tar.c (renamed from gnu/usr.bin/cpio/tar.c)8
-rw-r--r--contrib/cpio/tar.h (renamed from gnu/usr.bin/cpio/tar.h)0
-rw-r--r--contrib/cpio/tarhdr.h (renamed from gnu/usr.bin/cpio/tarhdr.h)0
-rw-r--r--contrib/cpio/tcexparg.c (renamed from gnu/usr.bin/cpio/tcexparg.c)0
-rw-r--r--contrib/cpio/userspec.c277
-rw-r--r--contrib/cpio/util.c (renamed from gnu/usr.bin/cpio/util.c)495
-rw-r--r--contrib/cpio/version.c (renamed from gnu/usr.bin/cpio/version.c)2
-rw-r--r--contrib/cpio/xmalloc.c103
-rw-r--r--contrib/cpio/xstrdup.c (renamed from gnu/usr.bin/cpio/xstrdup.c)4
-rw-r--r--gnu/usr.bin/cpio/userspec.c180
-rw-r--r--gnu/usr.bin/cpio/xmalloc.c65
44 files changed, 1648 insertions, 745 deletions
diff --git a/gnu/usr.bin/cpio/COPYING b/contrib/cpio/COPYING
index a43ea2126fb6..a43ea2126fb6 100644
--- a/gnu/usr.bin/cpio/COPYING
+++ b/contrib/cpio/COPYING
diff --git a/gnu/usr.bin/cpio/COPYING.LIB b/contrib/cpio/COPYING.LIB
index eb685a5ec981..bbe3fe198789 100644
--- a/gnu/usr.bin/cpio/COPYING.LIB
+++ b/contrib/cpio/COPYING.LIB
@@ -133,7 +133,7 @@ such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
-
+
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
diff --git a/gnu/usr.bin/cpio/ChangeLog b/contrib/cpio/ChangeLog
index 9b18d4f61bba..eaf14a9f8dfa 100644
--- a/gnu/usr.bin/cpio/ChangeLog
+++ b/contrib/cpio/ChangeLog
@@ -1,3 +1,190 @@
+Tue Jan 16 19:03:05 1996 John Oleynick (juo@wombat.gnu.ai.mit.edu)
+ * util.c: An I/O error reading a file would cause the last byte
+ of the next file to be corrupted in the archive. Thanks to a
+ buggy NT NFS server for pointing out this problem.
+ * Version 2.4.2 released.
+
+Tue Jan 9 23:19:37 1996 John Oleynick (juo@wombat.gnu.ai.mit.edu)
+ * copyout.c: missed 1 part of last bug fix.
+
+Mon Jan 8 16:49:01 1996 John Oleynick (juo@wombat.gnu.ai.mit.edu)
+ * copyout.c, copypass.c: Use result of readlink() as length
+ of link name instead of size from lstat(). On some OS's lstat()
+ doesn't return the true length in size. Bug reported by
+ Robert Joop (rj@rainbow.IN-berlin.DE).
+
+Wed Dec 20 10:52:56 1995 John Oleynick (juo@wombat.gnu.ai.mit.edu)
+ * rmt.c: Added temporary kludge so make rmt will work on Linux.
+ * configure.in: Only define HAVE_UTIME_H if utime.h declares
+ struct utimbuf.
+ * Makefile.in: Change prefix, exec_prefix and bindir to get their
+ values from configure. Added cpio.info to DISTFILES.
+ * cpio.texi: Added INFO-DIR-ENTRY.
+ * Version 2.4.1 released.
+
+Wed Nov 22 19:37:05 1995 John Oleynick (juo@wombat.gnu.ai.mit.edu)
+ * cpio.texi: Updated release date and FSF's address.
+ * NEWS: Listed major new features for 2.4.
+ * mt.c, mt.1: Added seek and fsfm commands.
+ * Version 2.4 released.
+
+Tue Jun 27 19:14:27 1995 John Oleynick (juo@wombat.gnu.ai.mit.edu)
+ * configure.in: fixed for new autoconf. Added check to make
+ sure fnmatch() works.
+ * Makefile.in: changed realclean to maintainer-clean. Added
+ support to handle fnmatch separate from other LIBOBJS.
+ * cpio.texi: More changes for 2.4.
+
+Wed Dec 14 16:14:27 1994 John Oleynick (juo@wombat.gnu.ai.mit.edu)
+ * copypass.h: When given the -a option, set the access time of
+ the copy to be the access time of the original (instead of the
+ modification time of the original). Reported by
+ karney@pppl.gov (Charles Karney).
+ * cpio.texi: Updated with changes for 2.4.
+
+Wed Nov 3 18:18:07 1994 John Oleynick (juo@wombat.gnu.ai.mit.edu)
+ * safe-stat.h, Makefile.in: New file used by mkdir.c. This will go
+ away when we get the real safe-xstat.[ch]in for mkdir.c.
+ * main.c: Don't mention [--null] twice in -p's usage message.
+ Changed --no-absolute-paths to --no-absolute-filenames.
+ * cpio.1: Updated man page with new features.
+ * cpio.texi, texinfo.tex, Makefile.in: Added texi documentation
+ from Robert Carleton (rbc@gnu.ai.mit.edu).
+
+Mon Oct 3 00:46:30 1994 John Oleynick (juo@wombat.gnu.ai.mit.edu)
+ * makefile.pc, system.h: Changes to compile with Borland C++ 4.0.
+
+Thu Sep 29 22:15:50 1994 John Oleynick (juo@wombat.gnu.ai.mit.edu)
+ * makepath.c: Don't #define index if it is already #defined.
+
+ * mt.c: Check for __hpux defined instead of __hpux__. Reported
+ by ericb@lsid.hp.com (Eric Backus).
+
+Thu Sep 29 11:21:31 1994 John Oleynick (juo@wombat.gnu.ai.mit.edu)
+ * extern.h, util.c, copyout.c, copypass.c, main.c, global.c:
+ Never mind --ignore-disk-input-errors flag, we'll just always
+ do that, like tar.
+
+ * global.c, extern.h, main.c, copyin.c, copyout.c, copypass.c:
+ Added --quiet flag to supress printing number of blocks copied.
+
+ * global.c, extern.h: If compiled with gcc, make input_bytes
+ and output_bytes `long long' instead of `long'. We need more
+ than 32 bits to keep track of the number of bytes copied to
+ and from tape drives that hold more than 4Gbytes.
+
+ * util.c, copyin.c, main.c, global.c, extern.h: Added
+ --only-verify-crc flag to read a CRC format archive and verify
+ its contents' CRCs.
+
+ * copyout.c: Fixed problem with creating oldc format archives
+ on machines with 16 bit ints. Reported by mpoole@cix.compulink.co.uk
+ (Martin Poole).
+
+ * mt.c: Need to open tape WR_ONLY for erase command (and probably
+ others?). Reported by robert@hst.e.technik.uni-kl.de (Robert
+ Vogelgesan). Accept `eject' as a synonym for `offline'. Accept
+ `-t' as a synonym for `-f' (to be compatible with HPUX mt, which
+ only accepts `-t').
+
+Wed Sep 28 12:01:55 1994 John Oleynick (juo@wombat.gnu.ai.mit.edu)
+ * extern.h, global.c, main.c, util.c: only write sparse files
+ when given --sparse flag.
+ * extern.h, util.c, copyout.c, copypass.c, main.c, global.c:
+ Added support for --ignore-disk-input-errors flag.
+
+Wed Aug 24 12:55:38 1994 David J. MacKenzie (djm@churchy.gnu.ai.mit.edu)
+
+ * configure.in: Replace calls to AC_REMOTE_TAPE and AC_RSH
+ with equivalent code, since those macros are going away.
+
+Sun Feb 13 00:56:48 1994 John Oleynick (juo@goldman.gnu.ai.mit.edu)
+ * extern.h, global.c, main.c, util.c: Added code to
+ tape_buffered_peek() to properly handle large, corrutped
+ archives, without overrunning the allocated buffer and
+ dumping core. Also changed the way the input and output
+ buffers are allocated in initialize_buffers().
+
+Tue Jan 25 01:04:32 1994 John Oleynick (juo@goldman.gnu.ai.mit.edu)
+ * copyin.c, copyout.c, copypass.c, extern.h, main.c, tar.c, util.c:
+ Redid i/o buffer code. Previously, the same routines buffered input and
+ output for accessing the archive and the filesystem. Now there are
+ separate routines for buffering input and output and for buffering the
+ archive and the filesystem. This simplifies much of the buffer code
+ (e.g., only input from the archive has to check for end of tape and
+ allow the tape to be changed, only output to the filesystem has to
+ handle byte and word swapping, etc.; previously one routine had to
+ handle all of these special cases) This is how the routines got split
+ and renamed (old name -> new name):
+
+ clear_rest_of_block -> tape_clear_rest_of_block
+ copy_files -> copy_files_tape_to_disk
+ " -> copy_files_disk_to_disk
+ " -> copy_files_disk_to_tape
+ copy_buf_out -> disk_buffered_write
+ " -> tape_buffered_write
+ copy_in_buf -> tape_buffered_read
+ empty_output_buffer -> tape_empty_output_buffer
+ " -> disk_empty_output_buffer
+ fill_input_buffer -> tape_fill_input_buffer
+ " -> disk_fill_input_buffer
+ pad_output -> tape_pad_output
+ peek_in_buf -> tape_buffered_peek
+ skip_padding -> tape_skip_padding
+ toss_input -> tape_toss_input
+
+ * extern.h, global.c, main.c, util.c: Added support for
+ writing sparse files.
+
+Tue Dec 28 23:01:36 1993 John Oleynick (juo@goldman.gnu.ai.mit.edu)
+ * util.c, system.h, makepath.c, extern.h: don't define chown()
+ and don't typedef uid_t and gid_t if we are being compiled
+ by DJGPP.
+
+ * copyin.c, extern.h, global.c, main.c: Added support for
+ --rename-batch-file.
+
+ * copyin.c, copyout.c, extern.h: Cleaned up to pass gcc -Wall.
+
+Wed Dec 22 02:17:44 1993 John Oleynick (juo@goldman.gnu.ai.mit.edu)
+
+ * makepath.c, copypass.c, copyin.c: If cpio was creating a
+ directory that contained `.' in the pathname (e.g. `foo/./bar'),
+ it would complain that it could not create `.', since it already
+ exists. From schwab@issan.informatik.uni-dortmund.de (Andreas
+ Schwab).
+
+ * mt.c: Added "eject" as a synonym for "offline".
+
+ * util.c: Slight modification to when we lseek with
+ BROKEN_LONG_TAPE_DRIVER (do it every 1Gb, instead
+ of every 2Gb).
+
+ * copyin.c, global.c, extern.h: Added --no-absolute-paths option,
+ to ignore absolute paths in archives.
+
+Tue Dec 21 01:30:59 1993 John Oleynick (juo@goldman.gnu.ai.mit.edu)
+
+ * util.c: Fix for copying new_media_message_after_number. From
+ Christian.Kuehnke@arbi.informatik.uni-oldenburg.de (Christian
+ Kuehnke).
+
+Thu Jul 29 20:35:57 1993 David J. MacKenzie (djm@wookumz.gnu.ai.mit.edu)
+
+ * Makefile.in (config.status): Run config.status --recheck, not
+ configure, to get the right args passed.
+
+Mon Jul 19 23:01:00 1993 David J. MacKenzie (djm@churchy.gnu.ai.mit.edu)
+
+ * Makefile.in (libdir): Use standard GNU value --
+ $(exec_prefix)/lib, not /etc.
+ (.c.o): Put CFLAGS last.
+
+Thu Jul 8 19:43:39 1993 David J. MacKenzie (djm@goldman.gnu.ai.mit.edu)
+
+ * Makefile.in: Add rules for remaking Makefile, configure,
+ config.status.
+
Mon Jul 5 14:54:08 1993 John Oleynick (juo@spiff.gnu.ai.mit.edu)
* cpio.1: Updated man page for 2.3.
diff --git a/gnu/usr.bin/cpio/NEWS b/contrib/cpio/NEWS
index 2648c843f955..5da98da8d83a 100644
--- a/gnu/usr.bin/cpio/NEWS
+++ b/contrib/cpio/NEWS
@@ -1,4 +1,13 @@
+Major changes in version 2.4:
+
+* new texinfo documentation
+* --sparse option to write sparse files
+* --only-verify-crc option to verify a CRC format archive
+* --no-absolute-paths option to ignore absolute paths
+* --quiet option to supress printing number of blocks copied
+* handle disk input errors more gracefully
+
Major changes in version 2.3:
* in newc and crc format archives, only store 1 copy of multiply linked files
diff --git a/gnu/usr.bin/cpio/README b/contrib/cpio/README
index 8206e9731537..8206e9731537 100644
--- a/gnu/usr.bin/cpio/README
+++ b/contrib/cpio/README
diff --git a/gnu/usr.bin/cpio/alloca.c b/contrib/cpio/alloca.c
index c04c0efebdb5..7061cec2d314 100644
--- a/gnu/usr.bin/cpio/alloca.c
+++ b/contrib/cpio/alloca.c
@@ -22,10 +22,18 @@
your main control loop, etc. to force garbage collection. */
#ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
#endif
-/* If compiling with GCC, this file's not needed. */
+#ifdef emacs
+#include "blockinput.h"
+#endif
+
+/* If compiling with GCC 2, this file's not needed. */
+#if !defined (__GNUC__) || __GNUC__ < 2
+
+/* If someone has defined alloca as a macro,
+ there must be some other way alloca is supposed to work. */
#ifndef alloca
#ifdef emacs
@@ -45,7 +53,7 @@ lose
/* If your stack is a linked list of frames, you have to
provide an "address metric" ADDRESS_FUNCTION macro. */
-#ifdef CRAY
+#if defined (CRAY) && defined (CRAY_STACKSEG_END)
long i00afunc ();
#define ADDRESS_FUNCTION(arg) (char *) i00afunc (&(arg))
#else
@@ -72,8 +80,8 @@ typedef char *pointer;
#ifndef emacs
#define malloc xmalloc
-extern pointer xmalloc ();
#endif
+extern pointer malloc ();
/* Define STACK_DIRECTION if you know the direction of stack
growth for your system; otherwise it will be automatically
@@ -168,6 +176,10 @@ alloca (size)
{
register header *hp; /* Traverses linked list. */
+#ifdef emacs
+ BLOCK_INPUT;
+#endif
+
for (hp = last_alloca_header; hp != NULL;)
if ((STACK_DIR > 0 && hp->h.deep > depth)
|| (STACK_DIR < 0 && hp->h.deep < depth))
@@ -182,6 +194,10 @@ alloca (size)
break; /* Rest are not deeper. */
last_alloca_header = hp; /* -> last valid storage. */
+
+#ifdef emacs
+ UNBLOCK_INPUT;
+#endif
}
if (size == 0)
@@ -193,6 +209,9 @@ alloca (size)
register pointer new = malloc (sizeof (header) + size);
/* Address of header. */
+ if (new == 0)
+ abort();
+
((header *) new)->h.next = last_alloca_header;
((header *) new)->h.deep = depth;
@@ -204,7 +223,7 @@ alloca (size)
}
}
-#ifdef CRAY
+#if defined (CRAY) && defined (CRAY_STACKSEG_END)
#ifdef DEBUG_I00AFUNC
#include <stdio.h>
@@ -473,3 +492,4 @@ i00afunc (long address)
#endif /* CRAY */
#endif /* no alloca */
+#endif /* not GCC version 2 */
diff --git a/gnu/usr.bin/cpio/copyin.c b/contrib/cpio/copyin.c
index 5196c5d67956..1cc7e4791242 100644
--- a/gnu/usr.bin/cpio/copyin.c
+++ b/contrib/cpio/copyin.c
@@ -34,7 +34,7 @@
#endif
static void read_pattern_file ();
-static void skip_padding ();
+static void tape_skip_padding ();
static void defer_copyin ();
static void create_defered_links ();
static void create_final_defers ();
@@ -62,7 +62,7 @@ read_in_header (file_hdr, in_des)
while (archive_format == arf_unknown)
{
- peeked_bytes = peek_in_buf (tmpbuf, in_des, 512);
+ peeked_bytes = tape_buffered_peek (tmpbuf, in_des, 512);
if (peeked_bytes < 6)
error (1, 0, "premature end of archive");
@@ -88,7 +88,7 @@ read_in_header (file_hdr, in_des)
}
else
{
- copy_in_buf ((char *) tmpbuf, in_des, 1L);
+ tape_buffered_read ((char *) tmpbuf, in_des, 1L);
++bytes_skipped;
}
}
@@ -107,7 +107,7 @@ read_in_header (file_hdr, in_des)
file_hdr->c_tar_linkname = NULL;
- copy_in_buf ((char *) file_hdr, in_des, 6L);
+ tape_buffered_read ((char *) file_hdr, in_des, 6L);
while (1)
{
if (append_flag)
@@ -149,7 +149,7 @@ read_in_header (file_hdr, in_des)
}
bytes_skipped++;
bcopy ((char *) file_hdr + 1, (char *) file_hdr, 5);
- copy_in_buf ((char *) file_hdr + 5, in_des, 1L);
+ tape_buffered_read ((char *) file_hdr + 5, in_des, 1L);
}
}
@@ -166,7 +166,7 @@ read_in_old_ascii (file_hdr, in_des)
unsigned long dev;
unsigned long rdev;
- copy_in_buf (ascii_header, in_des, 70L);
+ tape_buffered_read (ascii_header, in_des, 70L);
ascii_header[70] = '\0';
sscanf (ascii_header,
"%6lo%6lo%6lo%6lo%6lo%6lo%6lo%11lo%6lo%11lo",
@@ -183,7 +183,7 @@ read_in_old_ascii (file_hdr, in_des)
if (file_hdr->c_name != NULL)
free (file_hdr->c_name);
file_hdr->c_name = (char *) xmalloc (file_hdr->c_namesize + 1);
- copy_in_buf (file_hdr->c_name, in_des, (long) file_hdr->c_namesize);
+ tape_buffered_read (file_hdr->c_name, in_des, (long) file_hdr->c_namesize);
#ifndef __MSDOS__
/* HP/UX cpio creates archives that look just like ordinary archives,
but for devices it sets major = 0, minor = 1, and puts the
@@ -227,7 +227,7 @@ read_in_new_ascii (file_hdr, in_des)
{
char ascii_header[112];
- copy_in_buf (ascii_header, in_des, 104L);
+ tape_buffered_read (ascii_header, in_des, 104L);
ascii_header[104] = '\0';
sscanf (ascii_header,
"%8lx%8lx%8lx%8lx%8lx%8lx%8lx%8lx%8lx%8lx%8lx%8lx%8lx",
@@ -240,12 +240,12 @@ read_in_new_ascii (file_hdr, in_des)
if (file_hdr->c_name != NULL)
free (file_hdr->c_name);
file_hdr->c_name = (char *) xmalloc (file_hdr->c_namesize);
- copy_in_buf (file_hdr->c_name, in_des, (long) file_hdr->c_namesize);
+ tape_buffered_read (file_hdr->c_name, in_des, (long) file_hdr->c_namesize);
/* In SVR4 ASCII format, the amount of space allocated for the header
is rounded up to the next long-word, so we might need to drop
1-3 bytes. */
- skip_padding (in_des, file_hdr->c_namesize + 110);
+ tape_skip_padding (in_des, file_hdr->c_namesize + 110);
}
/* Fill in FILE_HDR by reading a binary format cpio header from
@@ -263,7 +263,7 @@ read_in_binary (file_hdr, in_des)
it into the argument long header. */
short_hdr.c_dev = ((struct old_cpio_header *) file_hdr)->c_dev;
short_hdr.c_ino = ((struct old_cpio_header *) file_hdr)->c_ino;
- copy_in_buf (((char *) &short_hdr) + 6, in_des, 20L);
+ tape_buffered_read (((char *) &short_hdr) + 6, in_des, 20L);
/* If the magic number is byte swapped, fix the header. */
if (file_hdr->c_magic == swab_short ((unsigned short) 070707))
@@ -300,13 +300,13 @@ read_in_binary (file_hdr, in_des)
if (file_hdr->c_name != NULL)
free (file_hdr->c_name);
file_hdr->c_name = (char *) xmalloc (file_hdr->c_namesize);
- copy_in_buf (file_hdr->c_name, in_des, (long) file_hdr->c_namesize);
+ tape_buffered_read (file_hdr->c_name, in_des, (long) file_hdr->c_namesize);
/* In binary mode, the amount of space allocated in the header for
the filename is `c_namesize' rounded up to the next short-word,
so we might need to drop a byte. */
if (file_hdr->c_namesize % 2)
- toss_input (in_des, 1L);
+ tape_toss_input (in_des, 1L);
#ifndef __MSDOS__
/* HP/UX cpio creates archives that look just like ordinary archives,
@@ -374,6 +374,7 @@ process_copy_in ()
dynamic_string new_name; /* New file name for rename option. */
FILE *tty_in; /* Interactive file for rename option. */
FILE *tty_out; /* Interactive file for rename option. */
+ FILE *rename_in; /* Batch file for rename option. */
char *str_res; /* Result for string function. */
struct utimbuf times; /* For setting file times. */
struct stat file_stat; /* Output file stat record. */
@@ -397,9 +398,15 @@ process_copy_in ()
/* Initialize this in case it has members we don't know to set. */
bzero (&times, sizeof (struct utimbuf));
- /* Open interactive file pair for rename operation. */
- if (rename_flag)
+ if (rename_batch_file)
{
+ rename_in = fopen (rename_batch_file, "r");
+ if (rename_in == NULL)
+ error (2, errno, CONSOLE);
+ }
+ else if (rename_flag)
+ {
+ /* Open interactive file pair for rename operation. */
tty_in = fopen (CONSOLE, "r");
if (tty_in == NULL)
error (2, errno, CONSOLE);
@@ -472,6 +479,30 @@ process_copy_in ()
break;
}
+ /* Do we have to ignore absolute paths, and if so, does the filename
+ have an absolute path? */
+ if (no_abs_paths_flag && file_hdr.c_name && file_hdr.c_name [0] == '/')
+ {
+ char *p;
+
+ p = file_hdr.c_name;
+ while (*p == '/')
+ ++p;
+ if (*p == '\0')
+ {
+ strcpy (file_hdr.c_name, ".");
+ }
+ else
+ {
+ char *non_abs_name;
+
+ non_abs_name = (char *) xmalloc (strlen (p) + 1);
+ strcpy (non_abs_name, p);
+ free (file_hdr.c_name);
+ file_hdr.c_name = non_abs_name;
+ }
+ }
+
/* Does the file name match one of the given patterns? */
if (num_patterns <= 0)
skip_file = FALSE;
@@ -488,8 +519,8 @@ process_copy_in ()
if (skip_file)
{
- toss_input (in_file_des, file_hdr.c_filesize);
- skip_padding (in_file_des, file_hdr.c_filesize);
+ tape_toss_input (in_file_des, file_hdr.c_filesize);
+ tape_skip_padding (in_file_des, file_hdr.c_filesize);
}
else if (table_flag)
{
@@ -502,10 +533,10 @@ process_copy_in ()
{
link_name = (char *) xmalloc ((unsigned int) file_hdr.c_filesize + 1);
link_name[file_hdr.c_filesize] = '\0';
- copy_in_buf (link_name, in_file_des, file_hdr.c_filesize);
+ tape_buffered_read (link_name, in_file_des, file_hdr.c_filesize);
long_format (&file_hdr, link_name);
free (link_name);
- skip_padding (in_file_des, file_hdr.c_filesize);
+ tape_skip_padding (in_file_des, file_hdr.c_filesize);
continue;
}
else
@@ -521,28 +552,66 @@ process_copy_in ()
else
printf ("%s\n", file_hdr.c_name);
- toss_input (in_file_des, file_hdr.c_filesize);
- skip_padding (in_file_des, file_hdr.c_filesize);
+ crc = 0;
+ tape_toss_input (in_file_des, file_hdr.c_filesize);
+ tape_skip_padding (in_file_des, file_hdr.c_filesize);
+ if (only_verify_crc_flag)
+ {
+#ifdef CP_IFLNK
+ if ((file_hdr.c_mode & CP_IFMT) == CP_IFLNK)
+ continue; /* links don't have a checksum */
+#endif
+ if (crc != file_hdr.c_chksum)
+ error (0, 0, "%s: checksum error (0x%x, should be 0x%x)",
+ file_hdr.c_name, crc, file_hdr.c_chksum);
+ }
}
else if (append_flag)
{
- toss_input (in_file_des, file_hdr.c_filesize);
- skip_padding (in_file_des, file_hdr.c_filesize);
+ tape_toss_input (in_file_des, file_hdr.c_filesize);
+ tape_skip_padding (in_file_des, file_hdr.c_filesize);
+ }
+ else if (only_verify_crc_flag)
+ {
+#ifdef CP_IFLNK
+ if ((file_hdr.c_mode & CP_IFMT) == CP_IFLNK)
+ {
+ if (archive_format != arf_tar && archive_format != arf_ustar)
+ {
+ tape_toss_input (in_file_des, file_hdr.c_filesize);
+ tape_skip_padding (in_file_des, file_hdr.c_filesize);
+ continue;
+ }
+ }
+#endif
+ crc = 0;
+ tape_toss_input (in_file_des, file_hdr.c_filesize);
+ tape_skip_padding (in_file_des, file_hdr.c_filesize);
+ if (crc != file_hdr.c_chksum)
+ error (0, 0, "%s: checksum error (0x%x, should be 0x%x)",
+ file_hdr.c_name, crc, file_hdr.c_chksum);
}
else
{
/* Copy the input file into the directory structure. */
/* Do we need to rename the file? */
- if (rename_flag)
+ if (rename_flag || rename_batch_file)
{
- fprintf (tty_out, "rename %s -> ", file_hdr.c_name);
- fflush (tty_out);
- str_res = ds_fgets (tty_in, &new_name);
+ if (rename_flag)
+ {
+ fprintf (tty_out, "rename %s -> ", file_hdr.c_name);
+ fflush (tty_out);
+ str_res = ds_fgets (tty_in, &new_name);
+ }
+ else
+ {
+ str_res = ds_fgetstr (rename_in, &new_name, '\n');
+ }
if (str_res == NULL || str_res[0] == 0)
{
- toss_input (in_file_des, file_hdr.c_filesize);
- skip_padding (in_file_des, file_hdr.c_filesize);
+ tape_toss_input (in_file_des, file_hdr.c_filesize);
+ tape_skip_padding (in_file_des, file_hdr.c_filesize);
continue;
}
else
@@ -566,8 +635,8 @@ process_copy_in ()
{
error (0, 0, "%s not created: newer or same age version exists",
file_hdr.c_name);
- toss_input (in_file_des, file_hdr.c_filesize);
- skip_padding (in_file_des, file_hdr.c_filesize);
+ tape_toss_input (in_file_des, file_hdr.c_filesize);
+ tape_skip_padding (in_file_des, file_hdr.c_filesize);
continue; /* Go to the next file. */
}
else if (S_ISDIR (file_stat.st_mode)
@@ -576,8 +645,8 @@ process_copy_in ()
{
error (0, errno, "cannot remove current %s",
file_hdr.c_name);
- toss_input (in_file_des, file_hdr.c_filesize);
- skip_padding (in_file_des, file_hdr.c_filesize);
+ tape_toss_input (in_file_des, file_hdr.c_filesize);
+ tape_skip_padding (in_file_des, file_hdr.c_filesize);
continue; /* Go to the next file. */
}
}
@@ -608,8 +677,8 @@ process_copy_in ()
running as root), but there's nothing we can do about
that. */
defer_copyin (&file_hdr);
- toss_input (in_file_des, file_hdr.c_filesize);
- skip_padding (in_file_des, file_hdr.c_filesize);
+ tape_toss_input (in_file_des, file_hdr.c_filesize);
+ tape_skip_padding (in_file_des, file_hdr.c_filesize);
break;
}
/* If the file has data (filesize != 0), then presumably
@@ -622,8 +691,8 @@ process_copy_in ()
file_hdr.c_ino);
if (link_res == 0)
{
- toss_input (in_file_des, file_hdr.c_filesize);
- skip_padding (in_file_des, file_hdr.c_filesize);
+ tape_toss_input (in_file_des, file_hdr.c_filesize);
+ tape_skip_padding (in_file_des, file_hdr.c_filesize);
break;
}
}
@@ -636,8 +705,8 @@ process_copy_in ()
file_hdr.c_ino);
if (link_res == 0)
{
- toss_input (in_file_des, file_hdr.c_filesize);
- skip_padding (in_file_des, file_hdr.c_filesize);
+ tape_toss_input (in_file_des, file_hdr.c_filesize);
+ tape_skip_padding (in_file_des, file_hdr.c_filesize);
break;
}
}
@@ -672,8 +741,8 @@ process_copy_in ()
if (out_file_des < 0)
{
error (0, errno, "%s", file_hdr.c_name);
- toss_input (in_file_des, file_hdr.c_filesize);
- skip_padding (in_file_des, file_hdr.c_filesize);
+ tape_toss_input (in_file_des, file_hdr.c_filesize);
+ tape_skip_padding (in_file_des, file_hdr.c_filesize);
continue;
}
@@ -694,8 +763,8 @@ process_copy_in ()
error (0, 0, "cannot swap bytes of %s: odd number of bytes",
file_hdr.c_name);
}
- copy_files (in_file_des, out_file_des, file_hdr.c_filesize);
- empty_output_buffer (out_file_des);
+ copy_files_tape_to_disk (in_file_des, out_file_des, file_hdr.c_filesize);
+ disk_empty_output_buffer (out_file_des);
if (close (out_file_des) < 0)
error (0, errno, "%s", file_hdr.c_name);
@@ -721,7 +790,7 @@ process_copy_in ()
if (utime (file_hdr.c_name, &times) < 0)
error (0, errno, "%s", file_hdr.c_name);
}
- skip_padding (in_file_des, file_hdr.c_filesize);
+ tape_skip_padding (in_file_des, file_hdr.c_filesize);
if (file_hdr.c_nlink > 1 && (archive_format == arf_newascii
|| archive_format == arf_crcascii) )
{
@@ -776,8 +845,18 @@ process_copy_in ()
}
if (res < 0)
{
- error (0, errno, "%s", file_hdr.c_name);
- continue;
+ /* In some odd cases where the file_hdr.c_name includes `.',
+ the directory may have actually been created by
+ create_all_directories(), so the mkdir will fail
+ because the directory exists. If that's the case,
+ don't complain about it. */
+ if ( (errno != EEXIST) ||
+ (lstat (file_hdr.c_name, &file_stat) != 0) ||
+ !(S_ISDIR (file_stat.st_mode) ) )
+ {
+ error (0, errno, "%s", file_hdr.c_name);
+ continue;
+ }
}
if (!no_chown_flag)
if ((chown (file_hdr.c_name,
@@ -880,8 +959,8 @@ process_copy_in ()
{
link_name = (char *) xmalloc ((unsigned int) file_hdr.c_filesize + 1);
link_name[file_hdr.c_filesize] = '\0';
- copy_in_buf (link_name, in_file_des, file_hdr.c_filesize);
- skip_padding (in_file_des, file_hdr.c_filesize);
+ tape_buffered_read (link_name, in_file_des, file_hdr.c_filesize);
+ tape_skip_padding (in_file_des, file_hdr.c_filesize);
}
else
{
@@ -917,8 +996,8 @@ process_copy_in ()
default:
error (0, 0, "%s: unknown file type", file_hdr.c_name);
- toss_input (in_file_des, file_hdr.c_filesize);
- skip_padding (in_file_des, file_hdr.c_filesize);
+ tape_toss_input (in_file_des, file_hdr.c_filesize);
+ tape_skip_padding (in_file_des, file_hdr.c_filesize);
}
if (verbose_flag)
@@ -936,11 +1015,14 @@ process_copy_in ()
if (archive_format == arf_newascii || archive_format == arf_crcascii)
create_final_defers ();
- res = (input_bytes + io_block_size - 1) / io_block_size;
- if (res == 1)
- fprintf (stderr, "1 block\n");
- else
- fprintf (stderr, "%d blocks\n", res);
+ if (!quiet_flag)
+ {
+ res = (input_bytes + io_block_size - 1) / io_block_size;
+ if (res == 1)
+ fprintf (stderr, "1 block\n");
+ else
+ fprintf (stderr, "%d blocks\n", res);
+ }
}
/* Print the file described by FILE_HDR in long format.
@@ -1008,7 +1090,7 @@ print_name_with_quoting (p)
{
register unsigned char c;
- while (c = *p++)
+ while ( (c = *p++) )
{
switch (c)
{
@@ -1114,7 +1196,7 @@ read_pattern_file ()
header type. */
static void
-skip_padding (in_file_des, offset)
+tape_skip_padding (in_file_des, offset)
int in_file_des;
int offset;
{
@@ -1130,7 +1212,7 @@ skip_padding (in_file_des, offset)
pad = 0;
if (pad != 0)
- toss_input (in_file_des, pad);
+ tape_toss_input (in_file_des, pad);
}
@@ -1216,8 +1298,6 @@ static void
create_final_defers ()
{
struct deferment *d;
- struct deferment *d_prev;
- struct new_cpio_header *h;
int link_res;
int out_file_des;
struct utimbuf times; /* For setting file times. */
diff --git a/gnu/usr.bin/cpio/copyout.c b/contrib/cpio/copyout.c
index f763f2b7ca9e..22e9a0ce08ad 100644
--- a/gnu/usr.bin/cpio/copyout.c
+++ b/contrib/cpio/copyout.c
@@ -27,8 +27,8 @@
#include "rmt.h"
static unsigned long read_for_checksum ();
-static void clear_rest_of_block ();
-static void pad_output ();
+static void tape_clear_rest_of_block ();
+static void tape_pad_output ();
static int last_link ();
static int count_defered_links_to_dev_ino ();
static void add_link_defer ();
@@ -61,11 +61,11 @@ write_out_header (file_hdr, out_des)
file_hdr->c_filesize, file_hdr->c_dev_maj, file_hdr->c_dev_min,
file_hdr->c_rdev_maj, file_hdr->c_rdev_min, file_hdr->c_namesize,
file_hdr->c_chksum);
- copy_buf_out (ascii_header, out_des, 110L);
+ tape_buffered_write (ascii_header, out_des, 110L);
/* Write file name to output. */
- copy_buf_out (file_hdr->c_name, out_des, (long) file_hdr->c_namesize);
- pad_output (out_des, file_hdr->c_namesize + 110);
+ tape_buffered_write (file_hdr->c_name, out_des, (long) file_hdr->c_namesize);
+ tape_pad_output (out_des, file_hdr->c_namesize + 110);
}
else if (archive_format == arf_oldascii || archive_format == arf_hpoldascii)
{
@@ -112,17 +112,17 @@ write_out_header (file_hdr, out_des)
error (0, 0, "%s: truncating inode number", file_hdr->c_name);
sprintf (ascii_header,
- "%06lo%06lo%06lo%06lo%06lo%06lo%06lo%06lo%011lo%06lo%011lo",
+ "%06o%06o%06lo%06lo%06lo%06lo%06lo%06o%011lo%06lo%011lo",
file_hdr->c_magic & 0xFFFF, dev & 0xFFFF,
file_hdr->c_ino & 0xFFFF, file_hdr->c_mode & 0xFFFF,
file_hdr->c_uid & 0xFFFF, file_hdr->c_gid & 0xFFFF,
file_hdr->c_nlink & 0xFFFF, rdev & 0xFFFF,
file_hdr->c_mtime, file_hdr->c_namesize & 0xFFFF,
file_hdr->c_filesize);
- copy_buf_out (ascii_header, out_des, 76L);
+ tape_buffered_write (ascii_header, out_des, 76L);
/* Write file name to output. */
- copy_buf_out (file_hdr->c_name, out_des, (long) file_hdr->c_namesize);
+ tape_buffered_write (file_hdr->c_name, out_des, (long) file_hdr->c_namesize);
}
else if (archive_format == arf_tar || archive_format == arf_ustar)
{
@@ -179,12 +179,12 @@ write_out_header (file_hdr, out_des)
short_hdr.c_filesizes[1] = file_hdr->c_filesize & 0xFFFF;
/* Output the file header. */
- copy_buf_out ((char *) &short_hdr, out_des, 26L);
+ tape_buffered_write ((char *) &short_hdr, out_des, 26L);
/* Write file name to output. */
- copy_buf_out (file_hdr->c_name, out_des, (long) file_hdr->c_namesize);
+ tape_buffered_write (file_hdr->c_name, out_des, (long) file_hdr->c_namesize);
- pad_output (out_des, file_hdr->c_namesize + 26);
+ tape_pad_output (out_des, file_hdr->c_namesize + 26);
}
}
@@ -383,7 +383,7 @@ process_copy_out ()
input_name.ds_string);
write_out_header (&file_hdr, out_file_des);
- copy_files (in_file_des, out_file_des, file_hdr.c_filesize);
+ copy_files_disk_to_tape (in_file_des, out_file_des, file_hdr.c_filesize, input_name.ds_string);
#ifndef __MSDOS__
if (archive_format == arf_tar || archive_format == arf_ustar)
@@ -391,7 +391,7 @@ process_copy_out ()
file_hdr.c_dev_min);
#endif
- pad_output (out_file_des, file_hdr.c_filesize);
+ tape_pad_output (out_file_des, file_hdr.c_filesize);
if (close (in_file_des) < 0)
error (0, errno, "%s", input_name.ds_string);
@@ -451,24 +451,27 @@ process_copy_out ()
case CP_IFLNK:
{
char *link_name = (char *) xmalloc (file_stat.st_size + 1);
+ int link_size;
- if (readlink (input_name.ds_string, link_name,
- file_stat.st_size) < 0)
+ link_size = readlink (input_name.ds_string, link_name,
+ file_stat.st_size);
+ if (link_size < 0)
{
error (0, errno, "%s", input_name.ds_string);
free (link_name);
continue;
}
+ file_hdr.c_filesize = link_size;
if (archive_format == arf_tar || archive_format == arf_ustar)
{
- if (file_stat.st_size + 1 > 100)
+ if (link_size + 1 > 100)
{
error (0, 0, "%s: symbolic link too long",
file_hdr.c_name);
}
else
{
- link_name[file_stat.st_size] = '\0';
+ link_name[link_size] = '\0';
file_hdr.c_tar_linkname = link_name;
write_out_header (&file_hdr, out_file_des);
}
@@ -476,8 +479,8 @@ process_copy_out ()
else
{
write_out_header (&file_hdr, out_file_des);
- copy_buf_out (link_name, out_file_des, file_stat.st_size);
- pad_output (out_file_des, file_hdr.c_filesize);
+ tape_buffered_write (link_name, out_file_des, link_size);
+ tape_pad_output (out_file_des, link_size);
}
free (link_name);
}
@@ -516,20 +519,23 @@ process_copy_out ()
write_out_header (&file_hdr, out_file_des);
else
{
- copy_buf_out (zeros_512, out_file_des, 512);
- copy_buf_out (zeros_512, out_file_des, 512);
+ tape_buffered_write (zeros_512, out_file_des, 512);
+ tape_buffered_write (zeros_512, out_file_des, 512);
}
/* Fill up the output block. */
- clear_rest_of_block (out_file_des);
- empty_output_buffer (out_file_des);
+ tape_clear_rest_of_block (out_file_des);
+ tape_empty_output_buffer (out_file_des);
if (dot_flag)
fputc ('\n', stderr);
- res = (output_bytes + io_block_size - 1) / io_block_size;
- if (res == 1)
- fprintf (stderr, "1 block\n");
- else
- fprintf (stderr, "%d blocks\n", res);
+ if (!quiet_flag)
+ {
+ res = (output_bytes + io_block_size - 1) / io_block_size;
+ if (res == 1)
+ fprintf (stderr, "1 block\n");
+ else
+ fprintf (stderr, "%d blocks\n", res);
+ }
}
/* Read FILE_SIZE bytes of FILE_NAME from IN_FILE_DES and
@@ -569,15 +575,15 @@ read_for_checksum (in_file_des, file_size, file_name)
OUT_FILE_DES. */
static void
-clear_rest_of_block (out_file_des)
+tape_clear_rest_of_block (out_file_des)
int out_file_des;
{
while (output_size < io_block_size)
{
if ((io_block_size - output_size) > 512)
- copy_buf_out (zeros_512, out_file_des, 512);
+ tape_buffered_write (zeros_512, out_file_des, 512);
else
- copy_buf_out (zeros_512, out_file_des, io_block_size - output_size);
+ tape_buffered_write (zeros_512, out_file_des, io_block_size - output_size);
}
}
@@ -585,7 +591,7 @@ clear_rest_of_block (out_file_des)
to the end of the header. */
static void
-pad_output (out_file_des, offset)
+tape_pad_output (out_file_des, offset)
int out_file_des;
int offset;
{
@@ -601,7 +607,7 @@ pad_output (out_file_des, offset)
pad = 0;
if (pad != 0)
- copy_buf_out (zeros_512, out_file_des, pad);
+ tape_buffered_write (zeros_512, out_file_des, pad);
}
@@ -686,7 +692,6 @@ writeout_other_defers (file_hdr, out_des)
int ino;
int maj;
int min;
- int count;
ino = file_hdr->c_ino;
maj = file_hdr->c_dev_maj;
min = file_hdr->c_dev_min;
@@ -754,6 +759,7 @@ writeout_final_defers(out_des)
static void
writeout_defered_file (header, out_file_des)
struct new_cpio_header *header;
+ int out_file_des;
{
int in_file_des;
struct new_cpio_header file_hdr;
@@ -778,7 +784,7 @@ writeout_defered_file (header, out_file_des)
header->c_name);
write_out_header (&file_hdr, out_file_des);
- copy_files (in_file_des, out_file_des, file_hdr.c_filesize);
+ copy_files_disk_to_tape (in_file_des, out_file_des, file_hdr.c_filesize, header->c_name);
#ifndef __MSDOS__
if (archive_format == arf_tar || archive_format == arf_ustar)
@@ -786,7 +792,7 @@ writeout_defered_file (header, out_file_des)
file_hdr.c_dev_min);
#endif
- pad_output (out_file_des, file_hdr.c_filesize);
+ tape_pad_output (out_file_des, file_hdr.c_filesize);
if (close (in_file_des) < 0)
error (0, errno, "%s", header->c_name);
diff --git a/gnu/usr.bin/cpio/copypass.c b/contrib/cpio/copypass.c
index afd5753ecaa4..dde43d587ef6 100644
--- a/gnu/usr.bin/cpio/copypass.c
+++ b/contrib/cpio/copypass.c
@@ -169,8 +169,8 @@ process_copy_pass ()
continue;
}
- copy_files (in_file_des, out_file_des, in_file_stat.st_size);
- empty_output_buffer (out_file_des);
+ copy_files_disk_to_disk (in_file_des, out_file_des, in_file_stat.st_size, input_name.ds_string);
+ disk_empty_output_buffer (out_file_des);
if (close (in_file_des) < 0)
error (0, errno, "%s", input_name.ds_string);
if (close (out_file_des) < 0)
@@ -235,8 +235,18 @@ process_copy_pass ()
}
if (res < 0)
{
- error (0, errno, "%s", output_name.ds_string);
- continue;
+ /* In some odd cases where the output_name includes `.',
+ the directory may have actually been created by
+ create_all_directories(), so the mkdir will fail
+ because the directory exists. If that's the case,
+ don't complain about it. */
+ if ( (errno != EEXIST) ||
+ (lstat (output_name.ds_string, &out_file_stat) != 0) ||
+ !(S_ISDIR (out_file_stat.st_mode) ) )
+ {
+ error (0, errno, "%s", output_name.ds_string);
+ continue;
+ }
}
if (!no_chown_flag)
if ((chown (output_name.ds_string,
@@ -321,16 +331,18 @@ process_copy_pass ()
else if (S_ISLNK (in_file_stat.st_mode))
{
char *link_name;
+ int link_size;
link_name = (char *) xmalloc ((unsigned int) in_file_stat.st_size + 1);
- if (readlink (input_name.ds_string, link_name,
- in_file_stat.st_size) < 0)
+ link_size = readlink (input_name.ds_string, link_name,
+ in_file_stat.st_size);
+ if (link_size < 0)
{
error (0, errno, "%s", input_name.ds_string);
free (link_name);
continue;
}
- link_name[in_file_stat.st_size] = '\0';
+ link_name[link_size] = '\0';
res = UMASKED_SYMLINK (link_name, output_name.ds_string,
in_file_stat.st_mode);
@@ -370,11 +382,14 @@ process_copy_pass ()
if (dot_flag)
fputc ('\n', stderr);
- res = (output_bytes + io_block_size - 1) / io_block_size;
- if (res == 1)
- fprintf (stderr, "1 block\n");
- else
- fprintf (stderr, "%d blocks\n", res);
+ if (!quiet_flag)
+ {
+ res = (output_bytes + io_block_size - 1) / io_block_size;
+ if (res == 1)
+ fprintf (stderr, "1 block\n");
+ else
+ fprintf (stderr, "%d blocks\n", res);
+ }
}
/* Try and create a hard link from FILE_NAME to another file
diff --git a/gnu/usr.bin/cpio/cpio.1 b/contrib/cpio/cpio.1
index 7ef74c41c15a..055476612086 100644
--- a/gnu/usr.bin/cpio/cpio.1
+++ b/contrib/cpio/cpio.1
@@ -7,8 +7,8 @@ cpio \- copy files to and from archives
[\-O [[user@]host:]archive] [\-F [[user@]host:]archive]
[\-\-file=[[user@]host:]archive] [\-\-format=format] [\-\-message=message]
[\-\-null] [\-\-reset-access-time] [\-\-verbose] [\-\-dot] [\-\-append]
-[\-\-block-size=blocks] [\-\-dereference] [\-\-io-size=bytes]
-[\-\-help] [\-\-version] < name-list [> archive]
+[\-\-block-size=blocks] [\-\-dereference] [\-\-io-size=bytes] [\-\-quiet]
+[\-\-force\-local] [\-\-help] [\-\-version] < name-list [> archive]
.B cpio
{\-i|\-\-extract} [\-bcdfmnrtsuvBSV] [\-C bytes] [\-E file] [\-H format]
@@ -19,14 +19,15 @@ cpio \- copy files to and from archives
[\-\-unconditional] [\-\-verbose] [\-\-block-size=blocks] [\-\-swap-halfwords]
[\-\-io-size=bytes] [\-\-pattern-file=file] [\-\-format=format]
[\-\-owner=[user][:.][group]] [\-\-no-preserve-owner] [\-\-message=message]
-[\-\-help] [\-\-version] [pattern...] [< archive]
+[\-\-force\-local] [\-\-no\-absolute\-filenames] [\-\-sparse] [\-\-only\-verify\-crc]
+[\-\-quiet] [\-\-help] [\-\-version] [pattern...] [< archive]
.B cpio
{\-p|\-\-pass-through} [\-0adlmuvLV] [\-R [user][:.][group]]
-[\-\-null] [\-\-reset-access-time] [\-\-make-directories] [\-\-link]
+[\-\-null] [\-\-reset-access-time] [\-\-make-directories] [\-\-link] [\-\-quiet]
[\-\-preserve-modification-time] [\-\-unconditional] [\-\-verbose] [\-\-dot]
[\-\-dereference] [\-\-owner=[user][:.][group]] [\-\-no-preserve-owner]
-[\-\-help] [\-\-version] destination-directory < name-list
+[\-\-sparse] [\-\-help] [\-\-version] destination-directory < name-list
.SH DESCRIPTION
This manual page
documents the GNU version of
@@ -34,7 +35,7 @@ documents the GNU version of
.B cpio
copies files into or out of a cpio or tar archive, which is a file that
contains other files plus information about them, such as their
-pathname, owner, timestamps, and access permissions. The archive can
+file name, owner, timestamps, and access permissions. The archive can
be another file on the disk, a magnetic tape, or a pipe.
.B cpio
has three operating modes.
@@ -248,6 +249,10 @@ current volume number (starting at 1).
In the verbose table of contents listing, show numeric UID and GID
instead of translating them into names.
.TP
+.I " \-\-no-absolute-filenames"
+In copy-in mode, create all files relative to the current directory,
+even if they have an absolute file name in the archive.
+.TP
.I " \-\-no-preserve-owner"
In copy-in mode and copy-pass mode, do not change the ownership of the
files; leave them owned by the user extracting them. This is the
@@ -258,29 +263,40 @@ inadvertantly give away files.
Run in copy-out mode.
.TP
.I "\-O archive"
-Archive filename to use instead of standard output. To use a
-tape drive on another machine as the archive, use a filename that
-starts with `HOSTNAME:'. The hostname can be preceded by a
-username and an `@' to access the remote tape drive as that user, if
-you have permission to do so (typically an entry in that user's
-`~/.rhosts' file).
+Archive filename to use instead of standard output. To use a tape
+drive on another machine as the archive, use a filename that starts
+with `HOSTNAME:'. The hostname can be preceded by a username and an
+`@' to access the remote tape drive as that user, if you have
+permission to do so (typically an entry in that user's `~/.rhosts'
+file).
+.TP
+.I " \-\-only-verify-crc"
+When reading a CRC format archive in copy-in mode, only verify the
+CRC's of each file in the archive, don't actually extract the files.
.TP
.I "\-p, \-\-pass-through"
Run in copy-pass mode.
.TP
+.I "\-\-quiet"
+Do not print the number of blocks copied.
+.TP
.I "\-r, \-\-rename"
Interactively rename files.
.TP
.I "\-R [user][:.][group], \-\-owner [user][:.][group]"
-In copy-out and copy-pass modes, set the ownership of all files
-created to the specified user and/or group. Either the user or the
-group, or both, must be present. If the group is omitted but the ":"
-or "." separator is given, use the given user's login group. Only the
+In copy-out and copy-pass modes, set the ownership of all files created
+to the specified user and/or group. Either the user or the group, or
+both, must be present. If the group is omitted but the ":" or "."
+separator is given, use the given user's login group. Only the
super-user can change files' ownership.
.TP
+.I "\-\-sparse"
+In copy-out and copy-pass modes, write files with large blocks of zeros
+as sparse files.
+.TP
.I "\-s, \-\-swap-bytes"
-In copy-in mode, swap the bytes of each halfword (pair of bytes) in
-the files.
+In copy-in mode, swap the bytes of each halfword (pair of bytes) in the
+files.
.TP
.I "\-S, \-\-swap-halfwords"
In copy-in mode, swap the halfwords of each word (4 bytes) in the
diff --git a/gnu/usr.bin/cpio/cpio.h b/contrib/cpio/cpio.h
index 537da72120f5..537da72120f5 100644
--- a/gnu/usr.bin/cpio/cpio.h
+++ b/contrib/cpio/cpio.h
diff --git a/gnu/usr.bin/cpio/cpiohdr.h b/contrib/cpio/cpiohdr.h
index 9694af69baec..9694af69baec 100644
--- a/gnu/usr.bin/cpio/cpiohdr.h
+++ b/contrib/cpio/cpiohdr.h
diff --git a/gnu/usr.bin/cpio/defer.c b/contrib/cpio/defer.c
index efe60e0dd118..efe60e0dd118 100644
--- a/gnu/usr.bin/cpio/defer.c
+++ b/contrib/cpio/defer.c
diff --git a/gnu/usr.bin/cpio/defer.h b/contrib/cpio/defer.h
index 89abffec03c8..89abffec03c8 100644
--- a/gnu/usr.bin/cpio/defer.h
+++ b/contrib/cpio/defer.h
diff --git a/gnu/usr.bin/cpio/dirname.c b/contrib/cpio/dirname.c
index 5a92ce557ff6..15d25967afe8 100644
--- a/gnu/usr.bin/cpio/dirname.c
+++ b/contrib/cpio/dirname.c
@@ -15,6 +15,10 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
#ifdef STDC_HEADERS
#include <stdlib.h>
#else
@@ -22,11 +26,11 @@ char *malloc ();
#endif
#if defined(STDC_HEADERS) || defined(HAVE_STRING_H)
#include <string.h>
-#ifndef rindex
-#define rindex strrchr
-#endif
#else
#include <strings.h>
+#ifndef strrchr
+#define strrchr rindex
+#endif
#endif
/* Return the leading directories part of PATH,
@@ -42,7 +46,7 @@ dirname (path)
char *slash;
int length; /* Length of result, not including NUL. */
- slash = rindex (path, '/');
+ slash = strrchr (path, '/');
if (slash == 0)
{
/* File is in the current directory. */
@@ -57,7 +61,7 @@ dirname (path)
length = slash - path + 1;
}
- newpath = malloc (length + 1);
+ newpath = (char *) malloc (length + 1);
if (newpath == 0)
return 0;
strncpy (newpath, path, length);
diff --git a/gnu/usr.bin/cpio/dstring.c b/contrib/cpio/dstring.c
index 26d6bbcc1dcf..26d6bbcc1dcf 100644
--- a/gnu/usr.bin/cpio/dstring.c
+++ b/contrib/cpio/dstring.c
diff --git a/gnu/usr.bin/cpio/dstring.h b/contrib/cpio/dstring.h
index 369da0bcbe7a..369da0bcbe7a 100644
--- a/gnu/usr.bin/cpio/dstring.h
+++ b/contrib/cpio/dstring.h
diff --git a/gnu/usr.bin/cpio/error.c b/contrib/cpio/error.c
index e849c5b2fb1a..a36198b6b6e8 100644
--- a/gnu/usr.bin/cpio/error.c
+++ b/contrib/cpio/error.c
@@ -1,5 +1,5 @@
/* error.c -- error handler for noninteractive utilities
- Copyright (C) 1990, 1991, 1992 Free Software Foundation, Inc.
+ Copyright (C) 1990, 91, 92, 93, 94, 95 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
@@ -15,42 +15,55 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-/* Written by David MacKenzie. */
+/* Written by David MacKenzie <djm@gnu.ai.mit.edu>. */
-#include <stdio.h>
-
-#ifdef HAVE_VPRINTF
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
-#if __STDC__
-#include <stdarg.h>
-#define VA_START(args, lastarg) va_start(args, lastarg)
-#else /* !__STDC__ */
-#include <varargs.h>
-#define VA_START(args, lastarg) va_start(args)
-#endif /* !__STDC__ */
+#include <stdio.h>
-#else /* !HAVE_VPRINTF */
+#if HAVE_VPRINTF || HAVE_DOPRNT || _LIBC
+# if __STDC__
+# include <stdarg.h>
+# define VA_START(args, lastarg) va_start(args, lastarg)
+# else
+# include <varargs.h>
+# define VA_START(args, lastarg) va_start(args)
+# endif
+#else
+# define va_alist a1, a2, a3, a4, a5, a6, a7, a8
+# define va_dcl char *a1, *a2, *a3, *a4, *a5, *a6, *a7, *a8;
+#endif
+
+#if STDC_HEADERS || _LIBC
+# include <stdlib.h>
+# include <string.h>
+#else
+void exit ();
+#endif
-#ifdef HAVE_DOPRNT
-#define va_alist args
-#define va_dcl int args;
-#else /* !HAVE_DOPRNT */
-#define va_alist a1, a2, a3, a4, a5, a6, a7, a8
-#define va_dcl char *a1, *a2, *a3, *a4, *a5, *a6, *a7, *a8;
-#endif /* !HAVE_DOPRNT */
+/* This variable is incremented each time `error' is called. */
+unsigned int error_message_count;
-#endif /* !HAVE_VPRINTF */
+/* If NULL, error will flush stdout, then print on stderr the program
+ name, a colon and a space. Otherwise, error will call this
+ function without parameters instead. */
+void (*error_print_progname) () = NULL;
-#ifdef STDC_HEADERS
-#include <stdlib.h>
-#include <string.h>
-#else /* !STDC_HEADERS */
-void exit ();
-#endif /* !STDC_HEADERS */
+#ifdef _LIBC
+#define program_name program_invocation_name
+#endif
+/* The calling program should define program_name and set it to the
+ name of the executing program. */
extern char *program_name;
-#ifndef HAVE_STRERROR
+#if HAVE_STRERROR || _LIBC
+# ifndef strerror /* On some systems, strerror is a macro */
+char *strerror ();
+# endif
+#else
static char *
private_strerror (errnum)
int errnum;
@@ -63,40 +76,51 @@ private_strerror (errnum)
return "Unknown system error";
}
#define strerror private_strerror
-#endif /* !HAVE_STRERROR */
+#endif
/* Print the program name and error message MESSAGE, which is a printf-style
format string with optional args.
If ERRNUM is nonzero, print its corresponding system error message.
Exit with status STATUS if it is nonzero. */
/* VARARGS */
+
void
-#if defined (HAVE_VPRINTF) && __STDC__
-error (int status, int errnum, char *message, ...)
-#else /* !HAVE_VPRINTF or !__STDC__ */
+#if defined(VA_START) && __STDC__
+error (int status, int errnum, const char *message, ...)
+#else
error (status, errnum, message, va_alist)
int status;
int errnum;
char *message;
va_dcl
-#endif /* !HAVE_VPRINTF or !__STDC__ */
+#endif
{
-#ifdef HAVE_VPRINTF
+#ifdef VA_START
va_list args;
-#endif /* HAVE_VPRINTF */
+#endif
+
+ if (error_print_progname)
+ (*error_print_progname) ();
+ else
+ {
+ fflush (stdout);
+ fprintf (stderr, "%s: ", program_name);
+ }
- fprintf (stderr, "%s: ", program_name);
-#ifdef HAVE_VPRINTF
+#ifdef VA_START
VA_START (args, message);
+# if HAVE_VPRINTF || _LIBC
vfprintf (stderr, message, args);
+# else
+ _doprnt (message, args, stderr);
+# endif
va_end (args);
-#else /* !HAVE_VPRINTF */
-#ifdef HAVE_DOPRNT
- _doprnt (message, &args, stderr);
-#else /* !HAVE_DOPRNT */
+#else
fprintf (stderr, message, a1, a2, a3, a4, a5, a6, a7, a8);
-#endif /* !HAVE_DOPRNT */
-#endif /* !HAVE_VPRINTF */
+#endif
+
+ ++error_message_count;
+
if (errnum)
fprintf (stderr, ": %s", strerror (errnum));
putc ('\n', stderr);
diff --git a/gnu/usr.bin/cpio/extern.h b/contrib/cpio/extern.h
index 50b152cdd92c..3ff70cc00a01 100644
--- a/gnu/usr.bin/cpio/extern.h
+++ b/contrib/cpio/extern.h
@@ -25,6 +25,7 @@ extern int reset_time_flag;
extern int io_block_size;
extern int create_dir_flag;
extern int rename_flag;
+extern char *rename_batch_file;
extern int table_flag;
extern int unconditional_flag;
extern int verbose_flag;
@@ -42,6 +43,11 @@ extern uid_t set_owner;
extern int set_group_flag;
extern gid_t set_group;
extern int no_chown_flag;
+extern int sparse_flag;
+extern int quiet_flag;
+extern int only_verify_crc_flag;
+extern int no_abs_paths_flag;
+
extern int last_header_start;
extern int copy_matching_files;
extern int numeric_uid;
@@ -58,8 +64,13 @@ extern int debug_flag;
extern char *input_buffer, *output_buffer;
extern char *in_buff, *out_buff;
+extern long input_buffer_size;
extern long input_size, output_size;
+#ifdef __GNUC__
+extern long long input_bytes, output_bytes;
+#else
extern long input_bytes, output_bytes;
+#endif
extern char zeros_512[];
extern char *directory_name;
extern char **save_patterns;
@@ -96,6 +107,9 @@ void process_copy_out P_((void));
/* copypass.c */
void process_copy_pass P_((void));
+int link_to_maj_min_ino P_((char *file_name, int st_dev_maj,
+ int st_dev_min, int st_ino));
+int link_to_name P_((char *link_name, char *link_target));
/* dirname.c */
char *dirname P_((char *path));
@@ -140,14 +154,16 @@ char *parse_user_spec P_((char *name, uid_t *uid, gid_t *gid,
#endif
/* util.c */
-void empty_output_buffer P_((int out_des));
+void tape_empty_output_buffer P_((int out_des));
+void disk_empty_output_buffer P_((int out_des));
void swahw_array P_((char *ptr, int count));
-void fill_input_buffer P_((int in_des, int num_bytes));
-void copy_buf_out P_((char *in_buf, int out_des, long num_bytes));
-void copy_in_buf P_((char *in_buf, int in_des, long num_bytes));
-int peek_in_buf P_((char *peek_buf, int in_des, int num_bytes));
-void toss_input P_((int in_des, long num_bytes));
-void copy_files P_((int in_des, int out_des, long num_bytes));
+void tape_buffered_write P_((char *in_buf, int out_des, long num_bytes));
+void tape_buffered_read P_((char *in_buf, int in_des, long num_bytes));
+int tape_buffered_peek P_((char *peek_buf, int in_des, int num_bytes));
+void tape_toss_input P_((int in_des, long num_bytes));
+void copy_files_tape_to_disk P_((int in_des, int out_des, long num_bytes));
+void copy_files_disk_to_tape P_((int in_des, int out_des, long num_bytes, char *filename));
+void copy_files_disk_to_disk P_((int in_des, int out_des, long num_bytes, char *filename));
void create_all_directories P_((char *name));
void prepare_append P_((int out_file_des));
char *find_inode_file P_((unsigned long node_num,
@@ -158,7 +174,7 @@ int open_archive P_((char *file));
void tape_offline P_((int tape_des));
void get_next_reel P_((int tape_des));
void set_new_media_message P_((char *message));
-#ifdef __MSDOS__
+#if defined(__MSDOS__) && !defined(__GNUC__)
int chown P_((char *path, int owner, int group));
#endif
#ifdef __TURBOC__
@@ -174,3 +190,5 @@ char *xrealloc P_((char *p, unsigned n));
/* xstrdup.c */
char *xstrdup P_((char *string));
+
+#define DISK_IO_BLOCK_SIZE (512)
diff --git a/gnu/usr.bin/cpio/filemode.c b/contrib/cpio/filemode.c
index 9293af681501..20c65c4b06e2 100644
--- a/gnu/usr.bin/cpio/filemode.c
+++ b/contrib/cpio/filemode.c
@@ -1,5 +1,5 @@
/* filemode.c -- make a string describing file modes
- Copyright (C) 1985, 1990 Free Software Foundation, Inc.
+ Copyright (C) 1985, 1990, 1993 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
@@ -16,43 +16,69 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
-#ifndef S_IREAD
-#define S_IREAD S_IRUSR
-#define S_IWRITE S_IWUSR
-#define S_IEXEC S_IXUSR
-#endif
-
-#if !defined(S_ISREG) || defined(NO_MODE_T)
-/* Doesn't have POSIX.1 stat stuff or doesn't have mode_t. */
-#define mode_t unsigned short
-#endif
+#if !S_IRUSR
+# if S_IREAD
+# define S_IRUSR S_IREAD
+# else
+# define S_IRUSR 00400
+# endif
+#endif
+
+#if !S_IWUSR
+# if S_IWRITE
+# define S_IWUSR S_IWRITE
+# else
+# define S_IWUSR 00200
+# endif
+#endif
+
+#if !S_IXUSR
+# if S_IEXEC
+# define S_IXUSR S_IEXEC
+# else
+# define S_IXUSR 00100
+# endif
+#endif
+
+#ifdef STAT_MACROS_BROKEN
+#undef S_ISBLK
+#undef S_ISCHR
+#undef S_ISDIR
+#undef S_ISFIFO
+#undef S_ISLNK
+#undef S_ISMPB
+#undef S_ISMPC
+#undef S_ISNWK
+#undef S_ISREG
+#undef S_ISSOCK
+#endif /* STAT_MACROS_BROKEN. */
#if !defined(S_ISBLK) && defined(S_IFBLK)
-#define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
+#define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
#endif
#if !defined(S_ISCHR) && defined(S_IFCHR)
-#define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
+#define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
#endif
#if !defined(S_ISDIR) && defined(S_IFDIR)
-#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
+#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
#endif
#if !defined(S_ISREG) && defined(S_IFREG)
-#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
+#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
#endif
#if !defined(S_ISFIFO) && defined(S_IFIFO)
-#define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
+#define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
#endif
#if !defined(S_ISLNK) && defined(S_IFLNK)
-#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
+#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
#endif
#if !defined(S_ISSOCK) && defined(S_IFSOCK)
-#define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
+#define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
#endif
#if !defined(S_ISMPB) && defined(S_IFMPB) /* V7 */
#define S_ISMPB(m) (((m) & S_IFMT) == S_IFMPB)
@@ -119,7 +145,7 @@ mode_string (mode, str)
unsigned short mode;
char *str;
{
- str[0] = ftypelet (mode);
+ str[0] = ftypelet ((long) mode);
rwx ((mode & 0700) << 0, &str[1]);
rwx ((mode & 0070) << 3, &str[4]);
rwx ((mode & 0007) << 6, &str[7]);
@@ -140,7 +166,7 @@ mode_string (mode, str)
static char
ftypelet (bits)
- mode_t bits;
+ long bits;
{
#ifdef S_ISBLK
if (S_ISBLK (bits))
@@ -183,9 +209,9 @@ rwx (bits, chars)
unsigned short bits;
char *chars;
{
- chars[0] = (bits & S_IREAD) ? 'r' : '-';
- chars[1] = (bits & S_IWRITE) ? 'w' : '-';
- chars[2] = (bits & S_IEXEC) ? 'x' : '-';
+ chars[0] = (bits & S_IRUSR) ? 'r' : '-';
+ chars[1] = (bits & S_IWUSR) ? 'w' : '-';
+ chars[2] = (bits & S_IXUSR) ? 'x' : '-';
}
/* Set the 's' and 't' flags in file attributes string CHARS,
diff --git a/gnu/usr.bin/cpio/filetypes.h b/contrib/cpio/filetypes.h
index 46a79a9c3b4a..46a79a9c3b4a 100644
--- a/gnu/usr.bin/cpio/filetypes.h
+++ b/contrib/cpio/filetypes.h
diff --git a/gnu/usr.bin/cpio/getopt.c b/contrib/cpio/getopt.c
index 2867a90f65e2..beb7450dd9ce 100644
--- a/gnu/usr.bin/cpio/getopt.c
+++ b/contrib/cpio/getopt.c
@@ -3,7 +3,7 @@
"Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu
before changing it!
- Copyright (C) 1987, 88, 89, 90, 91, 92, 1993
+ Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94, 95
Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify it
@@ -20,17 +20,22 @@
along with this program; if not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.
+ Ditto for AIX 3.2 and <stdlib.h>. */
+#ifndef _NO_PROTO
+#define _NO_PROTO
+#endif
+
#ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
#endif
-#if !__STDC__ && !defined(const) && IN_GCC
+#if !defined (__STDC__) || !__STDC__
+/* This is a separate conditional since some stdc systems
+ reject `defined (const)'. */
+#ifndef const
#define const
#endif
-
-/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>. */
-#ifndef _NO_PROTO
-#define _NO_PROTO
#endif
#include <stdio.h>
@@ -54,10 +59,16 @@
#include <stdlib.h>
#endif /* GNU C library. */
-/* If GETOPT_COMPAT is defined, `+' as well as `--' can introduce a
- long-named option. Because this is not POSIX.2 compliant, it is
- being phased out. */
-/* #define GETOPT_COMPAT */
+#ifndef _
+/* This is for other GNU distributions with internationalized messages.
+ When compiling libc, the _ macro is predefined. */
+#ifdef HAVE_LIBINTL_H
+# include <libintl.h>
+# define _(msgid) gettext (msgid)
+#else
+# define _(msgid) (msgid)
+#endif
+#endif
/* This version of `getopt' appears to the caller like standard Unix `getopt'
but it behaves differently for the user, since it allows the user
@@ -81,7 +92,7 @@
Also, when `ordering' is RETURN_IN_ORDER,
each non-option ARGV-element is returned here. */
-char *optarg = 0;
+char *optarg = NULL;
/* Index in ARGV of the next element to be scanned.
This is used for communication to and from the caller
@@ -151,6 +162,9 @@ static enum
{
REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
} ordering;
+
+/* Value of POSIXLY_CORRECT environment variable. */
+static char *posixly_correct;
#ifdef __GNU_LIBRARY__
/* We want to avoid inclusion of string.h with non-GNU libraries
@@ -183,15 +197,16 @@ my_index (str, chr)
/* If using GCC, we can safely declare strlen this way.
If not using GCC, it is ok not to declare it. */
#ifdef __GNUC__
-#ifdef IN_GCC
-#include "gstddef.h"
-#else
-#include <stddef.h>
-#endif
-extern size_t strlen (const char *);
-#endif
-
-#endif /* GNU C library. */
+/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h.
+ That was relevant to code that was here before. */
+#if !defined (__STDC__) || !__STDC__
+/* gcc with -traditional declares the built-in strlen to return int,
+ and has done so at least since version 2.4.5. -- rms. */
+extern int strlen (const char *);
+#endif /* not __STDC__ */
+#endif /* __GNUC__ */
+
+#endif /* not __GNU_LIBRARY__ */
/* Handle permutation of arguments. */
@@ -266,6 +281,42 @@ exchange (argv)
first_nonopt += (optind - last_nonopt);
last_nonopt = optind;
}
+
+/* Initialize the internal data when the first call is made. */
+
+static const char *
+_getopt_initialize (optstring)
+ const char *optstring;
+{
+ /* Start processing options with ARGV-element 1 (since ARGV-element 0
+ is the program name); the sequence of previously skipped
+ non-option ARGV-elements is empty. */
+
+ first_nonopt = last_nonopt = optind = 1;
+
+ nextchar = NULL;
+
+ posixly_correct = getenv ("POSIXLY_CORRECT");
+
+ /* Determine how to handle the ordering of options and nonoptions. */
+
+ if (optstring[0] == '-')
+ {
+ ordering = RETURN_IN_ORDER;
+ ++optstring;
+ }
+ else if (optstring[0] == '+')
+ {
+ ordering = REQUIRE_ORDER;
+ ++optstring;
+ }
+ else if (posixly_correct != NULL)
+ ordering = REQUIRE_ORDER;
+ else
+ ordering = PERMUTE;
+
+ return optstring;
+}
/* Scan elements of ARGV (whose length is ARGC) for option characters
given in OPTSTRING.
@@ -332,41 +383,18 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
int *longind;
int long_only;
{
- int option_index;
-
- optarg = 0;
-
- /* Initialize the internal data when the first call is made.
- Start processing options with ARGV-element 1 (since ARGV-element 0
- is the program name); the sequence of previously skipped
- non-option ARGV-elements is empty. */
+ optarg = NULL;
if (optind == 0)
{
- first_nonopt = last_nonopt = optind = 1;
-
- nextchar = NULL;
-
- /* Determine how to handle the ordering of options and nonoptions. */
-
- if (optstring[0] == '-')
- {
- ordering = RETURN_IN_ORDER;
- ++optstring;
- }
- else if (optstring[0] == '+')
- {
- ordering = REQUIRE_ORDER;
- ++optstring;
- }
- else if (getenv ("POSIXLY_CORRECT") != NULL)
- ordering = REQUIRE_ORDER;
- else
- ordering = PERMUTE;
+ optstring = _getopt_initialize (optstring);
+ optind = 1; /* Don't scan ARGV[0], the program name. */
}
if (nextchar == NULL || *nextchar == '\0')
{
+ /* Advance to the next ARGV-element. */
+
if (ordering == PERMUTE)
{
/* If we have just processed some options following some non-options,
@@ -377,21 +405,16 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
else if (last_nonopt != optind)
first_nonopt = optind;
- /* Now skip any additional non-options
+ /* Skip any additional non-options
and extend the range of non-options previously skipped. */
while (optind < argc
- && (argv[optind][0] != '-' || argv[optind][1] == '\0')
-#ifdef GETOPT_COMPAT
- && (longopts == NULL
- || argv[optind][0] != '+' || argv[optind][1] == '\0')
-#endif /* GETOPT_COMPAT */
- )
+ && (argv[optind][0] != '-' || argv[optind][1] == '\0'))
optind++;
last_nonopt = optind;
}
- /* Special ARGV-element `--' means premature end of options.
+ /* The special ARGV-element `--' means premature end of options.
Skip it like a null option,
then exchange with previous non-options as if it were an option,
then skip everything else like a non-option. */
@@ -424,12 +447,7 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
/* If we have come to a non-option and did not permute it,
either stop the scan or describe it to the caller and pass it by. */
- if ((argv[optind][0] != '-' || argv[optind][1] == '\0')
-#ifdef GETOPT_COMPAT
- && (longopts == NULL
- || argv[optind][0] != '+' || argv[optind][1] == '\0')
-#endif /* GETOPT_COMPAT */
- )
+ if ((argv[optind][0] != '-' || argv[optind][1] == '\0'))
{
if (ordering == REQUIRE_ORDER)
return EOF;
@@ -438,36 +456,48 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
}
/* We have found another option-ARGV-element.
- Start decoding its characters. */
+ Skip the initial punctuation. */
nextchar = (argv[optind] + 1
+ (longopts != NULL && argv[optind][1] == '-'));
}
+ /* Decode the current option-ARGV-element. */
+
+ /* Check whether the ARGV-element is a long option.
+
+ If long_only and the ARGV-element has the form "-f", where f is
+ a valid short option, don't consider it an abbreviated form of
+ a long option that starts with f. Otherwise there would be no
+ way to give the -f short option.
+
+ On the other hand, if there's a long option "fubar" and
+ the ARGV-element is "-fu", do consider that an abbreviation of
+ the long option, just like "--fu", and not "-f" with arg "u".
+
+ This distinction seems to be the most useful approach. */
+
if (longopts != NULL
- && ((argv[optind][0] == '-'
- && (argv[optind][1] == '-' || long_only))
-#ifdef GETOPT_COMPAT
- || argv[optind][0] == '+'
-#endif /* GETOPT_COMPAT */
- ))
+ && (argv[optind][1] == '-'
+ || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1])))))
{
+ char *nameend;
const struct option *p;
- char *s = nextchar;
+ const struct option *pfound = NULL;
int exact = 0;
int ambig = 0;
- const struct option *pfound = NULL;
int indfound;
+ int option_index;
- while (*s && *s != '=')
- s++;
+ for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
+ /* Do nothing. */ ;
- /* Test all options for either exact match or abbreviated matches. */
- for (p = longopts, option_index = 0; p->name;
- p++, option_index++)
- if (!strncmp (p->name, nextchar, s - nextchar))
+ /* Test all long options for either exact match
+ or abbreviated matches. */
+ for (p = longopts, option_index = 0; p->name; p++, option_index++)
+ if (!strncmp (p->name, nextchar, nameend - nextchar))
{
- if (s - nextchar == strlen (p->name))
+ if (nameend - nextchar == strlen (p->name))
{
/* Exact match found. */
pfound = p;
@@ -482,14 +512,14 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
indfound = option_index;
}
else
- /* Second nonexact match found. */
+ /* Second or later nonexact match found. */
ambig = 1;
}
if (ambig && !exact)
{
if (opterr)
- fprintf (stderr, "%s: option `%s' is ambiguous\n",
+ fprintf (stderr, _("%s: option `%s' is ambiguous\n"),
argv[0], argv[optind]);
nextchar += strlen (nextchar);
optind++;
@@ -500,27 +530,26 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
{
option_index = indfound;
optind++;
- if (*s)
+ if (*nameend)
{
/* Don't test has_arg with >, because some C compilers don't
allow it to be used on enums. */
if (pfound->has_arg)
- optarg = s + 1;
+ optarg = nameend + 1;
else
{
if (opterr)
- {
- if (argv[optind - 1][1] == '-')
- /* --option */
- fprintf (stderr,
- "%s: option `--%s' doesn't allow an argument\n",
- argv[0], pfound->name);
- else
- /* +option or -option */
- fprintf (stderr,
- "%s: option `%c%s' doesn't allow an argument\n",
- argv[0], argv[optind - 1][0], pfound->name);
- }
+ if (argv[optind - 1][1] == '-')
+ /* --option */
+ fprintf (stderr,
+ _("%s: option `--%s' doesn't allow an argument\n"),
+ argv[0], pfound->name);
+ else
+ /* +option or -option */
+ fprintf (stderr,
+ _("%s: option `%c%s' doesn't allow an argument\n"),
+ argv[0], argv[optind - 1][0], pfound->name);
+
nextchar += strlen (nextchar);
return '?';
}
@@ -532,8 +561,9 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
else
{
if (opterr)
- fprintf (stderr, "%s: option `%s' requires an argument\n",
- argv[0], argv[optind - 1]);
+ fprintf (stderr,
+ _("%s: option `%s' requires an argument\n"),
+ argv[0], argv[optind - 1]);
nextchar += strlen (nextchar);
return optstring[0] == ':' ? ':' : '?';
}
@@ -548,25 +578,23 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
}
return pfound->val;
}
+
/* Can't find it as a long option. If this is not getopt_long_only,
or the option starts with '--' or is not a valid short
option, then it's an error.
Otherwise interpret it as a short option. */
if (!long_only || argv[optind][1] == '-'
-#ifdef GETOPT_COMPAT
- || argv[optind][0] == '+'
-#endif /* GETOPT_COMPAT */
|| my_index (optstring, *nextchar) == NULL)
{
if (opterr)
{
if (argv[optind][1] == '-')
/* --option */
- fprintf (stderr, "%s: unrecognized option `--%s'\n",
+ fprintf (stderr, _("%s: unrecognized option `--%s'\n"),
argv[0], nextchar);
else
/* +option or -option */
- fprintf (stderr, "%s: unrecognized option `%c%s'\n",
+ fprintf (stderr, _("%s: unrecognized option `%c%s'\n"),
argv[0], argv[optind][0], nextchar);
}
nextchar = (char *) "";
@@ -575,7 +603,7 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
}
}
- /* Look at and handle the next option-character. */
+ /* Look at and handle the next short option-character. */
{
char c = *nextchar++;
@@ -589,16 +617,13 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
{
if (opterr)
{
-#if 0
- if (c < 040 || c >= 0177)
- fprintf (stderr, "%s: unrecognized option, character code 0%o\n",
+ if (posixly_correct)
+ /* 1003.2 specifies the format of this message. */
+ fprintf (stderr, _("%s: illegal option -- %c\n"),
argv[0], c);
else
- fprintf (stderr, "%s: unrecognized option `-%c'\n", argv[0], c);
-#else
- /* 1003.2 specifies the format of this message. */
- fprintf (stderr, "%s: illegal option -- %c\n", argv[0], c);
-#endif
+ fprintf (stderr, _("%s: invalid option -- %c\n"),
+ argv[0], c);
}
optopt = c;
return '?';
@@ -614,7 +639,7 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
optind++;
}
else
- optarg = 0;
+ optarg = NULL;
nextchar = NULL;
}
else
@@ -631,14 +656,10 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
{
if (opterr)
{
-#if 0
- fprintf (stderr, "%s: option `-%c' requires an argument\n",
- argv[0], c);
-#else
/* 1003.2 specifies the format of this message. */
- fprintf (stderr, "%s: option requires an argument -- %c\n",
- argv[0], c);
-#endif
+ fprintf (stderr,
+ _("%s: option requires an argument -- %c\n"),
+ argv[0], c);
}
optopt = c;
if (optstring[0] == ':')
diff --git a/gnu/usr.bin/cpio/getopt.h b/contrib/cpio/getopt.h
index 45541f5ac0f9..4ac33b71824d 100644
--- a/gnu/usr.bin/cpio/getopt.h
+++ b/contrib/cpio/getopt.h
@@ -1,5 +1,5 @@
/* Declarations for getopt.
- Copyright (C) 1989, 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
+ Copyright (C) 1989, 90, 91, 92, 93, 94 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
@@ -76,7 +76,7 @@ extern int optopt;
struct option
{
-#if __STDC__
+#if defined (__STDC__) && __STDC__
const char *name;
#else
char *name;
@@ -94,15 +94,15 @@ struct option
#define required_argument 1
#define optional_argument 2
-#if __STDC__
-#if defined(__GNU_LIBRARY__)
+#if defined (__STDC__) && __STDC__
+#ifdef __GNU_LIBRARY__
/* Many other libraries have conflicting prototypes for getopt, with
differences in the consts, in stdlib.h. To avoid compilation
errors, only prototype getopt for the GNU C library. */
extern int getopt (int argc, char *const *argv, const char *shortopts);
#else /* not __GNU_LIBRARY__ */
extern int getopt ();
-#endif /* not __GNU_LIBRARY__ */
+#endif /* __GNU_LIBRARY__ */
extern int getopt_long (int argc, char *const *argv, const char *shortopts,
const struct option *longopts, int *longind);
extern int getopt_long_only (int argc, char *const *argv,
@@ -120,7 +120,7 @@ extern int getopt_long ();
extern int getopt_long_only ();
extern int _getopt_internal ();
-#endif /* not __STDC__ */
+#endif /* __STDC__ */
#ifdef __cplusplus
}
diff --git a/gnu/usr.bin/cpio/getopt1.c b/contrib/cpio/getopt1.c
index a32615ce36e7..4580211cfac3 100644
--- a/gnu/usr.bin/cpio/getopt1.c
+++ b/contrib/cpio/getopt1.c
@@ -1,5 +1,5 @@
/* getopt_long and getopt_long_only entry points for GNU getopt.
- Copyright (C) 1987, 88, 89, 90, 91, 92, 1993
+ Copyright (C) 1987, 88, 89, 90, 91, 92, 1993, 1994
Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify it
@@ -17,14 +17,18 @@
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
#endif
#include "getopt.h"
-#if !__STDC__ && !defined(const) && IN_GCC
+#if !defined (__STDC__) || !__STDC__
+/* This is a separate conditional since some stdc systems
+ reject `defined (const)'. */
+#ifndef const
#define const
#endif
+#endif
#include <stdio.h>
diff --git a/gnu/usr.bin/cpio/global.c b/contrib/cpio/global.c
index d4b54415f11e..7fb66b2fa698 100644
--- a/gnu/usr.bin/cpio/global.c
+++ b/contrib/cpio/global.c
@@ -36,6 +36,10 @@ int create_dir_flag = FALSE;
/* If TRUE, interactively rename files. (-r) */
int rename_flag = FALSE;
+/* If non-NULL, the name of a file that will be read to
+ rename all of the files in the archive. --rename-batch-file. */
+char *rename_batch_file = NULL;
+
/* If TRUE, print a table of contents of input. (-t) */
int table_flag = FALSE;
@@ -84,6 +88,19 @@ gid_t set_group;
/* If TRUE, do not chown the files. */
int no_chown_flag = FALSE;
+/* If TRUE, try to write sparse ("holey") files. */
+int sparse_flag = FALSE;
+
+/* If TRUE, don't report number of blocks copied. */
+int quiet_flag = FALSE;
+
+/* If TRUE, only read the archive and verify the files' CRC's, don't
+ actually extract the files. */
+int only_verify_crc_flag = FALSE;
+
+/* If TRUE, don't use any absolute paths, prefix them by `./'. */
+int no_abs_paths_flag = FALSE;
+
#ifdef DEBUG_CPIO
/* If TRUE, print debugging information. */
int debug_flag = FALSE;
@@ -123,14 +140,26 @@ unsigned long crc;
/* Input and output buffers. */
char *input_buffer, *output_buffer;
+/* The size of the input buffer. */
+long input_buffer_size;
+
/* Current locations in `input_buffer' and `output_buffer'. */
char *in_buff, *out_buff;
/* Current number of bytes stored at `input_buff' and `output_buff'. */
long input_size, output_size;
-/* Total number of bytes read and written for all files. */
+/* Total number of bytes read and written for all files.
+ Now that many tape drives hold more than 4Gb we need more than 32
+ bits to hold input_bytes and output_bytes. But it's not worth
+ the trouble of adding special multi-precision arithmetic if the
+ compiler doesn't support 64 bit ints since input_bytes and
+ output_bytes are only used to print the number of blocks copied. */
+#ifdef __GNUC__
+long long input_bytes, output_bytes;
+#else
long input_bytes, output_bytes;
+#endif
/* 512 bytes of 0; used for various padding operations. */
char zeros_512[512];
diff --git a/gnu/usr.bin/cpio/idcache.c b/contrib/cpio/idcache.c
index dd9c366b1619..34dcc07c56a8 100644
--- a/gnu/usr.bin/cpio/idcache.c
+++ b/contrib/cpio/idcache.c
@@ -15,6 +15,10 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
#include <stdio.h>
#include <sys/types.h>
#include <pwd.h>
@@ -199,7 +203,7 @@ getgidbyname (group)
group_alist = tail;
return &tail->id.g;
}
-
+
tail->next = nogroup_alist;
nogroup_alist = tail;
return 0;
diff --git a/gnu/usr.bin/cpio/main.c b/contrib/cpio/main.c
index 78b5fc53145f..76125f0cd022 100644
--- a/gnu/usr.bin/cpio/main.c
+++ b/contrib/cpio/main.c
@@ -48,14 +48,19 @@ struct option long_opts[] =
{"list", 0, &table_flag, TRUE},
{"make-directories", 0, &create_dir_flag, TRUE},
{"message", 1, 0, 'M'},
+ {"no-absolute-filenames", 0, 0, 136},
{"no-preserve-owner", 0, 0, 134},
{"nonmatching", 0, &copy_matching_files, FALSE},
{"numeric-uid-gid", 0, &numeric_uid, TRUE},
+ {"only-verify-crc", 0, 0, 139},
{"owner", 1, 0, 'R'},
{"pass-through", 0, 0, 'p'},
{"pattern-file", 1, 0, 'E'},
{"preserve-modification-time", 0, &retain_time_flag, TRUE},
{"rename", 0, &rename_flag, TRUE},
+ {"rename-batch-file", 1, 0, 137},
+ {"quiet", 0, 0, 138},
+ {"sparse", 0, 0, 135},
{"swap", 0, 0, 'b'},
{"swap-bytes", 0, 0, 's'},
{"swap-halfwords", 0, 0, 'S'},
@@ -81,7 +86,7 @@ Usage: %s {-o|--create} [-0acvABLV] [-C bytes] [-H format] [-M message]\n\
[-O [[user@]host:]archive] [-F [[user@]host:]archive]\n\
[--file=[[user@]host:]archive] [--format=format] [--message=message]\n\
[--null] [--reset-access-time] [--verbose] [--dot] [--append]\n\
- [--block-size=blocks] [--dereference] [--io-size=bytes]\n\
+ [--block-size=blocks] [--dereference] [--io-size=bytes] [--quiet]\n\
[--force-local] [--help] [--version] < name-list [> archive]\n", program_name);
fprintf (fp, "\
%s {-i|--extract} [-bcdfmnrtsuvBSV] [-C bytes] [-E file] [-H format]\n\
@@ -92,14 +97,15 @@ Usage: %s {-o|--create} [-0acvABLV] [-C bytes] [-H format] [-M message]\n\
[--unconditional] [--verbose] [--block-size=blocks] [--swap-halfwords]\n\
[--io-size=bytes] [--pattern-file=file] [--format=format]\n\
[--owner=[user][:.][group]] [--no-preserve-owner] [--message=message]\n\
- [--force-local] [--help] [--version] [pattern...] [< archive]\n",
+ [--force-local] [--no-absolute-filenames] [--sparse] [--only-verify-crc]\n\
+ [--quiet] [--help] [--version] [pattern...] [< archive]\n",
program_name);
fprintf (fp, "\
%s {-p|--pass-through} [-0adlmuvLV] [-R [user][:.][group]]\n\
- [--null] [--reset-access-time] [--make-directories] [--link]\n\
+ [--null] [--reset-access-time] [--make-directories] [--link] [--quiet]\n\
[--preserve-modification-time] [--unconditional] [--verbose] [--dot]\n\
[--dereference] [--owner=[user][:.][group]] [--no-preserve-owner]\n\
- [--help] [--version] destination-directory < name-list\n", program_name);
+ [--sparse] [--help] [--version] destination-directory < name-list\n", program_name);
exit (status);
}
@@ -252,6 +258,10 @@ crc newc odc bin ustar tar (all-caps also recognized)", optarg);
numeric_uid = TRUE;
break;
+ case 136: /* --no-absolute-filenames */
+ no_abs_paths_flag = TRUE;
+ break;
+
case 134: /* --no-preserve-owner */
if (set_owner_flag || set_group_flag)
usage (stderr, 2);
@@ -268,6 +278,10 @@ crc newc odc bin ustar tar (all-caps also recognized)", optarg);
output_archive_name = optarg;
break;
+ case 139:
+ only_verify_crc_flag = TRUE;
+ break;
+
case 'p': /* Copy-pass mode. */
if (copy_function != 0)
usage (stderr, 2);
@@ -278,6 +292,14 @@ crc newc odc bin ustar tar (all-caps also recognized)", optarg);
rename_flag = TRUE;
break;
+ case 137:
+ rename_batch_file = optarg;
+ break;
+
+ case 138:
+ quiet_flag = TRUE;
+ break;
+
case 'R': /* Set the owner. */
if (no_chown_flag)
usage (stderr, 2);
@@ -331,6 +353,10 @@ crc newc odc bin ustar tar (all-caps also recognized)", optarg);
exit (0);
break;
+ case 135:
+ sparse_flag = TRUE;
+ break;
+
case 132: /* --help */
usage (stdout, 0);
break;
@@ -361,6 +387,7 @@ crc newc odc bin ustar tar (all-caps also recognized)", optarg);
{
archive_des = 0;
if (link_flag || reset_time_flag || xstat != lstat || append_flag
+ || sparse_flag
|| output_archive_name
|| (archive_name && input_archive_name))
usage (stderr, 2);
@@ -379,6 +406,7 @@ crc newc odc bin ustar tar (all-caps also recognized)", optarg);
|| retain_time_flag || no_chown_flag || set_owner_flag
|| set_group_flag || swap_bytes_flag || swap_halfwords_flag
|| (append_flag && !(archive_name || output_archive_name))
+ || rename_batch_file || no_abs_paths_flag
|| input_archive_name || (archive_name && output_archive_name))
usage (stderr, 2);
if (archive_format == arf_unknown)
@@ -392,7 +420,8 @@ crc newc odc bin ustar tar (all-caps also recognized)", optarg);
archive_des = -1;
if (argc - 1 != optind || archive_format != arf_unknown
|| swap_bytes_flag || swap_halfwords_flag
- || table_flag || rename_flag || append_flag)
+ || table_flag || rename_flag || append_flag
+ || rename_batch_file || no_abs_paths_flag)
usage (stderr, 2);
directory_name = argv[optind];
}
@@ -422,26 +451,39 @@ crc newc odc bin ustar tar (all-caps also recognized)", optarg);
void
initialize_buffers ()
{
- int buf_size;
+ int in_buf_size, out_buf_size;
- /* Make sure buffers can always hold 2 blocks and that they
- are big enough to hold 1 tar record (512 bytes) even if it
- is not aligned on a block boundary. The extra buffer space
- is needed by process_copyin and peek_in_buf to automatically
- figure out what kind of archive it is reading. */
-
- if (io_block_size >= 512)
- buf_size = 2 * io_block_size;
+ if (copy_function == process_copy_in)
+ {
+ /* Make sure the input buffer can always hold 2 blocks and that it
+ is big enough to hold 1 tar record (512 bytes) even if it
+ is not aligned on a block boundary. The extra buffer space
+ is needed by process_copyin and peek_in_buf to automatically
+ figure out what kind of archive it is reading. */
+ if (io_block_size >= 512)
+ in_buf_size = 2 * io_block_size;
+ else
+ in_buf_size = 1024;
+ out_buf_size = DISK_IO_BLOCK_SIZE;
+ }
+ else if (copy_function == process_copy_out)
+ {
+ in_buf_size = DISK_IO_BLOCK_SIZE;
+ out_buf_size = io_block_size;
+ }
else
- buf_size = 1024;
- input_buffer = (char *) xmalloc (buf_size);
+ {
+ in_buf_size = DISK_IO_BLOCK_SIZE;
+ out_buf_size = DISK_IO_BLOCK_SIZE;
+ }
+
+ input_buffer = (char *) xmalloc (in_buf_size);
in_buff = input_buffer;
+ input_buffer_size = in_buf_size;
input_size = 0;
input_bytes = 0;
- /* Leave space for an `int' sentinel for `empty_output_buffer',
- in case we ever put back sparseness checking. */
- output_buffer = (char *) xmalloc (buf_size + sizeof (int) * 2);
+ output_buffer = (char *) xmalloc (out_buf_size);
out_buff = output_buffer;
output_size = 0;
output_bytes = 0;
diff --git a/gnu/usr.bin/cpio/makepath.c b/contrib/cpio/makepath.c
index bdf6829750ef..fc47871868c6 100644
--- a/gnu/usr.bin/cpio/makepath.c
+++ b/contrib/cpio/makepath.c
@@ -46,8 +46,8 @@ char *alloca ();
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
#endif
-#ifdef STDC_HEADERS
#include <errno.h>
+#ifdef STDC_HEADERS
#include <stdlib.h>
#else
extern int errno;
@@ -55,12 +55,14 @@ extern int errno;
#if defined(STDC_HEADERS) || defined(HAVE_STRING_H)
#include <string.h>
+#ifndef index
#define index strchr
+#endif
#else
#include <strings.h>
#endif
-#ifdef __MSDOS__
+#if defined(__MSDOS__) && !defined(__GNUC__)
typedef int uid_t;
typedef int gid_t;
#endif
@@ -208,13 +210,21 @@ make_path (argpath, mode, parent_mode, owner, group, verbose_fmt_string)
}
/* We're done making leading directories.
- Make the final component of the path. */
+ Make the final component of the path. */
if (mkdir (dirpath, mode))
{
- error (0, errno, "cannot make directory `%s'", dirpath);
- umask (oldmask);
- return 1;
+ /* In some cases, if the final component in dirpath was `.' then we
+ just got an EEXIST error from that last mkdir(). If that's
+ the case, ignore it. */
+ if ( (errno != EEXIST) ||
+ (stat (dirpath, &stats) != 0) ||
+ (!S_ISDIR (stats.st_mode) ) )
+ {
+ error (0, errno, "cannot make directory `%s'", dirpath);
+ umask (oldmask);
+ return 1;
+ }
}
if (verbose_fmt_string != NULL)
error (0, 0, verbose_fmt_string, dirpath);
diff --git a/gnu/usr.bin/cpio/rmt.h b/contrib/cpio/rmt.h
index 2155223954c3..2155223954c3 100644
--- a/gnu/usr.bin/cpio/rmt.h
+++ b/contrib/cpio/rmt.h
diff --git a/gnu/usr.bin/cpio/rtapelib.c b/contrib/cpio/rtapelib.c
index eece76ffcd0f..eece76ffcd0f 100644
--- a/gnu/usr.bin/cpio/rtapelib.c
+++ b/contrib/cpio/rtapelib.c
diff --git a/contrib/cpio/safe-stat.h b/contrib/cpio/safe-stat.h
new file mode 100644
index 000000000000..3a379703cf64
--- /dev/null
+++ b/contrib/cpio/safe-stat.h
@@ -0,0 +1 @@
+#define SAFE_STAT(path,pbuf) stat(path,pbuf)
diff --git a/gnu/usr.bin/cpio/stripslash.c b/contrib/cpio/stripslash.c
index 2971d4ced00f..67330e57560b 100644
--- a/gnu/usr.bin/cpio/stripslash.c
+++ b/contrib/cpio/stripslash.c
@@ -15,6 +15,10 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
#if defined(STDC_HEADERS) || defined(HAVE_STRING_H)
#include <string.h>
#else
diff --git a/gnu/usr.bin/cpio/system.h b/contrib/cpio/system.h
index abe732d237b2..e4cf0ffe9809 100644
--- a/gnu/usr.bin/cpio/system.h
+++ b/contrib/cpio/system.h
@@ -50,6 +50,9 @@
#endif
#ifndef _POSIX_VERSION
+#if defined(__MSDOS__) && !defined(__GNUC__)
+typedef long off_t;
+#endif
off_t lseek ();
#endif
@@ -118,7 +121,7 @@ struct utimbuf
#define CONSOLE "con"
#endif
-#ifdef __MSDOS__
+#if defined(__MSDOS__) && !defined(__GNUC__)
typedef int uid_t;
typedef int gid_t;
#endif
diff --git a/gnu/usr.bin/cpio/tar.c b/contrib/cpio/tar.c
index 16eeee07648f..333ec20efd5b 100644
--- a/gnu/usr.bin/cpio/tar.c
+++ b/contrib/cpio/tar.c
@@ -165,7 +165,7 @@ write_out_tar_header (file_hdr, out_des)
to_oct (tar_checksum (tar_hdr), 8, tar_hdr->chksum);
- copy_buf_out ((char *) &tar_rec, out_des, TARRECORDSIZE);
+ tape_buffered_write ((char *) &tar_rec, out_des, TARRECORDSIZE);
}
/* Return nonzero iff all the bytes in BLOCK are NUL.
@@ -203,7 +203,7 @@ read_in_tar_header (file_hdr, in_des)
gid_t *gidp;
#endif
- copy_in_buf ((char *) &tar_rec, in_des, TARRECORDSIZE);
+ tape_buffered_read ((char *) &tar_rec, in_des, TARRECORDSIZE);
/* Check for a block of 0's. */
if (null_block ((long *) &tar_rec, TARRECORDSIZE))
@@ -216,7 +216,7 @@ read_in_tar_header (file_hdr, in_des)
/* Commented out because GNU tar sometimes creates archives with
only one block of 0's at the end. This happened for the
cpio 2.0 distribution! */
- copy_in_buf ((char *) &tar_rec, in_des, TARRECORDSIZE);
+ tape_buffered_read ((char *) &tar_rec, in_des, TARRECORDSIZE);
if (null_block ((long *) &tar_rec, TARRECORDSIZE))
#endif
{
@@ -249,7 +249,7 @@ read_in_tar_header (file_hdr, in_des)
}
bcopy (((char *) &tar_rec) + 1, (char *) &tar_rec,
TARRECORDSIZE - 1);
- copy_in_buf (((char *) &tar_rec) + (TARRECORDSIZE - 1), in_des, 1);
+ tape_buffered_read (((char *) &tar_rec) + (TARRECORDSIZE - 1), in_des, 1);
++bytes_skipped;
continue;
}
diff --git a/gnu/usr.bin/cpio/tar.h b/contrib/cpio/tar.h
index 411579c9d1ab..411579c9d1ab 100644
--- a/gnu/usr.bin/cpio/tar.h
+++ b/contrib/cpio/tar.h
diff --git a/gnu/usr.bin/cpio/tarhdr.h b/contrib/cpio/tarhdr.h
index 54de0d6a35bd..54de0d6a35bd 100644
--- a/gnu/usr.bin/cpio/tarhdr.h
+++ b/contrib/cpio/tarhdr.h
diff --git a/gnu/usr.bin/cpio/tcexparg.c b/contrib/cpio/tcexparg.c
index c5d88f069bf5..c5d88f069bf5 100644
--- a/gnu/usr.bin/cpio/tcexparg.c
+++ b/contrib/cpio/tcexparg.c
diff --git a/contrib/cpio/userspec.c b/contrib/cpio/userspec.c
new file mode 100644
index 000000000000..67f1583335c5
--- /dev/null
+++ b/contrib/cpio/userspec.c
@@ -0,0 +1,277 @@
+/* userspec.c -- Parse a user and group string.
+ Copyright (C) 1989, 1990, 1991, 1992 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+/* Written by David MacKenzie <djm@gnu.ai.mit.edu>. */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef __GNUC__
+#define alloca __builtin_alloca
+#else
+#ifdef HAVE_ALLOCA_H
+#include <alloca.h>
+#else
+#ifdef _AIX
+ #pragma alloca
+#else
+char *alloca ();
+#endif
+#endif
+#endif
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <pwd.h>
+#include <grp.h>
+
+#if defined(STDC_HEADERS) || defined(HAVE_STRING_H)
+#include <string.h>
+#ifndef index
+#define index strchr
+#endif
+#else
+#include <strings.h>
+#endif
+
+#ifdef STDC_HEADERS
+#include <stdlib.h>
+#endif
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#ifndef _POSIX_VERSION
+struct passwd *getpwnam ();
+struct group *getgrnam ();
+struct group *getgrgid ();
+#endif
+
+#ifdef _POSIX_SOURCE
+#define endpwent()
+#define endgrent()
+#endif
+
+/* Perform the equivalent of the statement `dest = strdup (src);',
+ but obtaining storage via alloca instead of from the heap. */
+
+#define V_STRDUP(dest, src) \
+ do \
+ { \
+ int _len = strlen ((src)); \
+ (dest) = (char *) alloca (_len + 1); \
+ strcpy (dest, src); \
+ } \
+ while (0)
+
+#define isdigit(c) ((c) >= '0' && (c) <= '9')
+
+char *strdup ();
+
+/* Return nonzero if STR represents an unsigned decimal integer,
+ otherwise return 0. */
+
+static int
+isnumber (str)
+ const char *str;
+{
+ for (; *str; str++)
+ if (!isdigit (*str))
+ return 0;
+ return 1;
+}
+
+/* Extract from NAME, which has the form "[user][:.][group]",
+ a USERNAME, UID U, GROUPNAME, and GID G.
+ Either user or group, or both, must be present.
+ If the group is omitted but the ":" or "." separator is given,
+ use the given user's login group.
+
+ USERNAME and GROUPNAME will be in newly malloc'd memory.
+ Either one might be NULL instead, indicating that it was not
+ given and the corresponding numeric ID was left unchanged.
+
+ Return NULL if successful, a static error message string if not. */
+
+const char *
+parse_user_spec (spec_arg, uid, gid, username_arg, groupname_arg)
+ const char *spec_arg;
+ uid_t *uid;
+ gid_t *gid;
+ char **username_arg, **groupname_arg;
+{
+ static const char *tired = "virtual memory exhausted";
+ const char *error_msg;
+ char *spec; /* A copy we can write on. */
+ struct passwd *pwd;
+ struct group *grp;
+ char *g, *u, *separator;
+ char *groupname;
+
+ error_msg = NULL;
+ *username_arg = *groupname_arg = NULL;
+ groupname = NULL;
+
+ V_STRDUP (spec, spec_arg);
+
+ /* Find the separator if there is one. */
+ separator = index (spec, ':');
+ if (separator == NULL)
+ separator = index (spec, '.');
+
+ /* Replace separator with a NUL. */
+ if (separator != NULL)
+ *separator = '\0';
+
+ /* Set U and G to non-zero length strings corresponding to user and
+ group specifiers or to NULL. */
+ u = (*spec == '\0' ? NULL : spec);
+
+ g = (separator == NULL || *(separator + 1) == '\0'
+ ? NULL
+ : separator + 1);
+
+ if (u == NULL && g == NULL)
+ return "can not omit both user and group";
+
+ if (u != NULL)
+ {
+ pwd = getpwnam (u);
+ if (pwd == NULL)
+ {
+
+ if (!isnumber (u))
+ error_msg = "invalid user";
+ else
+ {
+ int use_login_group;
+ use_login_group = (separator != NULL && g == NULL);
+ if (use_login_group)
+ error_msg = "cannot get the login group of a numeric UID";
+ else
+ *uid = atoi (u);
+ }
+ }
+ else
+ {
+ *uid = pwd->pw_uid;
+ if (g == NULL && separator != NULL)
+ {
+ /* A separator was given, but a group was not specified,
+ so get the login group. */
+ *gid = pwd->pw_gid;
+ grp = getgrgid (pwd->pw_gid);
+ if (grp == NULL)
+ {
+ /* This is enough room to hold the unsigned decimal
+ representation of any 32-bit quantity and the trailing
+ zero byte. */
+ char uint_buf[21];
+ sprintf (uint_buf, "%u", (unsigned) (pwd->pw_gid));
+ V_STRDUP (groupname, uint_buf);
+ }
+ else
+ {
+ V_STRDUP (groupname, grp->gr_name);
+ }
+ endgrent ();
+ }
+ }
+ endpwent ();
+ }
+
+ if (g != NULL && error_msg == NULL)
+ {
+ /* Explicit group. */
+ grp = getgrnam (g);
+ if (grp == NULL)
+ {
+ if (!isnumber (g))
+ error_msg = "invalid group";
+ else
+ *gid = atoi (g);
+ }
+ else
+ *gid = grp->gr_gid;
+ endgrent (); /* Save a file descriptor. */
+
+ if (error_msg == NULL)
+ V_STRDUP (groupname, g);
+ }
+
+ if (error_msg == NULL)
+ {
+ if (u != NULL)
+ {
+ *username_arg = strdup (u);
+ if (*username_arg == NULL)
+ error_msg = tired;
+ }
+
+ if (groupname != NULL && error_msg == NULL)
+ {
+ *groupname_arg = strdup (groupname);
+ if (*groupname_arg == NULL)
+ {
+ if (*username_arg != NULL)
+ {
+ free (*username_arg);
+ *username_arg = NULL;
+ }
+ error_msg = tired;
+ }
+ }
+ }
+
+ return error_msg;
+}
+
+#ifdef TEST
+
+#define NULL_CHECK(s) ((s) == NULL ? "(null)" : (s))
+
+int
+main (int argc, char **argv)
+{
+ int i;
+
+ for (i = 1; i < argc; i++)
+ {
+ const char *e;
+ char *username, *groupname;
+ uid_t uid;
+ gid_t gid;
+ char *tmp;
+
+ tmp = strdup (argv[i]);
+ e = parse_user_spec (tmp, &uid, &gid, &username, &groupname);
+ free (tmp);
+ printf ("%s: %u %u %s %s %s\n",
+ argv[i],
+ (unsigned int) uid,
+ (unsigned int) gid,
+ NULL_CHECK (username),
+ NULL_CHECK (groupname),
+ NULL_CHECK (e));
+ }
+
+ exit (0);
+}
+
+#endif
diff --git a/gnu/usr.bin/cpio/util.c b/contrib/cpio/util.c
index 52e3e85f4730..ab2d2987932c 100644
--- a/gnu/usr.bin/cpio/util.c
+++ b/contrib/cpio/util.c
@@ -39,35 +39,29 @@
#include <sys/mtio.h>
#endif
-static void empty_output_buffer_swap ();
+static void tape_fill_input_buffer P_((int in_des, int num_bytes));
+static int disk_fill_input_buffer P_((int in_des, int num_bytes));
static void hash_insert ();
+static void write_nuls_to_file P_((long num_bytes, int out_des));
/* Write `output_size' bytes of `output_buffer' to file
descriptor OUT_DES and reset `output_size' and `out_buff'. */
void
-empty_output_buffer (out_des)
+tape_empty_output_buffer (out_des)
int out_des;
{
int bytes_written;
#ifdef BROKEN_LONG_TAPE_DRIVER
static long output_bytes_before_lseek = 0;
-#endif
- if (swapping_halfwords || swapping_bytes)
- {
- empty_output_buffer_swap (out_des);
- return;
- }
-
-#ifdef BROKEN_LONG_TAPE_DRIVER
/* Some tape drivers seem to have a signed internal seek pointer and
they lose if it overflows and becomes negative (e.g. when writing
tapes > 2Gb). Doing an lseek (des, 0, SEEK_SET) seems to reset the
seek pointer and prevent it from overflowing. */
if (output_is_special
- && (output_bytes_before_lseek += output_size) < 0L)
+ && ( (output_bytes_before_lseek += output_size) >= 1073741824L) )
{
lseek(out_des, 0L, SEEK_SET);
output_bytes_before_lseek = 0;
@@ -104,120 +98,49 @@ empty_output_buffer (out_des)
}
/* Write `output_size' bytes of `output_buffer' to file
- descriptor OUT_DES with byte and/or halfword swapping and reset
- `output_size' and `out_buff'. This routine should not be called
- with `swapping_bytes' set unless the caller knows that the
- file being written has an even number of bytes, and it should not be
- called with `swapping_halfwords' set unless the caller knows
- that the file being written has a length divisible by 4. If either
- of those restrictions are not met, bytes may be lost in the output
- file. OUT_DES must refer to a file that we are creating during
- a process_copy_in, so we don't have to check for end of media
- errors or be careful about only writing in blocks of `output_size'
- bytes. */
+ descriptor OUT_DES and reset `output_size' and `out_buff'.
+ If `swapping_halfwords' or `swapping_bytes' is set,
+ do the appropriate swapping first. Our callers have
+ to make sure to only set these flags if `output_size'
+ is appropriate (a multiple of 4 for `swapping_halfwords',
+ 2 for `swapping_bytes'). The fact that DISK_IO_BLOCK_SIZE
+ must always be a multiple of 4 helps us (and our callers)
+ insure this. */
-static void
-empty_output_buffer_swap (out_des)
+void
+disk_empty_output_buffer (out_des)
int out_des;
{
- /* Since `output_size' might not be divisible by 4 or 2, we might
- not be able to be able to swap all the bytes and halfwords in
- `output_buffer' (e.g., if `output_size' is odd), so we might not be
- able to write them all. We will swap and write as many bytes as
- we can, and save the rest in `left_overs' for the next time we are
- called. */
- static char left_overs[4];
- static int left_over_bytes = 0;
-
int bytes_written;
- int complete_halfwords;
- int complete_words;
- int extra_bytes;
- output_bytes += output_size;
-
- out_buff = output_buffer;
-
- if (swapping_halfwords)
+ if (swapping_halfwords || swapping_bytes)
{
- if (left_over_bytes != 0)
- {
- while (output_size > 0 && left_over_bytes < 4)
- {
- left_overs[left_over_bytes++] = *out_buff++;
- --output_size;
- }
- if (left_over_bytes < 4)
- {
- out_buff = output_buffer;
- output_size = 0;
- return;
- }
- swahw_array (left_overs, 1);
- if (swapping_bytes)
- swab_array (left_overs, 2);
- bytes_written = rmtwrite (out_des, left_overs, 4);
- if (bytes_written != 4)
- error (1, errno, "write error");
- left_over_bytes = 0;
- }
- complete_words = output_size / 4;
- if (complete_words > 0)
+ if (swapping_halfwords)
{
- swahw_array (out_buff, complete_words);
+ int complete_words;
+ complete_words = output_size / 4;
+ swahw_array (output_buffer, complete_words);
if (swapping_bytes)
- swab_array (out_buff, 2 * complete_words);
- bytes_written = rmtwrite (out_des, out_buff, 4 * complete_words);
- if (bytes_written != (4 * complete_words))
- error (1, errno, "write error");
+ swab_array (output_buffer, 2 * complete_words);
}
- out_buff += (4 * complete_words);
- extra_bytes = output_size % 4;
- while (extra_bytes > 0)
+ else
{
- left_overs[left_over_bytes++] = *out_buff++;
- --extra_bytes;
+ int complete_halfwords;
+ complete_halfwords = output_size /2;
+ swab_array (output_buffer, complete_halfwords);
}
-
}
+
+ if (sparse_flag)
+ bytes_written = sparse_write (out_des, output_buffer, output_size);
else
+ bytes_written = write (out_des, output_buffer, output_size);
+
+ if (bytes_written != output_size)
{
- if (left_over_bytes != 0)
- {
- while (output_size > 0 && left_over_bytes < 2)
- {
- left_overs[left_over_bytes++] = *out_buff++;
- --output_size;
- }
- if (left_over_bytes < 2)
- {
- out_buff = output_buffer;
- output_size = 0;
- return;
- }
- swab_array (left_overs, 1);
- bytes_written = rmtwrite (out_des, left_overs, 2);
- if (bytes_written != 2)
- error (1, errno, "write error");
- left_over_bytes = 0;
- }
- complete_halfwords = output_size / 2;
- if (complete_halfwords > 0)
- {
- swab_array (out_buff, complete_halfwords);
- bytes_written = rmtwrite (out_des, out_buff, 2 * complete_halfwords);
- if (bytes_written != (2 * complete_halfwords))
- error (1, errno, "write error");
- }
- out_buff += (2 * complete_halfwords);
- extra_bytes = output_size % 2;
- while (extra_bytes > 0)
- {
- left_overs[left_over_bytes++] = *out_buff++;
- --extra_bytes;
- }
+ error (1, errno, "write error");
}
-
+ output_bytes += output_size;
out_buff = output_buffer;
output_size = 0;
}
@@ -255,8 +178,8 @@ swahw_array (ptr, count)
static long input_bytes_before_lseek = 0;
#endif
-void
-fill_input_buffer (in_des, num_bytes)
+static void
+tape_fill_input_buffer (in_des, num_bytes)
int in_des;
int num_bytes;
{
@@ -266,7 +189,7 @@ fill_input_buffer (in_des, num_bytes)
tapes > 4Gb). Doing an lseek (des, 0, SEEK_SET) seems to reset the
seek pointer and prevent it from overflowing. */
if (input_is_special
- && (input_bytes_before_lseek += num_bytes) < 0L)
+ && ( (input_bytes_before_lseek += num_bytes) >= 1073741824L) )
{
lseek(in_des, 0L, SEEK_SET);
input_bytes_before_lseek = 0;
@@ -289,12 +212,36 @@ fill_input_buffer (in_des, num_bytes)
}
input_bytes += input_size;
}
+
+/* Read at most NUM_BYTES or `DISK_IO_BLOCK_SIZE' bytes, whichever is smaller,
+ into the start of `input_buffer' from file descriptor IN_DES.
+ Set `input_size' to the number of bytes read and reset `in_buff'.
+ Exit with an error if end of file is reached. */
+
+static int
+disk_fill_input_buffer (in_des, num_bytes)
+ int in_des;
+ int num_bytes;
+{
+ in_buff = input_buffer;
+ num_bytes = (num_bytes < DISK_IO_BLOCK_SIZE) ? num_bytes : DISK_IO_BLOCK_SIZE;
+ input_size = read (in_des, input_buffer, num_bytes);
+ if (input_size < 0)
+ {
+ input_size = 0;
+ return (-1);
+ }
+ else if (input_size == 0)
+ return (1);
+ input_bytes += input_size;
+ return (0);
+}
/* Copy NUM_BYTES of buffer IN_BUF to `out_buff', which may be partly full.
When `out_buff' fills up, flush it to file descriptor OUT_DES. */
void
-copy_buf_out (in_buf, out_des, num_bytes)
+tape_buffered_write (in_buf, out_des, num_bytes)
char *in_buf;
int out_des;
long num_bytes;
@@ -306,7 +253,37 @@ copy_buf_out (in_buf, out_des, num_bytes)
{
space_left = io_block_size - output_size;
if (space_left == 0)
- empty_output_buffer (out_des);
+ tape_empty_output_buffer (out_des);
+ else
+ {
+ if (bytes_left < space_left)
+ space_left = bytes_left;
+ bcopy (in_buf, out_buff, (unsigned) space_left);
+ out_buff += space_left;
+ output_size += space_left;
+ in_buf += space_left;
+ bytes_left -= space_left;
+ }
+ }
+}
+
+/* Copy NUM_BYTES of buffer IN_BUF to `out_buff', which may be partly full.
+ When `out_buff' fills up, flush it to file descriptor OUT_DES. */
+
+void
+disk_buffered_write (in_buf, out_des, num_bytes)
+ char *in_buf;
+ int out_des;
+ long num_bytes;
+{
+ register long bytes_left = num_bytes; /* Bytes needing to be copied. */
+ register long space_left; /* Room left in output buffer. */
+
+ while (bytes_left > 0)
+ {
+ space_left = DISK_IO_BLOCK_SIZE - output_size;
+ if (space_left == 0)
+ disk_empty_output_buffer (out_des);
else
{
if (bytes_left < space_left)
@@ -325,7 +302,7 @@ copy_buf_out (in_buf, out_des, num_bytes)
When `in_buff' is exhausted, refill it from file descriptor IN_DES. */
void
-copy_in_buf (in_buf, in_des, num_bytes)
+tape_buffered_read (in_buf, in_des, num_bytes)
char *in_buf;
int in_des;
long num_bytes;
@@ -336,7 +313,7 @@ copy_in_buf (in_buf, in_des, num_bytes)
while (bytes_left > 0)
{
if (input_size == 0)
- fill_input_buffer (in_des, io_block_size);
+ tape_fill_input_buffer (in_des, io_block_size);
if (bytes_left < input_size)
space_left = bytes_left;
else
@@ -358,7 +335,7 @@ copy_in_buf (in_buf, in_des, num_bytes)
then EOF has been reached. */
int
-peek_in_buf (peek_buf, in_des, num_bytes)
+tape_buffered_peek (peek_buf, in_des, num_bytes)
char *peek_buf;
int in_des;
int num_bytes;
@@ -373,7 +350,7 @@ peek_in_buf (peek_buf, in_des, num_bytes)
tapes > 4Gb). Doing an lseek (des, 0, SEEK_SET) seems to reset the
seek pointer and prevent it from overflowing. */
if (input_is_special
- && (input_bytes_before_lseek += num_bytes) < 0L)
+ && ( (input_bytes_before_lseek += num_bytes) >= 1073741824L) )
{
lseek(in_des, 0L, SEEK_SET);
input_bytes_before_lseek = 0;
@@ -383,6 +360,21 @@ peek_in_buf (peek_buf, in_des, num_bytes)
while (input_size < num_bytes)
{
append_buf = in_buff + input_size;
+ if ( (append_buf - input_buffer) >= input_buffer_size)
+ {
+ /* We can keep up to 2 "blocks" (either the physical block size
+ or 512 bytes(the size of a tar record), which ever is
+ larger) in the input buffer when we are peeking. We
+ assume that our caller will never be interested in peeking
+ ahead at more than 512 bytes, so we know that by the time
+ we need a 3rd "block" in the buffer we can throw away the
+ first block to make room. */
+ int half;
+ half = input_buffer_size / 2;
+ bcopy (input_buffer + half, input_buffer, half);
+ in_buff = in_buff - half;
+ append_buf = append_buf - half;
+ }
tmp_input_size = rmtread (in_des, append_buf, io_block_size);
if (tmp_input_size == 0)
{
@@ -410,7 +402,7 @@ peek_in_buf (peek_buf, in_des, num_bytes)
/* Skip the next NUM_BYTES bytes of file descriptor IN_DES. */
void
-toss_input (in_des, num_bytes)
+tape_toss_input (in_des, num_bytes)
int in_des;
long num_bytes;
{
@@ -420,11 +412,19 @@ toss_input (in_des, num_bytes)
while (bytes_left > 0)
{
if (input_size == 0)
- fill_input_buffer (in_des, io_block_size);
+ tape_fill_input_buffer (in_des, io_block_size);
if (bytes_left < input_size)
space_left = bytes_left;
else
space_left = input_size;
+
+ if (crc_i_flag && only_verify_crc_flag)
+ {
+ int k;
+ for (k = 0; k < space_left; ++k)
+ crc += in_buff[k] & 0xff;
+ }
+
in_buff += space_left;
input_size -= space_left;
bytes_left -= space_left;
@@ -440,25 +440,120 @@ toss_input (in_des, num_bytes)
NUM_BYTES is the number of bytes to copy. */
void
-copy_files (in_des, out_des, num_bytes)
+copy_files_tape_to_disk (in_des, out_des, num_bytes)
+ int in_des;
+ int out_des;
+ long num_bytes;
+{
+ long size;
+ long k;
+
+ while (num_bytes > 0)
+ {
+ if (input_size == 0)
+ tape_fill_input_buffer (in_des, io_block_size);
+ size = (input_size < num_bytes) ? input_size : num_bytes;
+ if (crc_i_flag)
+ {
+ for (k = 0; k < size; ++k)
+ crc += in_buff[k] & 0xff;
+ }
+ disk_buffered_write (in_buff, out_des, size);
+ num_bytes -= size;
+ input_size -= size;
+ in_buff += size;
+ }
+}
+/* Copy a file using the input and output buffers, which may start out
+ partly full. After the copy, the files are not closed nor the last
+ block flushed to output, and the input buffer may still be partly
+ full. If `crc_i_flag' is set, add each byte to `crc'.
+ IN_DES is the file descriptor for input;
+ OUT_DES is the file descriptor for output;
+ NUM_BYTES is the number of bytes to copy. */
+
+void
+copy_files_disk_to_tape (in_des, out_des, num_bytes, filename)
int in_des;
int out_des;
long num_bytes;
+ char *filename;
{
long size;
long k;
+ int rc;
+ long original_num_bytes;
+
+ original_num_bytes = num_bytes;
while (num_bytes > 0)
{
if (input_size == 0)
- fill_input_buffer (in_des, io_block_size);
+ if (rc = disk_fill_input_buffer (in_des, DISK_IO_BLOCK_SIZE))
+ {
+ if (rc > 0)
+ error (0, 0, "File %s shrunk by %ld bytes, padding with zeros",
+ filename, num_bytes);
+ else
+ error (0, 0, "Read error at byte %ld in file %s, padding with zeros",
+ original_num_bytes - num_bytes, filename);
+ write_nuls_to_file (num_bytes, out_des);
+ break;
+ }
size = (input_size < num_bytes) ? input_size : num_bytes;
if (crc_i_flag)
{
for (k = 0; k < size; ++k)
crc += in_buff[k] & 0xff;
}
- copy_buf_out (in_buff, out_des, size);
+ tape_buffered_write (in_buff, out_des, size);
+ num_bytes -= size;
+ input_size -= size;
+ in_buff += size;
+ }
+}
+/* Copy a file using the input and output buffers, which may start out
+ partly full. After the copy, the files are not closed nor the last
+ block flushed to output, and the input buffer may still be partly
+ full. If `crc_i_flag' is set, add each byte to `crc'.
+ IN_DES is the file descriptor for input;
+ OUT_DES is the file descriptor for output;
+ NUM_BYTES is the number of bytes to copy. */
+
+void
+copy_files_disk_to_disk (in_des, out_des, num_bytes, filename)
+ int in_des;
+ int out_des;
+ long num_bytes;
+ char *filename;
+{
+ long size;
+ long k;
+ long original_num_bytes;
+ int rc;
+
+ original_num_bytes = num_bytes;
+ while (num_bytes > 0)
+ {
+ if (input_size == 0)
+ if (rc = disk_fill_input_buffer (in_des, DISK_IO_BLOCK_SIZE))
+ {
+ if (rc > 0)
+ error (0, 0, "File %s shrunk by %ld bytes, padding with zeros",
+ filename, num_bytes);
+ else
+ error (0, 0, "Read error at byte %ld in file %s, padding with zeros",
+ original_num_bytes - num_bytes, filename);
+ write_nuls_to_file (num_bytes, out_des);
+ break;
+ }
+ size = (input_size < num_bytes) ? input_size : num_bytes;
+ if (crc_i_flag)
+ {
+ for (k = 0; k < size; ++k)
+ crc += in_buff[k] & 0xff;
+ }
+ disk_buffered_write (in_buff, out_des, size);
num_bytes -= size;
input_size -= size;
in_buff += size;
@@ -535,7 +630,8 @@ prepare_append (out_file_des)
read (out_file_des, tmp_buf, useful_bytes_in_block);
if (lseek (out_file_des, start_of_block, SEEK_SET) < 0)
error (1, errno, "cannot seek on output");
- copy_buf_out (tmp_buf, out_file_des, useful_bytes_in_block);
+ /* fix juo -- is this copy_tape_buf_out? or copy_disk? */
+ tape_buffered_write (tmp_buf, out_file_des, useful_bytes_in_block);
free (tmp_buf);
}
@@ -877,7 +973,7 @@ set_new_media_message (message)
new_media_message_with_number[length] = '\0';
length = strlen (p + 1);
new_media_message_after_number = xmalloc (length + 1);
- strcpy (new_media_message_after_number, message);
+ strcpy (new_media_message_after_number, p + 1);
}
}
@@ -907,7 +1003,7 @@ umasked_symlink (name1, name2, mode)
}
#endif /* SYMLINK_USES_UMASK */
-#ifdef __MSDOS__
+#if defined(__MSDOS__) && !defined(__GNUC__)
int
chown (path, owner, group)
char *path;
@@ -1100,3 +1196,148 @@ islastparentcdf(path)
return 0;
}
#endif
+
+#define DISKBLOCKSIZE (512)
+
+enum sparse_write_states { begin, in_zeros, not_in_zeros };
+
+
+static int
+buf_all_zeros (buf, bufsize)
+ char *buf;
+ int bufsize;
+{
+ int i;
+ for (i = 0; i < bufsize; ++i)
+ {
+ if (*buf++ != '\0')
+ return 0;
+ }
+ return 1;
+}
+
+int delayed_seek_count = 0;
+
+/* Write NBYTE bytes from BUF to remote tape connection FILDES.
+ Return the number of bytes written on success, -1 on error. */
+
+int
+sparse_write (fildes, buf, nbyte)
+ int fildes;
+ char *buf;
+ unsigned int nbyte;
+{
+ int complete_block_count;
+ int leftover_bytes_count;
+ int seek_count;
+ int write_count;
+ char *cur_write_start;
+ int lseek_rc;
+ int write_rc;
+ int i;
+ enum sparse_write_states state;
+
+ complete_block_count = nbyte / DISKBLOCKSIZE;
+ leftover_bytes_count = nbyte % DISKBLOCKSIZE;
+
+ if (delayed_seek_count != 0)
+ state = in_zeros;
+ else
+ state = begin;
+
+ seek_count = delayed_seek_count;
+
+ for (i = 0; i < complete_block_count; ++i)
+ {
+ switch (state)
+ {
+ case begin :
+ if (buf_all_zeros (buf, DISKBLOCKSIZE))
+ {
+ seek_count = DISKBLOCKSIZE;
+ state = in_zeros;
+ }
+ else
+ {
+ cur_write_start = buf;
+ write_count = DISKBLOCKSIZE;
+ state = not_in_zeros;
+ }
+ buf += DISKBLOCKSIZE;
+ break;
+ case in_zeros :
+ if (buf_all_zeros (buf, DISKBLOCKSIZE))
+ {
+ seek_count += DISKBLOCKSIZE;
+ }
+ else
+ {
+ lseek (fildes, seek_count, SEEK_CUR);
+ cur_write_start = buf;
+ write_count = DISKBLOCKSIZE;
+ state = not_in_zeros;
+ }
+ buf += DISKBLOCKSIZE;
+ break;
+ case not_in_zeros :
+ if (buf_all_zeros (buf, DISKBLOCKSIZE))
+ {
+ write_rc = write (fildes, cur_write_start, write_count);
+ seek_count = DISKBLOCKSIZE;
+ state = in_zeros;
+ }
+ else
+ {
+ write_count += DISKBLOCKSIZE;
+ }
+ buf += DISKBLOCKSIZE;
+ break;
+ }
+ }
+
+ switch (state)
+ {
+ case begin :
+ case in_zeros :
+ delayed_seek_count = seek_count;
+ break;
+ case not_in_zeros :
+ write_rc = write (fildes, cur_write_start, write_count);
+ delayed_seek_count = 0;
+ break;
+ }
+
+ if (leftover_bytes_count != 0)
+ {
+ if (delayed_seek_count != 0)
+ {
+ lseek_rc = lseek (fildes, delayed_seek_count, SEEK_CUR);
+ delayed_seek_count = 0;
+ }
+ write_rc = write (fildes, buf, leftover_bytes_count);
+ }
+ return nbyte;
+}
+
+static void
+write_nuls_to_file (num_bytes, out_des)
+ long num_bytes;
+ int out_des;
+{
+ long blocks;
+ long extra_bytes;
+ long i;
+
+ blocks = num_bytes / 512;
+ extra_bytes = num_bytes % 512;
+ for (i = 0; i < extra_bytes; ++i)
+ {
+ if (write (out_des, zeros_512, 512) != 512)
+ error (1, errno, "error writing NUL's");
+ }
+ if (extra_bytes != 0)
+ {
+ if (write (out_des, zeros_512, extra_bytes) != extra_bytes)
+ error (1, errno, "error writing NUL's");
+ }
+}
diff --git a/gnu/usr.bin/cpio/version.c b/contrib/cpio/version.c
index 38a63f2c988b..c641a3a02010 100644
--- a/gnu/usr.bin/cpio/version.c
+++ b/contrib/cpio/version.c
@@ -1,2 +1,2 @@
/* The version number of cpio and mt. */
-char *version_string = "version 2.3\n";
+char *version_string = "version 2.4.2\n";
diff --git a/contrib/cpio/xmalloc.c b/contrib/cpio/xmalloc.c
new file mode 100644
index 000000000000..bad831f5db59
--- /dev/null
+++ b/contrib/cpio/xmalloc.c
@@ -0,0 +1,103 @@
+/* xmalloc.c -- malloc with out of memory checking
+ Copyright (C) 1990, 91, 92, 93, 94 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#if __STDC__
+#define VOID void
+#else
+#define VOID char
+#endif
+
+#include <sys/types.h>
+
+#if STDC_HEADERS
+#include <stdlib.h>
+#else
+VOID *malloc ();
+VOID *realloc ();
+void free ();
+#endif
+
+/* This is for other GNU distributions with internationalized messages.
+ The GNU C Library itself does not yet support such messages. */
+#if HAVE_LIBINTL_H
+# include <libintl.h>
+#else
+# define gettext(msgid) (msgid)
+#endif
+
+#ifndef EXIT_FAILURE
+#define EXIT_FAILURE 1
+#endif
+
+/* Exit value when the requested amount of memory is not available.
+ The caller may set it to some other value. */
+int xmalloc_exit_failure = EXIT_FAILURE;
+
+#if __STDC__ && (HAVE_VPRINTF || HAVE_DOPRNT)
+void error (int, int, const char *, ...);
+#else
+void error ();
+#endif
+
+static VOID *
+fixup_null_alloc (n)
+ size_t n;
+{
+ VOID *p;
+
+ p = 0;
+ if (n == 0)
+ p = malloc ((size_t) 1);
+ if (p == 0)
+ error (xmalloc_exit_failure, 0, gettext ("Memory exhausted"));
+ return p;
+}
+
+/* Allocate N bytes of memory dynamically, with error checking. */
+
+VOID *
+xmalloc (n)
+ size_t n;
+{
+ VOID *p;
+
+ p = malloc (n);
+ if (p == 0)
+ p = fixup_null_alloc (n);
+ return p;
+}
+
+/* Change the size of an allocated block of memory P to N bytes,
+ with error checking.
+ If P is NULL, run xmalloc. */
+
+VOID *
+xrealloc (p, n)
+ VOID *p;
+ size_t n;
+{
+ if (p == 0)
+ return xmalloc (n);
+ p = realloc (p, n);
+ if (p == 0)
+ p = fixup_null_alloc (n);
+ return p;
+}
diff --git a/gnu/usr.bin/cpio/xstrdup.c b/contrib/cpio/xstrdup.c
index 9588bc78d19a..27cd0c6738ce 100644
--- a/gnu/usr.bin/cpio/xstrdup.c
+++ b/contrib/cpio/xstrdup.c
@@ -15,6 +15,10 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
#if defined(STDC_HEADERS) || defined(HAVE_STRING_H)
#include <string.h>
#else
diff --git a/gnu/usr.bin/cpio/userspec.c b/gnu/usr.bin/cpio/userspec.c
deleted file mode 100644
index 44d7d91744d6..000000000000
--- a/gnu/usr.bin/cpio/userspec.c
+++ /dev/null
@@ -1,180 +0,0 @@
-/* userspec.c -- Parse a user and group string.
- Copyright (C) 1989, 1990, 1991, 1992 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-/* Written by David MacKenzie <djm@gnu.ai.mit.edu>. */
-
-#include <stdio.h>
-#include <sys/types.h>
-#include <pwd.h>
-#include <grp.h>
-
-#if defined(STDC_HEADERS) || defined(HAVE_STRING_H)
-#include <string.h>
-#ifndef index
-#define index strchr
-#endif
-#else
-#include <strings.h>
-#endif
-
-#ifdef STDC_HEADERS
-#include <stdlib.h>
-#else
-char *malloc ();
-#endif
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#ifndef _POSIX_VERSION
-struct passwd *getpwnam ();
-struct group *getgrnam ();
-struct group *getgrgid ();
-#endif
-
-#ifdef _POSIX_SOURCE
-#define endpwent()
-#define endgrent()
-#endif
-
-#define isdigit(c) ((c) >= '0' && (c) <= '9')
-
-char *strdup ();
-static int isnumber ();
-
-/* Extract from NAME, which has the form "[user][:.][group]",
- a USERNAME, UID U, GROUPNAME, and GID G.
- Either user or group, or both, must be present.
- If the group is omitted but the ":" or "." separator is given,
- use the given user's login group.
-
- USERNAME and GROUPNAME will be in newly malloc'd memory.
- Either one might be NULL instead, indicating that it was not
- given and the corresponding numeric ID was left unchanged.
- Might write NULs into NAME.
-
- Return NULL if successful, a static error message string if not. */
-
-char *
-parse_user_spec (name, uid, gid, username, groupname)
- char *name;
- uid_t *uid;
- gid_t *gid;
- char **username, **groupname;
-{
- static char *tired = "virtual memory exhausted";
- struct passwd *pwd;
- struct group *grp;
- char *cp;
- int use_login_group = 0;
-
- *username = *groupname = NULL;
-
- /* Check whether a group is given. */
- cp = index (name, ':');
- if (cp == NULL)
- cp = index (name, '.');
- if (cp != NULL)
- {
- *cp++ = '\0';
- if (*cp == '\0')
- {
- if (cp == name + 1)
- /* Neither user nor group given, just "." or ":". */
- return "can not omit both user and group";
- else
- /* "user.". */
- use_login_group = 1;
- }
- else
- {
- /* Explicit group. */
- *groupname = strdup (cp);
- if (*groupname == NULL)
- return tired;
- grp = getgrnam (cp);
- if (grp == NULL)
- {
- if (!isnumber (cp))
- return "invalid group";
- *gid = atoi (cp);
- }
- else
- *gid = grp->gr_gid;
- endgrent (); /* Save a file descriptor. */
- }
- }
-
- /* Parse the user name, now that any group has been removed. */
-
- if (name[0] == '\0')
- /* No user name was given, just a group. */
- return NULL;
-
- *username = strdup (name);
- if (*username == NULL)
- return tired;
-
- pwd = getpwnam (name);
- if (pwd == NULL)
- {
- if (!isnumber (name))
- return "invalid user";
- if (use_login_group)
- return "cannot get the login group of a numeric UID";
- *uid = atoi (name);
- }
- else
- {
- *uid = pwd->pw_uid;
- if (use_login_group)
- {
- *gid = pwd->pw_gid;
- grp = getgrgid (pwd->pw_gid);
- if (grp == NULL)
- {
- *groupname = malloc (15);
- if (*groupname == NULL)
- return tired;
- sprintf (*groupname, "%u", pwd->pw_gid);
- }
- else
- {
- *groupname = strdup (grp->gr_name);
- if (*groupname == NULL)
- return tired;
- }
- endgrent ();
- }
- }
- endpwent ();
- return NULL;
-}
-
-/* Return nonzero if STR represents an unsigned decimal integer,
- otherwise return 0. */
-
-static int
-isnumber (str)
- char *str;
-{
- for (; *str; str++)
- if (!isdigit (*str))
- return 0;
- return 1;
-}
diff --git a/gnu/usr.bin/cpio/xmalloc.c b/gnu/usr.bin/cpio/xmalloc.c
deleted file mode 100644
index f989004bebcd..000000000000
--- a/gnu/usr.bin/cpio/xmalloc.c
+++ /dev/null
@@ -1,65 +0,0 @@
-/* xmalloc.c -- malloc with out of memory checking
- Copyright (C) 1990, 1991 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-#ifdef STDC_HEADERS
-#include <stdlib.h>
-#else
-char *malloc ();
-char *realloc ();
-void free ();
-#endif
-
-void error ();
-
-/* Allocate N bytes of memory dynamically, with error checking. */
-
-char *
-xmalloc (n)
- unsigned n;
-{
- char *p;
-
- p = malloc (n);
- if (p == 0)
- /* Must exit with 2 for `cmp'. */
- error (2, 0, "virtual memory exhausted");
- return p;
-}
-
-/* Change the size of an allocated block of memory P to N bytes,
- with error checking.
- If P is NULL, run xmalloc.
- If N is 0, run free and return NULL. */
-
-char *
-xrealloc (p, n)
- char *p;
- unsigned n;
-{
- if (p == 0)
- return xmalloc (n);
- if (n == 0)
- {
- free (p);
- return 0;
- }
- p = realloc (p, n);
- if (p == 0)
- /* Must exit with 2 for `cmp'. */
- error (2, 0, "virtual memory exhausted");
- return p;
-}