1 /* A tar (tape archiver) program.
3 Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1999, 2000,
4 2001, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
6 Written by John Gilmore, starting 1985-08-25.
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
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.
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. */
27 #include <argp-namefrob.h>
28 #include <argp-fmtstream.h>
31 #if ! defined SIGCHLD && defined SIGCLD
32 # define SIGCHLD SIGCLD
35 /* The following causes "common.h" to produce definitions of all the global
36 variables, rather than just "extern" declarations of them. GNU tar does
37 depend on the system loader to preset all GLOBAL variables to neutral (or
38 zero) values; explicit initialization is usually not done. */
46 #include <localedir.h>
50 #include <version-etc.h>
54 /* Local declarations. */
56 #ifndef DEFAULT_ARCHIVE_FORMAT
57 # define DEFAULT_ARCHIVE_FORMAT GNU_FORMAT
60 #ifndef DEFAULT_ARCHIVE
61 # define DEFAULT_ARCHIVE "tar.out"
64 #ifndef DEFAULT_BLOCKING
65 # define DEFAULT_BLOCKING 20
71 /* Name of option using stdin. */
72 static const char *stdin_used_by
;
74 /* Doesn't return if stdin already requested. */
76 request_stdin (const char *option
)
79 USAGE_ERROR ((0, 0, _("Options `-%s' and `-%s' both want standard input"),
80 stdin_used_by
, option
));
82 stdin_used_by
= option
;
85 extern int rpmatch (char const *response
);
87 /* Returns true if and only if the user typed an affirmative response. */
89 confirm (const char *message_action
, const char *message_name
)
91 static FILE *confirm_file
;
92 static int confirm_file_EOF
;
97 if (archive
== 0 || stdin_used_by
)
99 confirm_file
= fopen (TTY_NAME
, "r");
101 open_fatal (TTY_NAME
);
105 request_stdin ("-w");
106 confirm_file
= stdin
;
110 fprintf (stdlis
, "%s %s?", message_action
, quote (message_name
));
113 if (!confirm_file_EOF
)
115 char *response
= NULL
;
116 size_t response_size
= 0;
117 if (getline (&response
, &response_size
, confirm_file
) < 0)
118 confirm_file_EOF
= 1;
120 status
= rpmatch (response
) > 0;
124 if (confirm_file_EOF
)
126 fputc ('\n', stdlis
);
133 static struct fmttab
{
135 enum archive_format fmt
;
138 { "oldgnu", OLDGNU_FORMAT
},
139 { "ustar", USTAR_FORMAT
},
140 { "posix", POSIX_FORMAT
},
141 #if 0 /* not fully supported yet */
142 { "star", STAR_FORMAT
},
144 { "gnu", GNU_FORMAT
},
145 { "pax", POSIX_FORMAT
}, /* An alias for posix */
150 set_archive_format (char const *name
)
152 struct fmttab
const *p
;
154 for (p
= fmttab
; strcmp (p
->name
, name
) != 0; )
156 USAGE_ERROR ((0, 0, _("%s: Invalid archive format"),
157 quotearg_colon (name
)));
159 archive_format
= p
->fmt
;
163 archive_format_string (enum archive_format fmt
)
165 struct fmttab
const *p
;
167 for (p
= fmttab
; p
->name
; p
++)
173 #define FORMAT_MASK(n) (1<<(n))
176 assert_format(unsigned fmt_mask
)
178 if ((FORMAT_MASK (archive_format
) & fmt_mask
) == 0)
180 _("GNU features wanted on incompatible archive format")));
184 subcommand_string (enum subcommand c
)
188 case UNKNOWN_SUBCOMMAND
:
191 case APPEND_SUBCOMMAND
:
197 case CREATE_SUBCOMMAND
:
200 case DELETE_SUBCOMMAND
:
203 case DIFF_SUBCOMMAND
:
206 case EXTRACT_SUBCOMMAND
:
209 case LIST_SUBCOMMAND
:
212 case UPDATE_SUBCOMMAND
:
221 tar_list_quoting_styles (argp_fmtstream_t fs
, char *prefix
)
225 for (i
= 0; quoting_style_args
[i
]; i
++)
226 argp_fmtstream_printf (fs
, "%s%s\n", prefix
, quoting_style_args
[i
]);
230 tar_set_quoting_style (char *arg
)
234 for (i
= 0; quoting_style_args
[i
]; i
++)
235 if (strcmp (arg
, quoting_style_args
[i
]) == 0)
237 set_quoting_style (NULL
, i
);
241 _("Unknown quoting style `%s'. Try `%s --quoting-style=help' to get a list."), arg
, program_invocation_short_name
));
249 ANCHORED_OPTION
= CHAR_MAX
+ 1,
250 ATIME_PRESERVE_OPTION
,
253 DELAY_DIRECTORY_RESTORE_OPTION
,
255 EXCLUDE_CACHES_OPTION
,
261 IGNORE_COMMAND_ERROR_OPTION
,
262 IGNORE_FAILED_READ_OPTION
,
264 KEEP_NEWER_FILES_OPTION
,
268 NO_DELAY_DIRECTORY_RESTORE_OPTION
,
269 NO_IGNORE_CASE_OPTION
,
270 NO_IGNORE_COMMAND_ERROR_OPTION
,
271 NO_OVERWRITE_DIR_OPTION
,
272 NO_QUOTE_CHARS_OPTION
,
274 NO_SAME_OWNER_OPTION
,
275 NO_SAME_PERMISSIONS_OPTION
,
277 NO_WILDCARDS_MATCH_SLASH_OPTION
,
280 NUMERIC_OWNER_OPTION
,
283 ONE_FILE_SYSTEM_OPTION
,
290 QUOTING_STYLE_OPTION
,
293 RECURSIVE_UNLINK_OPTION
,
299 SHOW_DEFAULTS_OPTION
,
300 SHOW_OMITTED_DIRS_OPTION
,
301 SHOW_TRANSFORMED_NAMES_OPTION
,
302 STRIP_COMPONENTS_OPTION
,
310 USE_COMPRESS_PROGRAM_OPTION
,
314 WILDCARDS_MATCH_SLASH_OPTION
,
318 const char *argp_program_version
= "tar (" PACKAGE_NAME
") " VERSION
;
319 const char *argp_program_bug_address
= "<" PACKAGE_BUGREPORT
">";
320 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\
323 tar -cf archive.tar foo bar # Create archive.tar from files foo and bar.\n\
324 tar -tvf archive.tar # List all files in archive.tar verbosely.\n\
325 tar -xf archive.tar # Extract all files from archive.tar.\n\
326 \vThe backup suffix is `~', unless set with --suffix or SIMPLE_BACKUP_SUFFIX.\n\
327 The version control may be set with --backup or VERSION_CONTROL, values are:\n\n\
328 none, off never make backups\n\
329 t, numbered make numbered backups\n\
330 nil, existing numbered if numbered backups exist, simple otherwise\n\
331 never, simple always make simple backups\n");
336 Available option letters are DEIJQY and aeqy. Consider the following
339 [For Solaris tar compatibility =/= Is it important at all?]
340 e exit immediately with a nonzero exit status if unexpected errors occur
341 E use extended headers (--format=posix)
343 [q alias for --occurrence=1 =/= this would better be used for quiet?]
344 [I same as T =/= will harm star compatibility]
346 y per-file gzip compression
347 Y per-block gzip compression */
349 static struct argp_option options
[] = {
352 N_("Main operation mode:"), GRID
},
355 N_("list the contents of an archive"), GRID
+1 },
356 {"extract", 'x', 0, 0,
357 N_("extract files from an archive"), GRID
+1 },
358 {"get", 0, 0, OPTION_ALIAS
, NULL
, GRID
+1 },
359 {"create", 'c', 0, 0,
360 N_("create a new archive"), GRID
+1 },
362 N_("find differences between archive and file system"), GRID
+1 },
363 {"compare", 0, 0, OPTION_ALIAS
, NULL
, GRID
+1 },
364 {"append", 'r', 0, 0,
365 N_("append files to the end of an archive"), GRID
+1 },
366 {"update", 'u', 0, 0,
367 N_("only append files newer than copy in archive"), GRID
+1 },
368 {"catenate", 'A', 0, 0,
369 N_("append tar files to an archive"), GRID
+1 },
370 {"concatenate", 0, 0, OPTION_ALIAS
, NULL
, GRID
+1 },
371 {"delete", DELETE_OPTION
, 0, 0,
372 N_("delete from the archive (not on mag tapes!)"), GRID
+1 },
373 {"test-label", TEST_LABEL_OPTION
, NULL
, 0,
374 N_("test the archive volume label and exit"), GRID
+1 },
379 N_("Operation modifiers:"), GRID
},
381 {"sparse", 'S', 0, 0,
382 N_("handle sparse files efficiently"), GRID
+1 },
383 {"incremental", 'G', 0, 0,
384 N_("handle old GNU-format incremental backup"), GRID
+1 },
385 {"listed-incremental", 'g', N_("FILE"), 0,
386 N_("handle new GNU-format incremental backup"), GRID
+1 },
387 {"ignore-failed-read", IGNORE_FAILED_READ_OPTION
, 0, 0,
388 N_("do not exit with nonzero on unreadable files"), GRID
+1 },
389 {"occurrence", OCCURRENCE_OPTION
, N_("NUMBER"), OPTION_ARG_OPTIONAL
,
390 N_("process only the NUMBERth occurrence of each file in the archive;"
391 " this option is valid only in conjunction with one of the subcommands"
392 " --delete, --diff, --extract or --list and when a list of files"
393 " is given either on the command line or via the -T option;"
394 " NUMBER defaults to 1"), GRID
+1 },
395 {"seek", 'n', NULL
, 0,
396 N_("archive is seekable"), GRID
+1 },
401 N_("Overwrite control:\n"), GRID
+1 },
403 {"verify", 'W', 0, 0,
404 N_("attempt to verify the archive after writing it"), GRID
+1 },
405 {"remove-files", REMOVE_FILES_OPTION
, 0, 0,
406 N_("remove files after adding them to the archive"), GRID
+1 },
407 {"keep-old-files", 'k', 0, 0,
408 N_("don't replace existing files when extracting"), GRID
+1 },
409 {"keep-newer-files", KEEP_NEWER_FILES_OPTION
, 0, 0,
410 N_("don't replace existing files that are newer than their archive copies"), GRID
+1 },
411 {"overwrite", OVERWRITE_OPTION
, 0, 0,
412 N_("overwrite existing files when extracting"), GRID
+1 },
413 {"unlink-first", 'U', 0, 0,
414 N_("remove each file prior to extracting over it"), GRID
+1 },
415 {"recursive-unlink", RECURSIVE_UNLINK_OPTION
, 0, 0,
416 N_("empty hierarchies prior to extracting directory"), GRID
+1 },
417 {"no-overwrite-dir", NO_OVERWRITE_DIR_OPTION
, 0, 0,
418 N_("preserve metadata of existing directories"), GRID
+1 },
423 N_("Select output stream:"), GRID
},
425 {"to-stdout", 'O', 0, 0,
426 N_("extract files to standard output"), GRID
+1 },
427 {"to-command", TO_COMMAND_OPTION
, N_("COMMAND"), 0,
428 N_("pipe extracted files to another program"), GRID
+1 },
429 {"ignore-command-error", IGNORE_COMMAND_ERROR_OPTION
, 0, 0,
430 N_("ignore exit codes of children"), GRID
+1 },
431 {"no-ignore-command-error", NO_IGNORE_COMMAND_ERROR_OPTION
, 0, 0,
432 N_("treat non-zero exit codes of children as error"), GRID
+1 },
437 N_("Handling of file attributes:"), GRID
},
439 {"owner", OWNER_OPTION
, N_("NAME"), 0,
440 N_("force NAME as owner for added files"), GRID
+1 },
441 {"group", GROUP_OPTION
, N_("NAME"), 0,
442 N_("force NAME as group for added files"), GRID
+1 },
443 {"mode", MODE_OPTION
, N_("CHANGES"), 0,
444 N_("force (symbolic) mode CHANGES for added files"), GRID
+1 },
445 {"atime-preserve", ATIME_PRESERVE_OPTION
,
446 N_("METHOD"), OPTION_ARG_OPTIONAL
,
447 N_("preserve access times on dumped files, either by restoring the times"
448 " after reading (METHOD='replace'; default) or by not setting the times"
449 " in the first place (METHOD='system')"), GRID
+1 },
451 N_("don't extract file modified time"), GRID
+1 },
452 {"same-owner", SAME_OWNER_OPTION
, 0, 0,
453 N_("try extracting files with the same ownership"), GRID
+1 },
454 {"no-same-owner", NO_SAME_OWNER_OPTION
, 0, 0,
455 N_("extract files as yourself"), GRID
+1 },
456 {"numeric-owner", NUMERIC_OWNER_OPTION
, 0, 0,
457 N_("always use numbers for user/group names"), GRID
+1 },
458 {"preserve-permissions", 'p', 0, 0,
459 N_("extract information about file permissions (default for superuser)"),
461 {"same-permissions", 0, 0, OPTION_ALIAS
, NULL
, GRID
+1 },
462 {"no-same-permissions", NO_SAME_PERMISSIONS_OPTION
, 0, 0,
463 N_("apply the user's umask when extracting permissions from the archive (default for ordinary users)"), GRID
+1 },
464 {"preserve-order", 's', 0, 0,
465 N_("sort names to extract to match archive"), GRID
+1 },
466 {"same-order", 0, 0, OPTION_ALIAS
, NULL
, GRID
+1 },
467 {"preserve", PRESERVE_OPTION
, 0, 0,
468 N_("same as both -p and -s"), GRID
+1 },
469 {"delay-directory-restore", DELAY_DIRECTORY_RESTORE_OPTION
, 0, 0,
470 N_("delay setting modification times and permissions of extracted"
471 " directories until the end of extraction"), GRID
+1 },
472 {"no-delay-directory-restore", NO_DELAY_DIRECTORY_RESTORE_OPTION
, 0, 0,
473 N_("cancel the effect of --delay-directory-restore option"), GRID
+1 },
478 N_("Device selection and switching:\n"), GRID
+1 },
480 {"file", 'f', N_("ARCHIVE"), 0,
481 N_("use archive file or device ARCHIVE"), GRID
+1 },
482 {"force-local", FORCE_LOCAL_OPTION
, 0, 0,
483 N_("archive file is local even if it has a colon"), GRID
+1 },
484 {"rmt-command", RMT_COMMAND_OPTION
, N_("COMMAND"), 0,
485 N_("use given rmt COMMAND instead of rmt"), GRID
+1 },
486 {"rsh-command", RSH_COMMAND_OPTION
, N_("COMMAND"), 0,
487 N_("use remote COMMAND instead of rsh"), GRID
+1 },
489 {"-[0-7][lmh]", 0, NULL
, OPTION_DOC
, /* It is OK, since `name' will never be
491 N_("specify drive and density"), GRID
+1 },
493 {NULL
, '0', NULL
, OPTION_HIDDEN
, NULL
, GRID
+1 },
494 {NULL
, '1', NULL
, OPTION_HIDDEN
, NULL
, GRID
+1 },
495 {NULL
, '2', NULL
, OPTION_HIDDEN
, NULL
, GRID
+1 },
496 {NULL
, '3', NULL
, OPTION_HIDDEN
, NULL
, GRID
+1 },
497 {NULL
, '4', NULL
, OPTION_HIDDEN
, NULL
, GRID
+1 },
498 {NULL
, '5', NULL
, OPTION_HIDDEN
, NULL
, GRID
+1 },
499 {NULL
, '6', NULL
, OPTION_HIDDEN
, NULL
, GRID
+1 },
500 {NULL
, '7', NULL
, OPTION_HIDDEN
, NULL
, GRID
+1 },
501 {NULL
, '8', NULL
, OPTION_HIDDEN
, NULL
, GRID
+1 },
502 {NULL
, '9', NULL
, OPTION_HIDDEN
, NULL
, GRID
+1 },
504 {"multi-volume", 'M', 0, 0,
505 N_("create/list/extract multi-volume archive"), GRID
+1 },
506 {"tape-length", 'L', N_("NUMBER"), 0,
507 N_("change tape after writing NUMBER x 1024 bytes"), GRID
+1 },
508 {"info-script", 'F', N_("NAME"), 0,
509 N_("run script at end of each tape (implies -M)"), GRID
+1 },
510 {"new-volume-script", 0, 0, OPTION_ALIAS
, NULL
, GRID
+1 },
511 {"volno-file", VOLNO_FILE_OPTION
, N_("FILE"), 0,
512 N_("use/update the volume number in FILE"), GRID
+1 },
517 N_("Device blocking:"), GRID
+1 },
519 {"blocking-factor", 'b', N_("BLOCKS"), 0,
520 N_("BLOCKS x 512 bytes per record"), GRID
+1 },
521 {"record-size", RECORD_SIZE_OPTION
, N_("NUMBER"), 0,
522 N_("NUMBER of bytes per record, multiple of 512"), GRID
+1 },
523 {"ignore-zeros", 'i', 0, 0,
524 N_("ignore zeroed blocks in archive (means EOF)"), GRID
+1 },
525 {"read-full-records", 'B', 0, 0,
526 N_("reblock as we read (for 4.2BSD pipes)"), GRID
+1 },
531 N_("Archive format selection:"), GRID
},
533 {"format", 'H', N_("FORMAT"), 0,
534 N_("create archive of the given format"), GRID
+1 },
536 {NULL
, 0, NULL
, 0, N_("FORMAT is one of the following:"), GRID
+2 },
537 {" v7", 0, NULL
, OPTION_DOC
|OPTION_NO_TRANS
, N_("old V7 tar format"),
539 {" oldgnu", 0, NULL
, OPTION_DOC
|OPTION_NO_TRANS
,
540 N_("GNU format as per tar <= 1.12"), GRID
+3 },
541 {" gnu", 0, NULL
, OPTION_DOC
|OPTION_NO_TRANS
,
542 N_("GNU tar 1.13.x format"), GRID
+3 },
543 {" ustar", 0, NULL
, OPTION_DOC
|OPTION_NO_TRANS
,
544 N_("POSIX 1003.1-1988 (ustar) format"), GRID
+3 },
545 {" pax", 0, NULL
, OPTION_DOC
|OPTION_NO_TRANS
,
546 N_("POSIX 1003.1-2001 (pax) format"), GRID
+3 },
547 {" posix", 0, NULL
, OPTION_DOC
|OPTION_NO_TRANS
, N_("same as pax"), GRID
+3 },
549 {"old-archive", OLD_ARCHIVE_OPTION
, 0, 0, /* FIXME */
550 N_("same as --format=v7"), GRID
+8 },
551 {"portability", 0, 0, OPTION_ALIAS
, NULL
, GRID
+8 },
552 {"posix", POSIX_OPTION
, 0, 0,
553 N_("same as --format=posix"), GRID
+8 },
554 {"pax-option", PAX_OPTION
, N_("keyword[[:]=value][,keyword[[:]=value]]..."), 0,
555 N_("control pax keywords"), GRID
+8 },
556 {"label", 'V', N_("TEXT"), 0,
557 N_("create archive with volume name TEXT; at list/extract time, use TEXT as a globbing pattern for volume name"), GRID
+8 },
559 N_("filter the archive through bzip2"), GRID
+8 },
561 N_("filter the archive through gzip"), GRID
+8 },
562 {"gunzip", 0, 0, OPTION_ALIAS
, NULL
, GRID
+8 },
563 {"ungzip", 0, 0, OPTION_ALIAS
, NULL
, GRID
+8 },
564 {"compress", 'Z', 0, 0,
565 N_("filter the archive through compress"), GRID
+8 },
566 {"uncompress", 0, 0, OPTION_ALIAS
, NULL
, GRID
+8 },
567 {"use-compress-program", USE_COMPRESS_PROGRAM_OPTION
, N_("PROG"), 0,
568 N_("filter through PROG (must accept -d)"), GRID
+8 },
573 N_("Local file selection:"), GRID
},
575 {"add-file", ARGP_KEY_ARG
, N_("FILE"), 0,
576 N_("add given FILE to the archive (useful if its name starts with a dash)"), GRID
+1 },
577 {"directory", 'C', N_("DIR"), 0,
578 N_("change to directory DIR"), GRID
+1 },
579 {"files-from", 'T', N_("FILE"), 0,
580 N_("get names to extract or create from FILE"), GRID
+1 },
581 {"null", NULL_OPTION
, 0, 0,
582 N_("-T reads null-terminated names, disable -C"), GRID
+1 },
583 {"unquote", UNQUOTE_OPTION
, 0, 0,
584 N_("unquote filenames read with -T (default)"), GRID
+1 },
585 {"no-unquote", NO_UNQUOTE_OPTION
, 0, 0,
586 N_("do not unquote filenames read with -T"), GRID
+1 },
587 {"exclude", EXCLUDE_OPTION
, N_("PATTERN"), 0,
588 N_("exclude files, given as a PATTERN"), GRID
+1 },
589 {"exclude-from", 'X', N_("FILE"), 0,
590 N_("exclude patterns listed in FILE"), GRID
+1 },
591 {"exclude-caches", EXCLUDE_CACHES_OPTION
, 0, 0,
592 N_("exclude directories containing a cache tag"), GRID
+1 },
593 {"no-recursion", NO_RECURSION_OPTION
, 0, 0,
594 N_("avoid descending automatically in directories"), GRID
+1 },
595 {"one-file-system", ONE_FILE_SYSTEM_OPTION
, 0, 0,
596 N_("stay in local file system when creating archive"), GRID
+1 },
597 {"recursion", RECURSION_OPTION
, 0, 0,
598 N_("recurse into directories (default)"), GRID
+1 },
599 {"absolute-names", 'P', 0, 0,
600 N_("don't strip leading `/'s from file names"), GRID
+1 },
601 {"dereference", 'h', 0, 0,
602 N_("follow symlinks; archive and dump the files they point to"), GRID
+1 },
603 {"starting-file", 'K', N_("MEMBER-NAME"), 0,
604 N_("begin at member MEMBER-NAME in the archive"), GRID
+1 },
605 {"newer", 'N', N_("DATE-OR-FILE"), 0,
606 N_("only store files newer than DATE-OR-FILE"), GRID
+1 },
607 {"newer-mtime", NEWER_MTIME_OPTION
, N_("DATE"), 0,
608 N_("compare date and time when data changed only"), GRID
+1 },
609 {"after-date", 'N', N_("DATE"), 0,
610 N_("same as -N"), GRID
+1 },
611 {"backup", BACKUP_OPTION
, N_("CONTROL"), OPTION_ARG_OPTIONAL
,
612 N_("backup before removal, choose version CONTROL"), GRID
+1 },
613 {"suffix", SUFFIX_OPTION
, N_("STRING"), 0,
614 N_("backup before removal, override usual suffix ('~' unless overridden by environment variable SIMPLE_BACKUP_SUFFIX)"), GRID
+1 },
619 N_("File name transformations:"), GRID
},
620 {"strip-components", STRIP_COMPONENTS_OPTION
, N_("NUMBER"), 0,
621 N_("strip NUMBER leading components from file names on extraction"),
623 {"transform", TRANSFORM_OPTION
, N_("EXPRESSION"), 0,
624 N_("Use sed replace EXPRESSION to transform file names"), GRID
+1 },
629 N_("File name matching options (affect both exclude and include patterns):"),
631 {"ignore-case", IGNORE_CASE_OPTION
, 0, 0,
632 N_("ignore case"), GRID
+1 },
633 {"anchored", ANCHORED_OPTION
, 0, 0,
634 N_("patterns match file name start"), GRID
+1 },
635 {"no-anchored", NO_ANCHORED_OPTION
, 0, 0,
636 N_("patterns match after any `/' (default for exclusion)"), GRID
+1 },
637 {"no-ignore-case", NO_IGNORE_CASE_OPTION
, 0, 0,
638 N_("case sensitive matching (default)"), GRID
+1 },
639 {"wildcards", WILDCARDS_OPTION
, 0, 0,
640 N_("use wildcards (default for exclusion)"), GRID
+1 },
641 {"no-wildcards", NO_WILDCARDS_OPTION
, 0, 0,
642 N_("verbatim string matching"), GRID
+1 },
643 {"no-wildcards-match-slash", NO_WILDCARDS_MATCH_SLASH_OPTION
, 0, 0,
644 N_("wildcards do not match `/'"), GRID
+1 },
645 {"wildcards-match-slash", WILDCARDS_MATCH_SLASH_OPTION
, 0, 0,
646 N_("wildcards match `/' (default for exclusion)"), GRID
+1 },
651 N_("Informative output:"), GRID
},
653 {"verbose", 'v', 0, 0,
654 N_("verbosely list files processed"), GRID
+1 },
655 {"checkpoint", CHECKPOINT_OPTION
, N_("[.]NUMBER"), OPTION_ARG_OPTIONAL
,
656 N_("display progress messages every NUMBERth record (default 10)"),
658 {"check-links", 'l', 0, 0,
659 N_("print a message if not all links are dumped"), GRID
+1 },
660 {"totals", TOTALS_OPTION
, 0, 0,
661 N_("print total bytes written while creating archive"), GRID
+1 },
662 {"utc", UTC_OPTION
, 0, 0,
663 N_("print file modification dates in UTC"), GRID
+1 },
664 {"index-file", INDEX_FILE_OPTION
, N_("FILE"), 0,
665 N_("send verbose output to FILE"), GRID
+1 },
666 {"block-number", 'R', 0, 0,
667 N_("show block number within archive with each message"), GRID
+1 },
668 {"interactive", 'w', 0, 0,
669 N_("ask for confirmation for every action"), GRID
+1 },
670 {"confirmation", 0, 0, OPTION_ALIAS
, NULL
, GRID
+1 },
671 {"show-defaults", SHOW_DEFAULTS_OPTION
, 0, 0,
672 N_("show tar defaults"), GRID
+1 },
673 {"show-omitted-dirs", SHOW_OMITTED_DIRS_OPTION
, 0, 0,
674 N_("when listing or extracting, list each directory that does not match search criteria"), GRID
+1 },
675 {"show-transformed-names", SHOW_TRANSFORMED_NAMES_OPTION
, 0, 0,
676 N_("show file or archive names after transformation"),
678 {"show-stored-names", 0, 0, OPTION_ALIAS
, NULL
, GRID
+1 },
679 {"quoting-style", QUOTING_STYLE_OPTION
, N_("STYLE"), 0,
680 N_("set name quoting style; see below for valid STYLE values"), GRID
+1 },
681 {"quote-chars", QUOTE_CHARS_OPTION
, N_("STRING"), 0,
682 N_("additionally quote characters from STRING"), GRID
+1 },
683 {"no-quote-chars", NO_QUOTE_CHARS_OPTION
, N_("STRING"), 0,
684 N_("disable quoting for characters from STRING"), GRID
+1 },
689 N_("Compatibility options:"), GRID
},
692 N_("when creating, same as --old-archive; when extracting, same as --no-same-owner"), GRID
+1 },
697 N_("Other options:"), GRID
},
699 {"restrict", RESTRICT_OPTION
, 0, 0,
700 N_("disable use of some potentially harmful options"), -1 },
702 {"help", '?', 0, 0, N_("give this help list"), -1},
703 {"usage", USAGE_OPTION
, 0, 0, N_("give a short usage message"), -1},
704 {"version", VERSION_OPTION
, 0, 0, N_("print program version"), -1},
705 /* FIXME -V (--label) conflicts with the default short option for
707 {"HANG", HANG_OPTION
, "SECS", OPTION_ARG_OPTIONAL
| OPTION_HIDDEN
,
708 N_("hang for SECS seconds (default 3600)"), 0},
714 static char const *const atime_preserve_args
[] =
716 "replace", "system", NULL
719 static enum atime_preserve
const atime_preserve_types
[] =
721 replace_atime_preserve
, system_atime_preserve
724 /* Make sure atime_preserve_types has as much entries as atime_preserve_args
725 (minus 1 for NULL guard) */
726 ARGMATCH_VERIFY (atime_preserve_args
, atime_preserve_types
);
728 /* Wildcard matching settings */
731 default_wildcards
, /* For exclusion == enable_wildcards,
732 for inclusion == disable_wildcards */
737 struct tar_args
/* Variables used during option parsing */
739 char const *textual_date_option
; /* Keeps the argument to --newer-mtime
740 option if it represents a textual date */
741 enum wildcards wildcards
; /* Wildcard settings (--wildcards/
743 int matching_flags
; /* exclude_fnmatch options */
744 int include_anchored
; /* Pattern anchoring options used for
746 bool o_option
; /* True if -o option was given */
747 bool pax_option
; /* True if --pax-option was given */
748 char const *backup_suffix_string
; /* --suffix option argument */
749 char const *version_control_string
; /* --backup option argument */
750 bool input_files
; /* True if some input files where given */
753 #define MAKE_EXCL_OPTIONS(args) \
754 ((((args)->wildcards != disable_wildcards) ? EXCLUDE_WILDCARDS : 0) \
755 | (args)->matching_flags \
758 #define MAKE_INCL_OPTIONS(args) \
759 ((((args)->wildcards == enable_wildcards) ? EXCLUDE_WILDCARDS : 0) \
760 | (args)->include_anchored \
761 | (args)->matching_flags \
765 # define DECL_SHOW_DEFAULT_SETTINGS(stream, printer) \
768 "--format=%s -f%s -b%d --quoting-style=%s --rmt-command=%s", \
769 archive_format_string (DEFAULT_ARCHIVE_FORMAT), \
770 DEFAULT_ARCHIVE, DEFAULT_BLOCKING, \
771 quoting_style_args[DEFAULT_QUOTING_STYLE], \
772 DEFAULT_RMT_COMMAND); \
773 printer (stream, " --rsh-command=%s", REMOTE_SHELL); \
774 printer (stream, "\n"); \
777 # define DECL_SHOW_DEFAULT_SETTINGS(stream, printer) \
780 "--format=%s -f%s -b%d --quoting-style=%s --rmt-command=%s", \
781 archive_format_string (DEFAULT_ARCHIVE_FORMAT), \
782 DEFAULT_ARCHIVE, DEFAULT_BLOCKING, \
783 quoting_style_args[DEFAULT_QUOTING_STYLE], \
784 DEFAULT_RMT_COMMAND); \
785 printer (stream, "\n"); \
790 show_default_settings (FILE *fp
)
791 DECL_SHOW_DEFAULT_SETTINGS(fp
, fprintf
)
794 show_default_settings_fs (argp_fmtstream_t fs
)
795 DECL_SHOW_DEFAULT_SETTINGS(fs
, argp_fmtstream_printf
)
798 set_subcommand_option (enum subcommand subcommand
)
800 if (subcommand_option
!= UNKNOWN_SUBCOMMAND
801 && subcommand_option
!= subcommand
)
803 _("You may not specify more than one `-Acdtrux' option")));
805 subcommand_option
= subcommand
;
809 set_use_compress_program_option (const char *string
)
811 if (use_compress_program_option
812 && strcmp (use_compress_program_option
, string
) != 0)
813 USAGE_ERROR ((0, 0, _("Conflicting compression options")));
815 use_compress_program_option
= string
;
818 static volatile int _argp_hang
;
820 enum read_file_list_state
/* Result of reading file name from the list file */
822 file_list_success
, /* OK, name read successfully */
823 file_list_end
, /* End of list file */
824 file_list_zero
/* Zero separator encountered where it should not */
827 /* Read from FP a sequence of characters up to FILENAME_TERMINATOR and put them
830 static enum read_file_list_state
831 read_name_from_file (FILE *fp
, struct obstack
*stk
)
836 for (c
= getc (fp
); c
!= EOF
&& c
!= filename_terminator
; c
= getc (fp
))
840 /* We have read a zero separator. The file possibly is
842 /* FATAL_ERROR((0, 0, N_("file name contains null character"))); */
843 return file_list_zero
;
845 obstack_1grow (stk
, c
);
849 obstack_1grow (stk
, 0);
851 return (counter
== 0 && c
== EOF
) ? file_list_end
: file_list_success
;
855 static bool files_from_option
; /* When set, tar will not refuse to create
857 static struct obstack argv_stk
; /* Storage for additional command line options
858 read using -T option */
860 /* Prevent recursive inclusion of the same file */
863 struct file_id_list
*next
;
868 static struct file_id_list
*file_id_list
;
871 add_file_id (const char *filename
)
873 struct file_id_list
*p
;
876 if (stat (filename
, &st
))
877 stat_fatal (filename
);
878 for (p
= file_id_list
; p
; p
= p
->next
)
879 if (p
->ino
== st
.st_ino
&& p
->dev
== st
.st_dev
)
881 FATAL_ERROR ((0, 0, _("%s: file list already read"),
882 quotearg_colon (filename
)));
884 p
= xmalloc (sizeof *p
);
885 p
->next
= file_id_list
;
891 /* Default density numbers for [0-9][lmh] device specifications */
893 #ifndef LOW_DENSITY_NUM
894 # define LOW_DENSITY_NUM 0
897 #ifndef MID_DENSITY_NUM
898 # define MID_DENSITY_NUM 8
901 #ifndef HIGH_DENSITY_NUM
902 # define HIGH_DENSITY_NUM 16
906 update_argv (const char *filename
, struct argp_state
*state
)
913 bool is_stdin
= false;
914 enum read_file_list_state read_state
;
916 if (!strcmp (filename
, "-"))
919 request_stdin ("-T");
924 add_file_id (filename
);
925 if ((fp
= fopen (filename
, "r")) == NULL
)
926 open_fatal (filename
);
929 while ((read_state
= read_name_from_file (fp
, &argv_stk
)) == file_list_success
)
932 if (read_state
== file_list_zero
)
936 WARN ((0, 0, N_("%s: file name read contains nul character"),
937 quotearg_colon (filename
)));
939 /* Prepare new stack contents */
940 size
= obstack_object_size (&argv_stk
);
941 p
= obstack_finish (&argv_stk
);
942 for (; size
> 0; size
--, p
++)
944 obstack_1grow (&argv_stk
, *p
);
946 obstack_1grow (&argv_stk
, '\n');
947 obstack_1grow (&argv_stk
, 0);
950 /* Read rest of files using new filename terminator */
951 filename_terminator
= 0;
952 while (read_name_from_file (fp
, &argv_stk
) == file_list_success
)
962 start
= obstack_finish (&argv_stk
);
964 if (filename_terminator
== 0)
965 for (p
= start
; *p
; p
+= strlen (p
) + 1)
969 new_argc
= state
->argc
+ count
;
970 new_argv
= xmalloc (sizeof (state
->argv
[0]) * (new_argc
+ 1));
971 memcpy (new_argv
, state
->argv
, sizeof (state
->argv
[0]) * (state
->argc
+ 1));
972 state
->argv
= new_argv
;
973 memmove (&state
->argv
[state
->next
+ count
], &state
->argv
[state
->next
],
974 (state
->argc
- state
->next
+ 1) * sizeof (state
->argv
[0]));
976 state
->argc
= new_argc
;
978 for (i
= state
->next
, p
= start
; *p
; p
+= strlen (p
) + 1, i
++)
980 if (filename_terminator
== 0 && p
[0] == '-')
981 state
->argv
[i
++] = "--add-file";
988 tar_help (struct argp_state
*state
)
991 state
->flags
|= ARGP_NO_EXIT
;
992 argp_state_help (state
, state
->out_stream
,
993 ARGP_HELP_STD_HELP
& ~ARGP_HELP_BUG_ADDR
);
994 /* FIXME: use struct uparams.rmargin (from argp-help.c) instead of 79 */
995 fs
= argp_make_fmtstream (state
->out_stream
, 0, 79, 0);
997 argp_fmtstream_printf (fs
, "\n%s\n\n",
998 _("Valid arguments for --quoting-style options are:"));
999 tar_list_quoting_styles (fs
, " ");
1001 argp_fmtstream_puts (fs
, _("\n*This* tar defaults to:\n"));
1002 show_default_settings_fs (fs
);
1003 argp_fmtstream_putc (fs
, '\n');
1004 argp_fmtstream_printf (fs
, _("Report bugs to %s.\n"),
1005 argp_program_bug_address
);
1006 argp_fmtstream_free (fs
);
1010 parse_opt (int key
, char *arg
, struct argp_state
*state
)
1012 struct tar_args
*args
= state
->input
;
1017 /* File name or non-parsed option, because of ARGP_IN_ORDER */
1018 name_add_name (arg
, MAKE_INCL_OPTIONS (args
));
1019 args
->input_files
= true;
1023 set_subcommand_option (CAT_SUBCOMMAND
);
1029 if (! (xstrtoumax (arg
, 0, 10, &u
, "") == LONGINT_OK
1030 && u
== (blocking_factor
= u
)
1031 && 0 < blocking_factor
1032 && u
== (record_size
= u
* BLOCKSIZE
) / BLOCKSIZE
))
1033 USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (arg
),
1034 _("Invalid blocking factor")));
1039 /* Try to reblock input records. For reading 4.2BSD pipes. */
1041 /* It would surely make sense to exchange -B and -R, but it seems
1042 that -B has been used for a long while in Sun tar and most
1043 BSD-derived systems. This is a consequence of the block/record
1044 terminology confusion. */
1046 read_full_records_option
= true;
1050 set_subcommand_option (CREATE_SUBCOMMAND
);
1058 set_subcommand_option (DIFF_SUBCOMMAND
);
1062 if (archive_names
== allocated_archive_names
)
1063 archive_name_array
= x2nrealloc (archive_name_array
,
1064 &allocated_archive_names
,
1065 sizeof (archive_name_array
[0]));
1067 archive_name_array
[archive_names
++] = arg
;
1071 /* Since -F is only useful with -M, make it implied. Run this
1072 script at the end of each tape. */
1074 info_script_option
= arg
;
1075 multi_volume_option
= true;
1079 listed_incremental_option
= arg
;
1080 after_date_option
= true;
1084 /* We are making an incremental dump (FIXME: are we?); save
1085 directories at the beginning of the archive, and include in each
1086 directory its contents. */
1088 incremental_option
= true;
1092 /* Follow symbolic links. */
1093 dereference_option
= true;
1097 /* Ignore zero blocks (eofs). This can't be the default,
1098 because Unix tar writes two blocks of zeros, then pads out
1099 the record with garbage. */
1101 ignore_zeros_option
= true;
1106 _("Warning: the -I option is not supported;"
1107 " perhaps you meant -j or -T?")));
1111 set_use_compress_program_option ("bzip2");
1115 /* Don't replace existing files. */
1116 old_files_option
= KEEP_OLD_FILES
;
1120 starting_file_option
= true;
1124 case ONE_FILE_SYSTEM_OPTION
:
1125 /* When dumping directories, don't dump files/subdirectories
1126 that are on other filesystems. */
1127 one_file_system_option
= true;
1131 check_links_option
= 1;
1137 if (xstrtoumax (arg
, 0, 10, &u
, "") != LONGINT_OK
)
1138 USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (arg
),
1139 _("Invalid tape length")));
1140 tape_length_option
= 1024 * (tarlong
) u
;
1141 multi_volume_option
= true;
1146 touch_option
= true;
1150 /* Make multivolume archive: when we can't write any more into
1151 the archive, re-open it, and continue writing. */
1153 multi_volume_option
= true;
1157 seekable_archive
= true;
1161 after_date_option
= true;
1164 case NEWER_MTIME_OPTION
:
1165 if (NEWER_OPTION_INITIALIZED (newer_mtime_option
))
1166 USAGE_ERROR ((0, 0, _("More than one threshold date")));
1168 if (FILE_SYSTEM_PREFIX_LEN (arg
) != 0
1173 if (deref_stat (dereference_option
, arg
, &st
) != 0)
1176 USAGE_ERROR ((0, 0, _("Date sample file not found")));
1178 newer_mtime_option
= get_stat_mtime (&st
);
1182 if (! get_date (&newer_mtime_option
, arg
, NULL
))
1184 WARN ((0, 0, _("Substituting %s for unknown date format %s"),
1185 tartime (newer_mtime_option
, false), quote (arg
)));
1186 newer_mtime_option
.tv_nsec
= 0;
1189 args
->textual_date_option
= arg
;
1195 args
->o_option
= true;
1199 to_stdout_option
= true;
1203 same_permissions_option
= true;
1207 absolute_names_option
= true;
1211 set_subcommand_option (APPEND_SUBCOMMAND
);
1215 /* Print block numbers for debugging bad tar archives. */
1217 /* It would surely make sense to exchange -B and -R, but it seems
1218 that -B has been used for a long while in Sun tar ans most
1219 BSD-derived systems. This is a consequence of the block/record
1220 terminology confusion. */
1222 block_number_option
= true;
1226 /* Names to extr are sorted. */
1228 same_order_option
= true;
1232 sparse_option
= true;
1236 set_subcommand_option (LIST_SUBCOMMAND
);
1240 case TEST_LABEL_OPTION
:
1241 set_subcommand_option (LIST_SUBCOMMAND
);
1242 test_label_option
= true;
1246 update_argv (arg
, state
);
1247 /* Indicate we've been given -T option. This is for backward
1248 compatibility only, so that `tar cfT archive /dev/null will
1250 files_from_option
= true;
1254 set_subcommand_option (UPDATE_SUBCOMMAND
);
1258 old_files_option
= UNLINK_FIRST_OLD_FILES
;
1270 volume_label_option
= arg
;
1274 interactive_option
= true;
1278 verify_option
= true;
1282 set_subcommand_option (EXTRACT_SUBCOMMAND
);
1286 if (add_exclude_file (add_exclude
, excluded
, arg
,
1287 MAKE_EXCL_OPTIONS (args
), '\n')
1291 FATAL_ERROR ((0, e
, "%s", quotearg_colon (arg
)));
1296 set_use_compress_program_option ("gzip");
1300 set_use_compress_program_option ("compress");
1303 case ANCHORED_OPTION
:
1304 args
->matching_flags
|= EXCLUDE_ANCHORED
;
1307 case ATIME_PRESERVE_OPTION
:
1308 atime_preserve_option
=
1310 ? XARGMATCH ("--atime-preserve", arg
,
1311 atime_preserve_args
, atime_preserve_types
)
1312 : replace_atime_preserve
);
1313 if (! O_NOATIME
&& atime_preserve_option
== system_atime_preserve
)
1315 _("--atime-preserve='system' is not supported"
1316 " on this platform")));
1319 case CHECKPOINT_OPTION
:
1326 checkpoint_style
= checkpoint_dot
;
1329 checkpoint_option
= strtoul (arg
, &p
, 0);
1332 _("--checkpoint value is not an integer")));
1335 checkpoint_option
= 10;
1339 backup_option
= true;
1341 args
->version_control_string
= arg
;
1344 case DELAY_DIRECTORY_RESTORE_OPTION
:
1345 delay_directory_restore_option
= true;
1348 case NO_DELAY_DIRECTORY_RESTORE_OPTION
:
1349 delay_directory_restore_option
= false;
1353 set_subcommand_option (DELETE_SUBCOMMAND
);
1356 case EXCLUDE_OPTION
:
1357 add_exclude (excluded
, arg
, MAKE_EXCL_OPTIONS (args
));
1360 case EXCLUDE_CACHES_OPTION
:
1361 exclude_caches_option
= true;
1364 case FORCE_LOCAL_OPTION
:
1365 force_local_option
= true;
1369 set_archive_format (arg
);
1372 case INDEX_FILE_OPTION
:
1373 index_file_name
= arg
;
1376 case IGNORE_CASE_OPTION
:
1377 args
->matching_flags
|= FNM_CASEFOLD
;
1380 case IGNORE_COMMAND_ERROR_OPTION
:
1381 ignore_command_error_option
= true;
1384 case IGNORE_FAILED_READ_OPTION
:
1385 ignore_failed_read_option
= true;
1388 case KEEP_NEWER_FILES_OPTION
:
1389 old_files_option
= KEEP_NEWER_FILES
;
1393 if (! (strlen (arg
) < GNAME_FIELD_SIZE
1394 && gname_to_gid (arg
, &group_option
)))
1397 if (xstrtoumax (arg
, 0, 10, &g
, "") == LONGINT_OK
1401 FATAL_ERROR ((0, 0, "%s: %s", quotearg_colon (arg
),
1402 _("%s: Invalid group")));
1407 mode_option
= mode_compile (arg
);
1409 FATAL_ERROR ((0, 0, _("Invalid mode given on option")));
1410 initial_umask
= umask (0);
1411 umask (initial_umask
);
1414 case NO_ANCHORED_OPTION
:
1415 args
->include_anchored
= 0; /* Clear the default for comman line args */
1416 args
->matching_flags
&= ~ EXCLUDE_ANCHORED
;
1419 case NO_IGNORE_CASE_OPTION
:
1420 args
->matching_flags
&= ~ FNM_CASEFOLD
;
1423 case NO_IGNORE_COMMAND_ERROR_OPTION
:
1424 ignore_command_error_option
= false;
1427 case NO_OVERWRITE_DIR_OPTION
:
1428 old_files_option
= NO_OVERWRITE_DIR_OLD_FILES
;
1431 case NO_QUOTE_CHARS_OPTION
:
1433 set_char_quoting (NULL
, *arg
, 0);
1436 case NO_WILDCARDS_OPTION
:
1437 args
->wildcards
= disable_wildcards
;
1440 case NO_WILDCARDS_MATCH_SLASH_OPTION
:
1441 args
->matching_flags
|= FNM_FILE_NAME
;
1445 filename_terminator
= '\0';
1448 case NUMERIC_OWNER_OPTION
:
1449 numeric_owner_option
= true;
1452 case OCCURRENCE_OPTION
:
1454 occurrence_option
= 1;
1458 if (xstrtoumax (arg
, 0, 10, &u
, "") == LONGINT_OK
)
1459 occurrence_option
= u
;
1461 FATAL_ERROR ((0, 0, "%s: %s", quotearg_colon (arg
),
1462 _("Invalid number")));
1466 case OVERWRITE_OPTION
:
1467 old_files_option
= OVERWRITE_OLD_FILES
;
1471 if (! (strlen (arg
) < UNAME_FIELD_SIZE
1472 && uname_to_uid (arg
, &owner_option
)))
1475 if (xstrtoumax (arg
, 0, 10, &u
, "") == LONGINT_OK
1479 FATAL_ERROR ((0, 0, "%s: %s", quotearg_colon (arg
),
1480 _("Invalid owner")));
1484 case QUOTE_CHARS_OPTION
:
1486 set_char_quoting (NULL
, *arg
, 1);
1489 case QUOTING_STYLE_OPTION
:
1490 tar_set_quoting_style (arg
);
1494 args
->pax_option
= true;
1495 xheader_set_option (arg
);
1499 set_archive_format ("posix");
1502 case PRESERVE_OPTION
:
1503 /* FIXME: What it is good for? */
1504 same_permissions_option
= true;
1505 same_order_option
= true;
1508 case RECORD_SIZE_OPTION
:
1511 if (! (xstrtoumax (arg
, 0, 10, &u
, "") == LONGINT_OK
1512 && u
== (size_t) u
))
1513 USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (arg
),
1514 _("Invalid record size")));
1516 if (record_size
% BLOCKSIZE
!= 0)
1517 USAGE_ERROR ((0, 0, _("Record size must be a multiple of %d."),
1519 blocking_factor
= record_size
/ BLOCKSIZE
;
1523 case RECURSIVE_UNLINK_OPTION
:
1524 recursive_unlink_option
= true;
1527 case REMOVE_FILES_OPTION
:
1528 remove_files_option
= true;
1531 case RESTRICT_OPTION
:
1532 restrict_option
= true;
1535 case RMT_COMMAND_OPTION
:
1539 case RSH_COMMAND_OPTION
:
1540 rsh_command_option
= arg
;
1543 case SHOW_DEFAULTS_OPTION
:
1544 show_default_settings (stdout
);
1548 case STRIP_COMPONENTS_OPTION
:
1551 if (! (xstrtoumax (arg
, 0, 10, &u
, "") == LONGINT_OK
1552 && u
== (size_t) u
))
1553 USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (arg
),
1554 _("Invalid number of elements")));
1555 strip_name_components
= u
;
1559 case SHOW_OMITTED_DIRS_OPTION
:
1560 show_omitted_dirs_option
= true;
1563 case SHOW_TRANSFORMED_NAMES_OPTION
:
1564 show_transformed_names_option
= true;
1568 backup_option
= true;
1569 args
->backup_suffix_string
= arg
;
1572 case TO_COMMAND_OPTION
:
1573 if (to_command_option
)
1574 USAGE_ERROR ((0, 0, _("Only one --to-command option allowed")));
1575 to_command_option
= arg
;
1579 totals_option
= true;
1582 case TRANSFORM_OPTION
:
1583 set_transform_expr (arg
);
1586 case USE_COMPRESS_PROGRAM_OPTION
:
1587 set_use_compress_program_option (arg
);
1590 case VOLNO_FILE_OPTION
:
1591 volno_file_option
= arg
;
1594 case WILDCARDS_OPTION
:
1595 args
->wildcards
= enable_wildcards
;
1598 case WILDCARDS_MATCH_SLASH_OPTION
:
1599 args
->matching_flags
&= ~ FNM_FILE_NAME
;
1602 case NO_RECURSION_OPTION
:
1603 recursion_option
= 0;
1606 case NO_SAME_OWNER_OPTION
:
1607 same_owner_option
= -1;
1610 case NO_SAME_PERMISSIONS_OPTION
:
1611 same_permissions_option
= -1;
1614 case RECURSION_OPTION
:
1615 recursion_option
= FNM_LEADING_DIR
;
1618 case SAME_OWNER_OPTION
:
1619 same_owner_option
= 1;
1622 case UNQUOTE_OPTION
:
1623 unquote_option
= true;
1626 case NO_UNQUOTE_OPTION
:
1627 unquote_option
= false;
1639 #ifdef DEVICE_PREFIX
1641 int device
= key
- '0';
1643 static char buf
[sizeof DEVICE_PREFIX
+ 10];
1647 argp_error (state
, _("Malformed density argument: %s"), quote (arg
));
1649 strcpy (buf
, DEVICE_PREFIX
);
1650 cursor
= buf
+ strlen (buf
);
1652 #ifdef DENSITY_LETTER
1654 sprintf (cursor
, "%d%c", device
, arg
[0]);
1656 #else /* not DENSITY_LETTER */
1661 device
+= LOW_DENSITY_NUM
;
1665 device
+= MID_DENSITY_NUM
;
1669 device
+= HIGH_DENSITY_NUM
;
1673 argp_error (state
, _("Unknown density: `%c'"), arg
[0]);
1675 sprintf (cursor
, "%d", device
);
1677 #endif /* not DENSITY_LETTER */
1679 if (archive_names
== allocated_archive_names
)
1680 archive_name_array
= x2nrealloc (archive_name_array
,
1681 &allocated_archive_names
,
1682 sizeof (archive_name_array
[0]));
1683 archive_name_array
[archive_names
++] = xstrdup (buf
);
1687 #else /* not DEVICE_PREFIX */
1690 _("Options `-[0-7][lmh]' not supported by *this* tar"));
1692 #endif /* not DEVICE_PREFIX */
1700 argp_state_help (state
, state
->out_stream
, ARGP_HELP_USAGE
);
1704 case VERSION_OPTION
:
1705 version_etc (state
->out_stream
, "tar", PACKAGE_NAME
, VERSION
,
1706 "John Gilmore", "Jay Fenlason", (char *) NULL
);
1711 _argp_hang
= atoi (arg
? arg
: "3600");
1712 while (_argp_hang
-- > 0)
1717 return ARGP_ERR_UNKNOWN
;
1722 static struct argp argp
= {
1735 argp_help (&argp
, stderr
, ARGP_HELP_SEE
, (char*) program_name
);
1740 /* Parse the options for tar. */
1742 static struct argp_option
*
1743 find_argp_option (struct argp_option
*options
, int letter
)
1746 !(options
->name
== NULL
1747 && options
->key
== 0
1748 && options
->arg
== 0
1749 && options
->flags
== 0
1750 && options
->doc
== NULL
); options
++)
1751 if (options
->key
== letter
)
1757 decode_options (int argc
, char **argv
)
1760 struct tar_args args
;
1762 /* Set some default option values. */
1763 args
.textual_date_option
= NULL
;
1764 args
.wildcards
= default_wildcards
;
1765 args
.matching_flags
= 0;
1766 args
.include_anchored
= EXCLUDE_ANCHORED
;
1767 args
.o_option
= false;
1768 args
.pax_option
= false;
1769 args
.backup_suffix_string
= getenv ("SIMPLE_BACKUP_SUFFIX");
1770 args
.version_control_string
= 0;
1771 args
.input_files
= false;
1773 subcommand_option
= UNKNOWN_SUBCOMMAND
;
1774 archive_format
= DEFAULT_FORMAT
;
1775 blocking_factor
= DEFAULT_BLOCKING
;
1776 record_size
= DEFAULT_BLOCKING
* BLOCKSIZE
;
1777 excluded
= new_exclude ();
1778 newer_mtime_option
.tv_sec
= TYPE_MINIMUM (time_t);
1779 newer_mtime_option
.tv_nsec
= -1;
1780 recursion_option
= FNM_LEADING_DIR
;
1781 unquote_option
= true;
1786 /* Convert old-style tar call by exploding option element and rearranging
1787 options accordingly. */
1789 if (argc
> 1 && argv
[1][0] != '-')
1791 int new_argc
; /* argc value for rearranged arguments */
1792 char **new_argv
; /* argv value for rearranged arguments */
1793 char *const *in
; /* cursor into original argv */
1794 char **out
; /* cursor into rearranged argv */
1795 const char *letter
; /* cursor into old option letters */
1796 char buffer
[3]; /* constructed option buffer */
1798 /* Initialize a constructed option. */
1803 /* Allocate a new argument array, and copy program name in it. */
1805 new_argc
= argc
- 1 + strlen (argv
[1]);
1806 new_argv
= xmalloc ((new_argc
+ 1) * sizeof (char *));
1811 /* Copy each old letter option as a separate option, and have the
1812 corresponding argument moved next to it. */
1814 for (letter
= *in
++; *letter
; letter
++)
1816 struct argp_option
*opt
;
1818 buffer
[1] = *letter
;
1819 *out
++ = xstrdup (buffer
);
1820 opt
= find_argp_option (options
, *letter
);
1821 if (opt
&& opt
->arg
)
1823 if (in
< argv
+ argc
)
1826 USAGE_ERROR ((0, 0, _("Old option `%c' requires an argument."),
1831 /* Copy all remaining options. */
1833 while (in
< argv
+ argc
)
1837 /* Replace the old option list by the new one. */
1843 /* Parse all options and non-options as they appear. */
1845 prepend_default_options (getenv ("TAR_OPTIONS"), &argc
, &argv
);
1847 if (argp_parse (&argp
, argc
, argv
, ARGP_IN_ORDER
|ARGP_NO_HELP
,
1849 exit (TAREXIT_FAILURE
);
1852 /* Special handling for 'o' option:
1854 GNU tar used to say "output old format".
1855 UNIX98 tar says don't chown files after extracting (we use
1856 "--no-same-owner" for this).
1858 The old GNU tar semantics is retained when used with --create
1859 option, otherwise UNIX98 semantics is assumed */
1863 if (subcommand_option
== CREATE_SUBCOMMAND
)
1865 /* GNU Tar <= 1.13 compatibility */
1866 set_archive_format ("v7");
1870 /* UNIX98 compatibility */
1871 same_owner_option
= -1;
1875 /* Handle operands after any "--" argument. */
1876 for (; index
< argc
; index
++)
1878 name_add_name (argv
[index
], MAKE_INCL_OPTIONS (&args
));
1879 args
.input_files
= true;
1882 /* Warn about implicit use of the wildcards in command line arguments.
1884 warn_regex_usage
= args
.wildcards
== default_wildcards
;
1886 /* Derive option values and check option consistency. */
1888 if (archive_format
== DEFAULT_FORMAT
)
1890 if (args
.pax_option
)
1891 archive_format
= POSIX_FORMAT
;
1893 archive_format
= DEFAULT_ARCHIVE_FORMAT
;
1896 if ((volume_label_option
&& subcommand_option
== CREATE_SUBCOMMAND
)
1897 || incremental_option
1898 || multi_volume_option
1900 assert_format (FORMAT_MASK (OLDGNU_FORMAT
)
1901 | FORMAT_MASK (GNU_FORMAT
)
1902 | FORMAT_MASK (POSIX_FORMAT
));
1904 if (multi_volume_option
1905 && archive_format
== POSIX_FORMAT
1906 && subcommand_option
== CREATE_SUBCOMMAND
1907 && !tape_length_option
)
1909 _("creating multi-volume archives in posix format requires using --tape-length (-L) option")));
1911 if (occurrence_option
)
1913 if (!args
.input_files
)
1915 _("--occurrence is meaningless without a file list")));
1916 if (subcommand_option
!= DELETE_SUBCOMMAND
1917 && subcommand_option
!= DIFF_SUBCOMMAND
1918 && subcommand_option
!= EXTRACT_SUBCOMMAND
1919 && subcommand_option
!= LIST_SUBCOMMAND
)
1921 _("--occurrence cannot be used in the requested operation mode")));
1924 if (seekable_archive
&& subcommand_option
== DELETE_SUBCOMMAND
)
1926 /* The current code in delete.c is based on the assumption that
1927 skip_member() reads all data from the archive. So, we should
1928 make sure it won't use seeks. On the other hand, the same code
1929 depends on the ability to backspace a record in the archive,
1930 so setting seekable_archive to false is technically incorrect.
1931 However, it is tested only in skip_member(), so it's not a
1933 seekable_archive
= false;
1936 if (archive_names
== 0)
1938 /* If no archive file name given, try TAPE from the environment, or
1939 else, DEFAULT_ARCHIVE from the configuration process. */
1942 archive_name_array
[0] = getenv ("TAPE");
1943 if (! archive_name_array
[0])
1944 archive_name_array
[0] = DEFAULT_ARCHIVE
;
1947 /* Allow multiple archives only with `-M'. */
1949 if (archive_names
> 1 && !multi_volume_option
)
1951 _("Multiple archive files require `-M' option")));
1953 if (listed_incremental_option
1954 && NEWER_OPTION_INITIALIZED (newer_mtime_option
))
1956 _("Cannot combine --listed-incremental with --newer")));
1958 if (volume_label_option
)
1960 if (archive_format
== GNU_FORMAT
|| archive_format
== OLDGNU_FORMAT
)
1962 size_t volume_label_max_len
=
1963 (sizeof current_header
->header
.name
1964 - 1 /* for trailing '\0' */
1965 - (multi_volume_option
1966 ? (sizeof " Volume "
1967 - 1 /* for null at end of " Volume " */
1968 + INT_STRLEN_BOUND (int) /* for volume number */
1969 - 1 /* for sign, as 0 <= volno */)
1971 if (volume_label_max_len
< strlen (volume_label_option
))
1973 ngettext ("%s: Volume label is too long (limit is %lu byte)",
1974 "%s: Volume label is too long (limit is %lu bytes)",
1975 volume_label_max_len
),
1976 quotearg_colon (volume_label_option
),
1977 (unsigned long) volume_label_max_len
));
1980 Label length in PAX format is limited by the volume size. */
1985 if (multi_volume_option
)
1986 USAGE_ERROR ((0, 0, _("Cannot verify multi-volume archives")));
1987 if (use_compress_program_option
)
1988 USAGE_ERROR ((0, 0, _("Cannot verify compressed archives")));
1991 if (use_compress_program_option
)
1993 if (multi_volume_option
)
1994 USAGE_ERROR ((0, 0, _("Cannot use multi-volume compressed archives")));
1995 if (subcommand_option
== UPDATE_SUBCOMMAND
1996 || subcommand_option
== APPEND_SUBCOMMAND
1997 || subcommand_option
== DELETE_SUBCOMMAND
)
1998 USAGE_ERROR ((0, 0, _("Cannot update compressed archives")));
1999 if (subcommand_option
== CAT_SUBCOMMAND
)
2000 USAGE_ERROR ((0, 0, _("Cannot concatenate compressed archives")));
2003 /* It is no harm to use --pax-option on non-pax archives in archive
2004 reading mode. It may even be useful, since it allows to override
2005 file attributes from tar headers. Therefore I allow such usage.
2008 && archive_format
!= POSIX_FORMAT
2009 && (subcommand_option
!= EXTRACT_SUBCOMMAND
2010 || subcommand_option
!= DIFF_SUBCOMMAND
2011 || subcommand_option
!= LIST_SUBCOMMAND
))
2012 USAGE_ERROR ((0, 0, _("--pax-option can be used only on POSIX archives")));
2014 /* If ready to unlink hierarchies, so we are for simpler files. */
2015 if (recursive_unlink_option
)
2016 old_files_option
= UNLINK_FIRST_OLD_FILES
;
2019 if (test_label_option
)
2021 /* --test-label is silent if the user has specified the label name to
2023 if (!args
.input_files
)
2026 else if (utc_option
)
2029 /* Forbid using -c with no input files whatsoever. Check that `-f -',
2030 explicit or implied, is used correctly. */
2032 switch (subcommand_option
)
2034 case CREATE_SUBCOMMAND
:
2035 if (!args
.input_files
&& !files_from_option
)
2037 _("Cowardly refusing to create an empty archive")));
2040 case EXTRACT_SUBCOMMAND
:
2041 case LIST_SUBCOMMAND
:
2042 case DIFF_SUBCOMMAND
:
2043 for (archive_name_cursor
= archive_name_array
;
2044 archive_name_cursor
< archive_name_array
+ archive_names
;
2045 archive_name_cursor
++)
2046 if (!strcmp (*archive_name_cursor
, "-"))
2047 request_stdin ("-f");
2050 case CAT_SUBCOMMAND
:
2051 case UPDATE_SUBCOMMAND
:
2052 case APPEND_SUBCOMMAND
:
2053 for (archive_name_cursor
= archive_name_array
;
2054 archive_name_cursor
< archive_name_array
+ archive_names
;
2055 archive_name_cursor
++)
2056 if (!strcmp (*archive_name_cursor
, "-"))
2058 _("Options `-Aru' are incompatible with `-f -'")));
2064 archive_name_cursor
= archive_name_array
;
2066 /* Prepare for generating backup names. */
2068 if (args
.backup_suffix_string
)
2069 simple_backup_suffix
= xstrdup (args
.backup_suffix_string
);
2073 backup_type
= xget_version ("--backup", args
.version_control_string
);
2074 /* No backup is needed either if explicitely disabled or if
2075 the extracted files are not being written to disk. */
2076 if (backup_type
== no_backups
|| EXTRACT_OVER_PIPE
)
2077 backup_option
= false;
2080 if (verbose_option
&& args
.textual_date_option
)
2082 char const *treated_as
= tartime (newer_mtime_option
, true);
2083 if (strcmp (args
.textual_date_option
, treated_as
) != 0)
2084 WARN ((0, 0, _("Treating date `%s' as %s"),
2085 args
.textual_date_option
, treated_as
));
2092 /* Main routine for tar. */
2094 main (int argc
, char **argv
)
2097 program_name
= argv
[0];
2099 setlocale (LC_ALL
, "");
2100 bindtextdomain (PACKAGE
, LOCALEDIR
);
2101 textdomain (PACKAGE
);
2103 exit_failure
= TAREXIT_FAILURE
;
2104 exit_status
= TAREXIT_SUCCESS
;
2105 filename_terminator
= '\n';
2106 set_quoting_style (0, DEFAULT_QUOTING_STYLE
);
2108 /* Make sure we have first three descriptors available */
2111 /* Pre-allocate a few structures. */
2113 allocated_archive_names
= 10;
2114 archive_name_array
=
2115 xmalloc (sizeof (const char *) * allocated_archive_names
);
2118 obstack_init (&argv_stk
);
2121 /* System V fork+wait does not work if SIGCHLD is ignored. */
2122 signal (SIGCHLD
, SIG_DFL
);
2125 /* Decode options. */
2127 decode_options (argc
, argv
);
2130 /* Main command execution. */
2132 if (volno_file_option
)
2133 init_volume_number ();
2135 switch (subcommand_option
)
2137 case UNKNOWN_SUBCOMMAND
:
2139 _("You must specify one of the `-Acdtrux' options")));
2141 case CAT_SUBCOMMAND
:
2142 case UPDATE_SUBCOMMAND
:
2143 case APPEND_SUBCOMMAND
:
2147 case DELETE_SUBCOMMAND
:
2148 delete_archive_members ();
2151 case CREATE_SUBCOMMAND
:
2154 print_total_written ();
2157 case EXTRACT_SUBCOMMAND
:
2159 read_and (extract_archive
);
2161 /* FIXME: should extract_finish () even if an ordinary signal is
2167 case LIST_SUBCOMMAND
:
2168 read_and (list_archive
);
2171 case DIFF_SUBCOMMAND
:
2173 read_and (diff_archive
);
2177 if (check_links_option
)
2180 if (volno_file_option
)
2181 closeout_volume_number ();
2183 /* Dispose of allocated memory, and return. */
2185 free (archive_name_array
);
2188 if (stdlis
== stdout
)
2191 if (exit_status
== TAREXIT_FAILURE
)
2192 error (0, 0, _("Error exit delayed from previous errors"));
2193 if (ferror (stderr
) || fclose (stderr
) != 0)
2194 exit_status
= TAREXIT_FAILURE
;
2199 tar_stat_init (struct tar_stat_info
*st
)
2201 memset (st
, 0, sizeof (*st
));
2205 tar_stat_destroy (struct tar_stat_info
*st
)
2207 free (st
->orig_file_name
);
2208 free (st
->file_name
);
2209 free (st
->link_name
);
2212 free (st
->sparse_map
);
2214 memset (st
, 0, sizeof (*st
));
2217 /* Format mask for all available formats that support nanosecond
2218 timestamp resolution. */
2219 #define NS_PRECISION_FORMAT_MASK FORMAT_MASK (POSIX_FORMAT)
2221 /* Same as timespec_cmp, but ignore nanoseconds if current archive
2222 format does not provide sufficient resolution. */
2224 tar_timespec_cmp (struct timespec a
, struct timespec b
)
2226 if (!(FORMAT_MASK (current_format
) & NS_PRECISION_FORMAT_MASK
))
2227 a
.tv_nsec
= b
.tv_nsec
= 0;
2228 return timespec_cmp (a
, b
);