1 /* A tar (tape archiver) program.
3 Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1999, 2000,
4 2001, 2003, 2004, 2005, 2006, 2007, 2009 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 3, 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. */
26 #include <argp-namefrob.h>
27 #include <argp-fmtstream.h>
30 #if ! defined SIGCHLD && defined SIGCLD
31 # define SIGCHLD SIGCLD
34 /* The following causes "common.h" to produce definitions of all the global
35 variables, rather than just "extern" declarations of them. GNU tar does
36 depend on the system loader to preset all GLOBAL variables to neutral (or
37 zero) values; explicit initialization is usually not done. */
43 #include <configmake.h>
47 #include <rmt-command.h>
50 #include <version-etc.h>
55 /* Local declarations. */
57 #ifndef DEFAULT_ARCHIVE_FORMAT
58 # define DEFAULT_ARCHIVE_FORMAT GNU_FORMAT
61 #ifndef DEFAULT_ARCHIVE
62 # define DEFAULT_ARCHIVE "tar.out"
65 #ifndef DEFAULT_BLOCKING
66 # define DEFAULT_BLOCKING 20
72 /* Name of option using stdin. */
73 static const char *stdin_used_by
;
75 /* Doesn't return if stdin already requested. */
77 request_stdin (const char *option
)
80 USAGE_ERROR ((0, 0, _("Options `-%s' and `-%s' both want standard input"),
81 stdin_used_by
, option
));
83 stdin_used_by
= option
;
86 extern int rpmatch (char const *response
);
88 /* Returns true if and only if the user typed an affirmative response. */
90 confirm (const char *message_action
, const char *message_name
)
92 static FILE *confirm_file
;
93 static int confirm_file_EOF
;
98 if (archive
== 0 || stdin_used_by
)
100 confirm_file
= fopen (TTY_NAME
, "r");
102 open_fatal (TTY_NAME
);
106 request_stdin ("-w");
107 confirm_file
= stdin
;
111 fprintf (stdlis
, "%s %s?", message_action
, quote (message_name
));
114 if (!confirm_file_EOF
)
116 char *response
= NULL
;
117 size_t response_size
= 0;
118 if (getline (&response
, &response_size
, confirm_file
) < 0)
119 confirm_file_EOF
= 1;
121 status
= rpmatch (response
) > 0;
125 if (confirm_file_EOF
)
127 fputc ('\n', stdlis
);
134 static struct fmttab
{
136 enum archive_format fmt
;
139 { "oldgnu", OLDGNU_FORMAT
},
140 { "ustar", USTAR_FORMAT
},
141 { "posix", POSIX_FORMAT
},
142 #if 0 /* not fully supported yet */
143 { "star", STAR_FORMAT
},
145 { "gnu", GNU_FORMAT
},
146 { "pax", POSIX_FORMAT
}, /* An alias for posix */
151 set_archive_format (char const *name
)
153 struct fmttab
const *p
;
155 for (p
= fmttab
; strcmp (p
->name
, name
) != 0; )
157 USAGE_ERROR ((0, 0, _("%s: Invalid archive format"),
158 quotearg_colon (name
)));
160 archive_format
= p
->fmt
;
164 archive_format_string (enum archive_format fmt
)
166 struct fmttab
const *p
;
168 for (p
= fmttab
; p
->name
; p
++)
174 #define FORMAT_MASK(n) (1<<(n))
177 assert_format(unsigned fmt_mask
)
179 if ((FORMAT_MASK (archive_format
) & fmt_mask
) == 0)
181 _("GNU features wanted on incompatible archive format")));
185 subcommand_string (enum subcommand c
)
189 case UNKNOWN_SUBCOMMAND
:
192 case APPEND_SUBCOMMAND
:
198 case CREATE_SUBCOMMAND
:
201 case DELETE_SUBCOMMAND
:
204 case DIFF_SUBCOMMAND
:
207 case EXTRACT_SUBCOMMAND
:
210 case LIST_SUBCOMMAND
:
213 case UPDATE_SUBCOMMAND
:
222 tar_list_quoting_styles (argp_fmtstream_t fs
, char *prefix
)
226 for (i
= 0; quoting_style_args
[i
]; i
++)
227 argp_fmtstream_printf (fs
, "%s%s\n", prefix
, quoting_style_args
[i
]);
231 tar_set_quoting_style (char *arg
)
235 for (i
= 0; quoting_style_args
[i
]; i
++)
236 if (strcmp (arg
, quoting_style_args
[i
]) == 0)
238 set_quoting_style (NULL
, i
);
242 _("Unknown quoting style `%s'. Try `%s --quoting-style=help' to get a list."), arg
, program_invocation_short_name
));
250 ANCHORED_OPTION
= CHAR_MAX
+ 1,
251 ATIME_PRESERVE_OPTION
,
255 CHECKPOINT_ACTION_OPTION
,
256 DELAY_DIRECTORY_RESTORE_OPTION
,
257 HARD_DEREFERENCE_OPTION
,
259 EXCLUDE_BACKUPS_OPTION
,
260 EXCLUDE_CACHES_OPTION
,
261 EXCLUDE_CACHES_UNDER_OPTION
,
262 EXCLUDE_CACHES_ALL_OPTION
,
265 EXCLUDE_TAG_UNDER_OPTION
,
266 EXCLUDE_TAG_ALL_OPTION
,
272 IGNORE_COMMAND_ERROR_OPTION
,
273 IGNORE_FAILED_READ_OPTION
,
275 KEEP_NEWER_FILES_OPTION
,
283 NO_AUTO_COMPRESS_OPTION
,
284 NO_CHECK_DEVICE_OPTION
,
285 NO_DELAY_DIRECTORY_RESTORE_OPTION
,
286 NO_IGNORE_CASE_OPTION
,
287 NO_IGNORE_COMMAND_ERROR_OPTION
,
289 NO_OVERWRITE_DIR_OPTION
,
290 NO_QUOTE_CHARS_OPTION
,
292 NO_SAME_OWNER_OPTION
,
293 NO_SAME_PERMISSIONS_OPTION
,
296 NO_WILDCARDS_MATCH_SLASH_OPTION
,
299 NUMERIC_OWNER_OPTION
,
302 ONE_FILE_SYSTEM_OPTION
,
303 OVERWRITE_DIR_OPTION
,
310 QUOTING_STYLE_OPTION
,
313 RECURSIVE_UNLINK_OPTION
,
319 SHOW_DEFAULTS_OPTION
,
320 SHOW_OMITTED_DIRS_OPTION
,
321 SHOW_TRANSFORMED_NAMES_OPTION
,
322 SPARSE_VERSION_OPTION
,
323 STRIP_COMPONENTS_OPTION
,
335 WILDCARDS_MATCH_SLASH_OPTION
,
339 const char *argp_program_version
= "tar (" PACKAGE_NAME
") " VERSION
;
340 const char *argp_program_bug_address
= "<" PACKAGE_BUGREPORT
">";
341 static char const doc
[] = N_("\
342 GNU `tar' saves many files together into a single tape or disk archive, \
343 and can restore individual files from the archive.\n\
346 tar -cf archive.tar foo bar # Create archive.tar from files foo and bar.\n\
347 tar -tvf archive.tar # List all files in archive.tar verbosely.\n\
348 tar -xf archive.tar # Extract all files from archive.tar.\n")
350 N_("The backup suffix is `~', unless set with --suffix or SIMPLE_BACKUP_SUFFIX.\n\
351 The version control may be set with --backup or VERSION_CONTROL, values are:\n\n\
352 none, off never make backups\n\
353 t, numbered make numbered backups\n\
354 nil, existing numbered if numbered backups exist, simple otherwise\n\
355 never, simple always make simple backups\n");
360 Available option letters are DEQY and eqy. Consider the following
363 [For Solaris tar compatibility =/= Is it important at all?]
364 e exit immediately with a nonzero exit status if unexpected errors occur
365 E use extended headers (--format=posix)
367 [q alias for --occurrence=1 =/= this would better be used for quiet?]
369 y per-file gzip compression
370 Y per-block gzip compression.
372 Additionally, the 'n' letter is assigned for option --seek, which
373 is probably not needed and should be marked as deprecated, so that
374 -n may become available in the future.
377 static struct argp_option options
[] = {
380 N_("Main operation mode:"), GRID
},
383 N_("list the contents of an archive"), GRID
+1 },
384 {"extract", 'x', 0, 0,
385 N_("extract files from an archive"), GRID
+1 },
386 {"get", 0, 0, OPTION_ALIAS
, NULL
, GRID
+1 },
387 {"create", 'c', 0, 0,
388 N_("create a new archive"), GRID
+1 },
390 N_("find differences between archive and file system"), GRID
+1 },
391 {"compare", 0, 0, OPTION_ALIAS
, NULL
, GRID
+1 },
392 {"append", 'r', 0, 0,
393 N_("append files to the end of an archive"), GRID
+1 },
394 {"update", 'u', 0, 0,
395 N_("only append files newer than copy in archive"), GRID
+1 },
396 {"catenate", 'A', 0, 0,
397 N_("append tar files to an archive"), GRID
+1 },
398 {"concatenate", 0, 0, OPTION_ALIAS
, NULL
, GRID
+1 },
399 {"delete", DELETE_OPTION
, 0, 0,
400 N_("delete from the archive (not on mag tapes!)"), GRID
+1 },
401 {"test-label", TEST_LABEL_OPTION
, NULL
, 0,
402 N_("test the archive volume label and exit"), GRID
+1 },
407 N_("Operation modifiers:"), GRID
},
409 {"sparse", 'S', 0, 0,
410 N_("handle sparse files efficiently"), GRID
+1 },
411 {"sparse-version", SPARSE_VERSION_OPTION
, N_("MAJOR[.MINOR]"), 0,
412 N_("set version of the sparse format to use (implies --sparse)"), GRID
+1},
413 {"incremental", 'G', 0, 0,
414 N_("handle old GNU-format incremental backup"), GRID
+1 },
415 {"listed-incremental", 'g', N_("FILE"), 0,
416 N_("handle new GNU-format incremental backup"), GRID
+1 },
417 {"level", LEVEL_OPTION
, N_("NUMBER"), 0,
418 N_("dump level for created listed-incremental archive"), GRID
+1 },
419 {"ignore-failed-read", IGNORE_FAILED_READ_OPTION
, 0, 0,
420 N_("do not exit with nonzero on unreadable files"), GRID
+1 },
421 {"occurrence", OCCURRENCE_OPTION
, N_("NUMBER"), OPTION_ARG_OPTIONAL
,
422 N_("process only the NUMBERth occurrence of each file in the archive;"
423 " this option is valid only in conjunction with one of the subcommands"
424 " --delete, --diff, --extract or --list and when a list of files"
425 " is given either on the command line or via the -T option;"
426 " NUMBER defaults to 1"), GRID
+1 },
427 {"seek", 'n', NULL
, 0,
428 N_("archive is seekable"), GRID
+1 },
429 {"no-seek", NO_SEEK_OPTION
, NULL
, 0,
430 N_("archive is not seekable"), GRID
+1 },
431 {"no-check-device", NO_CHECK_DEVICE_OPTION
, NULL
, 0,
432 N_("do not check device numbers when creating incremental archives"),
434 {"check-device", CHECK_DEVICE_OPTION
, NULL
, 0,
435 N_("check device numbers when creating incremental archives (default)"),
441 N_("Overwrite control:"), GRID
},
443 {"verify", 'W', 0, 0,
444 N_("attempt to verify the archive after writing it"), GRID
+1 },
445 {"remove-files", REMOVE_FILES_OPTION
, 0, 0,
446 N_("remove files after adding them to the archive"), GRID
+1 },
447 {"keep-old-files", 'k', 0, 0,
448 N_("don't replace existing files when extracting"), GRID
+1 },
449 {"keep-newer-files", KEEP_NEWER_FILES_OPTION
, 0, 0,
450 N_("don't replace existing files that are newer than their archive copies"), GRID
+1 },
451 {"overwrite", OVERWRITE_OPTION
, 0, 0,
452 N_("overwrite existing files when extracting"), GRID
+1 },
453 {"unlink-first", 'U', 0, 0,
454 N_("remove each file prior to extracting over it"), GRID
+1 },
455 {"recursive-unlink", RECURSIVE_UNLINK_OPTION
, 0, 0,
456 N_("empty hierarchies prior to extracting directory"), GRID
+1 },
457 {"no-overwrite-dir", NO_OVERWRITE_DIR_OPTION
, 0, 0,
458 N_("preserve metadata of existing directories"), GRID
+1 },
459 {"overwrite-dir", OVERWRITE_DIR_OPTION
, 0, 0,
460 N_("overwrite metadata of existing directories when extracting (default)"),
466 N_("Select output stream:"), GRID
},
468 {"to-stdout", 'O', 0, 0,
469 N_("extract files to standard output"), GRID
+1 },
470 {"to-command", TO_COMMAND_OPTION
, N_("COMMAND"), 0,
471 N_("pipe extracted files to another program"), GRID
+1 },
472 {"ignore-command-error", IGNORE_COMMAND_ERROR_OPTION
, 0, 0,
473 N_("ignore exit codes of children"), GRID
+1 },
474 {"no-ignore-command-error", NO_IGNORE_COMMAND_ERROR_OPTION
, 0, 0,
475 N_("treat non-zero exit codes of children as error"), GRID
+1 },
480 N_("Handling of file attributes:"), GRID
},
482 {"owner", OWNER_OPTION
, N_("NAME"), 0,
483 N_("force NAME as owner for added files"), GRID
+1 },
484 {"group", GROUP_OPTION
, N_("NAME"), 0,
485 N_("force NAME as group for added files"), GRID
+1 },
486 {"mtime", MTIME_OPTION
, N_("DATE-OR-FILE"), 0,
487 N_("set mtime for added files from DATE-OR-FILE"), GRID
+1 },
488 {"mode", MODE_OPTION
, N_("CHANGES"), 0,
489 N_("force (symbolic) mode CHANGES for added files"), GRID
+1 },
490 {"atime-preserve", ATIME_PRESERVE_OPTION
,
491 N_("METHOD"), OPTION_ARG_OPTIONAL
,
492 N_("preserve access times on dumped files, either by restoring the times"
493 " after reading (METHOD='replace'; default) or by not setting the times"
494 " in the first place (METHOD='system')"), GRID
+1 },
496 N_("don't extract file modified time"), GRID
+1 },
497 {"same-owner", SAME_OWNER_OPTION
, 0, 0,
498 N_("try extracting files with the same ownership as exists in the archive (default for superuser)"), GRID
+1 },
499 {"no-same-owner", NO_SAME_OWNER_OPTION
, 0, 0,
500 N_("extract files as yourself (default for ordinary users)"), GRID
+1 },
501 {"numeric-owner", NUMERIC_OWNER_OPTION
, 0, 0,
502 N_("always use numbers for user/group names"), GRID
+1 },
503 {"preserve-permissions", 'p', 0, 0,
504 N_("extract information about file permissions (default for superuser)"),
506 {"same-permissions", 0, 0, OPTION_ALIAS
, NULL
, GRID
+1 },
507 {"no-same-permissions", NO_SAME_PERMISSIONS_OPTION
, 0, 0,
508 N_("apply the user's umask when extracting permissions from the archive (default for ordinary users)"), GRID
+1 },
509 {"preserve-order", 's', 0, 0,
510 N_("sort names to extract to match archive"), GRID
+1 },
511 {"same-order", 0, 0, OPTION_ALIAS
, NULL
, GRID
+1 },
512 {"preserve", PRESERVE_OPTION
, 0, 0,
513 N_("same as both -p and -s"), GRID
+1 },
514 {"delay-directory-restore", DELAY_DIRECTORY_RESTORE_OPTION
, 0, 0,
515 N_("delay setting modification times and permissions of extracted"
516 " directories until the end of extraction"), GRID
+1 },
517 {"no-delay-directory-restore", NO_DELAY_DIRECTORY_RESTORE_OPTION
, 0, 0,
518 N_("cancel the effect of --delay-directory-restore option"), GRID
+1 },
523 N_("Device selection and switching:"), GRID
},
525 {"file", 'f', N_("ARCHIVE"), 0,
526 N_("use archive file or device ARCHIVE"), GRID
+1 },
527 {"force-local", FORCE_LOCAL_OPTION
, 0, 0,
528 N_("archive file is local even if it has a colon"), GRID
+1 },
529 {"rmt-command", RMT_COMMAND_OPTION
, N_("COMMAND"), 0,
530 N_("use given rmt COMMAND instead of rmt"), GRID
+1 },
531 {"rsh-command", RSH_COMMAND_OPTION
, N_("COMMAND"), 0,
532 N_("use remote COMMAND instead of rsh"), GRID
+1 },
534 {"-[0-7][lmh]", 0, NULL
, OPTION_DOC
, /* It is OK, since `name' will never be
536 N_("specify drive and density"), GRID
+1 },
538 {NULL
, '0', NULL
, OPTION_HIDDEN
, NULL
, GRID
+1 },
539 {NULL
, '1', NULL
, OPTION_HIDDEN
, NULL
, GRID
+1 },
540 {NULL
, '2', NULL
, OPTION_HIDDEN
, NULL
, GRID
+1 },
541 {NULL
, '3', NULL
, OPTION_HIDDEN
, NULL
, GRID
+1 },
542 {NULL
, '4', NULL
, OPTION_HIDDEN
, NULL
, GRID
+1 },
543 {NULL
, '5', NULL
, OPTION_HIDDEN
, NULL
, GRID
+1 },
544 {NULL
, '6', NULL
, OPTION_HIDDEN
, NULL
, GRID
+1 },
545 {NULL
, '7', NULL
, OPTION_HIDDEN
, NULL
, GRID
+1 },
546 {NULL
, '8', NULL
, OPTION_HIDDEN
, NULL
, GRID
+1 },
547 {NULL
, '9', NULL
, OPTION_HIDDEN
, NULL
, GRID
+1 },
549 {"multi-volume", 'M', 0, 0,
550 N_("create/list/extract multi-volume archive"), GRID
+1 },
551 {"tape-length", 'L', N_("NUMBER"), 0,
552 N_("change tape after writing NUMBER x 1024 bytes"), GRID
+1 },
553 {"info-script", 'F', N_("NAME"), 0,
554 N_("run script at end of each tape (implies -M)"), GRID
+1 },
555 {"new-volume-script", 0, 0, OPTION_ALIAS
, NULL
, GRID
+1 },
556 {"volno-file", VOLNO_FILE_OPTION
, N_("FILE"), 0,
557 N_("use/update the volume number in FILE"), GRID
+1 },
562 N_("Device blocking:"), GRID
},
564 {"blocking-factor", 'b', N_("BLOCKS"), 0,
565 N_("BLOCKS x 512 bytes per record"), GRID
+1 },
566 {"record-size", RECORD_SIZE_OPTION
, N_("NUMBER"), 0,
567 N_("NUMBER of bytes per record, multiple of 512"), GRID
+1 },
568 {"ignore-zeros", 'i', 0, 0,
569 N_("ignore zeroed blocks in archive (means EOF)"), GRID
+1 },
570 {"read-full-records", 'B', 0, 0,
571 N_("reblock as we read (for 4.2BSD pipes)"), GRID
+1 },
576 N_("Archive format selection:"), GRID
},
578 {"format", 'H', N_("FORMAT"), 0,
579 N_("create archive of the given format"), GRID
+1 },
581 {NULL
, 0, NULL
, 0, N_("FORMAT is one of the following:"), GRID
+2 },
582 {" v7", 0, NULL
, OPTION_DOC
|OPTION_NO_TRANS
, N_("old V7 tar format"),
584 {" oldgnu", 0, NULL
, OPTION_DOC
|OPTION_NO_TRANS
,
585 N_("GNU format as per tar <= 1.12"), GRID
+3 },
586 {" gnu", 0, NULL
, OPTION_DOC
|OPTION_NO_TRANS
,
587 N_("GNU tar 1.13.x format"), GRID
+3 },
588 {" ustar", 0, NULL
, OPTION_DOC
|OPTION_NO_TRANS
,
589 N_("POSIX 1003.1-1988 (ustar) format"), GRID
+3 },
590 {" pax", 0, NULL
, OPTION_DOC
|OPTION_NO_TRANS
,
591 N_("POSIX 1003.1-2001 (pax) format"), GRID
+3 },
592 {" posix", 0, NULL
, OPTION_DOC
|OPTION_NO_TRANS
, N_("same as pax"), GRID
+3 },
594 {"old-archive", OLD_ARCHIVE_OPTION
, 0, 0, /* FIXME */
595 N_("same as --format=v7"), GRID
+8 },
596 {"portability", 0, 0, OPTION_ALIAS
, NULL
, GRID
+8 },
597 {"posix", POSIX_OPTION
, 0, 0,
598 N_("same as --format=posix"), GRID
+8 },
599 {"pax-option", PAX_OPTION
, N_("keyword[[:]=value][,keyword[[:]=value]]..."), 0,
600 N_("control pax keywords"), GRID
+8 },
601 {"label", 'V', N_("TEXT"), 0,
602 N_("create archive with volume name TEXT; at list/extract time, use TEXT as a globbing pattern for volume name"), GRID
+8 },
607 N_("Compression options:"), GRID
},
608 {"auto-compress", 'a', 0, 0,
609 N_("use archive suffix to determine the compression program"), GRID
+1 },
610 {"no-auto-compress", NO_AUTO_COMPRESS_OPTION
, 0, 0,
611 N_("do not use archive suffix to determine the compression program"),
614 N_("filter the archive through bzip2"), GRID
+1 },
616 N_("filter the archive through gzip"), GRID
+1 },
617 {"gunzip", 0, 0, OPTION_ALIAS
, NULL
, GRID
+1 },
618 {"ungzip", 0, 0, OPTION_ALIAS
, NULL
, GRID
+1 },
619 {"compress", 'Z', 0, 0,
620 N_("filter the archive through compress"), GRID
+1 },
621 {"uncompress", 0, 0, OPTION_ALIAS
, NULL
, GRID
+1 },
622 {"lzma", LZMA_OPTION
, 0, 0,
623 N_("filter the archive through lzma"), GRID
+1 },
624 {"lzop", LZOP_OPTION
, 0, 0,
625 N_("filter the archive through lzop"), GRID
+8 },
627 N_("filter the archive through xz"), GRID
+8 },
628 {"use-compress-program", 'I', N_("PROG"), 0,
629 N_("filter through PROG (must accept -d)"), GRID
+1 },
634 N_("Local file selection:"), GRID
},
636 {"add-file", ARGP_KEY_ARG
, N_("FILE"), 0,
637 N_("add given FILE to the archive (useful if its name starts with a dash)"), GRID
+1 },
638 {"directory", 'C', N_("DIR"), 0,
639 N_("change to directory DIR"), GRID
+1 },
640 {"files-from", 'T', N_("FILE"), 0,
641 N_("get names to extract or create from FILE"), GRID
+1 },
642 {"null", NULL_OPTION
, 0, 0,
643 N_("-T reads null-terminated names, disable -C"), GRID
+1 },
644 {"no-null", NO_NULL_OPTION
, 0, 0,
645 N_("disable the effect of the previous --null option"), GRID
+1 },
646 {"unquote", UNQUOTE_OPTION
, 0, 0,
647 N_("unquote filenames read with -T (default)"), GRID
+1 },
648 {"no-unquote", NO_UNQUOTE_OPTION
, 0, 0,
649 N_("do not unquote filenames read with -T"), GRID
+1 },
650 {"exclude", EXCLUDE_OPTION
, N_("PATTERN"), 0,
651 N_("exclude files, given as a PATTERN"), GRID
+1 },
652 {"exclude-from", 'X', N_("FILE"), 0,
653 N_("exclude patterns listed in FILE"), GRID
+1 },
654 {"exclude-caches", EXCLUDE_CACHES_OPTION
, 0, 0,
655 N_("exclude contents of directories containing CACHEDIR.TAG, "
656 "except for the tag file itself"), GRID
+1 },
657 {"exclude-caches-under", EXCLUDE_CACHES_UNDER_OPTION
, 0, 0,
658 N_("exclude everything under directories containing CACHEDIR.TAG"),
660 {"exclude-caches-all", EXCLUDE_CACHES_ALL_OPTION
, 0, 0,
661 N_("exclude directories containing CACHEDIR.TAG"), GRID
+1 },
662 {"exclude-tag", EXCLUDE_TAG_OPTION
, N_("FILE"), 0,
663 N_("exclude contents of directories containing FILE, except"
664 " for FILE itself"), GRID
+1 },
665 {"exclude-tag-under", EXCLUDE_TAG_UNDER_OPTION
, N_("FILE"), 0,
666 N_("exclude everything under directories containing FILE"), GRID
+1 },
667 {"exclude-tag-all", EXCLUDE_TAG_ALL_OPTION
, N_("FILE"), 0,
668 N_("exclude directories containing FILE"), GRID
+1 },
669 {"exclude-vcs", EXCLUDE_VCS_OPTION
, NULL
, 0,
670 N_("exclude version control system directories"), GRID
+1 },
671 {"exclude-backups", EXCLUDE_BACKUPS_OPTION
, NULL
, 0,
672 N_("exclude backup and lock files"), GRID
+1 },
673 {"no-recursion", NO_RECURSION_OPTION
, 0, 0,
674 N_("avoid descending automatically in directories"), GRID
+1 },
675 {"one-file-system", ONE_FILE_SYSTEM_OPTION
, 0, 0,
676 N_("stay in local file system when creating archive"), GRID
+1 },
677 {"recursion", RECURSION_OPTION
, 0, 0,
678 N_("recurse into directories (default)"), GRID
+1 },
679 {"absolute-names", 'P', 0, 0,
680 N_("don't strip leading `/'s from file names"), GRID
+1 },
681 {"dereference", 'h', 0, 0,
682 N_("follow symlinks; archive and dump the files they point to"), GRID
+1 },
683 {"hard-dereference", HARD_DEREFERENCE_OPTION
, 0, 0,
684 N_("follow hard links; archive and dump the files they refer to"), GRID
+1 },
685 {"starting-file", 'K', N_("MEMBER-NAME"), 0,
686 N_("begin at member MEMBER-NAME in the archive"), GRID
+1 },
687 {"newer", 'N', N_("DATE-OR-FILE"), 0,
688 N_("only store files newer than DATE-OR-FILE"), GRID
+1 },
689 {"after-date", 0, 0, OPTION_ALIAS
, NULL
, GRID
+1 },
690 {"newer-mtime", NEWER_MTIME_OPTION
, N_("DATE"), 0,
691 N_("compare date and time when data changed only"), GRID
+1 },
692 {"backup", BACKUP_OPTION
, N_("CONTROL"), OPTION_ARG_OPTIONAL
,
693 N_("backup before removal, choose version CONTROL"), GRID
+1 },
694 {"suffix", SUFFIX_OPTION
, N_("STRING"), 0,
695 N_("backup before removal, override usual suffix ('~' unless overridden by environment variable SIMPLE_BACKUP_SUFFIX)"), GRID
+1 },
700 N_("File name transformations:"), GRID
},
701 {"strip-components", STRIP_COMPONENTS_OPTION
, N_("NUMBER"), 0,
702 N_("strip NUMBER leading components from file names on extraction"),
704 {"transform", TRANSFORM_OPTION
, N_("EXPRESSION"), 0,
705 N_("use sed replace EXPRESSION to transform file names"), GRID
+1 },
706 {"xform", 0, 0, OPTION_ALIAS
, NULL
, GRID
+1 },
711 N_("File name matching options (affect both exclude and include patterns):"),
713 {"ignore-case", IGNORE_CASE_OPTION
, 0, 0,
714 N_("ignore case"), GRID
+1 },
715 {"anchored", ANCHORED_OPTION
, 0, 0,
716 N_("patterns match file name start"), GRID
+1 },
717 {"no-anchored", NO_ANCHORED_OPTION
, 0, 0,
718 N_("patterns match after any `/' (default for exclusion)"), GRID
+1 },
719 {"no-ignore-case", NO_IGNORE_CASE_OPTION
, 0, 0,
720 N_("case sensitive matching (default)"), GRID
+1 },
721 {"wildcards", WILDCARDS_OPTION
, 0, 0,
722 N_("use wildcards (default for exclusion)"), GRID
+1 },
723 {"no-wildcards", NO_WILDCARDS_OPTION
, 0, 0,
724 N_("verbatim string matching"), GRID
+1 },
725 {"no-wildcards-match-slash", NO_WILDCARDS_MATCH_SLASH_OPTION
, 0, 0,
726 N_("wildcards do not match `/'"), GRID
+1 },
727 {"wildcards-match-slash", WILDCARDS_MATCH_SLASH_OPTION
, 0, 0,
728 N_("wildcards match `/' (default for exclusion)"), GRID
+1 },
733 N_("Informative output:"), GRID
},
735 {"verbose", 'v', 0, 0,
736 N_("verbosely list files processed"), GRID
+1 },
737 {"warning", WARNING_OPTION
, N_("KEYWORD"), 0,
738 N_("warning control"), GRID
+1 },
739 {"checkpoint", CHECKPOINT_OPTION
, N_("NUMBER"), OPTION_ARG_OPTIONAL
,
740 N_("display progress messages every NUMBERth record (default 10)"),
742 {"checkpoint-action", CHECKPOINT_ACTION_OPTION
, N_("ACTION"), 0,
743 N_("execute ACTION on each checkpoint"),
745 {"check-links", 'l', 0, 0,
746 N_("print a message if not all links are dumped"), GRID
+1 },
747 {"totals", TOTALS_OPTION
, N_("SIGNAL"), OPTION_ARG_OPTIONAL
,
748 N_("print total bytes after processing the archive; "
749 "with an argument - print total bytes when this SIGNAL is delivered; "
750 "Allowed signals are: SIGHUP, SIGQUIT, SIGINT, SIGUSR1 and SIGUSR2; "
751 "the names without SIG prefix are also accepted"), GRID
+1 },
752 {"utc", UTC_OPTION
, 0, 0,
753 N_("print file modification dates in UTC"), GRID
+1 },
754 {"index-file", INDEX_FILE_OPTION
, N_("FILE"), 0,
755 N_("send verbose output to FILE"), GRID
+1 },
756 {"block-number", 'R', 0, 0,
757 N_("show block number within archive with each message"), GRID
+1 },
758 {"interactive", 'w', 0, 0,
759 N_("ask for confirmation for every action"), GRID
+1 },
760 {"confirmation", 0, 0, OPTION_ALIAS
, NULL
, GRID
+1 },
761 {"show-defaults", SHOW_DEFAULTS_OPTION
, 0, 0,
762 N_("show tar defaults"), GRID
+1 },
763 {"show-omitted-dirs", SHOW_OMITTED_DIRS_OPTION
, 0, 0,
764 N_("when listing or extracting, list each directory that does not match search criteria"), GRID
+1 },
765 {"show-transformed-names", SHOW_TRANSFORMED_NAMES_OPTION
, 0, 0,
766 N_("show file or archive names after transformation"),
768 {"show-stored-names", 0, 0, OPTION_ALIAS
, NULL
, GRID
+1 },
769 {"quoting-style", QUOTING_STYLE_OPTION
, N_("STYLE"), 0,
770 N_("set name quoting style; see below for valid STYLE values"), GRID
+1 },
771 {"quote-chars", QUOTE_CHARS_OPTION
, N_("STRING"), 0,
772 N_("additionally quote characters from STRING"), GRID
+1 },
773 {"no-quote-chars", NO_QUOTE_CHARS_OPTION
, N_("STRING"), 0,
774 N_("disable quoting for characters from STRING"), GRID
+1 },
779 N_("Compatibility options:"), GRID
},
782 N_("when creating, same as --old-archive; when extracting, same as --no-same-owner"), GRID
+1 },
787 N_("Other options:"), GRID
},
789 {"restrict", RESTRICT_OPTION
, 0, 0,
790 N_("disable use of some potentially harmful options"), -1 },
792 {"help", '?', 0, 0, N_("give this help list"), -1},
793 {"usage", USAGE_OPTION
, 0, 0, N_("give a short usage message"), -1},
794 {"version", VERSION_OPTION
, 0, 0, N_("print program version"), -1},
795 /* FIXME -V (--label) conflicts with the default short option for
797 {"HANG", HANG_OPTION
, "SECS", OPTION_ARG_OPTIONAL
| OPTION_HIDDEN
,
798 N_("hang for SECS seconds (default 3600)"), 0},
804 static char const *const atime_preserve_args
[] =
806 "replace", "system", NULL
809 static enum atime_preserve
const atime_preserve_types
[] =
811 replace_atime_preserve
, system_atime_preserve
814 /* Make sure atime_preserve_types has as much entries as atime_preserve_args
815 (minus 1 for NULL guard) */
816 ARGMATCH_VERIFY (atime_preserve_args
, atime_preserve_types
);
818 /* Wildcard matching settings */
821 default_wildcards
, /* For exclusion == enable_wildcards,
822 for inclusion == disable_wildcards */
827 struct tar_args
/* Variables used during option parsing */
829 struct textual_date
*textual_date
; /* Keeps the arguments to --newer-mtime
830 and/or --date option if they are
832 enum wildcards wildcards
; /* Wildcard settings (--wildcards/
834 int matching_flags
; /* exclude_fnmatch options */
835 int include_anchored
; /* Pattern anchoring options used for
837 bool o_option
; /* True if -o option was given */
838 bool pax_option
; /* True if --pax-option was given */
839 char const *backup_suffix_string
; /* --suffix option argument */
840 char const *version_control_string
; /* --backup option argument */
841 bool input_files
; /* True if some input files where given */
842 int compress_autodetect
; /* True if compression autodetection should
843 be attempted when creating archives */
847 #define MAKE_EXCL_OPTIONS(args) \
848 ((((args)->wildcards != disable_wildcards) ? EXCLUDE_WILDCARDS : 0) \
849 | (args)->matching_flags \
852 #define MAKE_INCL_OPTIONS(args) \
853 ((((args)->wildcards == enable_wildcards) ? EXCLUDE_WILDCARDS : 0) \
854 | (args)->include_anchored \
855 | (args)->matching_flags \
858 static char const * const vcs_file_table
[] = {
890 static char const * const backup_file_table
[] = {
898 add_exclude_array (char const * const * fv
)
902 for (i
= 0; fv
[i
]; i
++)
903 add_exclude (excluded
, fv
[i
], 0);
908 # define DECL_SHOW_DEFAULT_SETTINGS(stream, printer) \
911 "--format=%s -f%s -b%d --quoting-style=%s --rmt-command=%s", \
912 archive_format_string (DEFAULT_ARCHIVE_FORMAT), \
913 DEFAULT_ARCHIVE, DEFAULT_BLOCKING, \
914 quoting_style_args[DEFAULT_QUOTING_STYLE], \
915 DEFAULT_RMT_COMMAND); \
916 printer (stream, " --rsh-command=%s", REMOTE_SHELL); \
917 printer (stream, "\n"); \
920 # define DECL_SHOW_DEFAULT_SETTINGS(stream, printer) \
923 "--format=%s -f%s -b%d --quoting-style=%s --rmt-command=%s", \
924 archive_format_string (DEFAULT_ARCHIVE_FORMAT), \
925 DEFAULT_ARCHIVE, DEFAULT_BLOCKING, \
926 quoting_style_args[DEFAULT_QUOTING_STYLE], \
927 DEFAULT_RMT_COMMAND); \
928 printer (stream, "\n"); \
933 show_default_settings (FILE *fp
)
934 DECL_SHOW_DEFAULT_SETTINGS(fp
, fprintf
)
937 show_default_settings_fs (argp_fmtstream_t fs
)
938 DECL_SHOW_DEFAULT_SETTINGS(fs
, argp_fmtstream_printf
)
941 set_subcommand_option (enum subcommand subcommand
)
943 if (subcommand_option
!= UNKNOWN_SUBCOMMAND
944 && subcommand_option
!= subcommand
)
946 _("You may not specify more than one `-Acdtrux' option")));
948 subcommand_option
= subcommand
;
952 set_use_compress_program_option (const char *string
)
954 if (use_compress_program_option
955 && strcmp (use_compress_program_option
, string
) != 0)
956 USAGE_ERROR ((0, 0, _("Conflicting compression options")));
958 use_compress_program_option
= string
;
965 print_total_stats ();
966 #ifndef HAVE_SIGACTION
967 signal (signo
, sigstat
);
972 stat_on_signal (int signo
)
974 #ifdef HAVE_SIGACTION
975 struct sigaction act
;
976 act
.sa_handler
= sigstat
;
977 sigemptyset (&act
.sa_mask
);
979 sigaction (signo
, &act
, NULL
);
981 signal (signo
, sigstat
);
986 set_stat_signal (const char *name
)
993 { "SIGUSR1", SIGUSR1
},
995 { "SIGUSR2", SIGUSR2
},
997 { "SIGHUP", SIGHUP
},
999 { "SIGINT", SIGINT
},
1001 { "SIGQUIT", SIGQUIT
},
1006 for (p
= sigtab
; p
< sigtab
+ sizeof (sigtab
) / sizeof (sigtab
[0]); p
++)
1007 if (strcmp (p
->name
, name
) == 0)
1009 stat_on_signal (p
->signo
);
1012 FATAL_ERROR ((0, 0, _("Unknown signal name: %s"), name
));
1018 struct textual_date
*next
;
1019 struct timespec
*ts
;
1025 get_date_or_file (struct tar_args
*args
, const char *option
,
1026 const char *str
, struct timespec
*ts
)
1028 if (FILE_SYSTEM_PREFIX_LEN (str
) != 0
1033 if (deref_stat (dereference_option
, str
, &st
) != 0)
1036 USAGE_ERROR ((0, 0, _("Date sample file not found")));
1038 *ts
= get_stat_mtime (&st
);
1042 if (! get_date (ts
, str
, NULL
))
1044 WARN ((0, 0, _("Substituting %s for unknown date format %s"),
1045 tartime (*ts
, false), quote (str
)));
1050 struct textual_date
*p
= xmalloc (sizeof (*p
));
1054 p
->next
= args
->textual_date
;
1055 args
->textual_date
= p
;
1061 report_textual_dates (struct tar_args
*args
)
1063 struct textual_date
*p
;
1064 for (p
= args
->textual_date
; p
; )
1066 struct textual_date
*next
= p
->next
;
1067 char const *treated_as
= tartime (*p
->ts
, true);
1068 if (strcmp (p
->date
, treated_as
) != 0)
1069 WARN ((0, 0, _("Option %s: Treating date `%s' as %s"),
1070 p
->option
, p
->date
, treated_as
));
1077 static volatile int _argp_hang
;
1079 /* Either NL or NUL, as decided by the --null option. */
1080 static char filename_terminator
;
1082 enum read_file_list_state
/* Result of reading file name from the list file */
1084 file_list_success
, /* OK, name read successfully */
1085 file_list_end
, /* End of list file */
1086 file_list_zero
, /* Zero separator encountered where it should not */
1087 file_list_skip
/* Empty (zero-length) entry encountered, skip it */
1090 /* Read from FP a sequence of characters up to TERM and put them
1093 static enum read_file_list_state
1094 read_name_from_file (FILE *fp
, struct obstack
*stk
, int term
)
1099 for (c
= getc (fp
); c
!= EOF
&& c
!= term
; c
= getc (fp
))
1103 /* We have read a zero separator. The file possibly is
1105 return file_list_zero
;
1107 obstack_1grow (stk
, c
);
1111 if (counter
== 0 && c
!= EOF
)
1112 return file_list_skip
;
1114 obstack_1grow (stk
, 0);
1116 return (counter
== 0 && c
== EOF
) ? file_list_end
: file_list_success
;
1120 static bool files_from_option
; /* When set, tar will not refuse to create
1122 static struct obstack argv_stk
; /* Storage for additional command line options
1123 read using -T option */
1125 /* Prevent recursive inclusion of the same file */
1128 struct file_id_list
*next
;
1133 static struct file_id_list
*file_id_list
;
1136 add_file_id (const char *filename
)
1138 struct file_id_list
*p
;
1141 if (stat (filename
, &st
))
1142 stat_fatal (filename
);
1143 for (p
= file_id_list
; p
; p
= p
->next
)
1144 if (p
->ino
== st
.st_ino
&& p
->dev
== st
.st_dev
)
1146 FATAL_ERROR ((0, 0, _("%s: file list already read"),
1147 quotearg_colon (filename
)));
1149 p
= xmalloc (sizeof *p
);
1150 p
->next
= file_id_list
;
1156 /* Default density numbers for [0-9][lmh] device specifications */
1158 #ifndef LOW_DENSITY_NUM
1159 # define LOW_DENSITY_NUM 0
1162 #ifndef MID_DENSITY_NUM
1163 # define MID_DENSITY_NUM 8
1166 #ifndef HIGH_DENSITY_NUM
1167 # define HIGH_DENSITY_NUM 16
1171 update_argv (const char *filename
, struct argp_state
*state
)
1174 size_t count
= 0, i
;
1178 bool is_stdin
= false;
1179 enum read_file_list_state read_state
;
1180 int term
= filename_terminator
;
1182 if (!strcmp (filename
, "-"))
1185 request_stdin ("-T");
1190 add_file_id (filename
);
1191 if ((fp
= fopen (filename
, "r")) == NULL
)
1192 open_fatal (filename
);
1195 while ((read_state
= read_name_from_file (fp
, &argv_stk
, term
))
1200 case file_list_success
:
1204 case file_list_end
: /* won't happen, just to pacify gcc */
1207 case file_list_zero
:
1211 WARNOPT (WARN_FILENAME_WITH_NULS
,
1212 (0, 0, N_("%s: file name read contains nul character"),
1213 quotearg_colon (filename
)));
1215 /* Prepare new stack contents */
1216 size
= obstack_object_size (&argv_stk
);
1217 p
= obstack_finish (&argv_stk
);
1218 for (; size
> 0; size
--, p
++)
1220 obstack_1grow (&argv_stk
, *p
);
1222 obstack_1grow (&argv_stk
, '\n');
1223 obstack_1grow (&argv_stk
, 0);
1225 /* Read rest of files using new filename terminator */
1230 case file_list_skip
:
1241 start
= obstack_finish (&argv_stk
);
1244 for (p
= start
; *p
; p
+= strlen (p
) + 1)
1248 new_argc
= state
->argc
+ count
;
1249 new_argv
= xmalloc (sizeof (state
->argv
[0]) * (new_argc
+ 1));
1250 memcpy (new_argv
, state
->argv
, sizeof (state
->argv
[0]) * (state
->argc
+ 1));
1251 state
->argv
= new_argv
;
1252 memmove (&state
->argv
[state
->next
+ count
], &state
->argv
[state
->next
],
1253 (state
->argc
- state
->next
+ 1) * sizeof (state
->argv
[0]));
1255 state
->argc
= new_argc
;
1257 for (i
= state
->next
, p
= start
; *p
; p
+= strlen (p
) + 1, i
++)
1259 if (term
== 0 && p
[0] == '-')
1260 state
->argv
[i
++] = "--add-file";
1267 tar_help (struct argp_state
*state
)
1269 argp_fmtstream_t fs
;
1270 state
->flags
|= ARGP_NO_EXIT
;
1271 argp_state_help (state
, state
->out_stream
,
1272 ARGP_HELP_STD_HELP
& ~ARGP_HELP_BUG_ADDR
);
1273 /* FIXME: use struct uparams.rmargin (from argp-help.c) instead of 79 */
1274 fs
= argp_make_fmtstream (state
->out_stream
, 0, 79, 0);
1276 argp_fmtstream_printf (fs
, "\n%s\n\n",
1277 _("Valid arguments for --quoting-style options are:"));
1278 tar_list_quoting_styles (fs
, " ");
1280 argp_fmtstream_puts (fs
, _("\n*This* tar defaults to:\n"));
1281 show_default_settings_fs (fs
);
1282 argp_fmtstream_putc (fs
, '\n');
1283 argp_fmtstream_printf (fs
, _("Report bugs to %s.\n"),
1284 argp_program_bug_address
);
1285 argp_fmtstream_free (fs
);
1289 parse_opt (int key
, char *arg
, struct argp_state
*state
)
1291 struct tar_args
*args
= state
->input
;
1296 /* File name or non-parsed option, because of ARGP_IN_ORDER */
1297 name_add_name (arg
, MAKE_INCL_OPTIONS (args
));
1298 args
->input_files
= true;
1302 set_subcommand_option (CAT_SUBCOMMAND
);
1306 args
->compress_autodetect
= true;
1309 case NO_AUTO_COMPRESS_OPTION
:
1310 args
->compress_autodetect
= false;
1316 if (! (xstrtoumax (arg
, 0, 10, &u
, "") == LONGINT_OK
1317 && u
== (blocking_factor
= u
)
1318 && 0 < blocking_factor
1319 && u
== (record_size
= u
* BLOCKSIZE
) / BLOCKSIZE
))
1320 USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (arg
),
1321 _("Invalid blocking factor")));
1326 /* Try to reblock input records. For reading 4.2BSD pipes. */
1328 /* It would surely make sense to exchange -B and -R, but it seems
1329 that -B has been used for a long while in Sun tar and most
1330 BSD-derived systems. This is a consequence of the block/record
1331 terminology confusion. */
1333 read_full_records_option
= true;
1337 set_subcommand_option (CREATE_SUBCOMMAND
);
1345 set_subcommand_option (DIFF_SUBCOMMAND
);
1349 if (archive_names
== allocated_archive_names
)
1350 archive_name_array
= x2nrealloc (archive_name_array
,
1351 &allocated_archive_names
,
1352 sizeof (archive_name_array
[0]));
1354 archive_name_array
[archive_names
++] = arg
;
1358 /* Since -F is only useful with -M, make it implied. Run this
1359 script at the end of each tape. */
1361 info_script_option
= arg
;
1362 multi_volume_option
= true;
1366 listed_incremental_option
= arg
;
1367 after_date_option
= true;
1371 /* We are making an incremental dump (FIXME: are we?); save
1372 directories at the beginning of the archive, and include in each
1373 directory its contents. */
1375 incremental_option
= true;
1379 /* Follow symbolic links. */
1380 dereference_option
= true;
1383 case HARD_DEREFERENCE_OPTION
:
1384 hard_dereference_option
= true;
1388 /* Ignore zero blocks (eofs). This can't be the default,
1389 because Unix tar writes two blocks of zeros, then pads out
1390 the record with garbage. */
1392 ignore_zeros_option
= true;
1396 set_use_compress_program_option ("bzip2");
1400 set_use_compress_program_option ("xz");
1404 /* Don't replace existing files. */
1405 old_files_option
= KEEP_OLD_FILES
;
1409 starting_file_option
= true;
1410 addname (arg
, 0, true, NULL
);
1413 case ONE_FILE_SYSTEM_OPTION
:
1414 /* When dumping directories, don't dump files/subdirectories
1415 that are on other filesystems. */
1416 one_file_system_option
= true;
1420 check_links_option
= 1;
1426 if (xstrtoumax (arg
, 0, 10, &u
, "") != LONGINT_OK
)
1427 USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (arg
),
1428 _("Invalid tape length")));
1429 tape_length_option
= 1024 * (tarlong
) u
;
1430 multi_volume_option
= true;
1437 incremental_level
= strtoul (arg
, &p
, 10);
1439 USAGE_ERROR ((0, 0, _("Invalid incremental level value")));
1444 set_use_compress_program_option ("lzma");
1448 set_use_compress_program_option ("lzop");
1452 touch_option
= true;
1456 /* Make multivolume archive: when we can't write any more into
1457 the archive, re-open it, and continue writing. */
1459 multi_volume_option
= true;
1463 get_date_or_file (args
, "--mtime", arg
, &mtime_option
);
1464 set_mtime_option
= true;
1471 case NO_SEEK_OPTION
:
1476 after_date_option
= true;
1479 case NEWER_MTIME_OPTION
:
1480 if (NEWER_OPTION_INITIALIZED (newer_mtime_option
))
1481 USAGE_ERROR ((0, 0, _("More than one threshold date")));
1482 get_date_or_file (args
,
1483 key
== NEWER_MTIME_OPTION
? "--newer-mtime"
1484 : "--after-date", arg
, &newer_mtime_option
);
1488 args
->o_option
= true;
1492 to_stdout_option
= true;
1496 same_permissions_option
= true;
1500 absolute_names_option
= true;
1504 set_subcommand_option (APPEND_SUBCOMMAND
);
1508 /* Print block numbers for debugging bad tar archives. */
1510 /* It would surely make sense to exchange -B and -R, but it seems
1511 that -B has been used for a long while in Sun tar and most
1512 BSD-derived systems. This is a consequence of the block/record
1513 terminology confusion. */
1515 block_number_option
= true;
1519 /* Names to extract are sorted. */
1521 same_order_option
= true;
1525 sparse_option
= true;
1528 case SPARSE_VERSION_OPTION
:
1529 sparse_option
= true;
1532 tar_sparse_major
= strtoul (arg
, &p
, 10);
1536 USAGE_ERROR ((0, 0, _("Invalid sparse version value")));
1537 tar_sparse_minor
= strtoul (p
+ 1, &p
, 10);
1539 USAGE_ERROR ((0, 0, _("Invalid sparse version value")));
1545 set_subcommand_option (LIST_SUBCOMMAND
);
1549 case TEST_LABEL_OPTION
:
1550 set_subcommand_option (LIST_SUBCOMMAND
);
1551 test_label_option
= true;
1555 update_argv (arg
, state
);
1556 /* Indicate we've been given -T option. This is for backward
1557 compatibility only, so that `tar cfT archive /dev/null will
1559 files_from_option
= true;
1563 set_subcommand_option (UPDATE_SUBCOMMAND
);
1567 old_files_option
= UNLINK_FIRST_OLD_FILES
;
1576 warning_option
|= WARN_VERBOSE_WARNINGS
;
1580 volume_label_option
= arg
;
1584 interactive_option
= true;
1588 verify_option
= true;
1592 set_subcommand_option (EXTRACT_SUBCOMMAND
);
1596 if (add_exclude_file (add_exclude
, excluded
, arg
,
1597 MAKE_EXCL_OPTIONS (args
), '\n')
1601 FATAL_ERROR ((0, e
, "%s", quotearg_colon (arg
)));
1606 set_use_compress_program_option ("gzip");
1610 set_use_compress_program_option ("compress");
1613 case ANCHORED_OPTION
:
1614 args
->matching_flags
|= EXCLUDE_ANCHORED
;
1617 case ATIME_PRESERVE_OPTION
:
1618 atime_preserve_option
=
1620 ? XARGMATCH ("--atime-preserve", arg
,
1621 atime_preserve_args
, atime_preserve_types
)
1622 : replace_atime_preserve
);
1623 if (! O_NOATIME
&& atime_preserve_option
== system_atime_preserve
)
1625 _("--atime-preserve='system' is not supported"
1626 " on this platform")));
1629 case CHECK_DEVICE_OPTION
:
1630 check_device_option
= true;
1633 case NO_CHECK_DEVICE_OPTION
:
1634 check_device_option
= false;
1637 case CHECKPOINT_OPTION
:
1644 checkpoint_compile_action (".");
1647 checkpoint_option
= strtoul (arg
, &p
, 0);
1650 _("--checkpoint value is not an integer")));
1653 checkpoint_option
= DEFAULT_CHECKPOINT
;
1656 case CHECKPOINT_ACTION_OPTION
:
1657 checkpoint_compile_action (arg
);
1661 backup_option
= true;
1663 args
->version_control_string
= arg
;
1666 case DELAY_DIRECTORY_RESTORE_OPTION
:
1667 delay_directory_restore_option
= true;
1670 case NO_DELAY_DIRECTORY_RESTORE_OPTION
:
1671 delay_directory_restore_option
= false;
1675 set_subcommand_option (DELETE_SUBCOMMAND
);
1678 case EXCLUDE_BACKUPS_OPTION
:
1679 add_exclude_array (backup_file_table
);
1682 case EXCLUDE_OPTION
:
1683 add_exclude (excluded
, arg
, MAKE_EXCL_OPTIONS (args
));
1686 case EXCLUDE_CACHES_OPTION
:
1687 add_exclusion_tag ("CACHEDIR.TAG", exclusion_tag_contents
,
1691 case EXCLUDE_CACHES_UNDER_OPTION
:
1692 add_exclusion_tag ("CACHEDIR.TAG", exclusion_tag_under
,
1696 case EXCLUDE_CACHES_ALL_OPTION
:
1697 add_exclusion_tag ("CACHEDIR.TAG", exclusion_tag_all
,
1701 case EXCLUDE_TAG_OPTION
:
1702 add_exclusion_tag (arg
, exclusion_tag_contents
, NULL
);
1705 case EXCLUDE_TAG_UNDER_OPTION
:
1706 add_exclusion_tag (arg
, exclusion_tag_under
, NULL
);
1709 case EXCLUDE_TAG_ALL_OPTION
:
1710 add_exclusion_tag (arg
, exclusion_tag_all
, NULL
);
1713 case EXCLUDE_VCS_OPTION
:
1714 add_exclude_array (vcs_file_table
);
1717 case FORCE_LOCAL_OPTION
:
1718 force_local_option
= true;
1722 set_archive_format (arg
);
1725 case INDEX_FILE_OPTION
:
1726 index_file_name
= arg
;
1729 case IGNORE_CASE_OPTION
:
1730 args
->matching_flags
|= FNM_CASEFOLD
;
1733 case IGNORE_COMMAND_ERROR_OPTION
:
1734 ignore_command_error_option
= true;
1737 case IGNORE_FAILED_READ_OPTION
:
1738 ignore_failed_read_option
= true;
1741 case KEEP_NEWER_FILES_OPTION
:
1742 old_files_option
= KEEP_NEWER_FILES
;
1746 if (! (strlen (arg
) < GNAME_FIELD_SIZE
1747 && gname_to_gid (arg
, &group_option
)))
1750 if (xstrtoumax (arg
, 0, 10, &g
, "") == LONGINT_OK
1754 FATAL_ERROR ((0, 0, "%s: %s", quotearg_colon (arg
),
1755 _("%s: Invalid group")));
1760 mode_option
= mode_compile (arg
);
1762 FATAL_ERROR ((0, 0, _("Invalid mode given on option")));
1763 initial_umask
= umask (0);
1764 umask (initial_umask
);
1767 case NO_ANCHORED_OPTION
:
1768 args
->include_anchored
= 0; /* Clear the default for comman line args */
1769 args
->matching_flags
&= ~ EXCLUDE_ANCHORED
;
1772 case NO_IGNORE_CASE_OPTION
:
1773 args
->matching_flags
&= ~ FNM_CASEFOLD
;
1776 case NO_IGNORE_COMMAND_ERROR_OPTION
:
1777 ignore_command_error_option
= false;
1780 case NO_OVERWRITE_DIR_OPTION
:
1781 old_files_option
= NO_OVERWRITE_DIR_OLD_FILES
;
1784 case NO_QUOTE_CHARS_OPTION
:
1786 set_char_quoting (NULL
, *arg
, 0);
1789 case NO_WILDCARDS_OPTION
:
1790 args
->wildcards
= disable_wildcards
;
1793 case NO_WILDCARDS_MATCH_SLASH_OPTION
:
1794 args
->matching_flags
|= FNM_FILE_NAME
;
1798 filename_terminator
= '\0';
1801 case NO_NULL_OPTION
:
1802 filename_terminator
= '\n';
1805 case NUMERIC_OWNER_OPTION
:
1806 numeric_owner_option
= true;
1809 case OCCURRENCE_OPTION
:
1811 occurrence_option
= 1;
1815 if (xstrtoumax (arg
, 0, 10, &u
, "") == LONGINT_OK
)
1816 occurrence_option
= u
;
1818 FATAL_ERROR ((0, 0, "%s: %s", quotearg_colon (arg
),
1819 _("Invalid number")));
1823 case OVERWRITE_DIR_OPTION
:
1824 old_files_option
= DEFAULT_OLD_FILES
;
1827 case OVERWRITE_OPTION
:
1828 old_files_option
= OVERWRITE_OLD_FILES
;
1832 if (! (strlen (arg
) < UNAME_FIELD_SIZE
1833 && uname_to_uid (arg
, &owner_option
)))
1836 if (xstrtoumax (arg
, 0, 10, &u
, "") == LONGINT_OK
1840 FATAL_ERROR ((0, 0, "%s: %s", quotearg_colon (arg
),
1841 _("Invalid owner")));
1845 case QUOTE_CHARS_OPTION
:
1847 set_char_quoting (NULL
, *arg
, 1);
1850 case QUOTING_STYLE_OPTION
:
1851 tar_set_quoting_style (arg
);
1855 args
->pax_option
= true;
1856 xheader_set_option (arg
);
1860 set_archive_format ("posix");
1863 case PRESERVE_OPTION
:
1864 /* FIXME: What it is good for? */
1865 same_permissions_option
= true;
1866 same_order_option
= true;
1867 WARN ((0, 0, _("The --preserve option is deprecated, "
1868 "use --preserve-permissions --preserve-order instead")));
1871 case RECORD_SIZE_OPTION
:
1874 if (! (xstrtoumax (arg
, 0, 10, &u
, "") == LONGINT_OK
1875 && u
== (size_t) u
))
1876 USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (arg
),
1877 _("Invalid record size")));
1879 if (record_size
% BLOCKSIZE
!= 0)
1880 USAGE_ERROR ((0, 0, _("Record size must be a multiple of %d."),
1882 blocking_factor
= record_size
/ BLOCKSIZE
;
1886 case RECURSIVE_UNLINK_OPTION
:
1887 recursive_unlink_option
= true;
1890 case REMOVE_FILES_OPTION
:
1891 remove_files_option
= true;
1894 case RESTRICT_OPTION
:
1895 restrict_option
= true;
1898 case RMT_COMMAND_OPTION
:
1902 case RSH_COMMAND_OPTION
:
1903 rsh_command_option
= arg
;
1906 case SHOW_DEFAULTS_OPTION
:
1907 show_default_settings (stdout
);
1911 case STRIP_COMPONENTS_OPTION
:
1914 if (! (xstrtoumax (arg
, 0, 10, &u
, "") == LONGINT_OK
1915 && u
== (size_t) u
))
1916 USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (arg
),
1917 _("Invalid number of elements")));
1918 strip_name_components
= u
;
1922 case SHOW_OMITTED_DIRS_OPTION
:
1923 show_omitted_dirs_option
= true;
1926 case SHOW_TRANSFORMED_NAMES_OPTION
:
1927 show_transformed_names_option
= true;
1931 backup_option
= true;
1932 args
->backup_suffix_string
= arg
;
1935 case TO_COMMAND_OPTION
:
1936 if (to_command_option
)
1937 USAGE_ERROR ((0, 0, _("Only one --to-command option allowed")));
1938 to_command_option
= arg
;
1943 set_stat_signal (arg
);
1945 totals_option
= true;
1948 case TRANSFORM_OPTION
:
1949 set_transform_expr (arg
);
1953 set_use_compress_program_option (arg
);
1956 case VOLNO_FILE_OPTION
:
1957 volno_file_option
= arg
;
1960 case WILDCARDS_OPTION
:
1961 args
->wildcards
= enable_wildcards
;
1964 case WILDCARDS_MATCH_SLASH_OPTION
:
1965 args
->matching_flags
&= ~ FNM_FILE_NAME
;
1968 case NO_RECURSION_OPTION
:
1969 recursion_option
= 0;
1972 case NO_SAME_OWNER_OPTION
:
1973 same_owner_option
= -1;
1976 case NO_SAME_PERMISSIONS_OPTION
:
1977 same_permissions_option
= -1;
1980 case RECURSION_OPTION
:
1981 recursion_option
= FNM_LEADING_DIR
;
1984 case SAME_OWNER_OPTION
:
1985 same_owner_option
= 1;
1988 case UNQUOTE_OPTION
:
1989 unquote_option
= true;
1992 case NO_UNQUOTE_OPTION
:
1993 unquote_option
= false;
1996 case WARNING_OPTION
:
1997 set_warning_option (arg
);
2009 #ifdef DEVICE_PREFIX
2011 int device
= key
- '0';
2013 static char buf
[sizeof DEVICE_PREFIX
+ 10];
2017 argp_error (state
, _("Malformed density argument: %s"), quote (arg
));
2019 strcpy (buf
, DEVICE_PREFIX
);
2020 cursor
= buf
+ strlen (buf
);
2022 #ifdef DENSITY_LETTER
2024 sprintf (cursor
, "%d%c", device
, arg
[0]);
2026 #else /* not DENSITY_LETTER */
2031 device
+= LOW_DENSITY_NUM
;
2035 device
+= MID_DENSITY_NUM
;
2039 device
+= HIGH_DENSITY_NUM
;
2043 argp_error (state
, _("Unknown density: `%c'"), arg
[0]);
2045 sprintf (cursor
, "%d", device
);
2047 #endif /* not DENSITY_LETTER */
2049 if (archive_names
== allocated_archive_names
)
2050 archive_name_array
= x2nrealloc (archive_name_array
,
2051 &allocated_archive_names
,
2052 sizeof (archive_name_array
[0]));
2053 archive_name_array
[archive_names
++] = xstrdup (buf
);
2057 #else /* not DEVICE_PREFIX */
2060 _("Options `-[0-7][lmh]' not supported by *this* tar"));
2062 #endif /* not DEVICE_PREFIX */
2070 argp_state_help (state
, state
->out_stream
, ARGP_HELP_USAGE
);
2074 case VERSION_OPTION
:
2075 version_etc (state
->out_stream
, "tar", PACKAGE_NAME
, VERSION
,
2076 "John Gilmore", "Jay Fenlason", (char *) NULL
);
2081 _argp_hang
= atoi (arg
? arg
: "3600");
2082 while (_argp_hang
-- > 0)
2087 return ARGP_ERR_UNKNOWN
;
2092 static struct argp argp
= {
2105 argp_help (&argp
, stderr
, ARGP_HELP_SEE
, (char*) program_name
);
2110 /* Parse the options for tar. */
2112 static struct argp_option
*
2113 find_argp_option (struct argp_option
*o
, int letter
)
2120 && o
->doc
== NULL
); o
++)
2121 if (o
->key
== letter
)
2127 decode_options (int argc
, char **argv
)
2130 struct tar_args args
;
2132 /* Set some default option values. */
2133 args
.textual_date
= NULL
;
2134 args
.wildcards
= default_wildcards
;
2135 args
.matching_flags
= 0;
2136 args
.include_anchored
= EXCLUDE_ANCHORED
;
2137 args
.o_option
= false;
2138 args
.pax_option
= false;
2139 args
.backup_suffix_string
= getenv ("SIMPLE_BACKUP_SUFFIX");
2140 args
.version_control_string
= 0;
2141 args
.input_files
= false;
2142 args
.compress_autodetect
= false;
2144 subcommand_option
= UNKNOWN_SUBCOMMAND
;
2145 archive_format
= DEFAULT_FORMAT
;
2146 blocking_factor
= DEFAULT_BLOCKING
;
2147 record_size
= DEFAULT_BLOCKING
* BLOCKSIZE
;
2148 excluded
= new_exclude ();
2149 newer_mtime_option
.tv_sec
= TYPE_MINIMUM (time_t);
2150 newer_mtime_option
.tv_nsec
= -1;
2151 recursion_option
= FNM_LEADING_DIR
;
2152 unquote_option
= true;
2153 tar_sparse_major
= 1;
2154 tar_sparse_minor
= 0;
2159 check_device_option
= true;
2161 incremental_level
= -1;
2165 /* Convert old-style tar call by exploding option element and rearranging
2166 options accordingly. */
2168 if (argc
> 1 && argv
[1][0] != '-')
2170 int new_argc
; /* argc value for rearranged arguments */
2171 char **new_argv
; /* argv value for rearranged arguments */
2172 char *const *in
; /* cursor into original argv */
2173 char **out
; /* cursor into rearranged argv */
2174 const char *letter
; /* cursor into old option letters */
2175 char buffer
[3]; /* constructed option buffer */
2177 /* Initialize a constructed option. */
2182 /* Allocate a new argument array, and copy program name in it. */
2184 new_argc
= argc
- 1 + strlen (argv
[1]);
2185 new_argv
= xmalloc ((new_argc
+ 1) * sizeof (char *));
2190 /* Copy each old letter option as a separate option, and have the
2191 corresponding argument moved next to it. */
2193 for (letter
= *in
++; *letter
; letter
++)
2195 struct argp_option
*opt
;
2197 buffer
[1] = *letter
;
2198 *out
++ = xstrdup (buffer
);
2199 opt
= find_argp_option (options
, *letter
);
2200 if (opt
&& opt
->arg
)
2202 if (in
< argv
+ argc
)
2205 USAGE_ERROR ((0, 0, _("Old option `%c' requires an argument."),
2210 /* Copy all remaining options. */
2212 while (in
< argv
+ argc
)
2216 /* Replace the old option list by the new one. */
2222 /* Parse all options and non-options as they appear. */
2224 prepend_default_options (getenv ("TAR_OPTIONS"), &argc
, &argv
);
2226 if (argp_parse (&argp
, argc
, argv
, ARGP_IN_ORDER
|ARGP_NO_HELP
,
2228 exit (TAREXIT_FAILURE
);
2231 /* Special handling for 'o' option:
2233 GNU tar used to say "output old format".
2234 UNIX98 tar says don't chown files after extracting (we use
2235 "--no-same-owner" for this).
2237 The old GNU tar semantics is retained when used with --create
2238 option, otherwise UNIX98 semantics is assumed */
2242 if (subcommand_option
== CREATE_SUBCOMMAND
)
2244 /* GNU Tar <= 1.13 compatibility */
2245 set_archive_format ("v7");
2249 /* UNIX98 compatibility */
2250 same_owner_option
= -1;
2254 /* Handle operands after any "--" argument. */
2255 for (; idx
< argc
; idx
++)
2257 name_add_name (argv
[idx
], MAKE_INCL_OPTIONS (&args
));
2258 args
.input_files
= true;
2261 /* Warn about implicit use of the wildcards in command line arguments.
2263 warn_regex_usage
= args
.wildcards
== default_wildcards
;
2265 /* Derive option values and check option consistency. */
2267 if (archive_format
== DEFAULT_FORMAT
)
2269 if (args
.pax_option
)
2270 archive_format
= POSIX_FORMAT
;
2272 archive_format
= DEFAULT_ARCHIVE_FORMAT
;
2275 if ((volume_label_option
&& subcommand_option
== CREATE_SUBCOMMAND
)
2276 || incremental_option
2277 || multi_volume_option
2279 assert_format (FORMAT_MASK (OLDGNU_FORMAT
)
2280 | FORMAT_MASK (GNU_FORMAT
)
2281 | FORMAT_MASK (POSIX_FORMAT
));
2283 if (occurrence_option
)
2285 if (!args
.input_files
)
2287 _("--occurrence is meaningless without a file list")));
2288 if (subcommand_option
!= DELETE_SUBCOMMAND
2289 && subcommand_option
!= DIFF_SUBCOMMAND
2290 && subcommand_option
!= EXTRACT_SUBCOMMAND
2291 && subcommand_option
!= LIST_SUBCOMMAND
)
2293 _("--occurrence cannot be used in the requested operation mode")));
2296 if (archive_names
== 0)
2298 /* If no archive file name given, try TAPE from the environment, or
2299 else, DEFAULT_ARCHIVE from the configuration process. */
2302 archive_name_array
[0] = getenv ("TAPE");
2303 if (! archive_name_array
[0])
2304 archive_name_array
[0] = DEFAULT_ARCHIVE
;
2307 /* Allow multiple archives only with `-M'. */
2309 if (archive_names
> 1 && !multi_volume_option
)
2311 _("Multiple archive files require `-M' option")));
2313 if (listed_incremental_option
2314 && NEWER_OPTION_INITIALIZED (newer_mtime_option
))
2316 _("Cannot combine --listed-incremental with --newer")));
2317 if (incremental_level
!= -1 && !listed_incremental_option
)
2319 _("--level is meaningless without --listed-incremental")));
2321 if (volume_label_option
)
2323 if (archive_format
== GNU_FORMAT
|| archive_format
== OLDGNU_FORMAT
)
2325 size_t volume_label_max_len
=
2326 (sizeof current_header
->header
.name
2327 - 1 /* for trailing '\0' */
2328 - (multi_volume_option
2329 ? (sizeof " Volume "
2330 - 1 /* for null at end of " Volume " */
2331 + INT_STRLEN_BOUND (int) /* for volume number */
2332 - 1 /* for sign, as 0 <= volno */)
2334 if (volume_label_max_len
< strlen (volume_label_option
))
2336 ngettext ("%s: Volume label is too long (limit is %lu byte)",
2337 "%s: Volume label is too long (limit is %lu bytes)",
2338 volume_label_max_len
),
2339 quotearg_colon (volume_label_option
),
2340 (unsigned long) volume_label_max_len
));
2343 Label length in PAX format is limited by the volume size. */
2348 if (multi_volume_option
)
2349 USAGE_ERROR ((0, 0, _("Cannot verify multi-volume archives")));
2350 if (use_compress_program_option
)
2351 USAGE_ERROR ((0, 0, _("Cannot verify compressed archives")));
2354 if (use_compress_program_option
)
2356 if (multi_volume_option
)
2357 USAGE_ERROR ((0, 0, _("Cannot use multi-volume compressed archives")));
2358 if (subcommand_option
== UPDATE_SUBCOMMAND
2359 || subcommand_option
== APPEND_SUBCOMMAND
2360 || subcommand_option
== DELETE_SUBCOMMAND
)
2361 USAGE_ERROR ((0, 0, _("Cannot update compressed archives")));
2362 if (subcommand_option
== CAT_SUBCOMMAND
)
2363 USAGE_ERROR ((0, 0, _("Cannot concatenate compressed archives")));
2366 /* It is no harm to use --pax-option on non-pax archives in archive
2367 reading mode. It may even be useful, since it allows to override
2368 file attributes from tar headers. Therefore I allow such usage.
2371 && archive_format
!= POSIX_FORMAT
2372 && (subcommand_option
!= EXTRACT_SUBCOMMAND
2373 || subcommand_option
!= DIFF_SUBCOMMAND
2374 || subcommand_option
!= LIST_SUBCOMMAND
))
2375 USAGE_ERROR ((0, 0, _("--pax-option can be used only on POSIX archives")));
2377 /* If ready to unlink hierarchies, so we are for simpler files. */
2378 if (recursive_unlink_option
)
2379 old_files_option
= UNLINK_FIRST_OLD_FILES
;
2382 if (test_label_option
)
2384 /* --test-label is silent if the user has specified the label name to
2386 if (!args
.input_files
)
2389 else if (utc_option
)
2392 if (tape_length_option
&& tape_length_option
< record_size
)
2393 USAGE_ERROR ((0, 0, _("Volume length cannot be less than record size")));
2395 if (same_order_option
&& listed_incremental_option
)
2396 USAGE_ERROR ((0, 0, _("--preserve-order is not compatible with "
2397 "--listed-incremental")));
2399 /* Forbid using -c with no input files whatsoever. Check that `-f -',
2400 explicit or implied, is used correctly. */
2402 switch (subcommand_option
)
2404 case CREATE_SUBCOMMAND
:
2405 if (!args
.input_files
&& !files_from_option
)
2407 _("Cowardly refusing to create an empty archive")));
2408 if (args
.compress_autodetect
&& archive_names
2409 && strcmp (archive_name_array
[0], "-"))
2410 set_comression_program_by_suffix (archive_name_array
[0],
2411 use_compress_program_option
);
2414 case EXTRACT_SUBCOMMAND
:
2415 case LIST_SUBCOMMAND
:
2416 case DIFF_SUBCOMMAND
:
2417 for (archive_name_cursor
= archive_name_array
;
2418 archive_name_cursor
< archive_name_array
+ archive_names
;
2419 archive_name_cursor
++)
2420 if (!strcmp (*archive_name_cursor
, "-"))
2421 request_stdin ("-f");
2424 case CAT_SUBCOMMAND
:
2425 case UPDATE_SUBCOMMAND
:
2426 case APPEND_SUBCOMMAND
:
2427 for (archive_name_cursor
= archive_name_array
;
2428 archive_name_cursor
< archive_name_array
+ archive_names
;
2429 archive_name_cursor
++)
2430 if (!strcmp (*archive_name_cursor
, "-"))
2432 _("Options `-Aru' are incompatible with `-f -'")));
2438 /* Initialize stdlis */
2439 if (index_file_name
)
2441 stdlis
= fopen (index_file_name
, "w");
2443 open_error (index_file_name
);
2446 stdlis
= to_stdout_option
? stderr
: stdout
;
2448 archive_name_cursor
= archive_name_array
;
2450 /* Prepare for generating backup names. */
2452 if (args
.backup_suffix_string
)
2453 simple_backup_suffix
= xstrdup (args
.backup_suffix_string
);
2457 backup_type
= xget_version ("--backup", args
.version_control_string
);
2458 /* No backup is needed either if explicitely disabled or if
2459 the extracted files are not being written to disk. */
2460 if (backup_type
== no_backups
|| EXTRACT_OVER_PIPE
)
2461 backup_option
= false;
2464 checkpoint_finish_compile ();
2467 report_textual_dates (&args
);
2473 /* Main routine for tar. */
2475 main (int argc
, char **argv
)
2478 program_name
= argv
[0];
2480 setlocale (LC_ALL
, "");
2481 bindtextdomain (PACKAGE
, LOCALEDIR
);
2482 textdomain (PACKAGE
);
2484 exit_failure
= TAREXIT_FAILURE
;
2485 exit_status
= TAREXIT_SUCCESS
;
2486 filename_terminator
= '\n';
2487 set_quoting_style (0, DEFAULT_QUOTING_STYLE
);
2489 /* Make sure we have first three descriptors available */
2492 /* Pre-allocate a few structures. */
2494 allocated_archive_names
= 10;
2495 archive_name_array
=
2496 xmalloc (sizeof (const char *) * allocated_archive_names
);
2499 obstack_init (&argv_stk
);
2501 /* Ensure default behavior for some signals */
2502 signal (SIGPIPE
, SIG_DFL
);
2503 /* System V fork+wait does not work if SIGCHLD is ignored. */
2504 signal (SIGCHLD
, SIG_DFL
);
2506 /* Try to disable the ability to unlink a directory. */
2507 priv_set_remove_linkdir ();
2509 /* Decode options. */
2511 decode_options (argc
, argv
);
2515 /* Main command execution. */
2517 if (volno_file_option
)
2518 init_volume_number ();
2520 switch (subcommand_option
)
2522 case UNKNOWN_SUBCOMMAND
:
2524 _("You must specify one of the `-Acdtrux' options")));
2526 case CAT_SUBCOMMAND
:
2527 case UPDATE_SUBCOMMAND
:
2528 case APPEND_SUBCOMMAND
:
2532 case DELETE_SUBCOMMAND
:
2533 delete_archive_members ();
2536 case CREATE_SUBCOMMAND
:
2540 case EXTRACT_SUBCOMMAND
:
2542 read_and (extract_archive
);
2544 /* FIXME: should extract_finish () even if an ordinary signal is
2550 case LIST_SUBCOMMAND
:
2551 read_and (list_archive
);
2554 case DIFF_SUBCOMMAND
:
2556 read_and (diff_archive
);
2561 print_total_stats ();
2563 if (check_links_option
)
2566 if (volno_file_option
)
2567 closeout_volume_number ();
2569 /* Dispose of allocated memory, and return. */
2571 free (archive_name_array
);
2574 if (exit_status
== TAREXIT_FAILURE
)
2575 error (0, 0, _("Exiting with failure status due to previous errors"));
2577 if (stdlis
== stdout
)
2579 else if (ferror (stderr
) || fclose (stderr
) != 0)
2580 exit_status
= TAREXIT_FAILURE
;
2586 tar_stat_init (struct tar_stat_info
*st
)
2588 memset (st
, 0, sizeof (*st
));
2592 tar_stat_destroy (struct tar_stat_info
*st
)
2594 free (st
->orig_file_name
);
2595 free (st
->file_name
);
2596 free (st
->link_name
);
2599 free (st
->sparse_map
);
2601 xheader_destroy (&st
->xhdr
);
2602 memset (st
, 0, sizeof (*st
));
2605 /* Format mask for all available formats that support nanosecond
2606 timestamp resolution. */
2607 #define NS_PRECISION_FORMAT_MASK FORMAT_MASK (POSIX_FORMAT)
2609 /* Same as timespec_cmp, but ignore nanoseconds if current archive
2610 format does not provide sufficient resolution. */
2612 tar_timespec_cmp (struct timespec a
, struct timespec b
)
2614 if (!(FORMAT_MASK (current_format
) & NS_PRECISION_FORMAT_MASK
))
2615 a
.tv_nsec
= b
.tv_nsec
= 0;
2616 return timespec_cmp (a
, b
);