Mon Dec 14 05:04:48 2009 UTC ()
Don't use NOGLOB_MTCH for pax, only for tar. Fixes fix for PR 41167 and
closes PR 42301. Since the 41167 fix was pulled up to -5, this needs to
be too.


(dholland)
diff -r1.105 -r1.106 src/bin/pax/options.c

cvs diff -r1.105 -r1.106 src/bin/pax/options.c (switch to unified diff)

--- src/bin/pax/options.c 2009/07/13 19:05:39 1.105
+++ src/bin/pax/options.c 2009/12/14 05:04:48 1.106
@@ -1,1694 +1,1694 @@ @@ -1,1694 +1,1694 @@
1/* $NetBSD: options.c,v 1.105 2009/07/13 19:05:39 roy Exp $ */ 1/* $NetBSD: options.c,v 1.106 2009/12/14 05:04:48 dholland Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1992 Keith Muller. 4 * Copyright (c) 1992 Keith Muller.
5 * Copyright (c) 1992, 1993 5 * Copyright (c) 1992, 1993
6 * The Regents of the University of California. All rights reserved. 6 * The Regents of the University of California. All rights reserved.
7 * 7 *
8 * This code is derived from software contributed to Berkeley by 8 * This code is derived from software contributed to Berkeley by
9 * Keith Muller of the University of California, San Diego. 9 * Keith Muller of the University of California, San Diego.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions 12 * modification, are permitted provided that the following conditions
13 * are met: 13 * are met:
14 * 1. Redistributions of source code must retain the above copyright 14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer. 15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright 16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the 17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution. 18 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the University nor the names of its contributors 19 * 3. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software 20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission. 21 * without specific prior written permission.
22 * 22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE. 33 * SUCH DAMAGE.
34 */ 34 */
35 35
36#if HAVE_NBTOOL_CONFIG_H 36#if HAVE_NBTOOL_CONFIG_H
37#include "nbtool_config.h" 37#include "nbtool_config.h"
38#endif 38#endif
39 39
40#include <sys/cdefs.h> 40#include <sys/cdefs.h>
41#if !defined(lint) 41#if !defined(lint)
42#if 0 42#if 0
43static char sccsid[] = "@(#)options.c 8.2 (Berkeley) 4/18/94"; 43static char sccsid[] = "@(#)options.c 8.2 (Berkeley) 4/18/94";
44#else 44#else
45__RCSID("$NetBSD: options.c,v 1.105 2009/07/13 19:05:39 roy Exp $"); 45__RCSID("$NetBSD: options.c,v 1.106 2009/12/14 05:04:48 dholland Exp $");
46#endif 46#endif
47#endif /* not lint */ 47#endif /* not lint */
48 48
49#include <sys/types.h> 49#include <sys/types.h>
50#include <sys/time.h> 50#include <sys/time.h>
51#include <sys/stat.h> 51#include <sys/stat.h>
52#include <sys/param.h> 52#include <sys/param.h>
53#include <ctype.h> 53#include <ctype.h>
54#include <errno.h> 54#include <errno.h>
55#if HAVE_NBTOOL_CONFIG_H 55#if HAVE_NBTOOL_CONFIG_H
56#include "compat_getopt.h" 56#include "compat_getopt.h"
57#else 57#else
58#include <getopt.h> 58#include <getopt.h>
59#endif 59#endif
60#include <limits.h> 60#include <limits.h>
61#include <stdio.h> 61#include <stdio.h>
62#include <stdlib.h> 62#include <stdlib.h>
63#include <string.h> 63#include <string.h>
64#include <unistd.h> 64#include <unistd.h>
65#include <paths.h> 65#include <paths.h>
66#include "pax.h" 66#include "pax.h"
67#include "options.h" 67#include "options.h"
68#include "cpio.h" 68#include "cpio.h"
69#include "tar.h" 69#include "tar.h"
70#include "extern.h" 70#include "extern.h"
71#ifndef SMALL 71#ifndef SMALL
72#include "mtree.h" 72#include "mtree.h"
73#endif /* SMALL */ 73#endif /* SMALL */
74 74
75/* 75/*
76 * Routines which handle command line options 76 * Routines which handle command line options
77 */ 77 */
78 78
79static int nopids; /* tar mode: suppress "pids" for -p option */ 79static int nopids; /* tar mode: suppress "pids" for -p option */
80static char flgch[] = FLGCH; /* list of all possible flags (pax) */ 80static char flgch[] = FLGCH; /* list of all possible flags (pax) */
81static OPLIST *ophead = NULL; /* head for format specific options -x */ 81static OPLIST *ophead = NULL; /* head for format specific options -x */
82static OPLIST *optail = NULL; /* option tail */ 82static OPLIST *optail = NULL; /* option tail */
83 83
84static int no_op(void); 84static int no_op(void);
85static void printflg(unsigned int); 85static void printflg(unsigned int);
86static int c_frmt(const void *, const void *); 86static int c_frmt(const void *, const void *);
87static off_t str_offt(char *); 87static off_t str_offt(char *);
88static char *get_line(FILE *fp); 88static char *get_line(FILE *fp);
89static void pax_options(int, char **); 89static void pax_options(int, char **);
90static void pax_usage(void); 90static void pax_usage(void);
91static void tar_options(int, char **); 91static void tar_options(int, char **);
92static void tar_usage(void); 92static void tar_usage(void);
93#ifndef NO_CPIO 93#ifndef NO_CPIO
94static void cpio_options(int, char **); 94static void cpio_options(int, char **);
95static void cpio_usage(void); 95static void cpio_usage(void);
96#endif 96#endif
97 97
98/* errors from get_line */ 98/* errors from get_line */
99#define GETLINE_FILE_CORRUPT 1 99#define GETLINE_FILE_CORRUPT 1
100#define GETLINE_OUT_OF_MEM 2 100#define GETLINE_OUT_OF_MEM 2
101static int get_line_error; 101static int get_line_error;
102 102
103#define BZIP2_CMD "bzip2" /* command to run as bzip2 */ 103#define BZIP2_CMD "bzip2" /* command to run as bzip2 */
104#define GZIP_CMD "gzip" /* command to run as gzip */ 104#define GZIP_CMD "gzip" /* command to run as gzip */
105#define COMPRESS_CMD "compress" /* command to run as compress */ 105#define COMPRESS_CMD "compress" /* command to run as compress */
106 106
107/* 107/*
108 * Long options. 108 * Long options.
109 */ 109 */
110#define OPT_USE_COMPRESS_PROGRAM 0 110#define OPT_USE_COMPRESS_PROGRAM 0
111#define OPT_CHECKPOINT 1 111#define OPT_CHECKPOINT 1
112#define OPT_UNLINK 2 112#define OPT_UNLINK 2
113#define OPT_HELP 3 113#define OPT_HELP 3
114#define OPT_ATIME_PRESERVE 4 114#define OPT_ATIME_PRESERVE 4
115#define OPT_IGNORE_FAILED_READ 5 115#define OPT_IGNORE_FAILED_READ 5
116#define OPT_REMOVE_FILES 6 116#define OPT_REMOVE_FILES 6
117#define OPT_NULL 7 117#define OPT_NULL 7
118#define OPT_TOTALS 8 118#define OPT_TOTALS 8
119#define OPT_VERSION 9 119#define OPT_VERSION 9
120#define OPT_EXCLUDE 10 120#define OPT_EXCLUDE 10
121#define OPT_BLOCK_COMPRESS 11 121#define OPT_BLOCK_COMPRESS 11
122#define OPT_NORECURSE 12 122#define OPT_NORECURSE 12
123#define OPT_FORCE_LOCAL 13 123#define OPT_FORCE_LOCAL 13
124#define OPT_INSECURE 14 124#define OPT_INSECURE 14
125#define OPT_STRICT 15 125#define OPT_STRICT 15
126#define OPT_SPARSE 16 126#define OPT_SPARSE 16
127#if !HAVE_NBTOOL_CONFIG_H 127#if !HAVE_NBTOOL_CONFIG_H
128#define OPT_CHROOT 17 128#define OPT_CHROOT 17
129#endif 129#endif
130 130
131/* 131/*
132 * Format specific routine table - MUST BE IN SORTED ORDER BY NAME 132 * Format specific routine table - MUST BE IN SORTED ORDER BY NAME
133 * (see pax.h for description of each function) 133 * (see pax.h for description of each function)
134 * 134 *
135 * name, blksz, hdsz, udev, hlk, blkagn, inhead, id, st_read, 135 * name, blksz, hdsz, udev, hlk, blkagn, inhead, id, st_read,
136 * read, end_read, st_write, write, end_write, trail, 136 * read, end_read, st_write, write, end_write, trail,
137 * subtrail, rd_data, wr_data, options 137 * subtrail, rd_data, wr_data, options
138 */ 138 */
139 139
140FSUB fsub[] = { 140FSUB fsub[] = {
141#ifndef NO_CPIO 141#ifndef NO_CPIO
142/* 0: OLD BINARY CPIO */ 142/* 0: OLD BINARY CPIO */
143 { "bcpio", 5120, sizeof(HD_BCPIO), 1, 0, 0, 1, bcpio_id, cpio_strd, 143 { "bcpio", 5120, sizeof(HD_BCPIO), 1, 0, 0, 1, bcpio_id, cpio_strd,
144 bcpio_rd, bcpio_endrd, cpio_stwr, bcpio_wr, cpio_endwr, NULL, 144 bcpio_rd, bcpio_endrd, cpio_stwr, bcpio_wr, cpio_endwr, NULL,
145 cpio_subtrail, rd_wrfile, wr_rdfile, bad_opt }, 145 cpio_subtrail, rd_wrfile, wr_rdfile, bad_opt },
146 146
147/* 1: OLD OCTAL CHARACTER CPIO */ 147/* 1: OLD OCTAL CHARACTER CPIO */
148 { "cpio", 5120, sizeof(HD_CPIO), 1, 0, 0, 1, cpio_id, cpio_strd, 148 { "cpio", 5120, sizeof(HD_CPIO), 1, 0, 0, 1, cpio_id, cpio_strd,
149 cpio_rd, cpio_endrd, cpio_stwr, cpio_wr, cpio_endwr, NULL, 149 cpio_rd, cpio_endrd, cpio_stwr, cpio_wr, cpio_endwr, NULL,
150 cpio_subtrail, rd_wrfile, wr_rdfile, bad_opt }, 150 cpio_subtrail, rd_wrfile, wr_rdfile, bad_opt },
151 151
152/* 2: SVR4 HEX CPIO */ 152/* 2: SVR4 HEX CPIO */
153 { "sv4cpio", 5120, sizeof(HD_VCPIO), 1, 0, 0, 1, vcpio_id, cpio_strd, 153 { "sv4cpio", 5120, sizeof(HD_VCPIO), 1, 0, 0, 1, vcpio_id, cpio_strd,
154 vcpio_rd, vcpio_endrd, cpio_stwr, vcpio_wr, cpio_endwr, NULL, 154 vcpio_rd, vcpio_endrd, cpio_stwr, vcpio_wr, cpio_endwr, NULL,
155 cpio_subtrail, rd_wrfile, wr_rdfile, bad_opt }, 155 cpio_subtrail, rd_wrfile, wr_rdfile, bad_opt },
156 156
157/* 3: SVR4 HEX CPIO WITH CRC */ 157/* 3: SVR4 HEX CPIO WITH CRC */
158 { "sv4crc", 5120, sizeof(HD_VCPIO), 1, 0, 0, 1, crc_id, crc_strd, 158 { "sv4crc", 5120, sizeof(HD_VCPIO), 1, 0, 0, 1, crc_id, crc_strd,
159 vcpio_rd, vcpio_endrd, crc_stwr, vcpio_wr, cpio_endwr, NULL, 159 vcpio_rd, vcpio_endrd, crc_stwr, vcpio_wr, cpio_endwr, NULL,
160 cpio_subtrail, rd_wrfile, wr_rdfile, bad_opt }, 160 cpio_subtrail, rd_wrfile, wr_rdfile, bad_opt },
161#endif 161#endif
162/* 4: OLD TAR */ 162/* 4: OLD TAR */
163 { "tar", 10240, BLKMULT, 0, 1, BLKMULT, 0, tar_id, no_op, 163 { "tar", 10240, BLKMULT, 0, 1, BLKMULT, 0, tar_id, no_op,
164 tar_rd, tar_endrd, no_op, tar_wr, tar_endwr, tar_trail, 164 tar_rd, tar_endrd, no_op, tar_wr, tar_endwr, tar_trail,
165 NULL, rd_wrfile, wr_rdfile, tar_opt }, 165 NULL, rd_wrfile, wr_rdfile, tar_opt },
166 166
167/* 5: POSIX USTAR */ 167/* 5: POSIX USTAR */
168 { "ustar", 10240, BLKMULT, 0, 1, BLKMULT, 0, ustar_id, ustar_strd, 168 { "ustar", 10240, BLKMULT, 0, 1, BLKMULT, 0, ustar_id, ustar_strd,
169 ustar_rd, tar_endrd, ustar_stwr, ustar_wr, tar_endwr, tar_trail, 169 ustar_rd, tar_endrd, ustar_stwr, ustar_wr, tar_endwr, tar_trail,
170 NULL, rd_wrfile, wr_rdfile, bad_opt } 170 NULL, rd_wrfile, wr_rdfile, bad_opt }
171}; 171};
172#ifndef NO_CPIO 172#ifndef NO_CPIO
173#define F_BCPIO 0 /* old binary cpio format */ 173#define F_BCPIO 0 /* old binary cpio format */
174#define F_CPIO 1 /* old octal character cpio format */ 174#define F_CPIO 1 /* old octal character cpio format */
175#define F_SV4CPIO 2 /* SVR4 hex cpio format */ 175#define F_SV4CPIO 2 /* SVR4 hex cpio format */
176#define F_SV4CRC 3 /* SVR4 hex with crc cpio format */ 176#define F_SV4CRC 3 /* SVR4 hex with crc cpio format */
177#define F_TAR 4 /* old V7 UNIX tar format */ 177#define F_TAR 4 /* old V7 UNIX tar format */
178#define F_USTAR 5 /* ustar format */ 178#define F_USTAR 5 /* ustar format */
179#else 179#else
180#define F_TAR 0 /* old V7 UNIX tar format */ 180#define F_TAR 0 /* old V7 UNIX tar format */
181#define F_USTAR 1 /* ustar format */ 181#define F_USTAR 1 /* ustar format */
182#endif 182#endif
183#define DEFLT F_USTAR /* default write format from list above */ 183#define DEFLT F_USTAR /* default write format from list above */
184 184
185/* 185/*
186 * ford is the archive search order used by get_arc() to determine what kind 186 * ford is the archive search order used by get_arc() to determine what kind
187 * of archive we are dealing with. This helps to properly id archive formats 187 * of archive we are dealing with. This helps to properly id archive formats
188 * some formats may be subsets of others.... 188 * some formats may be subsets of others....
189 */ 189 */
190int ford[] = {F_USTAR, F_TAR, 190int ford[] = {F_USTAR, F_TAR,
191#ifndef NO_CPIO 191#ifndef NO_CPIO
192 F_SV4CRC, F_SV4CPIO, F_CPIO, F_BCPIO,  192 F_SV4CRC, F_SV4CPIO, F_CPIO, F_BCPIO,
193#endif 193#endif
194 -1}; 194 -1};
195 195
196/* 196/*
197 * filename record separator 197 * filename record separator
198 */ 198 */
199int sep = '\n'; 199int sep = '\n';
200 200
201/* 201/*
202 * Do we have -C anywhere? 202 * Do we have -C anywhere?
203 */ 203 */
204int havechd = 0; 204int havechd = 0;
205 205
206/* 206/*
207 * options() 207 * options()
208 * figure out if we are pax, tar or cpio. Call the appropriate options 208 * figure out if we are pax, tar or cpio. Call the appropriate options
209 * parser 209 * parser
210 */ 210 */
211 211
212void 212void
213options(int argc, char **argv) 213options(int argc, char **argv)
214{ 214{
215 215
216 /* 216 /*
217 * Are we acting like pax, tar or cpio (based on argv[0]) 217 * Are we acting like pax, tar or cpio (based on argv[0])
218 */ 218 */
219 if ((argv0 = strrchr(argv[0], '/')) != NULL) 219 if ((argv0 = strrchr(argv[0], '/')) != NULL)
220 argv0++; 220 argv0++;
221 else 221 else
222 argv0 = argv[0]; 222 argv0 = argv[0];
223 223
224 if (strstr(argv0, NM_TAR)) { 224 if (strstr(argv0, NM_TAR)) {
225 argv0 = NM_TAR; 225 argv0 = NM_TAR;
226 tar_options(argc, argv); 226 tar_options(argc, argv);
227#ifndef NO_CPIO 227#ifndef NO_CPIO
228 } else if (strstr(argv0, NM_CPIO)) { 228 } else if (strstr(argv0, NM_CPIO)) {
229 argv0 = NM_CPIO; 229 argv0 = NM_CPIO;
230 cpio_options(argc, argv); 230 cpio_options(argc, argv);
231#endif 231#endif
232 } else { 232 } else {
233 argv0 = NM_PAX; 233 argv0 = NM_PAX;
234 pax_options(argc, argv); 234 pax_options(argc, argv);
235 } 235 }
236} 236}
237 237
238struct option pax_longopts[] = { 238struct option pax_longopts[] = {
239 { "insecure", no_argument, 0, 239 { "insecure", no_argument, 0,
240 OPT_INSECURE }, 240 OPT_INSECURE },
241 { "force-local", no_argument, 0, 241 { "force-local", no_argument, 0,
242 OPT_FORCE_LOCAL }, 242 OPT_FORCE_LOCAL },
243 { 0, 0, 0, 243 { 0, 0, 0,
244 0 }, 244 0 },
245}; 245};
246 246
247/* 247/*
248 * pax_options() 248 * pax_options()
249 * look at the user specified flags. set globals as required and check if 249 * look at the user specified flags. set globals as required and check if
250 * the user specified a legal set of flags. If not, complain and exit 250 * the user specified a legal set of flags. If not, complain and exit
251 */ 251 */
252 252
253static void 253static void
254pax_options(int argc, char **argv) 254pax_options(int argc, char **argv)
255{ 255{
256 int c; 256 int c;
257 size_t i; 257 size_t i;
258 u_int64_t flg = 0; 258 u_int64_t flg = 0;
259 u_int64_t bflg = 0; 259 u_int64_t bflg = 0;
260 char *pt; 260 char *pt;
261 FSUB tmp; 261 FSUB tmp;
262 262
263 /* 263 /*
264 * process option flags 264 * process option flags
265 */ 265 */
266 while ((c = getopt_long(argc, argv, 266 while ((c = getopt_long(argc, argv,
267 "0ab:cdf:ijklno:p:rs:tuvwx:zAB:DE:G:HLMN:OPT:U:VXYZ", 267 "0ab:cdf:ijklno:p:rs:tuvwx:zAB:DE:G:HLMN:OPT:U:VXYZ",
268 pax_longopts, NULL)) != -1) { 268 pax_longopts, NULL)) != -1) {
269 switch (c) { 269 switch (c) {
270 case '0': 270 case '0':
271 sep = '\0'; 271 sep = '\0';
272 break; 272 break;
273 case 'a': 273 case 'a':
274 /* 274 /*
275 * append 275 * append
276 */ 276 */
277 flg |= AF; 277 flg |= AF;
278 break; 278 break;
279 case 'b': 279 case 'b':
280 /* 280 /*
281 * specify blocksize 281 * specify blocksize
282 */ 282 */
283 flg |= BF; 283 flg |= BF;
284 if ((wrblksz = (int)str_offt(optarg)) <= 0) { 284 if ((wrblksz = (int)str_offt(optarg)) <= 0) {
285 tty_warn(1, "Invalid block size %s", optarg); 285 tty_warn(1, "Invalid block size %s", optarg);
286 pax_usage(); 286 pax_usage();
287 } 287 }
288 break; 288 break;
289 case 'c': 289 case 'c':
290 /* 290 /*
291 * inverse match on patterns 291 * inverse match on patterns
292 */ 292 */
293 cflag = 1; 293 cflag = 1;
294 flg |= CF; 294 flg |= CF;
295 break; 295 break;
296 case 'd': 296 case 'd':
297 /* 297 /*
298 * match only dir on extract, not the subtree at dir 298 * match only dir on extract, not the subtree at dir
299 */ 299 */
300 dflag = 1; 300 dflag = 1;
301 flg |= DF; 301 flg |= DF;
302 break; 302 break;
303 case 'f': 303 case 'f':
304 /* 304 /*
305 * filename where the archive is stored 305 * filename where the archive is stored
306 */ 306 */
307 arcname = optarg; 307 arcname = optarg;
308 flg |= FF; 308 flg |= FF;
309 break; 309 break;
310 case 'i': 310 case 'i':
311 /* 311 /*
312 * interactive file rename 312 * interactive file rename
313 */ 313 */
314 iflag = 1; 314 iflag = 1;
315 flg |= IF; 315 flg |= IF;
316 break; 316 break;
317 case 'j': 317 case 'j':
318 /* 318 /*
319 * pass through bzip2 319 * pass through bzip2
320 */ 320 */
321 jflag = 1; 321 jflag = 1;
322 gzip_program = BZIP2_CMD; 322 gzip_program = BZIP2_CMD;
323 break; 323 break;
324 case 'k': 324 case 'k':
325 /* 325 /*
326 * do not clobber files that exist 326 * do not clobber files that exist
327 */ 327 */
328 kflag = 1; 328 kflag = 1;
329 flg |= KF; 329 flg |= KF;
330 break; 330 break;
331 case 'l': 331 case 'l':
332 /* 332 /*
333 * try to link src to dest with copy (-rw) 333 * try to link src to dest with copy (-rw)
334 */ 334 */
335 lflag = 1; 335 lflag = 1;
336 flg |= LF; 336 flg |= LF;
337 break; 337 break;
338 case 'n': 338 case 'n':
339 /* 339 /*
340 * select first match for a pattern only 340 * select first match for a pattern only
341 */ 341 */
342 nflag = 1; 342 nflag = 1;
343 flg |= NF; 343 flg |= NF;
344 break; 344 break;
345 case 'o': 345 case 'o':
346 /* 346 /*
347 * pass format specific options 347 * pass format specific options
348 */ 348 */
349 flg |= OF; 349 flg |= OF;
350 if (opt_add(optarg) < 0) 350 if (opt_add(optarg) < 0)
351 pax_usage(); 351 pax_usage();
352 break; 352 break;
353 case 'p': 353 case 'p':
354 /* 354 /*
355 * specify file characteristic options 355 * specify file characteristic options
356 */ 356 */
357 for (pt = optarg; *pt != '\0'; ++pt) { 357 for (pt = optarg; *pt != '\0'; ++pt) {
358 switch(*pt) { 358 switch(*pt) {
359 case 'a': 359 case 'a':
360 /* 360 /*
361 * do not preserve access time 361 * do not preserve access time
362 */ 362 */
363 patime = 0; 363 patime = 0;
364 break; 364 break;
365 case 'e': 365 case 'e':
366 /* 366 /*
367 * preserve user id, group id, file 367 * preserve user id, group id, file
368 * mode, access/modification times 368 * mode, access/modification times
369 * and file flags. 369 * and file flags.
370 */ 370 */
371 pids = 1; 371 pids = 1;
372 pmode = 1; 372 pmode = 1;
373 patime = 1; 373 patime = 1;
374 pmtime = 1; 374 pmtime = 1;
375 pfflags = 1; 375 pfflags = 1;
376 break; 376 break;
377#if 0 377#if 0
378 case 'f': 378 case 'f':
379 /* 379 /*
380 * do not preserve file flags 380 * do not preserve file flags
381 */ 381 */
382 pfflags = 0; 382 pfflags = 0;
383 break; 383 break;
384#endif 384#endif
385 case 'm': 385 case 'm':
386 /* 386 /*
387 * do not preserve modification time 387 * do not preserve modification time
388 */ 388 */
389 pmtime = 0; 389 pmtime = 0;
390 break; 390 break;
391 case 'o': 391 case 'o':
392 /* 392 /*
393 * preserve uid/gid 393 * preserve uid/gid
394 */ 394 */
395 pids = 1; 395 pids = 1;
396 break; 396 break;
397 case 'p': 397 case 'p':
398 /* 398 /*
399 * preserve file mode bits 399 * preserve file mode bits
400 */ 400 */
401 pmode = 1; 401 pmode = 1;
402 break; 402 break;
403 default: 403 default:
404 tty_warn(1, "Invalid -p string: %c", 404 tty_warn(1, "Invalid -p string: %c",
405 *pt); 405 *pt);
406 pax_usage(); 406 pax_usage();
407 break; 407 break;
408 } 408 }
409 } 409 }
410 flg |= PF; 410 flg |= PF;
411 break; 411 break;
412 case 'r': 412 case 'r':
413 /* 413 /*
414 * read the archive 414 * read the archive
415 */ 415 */
416 flg |= RF; 416 flg |= RF;
417 break; 417 break;
418 case 's': 418 case 's':
419 /* 419 /*
420 * file name substitution name pattern 420 * file name substitution name pattern
421 */ 421 */
422 if (rep_add(optarg) < 0) { 422 if (rep_add(optarg) < 0) {
423 pax_usage(); 423 pax_usage();
424 break; 424 break;
425 } 425 }
426 flg |= SF; 426 flg |= SF;
427 break; 427 break;
428 case 't': 428 case 't':
429 /* 429 /*
430 * preserve access time on filesystem nodes we read 430 * preserve access time on filesystem nodes we read
431 */ 431 */
432 tflag = 1; 432 tflag = 1;
433 flg |= TF; 433 flg |= TF;
434 break; 434 break;
435 case 'u': 435 case 'u':
436 /* 436 /*
437 * ignore those older files 437 * ignore those older files
438 */ 438 */
439 uflag = 1; 439 uflag = 1;
440 flg |= UF; 440 flg |= UF;
441 break; 441 break;
442 case 'v': 442 case 'v':
443 /* 443 /*
444 * verbose operation mode 444 * verbose operation mode
445 */ 445 */
446 vflag = 1; 446 vflag = 1;
447 flg |= VF; 447 flg |= VF;
448 break; 448 break;
449 case 'w': 449 case 'w':
450 /* 450 /*
451 * write an archive 451 * write an archive
452 */ 452 */
453 flg |= WF; 453 flg |= WF;
454 break; 454 break;
455 case 'x': 455 case 'x':
456 /* 456 /*
457 * specify an archive format on write 457 * specify an archive format on write
458 */ 458 */
459 tmp.name = optarg; 459 tmp.name = optarg;
460 frmt = (FSUB *)bsearch((void *)&tmp, (void *)fsub, 460 frmt = (FSUB *)bsearch((void *)&tmp, (void *)fsub,
461 sizeof(fsub)/sizeof(FSUB), sizeof(FSUB), c_frmt); 461 sizeof(fsub)/sizeof(FSUB), sizeof(FSUB), c_frmt);
462 if (frmt != NULL) { 462 if (frmt != NULL) {
463 flg |= XF; 463 flg |= XF;
464 break; 464 break;
465 } 465 }
466 tty_warn(1, "Unknown -x format: %s", optarg); 466 tty_warn(1, "Unknown -x format: %s", optarg);
467 (void)fputs("pax: Known -x formats are:", stderr); 467 (void)fputs("pax: Known -x formats are:", stderr);
468 for (i = 0; i < (sizeof(fsub)/sizeof(FSUB)); ++i) 468 for (i = 0; i < (sizeof(fsub)/sizeof(FSUB)); ++i)
469 (void)fprintf(stderr, " %s", fsub[i].name); 469 (void)fprintf(stderr, " %s", fsub[i].name);
470 (void)fputs("\n\n", stderr); 470 (void)fputs("\n\n", stderr);
471 pax_usage(); 471 pax_usage();
472 break; 472 break;
473 case 'z': 473 case 'z':
474 /* 474 /*
475 * use gzip. Non standard option. 475 * use gzip. Non standard option.
476 */ 476 */
477 gzip_program = GZIP_CMD; 477 gzip_program = GZIP_CMD;
478 break; 478 break;
479 case 'A': 479 case 'A':
480 Aflag = 1; 480 Aflag = 1;
481 flg |= CAF; 481 flg |= CAF;
482 break; 482 break;
483 case 'B': 483 case 'B':
484 /* 484 /*
485 * non-standard option on number of bytes written on a 485 * non-standard option on number of bytes written on a
486 * single archive volume. 486 * single archive volume.
487 */ 487 */
488 if ((wrlimit = str_offt(optarg)) <= 0) { 488 if ((wrlimit = str_offt(optarg)) <= 0) {
489 tty_warn(1, "Invalid write limit %s", optarg); 489 tty_warn(1, "Invalid write limit %s", optarg);
490 pax_usage(); 490 pax_usage();
491 } 491 }
492 if (wrlimit % BLKMULT) { 492 if (wrlimit % BLKMULT) {
493 tty_warn(1, 493 tty_warn(1,
494 "Write limit is not a %d byte multiple", 494 "Write limit is not a %d byte multiple",
495 BLKMULT); 495 BLKMULT);
496 pax_usage(); 496 pax_usage();
497 } 497 }
498 flg |= CBF; 498 flg |= CBF;
499 break; 499 break;
500 case 'D': 500 case 'D':
501 /* 501 /*
502 * On extraction check file inode change time before the 502 * On extraction check file inode change time before the
503 * modification of the file name. Non standard option. 503 * modification of the file name. Non standard option.
504 */ 504 */
505 Dflag = 1; 505 Dflag = 1;
506 flg |= CDF; 506 flg |= CDF;
507 break; 507 break;
508 case 'E': 508 case 'E':
509 /* 509 /*
510 * non-standard limit on read faults 510 * non-standard limit on read faults
511 * 0 indicates stop after first error, values 511 * 0 indicates stop after first error, values
512 * indicate a limit, "none" try forever 512 * indicate a limit, "none" try forever
513 */ 513 */
514 flg |= CEF; 514 flg |= CEF;
515 if (strcmp(none, optarg) == 0) 515 if (strcmp(none, optarg) == 0)
516 maxflt = -1; 516 maxflt = -1;
517 else if ((maxflt = atoi(optarg)) < 0) { 517 else if ((maxflt = atoi(optarg)) < 0) {
518 tty_warn(1, 518 tty_warn(1,
519 "Error count value must be positive"); 519 "Error count value must be positive");
520 pax_usage(); 520 pax_usage();
521 } 521 }
522 break; 522 break;
523 case 'G': 523 case 'G':
524 /* 524 /*
525 * non-standard option for selecting files within an 525 * non-standard option for selecting files within an
526 * archive by group (gid or name) 526 * archive by group (gid or name)
527 */ 527 */
528 if (grp_add(optarg) < 0) { 528 if (grp_add(optarg) < 0) {
529 pax_usage(); 529 pax_usage();
530 break; 530 break;
531 } 531 }
532 flg |= CGF; 532 flg |= CGF;
533 break; 533 break;
534 case 'H': 534 case 'H':
535 /* 535 /*
536 * follow command line symlinks only 536 * follow command line symlinks only
537 */ 537 */
538 Hflag = 1; 538 Hflag = 1;
539 flg |= CHF; 539 flg |= CHF;
540 break; 540 break;
541 case 'L': 541 case 'L':
542 /* 542 /*
543 * follow symlinks 543 * follow symlinks
544 */ 544 */
545 Lflag = 1; 545 Lflag = 1;
546 flg |= CLF; 546 flg |= CLF;
547 break; 547 break;
548#ifdef SMALL 548#ifdef SMALL
549 case 'M': 549 case 'M':
550 case 'N': 550 case 'N':
551 tty_warn(1, "Support for -%c is not compiled in", c); 551 tty_warn(1, "Support for -%c is not compiled in", c);
552 exit(1); 552 exit(1);
553#else /* !SMALL */ 553#else /* !SMALL */
554 case 'M': 554 case 'M':
555 /* 555 /*
556 * Treat list of filenames on stdin as an 556 * Treat list of filenames on stdin as an
557 * mtree(8) specfile. Non standard option. 557 * mtree(8) specfile. Non standard option.
558 */ 558 */
559 Mflag = 1; 559 Mflag = 1;
560 flg |= CMF; 560 flg |= CMF;
561 break; 561 break;
562 case 'N': 562 case 'N':
563 /* 563 /*
564 * Use alternative directory for user db lookups. 564 * Use alternative directory for user db lookups.
565 */ 565 */
566 if (!setup_getid(optarg)) { 566 if (!setup_getid(optarg)) {
567 tty_warn(1, 567 tty_warn(1,
568 "Unable to use user and group databases in `%s'", 568 "Unable to use user and group databases in `%s'",
569 optarg); 569 optarg);
570 pax_usage(); 570 pax_usage();
571 } 571 }
572 break; 572 break;
573#endif /* !SMALL */ 573#endif /* !SMALL */
574 case 'O': 574 case 'O':
575 /* 575 /*
576 * Force one volume. Non standard option. 576 * Force one volume. Non standard option.
577 */ 577 */
578 force_one_volume = 1; 578 force_one_volume = 1;
579 break; 579 break;
580 case 'P': 580 case 'P':
581 /* 581 /*
582 * do NOT follow symlinks (default) 582 * do NOT follow symlinks (default)
583 */ 583 */
584 Lflag = 0; 584 Lflag = 0;
585 flg |= CPF; 585 flg |= CPF;
586 break; 586 break;
587 case 'T': 587 case 'T':
588 /* 588 /*
589 * non-standard option for selecting files within an 589 * non-standard option for selecting files within an
590 * archive by modification time range (lower,upper) 590 * archive by modification time range (lower,upper)
591 */ 591 */
592 if (trng_add(optarg) < 0) { 592 if (trng_add(optarg) < 0) {
593 pax_usage(); 593 pax_usage();
594 break; 594 break;
595 } 595 }
596 flg |= CTF; 596 flg |= CTF;
597 break; 597 break;
598 case 'U': 598 case 'U':
599 /* 599 /*
600 * non-standard option for selecting files within an 600 * non-standard option for selecting files within an
601 * archive by user (uid or name) 601 * archive by user (uid or name)
602 */ 602 */
603 if (usr_add(optarg) < 0) { 603 if (usr_add(optarg) < 0) {
604 pax_usage(); 604 pax_usage();
605 break; 605 break;
606 } 606 }
607 flg |= CUF; 607 flg |= CUF;
608 break; 608 break;
609 case 'V': 609 case 'V':
610 /* 610 /*
611 * somewhat verbose operation mode (no listing) 611 * somewhat verbose operation mode (no listing)
612 */ 612 */
613 Vflag = 1; 613 Vflag = 1;
614 flg |= VSF; 614 flg |= VSF;
615 break; 615 break;
616 case 'X': 616 case 'X':
617 /* 617 /*
618 * do not pass over mount points in the file system 618 * do not pass over mount points in the file system
619 */ 619 */
620 Xflag = 1; 620 Xflag = 1;
621 flg |= CXF; 621 flg |= CXF;
622 break; 622 break;
623 case 'Y': 623 case 'Y':
624 /* 624 /*
625 * On extraction check file inode change time after the 625 * On extraction check file inode change time after the
626 * modification of the file name. Non standard option. 626 * modification of the file name. Non standard option.
627 */ 627 */
628 Yflag = 1; 628 Yflag = 1;
629 flg |= CYF; 629 flg |= CYF;
630 break; 630 break;
631 case 'Z': 631 case 'Z':
632 /* 632 /*
633 * On extraction check modification time after the 633 * On extraction check modification time after the
634 * modification of the file name. Non standard option. 634 * modification of the file name. Non standard option.
635 */ 635 */
636 Zflag = 1; 636 Zflag = 1;
637 flg |= CZF; 637 flg |= CZF;
638 break; 638 break;
639 case OPT_INSECURE: 639 case OPT_INSECURE:
640 secure = 0; 640 secure = 0;
641 break; 641 break;
642 case OPT_FORCE_LOCAL: 642 case OPT_FORCE_LOCAL:
643 forcelocal = 0; 643 forcelocal = 0;
644 break; 644 break;
645 case '?': 645 case '?':
646 default: 646 default:
647 pax_usage(); 647 pax_usage();
648 break; 648 break;
649 } 649 }
650 } 650 }
651 651
652 /* 652 /*
653 * figure out the operation mode of pax read,write,extract,copy,append 653 * figure out the operation mode of pax read,write,extract,copy,append
654 * or list. check that we have not been given a bogus set of flags 654 * or list. check that we have not been given a bogus set of flags
655 * for the operation mode. 655 * for the operation mode.
656 */ 656 */
657 if (ISLIST(flg)) { 657 if (ISLIST(flg)) {
658 act = LIST; 658 act = LIST;
659 listf = stdout; 659 listf = stdout;
660 bflg = flg & BDLIST; 660 bflg = flg & BDLIST;
661 } else if (ISEXTRACT(flg)) { 661 } else if (ISEXTRACT(flg)) {
662 act = EXTRACT; 662 act = EXTRACT;
663 bflg = flg & BDEXTR; 663 bflg = flg & BDEXTR;
664 } else if (ISARCHIVE(flg)) { 664 } else if (ISARCHIVE(flg)) {
665 act = ARCHIVE; 665 act = ARCHIVE;
666 bflg = flg & BDARCH; 666 bflg = flg & BDARCH;
667 } else if (ISAPPND(flg)) { 667 } else if (ISAPPND(flg)) {
668 act = APPND; 668 act = APPND;
669 bflg = flg & BDARCH; 669 bflg = flg & BDARCH;
670 } else if (ISCOPY(flg)) { 670 } else if (ISCOPY(flg)) {
671 act = COPY; 671 act = COPY;
672 bflg = flg & BDCOPY; 672 bflg = flg & BDCOPY;
673 } else 673 } else
674 pax_usage(); 674 pax_usage();
675 if (bflg) { 675 if (bflg) {
676 printflg(flg); 676 printflg(flg);
677 pax_usage(); 677 pax_usage();
678 } 678 }
679 679
680 /* 680 /*
681 * if we are writing (ARCHIVE) we use the default format if the user 681 * if we are writing (ARCHIVE) we use the default format if the user
682 * did not specify a format. when we write during an APPEND, we will 682 * did not specify a format. when we write during an APPEND, we will
683 * adopt the format of the existing archive if none was supplied. 683 * adopt the format of the existing archive if none was supplied.
684 */ 684 */
685 if (!(flg & XF) && (act == ARCHIVE)) 685 if (!(flg & XF) && (act == ARCHIVE))
686 frmt = &(fsub[DEFLT]); 686 frmt = &(fsub[DEFLT]);
687 687
688 /* 688 /*
689 * process the args as they are interpreted by the operation mode 689 * process the args as they are interpreted by the operation mode
690 */ 690 */
691 switch (act) { 691 switch (act) {
692 case LIST: 692 case LIST:
693 case EXTRACT: 693 case EXTRACT:
694 for (; optind < argc; optind++) 694 for (; optind < argc; optind++)
695 if (pat_add(argv[optind], NULL, NOGLOB_MTCH) < 0) 695 if (pat_add(argv[optind], NULL, 0) < 0)
696 pax_usage(); 696 pax_usage();
697 break; 697 break;
698 case COPY: 698 case COPY:
699 if (optind >= argc) { 699 if (optind >= argc) {
700 tty_warn(0, "Destination directory was not supplied"); 700 tty_warn(0, "Destination directory was not supplied");
701 pax_usage(); 701 pax_usage();
702 } 702 }
703 --argc; 703 --argc;
704 dirptr = argv[argc]; 704 dirptr = argv[argc];
705 if (mkpath(dirptr) < 0) 705 if (mkpath(dirptr) < 0)
706 exit(1); 706 exit(1);
707 /* FALLTHROUGH */ 707 /* FALLTHROUGH */
708 case ARCHIVE: 708 case ARCHIVE:
709 case APPND: 709 case APPND:
710 for (; optind < argc; optind++) 710 for (; optind < argc; optind++)
711 if (ftree_add(argv[optind], 0) < 0) 711 if (ftree_add(argv[optind], 0) < 0)
712 pax_usage(); 712 pax_usage();
713 /* 713 /*
714 * no read errors allowed on updates/append operation! 714 * no read errors allowed on updates/append operation!
715 */ 715 */
716 maxflt = 0; 716 maxflt = 0;
717 break; 717 break;
718 } 718 }
719} 719}
720 720
721 721
722/* 722/*
723 * tar_options() 723 * tar_options()
724 * look at the user specified flags. set globals as required and check if 724 * look at the user specified flags. set globals as required and check if
725 * the user specified a legal set of flags. If not, complain and exit 725 * the user specified a legal set of flags. If not, complain and exit
726 */ 726 */
727 727
728struct option tar_longopts[] = { 728struct option tar_longopts[] = {
729 { "block-size", required_argument, 0, 'b' }, 729 { "block-size", required_argument, 0, 'b' },
730 { "bunzip2", no_argument, 0, 'j' }, 730 { "bunzip2", no_argument, 0, 'j' },
731 { "bzip2", no_argument, 0, 'j' }, 731 { "bzip2", no_argument, 0, 'j' },
732 { "create", no_argument, 0, 'c' }, /* F */ 732 { "create", no_argument, 0, 'c' }, /* F */
733 /* -e -- no corresponding long option */ 733 /* -e -- no corresponding long option */
734 { "file", required_argument, 0, 'f' }, 734 { "file", required_argument, 0, 'f' },
735 { "dereference", no_argument, 0, 'h' }, 735 { "dereference", no_argument, 0, 'h' },
736 { "keep-old-files", no_argument, 0, 'k' }, 736 { "keep-old-files", no_argument, 0, 'k' },
737 { "one-file-system", no_argument, 0, 'l' }, 737 { "one-file-system", no_argument, 0, 'l' },
738 { "modification-time", no_argument, 0, 'm' }, 738 { "modification-time", no_argument, 0, 'm' },
739 { "old-archive", no_argument, 0, 'o' }, 739 { "old-archive", no_argument, 0, 'o' },
740 { "portability", no_argument, 0, 'o' }, 740 { "portability", no_argument, 0, 'o' },
741 { "same-permissions", no_argument, 0, 'p' }, 741 { "same-permissions", no_argument, 0, 'p' },
742 { "preserve-permissions", no_argument, 0, 'p' }, 742 { "preserve-permissions", no_argument, 0, 'p' },
743 { "preserve", no_argument, 0, 'p' }, 743 { "preserve", no_argument, 0, 'p' },
744 { "fast-read", no_argument, 0, 'q' }, 744 { "fast-read", no_argument, 0, 'q' },
745 { "append", no_argument, 0, 'r' }, /* F */ 745 { "append", no_argument, 0, 'r' }, /* F */
746 { "update", no_argument, 0, 'u' }, /* F */ 746 { "update", no_argument, 0, 'u' }, /* F */
747 { "list", no_argument, 0, 't' }, /* F */ 747 { "list", no_argument, 0, 't' }, /* F */
748 { "verbose", no_argument, 0, 'v' }, 748 { "verbose", no_argument, 0, 'v' },
749 { "interactive", no_argument, 0, 'w' }, 749 { "interactive", no_argument, 0, 'w' },
750 { "confirmation", no_argument, 0, 'w' }, 750 { "confirmation", no_argument, 0, 'w' },
751 { "extract", no_argument, 0, 'x' }, /* F */ 751 { "extract", no_argument, 0, 'x' }, /* F */
752 { "get", no_argument, 0, 'x' }, /* F */ 752 { "get", no_argument, 0, 'x' }, /* F */
753 { "gzip", no_argument, 0, 'z' }, 753 { "gzip", no_argument, 0, 'z' },
754 { "gunzip", no_argument, 0, 'z' }, 754 { "gunzip", no_argument, 0, 'z' },
755 { "read-full-blocks", no_argument, 0, 'B' }, 755 { "read-full-blocks", no_argument, 0, 'B' },
756 { "directory", required_argument, 0, 'C' }, 756 { "directory", required_argument, 0, 'C' },
757 { "to-stdout", no_argument, 0, 'O' }, 757 { "to-stdout", no_argument, 0, 'O' },
758 { "absolute-paths", no_argument, 0, 'P' }, 758 { "absolute-paths", no_argument, 0, 'P' },
759 { "sparse", no_argument, 0, 'S' }, 759 { "sparse", no_argument, 0, 'S' },
760 { "files-from", required_argument, 0, 'T' }, 760 { "files-from", required_argument, 0, 'T' },
761 { "summary", no_argument, 0, 'V' }, 761 { "summary", no_argument, 0, 'V' },
762 { "stats", no_argument, 0, 'V' }, 762 { "stats", no_argument, 0, 'V' },
763 { "exclude-from", required_argument, 0, 'X' }, 763 { "exclude-from", required_argument, 0, 'X' },
764 { "compress", no_argument, 0, 'Z' }, 764 { "compress", no_argument, 0, 'Z' },
765 { "uncompress", no_argument, 0, 'Z' }, 765 { "uncompress", no_argument, 0, 'Z' },
766 { "strict", no_argument, 0, 766 { "strict", no_argument, 0,
767 OPT_STRICT }, 767 OPT_STRICT },
768 { "atime-preserve", no_argument, 0, 768 { "atime-preserve", no_argument, 0,
769 OPT_ATIME_PRESERVE }, 769 OPT_ATIME_PRESERVE },
770 { "unlink", no_argument, 0, 770 { "unlink", no_argument, 0,
771 OPT_UNLINK }, 771 OPT_UNLINK },
772 { "use-compress-program", required_argument, 0, 772 { "use-compress-program", required_argument, 0,
773 OPT_USE_COMPRESS_PROGRAM }, 773 OPT_USE_COMPRESS_PROGRAM },
774 { "force-local", no_argument, 0, 774 { "force-local", no_argument, 0,
775 OPT_FORCE_LOCAL }, 775 OPT_FORCE_LOCAL },
776 { "insecure", no_argument, 0, 776 { "insecure", no_argument, 0,
777 OPT_INSECURE }, 777 OPT_INSECURE },
778 { "exclude", required_argument, 0, 778 { "exclude", required_argument, 0,
779 OPT_EXCLUDE }, 779 OPT_EXCLUDE },
780 { "no-recursion", no_argument, 0, 780 { "no-recursion", no_argument, 0,
781 OPT_NORECURSE }, 781 OPT_NORECURSE },
782#if !HAVE_NBTOOL_CONFIG_H 782#if !HAVE_NBTOOL_CONFIG_H
783 { "chroot", no_argument, 0, 783 { "chroot", no_argument, 0,
784 OPT_CHROOT }, 784 OPT_CHROOT },
785#endif 785#endif
786#if 0 /* Not implemented */ 786#if 0 /* Not implemented */
787 { "catenate", no_argument, 0, 'A' }, /* F */ 787 { "catenate", no_argument, 0, 'A' }, /* F */
788 { "concatenate", no_argument, 0, 'A' }, /* F */ 788 { "concatenate", no_argument, 0, 'A' }, /* F */
789 { "diff", no_argument, 0, 'd' }, /* F */ 789 { "diff", no_argument, 0, 'd' }, /* F */
790 { "compare", no_argument, 0, 'd' }, /* F */ 790 { "compare", no_argument, 0, 'd' }, /* F */
791 { "checkpoint", no_argument, 0, 791 { "checkpoint", no_argument, 0,
792 OPT_CHECKPOINT }, 792 OPT_CHECKPOINT },
793 { "help", no_argument, 0, 793 { "help", no_argument, 0,
794 OPT_HELP }, 794 OPT_HELP },
795 { "info-script", required_argument, 0, 'F' }, 795 { "info-script", required_argument, 0, 'F' },
796 { "new-volume-script", required_argument, 0, 'F' }, 796 { "new-volume-script", required_argument, 0, 'F' },
797 { "incremental", no_argument, 0, 'G' }, 797 { "incremental", no_argument, 0, 'G' },
798 { "listed-incremental", required_argument, 0, 'g' }, 798 { "listed-incremental", required_argument, 0, 'g' },
799 { "ignore-zeros", no_argument, 0, 'i' }, 799 { "ignore-zeros", no_argument, 0, 'i' },
800 { "ignore-failed-read", no_argument, 0, 800 { "ignore-failed-read", no_argument, 0,
801 OPT_IGNORE_FAILED_READ }, 801 OPT_IGNORE_FAILED_READ },
802 { "starting-file", no_argument, 0, 'K' }, 802 { "starting-file", no_argument, 0, 'K' },
803 { "tape-length", required_argument, 0, 'L' }, 803 { "tape-length", required_argument, 0, 'L' },
804 { "multi-volume", no_argument, 0, 'M' }, 804 { "multi-volume", no_argument, 0, 'M' },
805 { "after-date", required_argument, 0, 'N' }, 805 { "after-date", required_argument, 0, 'N' },
806 { "newer", required_argument, 0, 'N' }, 806 { "newer", required_argument, 0, 'N' },
807 { "record-number", no_argument, 0, 'R' }, 807 { "record-number", no_argument, 0, 'R' },
808 { "remove-files", no_argument, 0, 808 { "remove-files", no_argument, 0,
809 OPT_REMOVE_FILES }, 809 OPT_REMOVE_FILES },
810 { "same-order", no_argument, 0, 's' }, 810 { "same-order", no_argument, 0, 's' },
811 { "preserve-order", no_argument, 0, 's' }, 811 { "preserve-order", no_argument, 0, 's' },
812 { "null", no_argument, 0, 812 { "null", no_argument, 0,
813 OPT_NULL }, 813 OPT_NULL },
814 { "totals", no_argument, 0, 814 { "totals", no_argument, 0,
815 OPT_TOTALS }, 815 OPT_TOTALS },
816 { "volume-name", required_argument, 0, 'V' }, /* XXX */ 816 { "volume-name", required_argument, 0, 'V' }, /* XXX */
817 { "label", required_argument, 0, 'V' }, /* XXX */ 817 { "label", required_argument, 0, 'V' }, /* XXX */
818 { "version", no_argument, 0, 818 { "version", no_argument, 0,
819 OPT_VERSION }, 819 OPT_VERSION },
820 { "verify", no_argument, 0, 'W' }, 820 { "verify", no_argument, 0, 'W' },
821 { "block-compress", no_argument, 0, 821 { "block-compress", no_argument, 0,
822 OPT_BLOCK_COMPRESS }, 822 OPT_BLOCK_COMPRESS },
823#endif 823#endif
824 { 0, 0, 0, 0 }, 824 { 0, 0, 0, 0 },
825}; 825};
826 826
827static void 827static void
828tar_set_action(int op) 828tar_set_action(int op)
829{ 829{
830 if (act != ERROR && act != op) 830 if (act != ERROR && act != op)
831 tar_usage(); 831 tar_usage();
832 act = op; 832 act = op;
833} 833}
834 834
835static void 835static void
836tar_options(int argc, char **argv) 836tar_options(int argc, char **argv)
837{ 837{
838 int c; 838 int c;
839 int fstdin = 0; 839 int fstdin = 0;
840 int Oflag = 0; 840 int Oflag = 0;
841 int nincfiles = 0; 841 int nincfiles = 0;
842 int incfiles_max = 0; 842 int incfiles_max = 0;
843 struct incfile { 843 struct incfile {
844 char *file; 844 char *file;
845 char *dir; 845 char *dir;
846 }; 846 };
847 struct incfile *incfiles = NULL; 847 struct incfile *incfiles = NULL;
848 848
849 /* 849 /*
850 * Set default values. 850 * Set default values.
851 */ 851 */
852 rmleadslash = 1; 852 rmleadslash = 1;
853 is_gnutar = 1; 853 is_gnutar = 1;
854 854
855 /* 855 /*
856 * process option flags 856 * process option flags
857 */ 857 */
858 while ((c = getoldopt(argc, argv, 858 while ((c = getoldopt(argc, argv,
859 "+b:cef:hjklmopqrs:tuvwxzBC:HI:OPST:X:Z014578", 859 "+b:cef:hjklmopqrs:tuvwxzBC:HI:OPST:X:Z014578",
860 tar_longopts, NULL)) 860 tar_longopts, NULL))
861 != -1) { 861 != -1) {
862 switch(c) { 862 switch(c) {
863 case 'b': 863 case 'b':
864 /* 864 /*
865 * specify blocksize in 512-byte blocks 865 * specify blocksize in 512-byte blocks
866 */ 866 */
867 if ((wrblksz = (int)str_offt(optarg)) <= 0) { 867 if ((wrblksz = (int)str_offt(optarg)) <= 0) {
868 tty_warn(1, "Invalid block size %s", optarg); 868 tty_warn(1, "Invalid block size %s", optarg);
869 tar_usage(); 869 tar_usage();
870 } 870 }
871 wrblksz *= 512; /* XXX - check for int oflow */ 871 wrblksz *= 512; /* XXX - check for int oflow */
872 break; 872 break;
873 case 'c': 873 case 'c':
874 /* 874 /*
875 * create an archive 875 * create an archive
876 */ 876 */
877 tar_set_action(ARCHIVE); 877 tar_set_action(ARCHIVE);
878 break; 878 break;
879 case 'e': 879 case 'e':
880 /* 880 /*
881 * stop after first error 881 * stop after first error
882 */ 882 */
883 maxflt = 0; 883 maxflt = 0;
884 break; 884 break;
885 case 'f': 885 case 'f':
886 /* 886 /*
887 * filename where the archive is stored 887 * filename where the archive is stored
888 */ 888 */
889 if ((optarg[0] == '-') && (optarg[1]== '\0')) { 889 if ((optarg[0] == '-') && (optarg[1]== '\0')) {
890 /* 890 /*
891 * treat a - as stdin 891 * treat a - as stdin
892 */ 892 */
893 fstdin = 1; 893 fstdin = 1;
894 arcname = NULL; 894 arcname = NULL;
895 break; 895 break;
896 } 896 }
897 fstdin = 0; 897 fstdin = 0;
898 arcname = optarg; 898 arcname = optarg;
899 break; 899 break;
900 case 'h': 900 case 'h':
901 /* 901 /*
902 * follow symlinks 902 * follow symlinks
903 */ 903 */
904 Lflag = 1; 904 Lflag = 1;
905 break; 905 break;
906 case 'j': 906 case 'j':
907 /* 907 /*
908 * pass through bzip2. not a standard option 908 * pass through bzip2. not a standard option
909 */ 909 */
910 jflag = 1; 910 jflag = 1;
911 gzip_program = BZIP2_CMD; 911 gzip_program = BZIP2_CMD;
912 break; 912 break;
913 case 'k': 913 case 'k':
914 /* 914 /*
915 * do not clobber files that exist 915 * do not clobber files that exist
916 */ 916 */
917 kflag = 1; 917 kflag = 1;
918 break; 918 break;
919 case 'l': 919 case 'l':
920 /* 920 /*
921 * do not pass over mount points in the file system 921 * do not pass over mount points in the file system
922 */ 922 */
923 Xflag = 1; 923 Xflag = 1;
924 break; 924 break;
925 case 'm': 925 case 'm':
926 /* 926 /*
927 * do not preserve modification time 927 * do not preserve modification time
928 */ 928 */
929 pmtime = 0; 929 pmtime = 0;
930 break; 930 break;
931 case 'o': 931 case 'o':
932 /* 932 /*
933 * This option does several things based on whether 933 * This option does several things based on whether
934 * this is a create or extract operation. 934 * this is a create or extract operation.
935 */ 935 */
936 if (act == ARCHIVE) { 936 if (act == ARCHIVE) {
937 /* GNU tar: write V7 format archives. */ 937 /* GNU tar: write V7 format archives. */
938 Oflag = 1; 938 Oflag = 1;
939 /* 4.2BSD: don't add directory entries. */ 939 /* 4.2BSD: don't add directory entries. */
940 if (opt_add("write_opt=nodir") < 0) 940 if (opt_add("write_opt=nodir") < 0)
941 tar_usage(); 941 tar_usage();
942 942
943 } else { 943 } else {
944 /* SUS: don't preserve owner/group. */ 944 /* SUS: don't preserve owner/group. */
945 pids = 0; 945 pids = 0;
946 nopids = 1; 946 nopids = 1;
947 } 947 }
948 break; 948 break;
949 case 'O': 949 case 'O':
950 Oflag = 1; 950 Oflag = 1;
951 break; 951 break;
952 case 'p': 952 case 'p':
953 /* 953 /*
954 * preserve user id, group id, file 954 * preserve user id, group id, file
955 * mode, access/modification times 955 * mode, access/modification times
956 */ 956 */
957 if (!nopids) 957 if (!nopids)
958 pids = 1; 958 pids = 1;
959 pmode = 1; 959 pmode = 1;
960 patime = 1; 960 patime = 1;
961 pmtime = 1; 961 pmtime = 1;
962 break; 962 break;
963 case 'q': 963 case 'q':
964 /* 964 /*
965 * select first match for a pattern only 965 * select first match for a pattern only
966 */ 966 */
967 nflag = 1; 967 nflag = 1;
968 break; 968 break;
969 case 'r': 969 case 'r':
970 case 'u': 970 case 'u':
971 /* 971 /*
972 * append to the archive 972 * append to the archive
973 */ 973 */
974 tar_set_action(APPND); 974 tar_set_action(APPND);
975 break; 975 break;
976 case 's': 976 case 's':
977 /* 977 /*
978 * file name substitution name pattern 978 * file name substitution name pattern
979 */ 979 */
980 if (rep_add(optarg) < 0) { 980 if (rep_add(optarg) < 0) {
981 tar_usage(); 981 tar_usage();
982 break; 982 break;
983 } 983 }
984 break; 984 break;
985 case 't': 985 case 't':
986 /* 986 /*
987 * list contents of the tape 987 * list contents of the tape
988 */ 988 */
989 tar_set_action(LIST); 989 tar_set_action(LIST);
990 break; 990 break;
991 case 'v': 991 case 'v':
992 /* 992 /*
993 * verbose operation mode 993 * verbose operation mode
994 */ 994 */
995 vflag = 1; 995 vflag = 1;
996 break; 996 break;
997 case 'w': 997 case 'w':
998 /* 998 /*
999 * interactive file rename 999 * interactive file rename
1000 */ 1000 */
1001 iflag = 1; 1001 iflag = 1;
1002 break; 1002 break;
1003 case 'x': 1003 case 'x':
1004 /* 1004 /*
1005 * extract an archive, preserving mode, 1005 * extract an archive, preserving mode,
1006 * and mtime if possible. 1006 * and mtime if possible.
1007 */ 1007 */
1008 tar_set_action(EXTRACT); 1008 tar_set_action(EXTRACT);
1009 pmtime = 1; 1009 pmtime = 1;
1010 break; 1010 break;
1011 case 'z': 1011 case 'z':
1012 /* 1012 /*
1013 * use gzip. Non standard option. 1013 * use gzip. Non standard option.
1014 */ 1014 */
1015 zflag = 1; 1015 zflag = 1;
1016 gzip_program = GZIP_CMD; 1016 gzip_program = GZIP_CMD;
1017 break; 1017 break;
1018 case 'B': 1018 case 'B':
1019 /* 1019 /*
1020 * Nothing to do here, this is pax default 1020 * Nothing to do here, this is pax default
1021 */ 1021 */
1022 break; 1022 break;
1023 case 'C': 1023 case 'C':
1024 havechd++; 1024 havechd++;
1025 chdname = optarg; 1025 chdname = optarg;
1026 break; 1026 break;
1027 case 'H': 1027 case 'H':
1028 /* 1028 /*
1029 * follow command line symlinks only 1029 * follow command line symlinks only
1030 */ 1030 */
1031 Hflag = 1; 1031 Hflag = 1;
1032 break; 1032 break;
1033 case 'I': 1033 case 'I':
1034 case 'T': 1034 case 'T':
1035 if (++nincfiles > incfiles_max) { 1035 if (++nincfiles > incfiles_max) {
1036 incfiles_max = nincfiles + 3; 1036 incfiles_max = nincfiles + 3;
1037 incfiles = realloc(incfiles, 1037 incfiles = realloc(incfiles,
1038 sizeof(*incfiles) * incfiles_max); 1038 sizeof(*incfiles) * incfiles_max);
1039 if (incfiles == NULL) { 1039 if (incfiles == NULL) {
1040 tty_warn(0, "Unable to allocate space " 1040 tty_warn(0, "Unable to allocate space "
1041 "for option list"); 1041 "for option list");
1042 exit(1); 1042 exit(1);
1043 } 1043 }
1044 } 1044 }
1045 incfiles[nincfiles - 1].file = optarg; 1045 incfiles[nincfiles - 1].file = optarg;
1046 incfiles[nincfiles - 1].dir = chdname; 1046 incfiles[nincfiles - 1].dir = chdname;
1047 break; 1047 break;
1048 case 'P': 1048 case 'P':
1049 /* 1049 /*
1050 * do not remove leading '/' from pathnames 1050 * do not remove leading '/' from pathnames
1051 */ 1051 */
1052 rmleadslash = 0; 1052 rmleadslash = 0;
1053 Aflag = 1; 1053 Aflag = 1;
1054 break; 1054 break;
1055 case 'S': 1055 case 'S':
1056 /* do nothing; we already generate sparse files */ 1056 /* do nothing; we already generate sparse files */
1057 break; 1057 break;
1058 case 'V': 1058 case 'V':
1059 /* 1059 /*
1060 * semi-verbose operation mode (no listing) 1060 * semi-verbose operation mode (no listing)
1061 */ 1061 */
1062 Vflag = 1; 1062 Vflag = 1;
1063 break; 1063 break;
1064 case 'X': 1064 case 'X':
1065 /* 1065 /*
1066 * GNU tar compat: exclude the files listed in optarg 1066 * GNU tar compat: exclude the files listed in optarg
1067 */ 1067 */
1068 if (tar_gnutar_X_compat(optarg) != 0) 1068 if (tar_gnutar_X_compat(optarg) != 0)
1069 tar_usage(); 1069 tar_usage();
1070 break; 1070 break;
1071 case 'Z': 1071 case 'Z':
1072 /* 1072 /*
1073 * use compress. 1073 * use compress.
1074 */ 1074 */
1075 zflag = 1; 1075 zflag = 1;
1076 gzip_program = COMPRESS_CMD; 1076 gzip_program = COMPRESS_CMD;
1077 break; 1077 break;
1078 case '0': 1078 case '0':
1079 arcname = DEV_0; 1079 arcname = DEV_0;
1080 break; 1080 break;
1081 case '1': 1081 case '1':
1082 arcname = DEV_1; 1082 arcname = DEV_1;
1083 break; 1083 break;
1084 case '4': 1084 case '4':
1085 arcname = DEV_4; 1085 arcname = DEV_4;
1086 break; 1086 break;
1087 case '5': 1087 case '5':
1088 arcname = DEV_5; 1088 arcname = DEV_5;
1089 break; 1089 break;
1090 case '7': 1090 case '7':
1091 arcname = DEV_7; 1091 arcname = DEV_7;
1092 break; 1092 break;
1093 case '8': 1093 case '8':
1094 arcname = DEV_8; 1094 arcname = DEV_8;
1095 break; 1095 break;
1096 case OPT_ATIME_PRESERVE: 1096 case OPT_ATIME_PRESERVE:
1097 patime = 1; 1097 patime = 1;
1098 break; 1098 break;
1099 case OPT_UNLINK: 1099 case OPT_UNLINK:
1100 /* Just ignore -- we always unlink first. */ 1100 /* Just ignore -- we always unlink first. */
1101 break; 1101 break;
1102 case OPT_USE_COMPRESS_PROGRAM: 1102 case OPT_USE_COMPRESS_PROGRAM:
1103 zflag = 1; 1103 zflag = 1;
1104 gzip_program = optarg; 1104 gzip_program = optarg;
1105 break; 1105 break;
1106 case OPT_FORCE_LOCAL: 1106 case OPT_FORCE_LOCAL:
1107 forcelocal = 1; 1107 forcelocal = 1;
1108 break; 1108 break;
1109 case OPT_INSECURE: 1109 case OPT_INSECURE:
1110 secure = 0; 1110 secure = 0;
1111 break; 1111 break;
1112 case OPT_STRICT: 1112 case OPT_STRICT:
1113 /* disable gnu extensions */ 1113 /* disable gnu extensions */
1114 is_gnutar = 0; 1114 is_gnutar = 0;
1115 break; 1115 break;
1116 case OPT_EXCLUDE: 1116 case OPT_EXCLUDE:
1117 if (tar_gnutar_minus_minus_exclude(optarg) != 0) 1117 if (tar_gnutar_minus_minus_exclude(optarg) != 0)
1118 tar_usage(); 1118 tar_usage();
1119 break; 1119 break;
1120 case OPT_NORECURSE: 1120 case OPT_NORECURSE:
1121 dflag = 1; 1121 dflag = 1;
1122 break; 1122 break;
1123#if !HAVE_NBTOOL_CONFIG_H 1123#if !HAVE_NBTOOL_CONFIG_H
1124 case OPT_CHROOT: 1124 case OPT_CHROOT:
1125 do_chroot = 1; 1125 do_chroot = 1;
1126 break; 1126 break;
1127#endif 1127#endif
1128 default: 1128 default:
1129 tar_usage(); 1129 tar_usage();
1130 break; 1130 break;
1131 } 1131 }
1132 } 1132 }
1133 argc -= optind; 1133 argc -= optind;
1134 argv += optind; 1134 argv += optind;
1135 1135
1136 /* Tar requires an action. */ 1136 /* Tar requires an action. */
1137 if (act == ERROR) 1137 if (act == ERROR)
1138 tar_usage(); 1138 tar_usage();
1139 1139
1140 /* Traditional tar behaviour (pax uses stderr unless in list mode) */ 1140 /* Traditional tar behaviour (pax uses stderr unless in list mode) */
1141 if (fstdin == 1 && act == ARCHIVE) 1141 if (fstdin == 1 && act == ARCHIVE)
1142 listf = stderr; 1142 listf = stderr;
1143 else 1143 else
1144 listf = stdout; 1144 listf = stdout;
1145 1145
1146 /* Traditional tar behaviour (pax wants to read file list from stdin) */ 1146 /* Traditional tar behaviour (pax wants to read file list from stdin) */
1147 if ((act == ARCHIVE || act == APPND) && argc == 0 && nincfiles == 0) 1147 if ((act == ARCHIVE || act == APPND) && argc == 0 && nincfiles == 0)
1148 exit(0); 1148 exit(0);
1149 /* 1149 /*
1150 * if we are writing (ARCHIVE) specify tar, otherwise run like pax 1150 * if we are writing (ARCHIVE) specify tar, otherwise run like pax
1151 * (unless -o specified) 1151 * (unless -o specified)
1152 */ 1152 */
1153 if (act == ARCHIVE || act == APPND) 1153 if (act == ARCHIVE || act == APPND)
1154 frmt = &(fsub[Oflag ? F_TAR : F_USTAR]); 1154 frmt = &(fsub[Oflag ? F_TAR : F_USTAR]);
1155 else if (Oflag) { 1155 else if (Oflag) {
1156 if (act == EXTRACT) 1156 if (act == EXTRACT)
1157 to_stdout = 1; 1157 to_stdout = 1;
1158 else { 1158 else {
1159 tty_warn(1, "The -O/-o options are only valid when " 1159 tty_warn(1, "The -O/-o options are only valid when "
1160 "writing or extracting an archive"); 1160 "writing or extracting an archive");
1161 tar_usage(); 1161 tar_usage();
1162 } 1162 }
1163 } 1163 }
1164 1164
1165 /* 1165 /*
1166 * process the args as they are interpreted by the operation mode 1166 * process the args as they are interpreted by the operation mode
1167 */ 1167 */
1168 switch (act) { 1168 switch (act) {
1169 case LIST: 1169 case LIST:
1170 case EXTRACT: 1170 case EXTRACT:
1171 default: 1171 default:
1172 { 1172 {
1173 int sawpat = 0; 1173 int sawpat = 0;
1174 int dirisnext = 0; 1174 int dirisnext = 0;
1175 char *file, *dir = NULL; 1175 char *file, *dir = NULL;
1176 int mustfreedir = 0; 1176 int mustfreedir = 0;
1177 1177
1178 while (nincfiles || *argv != NULL) { 1178 while (nincfiles || *argv != NULL) {
1179 /* 1179 /*
1180 * If we queued up any include files, 1180 * If we queued up any include files,
1181 * pull them in now. Otherwise, check 1181 * pull them in now. Otherwise, check
1182 * for -I and -C positional flags. 1182 * for -I and -C positional flags.
1183 * Anything else must be a file to 1183 * Anything else must be a file to
1184 * extract. 1184 * extract.
1185 */ 1185 */
1186 if (nincfiles) { 1186 if (nincfiles) {
1187 file = incfiles->file; 1187 file = incfiles->file;
1188 dir = incfiles->dir; 1188 dir = incfiles->dir;
1189 mustfreedir = 0; 1189 mustfreedir = 0;
1190 incfiles++; 1190 incfiles++;
1191 nincfiles--; 1191 nincfiles--;
1192 } else if (strcmp(*argv, "-I") == 0) { 1192 } else if (strcmp(*argv, "-I") == 0) {
1193 if (*++argv == NULL) 1193 if (*++argv == NULL)
1194 break; 1194 break;
1195 file = *argv++; 1195 file = *argv++;
1196 dir = chdname; 1196 dir = chdname;
1197 mustfreedir = 0; 1197 mustfreedir = 0;
1198 } else { 1198 } else {
1199 file = NULL; 1199 file = NULL;
1200 dir = NULL; 1200 dir = NULL;
1201 mustfreedir = 0; 1201 mustfreedir = 0;
1202 } 1202 }
1203 if (file != NULL) { 1203 if (file != NULL) {
1204 FILE *fp; 1204 FILE *fp;
1205 char *str; 1205 char *str;
1206 1206
1207 if (strcmp(file, "-") == 0) 1207 if (strcmp(file, "-") == 0)
1208 fp = stdin; 1208 fp = stdin;
1209 else if ((fp = fopen(file, "r")) == NULL) { 1209 else if ((fp = fopen(file, "r")) == NULL) {
1210 tty_warn(1, "Unable to open file '%s' for read", file); 1210 tty_warn(1, "Unable to open file '%s' for read", file);
1211 tar_usage(); 1211 tar_usage();
1212 } 1212 }
1213 while ((str = get_line(fp)) != NULL) { 1213 while ((str = get_line(fp)) != NULL) {
1214 if (dirisnext) { 1214 if (dirisnext) {
1215 if (dir && mustfreedir) 1215 if (dir && mustfreedir)
1216 free(dir); 1216 free(dir);
1217 dir = str; 1217 dir = str;
1218 mustfreedir = 1; 1218 mustfreedir = 1;
1219 dirisnext = 0; 1219 dirisnext = 0;
1220 continue; 1220 continue;
1221 } 1221 }
1222 if (strcmp(str, "-C") == 0) { 1222 if (strcmp(str, "-C") == 0) {
1223 havechd++; 1223 havechd++;
1224 dirisnext = 1; 1224 dirisnext = 1;
1225 free(str); 1225 free(str);
1226 continue; 1226 continue;
1227 } 1227 }
1228 if (strncmp(str, "-C ", 3) == 0) { 1228 if (strncmp(str, "-C ", 3) == 0) {
1229 havechd++; 1229 havechd++;
1230 if (dir && mustfreedir) 1230 if (dir && mustfreedir)
1231 free(dir); 1231 free(dir);
1232 dir = strdup(str + 3); 1232 dir = strdup(str + 3);
1233 mustfreedir = 1; 1233 mustfreedir = 1;
1234 free(str); 1234 free(str);
1235 continue; 1235 continue;
1236 } 1236 }
1237 if (pat_add(str, dir, NOGLOB_MTCH) < 0) 1237 if (pat_add(str, dir, NOGLOB_MTCH) < 0)
1238 tar_usage(); 1238 tar_usage();
1239 sawpat = 1; 1239 sawpat = 1;
1240 } 1240 }
1241 /* Bomb if given -C w/out a dir. */ 1241 /* Bomb if given -C w/out a dir. */
1242 if (dirisnext) 1242 if (dirisnext)
1243 tar_usage(); 1243 tar_usage();
1244 if (dir && mustfreedir) 1244 if (dir && mustfreedir)
1245 free(dir); 1245 free(dir);
1246 if (strcmp(file, "-") != 0) 1246 if (strcmp(file, "-") != 0)
1247 fclose(fp); 1247 fclose(fp);
1248 if (get_line_error) { 1248 if (get_line_error) {
1249 tty_warn(1, "Problem with file '%s'", file); 1249 tty_warn(1, "Problem with file '%s'", file);
1250 tar_usage(); 1250 tar_usage();
1251 } 1251 }
1252 } else if (strcmp(*argv, "-C") == 0) { 1252 } else if (strcmp(*argv, "-C") == 0) {
1253 if (*++argv == NULL) 1253 if (*++argv == NULL)
1254 break; 1254 break;
1255 chdname = *argv++; 1255 chdname = *argv++;
1256 havechd++; 1256 havechd++;
1257 } else if (pat_add(*argv++, chdname, 0) < 0) 1257 } else if (pat_add(*argv++, chdname, 0) < 0)
1258 tar_usage(); 1258 tar_usage();
1259 else 1259 else
1260 sawpat = 1; 1260 sawpat = 1;
1261 } 1261 }
1262 /* 1262 /*
1263 * if patterns were added, we are doing chdir() 1263 * if patterns were added, we are doing chdir()
1264 * on a file-by-file basis, else, just one 1264 * on a file-by-file basis, else, just one
1265 * global chdir (if any) after opening input. 1265 * global chdir (if any) after opening input.
1266 */ 1266 */
1267 if (sawpat > 0) 1267 if (sawpat > 0)
1268 chdname = NULL; 1268 chdname = NULL;
1269 } 1269 }
1270 break; 1270 break;
1271 case ARCHIVE: 1271 case ARCHIVE:
1272 case APPND: 1272 case APPND:
1273 if (chdname != NULL) { /* initial chdir() */ 1273 if (chdname != NULL) { /* initial chdir() */
1274 if (ftree_add(chdname, 1) < 0) 1274 if (ftree_add(chdname, 1) < 0)
1275 tar_usage(); 1275 tar_usage();
1276 } 1276 }
1277 1277
1278 while (nincfiles || *argv != NULL) { 1278 while (nincfiles || *argv != NULL) {
1279 char *file, *dir; 1279 char *file, *dir;
1280 1280
1281 /* 1281 /*
1282 * If we queued up any include files, pull them in 1282 * If we queued up any include files, pull them in
1283 * now. Otherwise, check for -I and -C positional 1283 * now. Otherwise, check for -I and -C positional
1284 * flags. Anything else must be a file to include 1284 * flags. Anything else must be a file to include
1285 * in the archive. 1285 * in the archive.
1286 */ 1286 */
1287 if (nincfiles) { 1287 if (nincfiles) {
1288 file = incfiles->file; 1288 file = incfiles->file;
1289 dir = incfiles->dir; 1289 dir = incfiles->dir;
1290 incfiles++; 1290 incfiles++;
1291 nincfiles--; 1291 nincfiles--;
1292 } else if (strcmp(*argv, "-I") == 0) { 1292 } else if (strcmp(*argv, "-I") == 0) {
1293 if (*++argv == NULL) 1293 if (*++argv == NULL)
1294 break; 1294 break;
1295 file = *argv++; 1295 file = *argv++;
1296 dir = NULL; 1296 dir = NULL;
1297 } else { 1297 } else {
1298 file = NULL; 1298 file = NULL;
1299 dir = NULL; 1299 dir = NULL;
1300 } 1300 }
1301 if (file != NULL) { 1301 if (file != NULL) {
1302 FILE *fp; 1302 FILE *fp;
1303 char *str; 1303 char *str;
1304 int dirisnext = 0; 1304 int dirisnext = 0;
1305 1305
1306 /* Set directory if needed */ 1306 /* Set directory if needed */
1307 if (dir) { 1307 if (dir) {
1308 if (ftree_add(dir, 1) < 0) 1308 if (ftree_add(dir, 1) < 0)
1309 tar_usage(); 1309 tar_usage();
1310 } 1310 }
1311 1311
1312 if (strcmp(file, "-") == 0) 1312 if (strcmp(file, "-") == 0)
1313 fp = stdin; 1313 fp = stdin;
1314 else if ((fp = fopen(file, "r")) == NULL) { 1314 else if ((fp = fopen(file, "r")) == NULL) {
1315 tty_warn(1, "Unable to open file '%s' for read", file); 1315 tty_warn(1, "Unable to open file '%s' for read", file);
1316 tar_usage(); 1316 tar_usage();
1317 } 1317 }
1318 while ((str = get_line(fp)) != NULL) { 1318 while ((str = get_line(fp)) != NULL) {
1319 if (dirisnext) { 1319 if (dirisnext) {
1320 if (ftree_add(str, 1) < 0) 1320 if (ftree_add(str, 1) < 0)
1321 tar_usage(); 1321 tar_usage();
1322 dirisnext = 0; 1322 dirisnext = 0;
1323 continue; 1323 continue;
1324 } 1324 }
1325 if (strcmp(str, "-C") == 0) { 1325 if (strcmp(str, "-C") == 0) {
1326 dirisnext = 1; 1326 dirisnext = 1;
1327 continue; 1327 continue;
1328 } 1328 }
1329 if (strncmp(str, "-C ", 3) == 0) { 1329 if (strncmp(str, "-C ", 3) == 0) {
1330 if (ftree_add(str + 3, 1) < 0) 1330 if (ftree_add(str + 3, 1) < 0)
1331 tar_usage(); 1331 tar_usage();
1332 continue; 1332 continue;
1333 } 1333 }
1334 if (ftree_add(str, 0) < 0) 1334 if (ftree_add(str, 0) < 0)
1335 tar_usage(); 1335 tar_usage();
1336 } 1336 }
1337 /* Bomb if given -C w/out a dir. */ 1337 /* Bomb if given -C w/out a dir. */
1338 if (dirisnext) 1338 if (dirisnext)
1339 tar_usage(); 1339 tar_usage();
1340 if (strcmp(file, "-") != 0) 1340 if (strcmp(file, "-") != 0)
1341 fclose(fp); 1341 fclose(fp);
1342 if (get_line_error) { 1342 if (get_line_error) {
1343 tty_warn(1, "Problem with file '%s'", 1343 tty_warn(1, "Problem with file '%s'",
1344 file); 1344 file);
1345 tar_usage(); 1345 tar_usage();
1346 } 1346 }
1347 } else if (strcmp(*argv, "-C") == 0) { 1347 } else if (strcmp(*argv, "-C") == 0) {
1348 if (*++argv == NULL) 1348 if (*++argv == NULL)
1349 break; 1349 break;
1350 if (ftree_add(*argv++, 1) < 0) 1350 if (ftree_add(*argv++, 1) < 0)
1351 tar_usage(); 1351 tar_usage();
1352 } else if (ftree_add(*argv++, 0) < 0) 1352 } else if (ftree_add(*argv++, 0) < 0)
1353 tar_usage(); 1353 tar_usage();
1354 } 1354 }
1355 /* 1355 /*
1356 * no read errors allowed on updates/append operation! 1356 * no read errors allowed on updates/append operation!
1357 */ 1357 */
1358 maxflt = 0; 1358 maxflt = 0;
1359 break; 1359 break;
1360 } 1360 }
1361 if (!fstdin && ((arcname == (char *)NULL) || (*arcname == '\0'))) { 1361 if (!fstdin && ((arcname == (char *)NULL) || (*arcname == '\0'))) {
1362 arcname = getenv("TAPE"); 1362 arcname = getenv("TAPE");
1363 if ((arcname == NULL) || (*arcname == '\0')) 1363 if ((arcname == NULL) || (*arcname == '\0'))
1364 arcname = _PATH_DEFTAPE; 1364 arcname = _PATH_DEFTAPE;
1365 } 1365 }
1366} 1366}
1367 1367
1368int 1368int
1369mkpath(path) 1369mkpath(path)
1370 char *path; 1370 char *path;
1371{ 1371{
1372 char *slash; 1372 char *slash;
1373 int done = 0; 1373 int done = 0;
1374 1374
1375 slash = path; 1375 slash = path;
1376 1376
1377 while (!done) { 1377 while (!done) {
1378 slash += strspn(slash, "/"); 1378 slash += strspn(slash, "/");
1379 slash += strcspn(slash, "/"); 1379 slash += strcspn(slash, "/");
1380 1380
1381 done = (*slash == '\0'); 1381 done = (*slash == '\0');
1382 *slash = '\0'; 1382 *slash = '\0';
1383 1383
1384 if (domkdir(path, 0777) == -1) 1384 if (domkdir(path, 0777) == -1)
1385 goto out; 1385 goto out;
1386 1386
1387 if (!done) 1387 if (!done)
1388 *slash = '/'; 1388 *slash = '/';
1389 } 1389 }
1390 1390
1391 return 0; 1391 return 0;
1392out: 1392out:
1393 /* Can't create or or not a directory */ 1393 /* Can't create or or not a directory */
1394 syswarn(1, errno, "Cannot create directory `%s'", path); 1394 syswarn(1, errno, "Cannot create directory `%s'", path);
1395 return -1; 1395 return -1;
1396} 1396}
1397 1397
1398 1398
1399#ifndef NO_CPIO 1399#ifndef NO_CPIO
1400struct option cpio_longopts[] = { 1400struct option cpio_longopts[] = {
1401 { "reset-access-time", no_argument, 0, 'a' }, 1401 { "reset-access-time", no_argument, 0, 'a' },
1402 { "make-directories", no_argument, 0, 'd' }, 1402 { "make-directories", no_argument, 0, 'd' },
1403 { "nonmatching", no_argument, 0, 'f' }, 1403 { "nonmatching", no_argument, 0, 'f' },
1404 { "extract", no_argument, 0, 'i' }, 1404 { "extract", no_argument, 0, 'i' },
1405 { "link", no_argument, 0, 'l' }, 1405 { "link", no_argument, 0, 'l' },
1406 { "preserve-modification-time", no_argument, 0, 'm' }, 1406 { "preserve-modification-time", no_argument, 0, 'm' },
1407 { "create", no_argument, 0, 'o' }, 1407 { "create", no_argument, 0, 'o' },
1408 { "pass-through", no_argument, 0, 'p' }, 1408 { "pass-through", no_argument, 0, 'p' },
1409 { "rename", no_argument, 0, 'r' }, 1409 { "rename", no_argument, 0, 'r' },
1410 { "list", no_argument, 0, 't' }, 1410 { "list", no_argument, 0, 't' },
1411 { "unconditional", no_argument, 0, 'u' }, 1411 { "unconditional", no_argument, 0, 'u' },
1412 { "verbose", no_argument, 0, 'v' }, 1412 { "verbose", no_argument, 0, 'v' },
1413 { "append", no_argument, 0, 'A' }, 1413 { "append", no_argument, 0, 'A' },
1414 { "pattern-file", required_argument, 0, 'E' }, 1414 { "pattern-file", required_argument, 0, 'E' },
1415 { "file", required_argument, 0, 'F' }, 1415 { "file", required_argument, 0, 'F' },
1416 { "force-local", no_argument, 0, 1416 { "force-local", no_argument, 0,
1417 OPT_FORCE_LOCAL }, 1417 OPT_FORCE_LOCAL },
1418 { "format", required_argument, 0, 'H' }, 1418 { "format", required_argument, 0, 'H' },
1419 { "dereference", no_argument, 0, 'L' }, 1419 { "dereference", no_argument, 0, 'L' },
1420 { "swap-halfwords", no_argument, 0, 'S' }, 1420 { "swap-halfwords", no_argument, 0, 'S' },
1421 { "summary", no_argument, 0, 'V' }, 1421 { "summary", no_argument, 0, 'V' },
1422 { "stats", no_argument, 0, 'V' }, 1422 { "stats", no_argument, 0, 'V' },
1423 { "insecure", no_argument, 0, 1423 { "insecure", no_argument, 0,
1424 OPT_INSECURE }, 1424 OPT_INSECURE },
1425 { "sparse", no_argument, 0, 1425 { "sparse", no_argument, 0,
1426 OPT_SPARSE }, 1426 OPT_SPARSE },
1427 1427
1428#ifdef notyet 1428#ifdef notyet
1429/* Not implemented */ 1429/* Not implemented */
1430 { "null", no_argument, 0, '0' }, 1430 { "null", no_argument, 0, '0' },
1431 { "swap", no_argument, 0, 'b' }, 1431 { "swap", no_argument, 0, 'b' },
1432 { "numeric-uid-gid", no_argument, 0, 'n' }, 1432 { "numeric-uid-gid", no_argument, 0, 'n' },
1433 { "swap-bytes", no_argument, 0, 's' }, 1433 { "swap-bytes", no_argument, 0, 's' },
1434 { "message", required_argument, 0, 'M' }, 1434 { "message", required_argument, 0, 'M' },
1435 { "owner", required_argument, 0 'R' }, 1435 { "owner", required_argument, 0 'R' },
1436 { "dot", no_argument, 0, 'V' }, /* xxx */ 1436 { "dot", no_argument, 0, 'V' }, /* xxx */
1437 { "block-size", required_argument, 0, 1437 { "block-size", required_argument, 0,
1438 OPT_BLOCK_SIZE }, 1438 OPT_BLOCK_SIZE },
1439 { "no-absolute-pathnames", no_argument, 0, 1439 { "no-absolute-pathnames", no_argument, 0,
1440 OPT_NO_ABSOLUTE_PATHNAMES }, 1440 OPT_NO_ABSOLUTE_PATHNAMES },
1441 { "no-preserve-owner", no_argument, 0, 1441 { "no-preserve-owner", no_argument, 0,
1442 OPT_NO_PRESERVE_OWNER }, 1442 OPT_NO_PRESERVE_OWNER },
1443 { "only-verify-crc", no_argument, 0, 1443 { "only-verify-crc", no_argument, 0,
1444 OPT_ONLY_VERIFY_CRC }, 1444 OPT_ONLY_VERIFY_CRC },
1445 { "rsh-command", required_argument, 0, 1445 { "rsh-command", required_argument, 0,
1446 OPT_RSH_COMMAND }, 1446 OPT_RSH_COMMAND },
1447 { "version", no_argument, 0, 1447 { "version", no_argument, 0,
1448 OPT_VERSION }, 1448 OPT_VERSION },
1449#endif 1449#endif
1450 { 0, 0, 0, 0 }, 1450 { 0, 0, 0, 0 },
1451}; 1451};
1452 1452
1453static void 1453static void
1454cpio_set_action(int op) 1454cpio_set_action(int op)
1455{ 1455{
1456 if ((act == APPND && op == ARCHIVE) || (act == ARCHIVE && op == APPND)) 1456 if ((act == APPND && op == ARCHIVE) || (act == ARCHIVE && op == APPND))
1457 act = APPND; 1457 act = APPND;
1458 else if (act != ERROR && act != op) 1458 else if (act != ERROR && act != op)
1459 cpio_usage(); 1459 cpio_usage();
1460 else 1460 else
1461 act = op; 1461 act = op;
1462} 1462}
1463 1463
1464/* 1464/*
1465 * cpio_options() 1465 * cpio_options()
1466 * look at the user specified flags. set globals as required and check if 1466 * look at the user specified flags. set globals as required and check if
1467 * the user specified a legal set of flags. If not, complain and exit 1467 * the user specified a legal set of flags. If not, complain and exit
1468 */ 1468 */
1469 1469
1470static void 1470static void
1471cpio_options(int argc, char **argv) 1471cpio_options(int argc, char **argv)
1472{ 1472{
1473 FSUB tmp; 1473 FSUB tmp;
1474 u_int64_t flg = 0; 1474 u_int64_t flg = 0;
1475 u_int64_t bflg = 0; 1475 u_int64_t bflg = 0;
1476 int c; 1476 int c;
1477 size_t i; 1477 size_t i;
1478 FILE *fp; 1478 FILE *fp;
1479 char *str; 1479 char *str;
1480 1480
1481 uflag = 1; 1481 uflag = 1;
1482 kflag = 1; 1482 kflag = 1;
1483 pids = 1; 1483 pids = 1;
1484 pmode = 1; 1484 pmode = 1;
1485 pmtime = 0; 1485 pmtime = 0;
1486 arcname = NULL; 1486 arcname = NULL;
1487 dflag = 1; 1487 dflag = 1;
1488 nodirs = 1; 1488 nodirs = 1;
1489 /* 1489 /*
1490 * process option flags 1490 * process option flags
1491 */ 1491 */
1492 while ((c = getoldopt(argc, argv, 1492 while ((c = getoldopt(argc, argv,
1493 "+abcdfiklmoprstuvzABC:E:F:H:I:LM:O:R:SVZ6", 1493 "+abcdfiklmoprstuvzABC:E:F:H:I:LM:O:R:SVZ6",
1494 cpio_longopts, NULL)) != -1) { 1494 cpio_longopts, NULL)) != -1) {
1495 switch(c) { 1495 switch(c) {
1496 case 'a': 1496 case 'a':
1497 /* 1497 /*
1498 * preserve access time on filesystem nodes we read 1498 * preserve access time on filesystem nodes we read
1499 */ 1499 */
1500 tflag = 1; 1500 tflag = 1;
1501 flg |= TF; 1501 flg |= TF;
1502 break; 1502 break;
1503#ifdef notyet 1503#ifdef notyet
1504 case 'b': 1504 case 'b':
1505 /* 1505 /*
1506 * swap bytes and half-words when reading data 1506 * swap bytes and half-words when reading data
1507 */ 1507 */
1508 break; 1508 break;
1509#endif 1509#endif
1510 case 'c': 1510 case 'c':
1511 /* 1511 /*
1512 * ASCII cpio header 1512 * ASCII cpio header
1513 */ 1513 */
1514 frmt = &fsub[F_SV4CPIO]; 1514 frmt = &fsub[F_SV4CPIO];
1515 break; 1515 break;
1516 case 'd': 1516 case 'd':
1517 /* 1517 /*
1518 * create directories as needed 1518 * create directories as needed
1519 * pax does this by default .. 1519 * pax does this by default ..
1520 */ 1520 */
1521 nodirs = 0; 1521 nodirs = 0;
1522 break; 1522 break;
1523 case 'f': 1523 case 'f':
1524 /* 1524 /*
1525 * inverse match on patterns 1525 * inverse match on patterns
1526 */ 1526 */
1527 cflag = 1; 1527 cflag = 1;
1528 flg |= CF; 1528 flg |= CF;
1529 break; 1529 break;
1530 case 'i': 1530 case 'i':
1531 /* 1531 /*
1532 * read the archive 1532 * read the archive
1533 */ 1533 */
1534 cpio_set_action(EXTRACT); 1534 cpio_set_action(EXTRACT);
1535 flg |= RF; 1535 flg |= RF;
1536 break; 1536 break;
1537#ifdef notyet 1537#ifdef notyet
1538 case 'k': 1538 case 'k':
1539 break; 1539 break;
1540#endif 1540#endif
1541 case 'l': 1541 case 'l':
1542 /* 1542 /*
1543 * try to link src to dest with copy (-rw) 1543 * try to link src to dest with copy (-rw)
1544 */ 1544 */
1545 lflag = 1; 1545 lflag = 1;
1546 flg |= LF; 1546 flg |= LF;
1547 break; 1547 break;
1548 case 'm': 1548 case 'm':
1549 /* 1549 /*
1550 * preserve mtime 1550 * preserve mtime
1551 */ 1551 */
1552 flg |= PF; 1552 flg |= PF;
1553 pmtime = 1; 1553 pmtime = 1;
1554 break; 1554 break;
1555 case 'o': 1555 case 'o':
1556 /* 1556 /*
1557 * write an archive 1557 * write an archive
1558 */ 1558 */
1559 cpio_set_action(ARCHIVE); 1559 cpio_set_action(ARCHIVE);
1560 frmt = &(fsub[F_SV4CRC]); 1560 frmt = &(fsub[F_SV4CRC]);
1561 flg |= WF; 1561 flg |= WF;
1562 break; 1562 break;
1563 case 'p': 1563 case 'p':
1564 /* 1564 /*
1565 * cpio -p is like pax -rw 1565 * cpio -p is like pax -rw
1566 */ 1566 */
1567 cpio_set_action(COPY); 1567 cpio_set_action(COPY);
1568 flg |= RF | WF; 1568 flg |= RF | WF;
1569 break; 1569 break;
1570 case 'r': 1570 case 'r':
1571 /* 1571 /*
1572 * interactive file rename 1572 * interactive file rename
1573 */ 1573 */
1574 iflag = 1; 1574 iflag = 1;
1575 flg |= IF; 1575 flg |= IF;
1576 break; 1576 break;
1577#ifdef notyet 1577#ifdef notyet
1578 case 's': 1578 case 's':
1579 /* 1579 /*
1580 * swap bytes after reading data 1580 * swap bytes after reading data
1581 */ 1581 */
1582 break; 1582 break;
1583#endif 1583#endif
1584 case 't': 1584 case 't':
1585 /* 1585 /*
1586 * list contents of archive 1586 * list contents of archive
1587 */ 1587 */
1588 cpio_set_action(LIST); 1588 cpio_set_action(LIST);
1589 listf = stdout; 1589 listf = stdout;
1590 flg &= ~RF; 1590 flg &= ~RF;
1591 break; 1591 break;
1592 case 'u': 1592 case 'u':
1593 /* 1593 /*
1594 * don't ignore those older files 1594 * don't ignore those older files
1595 */ 1595 */
1596 uflag = 0; 1596 uflag = 0;
1597 kflag = 0; 1597 kflag = 0;
1598 flg |= UF; 1598 flg |= UF;
1599 break; 1599 break;
1600 case 'v': 1600 case 'v':
1601 /* 1601 /*
1602 * verbose operation mode 1602 * verbose operation mode
1603 */ 1603 */
1604 vflag = 1; 1604 vflag = 1;
1605 flg |= VF; 1605 flg |= VF;
1606 break; 1606 break;
1607 case 'z': 1607 case 'z':
1608 /* 1608 /*
1609 * use gzip. Non standard option. 1609 * use gzip. Non standard option.
1610 */ 1610 */
1611 gzip_program = GZIP_CMD; 1611 gzip_program = GZIP_CMD;
1612 break; 1612 break;
1613 case 'A': 1613 case 'A':
1614 /* 1614 /*
1615 * append to an archive 1615 * append to an archive
1616 */ 1616 */
1617 cpio_set_action(APPND); 1617 cpio_set_action(APPND);
1618 flg |= AF; 1618 flg |= AF;
1619 break; 1619 break;
1620 case 'B': 1620 case 'B':
1621 /* 1621 /*
1622 * set blocksize to 5120 1622 * set blocksize to 5120
1623 */ 1623 */
1624 blksz = 5120; 1624 blksz = 5120;
1625 break; 1625 break;
1626 case 'C': 1626 case 'C':
1627 /* 1627 /*
1628 * specify blocksize 1628 * specify blocksize
1629 */ 1629 */
1630 if ((blksz = (int)str_offt(optarg)) <= 0) { 1630 if ((blksz = (int)str_offt(optarg)) <= 0) {
1631 tty_warn(1, "Invalid block size %s", optarg); 1631 tty_warn(1, "Invalid block size %s", optarg);
1632 cpio_usage(); 1632 cpio_usage();
1633 } 1633 }
1634 break; 1634 break;
1635 case 'E': 1635 case 'E':
1636 /* 1636 /*
1637 * file with patterns to extract or list 1637 * file with patterns to extract or list
1638 */ 1638 */
1639 if ((fp = fopen(optarg, "r")) == NULL) { 1639 if ((fp = fopen(optarg, "r")) == NULL) {
1640 tty_warn(1, "Unable to open file '%s' for read", 1640 tty_warn(1, "Unable to open file '%s' for read",
1641 optarg); 1641 optarg);
1642 cpio_usage(); 1642 cpio_usage();
1643 } 1643 }
1644 while ((str = get_line(fp)) != NULL) { 1644 while ((str = get_line(fp)) != NULL) {
1645 pat_add(str, NULL, 0); 1645 pat_add(str, NULL, 0);
1646 } 1646 }
1647 fclose(fp); 1647 fclose(fp);
1648 if (get_line_error) { 1648 if (get_line_error) {
1649 tty_warn(1, "Problem with file '%s'", optarg); 1649 tty_warn(1, "Problem with file '%s'", optarg);
1650 cpio_usage(); 1650 cpio_usage();
1651 } 1651 }
1652 break; 1652 break;
1653 case 'H': 1653 case 'H':
1654 /* 1654 /*
1655 * specify an archive format on write 1655 * specify an archive format on write
1656 */ 1656 */
1657 tmp.name = optarg; 1657 tmp.name = optarg;
1658 frmt = (FSUB *)bsearch((void *)&tmp, (void *)fsub, 1658 frmt = (FSUB *)bsearch((void *)&tmp, (void *)fsub,
1659 sizeof(fsub)/sizeof(FSUB), sizeof(FSUB), c_frmt); 1659 sizeof(fsub)/sizeof(FSUB), sizeof(FSUB), c_frmt);
1660 if (frmt != NULL) { 1660 if (frmt != NULL) {
1661 flg |= XF; 1661 flg |= XF;
1662 break; 1662 break;
1663 } 1663 }
1664 tty_warn(1, "Unknown -H format: %s", optarg); 1664 tty_warn(1, "Unknown -H format: %s", optarg);
1665 (void)fputs("cpio: Known -H formats are:", stderr); 1665 (void)fputs("cpio: Known -H formats are:", stderr);
1666 for (i = 0; i < (sizeof(fsub)/sizeof(FSUB)); ++i) 1666 for (i = 0; i < (sizeof(fsub)/sizeof(FSUB)); ++i)
1667 (void)fprintf(stderr, " %s", fsub[i].name); 1667 (void)fprintf(stderr, " %s", fsub[i].name);
1668 (void)fputs("\n\n", stderr); 1668 (void)fputs("\n\n", stderr);
1669 cpio_usage(); 1669 cpio_usage();
1670 break; 1670 break;
1671 case 'I': 1671 case 'I':
1672 case 'O': 1672 case 'O':
1673 /* 1673 /*
1674 * filename where the archive is stored 1674 * filename where the archive is stored
1675 */ 1675 */
1676 if ((optarg[0] == '-') && (optarg[1]== '\0')) { 1676 if ((optarg[0] == '-') && (optarg[1]== '\0')) {
1677 /* 1677 /*
1678 * treat a - as stdin 1678 * treat a - as stdin
1679 */ 1679 */
1680 arcname = NULL; 1680 arcname = NULL;
1681 break; 1681 break;
1682 } 1682 }
1683 arcname = optarg; 1683 arcname = optarg;
1684 break; 1684 break;
1685 case 'L': 1685 case 'L':
1686 /* 1686 /*
1687 * follow symlinks 1687 * follow symlinks
1688 */ 1688 */
1689 Lflag = 1; 1689 Lflag = 1;
1690 flg |= CLF; 1690 flg |= CLF;
1691 break; 1691 break;
1692#ifdef notyet 1692#ifdef notyet
1693 case 'M': 1693 case 'M':
1694 arg = optarg; 1694 arg = optarg;