2005-05-01 06:59:28 +04:00
|
|
|
/* $NetBSD: options.c,v 1.85 2005/05/01 02:59:28 christos Exp $ */
|
1995-03-21 12:01:59 +03:00
|
|
|
|
1994-06-13 20:13:35 +04:00
|
|
|
/*-
|
2003-10-13 11:41:22 +04:00
|
|
|
* Copyright (c) 1992 Keith Muller.
|
1994-06-13 20:13:35 +04:00
|
|
|
* Copyright (c) 1992, 1993
|
|
|
|
* The Regents of the University of California. All rights reserved.
|
|
|
|
*
|
|
|
|
* This code is derived from software contributed to Berkeley by
|
|
|
|
* Keith Muller of the University of California, San Diego.
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
* are met:
|
|
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
2003-08-07 13:05:01 +04:00
|
|
|
* 3. Neither the name of the University nor the names of its contributors
|
|
|
|
* may be used to endorse or promote products derived from this software
|
|
|
|
* without specific prior written permission.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
|
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
|
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
|
|
* SUCH DAMAGE.
|
|
|
|
*/
|
|
|
|
|
2003-10-27 03:12:41 +03:00
|
|
|
#if HAVE_NBTOOL_CONFIG_H
|
|
|
|
#include "nbtool_config.h"
|
|
|
|
#endif
|
|
|
|
|
1997-07-21 00:32:15 +04:00
|
|
|
#include <sys/cdefs.h>
|
2003-10-27 03:12:41 +03:00
|
|
|
#if !defined(lint)
|
1995-03-21 12:01:59 +03:00
|
|
|
#if 0
|
|
|
|
static char sccsid[] = "@(#)options.c 8.2 (Berkeley) 4/18/94";
|
|
|
|
#else
|
2005-05-01 06:59:28 +04:00
|
|
|
__RCSID("$NetBSD: options.c,v 1.85 2005/05/01 02:59:28 christos Exp $");
|
1995-03-21 12:01:59 +03:00
|
|
|
#endif
|
1994-06-13 20:13:35 +04:00
|
|
|
#endif /* not lint */
|
|
|
|
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/time.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <sys/param.h>
|
|
|
|
#include <ctype.h>
|
2002-10-12 19:39:29 +04:00
|
|
|
#include <errno.h>
|
2004-06-21 02:20:14 +04:00
|
|
|
#if HAVE_NBTOOL_CONFIG_H
|
|
|
|
#include "compat_getopt.h"
|
|
|
|
#else
|
2002-02-01 01:43:33 +03:00
|
|
|
#include <getopt.h>
|
2004-06-21 02:20:14 +04:00
|
|
|
#endif
|
2002-02-01 01:43:33 +03:00
|
|
|
#include <limits.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
1994-06-13 20:13:35 +04:00
|
|
|
#include <string.h>
|
|
|
|
#include <unistd.h>
|
2002-10-12 19:39:29 +04:00
|
|
|
#include <paths.h>
|
1994-06-13 20:13:35 +04:00
|
|
|
#include "pax.h"
|
|
|
|
#include "options.h"
|
|
|
|
#include "cpio.h"
|
|
|
|
#include "tar.h"
|
|
|
|
#include "extern.h"
|
2002-02-02 15:34:39 +03:00
|
|
|
#ifndef SMALL
|
2002-01-24 10:45:33 +03:00
|
|
|
#include "mtree.h"
|
2002-02-02 15:34:39 +03:00
|
|
|
#endif /* SMALL */
|
1994-06-13 20:13:35 +04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Routines which handle command line options
|
|
|
|
*/
|
|
|
|
|
1999-02-07 03:56:55 +03:00
|
|
|
static int nopids; /* tar mode: suppress "pids" for -p option */
|
2004-05-11 21:12:26 +04:00
|
|
|
static char flgch[] = FLGCH; /* list of all possible flags (pax) */
|
1994-06-13 20:13:35 +04:00
|
|
|
static OPLIST *ophead = NULL; /* head for format specific options -x */
|
|
|
|
static OPLIST *optail = NULL; /* option tail */
|
|
|
|
|
2001-10-25 09:33:32 +04:00
|
|
|
static int no_op(void);
|
|
|
|
static void printflg(unsigned int);
|
|
|
|
static int c_frmt(const void *, const void *);
|
|
|
|
static off_t str_offt(char *);
|
2002-10-12 19:39:29 +04:00
|
|
|
static char *getline(FILE *fp);
|
2001-10-25 09:33:32 +04:00
|
|
|
static void pax_options(int, char **);
|
|
|
|
static void pax_usage(void);
|
|
|
|
static void tar_options(int, char **);
|
|
|
|
static void tar_usage(void);
|
|
|
|
static void cpio_options(int, char **);
|
|
|
|
static void cpio_usage(void);
|
1994-06-13 20:13:35 +04:00
|
|
|
|
2002-10-12 19:39:29 +04:00
|
|
|
/* errors from getline */
|
|
|
|
#define GETLINE_FILE_CORRUPT 1
|
|
|
|
#define GETLINE_OUT_OF_MEM 2
|
|
|
|
static int getline_error;
|
1999-10-23 00:59:08 +04:00
|
|
|
|
2003-02-25 16:36:59 +03:00
|
|
|
#define BZIP2_CMD "bzip2" /* command to run as bzip2 */
|
1996-03-27 02:54:13 +03:00
|
|
|
#define GZIP_CMD "gzip" /* command to run as gzip */
|
|
|
|
#define COMPRESS_CMD "compress" /* command to run as compress */
|
|
|
|
|
2002-10-15 20:16:29 +04:00
|
|
|
/*
|
|
|
|
* Long options.
|
|
|
|
*/
|
|
|
|
#define OPT_USE_COMPRESS_PROGRAM 0
|
|
|
|
#define OPT_CHECKPOINT 1
|
|
|
|
#define OPT_UNLINK 2
|
|
|
|
#define OPT_HELP 3
|
|
|
|
#define OPT_ATIME_PRESERVE 4
|
|
|
|
#define OPT_IGNORE_FAILED_READ 5
|
|
|
|
#define OPT_REMOVE_FILES 6
|
|
|
|
#define OPT_NULL 7
|
|
|
|
#define OPT_TOTALS 8
|
|
|
|
#define OPT_VERSION 9
|
|
|
|
#define OPT_EXCLUDE 10
|
|
|
|
#define OPT_BLOCK_COMPRESS 11
|
|
|
|
#define OPT_NORECURSE 12
|
|
|
|
#define OPT_FORCE_LOCAL 13
|
|
|
|
#define OPT_INSECURE 14
|
2002-10-16 07:46:07 +04:00
|
|
|
#define OPT_STRICT 15
|
2004-09-27 03:46:00 +04:00
|
|
|
#define OPT_SPARSE 16
|
2004-10-23 01:00:18 +04:00
|
|
|
#if !HAVE_NBTOOL_CONFIG_H
|
2004-10-17 22:49:55 +04:00
|
|
|
#define OPT_CHROOT 17
|
2004-10-23 01:00:18 +04:00
|
|
|
#endif
|
2002-10-15 20:16:29 +04:00
|
|
|
|
1994-06-13 20:13:35 +04:00
|
|
|
/*
|
|
|
|
* Format specific routine table - MUST BE IN SORTED ORDER BY NAME
|
|
|
|
* (see pax.h for description of each function)
|
|
|
|
*
|
2000-02-17 06:12:22 +03:00
|
|
|
* name, blksz, hdsz, udev, hlk, blkagn, inhead, id, st_read,
|
1994-06-13 20:13:35 +04:00
|
|
|
* read, end_read, st_write, write, end_write, trail,
|
2004-09-22 18:52:00 +04:00
|
|
|
* subtrail, rd_data, wr_data, options
|
1994-06-13 20:13:35 +04:00
|
|
|
*/
|
|
|
|
|
|
|
|
FSUB fsub[] = {
|
|
|
|
/* 0: OLD BINARY CPIO */
|
1997-07-21 00:32:15 +04:00
|
|
|
{ "bcpio", 5120, sizeof(HD_BCPIO), 1, 0, 0, 1, bcpio_id, cpio_strd,
|
|
|
|
bcpio_rd, bcpio_endrd, cpio_stwr, bcpio_wr, cpio_endwr, NULL,
|
|
|
|
cpio_subtrail, rd_wrfile, wr_rdfile, bad_opt },
|
1994-06-13 20:13:35 +04:00
|
|
|
|
|
|
|
/* 1: OLD OCTAL CHARACTER CPIO */
|
1997-07-21 00:32:15 +04:00
|
|
|
{ "cpio", 5120, sizeof(HD_CPIO), 1, 0, 0, 1, cpio_id, cpio_strd,
|
|
|
|
cpio_rd, cpio_endrd, cpio_stwr, cpio_wr, cpio_endwr, NULL,
|
|
|
|
cpio_subtrail, rd_wrfile, wr_rdfile, bad_opt },
|
1994-06-13 20:13:35 +04:00
|
|
|
|
|
|
|
/* 2: SVR4 HEX CPIO */
|
1997-07-21 00:32:15 +04:00
|
|
|
{ "sv4cpio", 5120, sizeof(HD_VCPIO), 1, 0, 0, 1, vcpio_id, cpio_strd,
|
|
|
|
vcpio_rd, vcpio_endrd, cpio_stwr, vcpio_wr, cpio_endwr, NULL,
|
|
|
|
cpio_subtrail, rd_wrfile, wr_rdfile, bad_opt },
|
1994-06-13 20:13:35 +04:00
|
|
|
|
|
|
|
/* 3: SVR4 HEX CPIO WITH CRC */
|
1997-07-21 00:32:15 +04:00
|
|
|
{ "sv4crc", 5120, sizeof(HD_VCPIO), 1, 0, 0, 1, crc_id, crc_strd,
|
|
|
|
vcpio_rd, vcpio_endrd, crc_stwr, vcpio_wr, cpio_endwr, NULL,
|
|
|
|
cpio_subtrail, rd_wrfile, wr_rdfile, bad_opt },
|
1994-06-13 20:13:35 +04:00
|
|
|
|
|
|
|
/* 4: OLD TAR */
|
1997-07-21 00:32:15 +04:00
|
|
|
{ "tar", 10240, BLKMULT, 0, 1, BLKMULT, 0, tar_id, no_op,
|
1994-06-13 20:13:35 +04:00
|
|
|
tar_rd, tar_endrd, no_op, tar_wr, tar_endwr, tar_trail,
|
1997-07-21 00:32:15 +04:00
|
|
|
NULL, rd_wrfile, wr_rdfile, tar_opt },
|
1994-06-13 20:13:35 +04:00
|
|
|
|
|
|
|
/* 5: POSIX USTAR */
|
1997-07-21 00:32:15 +04:00
|
|
|
{ "ustar", 10240, BLKMULT, 0, 1, BLKMULT, 0, ustar_id, ustar_strd,
|
1994-06-13 20:13:35 +04:00
|
|
|
ustar_rd, tar_endrd, ustar_stwr, ustar_wr, tar_endwr, tar_trail,
|
1997-07-21 00:32:15 +04:00
|
|
|
NULL, rd_wrfile, wr_rdfile, bad_opt }
|
1994-06-13 20:13:35 +04:00
|
|
|
};
|
1998-03-06 12:13:01 +03:00
|
|
|
#define F_BCPIO 0 /* old binary cpio format */
|
|
|
|
#define F_CPIO 1 /* old octal character cpio format */
|
|
|
|
#define F_SV4CPIO 2 /* SVR4 hex cpio format */
|
|
|
|
#define F_SV4CRC 3 /* SVR4 hex with crc cpio format */
|
1999-02-07 03:56:55 +03:00
|
|
|
#define F_TAR 4 /* old V7 UNIX tar format */
|
1998-03-06 12:13:01 +03:00
|
|
|
#define F_USTAR 5 /* ustar format */
|
|
|
|
#define DEFLT F_USTAR /* default write format from list above */
|
1994-06-13 20:13:35 +04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* ford is the archive search order used by get_arc() to determine what kind
|
2003-02-02 13:21:13 +03:00
|
|
|
* of archive we are dealing with. This helps to properly id archive formats
|
1994-06-13 20:13:35 +04:00
|
|
|
* some formats may be subsets of others....
|
|
|
|
*/
|
1998-03-06 12:13:01 +03:00
|
|
|
int ford[] = {F_USTAR, F_TAR, F_SV4CRC, F_SV4CPIO, F_CPIO, F_BCPIO, -1};
|
1994-06-13 20:13:35 +04:00
|
|
|
|
2004-06-19 06:27:00 +04:00
|
|
|
/*
|
|
|
|
* filename record separator
|
|
|
|
*/
|
|
|
|
int sep = '\n';
|
|
|
|
|
1994-06-13 20:13:35 +04:00
|
|
|
/*
|
|
|
|
* options()
|
|
|
|
* figure out if we are pax, tar or cpio. Call the appropriate options
|
|
|
|
* parser
|
|
|
|
*/
|
|
|
|
|
|
|
|
void
|
1997-01-11 05:04:27 +03:00
|
|
|
options(int argc, char **argv)
|
1994-06-13 20:13:35 +04:00
|
|
|
{
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Are we acting like pax, tar or cpio (based on argv[0])
|
|
|
|
*/
|
|
|
|
if ((argv0 = strrchr(argv[0], '/')) != NULL)
|
|
|
|
argv0++;
|
|
|
|
else
|
|
|
|
argv0 = argv[0];
|
|
|
|
|
|
|
|
if (strcmp(NM_TAR, argv0) == 0)
|
2002-11-27 21:40:34 +03:00
|
|
|
tar_options(argc, argv);
|
1994-06-13 20:13:35 +04:00
|
|
|
else if (strcmp(NM_CPIO, argv0) == 0)
|
2002-11-27 21:40:34 +03:00
|
|
|
cpio_options(argc, argv);
|
1998-07-28 15:41:40 +04:00
|
|
|
else {
|
|
|
|
argv0 = NM_PAX;
|
2002-11-27 21:40:34 +03:00
|
|
|
pax_options(argc, argv);
|
1998-07-28 15:41:40 +04:00
|
|
|
}
|
1994-06-13 20:13:35 +04:00
|
|
|
}
|
|
|
|
|
2002-10-15 20:16:29 +04:00
|
|
|
struct option pax_longopts[] = {
|
|
|
|
{ "insecure", no_argument, 0,
|
|
|
|
OPT_INSECURE },
|
2002-10-17 01:45:31 +04:00
|
|
|
{ "force-local", no_argument, 0,
|
|
|
|
OPT_FORCE_LOCAL },
|
2005-04-24 07:39:26 +04:00
|
|
|
{ 0, 0, 0 },
|
2002-10-15 20:16:29 +04:00
|
|
|
};
|
|
|
|
|
1994-06-13 20:13:35 +04:00
|
|
|
/*
|
|
|
|
* pax_options()
|
|
|
|
* look at the user specified flags. set globals as required and check if
|
|
|
|
* the user specified a legal set of flags. If not, complain and exit
|
|
|
|
*/
|
|
|
|
|
|
|
|
static void
|
1997-01-11 05:04:27 +03:00
|
|
|
pax_options(int argc, char **argv)
|
1994-06-13 20:13:35 +04:00
|
|
|
{
|
1997-01-11 05:04:27 +03:00
|
|
|
int c;
|
|
|
|
int i;
|
1994-06-13 20:13:35 +04:00
|
|
|
unsigned int flg = 0;
|
|
|
|
unsigned int bflg = 0;
|
1997-01-11 05:04:27 +03:00
|
|
|
char *pt;
|
2000-02-17 06:12:22 +03:00
|
|
|
FSUB tmp;
|
1994-06-13 20:13:35 +04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* process option flags
|
|
|
|
*/
|
2002-10-15 20:16:29 +04:00
|
|
|
while ((c = getopt_long(argc, argv,
|
2004-06-19 06:27:00 +04:00
|
|
|
"0ab:cdf:ijklno:p:rs:tuvwx:zAB:DE:G:HLMN:OPT:U:XYZ",
|
2002-10-15 20:16:29 +04:00
|
|
|
pax_longopts, NULL)) != -1) {
|
1994-06-13 20:13:35 +04:00
|
|
|
switch (c) {
|
2004-06-19 06:27:00 +04:00
|
|
|
case '0':
|
|
|
|
sep = '\0';
|
|
|
|
break;
|
1994-06-13 20:13:35 +04:00
|
|
|
case 'a':
|
|
|
|
/*
|
|
|
|
* append
|
|
|
|
*/
|
|
|
|
flg |= AF;
|
|
|
|
break;
|
|
|
|
case 'b':
|
|
|
|
/*
|
|
|
|
* specify blocksize
|
|
|
|
*/
|
|
|
|
flg |= BF;
|
|
|
|
if ((wrblksz = (int)str_offt(optarg)) <= 0) {
|
1997-07-21 00:32:15 +04:00
|
|
|
tty_warn(1, "Invalid block size %s", optarg);
|
1994-06-13 20:13:35 +04:00
|
|
|
pax_usage();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 'c':
|
|
|
|
/*
|
|
|
|
* inverse match on patterns
|
|
|
|
*/
|
|
|
|
cflag = 1;
|
|
|
|
flg |= CF;
|
|
|
|
break;
|
|
|
|
case 'd':
|
|
|
|
/*
|
|
|
|
* match only dir on extract, not the subtree at dir
|
|
|
|
*/
|
|
|
|
dflag = 1;
|
|
|
|
flg |= DF;
|
|
|
|
break;
|
|
|
|
case 'f':
|
|
|
|
/*
|
|
|
|
* filename where the archive is stored
|
|
|
|
*/
|
|
|
|
arcname = optarg;
|
|
|
|
flg |= FF;
|
|
|
|
break;
|
|
|
|
case 'i':
|
|
|
|
/*
|
|
|
|
* interactive file rename
|
|
|
|
*/
|
|
|
|
iflag = 1;
|
|
|
|
flg |= IF;
|
|
|
|
break;
|
2003-04-01 00:10:08 +04:00
|
|
|
case 'j':
|
|
|
|
/*
|
|
|
|
* pass through bzip2
|
|
|
|
*/
|
|
|
|
jflag = 1;
|
|
|
|
gzip_program = BZIP2_CMD;
|
|
|
|
break;
|
1994-06-13 20:13:35 +04:00
|
|
|
case 'k':
|
|
|
|
/*
|
|
|
|
* do not clobber files that exist
|
|
|
|
*/
|
|
|
|
kflag = 1;
|
|
|
|
flg |= KF;
|
|
|
|
break;
|
|
|
|
case 'l':
|
|
|
|
/*
|
|
|
|
* try to link src to dest with copy (-rw)
|
|
|
|
*/
|
|
|
|
lflag = 1;
|
|
|
|
flg |= LF;
|
|
|
|
break;
|
|
|
|
case 'n':
|
|
|
|
/*
|
|
|
|
* select first match for a pattern only
|
|
|
|
*/
|
|
|
|
nflag = 1;
|
|
|
|
flg |= NF;
|
|
|
|
break;
|
|
|
|
case 'o':
|
|
|
|
/*
|
|
|
|
* pass format specific options
|
|
|
|
*/
|
|
|
|
flg |= OF;
|
|
|
|
if (opt_add(optarg) < 0)
|
|
|
|
pax_usage();
|
|
|
|
break;
|
|
|
|
case 'p':
|
|
|
|
/*
|
|
|
|
* specify file characteristic options
|
|
|
|
*/
|
|
|
|
for (pt = optarg; *pt != '\0'; ++pt) {
|
|
|
|
switch(*pt) {
|
|
|
|
case 'a':
|
|
|
|
/*
|
|
|
|
* do not preserve access time
|
|
|
|
*/
|
|
|
|
patime = 0;
|
|
|
|
break;
|
|
|
|
case 'e':
|
|
|
|
/*
|
|
|
|
* preserve user id, group id, file
|
|
|
|
* mode, access/modification times
|
1999-11-01 04:35:58 +03:00
|
|
|
* and file flags.
|
1994-06-13 20:13:35 +04:00
|
|
|
*/
|
|
|
|
pids = 1;
|
|
|
|
pmode = 1;
|
|
|
|
patime = 1;
|
|
|
|
pmtime = 1;
|
1999-11-01 04:35:58 +03:00
|
|
|
pfflags = 1;
|
|
|
|
break;
|
1999-11-07 18:57:31 +03:00
|
|
|
#if 0
|
1999-11-01 04:35:58 +03:00
|
|
|
case 'f':
|
|
|
|
/*
|
|
|
|
* do not preserve file flags
|
|
|
|
*/
|
|
|
|
pfflags = 0;
|
1994-06-13 20:13:35 +04:00
|
|
|
break;
|
1999-11-07 18:57:31 +03:00
|
|
|
#endif
|
1994-06-13 20:13:35 +04:00
|
|
|
case 'm':
|
|
|
|
/*
|
|
|
|
* do not preserve modification time
|
|
|
|
*/
|
|
|
|
pmtime = 0;
|
|
|
|
break;
|
|
|
|
case 'o':
|
|
|
|
/*
|
|
|
|
* preserve uid/gid
|
|
|
|
*/
|
|
|
|
pids = 1;
|
|
|
|
break;
|
|
|
|
case 'p':
|
|
|
|
/*
|
2002-01-24 10:45:33 +03:00
|
|
|
* preserve file mode bits
|
1994-06-13 20:13:35 +04:00
|
|
|
*/
|
|
|
|
pmode = 1;
|
|
|
|
break;
|
|
|
|
default:
|
2002-10-12 19:39:29 +04:00
|
|
|
tty_warn(1, "Invalid -p string: %c",
|
|
|
|
*pt);
|
1994-06-13 20:13:35 +04:00
|
|
|
pax_usage();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
flg |= PF;
|
|
|
|
break;
|
|
|
|
case 'r':
|
|
|
|
/*
|
|
|
|
* read the archive
|
|
|
|
*/
|
|
|
|
flg |= RF;
|
|
|
|
break;
|
|
|
|
case 's':
|
|
|
|
/*
|
|
|
|
* file name substitution name pattern
|
|
|
|
*/
|
|
|
|
if (rep_add(optarg) < 0) {
|
|
|
|
pax_usage();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
flg |= SF;
|
|
|
|
break;
|
|
|
|
case 't':
|
|
|
|
/*
|
|
|
|
* preserve access time on filesystem nodes we read
|
|
|
|
*/
|
|
|
|
tflag = 1;
|
|
|
|
flg |= TF;
|
|
|
|
break;
|
|
|
|
case 'u':
|
|
|
|
/*
|
|
|
|
* ignore those older files
|
|
|
|
*/
|
|
|
|
uflag = 1;
|
|
|
|
flg |= UF;
|
|
|
|
break;
|
|
|
|
case 'v':
|
|
|
|
/*
|
|
|
|
* verbose operation mode
|
|
|
|
*/
|
|
|
|
vflag = 1;
|
|
|
|
flg |= VF;
|
|
|
|
break;
|
|
|
|
case 'w':
|
|
|
|
/*
|
|
|
|
* write an archive
|
|
|
|
*/
|
|
|
|
flg |= WF;
|
|
|
|
break;
|
|
|
|
case 'x':
|
|
|
|
/*
|
|
|
|
* specify an archive format on write
|
|
|
|
*/
|
|
|
|
tmp.name = optarg;
|
1997-07-21 00:32:15 +04:00
|
|
|
frmt = (FSUB *)bsearch((void *)&tmp, (void *)fsub,
|
|
|
|
sizeof(fsub)/sizeof(FSUB), sizeof(FSUB), c_frmt);
|
|
|
|
if (frmt != NULL) {
|
1994-06-13 20:13:35 +04:00
|
|
|
flg |= XF;
|
|
|
|
break;
|
|
|
|
}
|
1997-07-21 00:32:15 +04:00
|
|
|
tty_warn(1, "Unknown -x format: %s", optarg);
|
1994-06-13 20:13:35 +04:00
|
|
|
(void)fputs("pax: Known -x formats are:", stderr);
|
|
|
|
for (i = 0; i < (sizeof(fsub)/sizeof(FSUB)); ++i)
|
|
|
|
(void)fprintf(stderr, " %s", fsub[i].name);
|
|
|
|
(void)fputs("\n\n", stderr);
|
|
|
|
pax_usage();
|
|
|
|
break;
|
1996-03-27 02:54:13 +03:00
|
|
|
case 'z':
|
|
|
|
/*
|
|
|
|
* use gzip. Non standard option.
|
|
|
|
*/
|
|
|
|
gzip_program = GZIP_CMD;
|
|
|
|
break;
|
1999-08-24 11:57:06 +04:00
|
|
|
case 'A':
|
|
|
|
Aflag = 1;
|
|
|
|
flg |= CAF;
|
|
|
|
break;
|
1994-06-13 20:13:35 +04:00
|
|
|
case 'B':
|
|
|
|
/*
|
|
|
|
* non-standard option on number of bytes written on a
|
|
|
|
* single archive volume.
|
|
|
|
*/
|
|
|
|
if ((wrlimit = str_offt(optarg)) <= 0) {
|
1997-07-21 00:32:15 +04:00
|
|
|
tty_warn(1, "Invalid write limit %s", optarg);
|
1994-06-13 20:13:35 +04:00
|
|
|
pax_usage();
|
|
|
|
}
|
|
|
|
if (wrlimit % BLKMULT) {
|
1997-07-21 00:32:15 +04:00
|
|
|
tty_warn(1,
|
|
|
|
"Write limit is not a %d byte multiple",
|
1994-06-13 20:13:35 +04:00
|
|
|
BLKMULT);
|
|
|
|
pax_usage();
|
|
|
|
}
|
|
|
|
flg |= CBF;
|
|
|
|
break;
|
|
|
|
case 'D':
|
|
|
|
/*
|
|
|
|
* On extraction check file inode change time before the
|
|
|
|
* modification of the file name. Non standard option.
|
|
|
|
*/
|
|
|
|
Dflag = 1;
|
|
|
|
flg |= CDF;
|
|
|
|
break;
|
|
|
|
case 'E':
|
|
|
|
/*
|
|
|
|
* non-standard limit on read faults
|
|
|
|
* 0 indicates stop after first error, values
|
2004-05-11 21:12:26 +04:00
|
|
|
* indicate a limit, "none" try forever
|
1994-06-13 20:13:35 +04:00
|
|
|
*/
|
|
|
|
flg |= CEF;
|
2004-05-11 21:12:26 +04:00
|
|
|
if (strcmp(none, optarg) == 0)
|
1994-06-13 20:13:35 +04:00
|
|
|
maxflt = -1;
|
|
|
|
else if ((maxflt = atoi(optarg)) < 0) {
|
1997-07-21 00:32:15 +04:00
|
|
|
tty_warn(1,
|
|
|
|
"Error count value must be positive");
|
1994-06-13 20:13:35 +04:00
|
|
|
pax_usage();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 'G':
|
|
|
|
/*
|
|
|
|
* non-standard option for selecting files within an
|
|
|
|
* archive by group (gid or name)
|
|
|
|
*/
|
|
|
|
if (grp_add(optarg) < 0) {
|
|
|
|
pax_usage();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
flg |= CGF;
|
|
|
|
break;
|
|
|
|
case 'H':
|
|
|
|
/*
|
|
|
|
* follow command line symlinks only
|
|
|
|
*/
|
|
|
|
Hflag = 1;
|
|
|
|
flg |= CHF;
|
|
|
|
break;
|
|
|
|
case 'L':
|
|
|
|
/*
|
|
|
|
* follow symlinks
|
|
|
|
*/
|
|
|
|
Lflag = 1;
|
|
|
|
flg |= CLF;
|
|
|
|
break;
|
2002-02-02 15:34:39 +03:00
|
|
|
#ifdef SMALL
|
|
|
|
case 'M':
|
|
|
|
case 'N':
|
|
|
|
tty_warn(1, "Support for -%c is not compiled in", c);
|
|
|
|
exit(1);
|
|
|
|
#else /* !SMALL */
|
Implement -M flag: During a write or copy operation, treat the list of
files on standard input as an mtree(8) `specfile' specification, and
write or copy only those items in the specfile.
If the file exists in the underlying file system, its permissions and
modification time will be used unless specifically overridden by the
specfile. An error will be raised if the type of entry in the specfile
conflicts with that of an existing file.
Otherwise, it is necessary to specify at least the following parameters
in the specfile: type, mode, gname or gid, and uname or uid, device
(in the case of block or character devices), and link (in the case of
symbolic links). If time isn't provided, the current time will be used.
2001-10-25 12:51:50 +04:00
|
|
|
case 'M':
|
|
|
|
/*
|
|
|
|
* Treat list of filenames on stdin as an
|
|
|
|
* mtree(8) specfile. Non standard option.
|
|
|
|
*/
|
|
|
|
Mflag = 1;
|
|
|
|
flg |= CMF;
|
|
|
|
break;
|
2002-01-24 10:45:33 +03:00
|
|
|
case 'N':
|
|
|
|
/*
|
|
|
|
* Use alternative directory for user db lookups.
|
|
|
|
*/
|
2002-01-26 05:22:54 +03:00
|
|
|
if (!setup_getid(optarg)) {
|
|
|
|
tty_warn(1,
|
|
|
|
"Unable to use user and group databases in `%s'",
|
|
|
|
optarg);
|
2002-01-24 10:45:33 +03:00
|
|
|
pax_usage();
|
2002-01-26 05:22:54 +03:00
|
|
|
}
|
2002-01-24 10:45:33 +03:00
|
|
|
break;
|
2002-02-02 15:34:39 +03:00
|
|
|
#endif /* !SMALL */
|
2000-03-30 21:53:04 +04:00
|
|
|
case 'O':
|
|
|
|
/*
|
|
|
|
* Force one volume. Non standard option.
|
|
|
|
*/
|
|
|
|
force_one_volume = 1;
|
|
|
|
break;
|
1994-06-13 20:13:35 +04:00
|
|
|
case 'P':
|
|
|
|
/*
|
|
|
|
* do NOT follow symlinks (default)
|
|
|
|
*/
|
|
|
|
Lflag = 0;
|
|
|
|
flg |= CPF;
|
|
|
|
break;
|
|
|
|
case 'T':
|
|
|
|
/*
|
|
|
|
* non-standard option for selecting files within an
|
|
|
|
* archive by modification time range (lower,upper)
|
|
|
|
*/
|
|
|
|
if (trng_add(optarg) < 0) {
|
|
|
|
pax_usage();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
flg |= CTF;
|
|
|
|
break;
|
|
|
|
case 'U':
|
|
|
|
/*
|
|
|
|
* non-standard option for selecting files within an
|
|
|
|
* archive by user (uid or name)
|
|
|
|
*/
|
|
|
|
if (usr_add(optarg) < 0) {
|
|
|
|
pax_usage();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
flg |= CUF;
|
|
|
|
break;
|
|
|
|
case 'X':
|
|
|
|
/*
|
|
|
|
* do not pass over mount points in the file system
|
|
|
|
*/
|
|
|
|
Xflag = 1;
|
|
|
|
flg |= CXF;
|
|
|
|
break;
|
|
|
|
case 'Y':
|
|
|
|
/*
|
|
|
|
* On extraction check file inode change time after the
|
|
|
|
* modification of the file name. Non standard option.
|
|
|
|
*/
|
|
|
|
Yflag = 1;
|
|
|
|
flg |= CYF;
|
|
|
|
break;
|
|
|
|
case 'Z':
|
|
|
|
/*
|
|
|
|
* On extraction check modification time after the
|
|
|
|
* modification of the file name. Non standard option.
|
|
|
|
*/
|
|
|
|
Zflag = 1;
|
|
|
|
flg |= CZF;
|
|
|
|
break;
|
2002-10-15 20:16:29 +04:00
|
|
|
case OPT_INSECURE:
|
|
|
|
secure = 0;
|
|
|
|
break;
|
2002-10-17 01:45:31 +04:00
|
|
|
case OPT_FORCE_LOCAL:
|
|
|
|
forcelocal = 0;
|
|
|
|
break;
|
1994-06-13 20:13:35 +04:00
|
|
|
case '?':
|
|
|
|
default:
|
|
|
|
pax_usage();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* figure out the operation mode of pax read,write,extract,copy,append
|
|
|
|
* or list. check that we have not been given a bogus set of flags
|
|
|
|
* for the operation mode.
|
|
|
|
*/
|
|
|
|
if (ISLIST(flg)) {
|
|
|
|
act = LIST;
|
2002-10-12 19:39:29 +04:00
|
|
|
listf = stdout;
|
1994-06-13 20:13:35 +04:00
|
|
|
bflg = flg & BDLIST;
|
|
|
|
} else if (ISEXTRACT(flg)) {
|
|
|
|
act = EXTRACT;
|
|
|
|
bflg = flg & BDEXTR;
|
|
|
|
} else if (ISARCHIVE(flg)) {
|
|
|
|
act = ARCHIVE;
|
|
|
|
bflg = flg & BDARCH;
|
|
|
|
} else if (ISAPPND(flg)) {
|
|
|
|
act = APPND;
|
|
|
|
bflg = flg & BDARCH;
|
|
|
|
} else if (ISCOPY(flg)) {
|
|
|
|
act = COPY;
|
|
|
|
bflg = flg & BDCOPY;
|
|
|
|
} else
|
|
|
|
pax_usage();
|
|
|
|
if (bflg) {
|
|
|
|
printflg(flg);
|
|
|
|
pax_usage();
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* if we are writing (ARCHIVE) we use the default format if the user
|
|
|
|
* did not specify a format. when we write during an APPEND, we will
|
|
|
|
* adopt the format of the existing archive if none was supplied.
|
|
|
|
*/
|
|
|
|
if (!(flg & XF) && (act == ARCHIVE))
|
|
|
|
frmt = &(fsub[DEFLT]);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* process the args as they are interpreted by the operation mode
|
|
|
|
*/
|
|
|
|
switch (act) {
|
|
|
|
case LIST:
|
|
|
|
case EXTRACT:
|
|
|
|
for (; optind < argc; optind++)
|
2002-10-12 19:39:29 +04:00
|
|
|
if (pat_add(argv[optind], NULL) < 0)
|
1994-06-13 20:13:35 +04:00
|
|
|
pax_usage();
|
|
|
|
break;
|
|
|
|
case COPY:
|
|
|
|
if (optind >= argc) {
|
1997-07-21 00:32:15 +04:00
|
|
|
tty_warn(0, "Destination directory was not supplied");
|
1994-06-13 20:13:35 +04:00
|
|
|
pax_usage();
|
|
|
|
}
|
2002-10-13 15:31:02 +04:00
|
|
|
--argc;
|
|
|
|
dirptr = argv[argc];
|
2002-10-12 19:39:29 +04:00
|
|
|
if (mkpath(dirptr) < 0)
|
2003-01-16 00:56:46 +03:00
|
|
|
pax_usage();
|
1998-07-28 21:44:23 +04:00
|
|
|
/* FALLTHROUGH */
|
1994-06-13 20:13:35 +04:00
|
|
|
case ARCHIVE:
|
|
|
|
case APPND:
|
|
|
|
for (; optind < argc; optind++)
|
1999-10-23 00:59:08 +04:00
|
|
|
if (ftree_add(argv[optind], 0) < 0)
|
1994-06-13 20:13:35 +04:00
|
|
|
pax_usage();
|
|
|
|
/*
|
|
|
|
* no read errors allowed on updates/append operation!
|
|
|
|
*/
|
|
|
|
maxflt = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* tar_options()
|
|
|
|
* look at the user specified flags. set globals as required and check if
|
|
|
|
* the user specified a legal set of flags. If not, complain and exit
|
|
|
|
*/
|
|
|
|
|
2000-07-04 21:17:49 +04:00
|
|
|
struct option tar_longopts[] = {
|
|
|
|
{ "block-size", required_argument, 0, 'b' },
|
2003-02-25 16:36:59 +03:00
|
|
|
{ "bunzip2", no_argument, 0, 'j' },
|
|
|
|
{ "bzip2", no_argument, 0, 'j' },
|
2000-07-04 21:17:49 +04:00
|
|
|
{ "create", no_argument, 0, 'c' }, /* F */
|
|
|
|
/* -e -- no corresponding long option */
|
|
|
|
{ "file", required_argument, 0, 'f' },
|
|
|
|
{ "dereference", no_argument, 0, 'h' },
|
2003-04-08 19:13:10 +04:00
|
|
|
{ "keep-old-files", no_argument, 0, 'k' },
|
2000-07-04 21:17:49 +04:00
|
|
|
{ "one-file-system", no_argument, 0, 'l' },
|
|
|
|
{ "modification-time", no_argument, 0, 'm' },
|
|
|
|
{ "old-archive", no_argument, 0, 'o' },
|
|
|
|
{ "portability", no_argument, 0, 'o' },
|
|
|
|
{ "same-permissions", no_argument, 0, 'p' },
|
|
|
|
{ "preserve-permissions", no_argument, 0, 'p' },
|
|
|
|
{ "preserve", no_argument, 0, 'p' },
|
2002-10-15 18:58:53 +04:00
|
|
|
{ "fast-read", no_argument, 0, 'q' },
|
2000-07-04 21:17:49 +04:00
|
|
|
{ "append", no_argument, 0, 'r' }, /* F */
|
|
|
|
{ "update", no_argument, 0, 'u' }, /* F */
|
|
|
|
{ "list", no_argument, 0, 't' }, /* F */
|
|
|
|
{ "verbose", no_argument, 0, 'v' },
|
|
|
|
{ "interactive", no_argument, 0, 'w' },
|
|
|
|
{ "confirmation", no_argument, 0, 'w' },
|
|
|
|
{ "extract", no_argument, 0, 'x' }, /* F */
|
|
|
|
{ "get", no_argument, 0, 'x' }, /* F */
|
|
|
|
{ "gzip", no_argument, 0, 'z' },
|
|
|
|
{ "gunzip", no_argument, 0, 'z' },
|
|
|
|
{ "read-full-blocks", no_argument, 0, 'B' },
|
|
|
|
{ "directory", required_argument, 0, 'C' },
|
2003-07-08 10:00:48 +04:00
|
|
|
{ "to-stdout", no_argument, 0, 'O' },
|
2000-07-04 21:17:49 +04:00
|
|
|
{ "absolute-paths", no_argument, 0, 'P' },
|
2004-10-17 22:49:55 +04:00
|
|
|
{ "sparse", no_argument, 0, 'S' },
|
2002-10-12 19:39:29 +04:00
|
|
|
{ "files-from", required_argument, 0, 'T' },
|
2000-07-04 21:17:49 +04:00
|
|
|
{ "exclude-from", required_argument, 0, 'X' },
|
|
|
|
{ "compress", no_argument, 0, 'Z' },
|
|
|
|
{ "uncompress", no_argument, 0, 'Z' },
|
2002-10-16 07:46:07 +04:00
|
|
|
{ "strict", no_argument, 0,
|
|
|
|
OPT_STRICT },
|
2000-07-04 21:28:47 +04:00
|
|
|
{ "atime-preserve", no_argument, 0,
|
|
|
|
OPT_ATIME_PRESERVE },
|
2000-07-04 21:17:49 +04:00
|
|
|
{ "unlink", no_argument, 0,
|
|
|
|
OPT_UNLINK },
|
2000-07-04 21:24:47 +04:00
|
|
|
{ "use-compress-program", required_argument, 0,
|
|
|
|
OPT_USE_COMPRESS_PROGRAM },
|
2002-10-12 19:39:29 +04:00
|
|
|
{ "force-local", no_argument, 0,
|
|
|
|
OPT_FORCE_LOCAL },
|
2002-10-15 20:16:29 +04:00
|
|
|
{ "insecure", no_argument, 0,
|
|
|
|
OPT_INSECURE },
|
2002-12-08 04:35:12 +03:00
|
|
|
{ "exclude", required_argument, 0,
|
|
|
|
OPT_EXCLUDE },
|
2004-10-23 01:00:18 +04:00
|
|
|
#if !HAVE_NBTOOL_CONFIG_H
|
2004-10-17 22:49:55 +04:00
|
|
|
{ "chroot", no_argument, 0,
|
|
|
|
OPT_CHROOT },
|
2004-10-23 01:00:18 +04:00
|
|
|
#endif
|
2000-07-04 21:17:49 +04:00
|
|
|
#if 0 /* Not implemented */
|
|
|
|
{ "catenate", no_argument, 0, 'A' }, /* F */
|
|
|
|
{ "concatenate", no_argument, 0, 'A' }, /* F */
|
|
|
|
{ "diff", no_argument, 0, 'd' }, /* F */
|
|
|
|
{ "compare", no_argument, 0, 'd' }, /* F */
|
|
|
|
{ "checkpoint", no_argument, 0,
|
|
|
|
OPT_CHECKPOINT },
|
2000-07-04 21:28:47 +04:00
|
|
|
{ "help", no_argument, 0,
|
2000-07-04 21:17:49 +04:00
|
|
|
OPT_HELP },
|
|
|
|
{ "info-script", required_argument, 0, 'F' },
|
|
|
|
{ "new-volume-script", required_argument, 0, 'F' },
|
|
|
|
{ "incremental", no_argument, 0, 'G' },
|
|
|
|
{ "listed-incremental", required_argument, 0, 'g' },
|
|
|
|
{ "ignore-zeros", no_argument, 0, 'i' },
|
|
|
|
{ "ignore-failed-read", no_argument, 0,
|
|
|
|
OPT_IGNORE_FAILED_READ },
|
|
|
|
{ "starting-file", no_argument, 0, 'K' },
|
2002-10-17 01:45:31 +04:00
|
|
|
{ "tape-length", required_argument, 0, 'L' },
|
2000-07-04 21:17:49 +04:00
|
|
|
{ "multi-volume", no_argument, 0, 'M' },
|
|
|
|
{ "after-date", required_argument, 0, 'N' },
|
|
|
|
{ "newer", required_argument, 0, 'N' },
|
|
|
|
{ "record-number", no_argument, 0, 'R' },
|
|
|
|
{ "remove-files", no_argument, 0,
|
|
|
|
OPT_REMOVE_FILES },
|
|
|
|
{ "same-order", no_argument, 0, 's' },
|
|
|
|
{ "preserve-order", no_argument, 0, 's' },
|
|
|
|
{ "null", no_argument, 0,
|
|
|
|
OPT_NULL },
|
|
|
|
{ "totals", no_argument, 0,
|
|
|
|
OPT_TOTALS },
|
|
|
|
{ "volume-name", required_argument, 0, 'V' },
|
|
|
|
{ "label", required_argument, 0, 'V' },
|
|
|
|
{ "version", no_argument, 0,
|
|
|
|
OPT_VERSION },
|
|
|
|
{ "verify", no_argument, 0, 'W' },
|
|
|
|
{ "block-compress", no_argument, 0,
|
|
|
|
OPT_BLOCK_COMPRESS },
|
|
|
|
{ "norecurse", no_argument, 0,
|
|
|
|
OPT_NORECURSE },
|
|
|
|
#endif
|
|
|
|
{ 0, 0, 0, 0 },
|
|
|
|
};
|
|
|
|
|
1994-06-13 20:13:35 +04:00
|
|
|
static void
|
1997-01-11 05:04:27 +03:00
|
|
|
tar_options(int argc, char **argv)
|
1994-06-13 20:13:35 +04:00
|
|
|
{
|
1997-01-11 05:04:27 +03:00
|
|
|
int c;
|
1994-06-13 20:13:35 +04:00
|
|
|
int fstdin = 0;
|
2002-10-12 19:39:29 +04:00
|
|
|
int Oflag = 0;
|
|
|
|
int nincfiles = 0;
|
|
|
|
int incfiles_max = 0;
|
|
|
|
struct incfile {
|
|
|
|
char *file;
|
|
|
|
char *dir;
|
|
|
|
};
|
|
|
|
struct incfile *incfiles = NULL;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Set default values.
|
|
|
|
*/
|
|
|
|
rmleadslash = 1;
|
2002-10-16 22:53:40 +04:00
|
|
|
is_gnutar = 1;
|
1994-06-13 20:13:35 +04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* process option flags
|
|
|
|
*/
|
2002-10-12 19:39:29 +04:00
|
|
|
while ((c = getoldopt(argc, argv,
|
2004-09-27 03:46:00 +04:00
|
|
|
"+b:cef:hjklmopqrs:tuvwxzBC:HI:OPST:X:Z014578",
|
2000-07-04 21:17:49 +04:00
|
|
|
tar_longopts, NULL))
|
1997-09-14 18:54:32 +04:00
|
|
|
!= -1) {
|
1994-06-14 05:16:02 +04:00
|
|
|
switch(c) {
|
1994-06-13 20:13:35 +04:00
|
|
|
case 'b':
|
|
|
|
/*
|
2002-10-12 19:39:29 +04:00
|
|
|
* specify blocksize in 512-byte blocks
|
1994-06-13 20:13:35 +04:00
|
|
|
*/
|
1994-06-14 05:16:02 +04:00
|
|
|
if ((wrblksz = (int)str_offt(optarg)) <= 0) {
|
1997-07-21 00:32:15 +04:00
|
|
|
tty_warn(1, "Invalid block size %s", optarg);
|
1994-06-13 20:13:35 +04:00
|
|
|
tar_usage();
|
|
|
|
}
|
2002-10-12 19:39:29 +04:00
|
|
|
wrblksz *= 512; /* XXX - check for int oflow */
|
1994-06-13 20:13:35 +04:00
|
|
|
break;
|
|
|
|
case 'c':
|
|
|
|
/*
|
|
|
|
* create an archive
|
|
|
|
*/
|
|
|
|
act = ARCHIVE;
|
|
|
|
break;
|
|
|
|
case 'e':
|
|
|
|
/*
|
|
|
|
* stop after first error
|
|
|
|
*/
|
|
|
|
maxflt = 0;
|
|
|
|
break;
|
|
|
|
case 'f':
|
|
|
|
/*
|
|
|
|
* filename where the archive is stored
|
|
|
|
*/
|
1994-06-14 05:16:02 +04:00
|
|
|
if ((optarg[0] == '-') && (optarg[1]== '\0')) {
|
1994-06-13 20:13:35 +04:00
|
|
|
/*
|
|
|
|
* treat a - as stdin
|
|
|
|
*/
|
1994-06-14 05:16:02 +04:00
|
|
|
fstdin = 1;
|
2002-10-12 19:39:29 +04:00
|
|
|
arcname = NULL;
|
1994-06-13 20:13:35 +04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
fstdin = 0;
|
1994-06-14 05:16:02 +04:00
|
|
|
arcname = optarg;
|
1994-06-13 20:13:35 +04:00
|
|
|
break;
|
1999-08-24 12:00:03 +04:00
|
|
|
case 'h':
|
|
|
|
/*
|
2003-01-09 20:26:21 +03:00
|
|
|
* follow symlinks
|
1999-08-24 12:00:03 +04:00
|
|
|
*/
|
2003-01-09 20:26:21 +03:00
|
|
|
Lflag = 1;
|
1999-08-24 12:00:03 +04:00
|
|
|
break;
|
2003-02-25 16:36:59 +03:00
|
|
|
case 'j':
|
|
|
|
/*
|
|
|
|
* pass through bzip2. not a standard option
|
|
|
|
*/
|
|
|
|
jflag = 1;
|
|
|
|
gzip_program = BZIP2_CMD;
|
|
|
|
break;
|
2003-04-08 19:13:10 +04:00
|
|
|
case 'k':
|
|
|
|
/*
|
|
|
|
* do not clobber files that exist
|
|
|
|
*/
|
|
|
|
kflag = 1;
|
|
|
|
break;
|
1998-03-06 12:13:01 +03:00
|
|
|
case 'l':
|
|
|
|
/*
|
|
|
|
* do not pass over mount points in the file system
|
|
|
|
*/
|
|
|
|
Xflag = 1;
|
|
|
|
break;
|
1994-06-13 20:13:35 +04:00
|
|
|
case 'm':
|
|
|
|
/*
|
|
|
|
* do not preserve modification time
|
|
|
|
*/
|
|
|
|
pmtime = 0;
|
|
|
|
break;
|
|
|
|
case 'o':
|
1999-02-07 03:56:55 +03:00
|
|
|
/*
|
|
|
|
* This option does several things based on whether
|
|
|
|
* this is a create or extract operation.
|
|
|
|
*/
|
|
|
|
if (act == ARCHIVE) {
|
2002-10-16 07:46:07 +04:00
|
|
|
/* GNU tar: write V7 format archives. */
|
|
|
|
Oflag = 1;
|
1999-02-07 03:56:55 +03:00
|
|
|
/* 4.2BSD: don't add directory entries. */
|
|
|
|
if (opt_add("write_opt=nodir") < 0)
|
|
|
|
tar_usage();
|
|
|
|
|
|
|
|
} else {
|
|
|
|
/* SUS: don't preserve owner/group. */
|
|
|
|
pids = 0;
|
|
|
|
nopids = 1;
|
|
|
|
}
|
1994-06-13 20:13:35 +04:00
|
|
|
break;
|
2002-10-12 19:39:29 +04:00
|
|
|
case 'O':
|
|
|
|
Oflag = 1;
|
|
|
|
break;
|
1994-06-13 20:13:35 +04:00
|
|
|
case 'p':
|
|
|
|
/*
|
|
|
|
* preserve user id, group id, file
|
|
|
|
* mode, access/modification times
|
|
|
|
*/
|
1999-02-07 03:56:55 +03:00
|
|
|
if (!nopids)
|
|
|
|
pids = 1;
|
1994-06-13 20:13:35 +04:00
|
|
|
pmode = 1;
|
|
|
|
patime = 1;
|
|
|
|
pmtime = 1;
|
|
|
|
break;
|
2002-10-12 19:39:29 +04:00
|
|
|
case 'q':
|
|
|
|
/*
|
|
|
|
* select first match for a pattern only
|
|
|
|
*/
|
|
|
|
nflag = 1;
|
|
|
|
break;
|
1994-06-13 20:13:35 +04:00
|
|
|
case 'r':
|
|
|
|
case 'u':
|
|
|
|
/*
|
|
|
|
* append to the archive
|
|
|
|
*/
|
|
|
|
act = APPND;
|
|
|
|
break;
|
2002-10-12 19:39:29 +04:00
|
|
|
case 's':
|
|
|
|
/*
|
|
|
|
* file name substitution name pattern
|
|
|
|
*/
|
|
|
|
if (rep_add(optarg) < 0) {
|
|
|
|
tar_usage();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
1994-06-13 20:13:35 +04:00
|
|
|
case 't':
|
|
|
|
/*
|
|
|
|
* list contents of the tape
|
|
|
|
*/
|
|
|
|
act = LIST;
|
|
|
|
break;
|
|
|
|
case 'v':
|
|
|
|
/*
|
|
|
|
* verbose operation mode
|
|
|
|
*/
|
|
|
|
vflag = 1;
|
|
|
|
break;
|
|
|
|
case 'w':
|
|
|
|
/*
|
|
|
|
* interactive file rename
|
|
|
|
*/
|
|
|
|
iflag = 1;
|
|
|
|
break;
|
|
|
|
case 'x':
|
|
|
|
/*
|
2002-10-12 19:39:29 +04:00
|
|
|
* extract an archive, preserving mode,
|
|
|
|
* and mtime if possible.
|
1994-06-13 20:13:35 +04:00
|
|
|
*/
|
|
|
|
act = EXTRACT;
|
2002-10-12 19:39:29 +04:00
|
|
|
pmtime = 1;
|
1994-06-13 20:13:35 +04:00
|
|
|
break;
|
1996-03-27 02:54:13 +03:00
|
|
|
case 'z':
|
|
|
|
/*
|
|
|
|
* use gzip. Non standard option.
|
|
|
|
*/
|
|
|
|
zflag = 1;
|
|
|
|
gzip_program = GZIP_CMD;
|
|
|
|
break;
|
1994-06-13 20:13:35 +04:00
|
|
|
case 'B':
|
|
|
|
/*
|
|
|
|
* Nothing to do here, this is pax default
|
|
|
|
*/
|
|
|
|
break;
|
2002-10-12 19:39:29 +04:00
|
|
|
case 'C':
|
|
|
|
chdname = optarg;
|
|
|
|
break;
|
|
|
|
case 'H':
|
|
|
|
/*
|
|
|
|
* follow command line symlinks only
|
|
|
|
*/
|
|
|
|
Hflag = 1;
|
|
|
|
break;
|
|
|
|
case 'I':
|
|
|
|
case 'T':
|
|
|
|
if (++nincfiles > incfiles_max) {
|
|
|
|
incfiles_max = nincfiles + 3;
|
|
|
|
incfiles = realloc(incfiles,
|
|
|
|
sizeof(*incfiles) * incfiles_max);
|
|
|
|
if (incfiles == NULL) {
|
|
|
|
tty_warn(0, "Unable to allocate space "
|
|
|
|
"for option list");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
incfiles[nincfiles - 1].file = optarg;
|
|
|
|
incfiles[nincfiles - 1].dir = chdname;
|
|
|
|
break;
|
1994-06-13 20:13:35 +04:00
|
|
|
case 'P':
|
2002-10-12 19:39:29 +04:00
|
|
|
/*
|
|
|
|
* do not remove leading '/' from pathnames
|
|
|
|
*/
|
|
|
|
rmleadslash = 0;
|
1999-08-24 12:00:03 +04:00
|
|
|
Aflag = 1;
|
1994-06-13 20:13:35 +04:00
|
|
|
break;
|
2004-09-27 03:46:00 +04:00
|
|
|
case 'S':
|
|
|
|
/* do nothing; we already generate sparse files */
|
|
|
|
break;
|
1994-06-13 20:13:35 +04:00
|
|
|
case 'X':
|
|
|
|
/*
|
1999-01-20 17:45:09 +03:00
|
|
|
* GNU tar compat: exclude the files listed in optarg
|
1994-06-13 20:13:35 +04:00
|
|
|
*/
|
1999-01-20 17:45:09 +03:00
|
|
|
if (tar_gnutar_X_compat(optarg) != 0)
|
|
|
|
tar_usage();
|
1994-06-13 20:13:35 +04:00
|
|
|
break;
|
1996-03-27 02:54:13 +03:00
|
|
|
case 'Z':
|
|
|
|
/*
|
|
|
|
* use compress.
|
|
|
|
*/
|
|
|
|
zflag = 1;
|
|
|
|
gzip_program = COMPRESS_CMD;
|
|
|
|
break;
|
1994-06-13 20:13:35 +04:00
|
|
|
case '0':
|
|
|
|
arcname = DEV_0;
|
|
|
|
break;
|
|
|
|
case '1':
|
|
|
|
arcname = DEV_1;
|
|
|
|
break;
|
|
|
|
case '4':
|
|
|
|
arcname = DEV_4;
|
|
|
|
break;
|
|
|
|
case '5':
|
|
|
|
arcname = DEV_5;
|
|
|
|
break;
|
|
|
|
case '7':
|
|
|
|
arcname = DEV_7;
|
|
|
|
break;
|
|
|
|
case '8':
|
|
|
|
arcname = DEV_8;
|
|
|
|
break;
|
2000-07-04 21:28:47 +04:00
|
|
|
case OPT_ATIME_PRESERVE:
|
|
|
|
patime = 1;
|
|
|
|
break;
|
2000-07-04 21:17:49 +04:00
|
|
|
case OPT_UNLINK:
|
|
|
|
/* Just ignore -- we always unlink first. */
|
|
|
|
break;
|
2000-07-04 21:24:47 +04:00
|
|
|
case OPT_USE_COMPRESS_PROGRAM:
|
|
|
|
zflag = 1;
|
|
|
|
gzip_program = optarg;
|
|
|
|
break;
|
2002-10-12 19:39:29 +04:00
|
|
|
case OPT_FORCE_LOCAL:
|
|
|
|
forcelocal = 1;
|
|
|
|
break;
|
2002-10-15 20:16:29 +04:00
|
|
|
case OPT_INSECURE:
|
|
|
|
secure = 0;
|
|
|
|
break;
|
2002-10-16 07:46:07 +04:00
|
|
|
case OPT_STRICT:
|
|
|
|
/* disable gnu extensions */
|
|
|
|
is_gnutar = 0;
|
|
|
|
break;
|
2002-12-08 04:35:12 +03:00
|
|
|
case OPT_EXCLUDE:
|
|
|
|
if (tar_gnutar_minus_minus_exclude(optarg) != 0)
|
|
|
|
tar_usage();
|
|
|
|
break;
|
2004-10-23 01:00:18 +04:00
|
|
|
#if !HAVE_NBTOOL_CONFIG_H
|
2004-10-17 22:49:55 +04:00
|
|
|
case OPT_CHROOT:
|
|
|
|
do_chroot = 1;
|
|
|
|
break;
|
2004-10-23 01:00:18 +04:00
|
|
|
#endif
|
1994-06-13 20:13:35 +04:00
|
|
|
default:
|
|
|
|
tar_usage();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
1994-06-14 05:16:02 +04:00
|
|
|
argc -= optind;
|
|
|
|
argv += optind;
|
1994-06-13 20:13:35 +04:00
|
|
|
|
2002-10-17 03:22:59 +04:00
|
|
|
/* Tar requires an action. */
|
2002-10-17 04:42:02 +04:00
|
|
|
if (act == ERROR)
|
2002-10-17 03:22:59 +04:00
|
|
|
tar_usage();
|
|
|
|
|
2002-10-12 19:39:29 +04:00
|
|
|
/* Traditional tar behaviour (pax uses stderr unless in list mode) */
|
|
|
|
if (fstdin == 1 && act == ARCHIVE)
|
|
|
|
listf = stderr;
|
|
|
|
else
|
|
|
|
listf = stdout;
|
1999-10-23 00:59:08 +04:00
|
|
|
|
2002-10-12 19:39:29 +04:00
|
|
|
/* Traditional tar behaviour (pax wants to read file list from stdin) */
|
|
|
|
if ((act == ARCHIVE || act == APPND) && argc == 0 && nincfiles == 0)
|
|
|
|
exit(0);
|
1999-02-03 02:42:41 +03:00
|
|
|
/*
|
|
|
|
* if we are writing (ARCHIVE) specify tar, otherwise run like pax
|
2002-10-12 19:39:29 +04:00
|
|
|
* (unless -o specified)
|
1999-02-03 02:42:41 +03:00
|
|
|
*/
|
2002-10-12 19:39:29 +04:00
|
|
|
if (act == ARCHIVE || act == APPND)
|
|
|
|
frmt = &(fsub[Oflag ? F_TAR : F_USTAR]);
|
|
|
|
else if (Oflag) {
|
2003-07-08 10:00:48 +04:00
|
|
|
if (act == EXTRACT)
|
|
|
|
to_stdout = 1;
|
|
|
|
else {
|
|
|
|
tty_warn(1, "The -O/-o options are only valid when "
|
|
|
|
"writing or extracting an archive");
|
|
|
|
tar_usage();
|
|
|
|
}
|
2002-10-12 19:39:29 +04:00
|
|
|
}
|
1999-02-03 02:42:41 +03:00
|
|
|
|
1994-06-13 20:13:35 +04:00
|
|
|
/*
|
|
|
|
* process the args as they are interpreted by the operation mode
|
|
|
|
*/
|
|
|
|
switch (act) {
|
|
|
|
case LIST:
|
1999-10-23 00:59:08 +04:00
|
|
|
case EXTRACT:
|
2002-10-12 19:39:29 +04:00
|
|
|
default:
|
|
|
|
{
|
|
|
|
int sawpat = 0;
|
2002-10-18 17:45:05 +04:00
|
|
|
int dirisnext = 0;
|
2002-10-12 19:39:29 +04:00
|
|
|
char *file, *dir;
|
|
|
|
|
|
|
|
while (nincfiles || *argv != NULL) {
|
|
|
|
/*
|
|
|
|
* If we queued up any include files,
|
|
|
|
* pull them in now. Otherwise, check
|
|
|
|
* for -I and -C positional flags.
|
|
|
|
* Anything else must be a file to
|
|
|
|
* extract.
|
|
|
|
*/
|
|
|
|
if (nincfiles) {
|
|
|
|
file = incfiles->file;
|
|
|
|
dir = incfiles->dir;
|
|
|
|
incfiles++;
|
|
|
|
nincfiles--;
|
|
|
|
} else if (strcmp(*argv, "-I") == 0) {
|
|
|
|
if (*++argv == NULL)
|
|
|
|
break;
|
|
|
|
file = *argv++;
|
|
|
|
dir = chdname;
|
|
|
|
} else
|
|
|
|
file = NULL;
|
|
|
|
if (file != NULL) {
|
|
|
|
FILE *fp;
|
|
|
|
char *str;
|
|
|
|
|
|
|
|
if (strcmp(file, "-") == 0)
|
|
|
|
fp = stdin;
|
|
|
|
else if ((fp = fopen(file, "r")) == NULL) {
|
|
|
|
tty_warn(1, "Unable to open file '%s' for read", file);
|
|
|
|
tar_usage();
|
|
|
|
}
|
|
|
|
while ((str = getline(fp)) != NULL) {
|
2002-10-18 17:45:05 +04:00
|
|
|
if (dirisnext) {
|
|
|
|
dir = str;
|
|
|
|
dirisnext = 0;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (strcmp(str, "-C") == 0) {
|
|
|
|
dirisnext = 1;
|
|
|
|
continue;
|
|
|
|
}
|
2004-10-11 02:05:26 +04:00
|
|
|
if (strncmp(str, "-C ", 3) == 0) {
|
|
|
|
dir = str + 3;
|
|
|
|
continue;
|
|
|
|
}
|
2002-10-12 19:39:29 +04:00
|
|
|
if (pat_add(str, dir) < 0)
|
|
|
|
tar_usage();
|
|
|
|
sawpat = 1;
|
|
|
|
}
|
2002-10-18 17:45:05 +04:00
|
|
|
/* Bomb if given -C w/out a dir. */
|
|
|
|
if (dirisnext)
|
|
|
|
tar_usage();
|
2002-10-12 19:39:29 +04:00
|
|
|
if (strcmp(file, "-") != 0)
|
|
|
|
fclose(fp);
|
|
|
|
if (getline_error) {
|
|
|
|
tty_warn(1, "Problem with file '%s'", file);
|
|
|
|
tar_usage();
|
|
|
|
}
|
|
|
|
} else if (strcmp(*argv, "-C") == 0) {
|
|
|
|
if (*++argv == NULL)
|
|
|
|
break;
|
|
|
|
chdname = *argv++;
|
|
|
|
} else if (pat_add(*argv++, chdname) < 0)
|
|
|
|
tar_usage();
|
|
|
|
else
|
|
|
|
sawpat = 1;
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
* if patterns were added, we are doing chdir()
|
|
|
|
* on a file-by-file basis, else, just one
|
|
|
|
* global chdir (if any) after opening input.
|
|
|
|
*/
|
|
|
|
if (sawpat > 0)
|
|
|
|
chdname = NULL;
|
|
|
|
}
|
1999-10-23 00:59:08 +04:00
|
|
|
break;
|
1994-06-13 20:13:35 +04:00
|
|
|
case ARCHIVE:
|
|
|
|
case APPND:
|
2002-10-12 19:39:29 +04:00
|
|
|
if (chdname != NULL) { /* initial chdir() */
|
|
|
|
if (ftree_add(chdname, 1) < 0)
|
|
|
|
tar_usage();
|
|
|
|
}
|
|
|
|
|
|
|
|
while (nincfiles || *argv != NULL) {
|
|
|
|
char *file, *dir;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If we queued up any include files, pull them in
|
|
|
|
* now. Otherwise, check for -I and -C positional
|
|
|
|
* flags. Anything else must be a file to include
|
|
|
|
* in the archive.
|
|
|
|
*/
|
|
|
|
if (nincfiles) {
|
|
|
|
file = incfiles->file;
|
|
|
|
dir = incfiles->dir;
|
|
|
|
incfiles++;
|
|
|
|
nincfiles--;
|
|
|
|
} else if (strcmp(*argv, "-I") == 0) {
|
|
|
|
if (*++argv == NULL)
|
|
|
|
break;
|
|
|
|
file = *argv++;
|
|
|
|
dir = NULL;
|
|
|
|
} else
|
|
|
|
file = NULL;
|
|
|
|
if (file != NULL) {
|
|
|
|
FILE *fp;
|
|
|
|
char *str;
|
2002-10-18 17:45:05 +04:00
|
|
|
int dirisnext = 0;
|
2002-10-12 19:39:29 +04:00
|
|
|
|
|
|
|
/* Set directory if needed */
|
|
|
|
if (dir) {
|
|
|
|
if (ftree_add(dir, 1) < 0)
|
|
|
|
tar_usage();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (strcmp(file, "-") == 0)
|
|
|
|
fp = stdin;
|
|
|
|
else if ((fp = fopen(file, "r")) == NULL) {
|
|
|
|
tty_warn(1, "Unable to open file '%s' for read", file);
|
|
|
|
tar_usage();
|
|
|
|
}
|
|
|
|
while ((str = getline(fp)) != NULL) {
|
2002-10-18 17:45:05 +04:00
|
|
|
if (dirisnext) {
|
|
|
|
if (ftree_add(str, 1) < 0)
|
|
|
|
tar_usage();
|
|
|
|
dirisnext = 0;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (strcmp(str, "-C") == 0) {
|
|
|
|
dirisnext = 1;
|
|
|
|
continue;
|
|
|
|
}
|
2004-10-11 02:05:26 +04:00
|
|
|
if (strncmp(str, "-C ", 3) == 0) {
|
|
|
|
if (ftree_add(str + 3, 1) < 0)
|
|
|
|
tar_usage();
|
|
|
|
continue;
|
|
|
|
}
|
2002-10-12 19:39:29 +04:00
|
|
|
if (ftree_add(str, 0) < 0)
|
|
|
|
tar_usage();
|
|
|
|
}
|
2002-10-18 17:45:05 +04:00
|
|
|
/* Bomb if given -C w/out a dir. */
|
|
|
|
if (dirisnext)
|
|
|
|
tar_usage();
|
2002-10-12 19:39:29 +04:00
|
|
|
if (strcmp(file, "-") != 0)
|
|
|
|
fclose(fp);
|
|
|
|
if (getline_error) {
|
|
|
|
tty_warn(1, "Problem with file '%s'",
|
|
|
|
file);
|
|
|
|
tar_usage();
|
|
|
|
}
|
|
|
|
} else if (strcmp(*argv, "-C") == 0) {
|
|
|
|
if (*++argv == NULL)
|
|
|
|
break;
|
|
|
|
if (ftree_add(*argv++, 1) < 0)
|
|
|
|
tar_usage();
|
|
|
|
} else if (ftree_add(*argv++, 0) < 0)
|
|
|
|
tar_usage();
|
|
|
|
}
|
1994-06-13 20:13:35 +04:00
|
|
|
/*
|
|
|
|
* no read errors allowed on updates/append operation!
|
|
|
|
*/
|
|
|
|
maxflt = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (!fstdin && ((arcname == (char *)NULL) || (*arcname == '\0'))) {
|
|
|
|
arcname = getenv("TAPE");
|
2002-10-12 19:39:29 +04:00
|
|
|
if ((arcname == NULL) || (*arcname == '\0'))
|
|
|
|
arcname = _PATH_DEFTAPE;
|
1994-06-13 20:13:35 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-10-12 19:39:29 +04:00
|
|
|
int
|
|
|
|
mkpath(path)
|
|
|
|
char *path;
|
|
|
|
{
|
|
|
|
struct stat sb;
|
|
|
|
char *slash;
|
|
|
|
int done = 0;
|
|
|
|
|
|
|
|
slash = path;
|
|
|
|
|
|
|
|
while (!done) {
|
|
|
|
slash += strspn(slash, "/");
|
|
|
|
slash += strcspn(slash, "/");
|
|
|
|
|
|
|
|
done = (*slash == '\0');
|
|
|
|
*slash = '\0';
|
|
|
|
|
|
|
|
if (stat(path, &sb)) {
|
|
|
|
if (errno != ENOENT || mkdir(path, 0777)) {
|
|
|
|
tty_warn(1, "%s", path);
|
|
|
|
return (-1);
|
|
|
|
}
|
|
|
|
} else if (!S_ISDIR(sb.st_mode)) {
|
|
|
|
syswarn(1, ENOTDIR, "%s", path);
|
|
|
|
return (-1);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!done)
|
|
|
|
*slash = '/';
|
|
|
|
}
|
|
|
|
|
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
2002-10-15 18:51:04 +04:00
|
|
|
|
|
|
|
struct option cpio_longopts[] = {
|
|
|
|
{ "reset-access-time", no_argument, 0, 'a' },
|
|
|
|
{ "make-directories", no_argument, 0, 'd' },
|
|
|
|
{ "nonmatching", no_argument, 0, 'f' },
|
|
|
|
{ "extract", no_argument, 0, 'i' },
|
|
|
|
{ "link", no_argument, 0, 'l' },
|
|
|
|
{ "preserve-modification-time", no_argument, 0, 'm' },
|
|
|
|
{ "create", no_argument, 0, 'o' },
|
|
|
|
{ "pass-through", no_argument, 0, 'p' },
|
|
|
|
{ "rename", no_argument, 0, 'r' },
|
|
|
|
{ "list", no_argument, 0, 't' },
|
|
|
|
{ "unconditional", no_argument, 0, 'u' },
|
|
|
|
{ "verbose", no_argument, 0, 'v' },
|
|
|
|
{ "append", no_argument, 0, 'A' },
|
|
|
|
{ "pattern-file", required_argument, 0, 'E' },
|
|
|
|
{ "file", required_argument, 0, 'F' },
|
|
|
|
{ "force-local", no_argument, 0,
|
2002-10-15 20:16:29 +04:00
|
|
|
OPT_FORCE_LOCAL },
|
2002-10-15 18:51:04 +04:00
|
|
|
{ "format", required_argument, 0, 'H' },
|
|
|
|
{ "dereference", no_argument, 0, 'L' },
|
|
|
|
{ "swap-halfwords", no_argument, 0, 'S' },
|
2002-10-15 20:16:29 +04:00
|
|
|
{ "insecure", no_argument, 0,
|
|
|
|
OPT_INSECURE },
|
2004-09-27 03:46:00 +04:00
|
|
|
{ "sparse", no_argument, 0,
|
|
|
|
OPT_SPARSE },
|
2002-10-15 18:51:04 +04:00
|
|
|
|
|
|
|
#ifdef notyet
|
|
|
|
/* Not implemented */
|
|
|
|
{ "null", no_argument, 0, '0' },
|
|
|
|
{ "swap", no_argument, 0, 'b' },
|
|
|
|
{ "numeric-uid-gid", no_argument, 0, 'n' },
|
|
|
|
{ "swap-bytes", no_argument, 0, 's' },
|
|
|
|
{ "message", required_argument, 0, 'M' },
|
|
|
|
{ "owner", required_argument, 0 'R' },
|
|
|
|
{ "dot", no_argument, 0, 'V' },
|
|
|
|
{ "block-size", required_argument, 0,
|
2002-10-15 20:16:29 +04:00
|
|
|
OPT_BLOCK_SIZE },
|
2002-10-15 18:51:04 +04:00
|
|
|
{ "no-absolute-pathnames", no_argument, 0,
|
2002-10-15 20:16:29 +04:00
|
|
|
OPT_NO_ABSOLUTE_PATHNAMES },
|
2002-10-15 18:51:04 +04:00
|
|
|
{ "no-preserve-owner", no_argument, 0,
|
2002-10-15 20:16:29 +04:00
|
|
|
OPT_NO_PRESERVE_OWNER },
|
2002-10-15 18:51:04 +04:00
|
|
|
{ "only-verify-crc", no_argument, 0,
|
2002-10-15 20:16:29 +04:00
|
|
|
OPT_ONLY_VERIFY_CRC },
|
2002-10-15 18:51:04 +04:00
|
|
|
{ "rsh-command", required_argument, 0,
|
2002-10-15 20:16:29 +04:00
|
|
|
OPT_RSH_COMMAND },
|
2002-10-15 18:51:04 +04:00
|
|
|
{ "version", no_argument, 0,
|
2002-10-15 20:16:29 +04:00
|
|
|
OPT_VERSION },
|
2002-10-15 18:51:04 +04:00
|
|
|
#endif
|
2005-02-10 20:48:33 +03:00
|
|
|
{ 0, 0, 0, 0 },
|
2002-10-15 18:51:04 +04:00
|
|
|
};
|
|
|
|
|
1994-06-13 20:13:35 +04:00
|
|
|
/*
|
|
|
|
* cpio_options()
|
|
|
|
* look at the user specified flags. set globals as required and check if
|
|
|
|
* the user specified a legal set of flags. If not, complain and exit
|
|
|
|
*/
|
|
|
|
|
|
|
|
static void
|
1997-01-11 05:04:27 +03:00
|
|
|
cpio_options(int argc, char **argv)
|
1994-06-13 20:13:35 +04:00
|
|
|
{
|
2000-02-17 06:12:22 +03:00
|
|
|
FSUB tmp;
|
1998-03-06 12:13:01 +03:00
|
|
|
unsigned int flg = 0;
|
|
|
|
unsigned int bflg = 0;
|
|
|
|
int c, i;
|
2002-10-12 19:39:29 +04:00
|
|
|
FILE *fp;
|
|
|
|
char *str;
|
|
|
|
|
|
|
|
uflag = 1;
|
|
|
|
kflag = 1;
|
|
|
|
pids = 1;
|
|
|
|
pmode = 1;
|
|
|
|
pmtime = 0;
|
|
|
|
arcname = NULL;
|
|
|
|
dflag = 1;
|
|
|
|
nodirs = 1;
|
1998-03-06 12:13:01 +03:00
|
|
|
/*
|
|
|
|
* process option flags
|
|
|
|
*/
|
2000-07-04 21:17:49 +04:00
|
|
|
while ((c = getoldopt(argc, argv,
|
2002-10-15 20:16:29 +04:00
|
|
|
"+abcdfiklmoprstuvzABC:E:F:H:I:LM:O:R:SVZ6",
|
2002-10-15 18:51:04 +04:00
|
|
|
cpio_longopts, NULL)) != -1) {
|
1998-03-06 12:13:01 +03:00
|
|
|
switch(c) {
|
|
|
|
case 'a':
|
|
|
|
/*
|
|
|
|
* preserve access time on filesystem nodes we read
|
|
|
|
*/
|
|
|
|
tflag = 1;
|
|
|
|
flg |= TF;
|
|
|
|
break;
|
|
|
|
#ifdef notyet
|
|
|
|
case 'b':
|
2002-10-12 19:39:29 +04:00
|
|
|
/*
|
|
|
|
* swap bytes and half-words when reading data
|
|
|
|
*/
|
1998-03-06 12:13:01 +03:00
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
case 'c':
|
2002-10-12 19:39:29 +04:00
|
|
|
/*
|
|
|
|
* ASCII cpio header
|
|
|
|
*/
|
1998-03-06 12:13:01 +03:00
|
|
|
frmt = &fsub[F_SV4CPIO];
|
|
|
|
break;
|
|
|
|
case 'd':
|
|
|
|
/*
|
2002-10-12 19:39:29 +04:00
|
|
|
* create directories as needed
|
1998-03-06 12:13:01 +03:00
|
|
|
* pax does this by default ..
|
|
|
|
*/
|
2002-10-12 19:39:29 +04:00
|
|
|
nodirs = 0;
|
1998-03-06 12:13:01 +03:00
|
|
|
break;
|
|
|
|
case 'f':
|
|
|
|
/*
|
|
|
|
* inverse match on patterns
|
|
|
|
*/
|
|
|
|
cflag = 1;
|
|
|
|
flg |= CF;
|
|
|
|
break;
|
|
|
|
case 'i':
|
|
|
|
/*
|
|
|
|
* read the archive
|
|
|
|
*/
|
2002-10-12 19:39:29 +04:00
|
|
|
act = EXTRACT;
|
1998-03-06 12:13:01 +03:00
|
|
|
flg |= RF;
|
|
|
|
break;
|
|
|
|
#ifdef notyet
|
|
|
|
case 'k':
|
|
|
|
break;
|
1994-06-13 20:13:35 +04:00
|
|
|
#endif
|
1998-03-06 12:13:01 +03:00
|
|
|
case 'l':
|
|
|
|
/*
|
|
|
|
* try to link src to dest with copy (-rw)
|
|
|
|
*/
|
|
|
|
lflag = 1;
|
|
|
|
flg |= LF;
|
|
|
|
break;
|
|
|
|
case 'm':
|
|
|
|
/*
|
|
|
|
* preserve mtime
|
|
|
|
*/
|
|
|
|
flg |= PF;
|
|
|
|
pmtime = 1;
|
|
|
|
break;
|
|
|
|
case 'o':
|
|
|
|
/*
|
|
|
|
* write an archive
|
|
|
|
*/
|
2002-10-12 19:39:29 +04:00
|
|
|
act = ARCHIVE;
|
|
|
|
frmt = &(fsub[F_SV4CRC]);
|
1998-03-06 12:13:01 +03:00
|
|
|
flg |= WF;
|
|
|
|
break;
|
|
|
|
case 'p':
|
|
|
|
/*
|
|
|
|
* cpio -p is like pax -rw
|
|
|
|
*/
|
2002-10-12 19:39:29 +04:00
|
|
|
act = COPY;
|
1998-03-06 12:13:01 +03:00
|
|
|
flg |= RF | WF;
|
|
|
|
break;
|
|
|
|
case 'r':
|
|
|
|
/*
|
|
|
|
* interactive file rename
|
|
|
|
*/
|
|
|
|
iflag = 1;
|
|
|
|
flg |= IF;
|
|
|
|
break;
|
|
|
|
#ifdef notyet
|
|
|
|
case 's':
|
2002-10-12 19:39:29 +04:00
|
|
|
/*
|
|
|
|
* swap bytes after reading data
|
|
|
|
*/
|
1998-03-06 12:13:01 +03:00
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
case 't':
|
2002-10-12 19:39:29 +04:00
|
|
|
/*
|
|
|
|
* list contents of archive
|
|
|
|
*/
|
1998-03-06 12:13:01 +03:00
|
|
|
act = LIST;
|
2002-10-12 19:39:29 +04:00
|
|
|
listf = stdout;
|
2004-10-26 20:11:49 +04:00
|
|
|
flg &= ~RF;
|
1998-03-06 12:13:01 +03:00
|
|
|
break;
|
|
|
|
case 'u':
|
|
|
|
/*
|
|
|
|
* don't ignore those older files
|
|
|
|
*/
|
|
|
|
uflag = 0;
|
2002-10-12 19:39:29 +04:00
|
|
|
kflag = 0;
|
1998-03-06 12:13:01 +03:00
|
|
|
flg |= UF;
|
|
|
|
break;
|
|
|
|
case 'v':
|
|
|
|
/*
|
|
|
|
* verbose operation mode
|
|
|
|
*/
|
|
|
|
vflag = 1;
|
|
|
|
flg |= VF;
|
|
|
|
break;
|
2002-10-12 19:39:29 +04:00
|
|
|
case 'z':
|
|
|
|
/*
|
|
|
|
* use gzip. Non standard option.
|
|
|
|
*/
|
|
|
|
gzip_program = GZIP_CMD;
|
|
|
|
break;
|
|
|
|
case 'A':
|
|
|
|
/*
|
|
|
|
* append to an archive
|
|
|
|
*/
|
|
|
|
act = APPND;
|
|
|
|
flg |= AF;
|
|
|
|
break;
|
|
|
|
case 'B':
|
|
|
|
/*
|
|
|
|
* set blocksize to 5120
|
|
|
|
*/
|
|
|
|
blksz = 5120;
|
|
|
|
break;
|
|
|
|
case 'C':
|
|
|
|
/*
|
|
|
|
* specify blocksize
|
|
|
|
*/
|
|
|
|
if ((blksz = (int)str_offt(optarg)) <= 0) {
|
|
|
|
tty_warn(1, "Invalid block size %s", optarg);
|
2003-01-16 00:56:46 +03:00
|
|
|
cpio_usage();
|
2002-10-12 19:39:29 +04:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 'E':
|
|
|
|
/*
|
|
|
|
* file with patterns to extract or list
|
|
|
|
*/
|
|
|
|
if ((fp = fopen(optarg, "r")) == NULL) {
|
|
|
|
tty_warn(1, "Unable to open file '%s' for read",
|
|
|
|
optarg);
|
|
|
|
cpio_usage();
|
|
|
|
}
|
|
|
|
while ((str = getline(fp)) != NULL) {
|
|
|
|
pat_add(str, NULL);
|
|
|
|
}
|
|
|
|
fclose(fp);
|
|
|
|
if (getline_error) {
|
|
|
|
tty_warn(1, "Problem with file '%s'", optarg);
|
|
|
|
cpio_usage();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 'H':
|
|
|
|
/*
|
|
|
|
* specify an archive format on write
|
|
|
|
*/
|
|
|
|
tmp.name = optarg;
|
|
|
|
frmt = (FSUB *)bsearch((void *)&tmp, (void *)fsub,
|
|
|
|
sizeof(fsub)/sizeof(FSUB), sizeof(FSUB), c_frmt);
|
|
|
|
if (frmt != NULL) {
|
|
|
|
flg |= XF;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
tty_warn(1, "Unknown -H format: %s", optarg);
|
|
|
|
(void)fputs("cpio: Known -H formats are:", stderr);
|
|
|
|
for (i = 0; i < (sizeof(fsub)/sizeof(FSUB)); ++i)
|
|
|
|
(void)fprintf(stderr, " %s", fsub[i].name);
|
|
|
|
(void)fputs("\n\n", stderr);
|
2003-01-16 00:56:46 +03:00
|
|
|
cpio_usage();
|
2002-10-12 19:39:29 +04:00
|
|
|
break;
|
|
|
|
case 'I':
|
|
|
|
case 'O':
|
|
|
|
/*
|
|
|
|
* filename where the archive is stored
|
|
|
|
*/
|
|
|
|
if ((optarg[0] == '-') && (optarg[1]== '\0')) {
|
|
|
|
/*
|
|
|
|
* treat a - as stdin
|
|
|
|
*/
|
|
|
|
arcname = NULL;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
arcname = optarg;
|
|
|
|
break;
|
|
|
|
case 'L':
|
|
|
|
/*
|
|
|
|
* follow symlinks
|
|
|
|
*/
|
|
|
|
Lflag = 1;
|
|
|
|
flg |= CLF;
|
|
|
|
break;
|
|
|
|
#ifdef notyet
|
|
|
|
case 'M':
|
|
|
|
arg = optarg;
|
|
|
|
break;
|
|
|
|
case 'R':
|
|
|
|
arg = optarg;
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
case 'S':
|
|
|
|
/*
|
|
|
|
* swap halfwords after reading data
|
|
|
|
*/
|
|
|
|
cpio_swp_head = 1;
|
|
|
|
break;
|
|
|
|
#ifdef notyet
|
|
|
|
case 'V':
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
case 'Z':
|
|
|
|
/*
|
|
|
|
* use compress. Non standard option.
|
|
|
|
*/
|
|
|
|
gzip_program = COMPRESS_CMD;
|
|
|
|
break;
|
|
|
|
case '6':
|
|
|
|
/*
|
|
|
|
* process Version 6 cpio format
|
|
|
|
*/
|
|
|
|
frmt = &(fsub[F_BCPIO]);
|
2002-10-15 18:51:04 +04:00
|
|
|
case OPT_FORCE_LOCAL:
|
|
|
|
forcelocal = 1;
|
|
|
|
break;
|
2002-10-15 20:16:29 +04:00
|
|
|
case OPT_INSECURE:
|
|
|
|
secure = 0;
|
|
|
|
break;
|
2004-09-27 03:46:00 +04:00
|
|
|
|
|
|
|
case OPT_SPARSE:
|
|
|
|
/* do nothing; we already generate sparse files */
|
|
|
|
break;
|
1998-03-06 12:13:01 +03:00
|
|
|
default:
|
|
|
|
cpio_usage();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* figure out the operation mode of cpio. check that we have not been
|
|
|
|
* given a bogus set of flags for the operation mode.
|
|
|
|
*/
|
|
|
|
if (ISLIST(flg)) {
|
|
|
|
act = LIST;
|
|
|
|
bflg = flg & BDLIST;
|
|
|
|
} else if (ISEXTRACT(flg)) {
|
|
|
|
act = EXTRACT;
|
|
|
|
bflg = flg & BDEXTR;
|
|
|
|
} else if (ISARCHIVE(flg)) {
|
|
|
|
act = ARCHIVE;
|
|
|
|
bflg = flg & BDARCH;
|
|
|
|
} else if (ISAPPND(flg)) {
|
|
|
|
act = APPND;
|
|
|
|
bflg = flg & BDARCH;
|
|
|
|
} else if (ISCOPY(flg)) {
|
|
|
|
act = COPY;
|
|
|
|
bflg = flg & BDCOPY;
|
|
|
|
} else
|
|
|
|
cpio_usage();
|
|
|
|
if (bflg) {
|
|
|
|
cpio_usage();
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* if we are writing (ARCHIVE) we use the default format if the user
|
|
|
|
* did not specify a format. when we write during an APPEND, we will
|
|
|
|
* adopt the format of the existing archive if none was supplied.
|
|
|
|
*/
|
|
|
|
if (!(flg & XF) && (act == ARCHIVE))
|
|
|
|
frmt = &(fsub[F_BCPIO]);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* process the args as they are interpreted by the operation mode
|
|
|
|
*/
|
|
|
|
switch (act) {
|
|
|
|
case LIST:
|
|
|
|
case EXTRACT:
|
|
|
|
for (; optind < argc; optind++)
|
1999-10-23 00:59:08 +04:00
|
|
|
if (pat_add(argv[optind], 0) < 0)
|
1998-03-06 12:13:01 +03:00
|
|
|
cpio_usage();
|
|
|
|
break;
|
|
|
|
case COPY:
|
|
|
|
if (optind >= argc) {
|
|
|
|
tty_warn(0, "Destination directory was not supplied");
|
|
|
|
cpio_usage();
|
|
|
|
}
|
|
|
|
--argc;
|
|
|
|
dirptr = argv[argc];
|
1998-07-28 21:44:23 +04:00
|
|
|
/* FALLTHROUGH */
|
1998-03-06 12:13:01 +03:00
|
|
|
case ARCHIVE:
|
|
|
|
case APPND:
|
2002-10-12 19:39:29 +04:00
|
|
|
if (argc != optind) {
|
|
|
|
for (; optind < argc; optind++)
|
|
|
|
if (ftree_add(argv[optind], 0) < 0)
|
|
|
|
cpio_usage();
|
|
|
|
break;
|
|
|
|
}
|
1998-03-06 12:13:01 +03:00
|
|
|
/*
|
|
|
|
* no read errors allowed on updates/append operation!
|
|
|
|
*/
|
|
|
|
maxflt = 0;
|
2002-10-12 19:39:29 +04:00
|
|
|
while ((str = getline(stdin)) != NULL) {
|
2003-10-21 06:08:14 +04:00
|
|
|
ftree_add(str, 0);
|
2002-10-12 19:39:29 +04:00
|
|
|
}
|
|
|
|
if (getline_error) {
|
|
|
|
tty_warn(1, "Problem while reading stdin");
|
|
|
|
cpio_usage();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
cpio_usage();
|
1998-03-06 12:13:01 +03:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
1994-06-13 20:13:35 +04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* printflg()
|
|
|
|
* print out those invalid flag sets found to the user
|
|
|
|
*/
|
|
|
|
|
|
|
|
static void
|
|
|
|
printflg(unsigned int flg)
|
|
|
|
{
|
|
|
|
int nxt;
|
|
|
|
|
|
|
|
(void)fprintf(stderr,"%s: Invalid combination of options:", argv0);
|
1997-07-21 00:32:15 +04:00
|
|
|
while ((nxt = ffs(flg)) != 0) {
|
2004-01-05 20:27:46 +03:00
|
|
|
flg &= ~(1 << (nxt - 1));
|
|
|
|
(void)fprintf(stderr, " -%c", flgch[nxt - 1]);
|
1994-06-13 20:13:35 +04:00
|
|
|
}
|
|
|
|
(void)putc('\n', stderr);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* c_frmt()
|
|
|
|
* comparison routine used by bsearch to find the format specified
|
|
|
|
* by the user
|
|
|
|
*/
|
|
|
|
|
|
|
|
static int
|
|
|
|
c_frmt(const void *a, const void *b)
|
|
|
|
{
|
2004-05-11 21:12:26 +04:00
|
|
|
return(strcmp(((const FSUB *)a)->name, ((const FSUB *)b)->name));
|
1994-06-13 20:13:35 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* opt_next()
|
|
|
|
* called by format specific options routines to get each format specific
|
|
|
|
* flag and value specified with -o
|
|
|
|
* Return:
|
|
|
|
* pointer to next OPLIST entry or NULL (end of list).
|
|
|
|
*/
|
|
|
|
|
|
|
|
OPLIST *
|
|
|
|
opt_next(void)
|
|
|
|
{
|
|
|
|
OPLIST *opt;
|
|
|
|
|
|
|
|
if ((opt = ophead) != NULL)
|
|
|
|
ophead = ophead->fow;
|
|
|
|
return(opt);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* bad_opt()
|
|
|
|
* generic routine used to complain about a format specific options
|
|
|
|
* when the format does not support options.
|
|
|
|
*/
|
|
|
|
|
|
|
|
int
|
|
|
|
bad_opt(void)
|
|
|
|
{
|
1997-01-11 05:04:27 +03:00
|
|
|
OPLIST *opt;
|
1994-06-13 20:13:35 +04:00
|
|
|
|
|
|
|
if (ophead == NULL)
|
|
|
|
return(0);
|
|
|
|
/*
|
|
|
|
* print all we were given
|
|
|
|
*/
|
2002-10-16 07:46:07 +04:00
|
|
|
tty_warn(1," These format options are not supported for %s",
|
|
|
|
frmt->name);
|
1994-06-13 20:13:35 +04:00
|
|
|
while ((opt = opt_next()) != NULL)
|
|
|
|
(void)fprintf(stderr, "\t%s = %s\n", opt->name, opt->value);
|
2002-10-16 07:46:07 +04:00
|
|
|
if (strcmp(NM_TAR, argv0) == 0)
|
|
|
|
tar_usage();
|
|
|
|
else if (strcmp(NM_CPIO, argv0) == 0)
|
|
|
|
cpio_usage();
|
|
|
|
else
|
|
|
|
pax_usage();
|
1994-06-13 20:13:35 +04:00
|
|
|
return(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* opt_add()
|
|
|
|
* breaks the value supplied to -o into a option name and value. options
|
|
|
|
* are given to -o in the form -o name-value,name=value
|
2000-02-17 06:12:22 +03:00
|
|
|
* multiple -o may be specified.
|
1994-06-13 20:13:35 +04:00
|
|
|
* Return:
|
|
|
|
* 0 if format in name=value format, -1 if -o is passed junk
|
|
|
|
*/
|
|
|
|
|
|
|
|
int
|
1999-02-07 03:56:55 +03:00
|
|
|
opt_add(const char *str)
|
1994-06-13 20:13:35 +04:00
|
|
|
{
|
1997-01-11 05:04:27 +03:00
|
|
|
OPLIST *opt;
|
|
|
|
char *frpt;
|
|
|
|
char *pt;
|
|
|
|
char *endpt;
|
2002-10-12 19:39:29 +04:00
|
|
|
char *dstr;
|
1994-06-13 20:13:35 +04:00
|
|
|
|
|
|
|
if ((str == NULL) || (*str == '\0')) {
|
1997-07-21 00:32:15 +04:00
|
|
|
tty_warn(0, "Invalid option name");
|
1994-06-13 20:13:35 +04:00
|
|
|
return(-1);
|
|
|
|
}
|
2002-10-12 19:39:29 +04:00
|
|
|
if ((dstr = strdup(str)) == NULL) {
|
|
|
|
tty_warn(0, "Unable to allocate space for option list");
|
|
|
|
return(-1);
|
|
|
|
}
|
|
|
|
frpt = endpt = dstr;
|
1994-06-13 20:13:35 +04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* break into name and values pieces and stuff each one into a
|
|
|
|
* OPLIST structure. When we know the format, the format specific
|
|
|
|
* option function will go through this list
|
|
|
|
*/
|
|
|
|
while ((frpt != NULL) && (*frpt != '\0')) {
|
|
|
|
if ((endpt = strchr(frpt, ',')) != NULL)
|
|
|
|
*endpt = '\0';
|
|
|
|
if ((pt = strchr(frpt, '=')) == NULL) {
|
1997-07-21 00:32:15 +04:00
|
|
|
tty_warn(0, "Invalid options format");
|
2002-10-12 19:39:29 +04:00
|
|
|
free(dstr);
|
1994-06-13 20:13:35 +04:00
|
|
|
return(-1);
|
|
|
|
}
|
|
|
|
if ((opt = (OPLIST *)malloc(sizeof(OPLIST))) == NULL) {
|
1997-07-21 00:32:15 +04:00
|
|
|
tty_warn(0, "Unable to allocate space for option list");
|
2002-10-12 19:39:29 +04:00
|
|
|
free(dstr);
|
1994-06-13 20:13:35 +04:00
|
|
|
return(-1);
|
|
|
|
}
|
|
|
|
*pt++ = '\0';
|
|
|
|
opt->name = frpt;
|
|
|
|
opt->value = pt;
|
|
|
|
opt->fow = NULL;
|
|
|
|
if (endpt != NULL)
|
|
|
|
frpt = endpt + 1;
|
|
|
|
else
|
|
|
|
frpt = NULL;
|
|
|
|
if (ophead == NULL) {
|
|
|
|
optail = ophead = opt;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
optail->fow = opt;
|
|
|
|
optail = opt;
|
|
|
|
}
|
|
|
|
return(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* str_offt()
|
|
|
|
* Convert an expression of the following forms to an off_t > 0.
|
2000-02-17 06:12:22 +03:00
|
|
|
* 1) A positive decimal number.
|
1994-06-13 20:13:35 +04:00
|
|
|
* 2) A positive decimal number followed by a b (mult by 512).
|
|
|
|
* 3) A positive decimal number followed by a k (mult by 1024).
|
|
|
|
* 4) A positive decimal number followed by a m (mult by 512).
|
|
|
|
* 5) A positive decimal number followed by a w (mult by sizeof int)
|
|
|
|
* 6) Two or more positive decimal numbers (with/without k,b or w).
|
2001-07-22 17:33:58 +04:00
|
|
|
* separated by x (also * for backwards compatibility), specifying
|
1994-06-13 20:13:35 +04:00
|
|
|
* the product of the indicated values.
|
|
|
|
* Return:
|
|
|
|
* 0 for an error, a positive value o.w.
|
|
|
|
*/
|
|
|
|
|
|
|
|
static off_t
|
|
|
|
str_offt(char *val)
|
|
|
|
{
|
|
|
|
char *expr;
|
|
|
|
off_t num, t;
|
|
|
|
|
2001-10-25 09:33:32 +04:00
|
|
|
num = STRTOOFFT(val, &expr, 0);
|
|
|
|
if ((num == OFFT_MAX) || (num <= 0) || (expr == val))
|
1994-06-13 20:13:35 +04:00
|
|
|
return(0);
|
|
|
|
|
|
|
|
switch(*expr) {
|
|
|
|
case 'b':
|
|
|
|
t = num;
|
|
|
|
num *= 512;
|
|
|
|
if (t > num)
|
|
|
|
return(0);
|
|
|
|
++expr;
|
|
|
|
break;
|
|
|
|
case 'k':
|
|
|
|
t = num;
|
|
|
|
num *= 1024;
|
|
|
|
if (t > num)
|
|
|
|
return(0);
|
|
|
|
++expr;
|
|
|
|
break;
|
|
|
|
case 'm':
|
|
|
|
t = num;
|
|
|
|
num *= 1048576;
|
|
|
|
if (t > num)
|
|
|
|
return(0);
|
|
|
|
++expr;
|
|
|
|
break;
|
|
|
|
case 'w':
|
|
|
|
t = num;
|
|
|
|
num *= sizeof(int);
|
|
|
|
if (t > num)
|
|
|
|
return(0);
|
|
|
|
++expr;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch(*expr) {
|
|
|
|
case '\0':
|
|
|
|
break;
|
|
|
|
case '*':
|
|
|
|
case 'x':
|
|
|
|
t = num;
|
|
|
|
num *= str_offt(expr + 1);
|
|
|
|
if (t > num)
|
|
|
|
return(0);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return(0);
|
|
|
|
}
|
|
|
|
return(num);
|
|
|
|
}
|
|
|
|
|
2002-10-12 19:39:29 +04:00
|
|
|
char *
|
|
|
|
getline(FILE *f)
|
|
|
|
{
|
|
|
|
char *name, *temp;
|
|
|
|
size_t len;
|
|
|
|
|
|
|
|
name = fgetln(f, &len);
|
|
|
|
if (!name) {
|
|
|
|
getline_error = ferror(f) ? GETLINE_FILE_CORRUPT : 0;
|
|
|
|
return(0);
|
|
|
|
}
|
|
|
|
if (name[len-1] != '\n')
|
|
|
|
len++;
|
|
|
|
temp = malloc(len);
|
|
|
|
if (!temp) {
|
|
|
|
getline_error = GETLINE_OUT_OF_MEM;
|
|
|
|
return(0);
|
|
|
|
}
|
|
|
|
memcpy(temp, name, len-1);
|
|
|
|
temp[len-1] = 0;
|
|
|
|
return(temp);
|
|
|
|
}
|
|
|
|
|
1994-06-13 20:13:35 +04:00
|
|
|
/*
|
|
|
|
* no_op()
|
|
|
|
* for those option functions where the archive format has nothing to do.
|
|
|
|
* Return:
|
|
|
|
* 0
|
|
|
|
*/
|
|
|
|
|
|
|
|
static int
|
|
|
|
no_op(void)
|
|
|
|
{
|
|
|
|
return(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* pax_usage()
|
|
|
|
* print the usage summary to the user
|
|
|
|
*/
|
|
|
|
|
|
|
|
void
|
|
|
|
pax_usage(void)
|
|
|
|
{
|
2002-01-24 10:45:33 +03:00
|
|
|
fprintf(stderr,
|
2004-01-06 02:23:32 +03:00
|
|
|
"usage: pax [-cdjnvzO] [-E limit] [-f archive] [-N dbdir] [-s replstr] ...\n"
|
2002-01-24 10:45:33 +03:00
|
|
|
" [-U user] ... [-G group] ... [-T [from_date][,to_date]] ...\n"
|
|
|
|
" [pattern ...]\n");
|
|
|
|
fprintf(stderr,
|
2003-04-01 00:10:08 +04:00
|
|
|
" pax -r [-cdijknuvzADOYZ] [-E limit] [-f archive] [-N dbdir]\n"
|
2002-01-24 10:45:33 +03:00
|
|
|
" [-o options] ... [-p string] ... [-s replstr] ... [-U user] ...\n"
|
|
|
|
" [-G group] ... [-T [from_date][,to_date]] ... [pattern ...]\n");
|
|
|
|
fprintf(stderr,
|
2003-04-01 00:10:08 +04:00
|
|
|
" pax -w [-dijtuvzAHLMOPX] [-b blocksize] [[-a] [-f archive]] [-x format]\n"
|
2002-01-24 10:45:33 +03:00
|
|
|
" [-B bytes] [-N dbdir] [-o options] ... [-s replstr] ...\n"
|
|
|
|
" [-U user] ... [-G group] ...\n"
|
|
|
|
" [-T [from_date][,to_date][/[c][m]]] ... [file ...]\n");
|
|
|
|
fprintf(stderr,
|
2003-04-01 00:10:08 +04:00
|
|
|
" pax -r -w [-dijklntuvzADHLMOPXYZ] [-N dbdir] [-p string] ...\n"
|
2002-01-24 10:45:33 +03:00
|
|
|
" [-s replstr] ... [-U user] ... [-G group] ...\n"
|
|
|
|
" [-T [from_date][,to_date][/[c][m]]] ... [file ...] directory\n");
|
1994-06-13 20:13:35 +04:00
|
|
|
exit(1);
|
1998-07-28 09:31:22 +04:00
|
|
|
/* NOTREACHED */
|
1994-06-13 20:13:35 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* tar_usage()
|
|
|
|
* print the usage summary to the user
|
|
|
|
*/
|
|
|
|
|
|
|
|
void
|
|
|
|
tar_usage(void)
|
|
|
|
{
|
2004-10-17 22:49:55 +04:00
|
|
|
(void)fputs("usage: tar [-]{crtux}[-befhjlmopqvwzHOPSXZ014578] [archive] "
|
2002-10-14 19:04:41 +04:00
|
|
|
"[blocksize]\n"
|
|
|
|
" [-C directory] [-T file] [-s replstr] "
|
|
|
|
"[file ...]\n", stderr);
|
1994-06-13 20:13:35 +04:00
|
|
|
exit(1);
|
1998-07-28 09:31:22 +04:00
|
|
|
/* NOTREACHED */
|
1994-06-13 20:13:35 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* cpio_usage()
|
|
|
|
* print the usage summary to the user
|
|
|
|
*/
|
|
|
|
|
|
|
|
void
|
|
|
|
cpio_usage(void)
|
|
|
|
{
|
1998-03-06 12:13:01 +03:00
|
|
|
|
2004-01-06 02:23:32 +03:00
|
|
|
(void)fputs("usage: cpio -o [-aABcLvzZ] [-C bytes] [-F archive] "
|
2002-10-17 02:38:36 +04:00
|
|
|
"[-H format] [-O archive]\n"
|
|
|
|
" < name-list [> archive]\n"
|
|
|
|
" cpio -i [-bBcdfmrsStuvzZ6] [-C bytes] [-E file] "
|
|
|
|
"[-F archive] [-H format] \n"
|
|
|
|
" [-I archive] "
|
|
|
|
"[pattern ...] [< archive]\n"
|
|
|
|
" cpio -p [-adlLmuv] destination-directory "
|
|
|
|
"< name-list\n", stderr);
|
1994-06-13 20:13:35 +04:00
|
|
|
exit(1);
|
1998-07-28 09:31:22 +04:00
|
|
|
/* NOTREACHED */
|
1994-06-13 20:13:35 +04:00
|
|
|
}
|