mirror of
https://github.com/opnsense/src.git
synced 2026-05-28 04:12:45 -04:00
Virgin import of GNU cpio v2.4.2.
This commit is contained in:
parent
67adaf175d
commit
e7fc40c22f
44 changed files with 1649 additions and 746 deletions
|
|
@ -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
|
||||
|
|
@ -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.
|
||||
|
|
@ -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
|
||||
|
|
@ -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 */
|
||||
|
|
@ -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 (×, 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, ×) < 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. */
|
||||
|
|
@ -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);
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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);
|
||||
|
|
@ -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>. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef 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__
|
||||
#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__ */
|
||||
|
||||
#else /* !HAVE_VPRINTF */
|
||||
|
||||
#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 */
|
||||
|
||||
#endif /* !HAVE_VPRINTF */
|
||||
|
||||
#ifdef STDC_HEADERS
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#else /* !STDC_HEADERS */
|
||||
#if STDC_HEADERS || _LIBC
|
||||
# include <stdlib.h>
|
||||
# include <string.h>
|
||||
#else
|
||||
void exit ();
|
||||
#endif /* !STDC_HEADERS */
|
||||
#endif
|
||||
|
||||
/* This variable is incremented each time `error' is called. */
|
||||
unsigned int error_message_count;
|
||||
|
||||
/* 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 _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
|
||||
|
||||
fprintf (stderr, "%s: ", program_name);
|
||||
#ifdef HAVE_VPRINTF
|
||||
if (error_print_progname)
|
||||
(*error_print_progname) ();
|
||||
else
|
||||
{
|
||||
fflush (stdout);
|
||||
fprintf (stderr, "%s: ", program_name);
|
||||
}
|
||||
|
||||
#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);
|
||||
|
|
@ -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)
|
||||
|
|
@ -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
|
||||
#if !S_IRUSR
|
||||
# if S_IREAD
|
||||
# define S_IRUSR S_IREAD
|
||||
# else
|
||||
# define S_IRUSR 00400
|
||||
# endif
|
||||
#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
|
||||
#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,
|
||||
|
|
@ -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,19 +20,24 @@
|
|||
along with this program; if not, write to the Free Software
|
||||
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#if !__STDC__ && !defined(const) && IN_GCC
|
||||
#define const
|
||||
#endif
|
||||
|
||||
/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>. */
|
||||
/* 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>
|
||||
#endif
|
||||
|
||||
#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>
|
||||
|
||||
/* Comment out all this code if we are using the GNU C Library, and are not
|
||||
|
|
@ -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
|
||||
/* 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 /* GNU C library. */
|
||||
#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] == ':')
|
||||
|
|
@ -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
|
||||
}
|
||||
|
|
@ -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>
|
||||
|
||||
|
|
@ -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];
|
||||
|
|
@ -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;
|
||||
|
|
@ -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, ©_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;
|
||||
|
|
@ -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);
|
||||
1
contrib/cpio/safe-stat.h
Normal file
1
contrib/cpio/safe-stat.h
Normal file
|
|
@ -0,0 +1 @@
|
|||
#define SAFE_STAT(path,pbuf) stat(path,pbuf)
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
277
contrib/cpio/userspec.c
Normal file
277
contrib/cpio/userspec.c
Normal file
|
|
@ -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
|
||||
|
|
@ -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)
|
||||
if (swapping_halfwords)
|
||||
{
|
||||
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);
|
||||
int complete_words;
|
||||
complete_words = output_size / 4;
|
||||
swahw_array (output_buffer, complete_words);
|
||||
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;
|
||||
swab_array (output_buffer, 2 * complete_words);
|
||||
}
|
||||
complete_words = output_size / 4;
|
||||
if (complete_words > 0)
|
||||
else
|
||||
{
|
||||
swahw_array (out_buff, 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");
|
||||
int complete_halfwords;
|
||||
complete_halfwords = output_size /2;
|
||||
swab_array (output_buffer, complete_halfwords);
|
||||
}
|
||||
out_buff += (4 * complete_words);
|
||||
extra_bytes = output_size % 4;
|
||||
while (extra_bytes > 0)
|
||||
{
|
||||
left_overs[left_over_bytes++] = *out_buff++;
|
||||
--extra_bytes;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (sparse_flag)
|
||||
bytes_written = sparse_write (out_des, output_buffer, output_size);
|
||||
else
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
bytes_written = write (out_des, output_buffer, output_size);
|
||||
|
||||
if (bytes_written != output_size)
|
||||
{
|
||||
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,7 +440,7 @@ 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;
|
||||
|
|
@ -451,14 +451,109 @@ copy_files (in_des, out_des, num_bytes)
|
|||
while (num_bytes > 0)
|
||||
{
|
||||
if (input_size == 0)
|
||||
fill_input_buffer (in_des, io_block_size);
|
||||
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;
|
||||
}
|
||||
copy_buf_out (in_buff, out_des, size);
|
||||
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)
|
||||
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;
|
||||
}
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
|
@ -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";
|
||||
103
contrib/cpio/xmalloc.c
Normal file
103
contrib/cpio/xmalloc.c
Normal file
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
Loading…
Reference in a new issue