| @@ -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 |
43 | static char sccsid[] = "@(#)options.c 8.2 (Berkeley) 4/18/94"; | | 43 | static 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 | |
79 | static int nopids; /* tar mode: suppress "pids" for -p option */ | | 79 | static int nopids; /* tar mode: suppress "pids" for -p option */ |
80 | static char flgch[] = FLGCH; /* list of all possible flags (pax) */ | | 80 | static char flgch[] = FLGCH; /* list of all possible flags (pax) */ |
81 | static OPLIST *ophead = NULL; /* head for format specific options -x */ | | 81 | static OPLIST *ophead = NULL; /* head for format specific options -x */ |
82 | static OPLIST *optail = NULL; /* option tail */ | | 82 | static OPLIST *optail = NULL; /* option tail */ |
83 | | | 83 | |
84 | static int no_op(void); | | 84 | static int no_op(void); |
85 | static void printflg(unsigned int); | | 85 | static void printflg(unsigned int); |
86 | static int c_frmt(const void *, const void *); | | 86 | static int c_frmt(const void *, const void *); |
87 | static off_t str_offt(char *); | | 87 | static off_t str_offt(char *); |
88 | static char *get_line(FILE *fp); | | 88 | static char *get_line(FILE *fp); |
89 | static void pax_options(int, char **); | | 89 | static void pax_options(int, char **); |
90 | static void pax_usage(void); | | 90 | static void pax_usage(void); |
91 | static void tar_options(int, char **); | | 91 | static void tar_options(int, char **); |
92 | static void tar_usage(void); | | 92 | static void tar_usage(void); |
93 | #ifndef NO_CPIO | | 93 | #ifndef NO_CPIO |
94 | static void cpio_options(int, char **); | | 94 | static void cpio_options(int, char **); |
95 | static void cpio_usage(void); | | 95 | static 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 |
101 | static int get_line_error; | | 101 | static 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 | |
140 | FSUB fsub[] = { | | 140 | FSUB 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 | */ |
190 | int ford[] = {F_USTAR, F_TAR, | | 190 | int 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 | */ |
199 | int sep = '\n'; | | 199 | int sep = '\n'; |
200 | | | 200 | |
201 | /* | | 201 | /* |
202 | * Do we have -C anywhere? | | 202 | * Do we have -C anywhere? |
203 | */ | | 203 | */ |
204 | int havechd = 0; | | 204 | int 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 | |
212 | void | | 212 | void |
213 | options(int argc, char **argv) | | 213 | options(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 | |
238 | struct option pax_longopts[] = { | | 238 | struct 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 | |
253 | static void | | 253 | static void |
254 | pax_options(int argc, char **argv) | | 254 | pax_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 | |
728 | struct option tar_longopts[] = { | | 728 | struct 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 | |
827 | static void | | 827 | static void |
828 | tar_set_action(int op) | | 828 | tar_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 | |
835 | static void | | 835 | static void |
836 | tar_options(int argc, char **argv) | | 836 | tar_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 | |
1368 | int | | 1368 | int |
1369 | mkpath(path) | | 1369 | mkpath(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; |
1392 | out: | | 1392 | out: |
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 |
1400 | struct option cpio_longopts[] = { | | 1400 | struct 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 | |
1453 | static void | | 1453 | static void |
1454 | cpio_set_action(int op) | | 1454 | cpio_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 | |
1470 | static void | | 1470 | static void |
1471 | cpio_options(int argc, char **argv) | | 1471 | cpio_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; |