]> Dogcows Code - chaz/tar/blob - src/tar.c
Updated
[chaz/tar] / src / tar.c
1 /* A tar (tape archiver) program.
2
3 Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1999, 2000,
4 2001, 2003, 2004, 2005 Free Software Foundation, Inc.
5
6 Written by John Gilmore, starting 1985-08-25.
7
8 This program is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by the
10 Free Software Foundation; either version 2, or (at your option) any later
11 version.
12
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
16 Public License for more details.
17
18 You should have received a copy of the GNU General Public License along
19 with this program; if not, write to the Free Software Foundation, Inc.,
20 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
21
22 #include <system.h>
23
24 #include <fnmatch.h>
25 #include <argp.h>
26
27 #include <signal.h>
28 #if ! defined SIGCHLD && defined SIGCLD
29 # define SIGCHLD SIGCLD
30 #endif
31
32 /* The following causes "common.h" to produce definitions of all the global
33 variables, rather than just "extern" declarations of them. GNU tar does
34 depend on the system loader to preset all GLOBAL variables to neutral (or
35 zero) values; explicit initialization is usually not done. */
36 #define GLOBAL
37 #include "common.h"
38
39 #include <getdate.h>
40 #include <localedir.h>
41 #include <rmt.h>
42 #include <prepargs.h>
43 #include <quotearg.h>
44 #include <xstrtol.h>
45
46 /* Local declarations. */
47
48 #ifndef DEFAULT_ARCHIVE_FORMAT
49 # define DEFAULT_ARCHIVE_FORMAT GNU_FORMAT
50 #endif
51
52 #ifndef DEFAULT_ARCHIVE
53 # define DEFAULT_ARCHIVE "tar.out"
54 #endif
55
56 #ifndef DEFAULT_BLOCKING
57 # define DEFAULT_BLOCKING 20
58 #endif
59
60 \f
61 /* Miscellaneous. */
62
63 /* Name of option using stdin. */
64 static const char *stdin_used_by;
65
66 /* Doesn't return if stdin already requested. */
67 void
68 request_stdin (const char *option)
69 {
70 if (stdin_used_by)
71 USAGE_ERROR ((0, 0, _("Options `-%s' and `-%s' both want standard input"),
72 stdin_used_by, option));
73
74 stdin_used_by = option;
75 }
76
77 /* Returns true if and only if the user typed 'y' or 'Y'. */
78 int
79 confirm (const char *message_action, const char *message_name)
80 {
81 static FILE *confirm_file;
82 static int confirm_file_EOF;
83
84 if (!confirm_file)
85 {
86 if (archive == 0 || stdin_used_by)
87 {
88 confirm_file = fopen (TTY_NAME, "r");
89 if (! confirm_file)
90 open_fatal (TTY_NAME);
91 }
92 else
93 {
94 request_stdin ("-w");
95 confirm_file = stdin;
96 }
97 }
98
99 fprintf (stdlis, "%s %s?", message_action, quote (message_name));
100 fflush (stdlis);
101
102 {
103 int reply = confirm_file_EOF ? EOF : getc (confirm_file);
104 int character;
105
106 for (character = reply;
107 character != '\n';
108 character = getc (confirm_file))
109 if (character == EOF)
110 {
111 confirm_file_EOF = 1;
112 fputc ('\n', stdlis);
113 fflush (stdlis);
114 break;
115 }
116 return reply == 'y' || reply == 'Y';
117 }
118 }
119
120 static struct fmttab {
121 char const *name;
122 enum archive_format fmt;
123 } const fmttab[] = {
124 { "v7", V7_FORMAT },
125 { "oldgnu", OLDGNU_FORMAT },
126 { "ustar", USTAR_FORMAT },
127 { "posix", POSIX_FORMAT },
128 #if 0 /* not fully supported yet */
129 { "star", STAR_FORMAT },
130 #endif
131 { "gnu", GNU_FORMAT },
132 { "pax", POSIX_FORMAT }, /* An alias for posix */
133 { NULL, 0 }
134 };
135
136 static void
137 set_archive_format (char const *name)
138 {
139 struct fmttab const *p;
140
141 for (p = fmttab; strcmp (p->name, name) != 0; )
142 if (! (++p)->name)
143 USAGE_ERROR ((0, 0, _("%s: Invalid archive format"),
144 quotearg_colon (name)));
145
146 archive_format = p->fmt;
147 }
148
149 static const char *
150 archive_format_string (enum archive_format fmt)
151 {
152 struct fmttab const *p;
153
154 for (p = fmttab; p->name; p++)
155 if (p->fmt == fmt)
156 return p->name;
157 return "unknown?";
158 }
159
160 #define FORMAT_MASK(n) (1<<(n))
161
162 static void
163 assert_format(unsigned fmt_mask)
164 {
165 if ((FORMAT_MASK(archive_format) & fmt_mask) == 0)
166 USAGE_ERROR ((0, 0,
167 _("GNU features wanted on incompatible archive format")));
168 }
169
170
171 \f
172 /* Options. */
173
174 /* For long options that unconditionally set a single flag, we have getopt
175 do it. For the others, we share the code for the equivalent short
176 named option, the name of which is stored in the otherwise-unused `val'
177 field of the `struct option'; for long options that have no equivalent
178 short option, we use non-characters as pseudo short options,
179 starting at CHAR_MAX + 1 and going upwards. */
180
181 enum
182 {
183 ANCHORED_OPTION = CHAR_MAX + 1,
184 ATIME_PRESERVE_OPTION,
185 BACKUP_OPTION,
186 CHECKPOINT_OPTION,
187 CHECK_LINKS_OPTION,
188 DELETE_OPTION,
189 EXCLUDE_OPTION,
190 EXCLUDE_CACHES_OPTION,
191 FORCE_LOCAL_OPTION,
192 GROUP_OPTION,
193 HANG_OPTION,
194 IGNORE_CASE_OPTION,
195 IGNORE_COMMAND_ERROR_OPTION,
196 IGNORE_FAILED_READ_OPTION,
197 INDEX_FILE_OPTION,
198 KEEP_NEWER_FILES_OPTION,
199 LICENSE_OPTION,
200 MODE_OPTION,
201 NEWER_MTIME_OPTION,
202 NO_ANCHORED_OPTION,
203 NO_IGNORE_CASE_OPTION,
204 NO_IGNORE_COMMAND_ERROR_OPTION,
205 NO_OVERWRITE_DIR_OPTION,
206 NO_RECURSION_OPTION,
207 NO_SAME_OWNER_OPTION,
208 NO_SAME_PERMISSIONS_OPTION,
209 NO_UNQUOTE_OPTION,
210 NO_WILDCARDS_OPTION,
211 NO_WILDCARDS_MATCH_SLASH_OPTION,
212 NULL_OPTION,
213 NUMERIC_OWNER_OPTION,
214 OCCURRENCE_OPTION,
215 OLD_ARCHIVE_OPTION,
216 ONE_FILE_SYSTEM_OPTION,
217 OVERWRITE_OPTION,
218 OWNER_OPTION,
219 PAX_OPTION,
220 POSIX_OPTION,
221 PRESERVE_OPTION,
222 RECORD_SIZE_OPTION,
223 RECURSION_OPTION,
224 RECURSIVE_UNLINK_OPTION,
225 REMOVE_FILES_OPTION,
226 RMT_COMMAND_OPTION,
227 RSH_COMMAND_OPTION,
228 SAME_OWNER_OPTION,
229 SHOW_DEFAULTS_OPTION,
230 SHOW_OMITTED_DIRS_OPTION,
231 STRIP_COMPONENTS_OPTION,
232 SUFFIX_OPTION,
233 TEST_LABEL_OPTION,
234 TO_COMMAND_OPTION,
235 TOTALS_OPTION,
236 UNQUOTE_OPTION,
237 USAGE_OPTION,
238 USE_COMPRESS_PROGRAM_OPTION,
239 UTC_OPTION,
240 VERSION_OPTION,
241 VOLNO_FILE_OPTION,
242 WILDCARDS_OPTION,
243 WILDCARDS_MATCH_SLASH_OPTION
244 };
245
246 const char *argp_program_version = "tar (" PACKAGE_NAME ") " VERSION;
247 const char *argp_program_bug_address = "<" PACKAGE_BUGREPORT ">";
248 static char doc[] = N_("GNU `tar' saves many files together into a single tape or disk archive, and can restore individual files from the archive.\n\
249 \n\
250 Examples:\n\
251 tar -cf archive.tar foo bar # Create archive.tar from files foo and bar.\n\
252 tar -tvf archive.tar # List all files in archive.tar verbosely.\n\
253 tar -xf archive.tar # Extract all files from archive.tar.\n\
254 \vThe backup suffix is `~', unless set with --suffix or SIMPLE_BACKUP_SUFFIX.\n\
255 The version control may be set with --backup or VERSION_CONTROL, values are:\n\n\
256 none, off never make backups\n\
257 t, numbered make numbered backups\n\
258 nil, existing numbered if numbered backups exist, simple otherwise\n\
259 never, simple always make simple backups\n");
260
261
262 /* NOTE:
263
264 Available option letters are DEIJQY and aeqy. Consider the following
265 assignments:
266
267 [For Solaris tar compatibility]
268 e exit immediately with a nonzero exit status if unexpected errors occur
269 E use extended headers (--format=posix)
270 [q alias for --occurrence=1 =/= this would better be used for quiet?]
271 [I same as T =/= will harm star compatibility]
272
273 y per-file gzip compression
274 Y per-block gzip compression */
275
276 static struct argp_option options[] = {
277 {NULL, 0, NULL, 0,
278 N_("Main operation mode:"), 0},
279
280 {"list", 't', 0, 0,
281 N_("list the contents of an archive"), 10 },
282 {"extract", 'x', 0, 0,
283 N_("extract files from an archive"), 10 },
284 {"get", 0, 0, OPTION_ALIAS, NULL, 0 },
285 {"create", 'c', 0, 0,
286 N_("create a new archive"), 10 },
287 {"diff", 'd', 0, 0,
288 N_("find differences between archive and file system"), 10 },
289 {"compare", 0, 0, OPTION_ALIAS, NULL, 10},
290 {"append", 'r', 0, 0,
291 N_("append files to the end of an archive"), 10 },
292 {"update", 'u', 0, 0,
293 N_("only append files newer than copy in archive"), 10 },
294 {"catenate", 'A', 0, 0,
295 N_("append tar files to an archive"), 10 },
296 {"concatenate", 0, 0, OPTION_ALIAS, NULL, 10},
297 {"delete", DELETE_OPTION, 0, 0,
298 N_("delete from the archive (not on mag tapes!)"), 10 },
299
300 {NULL, 0, NULL, 0,
301 N_("Operation modifiers:"), 20},
302
303 {"sparse", 'S', 0, 0,
304 N_("handle sparse files efficiently"), 21 },
305 {"incremental", 'G', 0, 0,
306 N_("handle old GNU-format incremental backup"), 21 },
307 {"listed-incremental", 'g', N_("FILE"), 0,
308 N_("handle new GNU-format incremental backup"), 21 },
309 {"ignore-failed-read", IGNORE_FAILED_READ_OPTION, 0, 0,
310 N_("do not exit with nonzero on unreadable files"), 21 },
311 {"occurrence", OCCURRENCE_OPTION, N_("NUMBER"), OPTION_ARG_OPTIONAL,
312 N_("process only the NUMBERth occurrence of each file in the archive. This option is valid only in conjunction with one of the subcommands --delete, --diff, --extract or --list and when a list of files is given either on the command line or via -T option. NUMBER defaults to 1."), 21 },
313 {"seek", 'n', NULL, 0,
314 N_("archive is seekable"), 21 },
315 {"test-label", TEST_LABEL_OPTION, NULL, 0,
316 N_("List volume label and exit"), 21 },
317
318
319 {NULL, 0, NULL, 0,
320 N_("Overwrite control:"), 30},
321
322 {"verify", 'W', 0, 0,
323 N_("attempt to verify the archive after writing it"), 31 },
324 {"remove-files", REMOVE_FILES_OPTION, 0, 0,
325 N_("remove files after adding them to the archive"), 31 },
326 {"keep-old-files", 'k', 0, 0,
327 N_("don't replace existing files when extracting"), 31 },
328 {"keep-newer-files", KEEP_NEWER_FILES_OPTION, 0, 0,
329 N_("don't replace existing files that are newer than their archive copies"), 31 },
330 {"overwrite", OVERWRITE_OPTION, 0, 0,
331 N_("overwrite existing files when extracting"), 31 },
332 {"unlink-first", 'U', 0, 0,
333 N_("remove each file prior to extracting over it"), 31 },
334 {"recursive-unlink", RECURSIVE_UNLINK_OPTION, 0, 0,
335 N_("empty hierarchies prior to extracting directory"), 31 },
336 {"no-overwrite-dir", NO_OVERWRITE_DIR_OPTION, 0, 0,
337 N_("preserve metadata of existing directories"), 31 },
338
339 {NULL, 0, NULL, 0,
340 N_("Select output stream:"), 40},
341
342 {"to-stdout", 'O', 0, 0,
343 N_("extract files to standard output"), 41 },
344 {"to-command", TO_COMMAND_OPTION, N_("COMMAND"), 0,
345 N_("pipe extracted files to another program"), 41 },
346 {"ignore-command-error", IGNORE_COMMAND_ERROR_OPTION, 0, 0,
347 N_("ignore exit codes of children"), 41 },
348 {"no-ignore-command-error", NO_IGNORE_COMMAND_ERROR_OPTION, 0, 0,
349 N_("treat non-zero exit codes of children as error"), 41 },
350
351 {NULL, 0, NULL, 0,
352 N_("Handling of file attributes:"), 50 },
353
354 {"owner", OWNER_OPTION, N_("NAME"), 0,
355 N_("force NAME as owner for added files"), 51 },
356 {"group", GROUP_OPTION, N_("NAME"), 0,
357 N_("force NAME as group for added files"), 51 },
358 {"mode", MODE_OPTION, N_("CHANGES"), 0,
359 N_("force (symbolic) mode CHANGES for added files"), 51 },
360 {"atime-preserve", ATIME_PRESERVE_OPTION, 0, 0,
361 N_("don't change access times on dumped files"), 51 },
362 {"touch", 'm', 0, 0,
363 N_("don't extract file modified time"), 51 },
364 {"same-owner", SAME_OWNER_OPTION, 0, 0,
365 N_("try extracting files with the same ownership"), 51 },
366 {"no-same-owner", NO_SAME_OWNER_OPTION, 0, 0,
367 N_("extract files as yourself"), 51 },
368 {"numeric-owner", NUMERIC_OWNER_OPTION, 0, 0,
369 N_("always use numbers for user/group names"), 51 },
370 {"preserve-permissions", 'p', 0, 0,
371 N_("extract information about file permissions (default for superuser)"),
372 51 },
373 {"same-permissions", 0, 0, OPTION_ALIAS, NULL, 51 },
374 {"no-same-permissions", NO_SAME_PERMISSIONS_OPTION, 0, 0,
375 N_("apply the user's umask when extracting permissions from the archive (default for ordinary users)"), 51 },
376 {"preserve-order", 's', 0, 0,
377 N_("sort names to extract to match archive"), 51 },
378 {"same-order", 0, 0, OPTION_ALIAS, NULL, 51 },
379 {"preserve", PRESERVE_OPTION, 0, 0,
380 N_("same as both -p and -s"), 51 },
381
382 {NULL, 0, NULL, 0,
383 N_("Device selection and switching:"), 60 },
384
385 {"file", 'f', N_("ARCHIVE"), 0,
386 N_("use archive file or device ARCHIVE"), 61 },
387 {"force-local", FORCE_LOCAL_OPTION, 0, 0,
388 N_("archive file is local even if it has a colon"), 61 },
389 {"rmt-command", RMT_COMMAND_OPTION, N_("COMMAND"), 0,
390 N_("use given rmt COMMAND instead of rmt"), 61 },
391 {"rsh-command", RSH_COMMAND_OPTION, N_("COMMAND"), 0,
392 N_("use remote COMMAND instead of rsh"), 61 },
393 #ifdef DEVICE_PREFIX
394 {"-[0-7][lmh]", 0, NULL, OPTION_DOC, /* It is OK, since `name' will never be
395 translated */
396 N_("specify drive and density"), 61 },
397 #endif
398 {NULL, '0', NULL, OPTION_HIDDEN, NULL, 61 },
399 {NULL, '1', NULL, OPTION_HIDDEN, NULL, 61 },
400 {NULL, '2', NULL, OPTION_HIDDEN, NULL, 61 },
401 {NULL, '3', NULL, OPTION_HIDDEN, NULL, 61 },
402 {NULL, '4', NULL, OPTION_HIDDEN, NULL, 61 },
403 {NULL, '5', NULL, OPTION_HIDDEN, NULL, 61 },
404 {NULL, '6', NULL, OPTION_HIDDEN, NULL, 61 },
405 {NULL, '7', NULL, OPTION_HIDDEN, NULL, 61 },
406 {NULL, '8', NULL, OPTION_HIDDEN, NULL, 61 },
407 {NULL, '9', NULL, OPTION_HIDDEN, NULL, 61 },
408
409 {"multi-volume", 'M', 0, 0,
410 N_("create/list/extract multi-volume archive"), 61 },
411 {"tape-length", 'L', N_("NUMBER"), 0,
412 N_("change tape after writing NUMBER x 1024 bytes"), 61 },
413 {"info-script", 'F', N_("NAME"), 0,
414 N_("run script at end of each tape (implies -M)"), 61 },
415 {"new-volume-script", 0, 0, OPTION_ALIAS, NULL, 61 },
416 {"volno-file", VOLNO_FILE_OPTION, N_("FILE"), 0,
417 N_("use/update the volume number in FILE"), 61 },
418
419 {NULL, 0, NULL, 0,
420 N_("Device blocking:"), 70 },
421
422 {"blocking-factor", 'b', N_("BLOCKS"), 0,
423 N_("BLOCKS x 512 bytes per record"), 71 },
424 {"record-size", RECORD_SIZE_OPTION, N_("NUMBER"), 0,
425 N_("NUMBER of bytes per record, multiple of 512"), 71 },
426 {"ignore-zeros", 'i', 0, 0,
427 N_("ignore zeroed blocks in archive (means EOF)"), 71 },
428 {"read-full-records", 'B', 0, 0,
429 N_("reblock as we read (for 4.2BSD pipes)"), 71 },
430
431 {NULL, 0, NULL, 0,
432 N_("Archive format selection:"), 80 },
433
434 {"format", 'H', N_("FORMAT"), 0,
435 N_("create archive of the given format."), 81 },
436
437 {NULL, 0, NULL, 0, N_("FORMAT is one of the following:"), 82 },
438 {" v7", 0, NULL, OPTION_DOC|OPTION_NO_TRANS, N_("old V7 tar format"), 83},
439 {" oldgnu", 0, NULL, OPTION_DOC|OPTION_NO_TRANS,
440 N_("GNU format as per tar <= 1.12"), 83},
441 {" gnu", 0, NULL, OPTION_DOC|OPTION_NO_TRANS,
442 N_("GNU tar 1.13.x format"), 83},
443 {" ustar", 0, NULL, OPTION_DOC|OPTION_NO_TRANS,
444 N_("POSIX 1003.1-1988 (ustar) format"), 83 },
445 {" pax", 0, NULL, OPTION_DOC|OPTION_NO_TRANS,
446 N_("POSIX 1003.1-2001 (pax) format"), 83 },
447 {" posix", 0, NULL, OPTION_DOC|OPTION_NO_TRANS, N_("same as pax"), 83 },
448
449 {"old-archive", OLD_ARCHIVE_OPTION, 0, 0, /* FIXME */
450 N_("same as --format=v7"), 88 },
451 {"portability", 0, 0, OPTION_ALIAS, NULL, 88 },
452 {"posix", POSIX_OPTION, 0, 0,
453 N_("same as --format=posix"), 88 },
454 {"pax-option", PAX_OPTION, N_("keyword[[:]=value][,keyword[[:]=value], ...]"), 0,
455 N_("control pax keywords"), 88 },
456 {"label", 'V', N_("TEXT"), 0,
457 N_("create archive with volume name TEXT. At list/extract time, use TEXT as a globbing pattern for volume name"), 88 },
458 {"bzip2", 'j', 0, 0,
459 N_("filter the archive through bzip2"), 88 },
460 {"gzip", 'z', 0, 0,
461 N_("filter the archive through gzip"), 88 },
462 {"gunzip", 0, 0, OPTION_ALIAS, NULL, 88 },
463 {"ungzip", 0, 0, OPTION_ALIAS, NULL, 88 },
464 {"compress", 'Z', 0, 0,
465 N_("filter the archive through compress"), 88 },
466 {"uncompress", 0, 0, OPTION_ALIAS, NULL, 88 },
467 {"use-compress-program", USE_COMPRESS_PROGRAM_OPTION, N_("PROG"), 0,
468 N_("filter through PROG (must accept -d)"), 88 },
469
470 {NULL, 0, NULL, 0,
471 N_("Local file selection:"), 90 },
472
473 {"add-file", ARGP_KEY_ARG, N_("FILE"), 0,
474 N_("add given FILE to the archive (useful if its name starts with a dash)"), 91},
475 {"directory", 'C', N_("DIR"), 0,
476 N_("change to directory DIR"), 91 },
477 {"files-from", 'T', N_("FILE"), 0,
478 N_("get names to extract or create from FILE"), 91 },
479 {"null", NULL_OPTION, 0, 0,
480 N_("-T reads null-terminated names, disable -C"), 91 },
481 {"unquote", UNQUOTE_OPTION, 0, 0,
482 N_("unquote filenames read with -T (default)"), 91 },
483 {"no-unquote", NO_UNQUOTE_OPTION, 0, 0,
484 N_("do not unquote filenames read with -T"), 91 },
485 {"exclude", EXCLUDE_OPTION, N_("PATTERN"), 0,
486 N_("exclude files, given as a PATTERN"), 91 },
487 {"exclude-from", 'X', N_("FILE"), 0,
488 N_("exclude patterns listed in FILE"), 91 },
489 {"exclude-caches", EXCLUDE_CACHES_OPTION, 0, 0,
490 N_("exclude directories containing a cache tag"), 91 },
491 {"ignore-case", IGNORE_CASE_OPTION, 0, 0,
492 N_("exclusion ignores case"), 91 },
493 {"anchored", ANCHORED_OPTION, 0, 0,
494 N_("exclude patterns match file name start"), 91 },
495 {"no-anchored", NO_ANCHORED_OPTION, 0, 0,
496 N_("exclude patterns match after any `/' (default)"), 91 },
497 {"no-ignore-case", NO_IGNORE_CASE_OPTION, 0, 0,
498 N_("exclusion is case sensitive (default)"), 91 },
499 {"no-wildcards", NO_WILDCARDS_OPTION, 0, 0,
500 N_("exclude patterns are plain strings"), 91 },
501 {"no-wildcards-match-slash", NO_WILDCARDS_MATCH_SLASH_OPTION, 0, 0,
502 N_("exclude pattern wildcards do not match `/'"), 91 },
503 {"no-recursion", NO_RECURSION_OPTION, 0, 0,
504 N_("avoid descending automatically in directories"), 91 },
505 {"one-file-system", ONE_FILE_SYSTEM_OPTION, 0, 0,
506 N_("stay in local file system when creating archive"), 91 },
507 {NULL, 'l', 0, OPTION_HIDDEN, "", 91},
508 {"recursion", RECURSION_OPTION, 0, 0,
509 N_("recurse into directories (default)"), 91 },
510 {"absolute-names", 'P', 0, 0,
511 N_("don't strip leading `/'s from file names"), 91 },
512 {"dereference", 'h', 0, 0,
513 N_("follow symlinks; archive and dump the files they point to"), 91 },
514 {"starting-file", 'K', N_("MEMBER-NAME"), 0,
515 N_("begin at member MEMBER-NAME in the archive"), 91 },
516 {"strip-components", STRIP_COMPONENTS_OPTION, N_("NUMBER"), 0,
517 N_("strip NUMBER leading components from file names"), 91 },
518 {"newer", 'N', N_("DATE-OR-FILE"), 0,
519 N_("only store files newer than DATE-OR-FILE"), 91 },
520 {"newer-mtime", NEWER_MTIME_OPTION, N_("DATE"), 0,
521 N_("compare date and time when data changed only"), 91 },
522 {"after-date", 'N', N_("DATE"), 0,
523 N_("same as -N"), 91 },
524 {"backup", BACKUP_OPTION, N_("CONTROL"), OPTION_ARG_OPTIONAL,
525 N_("backup before removal, choose version CONTROL"), 91 },
526 {"suffix", SUFFIX_OPTION, N_("STRING"), 0,
527 N_("backup before removal, override usual suffix ('~' unless overridden by environment variable SIMPLE_BACKUP_SUFFIX)"), 91 },
528 {"wildcards", WILDCARDS_OPTION, 0, 0,
529 N_("exclude patterns use wildcards (default)"), 91 },
530 {"wildcards-match-slash", WILDCARDS_MATCH_SLASH_OPTION, 0, 0,
531 N_("exclude pattern wildcards match `/' (default)"), 91 },
532
533 {NULL, 0, NULL, 0,
534 N_("Informative output:"), 100 },
535
536 {"verbose", 'v', 0, 0,
537 N_("verbosely list files processed"), 101 },
538 {"checkpoint", CHECKPOINT_OPTION, 0, 0,
539 N_("display progress messages every 10th record"), 101 },
540 {"check-links", CHECK_LINKS_OPTION, 0, 0,
541 N_("print a message if not all links are dumped"), 102 },
542 {"totals", TOTALS_OPTION, 0, 0,
543 N_("print total bytes written while creating archive"), 102 },
544 {"utc", UTC_OPTION, 0, 0,
545 N_("print file modification dates in UTC"), 102 },
546 {"index-file", INDEX_FILE_OPTION, N_("FILE"), 0,
547 N_("send verbose output to FILE"), 102 },
548 {"block-number", 'R', 0, 0,
549 N_("show block number within archive with each message"), 102 },
550 {"interactive", 'w', 0, 0,
551 N_("ask for confirmation for every action"), 102 },
552 {"confirmation", 0, 0, OPTION_ALIAS, NULL, 102 },
553 {"show-defaults", SHOW_DEFAULTS_OPTION, 0, 0,
554 N_("Show tar defaults"), 102 },
555 {"show-omitted-dirs", SHOW_OMITTED_DIRS_OPTION, 0, 0,
556 N_("When listing or extracting, list each directory that does not match search criteria"), 102 },
557
558 {NULL, 0, NULL, 0,
559 N_("Compatibility options:"), 110 },
560
561 {NULL, 'o', 0, 0,
562 N_("when creating, same as --old-archive. When extracting, same as --no-same-owner"), 111 },
563
564 {NULL, 0, NULL, 0,
565 N_("Other options:"), 120 },
566
567 {"help", '?', 0, 0, N_("Give this help list"), -1},
568 {"usage", USAGE_OPTION, 0, 0, N_("Give a short usage message"), -1},
569 {"license", LICENSE_OPTION, 0, 0, N_("Print license and exit"), -1},
570 {"version", VERSION_OPTION, 0, 0, N_("Print program version"), -1},
571 /* FIXME -V (--label) conflicts with the default short option for
572 --version */
573 {"HANG", HANG_OPTION, "SECS", OPTION_ARG_OPTIONAL | OPTION_HIDDEN,
574 N_("Hang for SECS seconds (default 3600)"), 0},
575 {0, 0, 0, 0, 0, 0}
576 };
577
578 struct tar_args {
579 char const *textual_date_option;
580 int exclude_options;
581 bool o_option;
582 int pax_option;
583 char const *backup_suffix_string;
584 char const *version_control_string;
585 int input_files;
586 };
587
588 static void
589 show_default_settings (FILE *stream)
590 {
591 fprintf (stream,
592 "--format=%s -f%s -b%d --rmt-command=%s",
593 archive_format_string (DEFAULT_ARCHIVE_FORMAT),
594 DEFAULT_ARCHIVE, DEFAULT_BLOCKING,
595 DEFAULT_RMT_COMMAND);
596 #ifdef REMOTE_SHELL
597 fprintf (stream, " --rsh-command=%s", REMOTE_SHELL);
598 #endif
599 fprintf (stream, "\n");
600 }
601
602 static void
603 set_subcommand_option (enum subcommand subcommand)
604 {
605 if (subcommand_option != UNKNOWN_SUBCOMMAND
606 && subcommand_option != subcommand)
607 USAGE_ERROR ((0, 0,
608 _("You may not specify more than one `-Acdtrux' option")));
609
610 subcommand_option = subcommand;
611 }
612
613 static void
614 set_use_compress_program_option (const char *string)
615 {
616 if (use_compress_program_option
617 && strcmp (use_compress_program_option, string) != 0)
618 USAGE_ERROR ((0, 0, _("Conflicting compression options")));
619
620 use_compress_program_option = string;
621 }
622
623 void
624 license ()
625 {
626 printf ("tar (%s) %s\n%s\n", PACKAGE_NAME, PACKAGE_VERSION,
627 "Copyright (C) 2004 Free Software Foundation, Inc.\n");
628 puts (_("Based on the work of John Gilmore and Jay Fenlason. See AUTHORS\n\
629 for complete list of authors.\n"));
630 printf (_(" GNU tar is free software; you can redistribute it and/or modify\n"
631 " it under the terms of the GNU General Public License as published by\n"
632 " the Free Software Foundation; either version 2 of the License, or\n"
633 " (at your option) any later version.\n"
634 "\n"
635 " GNU tar is distributed in the hope that it will be useful,\n"
636 " but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
637 " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
638 " GNU General Public License for more details.\n"
639 "\n"
640 " You should have received a copy of the GNU General Public License\n"
641 " along with GNU tar; if not, write to the Free Software Foundation,\n"
642 " Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA\n\n"));
643 exit (0);
644 }
645
646 static volatile int _argp_hang;
647
648 enum read_file_list_state /* Result of reading file name from the list file */
649 {
650 file_list_success, /* OK, name read successfully */
651 file_list_end, /* End of list file */
652 file_list_zero /* Zero separator encountered where it should not */
653 };
654
655 /* Read from FP a sequence of characters up to FILENAME_TERMINATOR and put them
656 into STK.
657 */
658 static enum read_file_list_state
659 read_name_from_file (FILE *fp, struct obstack *stk)
660 {
661 int c;
662 size_t counter = 0;
663
664 for (c = getc (fp); c != EOF && c != filename_terminator; c = getc (fp))
665 {
666 if (c == 0)
667 {
668 /* We have read a zero separator. The file possibly is zero-separated */
669 /* FATAL_ERROR((0, 0, N_("file name contains null character"))); */
670 return file_list_zero;
671 }
672 obstack_1grow (stk, c);
673 counter++;
674 }
675
676 obstack_1grow (stk, 0);
677
678 return (counter == 0 && c == EOF) ? file_list_end : file_list_success;
679 }
680
681 \f
682 static bool files_from_option; /* When set, tar will not refuse to create
683 empty archives */
684 static struct obstack argv_stk; /* Storage for additional command line options
685 read using -T option */
686
687 /* Prevent recursive inclusion of the same file */
688 struct file_id_list
689 {
690 struct file_id_list *next;
691 ino_t ino;
692 dev_t dev;
693 };
694
695 static struct file_id_list *file_id_list;
696
697 static void
698 add_file_id (const char *filename)
699 {
700 struct file_id_list *p;
701 struct stat st;
702
703 if (stat (filename, &st))
704 stat_fatal (filename);
705 for (p = file_id_list; p; p = p->next)
706 if (p->ino == st.st_ino && p->dev == st.st_dev)
707 {
708 FATAL_ERROR ((0, 0, _("%s: file list already read"),
709 quotearg_colon (filename)));
710 }
711 p = xmalloc (sizeof *p);
712 p->next = file_id_list;
713 p->ino = st.st_ino;
714 p->dev = st.st_dev;
715 file_id_list = p;
716 }
717
718 static void
719 update_argv (const char *filename, struct argp_state *state)
720 {
721 FILE *fp;
722 size_t count = 0, i;
723 char *start, *p;
724 char **new_argv;
725 size_t new_argc;
726 bool is_stdin = false;
727 enum read_file_list_state read_state;
728
729 if (!strcmp (filename, "-"))
730 {
731 is_stdin = true;
732 request_stdin ("-T");
733 fp = stdin;
734 }
735 else
736 {
737 add_file_id (filename);
738 if ((fp = fopen (filename, "r")) == NULL)
739 open_fatal (filename);
740 }
741
742 while ((read_state = read_name_from_file (fp, &argv_stk)) == file_list_success)
743 count++;
744
745 if (read_state == file_list_zero)
746 {
747 size_t size;
748
749 WARN ((0, 0, N_("%s: file name read contains nul character"),
750 quotearg_colon (filename)));
751
752 /* Prepare new stack contents */
753 size = obstack_object_size (&argv_stk);
754 p = obstack_finish (&argv_stk);
755 for (; size > 0; size--, p++)
756 if (*p)
757 obstack_1grow (&argv_stk, *p);
758 else
759 obstack_1grow (&argv_stk, '\n');
760 obstack_1grow (&argv_stk, 0);
761 count = 1;
762
763 /* Read rest of files using new filename terminator */
764 filename_terminator = 0;
765 while (read_name_from_file (fp, &argv_stk) == file_list_success)
766 count++;
767 }
768
769 if (!is_stdin)
770 fclose (fp);
771
772 if (count == 0)
773 return;
774
775 start = obstack_finish (&argv_stk);
776
777 if (filename_terminator == 0)
778 for (p = start; *p; p += strlen (p) + 1)
779 if (p[0] == '-')
780 count++;
781
782 new_argc = state->argc + count;
783 new_argv = xmalloc (sizeof (state->argv[0]) * (new_argc + 1));
784 memcpy (new_argv, state->argv, sizeof (state->argv[0]) * (state->argc + 1));
785 state->argv = new_argv;
786 memmove (&state->argv[state->next + count], &state->argv[state->next],
787 (state->argc - state->next + 1) * sizeof (state->argv[0]));
788
789 state->argc = new_argc;
790
791 for (i = state->next, p = start; *p; p += strlen (p) + 1, i++)
792 {
793 if (filename_terminator == 0 && p[0] == '-')
794 state->argv[i++] = "--add-file";
795 state->argv[i] = p;
796 }
797 }
798
799 \f
800 static error_t
801 parse_opt (int key, char *arg, struct argp_state *state)
802 {
803 struct tar_args *args = state->input;
804
805 switch (key)
806 {
807 case ARGP_KEY_ARG:
808 /* File name or non-parsed option, because of ARGP_IN_ORDER */
809 name_add (arg);
810 args->input_files++;
811 break;
812
813 case 'A':
814 set_subcommand_option (CAT_SUBCOMMAND);
815 break;
816
817 case 'b':
818 {
819 uintmax_t u;
820 if (! (xstrtoumax (arg, 0, 10, &u, "") == LONGINT_OK
821 && u == (blocking_factor = u)
822 && 0 < blocking_factor
823 && u == (record_size = u * BLOCKSIZE) / BLOCKSIZE))
824 USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (arg),
825 _("Invalid blocking factor")));
826 }
827 break;
828
829 case 'B':
830 /* Try to reblock input records. For reading 4.2BSD pipes. */
831
832 /* It would surely make sense to exchange -B and -R, but it seems
833 that -B has been used for a long while in Sun tar and most
834 BSD-derived systems. This is a consequence of the block/record
835 terminology confusion. */
836
837 read_full_records_option = true;
838 break;
839
840 case 'c':
841 set_subcommand_option (CREATE_SUBCOMMAND);
842 break;
843
844 case 'C':
845 name_add ("-C");
846 name_add (arg);
847 break;
848
849 case 'd':
850 set_subcommand_option (DIFF_SUBCOMMAND);
851 break;
852
853 case 'f':
854 if (archive_names == allocated_archive_names)
855 {
856 allocated_archive_names *= 2;
857 archive_name_array =
858 xrealloc (archive_name_array,
859 sizeof (const char *) * allocated_archive_names);
860 }
861 archive_name_array[archive_names++] = arg;
862 break;
863
864 case 'F':
865 /* Since -F is only useful with -M, make it implied. Run this
866 script at the end of each tape. */
867
868 info_script_option = arg;
869 multi_volume_option = true;
870 break;
871
872 case 'g':
873 listed_incremental_option = arg;
874 after_date_option = true;
875 /* Fall through. */
876
877 case 'G':
878 /* We are making an incremental dump (FIXME: are we?); save
879 directories at the beginning of the archive, and include in each
880 directory its contents. */
881
882 incremental_option = true;
883 break;
884
885 case 'h':
886 /* Follow symbolic links. */
887 dereference_option = true;
888 break;
889
890 case 'i':
891 /* Ignore zero blocks (eofs). This can't be the default,
892 because Unix tar writes two blocks of zeros, then pads out
893 the record with garbage. */
894
895 ignore_zeros_option = true;
896 break;
897
898 case 'I':
899 USAGE_ERROR ((0, 0,
900 _("Warning: the -I option is not supported;"
901 " perhaps you meant -j or -T?")));
902 break;
903
904 case 'j':
905 set_use_compress_program_option ("bzip2");
906 break;
907
908 case 'k':
909 /* Don't replace existing files. */
910 old_files_option = KEEP_OLD_FILES;
911 break;
912
913 case 'K':
914 starting_file_option = true;
915 addname (arg, 0);
916 break;
917
918 case 'l':
919 /* Historically equivalent to --one-file-system. This usage is
920 incompatible with UNIX98 and POSIX specs and therefore is
921 deprecated. The semantics of -l option will be changed in
922 future versions. See TODO.
923 */
924 WARN ((0, 0,
925 _("Semantics of -l option will change in the future releases.")));
926 WARN ((0, 0,
927 _("Please use --one-file-system option instead.")));
928 /* FALL THROUGH */
929 case ONE_FILE_SYSTEM_OPTION:
930 /* When dumping directories, don't dump files/subdirectories
931 that are on other filesystems. */
932 one_file_system_option = true;
933 break;
934
935 case 'L':
936 {
937 uintmax_t u;
938 if (xstrtoumax (arg, 0, 10, &u, "") != LONGINT_OK)
939 USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (arg),
940 _("Invalid tape length")));
941 tape_length_option = 1024 * (tarlong) u;
942 multi_volume_option = true;
943 }
944 break;
945
946 case 'm':
947 touch_option = true;
948 break;
949
950 case 'M':
951 /* Make multivolume archive: when we can't write any more into
952 the archive, re-open it, and continue writing. */
953
954 multi_volume_option = true;
955 break;
956
957 case 'n':
958 seekable_archive = true;
959 break;
960
961 #if !MSDOS
962 case 'N':
963 after_date_option = true;
964 /* Fall through. */
965
966 case NEWER_MTIME_OPTION:
967 if (NEWER_OPTION_INITIALIZED (newer_mtime_option))
968 USAGE_ERROR ((0, 0, _("More than one threshold date")));
969
970 if (FILE_SYSTEM_PREFIX_LEN (arg) != 0
971 || ISSLASH (*arg)
972 || *arg == '.')
973 {
974 struct stat st;
975 if (deref_stat (dereference_option, arg, &st) != 0)
976 {
977 stat_error (arg);
978 USAGE_ERROR ((0, 0, _("Date sample file not found")));
979 }
980 newer_mtime_option = get_stat_mtime (&st);
981 }
982 else
983 {
984 if (! get_date (&newer_mtime_option, arg, NULL))
985 {
986 WARN ((0, 0, _("Substituting %s for unknown date format %s"),
987 tartime (newer_mtime_option, false), quote (arg)));
988 newer_mtime_option.tv_nsec = 0;
989 }
990 else
991 args->textual_date_option = arg;
992 }
993
994 break;
995 #endif /* not MSDOS */
996
997 case 'o':
998 args->o_option = true;
999 break;
1000
1001 case 'O':
1002 to_stdout_option = true;
1003 break;
1004
1005 case 'p':
1006 same_permissions_option = true;
1007 break;
1008
1009 case 'P':
1010 absolute_names_option = true;
1011 break;
1012
1013 case 'r':
1014 set_subcommand_option (APPEND_SUBCOMMAND);
1015 break;
1016
1017 case 'R':
1018 /* Print block numbers for debugging bad tar archives. */
1019
1020 /* It would surely make sense to exchange -B and -R, but it seems
1021 that -B has been used for a long while in Sun tar ans most
1022 BSD-derived systems. This is a consequence of the block/record
1023 terminology confusion. */
1024
1025 block_number_option = true;
1026 break;
1027
1028 case 's':
1029 /* Names to extr are sorted. */
1030
1031 same_order_option = true;
1032 break;
1033
1034 case 'S':
1035 sparse_option = true;
1036 break;
1037
1038 case 't':
1039 set_subcommand_option (LIST_SUBCOMMAND);
1040 verbose_option++;
1041 break;
1042
1043 case TEST_LABEL_OPTION:
1044 set_subcommand_option (LIST_SUBCOMMAND);
1045 test_label_option = true;
1046 break;
1047
1048 case 'T':
1049 update_argv (arg, state);
1050 /* Indicate we've been given -T option. This is for backward
1051 compatibility only, so that `tar cfT archive /dev/null will
1052 succeed */
1053 files_from_option = true;
1054 break;
1055
1056 case 'u':
1057 set_subcommand_option (UPDATE_SUBCOMMAND);
1058 break;
1059
1060 case 'U':
1061 old_files_option = UNLINK_FIRST_OLD_FILES;
1062 break;
1063
1064 case UTC_OPTION:
1065 utc_option = true;
1066 break;
1067
1068 case 'v':
1069 verbose_option++;
1070 break;
1071
1072 case 'V':
1073 volume_label_option = arg;
1074 break;
1075
1076 case 'w':
1077 interactive_option = true;
1078 break;
1079
1080 case 'W':
1081 verify_option = true;
1082 break;
1083
1084 case 'x':
1085 set_subcommand_option (EXTRACT_SUBCOMMAND);
1086 break;
1087
1088 case 'X':
1089 if (add_exclude_file (add_exclude, excluded, arg,
1090 args->exclude_options | recursion_option, '\n')
1091 != 0)
1092 {
1093 int e = errno;
1094 FATAL_ERROR ((0, e, "%s", quotearg_colon (arg)));
1095 }
1096 break;
1097
1098 case 'y':
1099 USAGE_ERROR ((0, 0,
1100 _("Warning: the -y option is not supported;"
1101 " perhaps you meant -j?")));
1102 break;
1103
1104 case 'z':
1105 set_use_compress_program_option ("gzip");
1106 break;
1107
1108 case 'Z':
1109 set_use_compress_program_option ("compress");
1110 break;
1111
1112 case ANCHORED_OPTION:
1113 args->exclude_options |= EXCLUDE_ANCHORED;
1114 break;
1115
1116 case ATIME_PRESERVE_OPTION:
1117 atime_preserve_option = true;
1118 break;
1119
1120 case CHECKPOINT_OPTION:
1121 checkpoint_option = true;
1122 break;
1123
1124 case BACKUP_OPTION:
1125 backup_option = true;
1126 if (arg)
1127 args->version_control_string = arg;
1128 break;
1129
1130 case DELETE_OPTION:
1131 set_subcommand_option (DELETE_SUBCOMMAND);
1132 break;
1133
1134 case EXCLUDE_OPTION:
1135 add_exclude (excluded, arg, args->exclude_options | recursion_option);
1136 break;
1137
1138 case EXCLUDE_CACHES_OPTION:
1139 exclude_caches_option = true;
1140 break;
1141
1142 case FORCE_LOCAL_OPTION:
1143 force_local_option = true;
1144 break;
1145
1146 case 'H':
1147 set_archive_format (arg);
1148 break;
1149
1150 case INDEX_FILE_OPTION:
1151 index_file_name = arg;
1152 break;
1153
1154 case IGNORE_CASE_OPTION:
1155 args->exclude_options |= FNM_CASEFOLD;
1156 break;
1157
1158 case IGNORE_COMMAND_ERROR_OPTION:
1159 ignore_command_error_option = true;
1160 break;
1161
1162 case IGNORE_FAILED_READ_OPTION:
1163 ignore_failed_read_option = true;
1164 break;
1165
1166 case KEEP_NEWER_FILES_OPTION:
1167 old_files_option = KEEP_NEWER_FILES;
1168 break;
1169
1170 case GROUP_OPTION:
1171 if (! (strlen (arg) < GNAME_FIELD_SIZE
1172 && gname_to_gid (arg, &group_option)))
1173 {
1174 uintmax_t g;
1175 if (xstrtoumax (arg, 0, 10, &g, "") == LONGINT_OK
1176 && g == (gid_t) g)
1177 group_option = g;
1178 else
1179 FATAL_ERROR ((0, 0, "%s: %s", quotearg_colon (arg),
1180 _("%s: Invalid group")));
1181 }
1182 break;
1183
1184 case MODE_OPTION:
1185 mode_option = mode_compile (arg);
1186 if (!mode_option)
1187 FATAL_ERROR ((0, 0, _("Invalid mode given on option")));
1188 initial_umask = umask (0);
1189 umask (initial_umask);
1190 break;
1191
1192 case NO_ANCHORED_OPTION:
1193 args->exclude_options &= ~ EXCLUDE_ANCHORED;
1194 break;
1195
1196 case NO_IGNORE_CASE_OPTION:
1197 args->exclude_options &= ~ FNM_CASEFOLD;
1198 break;
1199
1200 case NO_IGNORE_COMMAND_ERROR_OPTION:
1201 ignore_command_error_option = false;
1202 break;
1203
1204 case NO_OVERWRITE_DIR_OPTION:
1205 old_files_option = NO_OVERWRITE_DIR_OLD_FILES;
1206 break;
1207
1208 case NO_WILDCARDS_OPTION:
1209 args->exclude_options &= ~ EXCLUDE_WILDCARDS;
1210 break;
1211
1212 case NO_WILDCARDS_MATCH_SLASH_OPTION:
1213 args->exclude_options |= FNM_FILE_NAME;
1214 break;
1215
1216 case NULL_OPTION:
1217 filename_terminator = '\0';
1218 break;
1219
1220 case NUMERIC_OWNER_OPTION:
1221 numeric_owner_option = true;
1222 break;
1223
1224 case OCCURRENCE_OPTION:
1225 if (!arg)
1226 occurrence_option = 1;
1227 else
1228 {
1229 uintmax_t u;
1230 if (xstrtoumax (arg, 0, 10, &u, "") == LONGINT_OK)
1231 occurrence_option = u;
1232 else
1233 FATAL_ERROR ((0, 0, "%s: %s", quotearg_colon (arg),
1234 _("Invalid number")));
1235 }
1236 break;
1237
1238 case OVERWRITE_OPTION:
1239 old_files_option = OVERWRITE_OLD_FILES;
1240 break;
1241
1242 case OWNER_OPTION:
1243 if (! (strlen (arg) < UNAME_FIELD_SIZE
1244 && uname_to_uid (arg, &owner_option)))
1245 {
1246 uintmax_t u;
1247 if (xstrtoumax (arg, 0, 10, &u, "") == LONGINT_OK
1248 && u == (uid_t) u)
1249 owner_option = u;
1250 else
1251 FATAL_ERROR ((0, 0, "%s: %s", quotearg_colon (arg),
1252 _("Invalid owner")));
1253 }
1254 break;
1255
1256 case PAX_OPTION:
1257 args->pax_option++;
1258 xheader_set_option (arg);
1259 break;
1260
1261 case POSIX_OPTION:
1262 set_archive_format ("posix");
1263 break;
1264
1265 case PRESERVE_OPTION:
1266 same_permissions_option = true;
1267 same_order_option = true;
1268 break;
1269
1270 case RECORD_SIZE_OPTION:
1271 {
1272 uintmax_t u;
1273 if (! (xstrtoumax (arg, 0, 10, &u, "") == LONGINT_OK
1274 && u == (size_t) u))
1275 USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (arg),
1276 _("Invalid record size")));
1277 record_size = u;
1278 if (record_size % BLOCKSIZE != 0)
1279 USAGE_ERROR ((0, 0, _("Record size must be a multiple of %d."),
1280 BLOCKSIZE));
1281 blocking_factor = record_size / BLOCKSIZE;
1282 }
1283 break;
1284
1285 case RECURSIVE_UNLINK_OPTION:
1286 recursive_unlink_option = true;
1287 break;
1288
1289 case REMOVE_FILES_OPTION:
1290 remove_files_option = true;
1291 break;
1292
1293 case RMT_COMMAND_OPTION:
1294 rmt_command = arg;
1295 break;
1296
1297 case RSH_COMMAND_OPTION:
1298 rsh_command_option = arg;
1299 break;
1300
1301 case SHOW_DEFAULTS_OPTION:
1302 show_default_settings (stdout);
1303 exit(0);
1304
1305 case STRIP_COMPONENTS_OPTION:
1306 {
1307 uintmax_t u;
1308 if (! (xstrtoumax (arg, 0, 10, &u, "") == LONGINT_OK
1309 && u == (size_t) u))
1310 USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (arg),
1311 _("Invalid number of elements")));
1312 strip_name_components = u;
1313 }
1314 break;
1315
1316 case SHOW_OMITTED_DIRS_OPTION:
1317 show_omitted_dirs_option = true;
1318 break;
1319
1320 case SUFFIX_OPTION:
1321 backup_option = true;
1322 args->backup_suffix_string = arg;
1323 break;
1324
1325 case TO_COMMAND_OPTION:
1326 if (to_command_option)
1327 USAGE_ERROR ((0, 0, _("Only one --to-command option allowed")));
1328 to_command_option = arg;
1329 break;
1330
1331 case TOTALS_OPTION:
1332 totals_option = true;
1333 break;
1334
1335 case USE_COMPRESS_PROGRAM_OPTION:
1336 set_use_compress_program_option (arg);
1337 break;
1338
1339 case VOLNO_FILE_OPTION:
1340 volno_file_option = arg;
1341 break;
1342
1343 case WILDCARDS_OPTION:
1344 args->exclude_options |= EXCLUDE_WILDCARDS;
1345 break;
1346
1347 case WILDCARDS_MATCH_SLASH_OPTION:
1348 args->exclude_options &= ~ FNM_FILE_NAME;
1349 break;
1350
1351 case CHECK_LINKS_OPTION:
1352 check_links_option = 1;
1353 break;
1354
1355 case NO_RECURSION_OPTION:
1356 recursion_option = 0;
1357 break;
1358
1359 case NO_SAME_OWNER_OPTION:
1360 same_owner_option = -1;
1361 break;
1362
1363 case NO_SAME_PERMISSIONS_OPTION:
1364 same_permissions_option = -1;
1365 break;
1366
1367 case RECURSION_OPTION:
1368 recursion_option = FNM_LEADING_DIR;
1369 break;
1370
1371 case SAME_OWNER_OPTION:
1372 same_owner_option = 1;
1373 break;
1374
1375 case UNQUOTE_OPTION:
1376 unquote_option = true;
1377 break;
1378
1379 case NO_UNQUOTE_OPTION:
1380 unquote_option = false;
1381 break;
1382
1383 case '0':
1384 case '1':
1385 case '2':
1386 case '3':
1387 case '4':
1388 case '5':
1389 case '6':
1390 case '7':
1391
1392 #ifdef DEVICE_PREFIX
1393 {
1394 int device = key - '0';
1395 int density;
1396 static char buf[sizeof DEVICE_PREFIX + 10];
1397 char *cursor;
1398
1399 if (arg[1])
1400 argp_error (state, _("Malformed density argument: %s"), quote (arg));
1401
1402 strcpy (buf, DEVICE_PREFIX);
1403 cursor = buf + strlen (buf);
1404
1405 #ifdef DENSITY_LETTER
1406
1407 sprintf (cursor, "%d%c", device, arg[0]);
1408
1409 #else /* not DENSITY_LETTER */
1410
1411 switch (arg[0])
1412 {
1413 case 'l':
1414 #ifdef LOW_NUM
1415 device += LOW_NUM;
1416 #endif
1417 break;
1418
1419 case 'm':
1420 #ifdef MID_NUM
1421 device += MID_NUM;
1422 #else
1423 device += 8;
1424 #endif
1425 break;
1426
1427 case 'h':
1428 #ifdef HGH_NUM
1429 device += HGH_NUM;
1430 #else
1431 device += 16;
1432 #endif
1433 break;
1434
1435 default:
1436 argp_error (state, _("Unknown density: `%c'"), arg[0]);
1437 }
1438 sprintf (cursor, "%d", device);
1439
1440 #endif /* not DENSITY_LETTER */
1441
1442 if (archive_names == allocated_archive_names)
1443 {
1444 allocated_archive_names *= 2;
1445 archive_name_array =
1446 xrealloc (archive_name_array,
1447 sizeof (const char *) * allocated_archive_names);
1448 }
1449 archive_name_array[archive_names++] = xstrdup (buf);
1450 }
1451 break;
1452
1453 #else /* not DEVICE_PREFIX */
1454
1455 argp_error (state,
1456 _("Options `-[0-7][lmh]' not supported by *this* tar"));
1457
1458 #endif /* not DEVICE_PREFIX */
1459
1460 case '?':
1461 state->flags |= ARGP_NO_EXIT;
1462 argp_state_help (state, state->out_stream,
1463 ARGP_HELP_STD_HELP & ~ARGP_HELP_BUG_ADDR);
1464 fprintf (state->out_stream, _("\n*This* tar defaults to:\n"));
1465 show_default_settings (state->out_stream);
1466 fprintf (state->out_stream, "\n");
1467 fprintf (state->out_stream, _("Report bugs to %s.\n"),
1468 argp_program_bug_address);
1469 exit (0);
1470
1471 case USAGE_OPTION:
1472 argp_state_help (state, state->out_stream,
1473 ARGP_HELP_USAGE | ARGP_HELP_EXIT_OK);
1474 break;
1475
1476 case VERSION_OPTION:
1477 fprintf (state->out_stream, "%s\n", argp_program_version);
1478 exit (0);
1479
1480 case LICENSE_OPTION:
1481 license ();
1482 break;
1483
1484 case HANG_OPTION:
1485 _argp_hang = atoi (arg ? arg : "3600");
1486 while (_argp_hang-- > 0)
1487 sleep (1);
1488 break;
1489
1490 default:
1491 return ARGP_ERR_UNKNOWN;
1492 }
1493 return 0;
1494 }
1495
1496 static struct argp argp = {
1497 options,
1498 parse_opt,
1499 N_("[FILE]..."),
1500 doc,
1501 NULL,
1502 NULL,
1503 NULL
1504 };
1505
1506 void
1507 usage (int status)
1508 {
1509 argp_help (&argp, stderr, ARGP_HELP_SEE, (char*) program_name);
1510 exit (status);
1511 }
1512
1513 /* Parse the options for tar. */
1514
1515 static struct argp_option *
1516 find_argp_option (struct argp_option *options, int letter)
1517 {
1518 for (;
1519 !(options->name == NULL
1520 && options->key == 0
1521 && options->arg == 0
1522 && options->flags == 0
1523 && options->doc == NULL); options++)
1524 if (options->key == letter)
1525 return options;
1526 return NULL;
1527 }
1528
1529 static void
1530 decode_options (int argc, char **argv)
1531 {
1532 int index;
1533 struct tar_args args;
1534
1535 /* Set some default option values. */
1536 args.textual_date_option = NULL;
1537 args.exclude_options = EXCLUDE_WILDCARDS;
1538 args.o_option = 0;
1539 args.pax_option = 0;
1540 args.backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX");
1541 args.version_control_string = 0;
1542 args.input_files = 0;
1543
1544 subcommand_option = UNKNOWN_SUBCOMMAND;
1545 archive_format = DEFAULT_FORMAT;
1546 blocking_factor = DEFAULT_BLOCKING;
1547 record_size = DEFAULT_BLOCKING * BLOCKSIZE;
1548 excluded = new_exclude ();
1549 newer_mtime_option.tv_sec = TYPE_MINIMUM (time_t);
1550 newer_mtime_option.tv_nsec = -1;
1551 recursion_option = FNM_LEADING_DIR;
1552 unquote_option = true;
1553
1554 owner_option = -1;
1555 group_option = -1;
1556
1557 /* Convert old-style tar call by exploding option element and rearranging
1558 options accordingly. */
1559
1560 if (argc > 1 && argv[1][0] != '-')
1561 {
1562 int new_argc; /* argc value for rearranged arguments */
1563 char **new_argv; /* argv value for rearranged arguments */
1564 char *const *in; /* cursor into original argv */
1565 char **out; /* cursor into rearranged argv */
1566 const char *letter; /* cursor into old option letters */
1567 char buffer[3]; /* constructed option buffer */
1568
1569 /* Initialize a constructed option. */
1570
1571 buffer[0] = '-';
1572 buffer[2] = '\0';
1573
1574 /* Allocate a new argument array, and copy program name in it. */
1575
1576 new_argc = argc - 1 + strlen (argv[1]);
1577 new_argv = xmalloc ((new_argc + 1) * sizeof (char *));
1578 in = argv;
1579 out = new_argv;
1580 *out++ = *in++;
1581
1582 /* Copy each old letter option as a separate option, and have the
1583 corresponding argument moved next to it. */
1584
1585 for (letter = *in++; *letter; letter++)
1586 {
1587 struct argp_option *opt;
1588
1589 buffer[1] = *letter;
1590 *out++ = xstrdup (buffer);
1591 opt = find_argp_option (options, *letter);
1592 if (opt && opt->arg)
1593 {
1594 if (in < argv + argc)
1595 *out++ = *in++;
1596 else
1597 USAGE_ERROR ((0, 0, _("Old option `%c' requires an argument."),
1598 *letter));
1599 }
1600 }
1601
1602 /* Copy all remaining options. */
1603
1604 while (in < argv + argc)
1605 *out++ = *in++;
1606 *out = 0;
1607
1608 /* Replace the old option list by the new one. */
1609
1610 argc = new_argc;
1611 argv = new_argv;
1612 }
1613
1614 /* Parse all options and non-options as they appear. */
1615
1616 prepend_default_options (getenv ("TAR_OPTIONS"), &argc, &argv);
1617
1618 if (argp_parse (&argp, argc, argv, ARGP_IN_ORDER|ARGP_NO_HELP,
1619 &index, &args))
1620 exit (1);
1621
1622
1623 /* Special handling for 'o' option:
1624
1625 GNU tar used to say "output old format".
1626 UNIX98 tar says don't chown files after extracting (we use
1627 "--no-same-owner" for this).
1628
1629 The old GNU tar semantics is retained when used with --create
1630 option, otherwise UNIX98 semantics is assumed */
1631
1632 if (args.o_option)
1633 {
1634 if (subcommand_option == CREATE_SUBCOMMAND)
1635 {
1636 /* GNU Tar <= 1.13 compatibility */
1637 set_archive_format ("v7");
1638 }
1639 else
1640 {
1641 /* UNIX98 compatibility */
1642 same_owner_option = -1;
1643 }
1644 }
1645
1646 /* Handle operands after any "--" argument. */
1647 for (; index < argc; index++)
1648 {
1649 name_add (argv[index]);
1650 args.input_files++;
1651 }
1652
1653 /* Derive option values and check option consistency. */
1654
1655 if (archive_format == DEFAULT_FORMAT)
1656 {
1657 if (args.pax_option)
1658 archive_format = POSIX_FORMAT;
1659 else
1660 archive_format = DEFAULT_ARCHIVE_FORMAT;
1661 }
1662
1663 if (volume_label_option && subcommand_option == CREATE_SUBCOMMAND)
1664 assert_format (FORMAT_MASK (OLDGNU_FORMAT)
1665 | FORMAT_MASK (GNU_FORMAT));
1666
1667
1668 if (incremental_option || multi_volume_option)
1669 assert_format (FORMAT_MASK (OLDGNU_FORMAT) | FORMAT_MASK (GNU_FORMAT));
1670
1671 if (sparse_option)
1672 assert_format (FORMAT_MASK (OLDGNU_FORMAT)
1673 | FORMAT_MASK (GNU_FORMAT)
1674 | FORMAT_MASK (POSIX_FORMAT));
1675
1676 if (occurrence_option)
1677 {
1678 if (!args.input_files)
1679 USAGE_ERROR ((0, 0,
1680 _("--occurrence is meaningless without a file list")));
1681 if (subcommand_option != DELETE_SUBCOMMAND
1682 && subcommand_option != DIFF_SUBCOMMAND
1683 && subcommand_option != EXTRACT_SUBCOMMAND
1684 && subcommand_option != LIST_SUBCOMMAND)
1685 USAGE_ERROR ((0, 0,
1686 _("--occurrence cannot be used in the requested operation mode")));
1687 }
1688
1689 if (seekable_archive && subcommand_option == DELETE_SUBCOMMAND)
1690 {
1691 /* The current code in delete.c is based on the assumption that
1692 skip_member() reads all data from the archive. So, we should
1693 make sure it won't use seeks. On the other hand, the same code
1694 depends on the ability to backspace a record in the archive,
1695 so setting seekable_archive to false is technically incorrect.
1696 However, it is tested only in skip_member(), so it's not a
1697 problem. */
1698 seekable_archive = false;
1699 }
1700
1701 if (archive_names == 0)
1702 {
1703 /* If no archive file name given, try TAPE from the environment, or
1704 else, DEFAULT_ARCHIVE from the configuration process. */
1705
1706 archive_names = 1;
1707 archive_name_array[0] = getenv ("TAPE");
1708 if (! archive_name_array[0])
1709 archive_name_array[0] = DEFAULT_ARCHIVE;
1710 }
1711
1712 /* Allow multiple archives only with `-M'. */
1713
1714 if (archive_names > 1 && !multi_volume_option)
1715 USAGE_ERROR ((0, 0,
1716 _("Multiple archive files require `-M' option")));
1717
1718 if (listed_incremental_option
1719 && NEWER_OPTION_INITIALIZED (newer_mtime_option))
1720 USAGE_ERROR ((0, 0,
1721 _("Cannot combine --listed-incremental with --newer")));
1722
1723 if (volume_label_option)
1724 {
1725 size_t volume_label_max_len =
1726 (sizeof current_header->header.name
1727 - 1 /* for trailing '\0' */
1728 - (multi_volume_option
1729 ? (sizeof " Volume "
1730 - 1 /* for null at end of " Volume " */
1731 + INT_STRLEN_BOUND (int) /* for volume number */
1732 - 1 /* for sign, as 0 <= volno */)
1733 : 0));
1734 if (volume_label_max_len < strlen (volume_label_option))
1735 USAGE_ERROR ((0, 0,
1736 ngettext ("%s: Volume label is too long (limit is %lu byte)",
1737 "%s: Volume label is too long (limit is %lu bytes)",
1738 volume_label_max_len),
1739 quotearg_colon (volume_label_option),
1740 (unsigned long) volume_label_max_len));
1741 }
1742
1743 if (verify_option)
1744 {
1745 if (multi_volume_option)
1746 USAGE_ERROR ((0, 0, _("Cannot verify multi-volume archives")));
1747 if (use_compress_program_option)
1748 USAGE_ERROR ((0, 0, _("Cannot verify compressed archives")));
1749 }
1750
1751 if (use_compress_program_option)
1752 {
1753 if (multi_volume_option)
1754 USAGE_ERROR ((0, 0, _("Cannot use multi-volume compressed archives")));
1755 if (subcommand_option == UPDATE_SUBCOMMAND)
1756 USAGE_ERROR ((0, 0, _("Cannot update compressed archives")));
1757 }
1758
1759 /* It is no harm to use --pax-option on non-pax archives in archive
1760 reading mode. It may even be useful, since it allows to override
1761 file attributes from tar headers. Therefore I allow such usage.
1762 --gray */
1763 if (args.pax_option
1764 && archive_format != POSIX_FORMAT
1765 && (subcommand_option != EXTRACT_SUBCOMMAND
1766 || subcommand_option != DIFF_SUBCOMMAND
1767 || subcommand_option != LIST_SUBCOMMAND))
1768 USAGE_ERROR ((0, 0, _("--pax-option can be used only on POSIX archives")));
1769
1770 /* If ready to unlink hierarchies, so we are for simpler files. */
1771 if (recursive_unlink_option)
1772 old_files_option = UNLINK_FIRST_OLD_FILES;
1773
1774
1775 if (test_label_option)
1776 {
1777 /* --test-label is silent if the user has specified the label name to
1778 compare against. */
1779 if (args.input_files == 0)
1780 verbose_option++;
1781 }
1782 else if (utc_option)
1783 verbose_option = 2;
1784
1785 /* Forbid using -c with no input files whatsoever. Check that `-f -',
1786 explicit or implied, is used correctly. */
1787
1788 switch (subcommand_option)
1789 {
1790 case CREATE_SUBCOMMAND:
1791 if (args.input_files == 0 && !files_from_option)
1792 USAGE_ERROR ((0, 0,
1793 _("Cowardly refusing to create an empty archive")));
1794 break;
1795
1796 case EXTRACT_SUBCOMMAND:
1797 case LIST_SUBCOMMAND:
1798 case DIFF_SUBCOMMAND:
1799 for (archive_name_cursor = archive_name_array;
1800 archive_name_cursor < archive_name_array + archive_names;
1801 archive_name_cursor++)
1802 if (!strcmp (*archive_name_cursor, "-"))
1803 request_stdin ("-f");
1804 break;
1805
1806 case CAT_SUBCOMMAND:
1807 case UPDATE_SUBCOMMAND:
1808 case APPEND_SUBCOMMAND:
1809 for (archive_name_cursor = archive_name_array;
1810 archive_name_cursor < archive_name_array + archive_names;
1811 archive_name_cursor++)
1812 if (!strcmp (*archive_name_cursor, "-"))
1813 USAGE_ERROR ((0, 0,
1814 _("Options `-Aru' are incompatible with `-f -'")));
1815
1816 default:
1817 break;
1818 }
1819
1820 archive_name_cursor = archive_name_array;
1821
1822 /* Prepare for generating backup names. */
1823
1824 if (args.backup_suffix_string)
1825 simple_backup_suffix = xstrdup (args.backup_suffix_string);
1826
1827 if (backup_option)
1828 {
1829 backup_type = xget_version ("--backup", args.version_control_string);
1830 /* No backup is needed either if explicitely disabled or if
1831 the extracted files are not being written to disk. */
1832 if (backup_type == no_backups || EXTRACT_OVER_PIPE)
1833 backup_option = false;
1834 }
1835
1836 if (verbose_option && args.textual_date_option)
1837 {
1838 char const *treated_as = tartime (newer_mtime_option, true);
1839 if (strcmp (args.textual_date_option, treated_as) != 0)
1840 WARN ((0, 0, _("Treating date `%s' as %s"),
1841 args.textual_date_option, treated_as));
1842 }
1843 }
1844
1845 \f
1846 /* Tar proper. */
1847
1848 /* Main routine for tar. */
1849 int
1850 main (int argc, char **argv)
1851 {
1852 set_start_time ();
1853 program_name = argv[0];
1854
1855 setlocale (LC_ALL, "");
1856 bindtextdomain (PACKAGE, LOCALEDIR);
1857 textdomain (PACKAGE);
1858
1859 exit_status = TAREXIT_SUCCESS;
1860 filename_terminator = '\n';
1861 set_quoting_style (0, escape_quoting_style);
1862
1863 /* Pre-allocate a few structures. */
1864
1865 allocated_archive_names = 10;
1866 archive_name_array =
1867 xmalloc (sizeof (const char *) * allocated_archive_names);
1868 archive_names = 0;
1869
1870 obstack_init (&argv_stk);
1871
1872 #ifdef SIGCHLD
1873 /* System V fork+wait does not work if SIGCHLD is ignored. */
1874 signal (SIGCHLD, SIG_DFL);
1875 #endif
1876
1877 init_names ();
1878
1879 /* Decode options. */
1880
1881 decode_options (argc, argv);
1882 name_init ();
1883
1884 /* Main command execution. */
1885
1886 if (volno_file_option)
1887 init_volume_number ();
1888
1889 switch (subcommand_option)
1890 {
1891 case UNKNOWN_SUBCOMMAND:
1892 USAGE_ERROR ((0, 0,
1893 _("You must specify one of the `-Acdtrux' options")));
1894
1895 case CAT_SUBCOMMAND:
1896 case UPDATE_SUBCOMMAND:
1897 case APPEND_SUBCOMMAND:
1898 update_archive ();
1899 break;
1900
1901 case DELETE_SUBCOMMAND:
1902 delete_archive_members ();
1903 break;
1904
1905 case CREATE_SUBCOMMAND:
1906 create_archive ();
1907 if (totals_option)
1908 print_total_written ();
1909 break;
1910
1911 case EXTRACT_SUBCOMMAND:
1912 extr_init ();
1913 read_and (extract_archive);
1914
1915 /* FIXME: should extract_finish () even if an ordinary signal is
1916 received. */
1917 extract_finish ();
1918
1919 break;
1920
1921 case LIST_SUBCOMMAND:
1922 read_and (list_archive);
1923 break;
1924
1925 case DIFF_SUBCOMMAND:
1926 diff_init ();
1927 read_and (diff_archive);
1928 break;
1929 }
1930
1931 if (check_links_option)
1932 check_links ();
1933
1934 if (volno_file_option)
1935 closeout_volume_number ();
1936
1937 /* Dispose of allocated memory, and return. */
1938
1939 free (archive_name_array);
1940 name_term ();
1941
1942 if (stdlis != stderr && (ferror (stdlis) || fclose (stdlis) != 0))
1943 FATAL_ERROR ((0, 0, _("Error in writing to standard output")));
1944 if (exit_status == TAREXIT_FAILURE)
1945 error (0, 0, _("Error exit delayed from previous errors"));
1946 if (ferror (stderr) || fclose (stderr) != 0)
1947 exit_status = TAREXIT_FAILURE;
1948 return exit_status;
1949 }
1950
1951 void
1952 tar_stat_init (struct tar_stat_info *st)
1953 {
1954 memset (st, 0, sizeof (*st));
1955 }
1956
1957 void
1958 tar_stat_destroy (struct tar_stat_info *st)
1959 {
1960 free (st->orig_file_name);
1961 free (st->file_name);
1962 free (st->link_name);
1963 free (st->uname);
1964 free (st->gname);
1965 free (st->sparse_map);
1966 memset (st, 0, sizeof (*st));
1967 }
This page took 0.123178 seconds and 4 git commands to generate.