New option: --set-mtime-command
[tar.git] / src / tar.c
blob98132e79b1a043912c659ec9d06a71b337cc6b88
1 /* A tar (tape archiver) program.
3 Copyright 1988-2023 Free Software Foundation, Inc.
5 Written by John Gilmore, starting 1985-08-25.
7 This program is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 3, or (at your option) any later
10 version.
12 This program is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
15 Public License for more details.
17 You should have received a copy of the GNU General Public License along
18 with this program. If not, see <http://www.gnu.org/licenses/>. */
20 #include <system.h>
22 #include <fnmatch.h>
23 #include <argp.h>
24 #include <argp-namefrob.h>
25 #include <argp-fmtstream.h>
26 #include <argp-version-etc.h>
28 #include <signal.h>
29 #if ! defined SIGCHLD && defined SIGCLD
30 # define SIGCHLD SIGCLD
31 #endif
33 /* The following causes "common.h" to produce definitions of all the global
34 variables, rather than just "extern" declarations of them. GNU tar does
35 depend on the system loader to preset all GLOBAL variables to neutral (or
36 zero) values; explicit initialization is usually not done. */
37 #define GLOBAL
38 #include "common.h"
40 #include <argmatch.h>
41 #include <closeout.h>
42 #include <configmake.h>
43 #include <exitfail.h>
44 #include <parse-datetime.h>
45 #include <rmt.h>
46 #include <rmt-command.h>
47 #include <wordsplit.h>
48 #include <sysexits.h>
49 #include <quotearg.h>
50 #include <verify.h>
51 #include <version-etc.h>
52 #include <xstrtol.h>
53 #include <stdopen.h>
54 #include <priv-set.h>
55 #include <savedir.h>
57 /* Local declarations. */
59 #ifndef DEFAULT_ARCHIVE_FORMAT
60 # define DEFAULT_ARCHIVE_FORMAT GNU_FORMAT
61 #endif
63 #ifndef DEFAULT_ARCHIVE
64 # define DEFAULT_ARCHIVE "tar.out"
65 #endif
67 #ifndef DEFAULT_BLOCKING
68 # define DEFAULT_BLOCKING 20
69 #endif
71 /* Print a message if not all links are dumped */
72 static int check_links_option;
74 /* Number of allocated tape drive names. */
75 static size_t allocated_archive_names;
78 /* Miscellaneous. */
80 /* Name of option using stdin. */
81 static const char *stdin_used_by;
83 /* Doesn't return if stdin already requested. */
84 void
85 request_stdin (const char *option)
87 if (stdin_used_by)
88 USAGE_ERROR ((0, 0, _("Options '%s' and '%s' both want standard input"),
89 stdin_used_by, option));
91 stdin_used_by = option;
94 extern int rpmatch (char const *response);
96 /* Returns true if and only if the user typed an affirmative response. */
97 int
98 confirm (const char *message_action, const char *message_name)
100 static FILE *confirm_file;
101 static int confirm_file_EOF;
102 bool status = false;
104 if (!confirm_file)
106 if (archive == 0 || stdin_used_by)
108 confirm_file = fopen (TTY_NAME, "r");
109 if (! confirm_file)
110 open_fatal (TTY_NAME);
112 else
114 request_stdin ("-w");
115 confirm_file = stdin;
119 fprintf (stdlis, "%s %s?", message_action, quote (message_name));
120 fflush (stdlis);
122 if (!confirm_file_EOF)
124 char *response = NULL;
125 size_t response_size = 0;
126 if (getline (&response, &response_size, confirm_file) < 0)
127 confirm_file_EOF = 1;
128 else
129 status = rpmatch (response) > 0;
130 free (response);
133 if (confirm_file_EOF)
135 fputc ('\n', stdlis);
136 fflush (stdlis);
139 return status;
142 static struct fmttab {
143 char const *name;
144 enum archive_format fmt;
145 } const fmttab[] = {
146 { "v7", V7_FORMAT },
147 { "oldgnu", OLDGNU_FORMAT },
148 { "ustar", USTAR_FORMAT },
149 { "posix", POSIX_FORMAT },
150 #if 0 /* not fully supported yet */
151 { "star", STAR_FORMAT },
152 #endif
153 { "gnu", GNU_FORMAT },
154 { "pax", POSIX_FORMAT }, /* An alias for posix */
155 { NULL, 0 }
158 static void
159 set_archive_format (char const *name)
161 struct fmttab const *p;
163 for (p = fmttab; strcmp (p->name, name) != 0; )
164 if (! (++p)->name)
165 USAGE_ERROR ((0, 0, _("%s: Invalid archive format"),
166 quotearg_colon (name)));
168 archive_format = p->fmt;
171 static void
172 set_xattr_option (int value)
174 if (value == 1)
175 set_archive_format ("posix");
176 xattrs_option = value;
179 const char *
180 archive_format_string (enum archive_format fmt)
182 struct fmttab const *p;
184 for (p = fmttab; p->name; p++)
185 if (p->fmt == fmt)
186 return p->name;
187 return "unknown?";
190 #define FORMAT_MASK(n) (1<<(n))
192 static void
193 assert_format(unsigned fmt_mask)
195 if ((FORMAT_MASK (archive_format) & fmt_mask) == 0)
196 USAGE_ERROR ((0, 0,
197 _("GNU features wanted on incompatible archive format")));
200 const char *
201 subcommand_string (enum subcommand c)
203 switch (c)
205 case UNKNOWN_SUBCOMMAND:
206 return "unknown?";
208 case APPEND_SUBCOMMAND:
209 return "-r";
211 case CAT_SUBCOMMAND:
212 return "-A";
214 case CREATE_SUBCOMMAND:
215 return "-c";
217 case DELETE_SUBCOMMAND:
218 return "-D";
220 case DIFF_SUBCOMMAND:
221 return "-d";
223 case EXTRACT_SUBCOMMAND:
224 return "-x";
226 case LIST_SUBCOMMAND:
227 return "-t";
229 case UPDATE_SUBCOMMAND:
230 return "-u";
232 case TEST_LABEL_SUBCOMMAND:
233 return "--test-label";
235 abort ();
238 static void
239 tar_list_quoting_styles (struct obstack *stk, char const *prefix)
241 int i;
242 size_t prefixlen = strlen (prefix);
244 for (i = 0; quoting_style_args[i]; i++)
246 obstack_grow (stk, prefix, prefixlen);
247 obstack_grow (stk, quoting_style_args[i],
248 strlen (quoting_style_args[i]));
249 obstack_1grow (stk, '\n');
253 static void
254 tar_set_quoting_style (char *arg)
256 int i;
258 for (i = 0; quoting_style_args[i]; i++)
259 if (strcmp (arg, quoting_style_args[i]) == 0)
261 set_quoting_style (NULL, i);
262 return;
264 FATAL_ERROR ((0, 0,
265 _("Unknown quoting style '%s'. Try '%s --quoting-style=help' to get a list."), arg, program_name));
269 /* Options. */
271 enum
273 ACLS_OPTION = CHAR_MAX + 1,
274 ATIME_PRESERVE_OPTION,
275 BACKUP_OPTION,
276 CHECK_DEVICE_OPTION,
277 CHECKPOINT_OPTION,
278 CHECKPOINT_ACTION_OPTION,
279 CLAMP_MTIME_OPTION,
280 DELAY_DIRECTORY_RESTORE_OPTION,
281 HARD_DEREFERENCE_OPTION,
282 DELETE_OPTION,
283 FORCE_LOCAL_OPTION,
284 FULL_TIME_OPTION,
285 GROUP_OPTION,
286 GROUP_MAP_OPTION,
287 IGNORE_COMMAND_ERROR_OPTION,
288 IGNORE_FAILED_READ_OPTION,
289 INDEX_FILE_OPTION,
290 KEEP_DIRECTORY_SYMLINK_OPTION,
291 KEEP_NEWER_FILES_OPTION,
292 LEVEL_OPTION,
293 LZIP_OPTION,
294 LZMA_OPTION,
295 LZOP_OPTION,
296 MODE_OPTION,
297 MTIME_OPTION,
298 NEWER_MTIME_OPTION,
299 NO_ACLS_OPTION,
300 NO_AUTO_COMPRESS_OPTION,
301 NO_CHECK_DEVICE_OPTION,
302 NO_DELAY_DIRECTORY_RESTORE_OPTION,
303 NO_IGNORE_COMMAND_ERROR_OPTION,
304 NO_OVERWRITE_DIR_OPTION,
305 NO_QUOTE_CHARS_OPTION,
306 NO_SAME_OWNER_OPTION,
307 NO_SAME_PERMISSIONS_OPTION,
308 NO_SEEK_OPTION,
309 NO_SELINUX_CONTEXT_OPTION,
310 NO_XATTR_OPTION,
311 NUMERIC_OWNER_OPTION,
312 OCCURRENCE_OPTION,
313 OLD_ARCHIVE_OPTION,
314 ONE_FILE_SYSTEM_OPTION,
315 ONE_TOP_LEVEL_OPTION,
316 OVERWRITE_DIR_OPTION,
317 OVERWRITE_OPTION,
318 OWNER_OPTION,
319 OWNER_MAP_OPTION,
320 PAX_OPTION,
321 POSIX_OPTION,
322 QUOTE_CHARS_OPTION,
323 QUOTING_STYLE_OPTION,
324 RECORD_SIZE_OPTION,
325 RECURSIVE_UNLINK_OPTION,
326 REMOVE_FILES_OPTION,
327 RESTRICT_OPTION,
328 RMT_COMMAND_OPTION,
329 RSH_COMMAND_OPTION,
330 SAME_OWNER_OPTION,
331 SELINUX_CONTEXT_OPTION,
332 SHOW_DEFAULTS_OPTION,
333 SHOW_OMITTED_DIRS_OPTION,
334 SHOW_SNAPSHOT_FIELD_RANGES_OPTION,
335 SHOW_TRANSFORMED_NAMES_OPTION,
336 SKIP_OLD_FILES_OPTION,
337 SORT_OPTION,
338 HOLE_DETECTION_OPTION,
339 SPARSE_VERSION_OPTION,
340 STRIP_COMPONENTS_OPTION,
341 SUFFIX_OPTION,
342 TEST_LABEL_OPTION,
343 TOTALS_OPTION,
344 TO_COMMAND_OPTION,
345 TRANSFORM_OPTION,
346 UTC_OPTION,
347 VOLNO_FILE_OPTION,
348 WARNING_OPTION,
349 XATTR_OPTION,
350 XATTR_EXCLUDE,
351 XATTR_INCLUDE,
352 ZSTD_OPTION,
353 SET_MTIME_COMMAND_OPTION,
354 SET_MTIME_FORMAT_OPTION,
357 static char const doc[] = N_("\
358 GNU 'tar' saves many files together into a single tape or disk archive, \
359 and can restore individual files from the archive.\n\
361 Examples:\n\
362 tar -cf archive.tar foo bar # Create archive.tar from files foo and bar.\n\
363 tar -tvf archive.tar # List all files in archive.tar verbosely.\n\
364 tar -xf archive.tar # Extract all files from archive.tar.\n")
365 "\v"
366 N_("The backup suffix is '~', unless set with --suffix or SIMPLE_BACKUP_SUFFIX.\n\
367 The version control may be set with --backup or VERSION_CONTROL, values are:\n\n\
368 none, off never make backups\n\
369 t, numbered make numbered backups\n\
370 nil, existing numbered if numbered backups exist, simple otherwise\n\
371 never, simple always make simple backups\n");
374 /* NOTE:
376 Available option letters are DEQY and eqy. Consider the following
377 assignments:
379 [For Solaris tar compatibility =/= Is it important at all?]
380 e exit immediately with a nonzero exit status if unexpected errors occur
381 E use extended headers (--format=posix)
383 [q alias for --occurrence=1 =/= this would better be used for quiet?]
385 y per-file gzip compression
386 Y per-block gzip compression.
388 Additionally, the 'n' letter is assigned for option --seek, which
389 is probably not needed and should be marked as deprecated, so that
390 -n may become available in the future.
393 /* Option group idenitfiers help in sorting options by category: */
394 enum
396 GRH_COMMAND,
397 GRID_COMMAND, /* Main operation mode */
399 GRH_MODIFIER,
400 GRID_MODIFIER, /* Operation modifiers */
402 GRID_FILE_NAME,
404 GRH_OVERWRITE,
405 GRID_OVERWRITE, /* Overwrite control options */
407 GRH_OUTPUT,
408 GRID_OUTPUT, /* Output stream selection */
410 GRH_FATTR,
411 GRID_FATTR, /* File attributes (ownership and mode) */
413 GRH_XATTR,
414 GRID_XATTR, /* Extended file attributes */
416 GRH_DEVICE,
417 GRID_DEVICE, /* Device selection */
419 GRH_BLOCKING,
420 GRID_BLOCKING, /* Block and record length */
422 GRH_FORMAT,
423 GRID_FORMAT, /* Archive format options */
424 GRDOC_FORMAT,
426 GRID_FORMAT_OPT,
428 GRH_COMPRESS,
429 GRID_COMPRESS, /* Compression options */
431 GRH_FILE,
432 GRID_FILE, /* File selection options */
434 GRH_NAME_XFORM,
435 GRID_NAME_XFORM, /* File name transformations */
437 GRH_INFORMATIVE,
438 GRID_INFORMATIVE, /* Informative options */
440 GRH_COMPAT,
441 GRID_COMPAT, /* Compatibility options */
443 GRH_OTHER,
444 GRID_OTHER /* Other options */
447 static struct argp_option options[] = {
448 {NULL, 0, NULL, 0,
449 N_("Main operation mode:"), GRH_COMMAND },
451 {"list", 't', 0, 0,
452 N_("list the contents of an archive"), GRID_COMMAND },
453 {"extract", 'x', 0, 0,
454 N_("extract files from an archive"), GRID_COMMAND },
455 {"get", 0, 0, OPTION_ALIAS, NULL, GRID_COMMAND },
456 {"create", 'c', 0, 0,
457 N_("create a new archive"), GRID_COMMAND },
458 {"diff", 'd', 0, 0,
459 N_("find differences between archive and file system"), GRID_COMMAND },
460 {"compare", 0, 0, OPTION_ALIAS, NULL, GRID_COMMAND },
461 {"append", 'r', 0, 0,
462 N_("append files to the end of an archive"), GRID_COMMAND },
463 {"update", 'u', 0, 0,
464 N_("only append files newer than copy in archive"), GRID_COMMAND },
465 {"catenate", 'A', 0, 0,
466 N_("append tar files to an archive"), GRID_COMMAND },
467 {"concatenate", 0, 0, OPTION_ALIAS, NULL, GRID_COMMAND },
468 {"delete", DELETE_OPTION, 0, 0,
469 N_("delete from the archive (not on mag tapes!)"), GRID_COMMAND },
470 {"test-label", TEST_LABEL_OPTION, NULL, 0,
471 N_("test the archive volume label and exit"), GRID_COMMAND },
473 {NULL, 0, NULL, 0,
474 N_("Operation modifiers:"), GRH_MODIFIER },
476 {"sparse", 'S', 0, 0,
477 N_("handle sparse files efficiently"), GRID_MODIFIER },
478 {"hole-detection", HOLE_DETECTION_OPTION, N_("TYPE"), 0,
479 N_("technique to detect holes"), GRID_MODIFIER },
480 {"sparse-version", SPARSE_VERSION_OPTION, N_("MAJOR[.MINOR]"), 0,
481 N_("set version of the sparse format to use (implies --sparse)"),
482 GRID_MODIFIER},
483 {"incremental", 'G', 0, 0,
484 N_("handle old GNU-format incremental backup"), GRID_MODIFIER },
485 {"listed-incremental", 'g', N_("FILE"), 0,
486 N_("handle new GNU-format incremental backup"), GRID_MODIFIER },
487 {"level", LEVEL_OPTION, N_("NUMBER"), 0,
488 N_("dump level for created listed-incremental archive"), GRID_MODIFIER },
489 {"ignore-failed-read", IGNORE_FAILED_READ_OPTION, 0, 0,
490 N_("do not exit with nonzero on unreadable files"), GRID_MODIFIER },
491 {"occurrence", OCCURRENCE_OPTION, N_("NUMBER"), OPTION_ARG_OPTIONAL,
492 N_("process only the NUMBERth occurrence of each file in the archive;"
493 " this option is valid only in conjunction with one of the subcommands"
494 " --delete, --diff, --extract or --list and when a list of files"
495 " is given either on the command line or via the -T option;"
496 " NUMBER defaults to 1"), GRID_MODIFIER },
497 {"seek", 'n', NULL, 0,
498 N_("archive is seekable"), GRID_MODIFIER },
499 {"no-seek", NO_SEEK_OPTION, NULL, 0,
500 N_("archive is not seekable"), GRID_MODIFIER },
501 {"no-check-device", NO_CHECK_DEVICE_OPTION, NULL, 0,
502 N_("do not check device numbers when creating incremental archives"),
503 GRID_MODIFIER },
504 {"check-device", CHECK_DEVICE_OPTION, NULL, 0,
505 N_("check device numbers when creating incremental archives (default)"),
506 GRID_MODIFIER },
508 {NULL, 0, NULL, 0,
509 N_("Overwrite control:"), GRH_OVERWRITE },
511 {"verify", 'W', 0, 0,
512 N_("attempt to verify the archive after writing it"), GRID_OVERWRITE },
513 {"remove-files", REMOVE_FILES_OPTION, 0, 0,
514 N_("remove files after adding them to the archive"), GRID_OVERWRITE },
515 {"keep-old-files", 'k', 0, 0,
516 N_("don't replace existing files when extracting, "
517 "treat them as errors"), GRID_OVERWRITE },
518 {"skip-old-files", SKIP_OLD_FILES_OPTION, 0, 0,
519 N_("don't replace existing files when extracting, silently skip over them"),
520 GRID_OVERWRITE },
521 {"keep-newer-files", KEEP_NEWER_FILES_OPTION, 0, 0,
522 N_("don't replace existing files that are newer than their archive copies"), GRID_OVERWRITE },
523 {"overwrite", OVERWRITE_OPTION, 0, 0,
524 N_("overwrite existing files when extracting"), GRID_OVERWRITE },
525 {"unlink-first", 'U', 0, 0,
526 N_("remove each file prior to extracting over it"), GRID_OVERWRITE },
527 {"recursive-unlink", RECURSIVE_UNLINK_OPTION, 0, 0,
528 N_("empty hierarchies prior to extracting directory"), GRID_OVERWRITE },
529 {"no-overwrite-dir", NO_OVERWRITE_DIR_OPTION, 0, 0,
530 N_("preserve metadata of existing directories"), GRID_OVERWRITE },
531 {"overwrite-dir", OVERWRITE_DIR_OPTION, 0, 0,
532 N_("overwrite metadata of existing directories when extracting (default)"),
533 GRID_OVERWRITE },
534 {"keep-directory-symlink", KEEP_DIRECTORY_SYMLINK_OPTION, 0, 0,
535 N_("preserve existing symlinks to directories when extracting"),
536 GRID_OVERWRITE },
537 {"one-top-level", ONE_TOP_LEVEL_OPTION, N_("DIR"), OPTION_ARG_OPTIONAL,
538 N_("create a subdirectory to avoid having loose files extracted"),
539 GRID_OVERWRITE },
541 {NULL, 0, NULL, 0,
542 N_("Select output stream:"), GRH_OUTPUT },
544 {"to-stdout", 'O', 0, 0,
545 N_("extract files to standard output"), GRID_OUTPUT },
546 {"to-command", TO_COMMAND_OPTION, N_("COMMAND"), 0,
547 N_("pipe extracted files to another program"), GRID_OUTPUT },
548 {"ignore-command-error", IGNORE_COMMAND_ERROR_OPTION, 0, 0,
549 N_("ignore exit codes of children"), GRID_OUTPUT },
550 {"no-ignore-command-error", NO_IGNORE_COMMAND_ERROR_OPTION, 0, 0,
551 N_("treat non-zero exit codes of children as error"), GRID_OUTPUT },
553 {NULL, 0, NULL, 0,
554 N_("Handling of file attributes:"), GRH_FATTR },
556 {"owner", OWNER_OPTION, N_("NAME"), 0,
557 N_("force NAME as owner for added files"), GRID_FATTR },
558 {"group", GROUP_OPTION, N_("NAME"), 0,
559 N_("force NAME as group for added files"), GRID_FATTR },
560 {"owner-map", OWNER_MAP_OPTION, N_("FILE"), 0,
561 N_("use FILE to map file owner UIDs and names"), GRID_FATTR },
562 {"group-map", GROUP_MAP_OPTION, N_("FILE"), 0,
563 N_("use FILE to map file owner GIDs and names"), GRID_FATTR },
564 {"mtime", MTIME_OPTION, N_("DATE-OR-FILE"), 0,
565 N_("set mtime for added files from DATE-OR-FILE"), GRID_FATTR },
566 {"clamp-mtime", CLAMP_MTIME_OPTION, 0, 0,
567 N_("only set time when the file is more recent than what was given with --mtime"), GRID_FATTR },
568 {"set-mtime-command", SET_MTIME_COMMAND_OPTION, N_("COMMAND"), 0,
569 N_("use output of the COMMAND to set mtime of the stored archive members"),
570 GRID_FATTR },
571 {"set-mtime-format", SET_MTIME_FORMAT_OPTION, N_("FORMAT"), 0,
572 N_("set output format (in the sense of strptime(3)) of the --set-mtime-command command"), GRID_FATTR },
573 {"mode", MODE_OPTION, N_("CHANGES"), 0,
574 N_("force (symbolic) mode CHANGES for added files"), GRID_FATTR },
575 {"atime-preserve", ATIME_PRESERVE_OPTION,
576 N_("METHOD"), OPTION_ARG_OPTIONAL,
577 N_("preserve access times on dumped files, either by restoring the times"
578 " after reading (METHOD='replace'; default) or by not setting the times"
579 " in the first place (METHOD='system')"), GRID_FATTR },
580 {"touch", 'm', 0, 0,
581 N_("don't extract file modified time"), GRID_FATTR },
582 {"same-owner", SAME_OWNER_OPTION, 0, 0,
583 N_("try extracting files with the same ownership as exists in the archive (default for superuser)"), GRID_FATTR },
584 {"no-same-owner", NO_SAME_OWNER_OPTION, 0, 0,
585 N_("extract files as yourself (default for ordinary users)"), GRID_FATTR },
586 {"numeric-owner", NUMERIC_OWNER_OPTION, 0, 0,
587 N_("always use numbers for user/group names"), GRID_FATTR },
588 {"preserve-permissions", 'p', 0, 0,
589 N_("extract information about file permissions (default for superuser)"),
590 GRID_FATTR },
591 {"same-permissions", 0, 0, OPTION_ALIAS, NULL, GRID_FATTR },
592 {"no-same-permissions", NO_SAME_PERMISSIONS_OPTION, 0, 0,
593 N_("apply the user's umask when extracting permissions from the archive (default for ordinary users)"), GRID_FATTR },
594 {"preserve-order", 's', 0, 0,
595 N_("member arguments are listed in the same order as the "
596 "files in the archive"), GRID_FATTR },
597 {"same-order", 0, 0, OPTION_ALIAS, NULL, GRID_FATTR },
598 {"delay-directory-restore", DELAY_DIRECTORY_RESTORE_OPTION, 0, 0,
599 N_("delay setting modification times and permissions of extracted"
600 " directories until the end of extraction"), GRID_FATTR },
601 {"no-delay-directory-restore", NO_DELAY_DIRECTORY_RESTORE_OPTION, 0, 0,
602 N_("cancel the effect of --delay-directory-restore option"), GRID_FATTR },
603 {"sort", SORT_OPTION, N_("ORDER"), 0,
604 #if D_INO_IN_DIRENT
605 N_("directory sorting order: none (default), name or inode")
606 #else
607 N_("directory sorting order: none (default) or name")
608 #endif
609 , GRID_FATTR },
611 {NULL, 0, NULL, 0,
612 N_("Handling of extended file attributes:"), GRH_XATTR },
614 {"xattrs", XATTR_OPTION, 0, 0,
615 N_("Enable extended attributes support"), GRID_XATTR },
616 {"no-xattrs", NO_XATTR_OPTION, 0, 0,
617 N_("Disable extended attributes support"), GRID_XATTR },
618 {"xattrs-include", XATTR_INCLUDE, N_("MASK"), 0,
619 N_("specify the include pattern for xattr keys"), GRID_XATTR },
620 {"xattrs-exclude", XATTR_EXCLUDE, N_("MASK"), 0,
621 N_("specify the exclude pattern for xattr keys"), GRID_XATTR },
622 {"selinux", SELINUX_CONTEXT_OPTION, 0, 0,
623 N_("Enable the SELinux context support"), GRID_XATTR },
624 {"no-selinux", NO_SELINUX_CONTEXT_OPTION, 0, 0,
625 N_("Disable the SELinux context support"), GRID_XATTR },
626 {"acls", ACLS_OPTION, 0, 0,
627 N_("Enable the POSIX ACLs support"), GRID_XATTR },
628 {"no-acls", NO_ACLS_OPTION, 0, 0,
629 N_("Disable the POSIX ACLs support"), GRID_XATTR },
631 {NULL, 0, NULL, 0,
632 N_("Device selection and switching:"), GRH_DEVICE },
634 {"file", 'f', N_("ARCHIVE"), 0,
635 N_("use archive file or device ARCHIVE"), GRID_DEVICE },
636 #ifdef DEVICE_PREFIX
637 {"-[0-7][lmh]", 0, NULL, OPTION_DOC, /* It is OK, since 'name' will never be
638 translated */
639 N_("specify drive and density"), GRID_DEVICE },
640 #endif
641 {NULL, '0', NULL, OPTION_HIDDEN, NULL, GRID_DEVICE },
642 {NULL, '1', NULL, OPTION_HIDDEN, NULL, GRID_DEVICE },
643 {NULL, '2', NULL, OPTION_HIDDEN, NULL, GRID_DEVICE },
644 {NULL, '3', NULL, OPTION_HIDDEN, NULL, GRID_DEVICE },
645 {NULL, '4', NULL, OPTION_HIDDEN, NULL, GRID_DEVICE },
646 {NULL, '5', NULL, OPTION_HIDDEN, NULL, GRID_DEVICE },
647 {NULL, '6', NULL, OPTION_HIDDEN, NULL, GRID_DEVICE },
648 {NULL, '7', NULL, OPTION_HIDDEN, NULL, GRID_DEVICE },
649 {NULL, '8', NULL, OPTION_HIDDEN, NULL, GRID_DEVICE },
650 {NULL, '9', NULL, OPTION_HIDDEN, NULL, GRID_DEVICE },
652 {"force-local", FORCE_LOCAL_OPTION, 0, 0,
653 N_("archive file is local even if it has a colon"),
654 GRID_DEVICE },
655 {"rmt-command", RMT_COMMAND_OPTION, N_("COMMAND"), 0,
656 N_("use given rmt COMMAND instead of rmt"),
657 GRID_DEVICE },
658 {"rsh-command", RSH_COMMAND_OPTION, N_("COMMAND"), 0,
659 N_("use remote COMMAND instead of rsh"),
660 GRID_DEVICE },
662 {"multi-volume", 'M', 0, 0,
663 N_("create/list/extract multi-volume archive"),
664 GRID_DEVICE },
665 {"tape-length", 'L', N_("NUMBER"), 0,
666 N_("change tape after writing NUMBER x 1024 bytes"),
667 GRID_DEVICE },
668 {"info-script", 'F', N_("NAME"), 0,
669 N_("run script at end of each tape (implies -M)"),
670 GRID_DEVICE },
671 {"new-volume-script", 0, 0, OPTION_ALIAS, NULL, GRID_DEVICE },
672 {"volno-file", VOLNO_FILE_OPTION, N_("FILE"), 0,
673 N_("use/update the volume number in FILE"),
674 GRID_DEVICE },
676 {NULL, 0, NULL, 0,
677 N_("Device blocking:"), GRH_BLOCKING },
679 {"blocking-factor", 'b', N_("BLOCKS"), 0,
680 N_("BLOCKS x 512 bytes per record"), GRID_BLOCKING },
681 {"record-size", RECORD_SIZE_OPTION, N_("NUMBER"), 0,
682 N_("NUMBER of bytes per record, multiple of 512"), GRID_BLOCKING },
683 {"ignore-zeros", 'i', 0, 0,
684 N_("ignore zeroed blocks in archive (means EOF)"), GRID_BLOCKING },
685 {"read-full-records", 'B', 0, 0,
686 N_("reblock as we read (for 4.2BSD pipes)"), GRID_BLOCKING },
688 {NULL, 0, NULL, 0,
689 N_("Archive format selection:"), GRH_FORMAT },
691 {"format", 'H', N_("FORMAT"), 0,
692 N_("create archive of the given format"), GRID_FORMAT },
694 {NULL, 0, NULL, 0, N_("FORMAT is one of the following:"), GRDOC_FORMAT },
695 {" v7", 0, NULL, OPTION_DOC|OPTION_NO_TRANS, N_("old V7 tar format"),
696 GRDOC_FORMAT },
697 {" oldgnu", 0, NULL, OPTION_DOC|OPTION_NO_TRANS,
698 N_("GNU format as per tar <= 1.12"), GRDOC_FORMAT },
699 {" gnu", 0, NULL, OPTION_DOC|OPTION_NO_TRANS,
700 N_("GNU tar 1.13.x format"), GRDOC_FORMAT },
701 {" ustar", 0, NULL, OPTION_DOC|OPTION_NO_TRANS,
702 N_("POSIX 1003.1-1988 (ustar) format"), GRDOC_FORMAT },
703 {" pax", 0, NULL, OPTION_DOC|OPTION_NO_TRANS,
704 N_("POSIX 1003.1-2001 (pax) format"), GRDOC_FORMAT },
705 {" posix", 0, NULL, OPTION_DOC|OPTION_NO_TRANS, N_("same as pax"),
706 GRDOC_FORMAT },
708 {"old-archive", OLD_ARCHIVE_OPTION, 0, 0, /* FIXME */
709 N_("same as --format=v7"), GRID_FORMAT_OPT },
710 {"portability", 0, 0, OPTION_ALIAS, NULL, GRID_FORMAT_OPT },
711 {"posix", POSIX_OPTION, 0, 0,
712 N_("same as --format=posix"), GRID_FORMAT_OPT },
713 {"pax-option", PAX_OPTION, N_("keyword[[:]=value][,keyword[[:]=value]]..."), 0,
714 N_("control pax keywords"), GRID_FORMAT_OPT },
715 {"label", 'V', N_("TEXT"), 0,
716 N_("create archive with volume name TEXT; at list/extract time, use TEXT as a globbing pattern for volume name"),
717 GRID_FORMAT_OPT },
719 {NULL, 0, NULL, 0,
720 N_("Compression options:"), GRH_COMPRESS },
721 {"auto-compress", 'a', 0, 0,
722 N_("use archive suffix to determine the compression program"),
723 GRID_COMPRESS },
724 {"no-auto-compress", NO_AUTO_COMPRESS_OPTION, 0, 0,
725 N_("do not use archive suffix to determine the compression program"),
726 GRID_COMPRESS },
727 {"use-compress-program", 'I', N_("PROG"), 0,
728 N_("filter through PROG (must accept -d)"), GRID_COMPRESS },
729 /* Note: docstrings for the options below are generated by tar_help_filter */
730 {"bzip2", 'j', 0, 0, NULL, GRID_COMPRESS },
731 {"gzip", 'z', 0, 0, NULL, GRID_COMPRESS },
732 {"gunzip", 0, 0, OPTION_ALIAS, NULL, GRID_COMPRESS },
733 {"ungzip", 0, 0, OPTION_ALIAS, NULL, GRID_COMPRESS },
734 {"compress", 'Z', 0, 0, NULL, GRID_COMPRESS },
735 {"uncompress", 0, 0, OPTION_ALIAS, NULL, GRID_COMPRESS },
736 {"lzip", LZIP_OPTION, 0, 0, NULL, GRID_COMPRESS },
737 {"lzma", LZMA_OPTION, 0, 0, NULL, GRID_COMPRESS },
738 {"lzop", LZOP_OPTION, 0, 0, NULL, GRID_COMPRESS },
739 {"xz", 'J', 0, 0, NULL, GRID_COMPRESS },
740 {"zstd", ZSTD_OPTION, 0, 0, NULL, GRID_COMPRESS },
742 {NULL, 0, NULL, 0,
743 N_("Local file selection:"), GRH_FILE },
744 {"one-file-system", ONE_FILE_SYSTEM_OPTION, 0, 0,
745 N_("stay in local file system when creating archive"), GRID_FILE },
746 {"absolute-names", 'P', 0, 0,
747 N_("don't strip leading '/'s from file names"), GRID_FILE },
748 {"dereference", 'h', 0, 0,
749 N_("follow symlinks; archive and dump the files they point to"),
750 GRID_FILE },
751 {"hard-dereference", HARD_DEREFERENCE_OPTION, 0, 0,
752 N_("follow hard links; archive and dump the files they refer to"),
753 GRID_FILE },
754 {"starting-file", 'K', N_("MEMBER-NAME"), 0,
755 N_("begin at member MEMBER-NAME when reading the archive"),
756 GRID_FILE },
757 {"newer", 'N', N_("DATE-OR-FILE"), 0,
758 N_("only store files newer than DATE-OR-FILE"), GRID_FILE },
759 {"after-date", 0, 0, OPTION_ALIAS, NULL, GRID_FILE },
760 {"newer-mtime", NEWER_MTIME_OPTION, N_("DATE"), 0,
761 N_("compare date and time when data changed only"), GRID_FILE },
762 {"backup", BACKUP_OPTION, N_("CONTROL"), OPTION_ARG_OPTIONAL,
763 N_("backup before removal, choose version CONTROL"), GRID_FILE },
764 {"suffix", SUFFIX_OPTION, N_("STRING"), 0,
765 N_("backup before removal, override usual suffix ('~' unless overridden by environment variable SIMPLE_BACKUP_SUFFIX)"),
766 GRID_FILE },
768 {NULL, 0, NULL, 0,
769 N_("File name transformations:"), GRH_NAME_XFORM },
770 {"strip-components", STRIP_COMPONENTS_OPTION, N_("NUMBER"), 0,
771 N_("strip NUMBER leading components from file names on extraction"),
772 GRID_NAME_XFORM },
773 {"transform", TRANSFORM_OPTION, N_("EXPRESSION"), 0,
774 N_("use sed replace EXPRESSION to transform file names"),
775 GRID_NAME_XFORM },
776 {"xform", 0, 0, OPTION_ALIAS, NULL, GRID_NAME_XFORM },
778 {NULL, 0, NULL, 0,
779 N_("Informative output:"), GRH_INFORMATIVE },
781 {"checkpoint", CHECKPOINT_OPTION, N_("NUMBER"), OPTION_ARG_OPTIONAL,
782 N_("display progress messages every NUMBERth record (default 10)"),
783 GRID_INFORMATIVE },
784 {"checkpoint-action", CHECKPOINT_ACTION_OPTION, N_("ACTION"), 0,
785 N_("execute ACTION on each checkpoint"),
786 GRID_INFORMATIVE },
787 {"check-links", 'l', 0, 0,
788 N_("print a message if not all links are dumped"), GRID_INFORMATIVE },
789 {"totals", TOTALS_OPTION, N_("SIGNAL"), OPTION_ARG_OPTIONAL,
790 N_("print total bytes after processing the archive; "
791 "with an argument - print total bytes when this SIGNAL is delivered; "
792 "Allowed signals are: SIGHUP, SIGQUIT, SIGINT, SIGUSR1 and SIGUSR2; "
793 "the names without SIG prefix are also accepted"), GRID_INFORMATIVE },
794 {"utc", UTC_OPTION, 0, 0,
795 N_("print file modification times in UTC"), GRID_INFORMATIVE },
796 {"full-time", FULL_TIME_OPTION, 0, 0,
797 N_("print file time to its full resolution"), GRID_INFORMATIVE },
798 {"index-file", INDEX_FILE_OPTION, N_("FILE"), 0,
799 N_("send verbose output to FILE"), GRID_INFORMATIVE },
800 {"block-number", 'R', 0, 0,
801 N_("show block number within archive with each message"), GRID_INFORMATIVE },
802 {"show-defaults", SHOW_DEFAULTS_OPTION, 0, 0,
803 N_("show tar defaults"), GRID_INFORMATIVE },
804 {"show-snapshot-field-ranges", SHOW_SNAPSHOT_FIELD_RANGES_OPTION, 0, 0,
805 N_("show valid ranges for snapshot-file fields"), GRID_INFORMATIVE },
806 {"show-omitted-dirs", SHOW_OMITTED_DIRS_OPTION, 0, 0,
807 N_("when listing or extracting, list each directory that does not match search criteria"), GRID_INFORMATIVE },
808 {"show-transformed-names", SHOW_TRANSFORMED_NAMES_OPTION, 0, 0,
809 N_("show file or archive names after transformation"),
810 GRID_INFORMATIVE },
811 {"show-stored-names", 0, 0, OPTION_ALIAS, NULL, GRID_INFORMATIVE },
812 {"quoting-style", QUOTING_STYLE_OPTION, N_("STYLE"), 0,
813 N_("set name quoting style; see below for valid STYLE values"), GRID_INFORMATIVE },
814 {"quote-chars", QUOTE_CHARS_OPTION, N_("STRING"), 0,
815 N_("additionally quote characters from STRING"), GRID_INFORMATIVE },
816 {"no-quote-chars", NO_QUOTE_CHARS_OPTION, N_("STRING"), 0,
817 N_("disable quoting for characters from STRING"), GRID_INFORMATIVE },
818 {"interactive", 'w', 0, 0,
819 N_("ask for confirmation for every action"), GRID_INFORMATIVE },
820 {"confirmation", 0, 0, OPTION_ALIAS, NULL, GRID_INFORMATIVE },
821 {"verbose", 'v', 0, 0,
822 N_("verbosely list files processed"), GRID_INFORMATIVE },
823 {"warning", WARNING_OPTION, N_("KEYWORD"), 0,
824 N_("warning control"), GRID_INFORMATIVE },
826 {NULL, 0, NULL, 0,
827 N_("Compatibility options:"), GRH_COMPAT },
829 {NULL, 'o', 0, 0,
830 N_("when creating, same as --old-archive; when extracting, same as --no-same-owner"), GRID_COMPAT },
832 {NULL, 0, NULL, 0,
833 N_("Other options:"), GRH_OTHER },
835 {"restrict", RESTRICT_OPTION, 0, 0,
836 N_("disable use of some potentially harmful options"), -1 },
838 {0, 0, 0, 0, 0, 0}
841 static char const *const atime_preserve_args[] =
843 "replace", "system", NULL
846 static enum atime_preserve const atime_preserve_types[] =
848 replace_atime_preserve, system_atime_preserve
851 /* Make sure atime_preserve_types has as much entries as atime_preserve_args
852 (minus 1 for NULL guard) */
853 ARGMATCH_VERIFY (atime_preserve_args, atime_preserve_types);
856 static char * ATTRIBUTE_FORMAT ((printf, 1, 2))
857 easprintf (char const *format, ...)
859 va_list args;
861 va_start (args, format);
862 char *result = xvasprintf (format, args);
863 int err = errno;
864 va_end (args);
866 if (!result)
867 FATAL_ERROR ((0, err, "vasprintf"));
868 return result;
871 static char *
872 format_default_settings (void)
874 return easprintf (
875 "--format=%s -f%s -b%d --quoting-style=%s --rmt-command=%s"
876 #ifdef REMOTE_SHELL
877 " --rsh-command=%s"
878 #endif
880 archive_format_string (DEFAULT_ARCHIVE_FORMAT),
881 DEFAULT_ARCHIVE, DEFAULT_BLOCKING,
882 quoting_style_args[DEFAULT_QUOTING_STYLE],
883 DEFAULT_RMT_COMMAND
884 #ifdef REMOTE_SHELL
885 , REMOTE_SHELL
886 #endif
890 static void
891 option_conflict_error (const char *a, const char *b)
893 /* TRANSLATORS: Both %s in this statement are replaced with
894 option names. */
895 USAGE_ERROR ((0, 0, _("'%s' cannot be used with '%s'"), a, b));
898 /* Classes of options that can conflict: */
899 enum option_class
901 OC_COMPRESS, /* Compress options: -JjZz, -I, etc. */
902 OC_OCCURRENCE, /* --occurrence */
903 OC_LISTED_INCREMENTAL, /* --listed-incremental */
904 OC_NEWER, /* --newer, --newer-mtime, --after-date */
905 OC_VERIFY, /* --verify */
906 OC_STARTING_FILE, /* --starting-file */
907 OC_SAME_ORDER, /* --same-order */
908 OC_ONE_TOP_LEVEL, /* --one-top-level */
909 OC_ABSOLUTE_NAMES, /* --absolute-names */
910 OC_OLD_FILES, /* --keep-old-files, --overwrite, etc. */
911 OC_MAX
914 /* Table of locations of potentially conflicting options. Two options can
915 conflict only if they proceed from the command line. Otherwise, options
916 in command line silently override those defined in TAR_OPTIONS. */
917 static struct option_locus *option_class[OC_MAX];
919 /* Save location of an option of class ID. Return location of a previous
920 occurrence of an option of that class, or NULL. */
921 static struct option_locus *
922 optloc_save (unsigned int id, struct option_locus *loc)
924 struct option_locus *optloc;
925 char *p;
926 size_t s;
928 if (id >= sizeof (option_class) / sizeof (option_class[0]))
929 abort ();
930 s = sizeof (*loc);
931 if (loc->name)
932 s += strlen (loc->name) + 1;
933 optloc = xmalloc (s);
934 if (loc->name)
936 p = (char*) optloc + sizeof (*loc);
937 strcpy (p, loc->name);
938 optloc->name = p;
940 else
941 optloc->name = NULL;
942 optloc->source = loc->source;
943 optloc->line = loc->line;
944 optloc->prev = option_class[id];
945 option_class[id] = optloc;
946 return optloc->prev;
949 /* Return location of a recent option of class ID */
950 static struct option_locus *
951 optloc_lookup (int id)
953 return option_class[id];
956 /* Return true if the latest occurrence of option ID was in the command line */
957 static int
958 option_set_in_cl (int id)
960 struct option_locus *loc = optloc_lookup (id);
961 if (!loc)
962 return 0;
963 return loc->source == OPTS_COMMAND_LINE;
966 /* Compare two option locations */
967 static int
968 optloc_eq (struct option_locus *a, struct option_locus *b)
970 assume (a); /* Pacify GCC bug 106436. */
971 if (a->source != b->source)
972 return 0;
973 if (a->source == OPTS_COMMAND_LINE)
974 return 1;
975 return strcmp (a->name, b->name) == 0;
978 static void
979 set_subcommand_option (enum subcommand subcommand)
981 if (subcommand_option != UNKNOWN_SUBCOMMAND
982 && subcommand_option != subcommand)
983 USAGE_ERROR ((0, 0,
984 _("You may not specify more than one '-Acdtrux', '--delete' or '--test-label' option")));
986 subcommand_option = subcommand;
989 static void
990 set_use_compress_program_option (const char *string, struct option_locus *loc)
992 struct option_locus *p = optloc_save (OC_COMPRESS, loc);
993 if (use_compress_program_option
994 && strcmp (use_compress_program_option, string) != 0
995 && p->source == OPTS_COMMAND_LINE)
996 USAGE_ERROR ((0, 0, _("Conflicting compression options")));
998 use_compress_program_option = string;
1001 static void
1002 sigstat (int signo)
1004 compute_duration ();
1005 print_total_stats ();
1006 #ifndef HAVE_SIGACTION
1007 signal (signo, sigstat);
1008 #endif
1011 static void
1012 stat_on_signal (int signo)
1014 #ifdef HAVE_SIGACTION
1015 # ifndef SA_RESTART
1016 # define SA_RESTART 0
1017 # endif
1018 struct sigaction act;
1019 act.sa_handler = sigstat;
1020 sigemptyset (&act.sa_mask);
1021 act.sa_flags = SA_RESTART;
1022 sigaction (signo, &act, NULL);
1023 #else
1024 signal (signo, sigstat);
1025 #endif
1029 decode_signal (const char *name)
1031 static struct sigtab
1033 char const *name;
1034 int signo;
1035 } const sigtab[] = {
1036 { "USR1", SIGUSR1 },
1037 { "USR2", SIGUSR2 },
1038 { "HUP", SIGHUP },
1039 { "INT", SIGINT },
1040 { "QUIT", SIGQUIT }
1042 struct sigtab const *p;
1043 char const *s = name;
1045 if (strncmp (s, "SIG", 3) == 0)
1046 s += 3;
1047 for (p = sigtab; p < sigtab + sizeof (sigtab) / sizeof (sigtab[0]); p++)
1048 if (strcmp (p->name, s) == 0)
1049 return p->signo;
1050 FATAL_ERROR ((0, 0, _("Unknown signal name: %s"), name));
1053 static void
1054 set_stat_signal (const char *name)
1056 stat_on_signal (decode_signal (name));
1060 struct textual_date
1062 struct textual_date *next;
1063 struct timespec ts;
1064 const char *option;
1065 char *date;
1068 static int
1069 get_date_or_file (struct tar_args *args, const char *option,
1070 const char *str, struct timespec *ts)
1072 if (FILE_SYSTEM_PREFIX_LEN (str) != 0
1073 || ISSLASH (*str)
1074 || *str == '.')
1076 struct stat st;
1077 if (stat (str, &st) != 0)
1079 stat_error (str);
1080 USAGE_ERROR ((0, 0, _("Date sample file not found")));
1082 *ts = get_stat_mtime (&st);
1084 else
1086 if (! parse_datetime (ts, str, NULL))
1088 WARN ((0, 0, _("Substituting %s for unknown date format %s"),
1089 tartime (*ts, false), quote (str)));
1090 ts->tv_nsec = 0;
1091 return 1;
1093 else
1095 struct textual_date *p = xmalloc (sizeof (*p));
1096 p->ts = *ts;
1097 p->option = option;
1098 p->date = xstrdup (str);
1099 p->next = args->textual_date;
1100 args->textual_date = p;
1103 return 0;
1106 static void
1107 report_textual_dates (struct tar_args *args)
1109 struct textual_date *p;
1110 for (p = args->textual_date; p; )
1112 struct textual_date *next = p->next;
1113 if (verbose_option)
1115 char const *treated_as = tartime (p->ts, true);
1116 if (strcmp (p->date, treated_as) != 0)
1117 WARN ((0, 0, _("Option %s: Treating date '%s' as %s"),
1118 p->option, p->date, treated_as));
1120 free (p->date);
1121 free (p);
1122 p = next;
1127 /* Default density numbers for [0-9][lmh] device specifications */
1129 #if defined DEVICE_PREFIX && !defined DENSITY_LETTER
1130 # ifndef LOW_DENSITY_NUM
1131 # define LOW_DENSITY_NUM 0
1132 # endif
1134 # ifndef MID_DENSITY_NUM
1135 # define MID_DENSITY_NUM 8
1136 # endif
1138 # ifndef HIGH_DENSITY_NUM
1139 # define HIGH_DENSITY_NUM 16
1140 # endif
1141 #endif
1144 static char *
1145 tar_help_filter (int key, const char *text, MAYBE_UNUSED void *input)
1147 struct obstack stk;
1148 char *s;
1150 switch (key)
1152 default:
1153 s = (char*) text;
1154 break;
1156 case 'j':
1157 s = easprintf (_("filter the archive through %s"), BZIP2_PROGRAM);
1158 break;
1160 case 'z':
1161 s = easprintf (_("filter the archive through %s"), GZIP_PROGRAM);
1162 break;
1164 case 'Z':
1165 s = easprintf (_("filter the archive through %s"), COMPRESS_PROGRAM);
1166 break;
1168 case LZIP_OPTION:
1169 s = easprintf (_("filter the archive through %s"), LZIP_PROGRAM);
1170 break;
1172 case LZMA_OPTION:
1173 s = easprintf (_("filter the archive through %s"), LZMA_PROGRAM);
1174 break;
1176 case LZOP_OPTION:
1177 s = easprintf (_("filter the archive through %s"), LZOP_PROGRAM);
1178 break;
1180 case 'J':
1181 s = easprintf (_("filter the archive through %s"), XZ_PROGRAM);
1182 break;
1184 case ZSTD_OPTION:
1185 s = easprintf (_("filter the archive through %s"), ZSTD_PROGRAM);
1186 break;
1188 case ARGP_KEY_HELP_EXTRA:
1190 const char *tstr;
1192 obstack_init (&stk);
1193 tstr = _("Valid arguments for the --quoting-style option are:");
1194 obstack_grow (&stk, tstr, strlen (tstr));
1195 obstack_grow (&stk, "\n\n", 2);
1196 tar_list_quoting_styles (&stk, " ");
1197 tstr = _("\n*This* tar defaults to:\n");
1198 obstack_grow (&stk, tstr, strlen (tstr));
1199 s = format_default_settings ();
1200 obstack_grow (&stk, s, strlen (s));
1201 obstack_1grow (&stk, '\n');
1202 obstack_1grow (&stk, 0);
1203 s = xstrdup (obstack_finish (&stk));
1204 obstack_free (&stk, NULL);
1207 return s;
1210 static char * _GL_ATTRIBUTE_MALLOC
1211 expand_pax_option (struct tar_args *targs, const char *arg)
1213 struct obstack stk;
1214 char *res;
1216 obstack_init (&stk);
1217 while (*arg)
1219 size_t seglen = strcspn (arg, ",");
1220 char *p = memchr (arg, '=', seglen);
1221 if (p)
1223 size_t len = p - arg + 1;
1224 obstack_grow (&stk, arg, len);
1225 len = seglen - len;
1226 for (++p; *p && isspace ((unsigned char) *p); p++)
1227 len--;
1228 if (*p == '{' && p[len-1] == '}')
1230 struct timespec ts;
1231 char *tmp = xmalloc (len);
1232 memcpy (tmp, p + 1, len-2);
1233 tmp[len-2] = 0;
1234 if (get_date_or_file (targs, "--pax-option", tmp, &ts) == 0)
1236 char buf[TIMESPEC_STRSIZE_BOUND];
1237 char const *s = code_timespec (ts, buf);
1238 obstack_grow (&stk, s, strlen (s));
1240 else
1241 obstack_grow (&stk, p, len);
1242 free (tmp);
1244 else
1245 obstack_grow (&stk, p, len);
1247 else
1248 obstack_grow (&stk, arg, seglen);
1250 arg += seglen;
1251 if (*arg)
1253 obstack_1grow (&stk, *arg);
1254 arg++;
1257 obstack_1grow (&stk, 0);
1258 res = xstrdup (obstack_finish (&stk));
1259 obstack_free (&stk, NULL);
1260 return res;
1264 static uintmax_t
1265 parse_owner_group (char *arg, uintmax_t field_max, char const **name_option)
1267 uintmax_t u = UINTMAX_MAX;
1268 char *end;
1269 char const *name = 0;
1270 char const *invalid_num = 0;
1271 char *colon = strchr (arg, ':');
1273 if (colon)
1275 char const *num = colon + 1;
1276 *colon = '\0';
1277 if (*arg)
1278 name = arg;
1279 if (num && (! (xstrtoumax (num, &end, 10, &u, "") == LONGINT_OK
1280 && u <= field_max)))
1281 invalid_num = num;
1283 else
1285 uintmax_t u1;
1286 switch ('0' <= *arg && *arg <= '9'
1287 ? xstrtoumax (arg, &end, 10, &u1, "")
1288 : LONGINT_INVALID)
1290 default:
1291 name = arg;
1292 break;
1294 case LONGINT_OK:
1295 if (u1 <= field_max)
1297 u = u1;
1298 break;
1300 FALLTHROUGH;
1301 case LONGINT_OVERFLOW:
1302 invalid_num = arg;
1303 break;
1307 if (invalid_num)
1308 FATAL_ERROR ((0, 0, "%s: %s", quotearg_colon (invalid_num),
1309 _("Invalid owner or group ID")));
1310 if (name)
1311 *name_option = name;
1312 return u;
1315 #define TAR_SIZE_SUFFIXES "bBcGgkKMmPTtw"
1317 static char const *const sort_mode_arg[] = {
1318 "none",
1319 "name",
1320 #if D_INO_IN_DIRENT
1321 "inode",
1322 #endif
1323 NULL
1326 static int sort_mode_flag[] = {
1327 SAVEDIR_SORT_NONE,
1328 SAVEDIR_SORT_NAME,
1329 #if D_INO_IN_DIRENT
1330 SAVEDIR_SORT_INODE
1331 #endif
1334 ARGMATCH_VERIFY (sort_mode_arg, sort_mode_flag);
1336 static char const *const hole_detection_args[] =
1338 "raw", "seek", NULL
1341 static int const hole_detection_types[] =
1343 HOLE_DETECTION_RAW, HOLE_DETECTION_SEEK
1346 ARGMATCH_VERIFY (hole_detection_args, hole_detection_types);
1349 static void
1350 set_old_files_option (int code, struct option_locus *loc)
1352 struct option_locus *prev;
1353 static char const *const code_to_opt[] = {
1354 "--overwrite-dir",
1355 "--no-overwrite-dir",
1356 "--overwrite",
1357 "--unlink-first",
1358 "--keep-old-files",
1359 "--skip-old-files",
1360 "--keep-newer-files"
1363 prev = optloc_save (OC_OLD_FILES, loc);
1364 if (prev && optloc_eq (loc, prev) && code != old_files_option)
1365 option_conflict_error (code_to_opt[code], code_to_opt[old_files_option]);
1367 old_files_option = code;
1370 static error_t
1371 parse_opt (int key, char *arg, struct argp_state *state)
1373 struct tar_args *args = state->input;
1375 switch (key)
1377 case ARGP_KEY_INIT:
1378 if (state->root_argp->children)
1380 int i;
1382 for (i = 0; state->root_argp->children[i].argp; i++)
1383 state->child_inputs[i] = state->input;
1385 break;
1387 case ARGP_KEY_ARG:
1388 /* File name or non-parsed option, because of ARGP_IN_ORDER */
1389 name_add_name (arg);
1390 break;
1392 case 'A':
1393 set_subcommand_option (CAT_SUBCOMMAND);
1394 break;
1396 case 'a':
1397 args->compress_autodetect = true;
1398 break;
1400 case NO_AUTO_COMPRESS_OPTION:
1401 args->compress_autodetect = false;
1402 break;
1404 case 'b':
1406 uintmax_t u;
1407 if (! (xstrtoumax (arg, 0, 10, &u, "") == LONGINT_OK
1408 && u == (blocking_factor = u)
1409 && 0 < blocking_factor
1410 && u == (record_size = u * BLOCKSIZE) / BLOCKSIZE))
1411 USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (arg),
1412 _("Invalid blocking factor")));
1414 break;
1416 case 'B':
1417 /* Try to reblock input records. For reading 4.2BSD pipes. */
1419 /* It would surely make sense to exchange -B and -R, but it seems
1420 that -B has been used for a long while in Sun tar and most
1421 BSD-derived systems. This is a consequence of the block/record
1422 terminology confusion. */
1424 read_full_records_option = true;
1425 break;
1427 case 'c':
1428 set_subcommand_option (CREATE_SUBCOMMAND);
1429 break;
1431 case CLAMP_MTIME_OPTION:
1432 set_mtime_option = CLAMP_MTIME;
1433 break;
1435 case 'd':
1436 set_subcommand_option (DIFF_SUBCOMMAND);
1437 break;
1439 case 'F':
1440 /* Since -F is only useful with -M, make it implied. Run this
1441 script at the end of each tape. */
1443 info_script_option = arg;
1444 multi_volume_option = true;
1445 break;
1447 case 'f':
1448 if (archive_names == allocated_archive_names)
1449 archive_name_array = x2nrealloc (archive_name_array,
1450 &allocated_archive_names,
1451 sizeof (archive_name_array[0]));
1453 archive_name_array[archive_names++] = arg;
1454 break;
1456 case '0':
1457 case '1':
1458 case '2':
1459 case '3':
1460 case '4':
1461 case '5':
1462 case '6':
1463 case '7':
1465 #ifdef DEVICE_PREFIX
1467 int device = key - '0';
1468 int density;
1469 static char buf[sizeof DEVICE_PREFIX + 10];
1470 char *cursor;
1472 if (arg[1])
1473 argp_error (state, _("Malformed density argument: %s"), quote (arg));
1475 strcpy (buf, DEVICE_PREFIX);
1476 cursor = buf + strlen (buf);
1478 #ifdef DENSITY_LETTER
1480 sprintf (cursor, "%d%c", device, arg[0]);
1482 #else /* not DENSITY_LETTER */
1484 switch (arg[0])
1486 case 'l':
1487 device += LOW_DENSITY_NUM;
1488 break;
1490 case 'm':
1491 device += MID_DENSITY_NUM;
1492 break;
1494 case 'h':
1495 device += HIGH_DENSITY_NUM;
1496 break;
1498 default:
1499 argp_error (state, _("Unknown density: '%c'"), arg[0]);
1501 sprintf (cursor, "%d", device);
1503 #endif /* not DENSITY_LETTER */
1505 if (archive_names == allocated_archive_names)
1506 archive_name_array = x2nrealloc (archive_name_array,
1507 &allocated_archive_names,
1508 sizeof (archive_name_array[0]));
1509 archive_name_array[archive_names++] = xstrdup (buf);
1511 break;
1513 #else /* not DEVICE_PREFIX */
1515 argp_error (state,
1516 _("Options '-[0-7][lmh]' not supported by *this* tar"));
1517 exit (EX_USAGE);
1519 #endif /* not DEVICE_PREFIX */
1520 break;
1522 case FULL_TIME_OPTION:
1523 full_time_option = true;
1524 break;
1526 case 'g':
1527 optloc_save (OC_LISTED_INCREMENTAL, args->loc);
1528 listed_incremental_option = arg;
1529 after_date_option = true;
1530 FALLTHROUGH;
1531 case 'G':
1532 /* We are making an incremental dump (FIXME: are we?); save
1533 directories at the beginning of the archive, and include in each
1534 directory its contents. */
1536 incremental_option = true;
1537 break;
1539 case 'h':
1540 /* Follow symbolic links. */
1541 dereference_option = true;
1542 break;
1544 case HARD_DEREFERENCE_OPTION:
1545 hard_dereference_option = true;
1546 break;
1548 case 'i':
1549 /* Ignore zero blocks (eofs). This can't be the default,
1550 because Unix tar writes two blocks of zeros, then pads out
1551 the record with garbage. */
1553 ignore_zeros_option = true;
1554 break;
1556 case 'j':
1557 set_use_compress_program_option (BZIP2_PROGRAM, args->loc);
1558 break;
1560 case 'J':
1561 set_use_compress_program_option (XZ_PROGRAM, args->loc);
1562 break;
1564 case 'k':
1565 /* Don't replace existing files. */
1566 set_old_files_option (KEEP_OLD_FILES, args->loc);
1567 break;
1569 case 'K':
1570 optloc_save (OC_STARTING_FILE, args->loc);
1571 add_starting_file (arg);
1572 break;
1574 case ONE_FILE_SYSTEM_OPTION:
1575 /* When dumping directories, don't dump files/subdirectories
1576 that are on other filesystems. */
1577 one_file_system_option = true;
1578 break;
1580 case ONE_TOP_LEVEL_OPTION:
1581 optloc_save (OC_ONE_TOP_LEVEL, args->loc);
1582 one_top_level_option = true;
1583 one_top_level_dir = arg;
1584 break;
1586 case 'l':
1587 check_links_option = 1;
1588 break;
1590 case 'L':
1592 uintmax_t u;
1593 char *p;
1595 if (xstrtoumax (arg, &p, 10, &u, TAR_SIZE_SUFFIXES) != LONGINT_OK)
1596 USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (arg),
1597 _("Invalid tape length")));
1598 if (p > arg && !strchr (TAR_SIZE_SUFFIXES, p[-1]))
1599 tape_length_option = 1024 * (tarlong) u;
1600 else
1601 tape_length_option = (tarlong) u;
1602 multi_volume_option = true;
1604 break;
1606 case LEVEL_OPTION:
1608 char *p;
1609 incremental_level = strtoul (arg, &p, 10);
1610 if (*p)
1611 USAGE_ERROR ((0, 0, _("Invalid incremental level value")));
1613 break;
1615 case LZIP_OPTION:
1616 set_use_compress_program_option (LZIP_PROGRAM, args->loc);
1617 break;
1619 case LZMA_OPTION:
1620 set_use_compress_program_option (LZMA_PROGRAM, args->loc);
1621 break;
1623 case LZOP_OPTION:
1624 set_use_compress_program_option (LZOP_PROGRAM, args->loc);
1625 break;
1627 case 'm':
1628 touch_option = true;
1629 break;
1631 case 'M':
1632 /* Make multivolume archive: when we can't write any more into
1633 the archive, re-open it, and continue writing. */
1635 multi_volume_option = true;
1636 break;
1638 case MTIME_OPTION:
1639 get_date_or_file (args, "--mtime", arg, &mtime_option);
1640 if (set_mtime_option == USE_FILE_MTIME)
1641 set_mtime_option = FORCE_MTIME;
1642 break;
1644 case 'n':
1645 seek_option = 1;
1646 break;
1648 case NO_SEEK_OPTION:
1649 seek_option = 0;
1650 break;
1652 case 'N':
1653 after_date_option = true;
1654 FALLTHROUGH;
1655 case NEWER_MTIME_OPTION:
1656 if (TIME_OPTION_INITIALIZED (newer_mtime_option))
1657 USAGE_ERROR ((0, 0, _("More than one threshold date")));
1658 get_date_or_file (args,
1659 key == NEWER_MTIME_OPTION ? "--newer-mtime"
1660 : "--after-date", arg, &newer_mtime_option);
1661 optloc_save (OC_NEWER, args->loc);
1662 break;
1664 case 'o':
1665 args->o_option = true;
1666 break;
1668 case 'O':
1669 to_stdout_option = true;
1670 break;
1672 case 'p':
1673 same_permissions_option = true;
1674 break;
1676 case 'P':
1677 optloc_save (OC_ABSOLUTE_NAMES, args->loc);
1678 absolute_names_option = true;
1679 break;
1681 case 'r':
1682 set_subcommand_option (APPEND_SUBCOMMAND);
1683 break;
1685 case 'R':
1686 /* Print block numbers for debugging bad tar archives. */
1688 /* It would surely make sense to exchange -B and -R, but it seems
1689 that -B has been used for a long while in Sun tar and most
1690 BSD-derived systems. This is a consequence of the block/record
1691 terminology confusion. */
1693 block_number_option = true;
1694 break;
1696 case 's':
1697 /* Names to extract are sorted. */
1698 optloc_save (OC_SAME_ORDER, args->loc);
1699 same_order_option = true;
1700 break;
1702 case 'S':
1703 sparse_option = true;
1704 break;
1706 case SKIP_OLD_FILES_OPTION:
1707 set_old_files_option (SKIP_OLD_FILES, args->loc);
1708 break;
1710 case HOLE_DETECTION_OPTION:
1711 hole_detection = XARGMATCH ("--hole-detection", arg,
1712 hole_detection_args, hole_detection_types);
1713 sparse_option = true;
1714 break;
1716 case SET_MTIME_COMMAND_OPTION:
1717 set_mtime_command = arg;
1718 break;
1720 case SET_MTIME_FORMAT_OPTION:
1721 set_mtime_format = arg;
1722 break;
1724 case SPARSE_VERSION_OPTION:
1725 sparse_option = true;
1727 char *p;
1728 tar_sparse_major = strtoul (arg, &p, 10);
1729 if (*p)
1731 if (*p != '.')
1732 USAGE_ERROR ((0, 0, _("Invalid sparse version value")));
1733 tar_sparse_minor = strtoul (p + 1, &p, 10);
1734 if (*p)
1735 USAGE_ERROR ((0, 0, _("Invalid sparse version value")));
1738 break;
1740 case 't':
1741 set_subcommand_option (LIST_SUBCOMMAND);
1742 verbose_option++;
1743 break;
1745 case TEST_LABEL_OPTION:
1746 set_subcommand_option (TEST_LABEL_SUBCOMMAND);
1747 break;
1749 case TRANSFORM_OPTION:
1750 set_transform_expr (arg);
1751 break;
1753 case 'u':
1754 set_subcommand_option (UPDATE_SUBCOMMAND);
1755 break;
1757 case 'U':
1758 set_old_files_option (UNLINK_FIRST_OLD_FILES, args->loc);
1759 break;
1761 case UTC_OPTION:
1762 utc_option = true;
1763 break;
1765 case 'V':
1766 volume_label_option = arg;
1767 break;
1769 case 'v':
1770 verbose_option++;
1771 warning_option |= WARN_VERBOSE_WARNINGS;
1772 break;
1774 case 'w':
1775 interactive_option = true;
1776 break;
1778 case 'W':
1779 optloc_save (OC_VERIFY, args->loc);
1780 verify_option = true;
1781 break;
1783 case WARNING_OPTION:
1784 set_warning_option (arg);
1785 break;
1787 case 'x':
1788 set_subcommand_option (EXTRACT_SUBCOMMAND);
1789 break;
1791 case 'z':
1792 set_use_compress_program_option (GZIP_PROGRAM, args->loc);
1793 break;
1795 case 'Z':
1796 set_use_compress_program_option (COMPRESS_PROGRAM, args->loc);
1797 break;
1799 case ZSTD_OPTION:
1800 set_use_compress_program_option (ZSTD_PROGRAM, args->loc);
1801 break;
1803 case ATIME_PRESERVE_OPTION:
1804 atime_preserve_option =
1805 (arg
1806 ? XARGMATCH ("--atime-preserve", arg,
1807 atime_preserve_args, atime_preserve_types)
1808 : replace_atime_preserve);
1809 if (! O_NOATIME && atime_preserve_option == system_atime_preserve)
1810 FATAL_ERROR ((0, 0,
1811 _("--atime-preserve='system' is not supported"
1812 " on this platform")));
1813 break;
1815 case CHECK_DEVICE_OPTION:
1816 check_device_option = true;
1817 break;
1819 case NO_CHECK_DEVICE_OPTION:
1820 check_device_option = false;
1821 break;
1823 case CHECKPOINT_OPTION:
1824 if (arg)
1826 char *p;
1828 if (*arg == '.')
1830 checkpoint_compile_action (".");
1831 arg++;
1833 checkpoint_option = strtoul (arg, &p, 0);
1834 if (*p)
1835 FATAL_ERROR ((0, 0,
1836 _("--checkpoint value is not an integer")));
1838 else
1839 checkpoint_option = DEFAULT_CHECKPOINT;
1840 break;
1842 case CHECKPOINT_ACTION_OPTION:
1843 checkpoint_compile_action (arg);
1844 break;
1846 case BACKUP_OPTION:
1847 backup_option = true;
1848 if (arg)
1849 args->version_control_string = arg;
1850 break;
1852 case DELAY_DIRECTORY_RESTORE_OPTION:
1853 delay_directory_restore_option = true;
1854 break;
1856 case NO_DELAY_DIRECTORY_RESTORE_OPTION:
1857 delay_directory_restore_option = false;
1858 break;
1860 case DELETE_OPTION:
1861 set_subcommand_option (DELETE_SUBCOMMAND);
1862 break;
1864 case FORCE_LOCAL_OPTION:
1865 force_local_option = true;
1866 break;
1868 case 'H':
1869 set_archive_format (arg);
1870 break;
1872 case INDEX_FILE_OPTION:
1873 index_file_name = arg;
1874 break;
1876 case IGNORE_COMMAND_ERROR_OPTION:
1877 ignore_command_error_option = true;
1878 break;
1880 case IGNORE_FAILED_READ_OPTION:
1881 ignore_failed_read_option = true;
1882 break;
1884 case KEEP_DIRECTORY_SYMLINK_OPTION:
1885 keep_directory_symlink_option = true;
1886 break;
1888 case KEEP_NEWER_FILES_OPTION:
1889 set_old_files_option (KEEP_NEWER_FILES, args->loc);
1890 break;
1892 case GROUP_OPTION:
1894 uintmax_t u = parse_owner_group (arg, TYPE_MAXIMUM (gid_t),
1895 &group_name_option);
1896 if (u == UINTMAX_MAX)
1898 group_option = -1;
1899 if (group_name_option)
1900 gname_to_gid (group_name_option, &group_option);
1902 else
1903 group_option = u;
1905 break;
1907 case GROUP_MAP_OPTION:
1908 group_map_read (arg);
1909 break;
1911 case MODE_OPTION:
1912 mode_option = mode_compile (arg);
1913 if (!mode_option)
1914 FATAL_ERROR ((0, 0, _("Invalid mode given on option")));
1915 initial_umask = umask (0);
1916 umask (initial_umask);
1917 break;
1919 case NO_IGNORE_COMMAND_ERROR_OPTION:
1920 ignore_command_error_option = false;
1921 break;
1923 case NO_OVERWRITE_DIR_OPTION:
1924 set_old_files_option (NO_OVERWRITE_DIR_OLD_FILES, args->loc);
1925 break;
1927 case NO_QUOTE_CHARS_OPTION:
1928 for (;*arg; arg++)
1929 set_char_quoting (NULL, *arg, 0);
1930 break;
1932 case NUMERIC_OWNER_OPTION:
1933 numeric_owner_option = true;
1934 break;
1936 case OCCURRENCE_OPTION:
1937 optloc_save (OC_OCCURRENCE, args->loc);
1938 if (!arg)
1939 occurrence_option = 1;
1940 else
1942 uintmax_t u;
1943 if (xstrtoumax (arg, 0, 10, &u, "") == LONGINT_OK)
1944 occurrence_option = u;
1945 else
1946 FATAL_ERROR ((0, 0, "%s: %s", quotearg_colon (arg),
1947 _("Invalid number")));
1949 break;
1951 case OLD_ARCHIVE_OPTION:
1952 set_archive_format ("v7");
1953 break;
1955 case OVERWRITE_DIR_OPTION:
1956 set_old_files_option (DEFAULT_OLD_FILES, args->loc);
1957 break;
1959 case OVERWRITE_OPTION:
1960 set_old_files_option (OVERWRITE_OLD_FILES, args->loc);
1961 break;
1963 case OWNER_OPTION:
1965 uintmax_t u = parse_owner_group (arg, TYPE_MAXIMUM (uid_t),
1966 &owner_name_option);
1967 if (u == UINTMAX_MAX)
1969 owner_option = -1;
1970 if (owner_name_option)
1971 uname_to_uid (owner_name_option, &owner_option);
1973 else
1974 owner_option = u;
1976 break;
1978 case OWNER_MAP_OPTION:
1979 owner_map_read (arg);
1980 break;
1982 case QUOTE_CHARS_OPTION:
1983 for (;*arg; arg++)
1984 set_char_quoting (NULL, *arg, 1);
1985 break;
1987 case QUOTING_STYLE_OPTION:
1988 tar_set_quoting_style (arg);
1989 break;
1991 case PAX_OPTION:
1993 char *tmp = expand_pax_option (args, arg);
1994 args->pax_option = true;
1995 xheader_set_option (tmp);
1996 free (tmp);
1998 break;
2000 case POSIX_OPTION:
2001 set_archive_format ("posix");
2002 break;
2004 case RECORD_SIZE_OPTION:
2006 uintmax_t u;
2008 if (! (xstrtoumax (arg, NULL, 10, &u, TAR_SIZE_SUFFIXES) == LONGINT_OK
2009 && u == (size_t) u))
2010 USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (arg),
2011 _("Invalid record size")));
2012 record_size = u;
2013 if (record_size % BLOCKSIZE != 0)
2014 USAGE_ERROR ((0, 0, _("Record size must be a multiple of %d."),
2015 BLOCKSIZE));
2016 blocking_factor = record_size / BLOCKSIZE;
2018 break;
2020 case RECURSIVE_UNLINK_OPTION:
2021 recursive_unlink_option = true;
2022 break;
2024 case REMOVE_FILES_OPTION:
2025 remove_files_option = true;
2026 break;
2028 case RESTRICT_OPTION:
2029 restrict_option = true;
2030 break;
2032 case RMT_COMMAND_OPTION:
2033 rmt_command = arg;
2034 break;
2036 case RSH_COMMAND_OPTION:
2037 rsh_command_option = arg;
2038 break;
2040 case SHOW_DEFAULTS_OPTION:
2042 char *s = format_default_settings ();
2043 printf ("%s\n", s);
2044 close_stdout ();
2045 free (s);
2046 exit (0);
2049 case SHOW_SNAPSHOT_FIELD_RANGES_OPTION:
2050 show_snapshot_field_ranges ();
2051 close_stdout ();
2052 exit (0);
2054 case STRIP_COMPONENTS_OPTION:
2056 uintmax_t u;
2057 if (! (xstrtoumax (arg, 0, 10, &u, "") == LONGINT_OK
2058 && u == (size_t) u))
2059 USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (arg),
2060 _("Invalid number of elements")));
2061 strip_name_components = u;
2063 break;
2065 case SHOW_OMITTED_DIRS_OPTION:
2066 show_omitted_dirs_option = true;
2067 break;
2069 case SHOW_TRANSFORMED_NAMES_OPTION:
2070 show_transformed_names_option = true;
2071 break;
2073 case SORT_OPTION:
2074 savedir_sort_order = XARGMATCH ("--sort", arg,
2075 sort_mode_arg, sort_mode_flag);
2076 break;
2078 case SUFFIX_OPTION:
2079 backup_option = true;
2080 args->backup_suffix_string = arg;
2081 break;
2083 case TO_COMMAND_OPTION:
2084 if (to_command_option)
2085 USAGE_ERROR ((0, 0, _("Only one --to-command option allowed")));
2086 to_command_option = arg;
2087 break;
2089 case TOTALS_OPTION:
2090 if (arg)
2091 set_stat_signal (arg);
2092 else
2093 totals_option = true;
2094 break;
2096 case 'I':
2097 set_use_compress_program_option (arg, args->loc);
2098 break;
2100 case VOLNO_FILE_OPTION:
2101 volno_file_option = arg;
2102 break;
2104 case NO_SAME_OWNER_OPTION:
2105 same_owner_option = -1;
2106 break;
2108 case NO_SAME_PERMISSIONS_OPTION:
2109 same_permissions_option = -1;
2110 break;
2112 case ACLS_OPTION:
2113 set_archive_format ("posix");
2114 acls_option = 1;
2115 break;
2117 case NO_ACLS_OPTION:
2118 acls_option = -1;
2119 break;
2121 case SELINUX_CONTEXT_OPTION:
2122 set_archive_format ("posix");
2123 selinux_context_option = 1;
2124 break;
2126 case NO_SELINUX_CONTEXT_OPTION:
2127 selinux_context_option = -1;
2128 break;
2130 case XATTR_OPTION:
2131 set_xattr_option (1);
2132 break;
2134 case NO_XATTR_OPTION:
2135 set_xattr_option (-1);
2136 break;
2138 case XATTR_INCLUDE:
2139 case XATTR_EXCLUDE:
2140 set_xattr_option (1);
2141 xattrs_mask_add (arg, (key == XATTR_INCLUDE));
2142 break;
2144 case SAME_OWNER_OPTION:
2145 same_owner_option = 1;
2146 break;
2148 case ARGP_KEY_ERROR:
2149 if (args->loc->source == OPTS_FILE)
2150 error (0, 0, _("%s:%lu: location of the error"), args->loc->name,
2151 (unsigned long) args->loc->line);
2152 else if (args->loc->source == OPTS_ENVIRON)
2153 error (0, 0, _("error parsing %s"), args->loc->name);
2154 exit (EX_USAGE);
2156 default:
2157 return ARGP_ERR_UNKNOWN;
2159 return 0;
2162 extern struct argp names_argp;
2163 static struct argp_child argp_children[] = {
2164 { &names_argp, 0, NULL, GRID_FILE_NAME },
2165 { NULL }
2168 static struct argp argp = {
2169 options,
2170 parse_opt,
2171 N_("[FILE]..."),
2172 doc,
2173 argp_children,
2174 tar_help_filter,
2175 NULL
2178 void
2179 usage (int status)
2181 argp_help (&argp, stderr, ARGP_HELP_SEE, (char*) program_name);
2182 close_stdout ();
2183 exit (status);
2186 /* Parse the options for tar. */
2188 static struct argp_option const *
2189 find_argp_option_key (struct argp_option const *o, int key)
2191 for (;
2192 !(o->name == NULL
2193 && o->key == 0
2194 && o->arg == 0
2195 && o->flags == 0
2196 && o->doc == NULL); o++)
2197 if (o->key == key)
2198 return o;
2199 return NULL;
2202 static struct argp_option const *
2203 find_argp_option (struct argp *ap, int key)
2205 struct argp_option const *p = NULL;
2206 struct argp_child const *child;
2208 p = find_argp_option_key (ap->options, key);
2209 if (!p && ap->children)
2211 for (child = ap->children; child->argp; child++)
2213 p = find_argp_option_key (child->argp->options, key);
2214 if (p)
2215 break;
2218 return p;
2221 static const char *tar_authors[] = {
2222 "John Gilmore",
2223 "Jay Fenlason",
2224 NULL
2227 /* Subcommand classes */
2228 #define SUBCL_READ 0x01 /* subcommand reads from the archive */
2229 #define SUBCL_WRITE 0x02 /* subcommand writes to the archive */
2230 #define SUBCL_UPDATE 0x04 /* subcommand updates existing archive */
2231 #define SUBCL_TEST 0x08 /* subcommand tests archive header or meta-info */
2232 #define SUBCL_OCCUR 0x10 /* subcommand allows the use of the occurrence
2233 option */
2235 static int subcommand_class[] = {
2236 /* UNKNOWN_SUBCOMMAND */ 0,
2237 /* APPEND_SUBCOMMAND */ SUBCL_WRITE|SUBCL_UPDATE,
2238 /* CAT_SUBCOMMAND */ SUBCL_WRITE,
2239 /* CREATE_SUBCOMMAND */ SUBCL_WRITE,
2240 /* DELETE_SUBCOMMAND */ SUBCL_WRITE|SUBCL_UPDATE|SUBCL_OCCUR,
2241 /* DIFF_SUBCOMMAND */ SUBCL_READ|SUBCL_OCCUR,
2242 /* EXTRACT_SUBCOMMAND */ SUBCL_READ|SUBCL_OCCUR,
2243 /* LIST_SUBCOMMAND */ SUBCL_READ|SUBCL_OCCUR,
2244 /* UPDATE_SUBCOMMAND */ SUBCL_WRITE|SUBCL_UPDATE,
2245 /* TEST_LABEL_SUBCOMMAND */ SUBCL_TEST
2248 /* Return t if the subcommand_option is in class(es) f */
2249 #define IS_SUBCOMMAND_CLASS(f) (subcommand_class[subcommand_option] & (f))
2251 void
2252 more_options (int argc, char **argv, struct option_locus *loc)
2254 struct tar_args args = TAR_ARGS_INITIALIZER (loc);
2255 argp_parse (&names_argp, argc, argv, ARGP_IN_ORDER|ARGP_NO_EXIT|ARGP_NO_ERRS,
2256 NULL, &args);
2259 static void
2260 parse_default_options (struct tar_args *args)
2262 char *opts = getenv ("TAR_OPTIONS");
2263 struct wordsplit ws;
2264 struct option_locus loc = { OPTS_ENVIRON, "TAR_OPTIONS", 0, 0 };
2265 struct option_locus *save_loc_ptr;
2267 if (!opts)
2268 return;
2270 ws.ws_offs = 1;
2271 if (wordsplit (opts, &ws, WRDSF_DEFFLAGS|WRDSF_DOOFFS))
2272 FATAL_ERROR ((0, 0, _("cannot split TAR_OPTIONS: %s"),
2273 wordsplit_strerror (&ws)));
2274 if (ws.ws_wordc)
2276 int idx;
2277 ws.ws_wordv[0] = (char*) program_name;
2278 save_loc_ptr = args->loc;
2279 args->loc = &loc;
2280 if (argp_parse (&argp,
2281 ws.ws_offs + ws.ws_wordc,
2282 ws.ws_wordv,
2283 ARGP_IN_ORDER|ARGP_NO_EXIT, &idx, args))
2284 abort (); /* shouldn't happen */
2285 args->loc = save_loc_ptr;
2286 if (name_more_files ())
2287 USAGE_ERROR ((0, 0, _("non-option arguments in %s"), loc.name));
2288 /* Don't free consumed words */
2289 ws.ws_wordc = 0;
2291 wordsplit_free (&ws);
2294 static void
2295 decode_options (int argc, char **argv)
2297 int idx;
2298 struct option_locus loc = { OPTS_COMMAND_LINE, 0, 0, 0 };
2299 struct tar_args args = TAR_ARGS_INITIALIZER (&loc);
2301 argp_version_setup ("tar", tar_authors);
2303 /* Set some default option values. */
2304 args.backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX");
2306 posixly_correct = getenv ("POSIXLY_CORRECT") != NULL;
2308 subcommand_option = UNKNOWN_SUBCOMMAND;
2309 archive_format = DEFAULT_FORMAT;
2310 blocking_factor = DEFAULT_BLOCKING;
2311 record_size = DEFAULT_BLOCKING * BLOCKSIZE;
2312 excluded = new_exclude ();
2313 hole_detection = HOLE_DETECTION_DEFAULT;
2315 newer_mtime_option.tv_sec = TYPE_MINIMUM (time_t);
2316 newer_mtime_option.tv_nsec = -1;
2317 mtime_option.tv_sec = TYPE_MINIMUM (time_t);
2318 mtime_option.tv_nsec = -1;
2319 recursion_option = FNM_LEADING_DIR;
2320 unquote_option = true;
2321 tar_sparse_major = 1;
2322 tar_sparse_minor = 0;
2324 savedir_sort_order = SAVEDIR_SORT_NONE;
2326 owner_option = -1; owner_name_option = NULL;
2327 group_option = -1; group_name_option = NULL;
2329 check_device_option = true;
2331 incremental_level = -1;
2333 seek_option = -1;
2335 /* Convert old-style tar call by exploding option element and rearranging
2336 options accordingly. */
2338 if (argc > 1 && argv[1][0] != '-')
2340 int new_argc; /* argc value for rearranged arguments */
2341 char **new_argv; /* argv value for rearranged arguments */
2342 char *const *in; /* cursor into original argv */
2343 char **out; /* cursor into rearranged argv */
2344 const char *letter; /* cursor into old option letters */
2345 char buffer[3]; /* constructed option buffer */
2347 /* Initialize a constructed option. */
2349 buffer[0] = '-';
2350 buffer[2] = '\0';
2352 /* Allocate a new argument array, and copy program name in it. */
2354 new_argc = argc - 1 + strlen (argv[1]);
2355 new_argv = xmalloc ((new_argc + 1) * sizeof (char *));
2356 in = argv;
2357 out = new_argv;
2358 *out++ = *in++;
2360 /* Copy each old letter option as a separate option, and have the
2361 corresponding argument moved next to it. */
2363 for (letter = *in++; *letter; letter++)
2365 struct argp_option const *opt;
2367 buffer[1] = *letter;
2368 *out++ = xstrdup (buffer);
2369 opt = find_argp_option (&argp, *letter);
2370 if (opt && opt->arg)
2372 if (in < argv + argc)
2373 *out++ = *in++;
2374 else
2375 USAGE_ERROR ((0, 0, _("Old option '%c' requires an argument."),
2376 *letter));
2380 /* Copy all remaining options. */
2382 while (in < argv + argc)
2383 *out++ = *in++;
2384 *out = 0;
2386 /* Replace the old option list by the new one. */
2388 argc = new_argc;
2389 argv = new_argv;
2392 /* Parse all options and non-options as they appear. */
2393 parse_default_options (&args);
2395 if (argp_parse (&argp, argc, argv, ARGP_IN_ORDER, &idx, &args))
2396 exit (TAREXIT_FAILURE);
2398 /* Special handling for 'o' option:
2400 GNU tar used to say "output old format".
2401 UNIX98 tar says don't chown files after extracting (we use
2402 "--no-same-owner" for this).
2404 The old GNU tar semantics is retained when used with --create
2405 option, otherwise UNIX98 semantics is assumed */
2407 if (args.o_option)
2409 if (subcommand_option == CREATE_SUBCOMMAND)
2411 /* GNU Tar <= 1.13 compatibility */
2412 set_archive_format ("v7");
2414 else
2416 /* UNIX98 compatibility */
2417 same_owner_option = -1;
2421 /* Handle operands after any "--" argument. */
2422 for (; idx < argc; idx++)
2423 name_add_name (argv[idx]);
2425 /* Derive option values and check option consistency. */
2427 if (archive_format == DEFAULT_FORMAT)
2429 if (args.pax_option)
2430 archive_format = POSIX_FORMAT;
2431 else
2432 archive_format = DEFAULT_ARCHIVE_FORMAT;
2435 if ((volume_label_option && subcommand_option == CREATE_SUBCOMMAND)
2436 || incremental_option
2437 || multi_volume_option
2438 || sparse_option)
2439 assert_format (FORMAT_MASK (OLDGNU_FORMAT)
2440 | FORMAT_MASK (GNU_FORMAT)
2441 | FORMAT_MASK (POSIX_FORMAT));
2443 if (occurrence_option)
2445 if (!name_more_files ())
2446 USAGE_ERROR ((0, 0,
2447 _("--occurrence is meaningless without a file list")));
2448 if (!IS_SUBCOMMAND_CLASS (SUBCL_OCCUR))
2450 if (option_set_in_cl (OC_OCCURRENCE))
2451 option_conflict_error ("--occurrence",
2452 subcommand_string (subcommand_option));
2453 else
2454 occurrence_option = 0;
2458 if (archive_names == 0)
2460 /* If no archive file name given, try TAPE from the environment, or
2461 else, DEFAULT_ARCHIVE from the configuration process. */
2463 archive_names = 1;
2464 archive_name_array[0] = getenv ("TAPE");
2465 if (! archive_name_array[0])
2466 archive_name_array[0] = DEFAULT_ARCHIVE;
2469 /* Allow multiple archives only with '-M'. */
2471 if (archive_names > 1 && !multi_volume_option)
2472 USAGE_ERROR ((0, 0,
2473 _("Multiple archive files require '-M' option")));
2475 if (listed_incremental_option
2476 && TIME_OPTION_INITIALIZED (newer_mtime_option))
2478 struct option_locus *listed_loc = optloc_lookup (OC_LISTED_INCREMENTAL);
2479 struct option_locus *newer_loc = optloc_lookup (OC_NEWER);
2480 if (optloc_eq (listed_loc, newer_loc))
2481 option_conflict_error ("--listed-incremental", "--newer");
2482 else if (listed_loc->source == OPTS_COMMAND_LINE)
2483 listed_incremental_option = NULL;
2484 else
2485 memset (&newer_mtime_option, 0, sizeof (newer_mtime_option));
2488 if (incremental_level != -1 && !listed_incremental_option)
2489 WARN ((0, 0,
2490 _("--level is meaningless without --listed-incremental")));
2492 if (volume_label_option)
2494 if (archive_format == GNU_FORMAT || archive_format == OLDGNU_FORMAT)
2496 size_t volume_label_max_len =
2497 (sizeof current_header->header.name
2498 - 1 /* for trailing '\0' */
2499 - (multi_volume_option
2500 ? (sizeof " Volume "
2501 - 1 /* for null at end of " Volume " */
2502 + INT_STRLEN_BOUND (int) /* for volume number */
2503 - 1 /* for sign, as 0 <= volno */)
2504 : 0));
2505 if (volume_label_max_len < strlen (volume_label_option))
2506 USAGE_ERROR ((0, 0,
2507 ngettext ("%s: Volume label is too long (limit is %lu byte)",
2508 "%s: Volume label is too long (limit is %lu bytes)",
2509 volume_label_max_len),
2510 quotearg_colon (volume_label_option),
2511 (unsigned long) volume_label_max_len));
2513 /* else FIXME
2514 Label length in PAX format is limited by the volume size. */
2517 if (verify_option)
2519 if (multi_volume_option)
2520 USAGE_ERROR ((0, 0, _("Cannot verify multi-volume archives")));
2521 if (use_compress_program_option)
2522 USAGE_ERROR ((0, 0, _("Cannot verify compressed archives")));
2523 if (!IS_SUBCOMMAND_CLASS (SUBCL_WRITE))
2525 if (option_set_in_cl (OC_VERIFY))
2526 option_conflict_error ("--verify",
2527 subcommand_string (subcommand_option));
2528 else
2529 verify_option = false;
2533 if (use_compress_program_option)
2535 if (multi_volume_option)
2536 USAGE_ERROR ((0, 0, _("Cannot use multi-volume compressed archives")));
2537 if (IS_SUBCOMMAND_CLASS (SUBCL_UPDATE))
2538 USAGE_ERROR ((0, 0, _("Cannot update compressed archives")));
2539 if (subcommand_option == CAT_SUBCOMMAND)
2540 USAGE_ERROR ((0, 0, _("Cannot concatenate compressed archives")));
2543 if (set_mtime_command)
2545 if (set_mtime_option != USE_FILE_MTIME)
2547 USAGE_ERROR ((0, 0,
2548 _("--mtime conflicts with --set-mtime-command")));
2550 set_mtime_option = COMMAND_MTIME;
2552 else if (set_mtime_option == CLAMP_MTIME)
2554 if (!TIME_OPTION_INITIALIZED (mtime_option))
2555 USAGE_ERROR ((0, 0,
2556 _("--clamp-mtime needs a date specified using --mtime")));
2559 /* It is no harm to use --pax-option on non-pax archives in archive
2560 reading mode. It may even be useful, since it allows to override
2561 file attributes from tar headers. Therefore I allow such usage.
2562 --gray */
2563 if (args.pax_option
2564 && archive_format != POSIX_FORMAT
2565 && !IS_SUBCOMMAND_CLASS (SUBCL_READ))
2566 USAGE_ERROR ((0, 0, _("--pax-option can be used only on POSIX archives")));
2568 /* star creates non-POSIX typed archives with xattr support, so allow the
2569 extra headers when reading */
2570 if ((acls_option > 0)
2571 && archive_format != POSIX_FORMAT
2572 && !IS_SUBCOMMAND_CLASS (SUBCL_READ))
2573 USAGE_ERROR ((0, 0, _("--acls can be used only on POSIX archives")));
2575 if ((selinux_context_option > 0)
2576 && archive_format != POSIX_FORMAT
2577 && !IS_SUBCOMMAND_CLASS (SUBCL_READ))
2578 USAGE_ERROR ((0, 0, _("--selinux can be used only on POSIX archives")));
2580 if ((xattrs_option > 0)
2581 && archive_format != POSIX_FORMAT
2582 && !IS_SUBCOMMAND_CLASS (SUBCL_READ))
2583 USAGE_ERROR ((0, 0, _("--xattrs can be used only on POSIX archives")));
2585 if (starting_file_option && !IS_SUBCOMMAND_CLASS (SUBCL_READ))
2587 if (option_set_in_cl (OC_STARTING_FILE))
2588 option_conflict_error ("--starting-file",
2589 subcommand_string (subcommand_option));
2590 else
2591 starting_file_option = false;
2594 if (same_order_option && !IS_SUBCOMMAND_CLASS (SUBCL_READ))
2596 if (option_set_in_cl (OC_SAME_ORDER))
2597 option_conflict_error ("--same-order",
2598 subcommand_string (subcommand_option));
2599 else
2600 same_order_option = false;
2603 if (one_top_level_option)
2605 char *base;
2607 if (absolute_names_option)
2609 struct option_locus *one_top_level_loc =
2610 optloc_lookup (OC_ONE_TOP_LEVEL);
2611 struct option_locus *absolute_names_loc =
2612 optloc_lookup (OC_ABSOLUTE_NAMES);
2614 if (optloc_eq (one_top_level_loc, absolute_names_loc))
2615 option_conflict_error ("--one-top-level", "--absolute-names");
2616 else if (one_top_level_loc->source == OPTS_COMMAND_LINE)
2617 absolute_names_option = false;
2618 else
2619 one_top_level_option = false;
2622 if (one_top_level_option && !one_top_level_dir)
2624 /* If the user wants to guarantee that everything is under one
2625 directory, determine its name now and let it be created later. */
2626 base = base_name (archive_name_array[0]);
2627 one_top_level_dir = strip_compression_suffix (base);
2628 free (base);
2630 if (!one_top_level_dir)
2631 USAGE_ERROR ((0, 0,
2632 _("Cannot deduce top-level directory name; "
2633 "please set it explicitly with --one-top-level=DIR")));
2637 /* If ready to unlink hierarchies, so we are for simpler files. */
2638 if (recursive_unlink_option)
2639 old_files_option = UNLINK_FIRST_OLD_FILES;
2641 /* Flags for accessing files to be read from or copied into. POSIX says
2642 O_NONBLOCK has unspecified effect on most types of files, but in
2643 practice it never harms and sometimes helps. */
2645 int base_open_flags =
2646 (O_BINARY | O_CLOEXEC | O_NOCTTY | O_NONBLOCK
2647 | (dereference_option ? 0 : O_NOFOLLOW)
2648 | (atime_preserve_option == system_atime_preserve ? O_NOATIME : 0));
2649 open_read_flags = O_RDONLY | base_open_flags;
2650 open_searchdir_flags = O_SEARCH | O_DIRECTORY | base_open_flags;
2652 fstatat_flags = dereference_option ? 0 : AT_SYMLINK_NOFOLLOW;
2654 if (subcommand_option == TEST_LABEL_SUBCOMMAND)
2656 /* --test-label is silent if the user has specified the label name to
2657 compare against. */
2658 if (!name_more_files ())
2659 verbose_option++;
2661 else if (utc_option)
2662 verbose_option = 2;
2664 if (tape_length_option && tape_length_option < record_size)
2665 USAGE_ERROR ((0, 0, _("Volume length cannot be less than record size")));
2667 if (same_order_option && listed_incremental_option)
2669 struct option_locus *preserve_order_loc = optloc_lookup (OC_SAME_ORDER);
2670 struct option_locus *listed_incremental_loc =
2671 optloc_lookup (OC_LISTED_INCREMENTAL);
2673 if (optloc_eq (preserve_order_loc, listed_incremental_loc))
2674 option_conflict_error ("--preserve-order", "--listed-incremental");
2675 else if (preserve_order_loc->source == OPTS_COMMAND_LINE)
2676 listed_incremental_option = NULL;
2677 else
2678 same_order_option = false;
2681 /* Forbid using -c with no input files whatsoever. Check that '-f -',
2682 explicit or implied, is used correctly. */
2684 switch (subcommand_option)
2686 case CREATE_SUBCOMMAND:
2687 if (!name_more_files ())
2688 USAGE_ERROR ((0, 0,
2689 _("Cowardly refusing to create an empty archive")));
2690 if (args.compress_autodetect && archive_names
2691 && strcmp (archive_name_array[0], "-"))
2692 set_compression_program_by_suffix (archive_name_array[0],
2693 use_compress_program_option);
2694 break;
2696 case EXTRACT_SUBCOMMAND:
2697 case LIST_SUBCOMMAND:
2698 case DIFF_SUBCOMMAND:
2699 case TEST_LABEL_SUBCOMMAND:
2700 for (archive_name_cursor = archive_name_array;
2701 archive_name_cursor < archive_name_array + archive_names;
2702 archive_name_cursor++)
2703 if (!strcmp (*archive_name_cursor, "-"))
2704 request_stdin ("-f");
2705 break;
2707 case CAT_SUBCOMMAND:
2708 case UPDATE_SUBCOMMAND:
2709 case APPEND_SUBCOMMAND:
2710 for (archive_name_cursor = archive_name_array;
2711 archive_name_cursor < archive_name_array + archive_names;
2712 archive_name_cursor++)
2713 if (!strcmp (*archive_name_cursor, "-"))
2714 USAGE_ERROR ((0, 0,
2715 _("Options '-Aru' are incompatible with '-f -'")));
2717 default:
2718 break;
2721 /* Initialize stdlis */
2722 if (index_file_name)
2724 stdlis = fopen (index_file_name, "w");
2725 if (! stdlis)
2726 open_fatal (index_file_name);
2728 else
2729 stdlis = to_stdout_option ? stderr : stdout;
2731 archive_name_cursor = archive_name_array;
2733 /* Prepare for generating backup names. */
2735 if (args.backup_suffix_string)
2736 simple_backup_suffix = xstrdup (args.backup_suffix_string);
2738 if (backup_option)
2740 backup_type = xget_version ("--backup", args.version_control_string);
2741 /* No backup is needed either if explicitly disabled or if
2742 the extracted files are not being written to disk. */
2743 if (backup_type == no_backups || EXTRACT_OVER_PIPE)
2744 backup_option = false;
2747 checkpoint_finish_compile ();
2749 report_textual_dates (&args);
2752 #ifdef ENABLE_ERROR_PRINT_PROGNAME
2753 /* The error() function from glibc correctly prefixes each message it
2754 prints with program_name as set by set_program_name. However, its
2755 replacement from gnulib, which is linked in on systems where this
2756 function is not available, prints the name returned by getprogname()
2757 instead. Due to this messages output by tar subprocess (which sets its
2758 program name to 'tar (child)') become indiscernible from those printed
2759 by the main process. In particular, this breaks the remfiles01.at and
2760 remfiles02.at test cases.
2762 To avoid this, on such systems the following helper function is used
2763 to print proper program name. Its address is assigned to the
2764 error_print_progname variable, which error() then uses instead of
2765 printing getprogname() result.
2767 static void
2768 tar_print_progname (void)
2770 fprintf (stderr, "%s: ", program_name);
2772 #endif
2774 /* Tar proper. */
2776 /* Main routine for tar. */
2778 main (int argc, char **argv)
2780 set_start_time ();
2781 set_program_name (argv[0]);
2782 #ifdef ENABLE_ERROR_PRINT_PROGNAME
2783 error_print_progname = tar_print_progname;
2784 #endif
2785 setlocale (LC_ALL, "");
2786 bindtextdomain (PACKAGE, LOCALEDIR);
2787 textdomain (PACKAGE);
2789 exit_failure = TAREXIT_FAILURE;
2790 exit_status = TAREXIT_SUCCESS;
2791 error_hook = checkpoint_flush_actions;
2793 set_quoting_style (0, DEFAULT_QUOTING_STYLE);
2795 close_stdout_set_file_name (_("stdout"));
2796 /* Make sure we have first three descriptors available */
2797 if (stdopen ())
2798 FATAL_ERROR ((0, 0, "%s",
2799 _("failed to assert availability of the standard file descriptors")));
2801 /* Pre-allocate a few structures. */
2803 allocated_archive_names = 10;
2804 archive_name_array =
2805 xmalloc (sizeof (const char *) * allocated_archive_names);
2806 archive_names = 0;
2808 /* System V fork+wait does not work if SIGCHLD is ignored. */
2809 signal (SIGCHLD, SIG_DFL);
2811 /* Try to disable the ability to unlink a directory. */
2812 priv_set_remove_linkdir ();
2814 /* Decode options. */
2816 decode_options (argc, argv);
2818 name_init ();
2820 /* Main command execution. */
2822 if (volno_file_option)
2823 init_volume_number ();
2825 switch (subcommand_option)
2827 case UNKNOWN_SUBCOMMAND:
2828 USAGE_ERROR ((0, 0,
2829 _("You must specify one of the '-Acdtrux', '--delete' or '--test-label' options")));
2831 case CAT_SUBCOMMAND:
2832 case UPDATE_SUBCOMMAND:
2833 case APPEND_SUBCOMMAND:
2834 update_archive ();
2835 break;
2837 case DELETE_SUBCOMMAND:
2838 delete_archive_members ();
2839 break;
2841 case CREATE_SUBCOMMAND:
2842 create_archive ();
2843 break;
2845 case EXTRACT_SUBCOMMAND:
2846 extr_init ();
2847 read_and (extract_archive);
2849 /* FIXME: should extract_finish () even if an ordinary signal is
2850 received. */
2851 extract_finish ();
2853 break;
2855 case LIST_SUBCOMMAND:
2856 read_and (list_archive);
2857 break;
2859 case DIFF_SUBCOMMAND:
2860 diff_init ();
2861 read_and (diff_archive);
2862 break;
2864 case TEST_LABEL_SUBCOMMAND:
2865 test_archive_label ();
2868 checkpoint_finish ();
2870 if (totals_option)
2871 print_total_stats ();
2873 if (check_links_option)
2874 check_links ();
2876 if (volno_file_option)
2877 closeout_volume_number ();
2879 /* There is little point to freeing, as we are about to exit,
2880 and freeing is more likely to cause than cure trouble. */
2881 if (false)
2883 free (archive_name_array);
2884 xattrs_clear_setup ();
2885 name_term ();
2888 if (exit_status == TAREXIT_FAILURE)
2889 error (0, 0, _("Exiting with failure status due to previous errors"));
2891 if (stdlis == stdout)
2892 close_stdout ();
2893 else if (ferror (stderr) || fclose (stderr) != 0)
2894 set_exit_status (TAREXIT_FAILURE);
2896 return exit_status;
2899 void
2900 tar_stat_init (struct tar_stat_info *st)
2902 memset (st, 0, sizeof (*st));
2905 /* Close the stream or file descriptor associated with ST, and remove
2906 all traces of it from ST. Return true if successful, false (with a
2907 diagnostic) otherwise. */
2908 bool
2909 tar_stat_close (struct tar_stat_info *st)
2911 int status = (st->dirstream ? closedir (st->dirstream)
2912 : 0 < st->fd ? close (st->fd)
2913 : 0);
2914 st->dirstream = 0;
2915 st->fd = 0;
2917 if (status == 0)
2918 return true;
2919 else
2921 close_diag (st->orig_file_name);
2922 return false;
2926 void
2927 tar_stat_destroy (struct tar_stat_info *st)
2929 tar_stat_close (st);
2930 xattr_map_free (&st->xattr_map);
2931 free (st->orig_file_name);
2932 free (st->file_name);
2933 free (st->link_name);
2934 free (st->uname);
2935 free (st->gname);
2936 free (st->cntx_name);
2937 free (st->acls_a_ptr);
2938 free (st->acls_d_ptr);
2939 free (st->sparse_map);
2940 free (st->dumpdir);
2941 xheader_destroy (&st->xhdr);
2942 info_free_exclist (st);
2943 memset (st, 0, sizeof (*st));
2946 /* Format mask for all available formats that support nanosecond
2947 timestamp resolution. */
2948 #define NS_PRECISION_FORMAT_MASK FORMAT_MASK (POSIX_FORMAT)
2950 /* Same as timespec_cmp, but ignore nanoseconds if current archive
2951 format does not provide sufficient resolution. */
2953 tar_timespec_cmp (struct timespec a, struct timespec b)
2955 if (!(FORMAT_MASK (current_format) & NS_PRECISION_FORMAT_MASK))
2956 a.tv_nsec = b.tv_nsec = 0;
2957 return timespec_cmp (a, b);
2960 /* Set tar exit status to VAL, unless it is already indicating
2961 a more serious condition. This relies on the fact that the
2962 values of TAREXIT_ constants are ranged by severity. */
2963 void
2964 set_exit_status (int val)
2966 if (val > exit_status)
2967 exit_status = val;