Prefer other types to int in xattrs.c
[tar.git] / src / tar.c
blob66486fcf4276944dd54b1f70e4946c9fa01d647c
1 /* A tar (tape archiver) program.
3 Copyright 1988-2024 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 #include "common.h"
34 /* Define variables declared in common.h that belong to tar.c. */
35 enum subcommand subcommand_option;
36 enum archive_format archive_format;
37 idx_t blocking_factor;
38 idx_t record_size;
39 bool absolute_names_option;
40 bool utc_option;
41 bool full_time_option;
42 bool after_date_option;
43 enum atime_preserve atime_preserve_option;
44 bool backup_option;
45 enum backup_type backup_type;
46 bool block_number_option;
47 intmax_t checkpoint_option;
48 const char *use_compress_program_option;
49 bool dereference_option;
50 bool hard_dereference_option;
51 struct exclude *excluded;
52 char const *group_name_option;
53 gid_t group_option;
54 bool ignore_failed_read_option;
55 bool ignore_zeros_option;
56 bool incremental_option;
57 const char *info_script_option;
58 bool interactive_option;
59 intmax_t occurrence_option;
60 enum old_files old_files_option;
61 bool keep_directory_symlink_option;
62 const char *listed_incremental_option;
63 signed char incremental_level;
64 bool check_device_option;
65 struct mode_change *mode_option;
66 mode_t initial_umask;
67 bool multi_volume_option;
68 struct timespec newer_mtime_option;
69 enum set_mtime_option_mode set_mtime_option;
70 struct timespec mtime_option;
71 char *set_mtime_command;
72 char *set_mtime_format;
73 int recursion_option;
74 bool numeric_owner_option;
75 bool one_file_system_option;
76 bool one_top_level_option;
77 char *one_top_level_dir;
78 char const *owner_name_option;
79 uid_t owner_option;
80 bool recursive_unlink_option;
81 bool read_full_records_option;
82 bool remove_files_option;
83 const char *rsh_command_option;
84 bool same_order_option;
85 int same_owner_option;
86 int same_permissions_option;
87 int selinux_context_option;
88 int acls_option;
89 bool xattrs_option;
90 idx_t strip_name_components;
91 bool show_omitted_dirs_option;
92 bool sparse_option;
93 intmax_t tar_sparse_major;
94 intmax_t tar_sparse_minor;
95 enum hole_detection_method hole_detection;
96 bool starting_file_option;
97 tarlong tape_length_option;
98 bool to_stdout_option;
99 bool totals_option;
100 bool touch_option;
101 char *to_command_option;
102 bool ignore_command_error_option;
103 bool restrict_option;
104 int verbose_option;
105 bool verify_option;
106 const char *volno_file_option;
107 const char *volume_label_option;
108 bool posixly_correct;
109 const char **archive_name_array;
110 idx_t archive_names;
111 const char **archive_name_cursor;
112 char const *index_file_name;
113 int open_read_flags;
114 int open_searchdir_flags;
115 int fstatat_flags;
116 int seek_option;
117 bool unquote_option;
118 int savedir_sort_order;
119 bool show_transformed_names_option;
120 bool delay_directory_restore_option;
122 #include <argmatch.h>
123 #include <c-ctype.h>
124 #include <closeout.h>
125 #include <configmake.h>
126 #include <exitfail.h>
127 #include <parse-datetime.h>
128 #include <rmt.h>
129 #include <rmt-command.h>
130 #include <wordsplit.h>
131 #include <sysexits.h>
132 #include <quotearg.h>
133 #include <version-etc.h>
134 #include <xstrtol.h>
135 #include <stdopen.h>
136 #include <priv-set.h>
137 #include <savedir.h>
139 /* Local declarations. */
141 #ifndef DEFAULT_ARCHIVE_FORMAT
142 # define DEFAULT_ARCHIVE_FORMAT GNU_FORMAT
143 #endif
145 #ifndef DEFAULT_ARCHIVE
146 # define DEFAULT_ARCHIVE "tar.out"
147 #endif
149 #ifndef DEFAULT_BLOCKING
150 # define DEFAULT_BLOCKING 20
151 #endif
153 /* Print a message if not all links are dumped */
154 static bool check_links_option;
156 /* Number of allocated tape drive names. */
157 static idx_t allocated_archive_names;
160 /* Miscellaneous. */
162 /* Name of option using stdin. */
163 static const char *stdin_used_by;
165 /* Doesn't return if stdin already requested. */
166 void
167 request_stdin (const char *option)
169 if (stdin_used_by)
170 paxusage (_("Options '%s' and '%s' both want standard input"),
171 stdin_used_by, option);
173 stdin_used_by = option;
176 /* Returns true if and only if the user typed an affirmative response. */
177 bool
178 confirm (const char *message_action, const char *message_name)
180 static FILE *confirm_file;
181 static bool confirm_file_EOF;
182 bool status = false;
184 if (!confirm_file)
186 if (archive == 0 || stdin_used_by)
188 confirm_file = fopen (TTY_NAME, "r");
189 if (! confirm_file)
190 open_fatal (TTY_NAME);
192 else
194 request_stdin ("-w");
195 confirm_file = stdin;
199 fprintf (stdlis, "%s %s?", message_action, quote (message_name));
200 fflush (stdlis);
202 if (!confirm_file_EOF)
204 char *response = NULL;
205 size_t response_size = 0;
206 if (getline (&response, &response_size, confirm_file) < 0)
207 confirm_file_EOF = true;
208 else
209 status = rpmatch (response) > 0;
210 free (response);
213 if (confirm_file_EOF)
215 fputc ('\n', stdlis);
216 fflush (stdlis);
219 return status;
222 static struct fmttab {
223 char const *name;
224 enum archive_format fmt;
225 } const fmttab[] = {
226 { "v7", V7_FORMAT },
227 { "oldgnu", OLDGNU_FORMAT },
228 { "ustar", USTAR_FORMAT },
229 { "posix", POSIX_FORMAT },
230 #if 0 /* not fully supported yet */
231 { "star", STAR_FORMAT },
232 #endif
233 { "gnu", GNU_FORMAT },
234 { "pax", POSIX_FORMAT }, /* An alias for posix */
235 { NULL, 0 }
238 static void
239 set_archive_format (char const *name)
241 struct fmttab const *p;
243 for (p = fmttab; strcmp (p->name, name) != 0; )
244 if (! (++p)->name)
245 paxusage (_("%s: Invalid archive format"),
246 quotearg_colon (name));
248 archive_format = p->fmt;
251 static void
252 set_xattr_option (bool value)
254 if (value)
255 set_archive_format ("posix");
256 xattrs_option = value;
259 const char *
260 archive_format_string (enum archive_format fmt)
262 struct fmttab const *p;
264 for (p = fmttab; p->name; p++)
265 if (p->fmt == fmt)
266 return p->name;
267 return "unknown?";
270 static int
271 format_mask (int n)
273 return 1 << n;
276 static void
277 assert_format (int fmt_mask)
279 if ((format_mask (archive_format) & fmt_mask) == 0)
280 paxusage (_("GNU features wanted on incompatible archive format"));
283 const char *
284 subcommand_string (enum subcommand c)
286 switch (c)
288 case UNKNOWN_SUBCOMMAND:
289 return "unknown?";
291 case APPEND_SUBCOMMAND:
292 return "-r";
294 case CAT_SUBCOMMAND:
295 return "-A";
297 case CREATE_SUBCOMMAND:
298 return "-c";
300 case DELETE_SUBCOMMAND:
301 return "-D";
303 case DIFF_SUBCOMMAND:
304 return "-d";
306 case EXTRACT_SUBCOMMAND:
307 return "-x";
309 case LIST_SUBCOMMAND:
310 return "-t";
312 case UPDATE_SUBCOMMAND:
313 return "-u";
315 case TEST_LABEL_SUBCOMMAND:
316 return "--test-label";
318 abort ();
321 static void
322 tar_list_quoting_styles (struct obstack *stk, char const *prefix)
324 idx_t prefixlen = strlen (prefix);
326 for (idx_t i = 0; quoting_style_args[i]; i++)
328 obstack_grow (stk, prefix, prefixlen);
329 obstack_grow (stk, quoting_style_args[i],
330 strlen (quoting_style_args[i]));
331 obstack_1grow (stk, '\n');
335 static void
336 tar_set_quoting_style (char *arg)
338 for (idx_t i = 0; quoting_style_args[i]; i++)
339 if (strcmp (arg, quoting_style_args[i]) == 0)
341 set_quoting_style (NULL, i);
342 return;
344 paxfatal (0,
345 _("Unknown quoting style '%s'."
346 " Try '%s --quoting-style=help' to get a list."),
347 arg, program_name);
351 /* Options. */
353 enum
355 ACLS_OPTION = CHAR_MAX + 1,
356 ATIME_PRESERVE_OPTION,
357 BACKUP_OPTION,
358 CHECK_DEVICE_OPTION,
359 CHECKPOINT_OPTION,
360 CHECKPOINT_ACTION_OPTION,
361 CLAMP_MTIME_OPTION,
362 DELAY_DIRECTORY_RESTORE_OPTION,
363 HARD_DEREFERENCE_OPTION,
364 DELETE_OPTION,
365 FORCE_LOCAL_OPTION,
366 FULL_TIME_OPTION,
367 GROUP_OPTION,
368 GROUP_MAP_OPTION,
369 IGNORE_COMMAND_ERROR_OPTION,
370 IGNORE_FAILED_READ_OPTION,
371 INDEX_FILE_OPTION,
372 KEEP_DIRECTORY_SYMLINK_OPTION,
373 KEEP_NEWER_FILES_OPTION,
374 LEVEL_OPTION,
375 LZIP_OPTION,
376 LZMA_OPTION,
377 LZOP_OPTION,
378 MODE_OPTION,
379 MTIME_OPTION,
380 NEWER_MTIME_OPTION,
381 NO_ACLS_OPTION,
382 NO_AUTO_COMPRESS_OPTION,
383 NO_CHECK_DEVICE_OPTION,
384 NO_DELAY_DIRECTORY_RESTORE_OPTION,
385 NO_IGNORE_COMMAND_ERROR_OPTION,
386 NO_OVERWRITE_DIR_OPTION,
387 NO_QUOTE_CHARS_OPTION,
388 NO_SAME_OWNER_OPTION,
389 NO_SAME_PERMISSIONS_OPTION,
390 NO_SEEK_OPTION,
391 NO_SELINUX_CONTEXT_OPTION,
392 NO_XATTR_OPTION,
393 NUMERIC_OWNER_OPTION,
394 OCCURRENCE_OPTION,
395 OLD_ARCHIVE_OPTION,
396 ONE_FILE_SYSTEM_OPTION,
397 ONE_TOP_LEVEL_OPTION,
398 OVERWRITE_DIR_OPTION,
399 OVERWRITE_OPTION,
400 OWNER_OPTION,
401 OWNER_MAP_OPTION,
402 PAX_OPTION,
403 POSIX_OPTION,
404 QUOTE_CHARS_OPTION,
405 QUOTING_STYLE_OPTION,
406 RECORD_SIZE_OPTION,
407 RECURSIVE_UNLINK_OPTION,
408 REMOVE_FILES_OPTION,
409 RESTRICT_OPTION,
410 RMT_COMMAND_OPTION,
411 RSH_COMMAND_OPTION,
412 SAME_OWNER_OPTION,
413 SELINUX_CONTEXT_OPTION,
414 SHOW_DEFAULTS_OPTION,
415 SHOW_OMITTED_DIRS_OPTION,
416 SHOW_SNAPSHOT_FIELD_RANGES_OPTION,
417 SHOW_TRANSFORMED_NAMES_OPTION,
418 SKIP_OLD_FILES_OPTION,
419 SORT_OPTION,
420 HOLE_DETECTION_OPTION,
421 SPARSE_VERSION_OPTION,
422 STRIP_COMPONENTS_OPTION,
423 SUFFIX_OPTION,
424 TEST_LABEL_OPTION,
425 TOTALS_OPTION,
426 TO_COMMAND_OPTION,
427 TRANSFORM_OPTION,
428 UTC_OPTION,
429 VOLNO_FILE_OPTION,
430 WARNING_OPTION,
431 XATTR_OPTION,
432 XATTR_EXCLUDE,
433 XATTR_INCLUDE,
434 ZSTD_OPTION,
435 SET_MTIME_COMMAND_OPTION,
436 SET_MTIME_FORMAT_OPTION,
439 static char const doc[] = N_("\
440 GNU 'tar' saves many files together into a single tape or disk archive, \
441 and can restore individual files from the archive.\n\
443 Examples:\n\
444 tar -cf archive.tar foo bar # Create archive.tar from files foo and bar.\n\
445 tar -tvf archive.tar # List all files in archive.tar verbosely.\n\
446 tar -xf archive.tar # Extract all files from archive.tar.\n")
447 "\v"
448 N_("The backup suffix is '~', unless set with --suffix or SIMPLE_BACKUP_SUFFIX.\n\
449 The version control may be set with --backup or VERSION_CONTROL, values are:\n\n\
450 none, off never make backups\n\
451 t, numbered make numbered backups\n\
452 nil, existing numbered if numbered backups exist, simple otherwise\n\
453 never, simple always make simple backups\n");
456 /* NOTE:
458 Available option letters are DEQY and eqy. Consider the following
459 assignments:
461 [For Solaris tar compatibility =/= Is it important at all?]
462 e exit immediately with a nonzero exit status if unexpected errors occur
463 E use extended headers (--format=posix)
465 [q alias for --occurrence=1 =/= this would better be used for quiet?]
467 y per-file gzip compression
468 Y per-block gzip compression.
470 Additionally, the 'n' letter is assigned for option --seek, which
471 is probably not needed and should be marked as deprecated, so that
472 -n may become available in the future.
475 /* Option group idenitfiers help in sorting options by category: */
476 enum
478 GRH_COMMAND,
479 GRID_COMMAND, /* Main operation mode */
481 GRH_MODIFIER,
482 GRID_MODIFIER, /* Operation modifiers */
484 GRID_FILE_NAME,
486 GRH_OVERWRITE,
487 GRID_OVERWRITE, /* Overwrite control options */
489 GRH_OUTPUT,
490 GRID_OUTPUT, /* Output stream selection */
492 GRH_FATTR,
493 GRID_FATTR, /* File attributes (ownership and mode) */
495 GRH_XATTR,
496 GRID_XATTR, /* Extended file attributes */
498 GRH_DEVICE,
499 GRID_DEVICE, /* Device selection */
501 GRH_BLOCKING,
502 GRID_BLOCKING, /* Block and record length */
504 GRH_FORMAT,
505 GRID_FORMAT, /* Archive format options */
506 GRDOC_FORMAT,
508 GRID_FORMAT_OPT,
510 GRH_COMPRESS,
511 GRID_COMPRESS, /* Compression options */
513 GRH_FILE,
514 GRID_FILE, /* File selection options */
516 GRH_NAME_XFORM,
517 GRID_NAME_XFORM, /* File name transformations */
519 GRH_INFORMATIVE,
520 GRID_INFORMATIVE, /* Informative options */
522 GRH_COMPAT,
523 GRID_COMPAT, /* Compatibility options */
525 GRH_OTHER,
526 GRID_OTHER /* Other options */
529 static struct argp_option options[] = {
530 {NULL, 0, NULL, 0,
531 N_("Main operation mode:"), GRH_COMMAND },
533 {"list", 't', 0, 0,
534 N_("list the contents of an archive"), GRID_COMMAND },
535 {"extract", 'x', 0, 0,
536 N_("extract files from an archive"), GRID_COMMAND },
537 {"get", 0, 0, OPTION_ALIAS, NULL, GRID_COMMAND },
538 {"create", 'c', 0, 0,
539 N_("create a new archive"), GRID_COMMAND },
540 {"diff", 'd', 0, 0,
541 N_("find differences between archive and file system"), GRID_COMMAND },
542 {"compare", 0, 0, OPTION_ALIAS, NULL, GRID_COMMAND },
543 {"append", 'r', 0, 0,
544 N_("append files to the end of an archive"), GRID_COMMAND },
545 {"update", 'u', 0, 0,
546 N_("only append files newer than copy in archive"), GRID_COMMAND },
547 {"catenate", 'A', 0, 0,
548 N_("append tar files to an archive"), GRID_COMMAND },
549 {"concatenate", 0, 0, OPTION_ALIAS, NULL, GRID_COMMAND },
550 {"delete", DELETE_OPTION, 0, 0,
551 N_("delete from the archive (not on mag tapes!)"), GRID_COMMAND },
552 {"test-label", TEST_LABEL_OPTION, NULL, 0,
553 N_("test the archive volume label and exit"), GRID_COMMAND },
555 {NULL, 0, NULL, 0,
556 N_("Operation modifiers:"), GRH_MODIFIER },
558 {"sparse", 'S', 0, 0,
559 N_("handle sparse files efficiently"), GRID_MODIFIER },
560 {"hole-detection", HOLE_DETECTION_OPTION, N_("TYPE"), 0,
561 N_("technique to detect holes"), GRID_MODIFIER },
562 {"sparse-version", SPARSE_VERSION_OPTION, N_("MAJOR[.MINOR]"), 0,
563 N_("set version of the sparse format to use (implies --sparse)"),
564 GRID_MODIFIER},
565 {"incremental", 'G', 0, 0,
566 N_("handle old GNU-format incremental backup"), GRID_MODIFIER },
567 {"listed-incremental", 'g', N_("FILE"), 0,
568 N_("handle new GNU-format incremental backup"), GRID_MODIFIER },
569 {"level", LEVEL_OPTION, N_("NUMBER"), 0,
570 N_("dump level for created listed-incremental archive"), GRID_MODIFIER },
571 {"ignore-failed-read", IGNORE_FAILED_READ_OPTION, 0, 0,
572 N_("do not exit with nonzero on unreadable files"), GRID_MODIFIER },
573 {"occurrence", OCCURRENCE_OPTION, N_("NUMBER"), OPTION_ARG_OPTIONAL,
574 N_("process only the NUMBERth occurrence of each file in the archive;"
575 " this option is valid only in conjunction with one of the subcommands"
576 " --delete, --diff, --extract or --list and when a list of files"
577 " is given either on the command line or via the -T option;"
578 " NUMBER defaults to 1"), GRID_MODIFIER },
579 {"seek", 'n', NULL, 0,
580 N_("archive is seekable"), GRID_MODIFIER },
581 {"no-seek", NO_SEEK_OPTION, NULL, 0,
582 N_("archive is not seekable"), GRID_MODIFIER },
583 {"no-check-device", NO_CHECK_DEVICE_OPTION, NULL, 0,
584 N_("do not check device numbers when creating incremental archives"),
585 GRID_MODIFIER },
586 {"check-device", CHECK_DEVICE_OPTION, NULL, 0,
587 N_("check device numbers when creating incremental archives (default)"),
588 GRID_MODIFIER },
590 {NULL, 0, NULL, 0,
591 N_("Overwrite control:"), GRH_OVERWRITE },
593 {"verify", 'W', 0, 0,
594 N_("attempt to verify the archive after writing it"), GRID_OVERWRITE },
595 {"remove-files", REMOVE_FILES_OPTION, 0, 0,
596 N_("remove files after adding them to the archive"), GRID_OVERWRITE },
597 {"keep-old-files", 'k', 0, 0,
598 N_("don't replace existing files when extracting, "
599 "treat them as errors"), GRID_OVERWRITE },
600 {"skip-old-files", SKIP_OLD_FILES_OPTION, 0, 0,
601 N_("don't replace existing files when extracting, silently skip over them"),
602 GRID_OVERWRITE },
603 {"keep-newer-files", KEEP_NEWER_FILES_OPTION, 0, 0,
604 N_("don't replace existing files that are newer than their archive copies"), GRID_OVERWRITE },
605 {"overwrite", OVERWRITE_OPTION, 0, 0,
606 N_("overwrite existing files when extracting"), GRID_OVERWRITE },
607 {"unlink-first", 'U', 0, 0,
608 N_("remove each file prior to extracting over it"), GRID_OVERWRITE },
609 {"recursive-unlink", RECURSIVE_UNLINK_OPTION, 0, 0,
610 N_("empty hierarchies prior to extracting directory"), GRID_OVERWRITE },
611 {"no-overwrite-dir", NO_OVERWRITE_DIR_OPTION, 0, 0,
612 N_("preserve metadata of existing directories"), GRID_OVERWRITE },
613 {"overwrite-dir", OVERWRITE_DIR_OPTION, 0, 0,
614 N_("overwrite metadata of existing directories when extracting (default)"),
615 GRID_OVERWRITE },
616 {"keep-directory-symlink", KEEP_DIRECTORY_SYMLINK_OPTION, 0, 0,
617 N_("preserve existing symlinks to directories when extracting"),
618 GRID_OVERWRITE },
619 {"one-top-level", ONE_TOP_LEVEL_OPTION, N_("DIR"), OPTION_ARG_OPTIONAL,
620 N_("create a subdirectory to avoid having loose files extracted"),
621 GRID_OVERWRITE },
623 {NULL, 0, NULL, 0,
624 N_("Select output stream:"), GRH_OUTPUT },
626 {"to-stdout", 'O', 0, 0,
627 N_("extract files to standard output"), GRID_OUTPUT },
628 {"to-command", TO_COMMAND_OPTION, N_("COMMAND"), 0,
629 N_("pipe extracted files to another program"), GRID_OUTPUT },
630 {"ignore-command-error", IGNORE_COMMAND_ERROR_OPTION, 0, 0,
631 N_("ignore exit codes of children"), GRID_OUTPUT },
632 {"no-ignore-command-error", NO_IGNORE_COMMAND_ERROR_OPTION, 0, 0,
633 N_("treat non-zero exit codes of children as error"), GRID_OUTPUT },
635 {NULL, 0, NULL, 0,
636 N_("Handling of file attributes:"), GRH_FATTR },
638 {"owner", OWNER_OPTION, N_("NAME"), 0,
639 N_("force NAME as owner for added files"), GRID_FATTR },
640 {"group", GROUP_OPTION, N_("NAME"), 0,
641 N_("force NAME as group for added files"), GRID_FATTR },
642 {"owner-map", OWNER_MAP_OPTION, N_("FILE"), 0,
643 N_("use FILE to map file owner UIDs and names"), GRID_FATTR },
644 {"group-map", GROUP_MAP_OPTION, N_("FILE"), 0,
645 N_("use FILE to map file owner GIDs and names"), GRID_FATTR },
646 {"mtime", MTIME_OPTION, N_("DATE-OR-FILE"), 0,
647 N_("set mtime for added files from DATE-OR-FILE"), GRID_FATTR },
648 {"clamp-mtime", CLAMP_MTIME_OPTION, 0, 0,
649 N_("only set time when the file is more recent than what was given with --mtime"), GRID_FATTR },
650 {"set-mtime-command", SET_MTIME_COMMAND_OPTION, N_("COMMAND"), 0,
651 N_("use output of the COMMAND to set mtime of the stored archive members"),
652 GRID_FATTR },
653 {"set-mtime-format", SET_MTIME_FORMAT_OPTION, N_("FORMAT"), 0,
654 N_("set output format (in the sense of strptime(3)) of the --set-mtime-command command"), GRID_FATTR },
655 {"mode", MODE_OPTION, N_("CHANGES"), 0,
656 N_("force (symbolic) mode CHANGES for added files"), GRID_FATTR },
657 {"atime-preserve", ATIME_PRESERVE_OPTION,
658 N_("METHOD"), OPTION_ARG_OPTIONAL,
659 N_("preserve access times on dumped files, either by restoring the times"
660 " after reading (METHOD='replace'; default) or by not setting the times"
661 " in the first place (METHOD='system')"), GRID_FATTR },
662 {"touch", 'm', 0, 0,
663 N_("don't extract file modified time"), GRID_FATTR },
664 {"same-owner", SAME_OWNER_OPTION, 0, 0,
665 N_("try extracting files with the same ownership as exists in the archive (default for superuser)"), GRID_FATTR },
666 {"no-same-owner", NO_SAME_OWNER_OPTION, 0, 0,
667 N_("extract files as yourself (default for ordinary users)"), GRID_FATTR },
668 {"numeric-owner", NUMERIC_OWNER_OPTION, 0, 0,
669 N_("always use numbers for user/group names"), GRID_FATTR },
670 {"preserve-permissions", 'p', 0, 0,
671 N_("extract information about file permissions (default for superuser)"),
672 GRID_FATTR },
673 {"same-permissions", 0, 0, OPTION_ALIAS, NULL, GRID_FATTR },
674 {"no-same-permissions", NO_SAME_PERMISSIONS_OPTION, 0, 0,
675 N_("apply the user's umask when extracting permissions from the archive (default for ordinary users)"), GRID_FATTR },
676 {"preserve-order", 's', 0, 0,
677 N_("member arguments are listed in the same order as the "
678 "files in the archive"), GRID_FATTR },
679 {"same-order", 0, 0, OPTION_ALIAS, NULL, GRID_FATTR },
680 {"delay-directory-restore", DELAY_DIRECTORY_RESTORE_OPTION, 0, 0,
681 N_("delay setting modification times and permissions of extracted"
682 " directories until the end of extraction"), GRID_FATTR },
683 {"no-delay-directory-restore", NO_DELAY_DIRECTORY_RESTORE_OPTION, 0, 0,
684 N_("cancel the effect of --delay-directory-restore option"), GRID_FATTR },
685 {"sort", SORT_OPTION, N_("ORDER"), 0,
686 #if D_INO_IN_DIRENT
687 N_("directory sorting order: none (default), name or inode")
688 #else
689 N_("directory sorting order: none (default) or name")
690 #endif
691 , GRID_FATTR },
693 {NULL, 0, NULL, 0,
694 N_("Handling of extended file attributes:"), GRH_XATTR },
696 {"xattrs", XATTR_OPTION, 0, 0,
697 N_("Enable extended attributes support"), GRID_XATTR },
698 {"no-xattrs", NO_XATTR_OPTION, 0, 0,
699 N_("Disable extended attributes support"), GRID_XATTR },
700 {"xattrs-include", XATTR_INCLUDE, N_("MASK"), 0,
701 N_("specify the include pattern for xattr keys"), GRID_XATTR },
702 {"xattrs-exclude", XATTR_EXCLUDE, N_("MASK"), 0,
703 N_("specify the exclude pattern for xattr keys"), GRID_XATTR },
704 {"selinux", SELINUX_CONTEXT_OPTION, 0, 0,
705 N_("Enable the SELinux context support"), GRID_XATTR },
706 {"no-selinux", NO_SELINUX_CONTEXT_OPTION, 0, 0,
707 N_("Disable the SELinux context support"), GRID_XATTR },
708 {"acls", ACLS_OPTION, 0, 0,
709 N_("Enable the POSIX ACLs support"), GRID_XATTR },
710 {"no-acls", NO_ACLS_OPTION, 0, 0,
711 N_("Disable the POSIX ACLs support"), GRID_XATTR },
713 {NULL, 0, NULL, 0,
714 N_("Device selection and switching:"), GRH_DEVICE },
716 {"file", 'f', N_("ARCHIVE"), 0,
717 N_("use archive file or device ARCHIVE"), GRID_DEVICE },
718 #ifdef DEVICE_PREFIX
719 {"-[0-7][lmh]", 0, NULL, OPTION_DOC, /* It is OK, since 'name' will never be
720 translated */
721 N_("specify drive and density"), GRID_DEVICE },
722 #endif
723 {NULL, '0', NULL, OPTION_HIDDEN, NULL, GRID_DEVICE },
724 {NULL, '1', NULL, OPTION_HIDDEN, NULL, GRID_DEVICE },
725 {NULL, '2', NULL, OPTION_HIDDEN, NULL, GRID_DEVICE },
726 {NULL, '3', NULL, OPTION_HIDDEN, NULL, GRID_DEVICE },
727 {NULL, '4', NULL, OPTION_HIDDEN, NULL, GRID_DEVICE },
728 {NULL, '5', NULL, OPTION_HIDDEN, NULL, GRID_DEVICE },
729 {NULL, '6', NULL, OPTION_HIDDEN, NULL, GRID_DEVICE },
730 {NULL, '7', NULL, OPTION_HIDDEN, NULL, GRID_DEVICE },
731 {NULL, '8', NULL, OPTION_HIDDEN, NULL, GRID_DEVICE },
732 {NULL, '9', NULL, OPTION_HIDDEN, NULL, GRID_DEVICE },
734 {"force-local", FORCE_LOCAL_OPTION, 0, 0,
735 N_("archive file is local even if it has a colon"),
736 GRID_DEVICE },
737 {"rmt-command", RMT_COMMAND_OPTION, N_("COMMAND"), 0,
738 N_("use given rmt COMMAND instead of rmt"),
739 GRID_DEVICE },
740 {"rsh-command", RSH_COMMAND_OPTION, N_("COMMAND"), 0,
741 N_("use remote COMMAND instead of rsh"),
742 GRID_DEVICE },
744 {"multi-volume", 'M', 0, 0,
745 N_("create/list/extract multi-volume archive"),
746 GRID_DEVICE },
747 {"tape-length", 'L', N_("NUMBER"), 0,
748 N_("change tape after writing NUMBER x 1024 bytes"),
749 GRID_DEVICE },
750 {"info-script", 'F', N_("NAME"), 0,
751 N_("run script at end of each tape (implies -M)"),
752 GRID_DEVICE },
753 {"new-volume-script", 0, 0, OPTION_ALIAS, NULL, GRID_DEVICE },
754 {"volno-file", VOLNO_FILE_OPTION, N_("FILE"), 0,
755 N_("use/update the volume number in FILE"),
756 GRID_DEVICE },
758 {NULL, 0, NULL, 0,
759 N_("Device blocking:"), GRH_BLOCKING },
761 {"blocking-factor", 'b', N_("BLOCKS"), 0,
762 N_("BLOCKS x 512 bytes per record"), GRID_BLOCKING },
763 {"record-size", RECORD_SIZE_OPTION, N_("NUMBER"), 0,
764 N_("NUMBER of bytes per record, multiple of 512"), GRID_BLOCKING },
765 {"ignore-zeros", 'i', 0, 0,
766 N_("ignore zeroed blocks in archive (means EOF)"), GRID_BLOCKING },
767 {"read-full-records", 'B', 0, 0,
768 N_("reblock as we read (for 4.2BSD pipes)"), GRID_BLOCKING },
770 {NULL, 0, NULL, 0,
771 N_("Archive format selection:"), GRH_FORMAT },
773 {"format", 'H', N_("FORMAT"), 0,
774 N_("create archive of the given format"), GRID_FORMAT },
776 {NULL, 0, NULL, 0, N_("FORMAT is one of the following:"), GRDOC_FORMAT },
777 {" v7", 0, NULL, OPTION_DOC|OPTION_NO_TRANS, N_("old V7 tar format"),
778 GRDOC_FORMAT },
779 {" oldgnu", 0, NULL, OPTION_DOC|OPTION_NO_TRANS,
780 N_("GNU format as per tar <= 1.12"), GRDOC_FORMAT },
781 {" gnu", 0, NULL, OPTION_DOC|OPTION_NO_TRANS,
782 N_("GNU tar 1.13.x format"), GRDOC_FORMAT },
783 {" ustar", 0, NULL, OPTION_DOC|OPTION_NO_TRANS,
784 N_("POSIX 1003.1-1988 (ustar) format"), GRDOC_FORMAT },
785 {" pax", 0, NULL, OPTION_DOC|OPTION_NO_TRANS,
786 N_("POSIX 1003.1-2001 (pax) format"), GRDOC_FORMAT },
787 {" posix", 0, NULL, OPTION_DOC|OPTION_NO_TRANS, N_("same as pax"),
788 GRDOC_FORMAT },
790 {"old-archive", OLD_ARCHIVE_OPTION, 0, 0, /* FIXME */
791 N_("same as --format=v7"), GRID_FORMAT_OPT },
792 {"portability", 0, 0, OPTION_ALIAS, NULL, GRID_FORMAT_OPT },
793 {"posix", POSIX_OPTION, 0, 0,
794 N_("same as --format=posix"), GRID_FORMAT_OPT },
795 {"pax-option", PAX_OPTION, N_("keyword[[:]=value][,keyword[[:]=value]]..."), 0,
796 N_("control pax keywords"), GRID_FORMAT_OPT },
797 {"label", 'V', N_("TEXT"), 0,
798 N_("create archive with volume name TEXT; at list/extract time, use TEXT as a globbing pattern for volume name"),
799 GRID_FORMAT_OPT },
801 {NULL, 0, NULL, 0,
802 N_("Compression options:"), GRH_COMPRESS },
803 {"auto-compress", 'a', 0, 0,
804 N_("use archive suffix to determine the compression program"),
805 GRID_COMPRESS },
806 {"no-auto-compress", NO_AUTO_COMPRESS_OPTION, 0, 0,
807 N_("do not use archive suffix to determine the compression program"),
808 GRID_COMPRESS },
809 {"use-compress-program", 'I', N_("PROG"), 0,
810 N_("filter through PROG (must accept -d)"), GRID_COMPRESS },
811 /* Note: docstrings for the options below are generated by tar_help_filter */
812 {"bzip2", 'j', 0, 0, NULL, GRID_COMPRESS },
813 {"gzip", 'z', 0, 0, NULL, GRID_COMPRESS },
814 {"gunzip", 0, 0, OPTION_ALIAS, NULL, GRID_COMPRESS },
815 {"ungzip", 0, 0, OPTION_ALIAS, NULL, GRID_COMPRESS },
816 {"compress", 'Z', 0, 0, NULL, GRID_COMPRESS },
817 {"uncompress", 0, 0, OPTION_ALIAS, NULL, GRID_COMPRESS },
818 {"lzip", LZIP_OPTION, 0, 0, NULL, GRID_COMPRESS },
819 {"lzma", LZMA_OPTION, 0, 0, NULL, GRID_COMPRESS },
820 {"lzop", LZOP_OPTION, 0, 0, NULL, GRID_COMPRESS },
821 {"xz", 'J', 0, 0, NULL, GRID_COMPRESS },
822 {"zstd", ZSTD_OPTION, 0, 0, NULL, GRID_COMPRESS },
824 {NULL, 0, NULL, 0,
825 N_("Local file selection:"), GRH_FILE },
826 {"one-file-system", ONE_FILE_SYSTEM_OPTION, 0, 0,
827 N_("stay in local file system when creating archive"), GRID_FILE },
828 {"absolute-names", 'P', 0, 0,
829 N_("don't strip leading '/'s from file names"), GRID_FILE },
830 {"dereference", 'h', 0, 0,
831 N_("follow symlinks; archive and dump the files they point to"),
832 GRID_FILE },
833 {"hard-dereference", HARD_DEREFERENCE_OPTION, 0, 0,
834 N_("follow hard links; archive and dump the files they refer to"),
835 GRID_FILE },
836 {"starting-file", 'K', N_("MEMBER-NAME"), 0,
837 N_("begin at member MEMBER-NAME when reading the archive"),
838 GRID_FILE },
839 {"newer", 'N', N_("DATE-OR-FILE"), 0,
840 N_("only store files newer than DATE-OR-FILE"), GRID_FILE },
841 {"after-date", 0, 0, OPTION_ALIAS, NULL, GRID_FILE },
842 {"newer-mtime", NEWER_MTIME_OPTION, N_("DATE"), 0,
843 N_("compare date and time when data changed only"), GRID_FILE },
844 {"backup", BACKUP_OPTION, N_("CONTROL"), OPTION_ARG_OPTIONAL,
845 N_("backup before removal, choose version CONTROL"), GRID_FILE },
846 {"suffix", SUFFIX_OPTION, N_("STRING"), 0,
847 N_("backup before removal, override usual suffix ('~' unless overridden by environment variable SIMPLE_BACKUP_SUFFIX)"),
848 GRID_FILE },
850 {NULL, 0, NULL, 0,
851 N_("File name transformations:"), GRH_NAME_XFORM },
852 {"strip-components", STRIP_COMPONENTS_OPTION, N_("NUMBER"), 0,
853 N_("strip NUMBER leading components from file names on extraction"),
854 GRID_NAME_XFORM },
855 {"transform", TRANSFORM_OPTION, N_("EXPRESSION"), 0,
856 N_("use sed replace EXPRESSION to transform file names"),
857 GRID_NAME_XFORM },
858 {"xform", 0, 0, OPTION_ALIAS, NULL, GRID_NAME_XFORM },
860 {NULL, 0, NULL, 0,
861 N_("Informative output:"), GRH_INFORMATIVE },
863 {"checkpoint", CHECKPOINT_OPTION, N_("NUMBER"), OPTION_ARG_OPTIONAL,
864 N_("display progress messages every NUMBERth record (default 10)"),
865 GRID_INFORMATIVE },
866 {"checkpoint-action", CHECKPOINT_ACTION_OPTION, N_("ACTION"), 0,
867 N_("execute ACTION on each checkpoint"),
868 GRID_INFORMATIVE },
869 {"check-links", 'l', 0, 0,
870 N_("print a message if not all links are dumped"), GRID_INFORMATIVE },
871 {"totals", TOTALS_OPTION, N_("SIGNAL"), OPTION_ARG_OPTIONAL,
872 N_("print total bytes after processing the archive; "
873 "with an argument - print total bytes when this SIGNAL is delivered; "
874 "Allowed signals are: SIGHUP, SIGQUIT, SIGINT, SIGUSR1 and SIGUSR2; "
875 "the names without SIG prefix are also accepted"), GRID_INFORMATIVE },
876 {"utc", UTC_OPTION, 0, 0,
877 N_("print file modification times in UTC"), GRID_INFORMATIVE },
878 {"full-time", FULL_TIME_OPTION, 0, 0,
879 N_("print file time to its full resolution"), GRID_INFORMATIVE },
880 {"index-file", INDEX_FILE_OPTION, N_("FILE"), 0,
881 N_("send verbose output to FILE"), GRID_INFORMATIVE },
882 {"block-number", 'R', 0, 0,
883 N_("show block number within archive with each message"), GRID_INFORMATIVE },
884 {"show-defaults", SHOW_DEFAULTS_OPTION, 0, 0,
885 N_("show tar defaults"), GRID_INFORMATIVE },
886 {"show-snapshot-field-ranges", SHOW_SNAPSHOT_FIELD_RANGES_OPTION, 0, 0,
887 N_("show valid ranges for snapshot-file fields"), GRID_INFORMATIVE },
888 {"show-omitted-dirs", SHOW_OMITTED_DIRS_OPTION, 0, 0,
889 N_("when listing or extracting, list each directory that does not match search criteria"), GRID_INFORMATIVE },
890 {"show-transformed-names", SHOW_TRANSFORMED_NAMES_OPTION, 0, 0,
891 N_("show file or archive names after transformation"),
892 GRID_INFORMATIVE },
893 {"show-stored-names", 0, 0, OPTION_ALIAS, NULL, GRID_INFORMATIVE },
894 {"quoting-style", QUOTING_STYLE_OPTION, N_("STYLE"), 0,
895 N_("set name quoting style; see below for valid STYLE values"), GRID_INFORMATIVE },
896 {"quote-chars", QUOTE_CHARS_OPTION, N_("STRING"), 0,
897 N_("additionally quote characters from STRING"), GRID_INFORMATIVE },
898 {"no-quote-chars", NO_QUOTE_CHARS_OPTION, N_("STRING"), 0,
899 N_("disable quoting for characters from STRING"), GRID_INFORMATIVE },
900 {"interactive", 'w', 0, 0,
901 N_("ask for confirmation for every action"), GRID_INFORMATIVE },
902 {"confirmation", 0, 0, OPTION_ALIAS, NULL, GRID_INFORMATIVE },
903 {"verbose", 'v', 0, 0,
904 N_("verbosely list files processed"), GRID_INFORMATIVE },
905 {"warning", WARNING_OPTION, N_("KEYWORD"), 0,
906 N_("warning control"), GRID_INFORMATIVE },
908 {NULL, 0, NULL, 0,
909 N_("Compatibility options:"), GRH_COMPAT },
911 {NULL, 'o', 0, 0,
912 N_("when creating, same as --old-archive; when extracting, same as --no-same-owner"), GRID_COMPAT },
914 {NULL, 0, NULL, 0,
915 N_("Other options:"), GRH_OTHER },
917 {"restrict", RESTRICT_OPTION, 0, 0,
918 N_("disable use of some potentially harmful options"), -1 },
920 {0, 0, 0, 0, 0, 0}
923 static char const *const atime_preserve_args[] =
925 "replace", "system", NULL
928 static enum atime_preserve const atime_preserve_types[] =
930 replace_atime_preserve, system_atime_preserve
933 /* Make sure atime_preserve_types has as much entries as atime_preserve_args
934 (minus 1 for NULL guard) */
935 ARGMATCH_VERIFY (atime_preserve_args, atime_preserve_types);
938 static char * ATTRIBUTE_FORMAT ((printf, 1, 2))
939 easprintf (char const *format, ...)
941 va_list args;
943 va_start (args, format);
944 char *result = xvasprintf (format, args);
945 int err = errno;
946 va_end (args);
948 if (!result)
949 paxfatal (err, "vasprintf");
950 return result;
953 static char *
954 format_default_settings (void)
956 return easprintf (
957 "--format=%s -f%s -b%d --quoting-style=%s --rmt-command=%s"
958 #ifdef REMOTE_SHELL
959 " --rsh-command=%s"
960 #endif
962 archive_format_string (DEFAULT_ARCHIVE_FORMAT),
963 DEFAULT_ARCHIVE, DEFAULT_BLOCKING,
964 quoting_style_args[DEFAULT_QUOTING_STYLE],
965 DEFAULT_RMT_COMMAND
966 #ifdef REMOTE_SHELL
967 , REMOTE_SHELL
968 #endif
972 static void
973 option_conflict_error (const char *a, const char *b)
975 /* TRANSLATORS: Both %s in this statement are replaced with
976 option names. */
977 paxusage (_("'%s' cannot be used with '%s'"), a, b);
980 /* Classes of options that can conflict: */
981 enum option_class
983 OC_COMPRESS, /* Compress options: -JjZz, -I, etc. */
984 OC_OCCURRENCE, /* --occurrence */
985 OC_LISTED_INCREMENTAL, /* --listed-incremental */
986 OC_NEWER, /* --newer, --newer-mtime, --after-date */
987 OC_VERIFY, /* --verify */
988 OC_STARTING_FILE, /* --starting-file */
989 OC_SAME_ORDER, /* --same-order */
990 OC_ONE_TOP_LEVEL, /* --one-top-level */
991 OC_ABSOLUTE_NAMES, /* --absolute-names */
992 OC_OLD_FILES, /* --keep-old-files, --overwrite, etc. */
993 OC_MAX
996 /* Table of locations of potentially conflicting options. Two options can
997 conflict only if they proceed from the command line. Otherwise, options
998 in command line silently override those defined in TAR_OPTIONS. */
999 static struct option_locus *option_class[OC_MAX];
1001 /* Save location of an option of class ID. Return location of a previous
1002 occurrence of an option of that class, or NULL. */
1003 static struct option_locus *
1004 optloc_save (enum option_class id, struct option_locus *loc)
1006 char const *name = loc->name;
1007 idx_t namesize = name ? strlen (name) + 1 : 0;
1008 struct option_locus *optloc = ximalloc (sizeof *loc + namesize);
1009 optloc->name = name ? memcpy (optloc + 1, name, namesize) : NULL;
1010 optloc->source = loc->source;
1011 optloc->line = loc->line;
1012 optloc->prev = option_class[id];
1013 option_class[id] = optloc;
1014 return optloc->prev;
1017 /* Return location of a recent option of class ID */
1018 static struct option_locus *
1019 optloc_lookup (enum option_class id)
1021 return option_class[id];
1024 /* Return true if the latest occurrence of option ID was in the command line */
1025 static bool
1026 option_set_in_cl (enum option_class id)
1028 struct option_locus *loc = optloc_lookup (id);
1029 return loc && loc->source == OPTS_COMMAND_LINE;
1032 /* Compare two option locations */
1033 static bool
1034 optloc_eq (struct option_locus *a, struct option_locus *b)
1036 assume (a); /* Pacify GCC bug 106436. */
1037 if (a->source != b->source)
1038 return false;
1039 if (a->source == OPTS_COMMAND_LINE)
1040 return true;
1041 assume (a->name);
1042 return strcmp (a->name, b->name) == 0;
1045 static void
1046 set_subcommand_option (enum subcommand subcommand)
1048 if (subcommand_option != UNKNOWN_SUBCOMMAND
1049 && subcommand_option != subcommand)
1050 paxusage (_("You may not specify more than one '-Acdtrux',"
1051 " '--delete' or '--test-label' option"));
1053 subcommand_option = subcommand;
1056 static void
1057 set_use_compress_program_option (const char *string, struct option_locus *loc)
1059 struct option_locus *p = optloc_save (OC_COMPRESS, loc);
1060 if (use_compress_program_option
1061 && strcmp (use_compress_program_option, string) != 0
1062 && p->source == OPTS_COMMAND_LINE)
1063 paxusage (_("Conflicting compression options"));
1065 use_compress_program_option = string;
1068 static void
1069 sigstat (int signo)
1071 compute_duration_ns ();
1072 print_total_stats ();
1073 #ifndef HAVE_SIGACTION
1074 signal (signo, sigstat);
1075 #endif
1078 static void
1079 stat_on_signal (int signo)
1081 #ifdef HAVE_SIGACTION
1082 # ifndef SA_RESTART
1083 # define SA_RESTART 0
1084 # endif
1085 struct sigaction act;
1086 act.sa_handler = sigstat;
1087 sigemptyset (&act.sa_mask);
1088 act.sa_flags = SA_RESTART;
1089 sigaction (signo, &act, NULL);
1090 #else
1091 signal (signo, sigstat);
1092 #endif
1096 decode_signal (const char *name)
1098 static struct sigtab
1100 char name[sizeof "USR1"];
1101 int signo;
1102 } const sigtab[] = {
1103 { "USR1", SIGUSR1 },
1104 { "USR2", SIGUSR2 },
1105 { "HUP", SIGHUP },
1106 { "INT", SIGINT },
1107 { "QUIT", SIGQUIT }
1109 enum { nsigtab = sizeof sigtab / sizeof *sigtab };
1110 char const *s = name;
1112 if (strncmp (s, "SIG", 3) == 0)
1113 s += 3;
1114 for (struct sigtab const *p = sigtab; p < sigtab + nsigtab; p++)
1115 if (strcmp (p->name, s) == 0)
1116 return p->signo;
1117 paxfatal (0, _("Unknown signal name: %s"), name);
1120 static void
1121 set_stat_signal (const char *name)
1123 stat_on_signal (decode_signal (name));
1127 struct textual_date
1129 struct textual_date *next;
1130 struct timespec ts;
1131 const char *option;
1132 char *date;
1135 static bool
1136 get_date_or_file (struct tar_args *args, const char *option,
1137 const char *str, struct timespec *ts)
1139 if (FILE_SYSTEM_PREFIX_LEN (str) != 0
1140 || ISSLASH (*str)
1141 || *str == '.')
1143 struct stat st;
1144 if (stat (str, &st) < 0)
1146 stat_error (str);
1147 paxusage (_("Date sample file not found"));
1149 *ts = get_stat_mtime (&st);
1151 else
1153 if (! parse_datetime (ts, str, NULL))
1155 paxwarn (0, _("Substituting %s for unknown date format %s"),
1156 tartime (*ts, false), quote (str));
1157 ts->tv_nsec = 0;
1158 return false;
1160 else
1162 struct textual_date *p = xmalloc (sizeof (*p));
1163 p->ts = *ts;
1164 p->option = option;
1165 p->date = xstrdup (str);
1166 p->next = args->textual_date;
1167 args->textual_date = p;
1170 return true;
1173 static void
1174 report_textual_dates (struct tar_args *args)
1176 struct textual_date *p;
1177 for (p = args->textual_date; p; )
1179 struct textual_date *next = p->next;
1180 if (verbose_option)
1182 char const *treated_as = tartime (p->ts, true);
1183 if (strcmp (p->date, treated_as) != 0)
1184 paxwarn (0, _("Option %s: Treating date '%s' as %s"),
1185 p->option, p->date, treated_as);
1187 free (p->date);
1188 free (p);
1189 p = next;
1194 /* Default density numbers for [0-9][lmh] device specifications */
1196 #if defined DEVICE_PREFIX && !defined DENSITY_LETTER
1197 # ifndef LOW_DENSITY_NUM
1198 # define LOW_DENSITY_NUM 0
1199 # endif
1201 # ifndef MID_DENSITY_NUM
1202 # define MID_DENSITY_NUM 8
1203 # endif
1205 # ifndef HIGH_DENSITY_NUM
1206 # define HIGH_DENSITY_NUM 16
1207 # endif
1208 #endif
1211 static char *
1212 tar_help_filter (int key, const char *text, MAYBE_UNUSED void *input)
1214 struct obstack stk;
1215 char *s;
1217 switch (key)
1219 default:
1220 s = (char *) text;
1221 break;
1223 case 'j':
1224 s = easprintf (_("filter the archive through %s"), BZIP2_PROGRAM);
1225 break;
1227 case 'z':
1228 s = easprintf (_("filter the archive through %s"), GZIP_PROGRAM);
1229 break;
1231 case 'Z':
1232 s = easprintf (_("filter the archive through %s"), COMPRESS_PROGRAM);
1233 break;
1235 case LZIP_OPTION:
1236 s = easprintf (_("filter the archive through %s"), LZIP_PROGRAM);
1237 break;
1239 case LZMA_OPTION:
1240 s = easprintf (_("filter the archive through %s"), LZMA_PROGRAM);
1241 break;
1243 case LZOP_OPTION:
1244 s = easprintf (_("filter the archive through %s"), LZOP_PROGRAM);
1245 break;
1247 case 'J':
1248 s = easprintf (_("filter the archive through %s"), XZ_PROGRAM);
1249 break;
1251 case ZSTD_OPTION:
1252 s = easprintf (_("filter the archive through %s"), ZSTD_PROGRAM);
1253 break;
1255 case ARGP_KEY_HELP_EXTRA:
1257 const char *tstr;
1259 obstack_init (&stk);
1260 tstr = _("Valid arguments for the --quoting-style option are:");
1261 obstack_grow (&stk, tstr, strlen (tstr));
1262 obstack_grow (&stk, "\n\n", 2);
1263 tar_list_quoting_styles (&stk, " ");
1264 tstr = _("\n*This* tar defaults to:\n");
1265 obstack_grow (&stk, tstr, strlen (tstr));
1266 s = format_default_settings ();
1267 obstack_grow (&stk, s, strlen (s));
1268 obstack_1grow (&stk, '\n');
1269 obstack_1grow (&stk, 0);
1270 s = xstrdup (obstack_finish (&stk));
1271 obstack_free (&stk, NULL);
1274 return s;
1277 static char * _GL_ATTRIBUTE_MALLOC
1278 expand_pax_option (struct tar_args *targs, const char *arg)
1280 struct obstack stk;
1281 char *res;
1283 obstack_init (&stk);
1284 while (*arg)
1286 idx_t seglen = strcspn (arg, ",");
1287 char *p = memchr (arg, '=', seglen);
1288 if (p)
1290 idx_t len = p - arg + 1;
1291 obstack_grow (&stk, arg, len);
1292 len = seglen - len;
1293 for (++p; *p && c_isspace (*p); p++)
1294 len--;
1295 if (*p == '{' && p[len-1] == '}')
1297 struct timespec ts;
1298 char *tmp = xmalloc (len);
1299 memcpy (tmp, p + 1, len-2);
1300 tmp[len-2] = 0;
1301 if (get_date_or_file (targs, "--pax-option", tmp, &ts))
1303 char buf[TIMESPEC_STRSIZE_BOUND];
1304 char const *s = code_timespec (ts, buf);
1305 obstack_grow (&stk, s, strlen (s));
1307 else
1308 obstack_grow (&stk, p, len);
1309 free (tmp);
1311 else
1312 obstack_grow (&stk, p, len);
1314 else
1315 obstack_grow (&stk, arg, seglen);
1317 arg += seglen;
1318 if (*arg)
1320 obstack_1grow (&stk, *arg);
1321 arg++;
1324 obstack_1grow (&stk, 0);
1325 res = xstrdup (obstack_finish (&stk));
1326 obstack_free (&stk, NULL);
1327 return res;
1331 static uintmax_t
1332 parse_owner_group (char *arg, uintmax_t field_max, char const **name_option)
1334 char const *name = NULL;
1335 char const *num = arg;
1336 char *colon = strchr (arg, ':');
1337 if (colon)
1339 num = colon + 1;
1340 *colon = '\0';
1341 if (arg != colon)
1342 name = arg;
1345 bool overflow;
1346 char *end;
1347 uintmax_t u = stoint (num, &end, &overflow, 0, field_max);
1348 if ((end == num) | *end | overflow)
1349 paxfatal (0, "%s: %s", quotearg_colon (num),
1350 _("Invalid owner or group ID"));
1351 if (name_option)
1352 *name_option = name;
1353 return u;
1356 static char const TAR_SIZE_SUFFIXES[] = "bBcGgkKMmPTtw";
1358 static char const *const sort_mode_arg[] = {
1359 "none",
1360 "name",
1361 #if D_INO_IN_DIRENT
1362 "inode",
1363 #endif
1364 NULL
1367 static enum savedir_option const sort_mode_flag[] = {
1368 SAVEDIR_SORT_NONE,
1369 SAVEDIR_SORT_NAME,
1370 #if D_INO_IN_DIRENT
1371 SAVEDIR_SORT_INODE
1372 #endif
1375 ARGMATCH_VERIFY (sort_mode_arg, sort_mode_flag);
1377 static char const *const hole_detection_args[] =
1379 "raw", "seek", NULL
1382 static enum hole_detection_method const hole_detection_types[] =
1384 HOLE_DETECTION_RAW, HOLE_DETECTION_SEEK
1387 ARGMATCH_VERIFY (hole_detection_args, hole_detection_types);
1390 static void
1391 set_old_files_option (enum old_files code, struct option_locus *loc)
1393 struct option_locus *prev;
1394 /* Option compatibility map. 0 means two options are incompatible. */
1395 static bool compat_map[MAX_OLD_FILES][MAX_OLD_FILES] = {
1396 [NO_OVERWRITE_DIR_OLD_FILES] = {
1397 [KEEP_OLD_FILES] = 1,
1398 [SKIP_OLD_FILES] = 1
1400 [KEEP_OLD_FILES] = {
1401 [NO_OVERWRITE_DIR_OLD_FILES] = 1
1403 [SKIP_OLD_FILES] = {
1404 [NO_OVERWRITE_DIR_OLD_FILES] = 1
1407 static char const *const code_to_opt[] = {
1408 "--overwrite-dir",
1409 "--no-overwrite-dir",
1410 "--overwrite",
1411 "--unlink-first",
1412 "--keep-old-files",
1413 "--skip-old-files",
1414 "--keep-newer-files"
1417 prev = optloc_save (OC_OLD_FILES, loc);
1418 if (prev && optloc_eq (loc, prev) && code != old_files_option &&
1419 compat_map[code][old_files_option] == 0)
1420 option_conflict_error (code_to_opt[code], code_to_opt[old_files_option]);
1422 old_files_option = code;
1425 static error_t
1426 parse_opt (int key, char *arg, struct argp_state *state)
1428 struct tar_args *args = state->input;
1430 switch (key)
1432 case ARGP_KEY_INIT:
1433 if (state->root_argp->children)
1434 for (idx_t i = 0; state->root_argp->children[i].argp; i++)
1435 state->child_inputs[i] = state->input;
1436 break;
1438 case ARGP_KEY_ARG:
1439 /* File name or non-parsed option, because of ARGP_IN_ORDER */
1440 name_add_name (arg);
1441 break;
1443 case 'A':
1444 set_subcommand_option (CAT_SUBCOMMAND);
1445 break;
1447 case 'a':
1448 args->compress_autodetect = true;
1449 break;
1451 case NO_AUTO_COMPRESS_OPTION:
1452 args->compress_autodetect = false;
1453 break;
1455 case 'b':
1457 bool overflow;
1458 char *end;
1459 blocking_factor = stoint (arg, &end, &overflow, 0,
1460 (min (IDX_MAX, min (SSIZE_MAX, SIZE_MAX))
1461 / BLOCKSIZE));
1462 if ((end == arg) | *end | overflow | !blocking_factor)
1463 paxusage ("%s: %s", quotearg_colon (arg),
1464 _("Invalid blocking factor"));
1465 record_size = blocking_factor * BLOCKSIZE;
1467 break;
1469 case 'B':
1470 /* Try to reblock input records. For reading 4.2BSD pipes. */
1472 /* It would surely make sense to exchange -B and -R, but it seems
1473 that -B has been used for a long while in Sun tar and most
1474 BSD-derived systems. This is a consequence of the block/record
1475 terminology confusion. */
1477 read_full_records_option = true;
1478 break;
1480 case 'c':
1481 set_subcommand_option (CREATE_SUBCOMMAND);
1482 break;
1484 case CLAMP_MTIME_OPTION:
1485 set_mtime_option = CLAMP_MTIME;
1486 break;
1488 case 'd':
1489 set_subcommand_option (DIFF_SUBCOMMAND);
1490 break;
1492 case 'F':
1493 /* Since -F is only useful with -M, make it implied. Run this
1494 script at the end of each tape. */
1496 info_script_option = arg;
1497 multi_volume_option = true;
1498 break;
1500 case 'f':
1501 if (archive_names == allocated_archive_names)
1502 archive_name_array = xpalloc (archive_name_array,
1503 &allocated_archive_names,
1504 1, -1, sizeof *archive_name_array);
1505 archive_name_array[archive_names++] = arg;
1506 break;
1508 case '0':
1509 case '1':
1510 case '2':
1511 case '3':
1512 case '4':
1513 case '5':
1514 case '6':
1515 case '7':
1517 #ifdef DEVICE_PREFIX
1519 int device = key - '0';
1520 static char buf[sizeof DEVICE_PREFIX + INT_STRLEN_BOUND (int)]
1521 = DEVICE_PREFIX;
1523 if (arg[1])
1524 argp_error (state, _("Malformed density argument: %s"), quote (arg));
1526 char *cursor = buf + sizeof DEVICE_PREFIX - 1;
1528 #ifdef DENSITY_LETTER
1530 sprintf (cursor, "%d%c", device, arg[0]);
1532 #else /* not DENSITY_LETTER */
1534 switch (arg[0])
1536 case 'l':
1537 device += LOW_DENSITY_NUM;
1538 break;
1540 case 'm':
1541 device += MID_DENSITY_NUM;
1542 break;
1544 case 'h':
1545 device += HIGH_DENSITY_NUM;
1546 break;
1548 default:
1549 argp_error (state, _("Unknown density: '%c'"), arg[0]);
1551 sprintf (cursor, "%d", device);
1553 #endif /* not DENSITY_LETTER */
1555 if (archive_names == allocated_archive_names)
1556 archive_name_array = xpalloc (archive_name_array,
1557 &allocated_archive_names,
1558 1, -1, sizeof *archive_name_array);
1559 archive_name_array[archive_names++] = xstrdup (buf);
1561 break;
1563 #else /* not DEVICE_PREFIX */
1565 argp_error (state,
1566 _("Options '-[0-7][lmh]' not supported by *this* tar"));
1567 exit (EX_USAGE);
1569 #endif /* not DEVICE_PREFIX */
1570 break;
1572 case FULL_TIME_OPTION:
1573 full_time_option = true;
1574 break;
1576 case 'g':
1577 optloc_save (OC_LISTED_INCREMENTAL, args->loc);
1578 listed_incremental_option = arg;
1579 after_date_option = true;
1580 FALLTHROUGH;
1581 case 'G':
1582 /* We are making an incremental dump (FIXME: are we?); save
1583 directories at the beginning of the archive, and include in each
1584 directory its contents. */
1586 incremental_option = true;
1587 break;
1589 case 'h':
1590 /* Follow symbolic links. */
1591 dereference_option = true;
1592 break;
1594 case HARD_DEREFERENCE_OPTION:
1595 hard_dereference_option = true;
1596 break;
1598 case 'i':
1599 /* Ignore zero blocks (eofs). This can't be the default,
1600 because Unix tar writes two blocks of zeros, then pads out
1601 the record with garbage. */
1603 ignore_zeros_option = true;
1604 break;
1606 case 'j':
1607 set_use_compress_program_option (BZIP2_PROGRAM, args->loc);
1608 break;
1610 case 'J':
1611 set_use_compress_program_option (XZ_PROGRAM, args->loc);
1612 break;
1614 case 'k':
1615 /* Don't replace existing files. */
1616 set_old_files_option (KEEP_OLD_FILES, args->loc);
1617 break;
1619 case 'K':
1620 optloc_save (OC_STARTING_FILE, args->loc);
1621 add_starting_file (arg);
1622 break;
1624 case ONE_FILE_SYSTEM_OPTION:
1625 /* When dumping directories, don't dump files/subdirectories
1626 that are on other filesystems. */
1627 one_file_system_option = true;
1628 break;
1630 case ONE_TOP_LEVEL_OPTION:
1631 optloc_save (OC_ONE_TOP_LEVEL, args->loc);
1632 one_top_level_option = true;
1633 one_top_level_dir = arg;
1634 break;
1636 case 'l':
1637 check_links_option = true;
1638 break;
1640 case 'L':
1642 uintmax_t u;
1643 char *p;
1645 switch (xstrtoumax (arg, &p, 10, &u, TAR_SIZE_SUFFIXES))
1647 case LONGINT_OK:
1648 tape_length_option = u;
1649 if (arg < p && !strchr (TAR_SIZE_SUFFIXES, p[-1]))
1650 tape_length_option *= 1024;
1651 break;
1653 case LONGINT_OVERFLOW:
1654 /* Treat enormous values as effectively infinity. */
1655 tape_length_option = 0;
1656 break;
1658 default:
1659 paxusage ("%s: %s", quotearg_colon (arg),
1660 _("Invalid tape length"));
1663 multi_volume_option = true;
1665 break;
1667 case LEVEL_OPTION:
1669 char *end;
1670 incremental_level = stoint (arg, &end, NULL, 0, 1);
1671 if ((end == arg) | *end)
1672 paxusage (_("Invalid incremental level value"));
1674 break;
1676 case LZIP_OPTION:
1677 set_use_compress_program_option (LZIP_PROGRAM, args->loc);
1678 break;
1680 case LZMA_OPTION:
1681 set_use_compress_program_option (LZMA_PROGRAM, args->loc);
1682 break;
1684 case LZOP_OPTION:
1685 set_use_compress_program_option (LZOP_PROGRAM, args->loc);
1686 break;
1688 case 'm':
1689 touch_option = true;
1690 break;
1692 case 'M':
1693 /* Make multivolume archive: when we can't write any more into
1694 the archive, re-open it, and continue writing. */
1696 multi_volume_option = true;
1697 break;
1699 case MTIME_OPTION:
1700 get_date_or_file (args, "--mtime", arg, &mtime_option);
1701 if (set_mtime_option == USE_FILE_MTIME)
1702 set_mtime_option = FORCE_MTIME;
1703 break;
1705 case 'n':
1706 seek_option = 1;
1707 break;
1709 case NO_SEEK_OPTION:
1710 seek_option = 0;
1711 break;
1713 case 'N':
1714 after_date_option = true;
1715 FALLTHROUGH;
1716 case NEWER_MTIME_OPTION:
1717 if (time_option_initialized (newer_mtime_option))
1718 paxusage (_("More than one threshold date"));
1719 get_date_or_file (args,
1720 key == NEWER_MTIME_OPTION ? "--newer-mtime"
1721 : "--after-date", arg, &newer_mtime_option);
1722 optloc_save (OC_NEWER, args->loc);
1723 break;
1725 case 'o':
1726 args->o_option = true;
1727 break;
1729 case 'O':
1730 to_stdout_option = true;
1731 break;
1733 case 'p':
1734 same_permissions_option = true;
1735 break;
1737 case 'P':
1738 optloc_save (OC_ABSOLUTE_NAMES, args->loc);
1739 absolute_names_option = true;
1740 break;
1742 case 'r':
1743 set_subcommand_option (APPEND_SUBCOMMAND);
1744 break;
1746 case 'R':
1747 /* Print block numbers for debugging bad tar archives. */
1749 /* It would surely make sense to exchange -B and -R, but it seems
1750 that -B has been used for a long while in Sun tar and most
1751 BSD-derived systems. This is a consequence of the block/record
1752 terminology confusion. */
1754 block_number_option = true;
1755 break;
1757 case 's':
1758 /* Names to extract are sorted. */
1759 optloc_save (OC_SAME_ORDER, args->loc);
1760 same_order_option = true;
1761 break;
1763 case 'S':
1764 sparse_option = true;
1765 break;
1767 case SKIP_OLD_FILES_OPTION:
1768 set_old_files_option (SKIP_OLD_FILES, args->loc);
1769 break;
1771 case HOLE_DETECTION_OPTION:
1772 hole_detection = XARGMATCH ("--hole-detection", arg,
1773 hole_detection_args, hole_detection_types);
1774 sparse_option = true;
1775 break;
1777 case SET_MTIME_COMMAND_OPTION:
1778 set_mtime_command = arg;
1779 break;
1781 case SET_MTIME_FORMAT_OPTION:
1782 set_mtime_format = arg;
1783 break;
1785 case SPARSE_VERSION_OPTION:
1786 sparse_option = true;
1788 char *p;
1789 bool vmajor, vminor;
1790 tar_sparse_major = stoint (arg, &p, &vmajor, 0, INTMAX_MAX);
1791 if ((p != arg) & (*p == '.'))
1792 tar_sparse_minor = stoint (p + 1, &p, &vminor, 0, INTMAX_MAX);
1793 if ((p == arg) | *p | vmajor | vminor)
1794 paxusage (_("Invalid sparse version value"));
1796 break;
1798 case 't':
1799 set_subcommand_option (LIST_SUBCOMMAND);
1800 verbose_option += verbose_option <= 2;
1801 break;
1803 case TEST_LABEL_OPTION:
1804 set_subcommand_option (TEST_LABEL_SUBCOMMAND);
1805 break;
1807 case TRANSFORM_OPTION:
1808 set_transform_expr (arg);
1809 break;
1811 case 'u':
1812 set_subcommand_option (UPDATE_SUBCOMMAND);
1813 break;
1815 case 'U':
1816 set_old_files_option (UNLINK_FIRST_OLD_FILES, args->loc);
1817 break;
1819 case UTC_OPTION:
1820 utc_option = true;
1821 break;
1823 case 'V':
1824 volume_label_option = arg;
1825 break;
1827 case 'v':
1828 verbose_option += verbose_option <= 2;
1829 warning_option |= WARN_VERBOSE_WARNINGS;
1830 break;
1832 case 'w':
1833 interactive_option = true;
1834 break;
1836 case 'W':
1837 optloc_save (OC_VERIFY, args->loc);
1838 verify_option = true;
1839 break;
1841 case WARNING_OPTION:
1842 set_warning_option (arg);
1843 break;
1845 case 'x':
1846 set_subcommand_option (EXTRACT_SUBCOMMAND);
1847 break;
1849 case 'z':
1850 set_use_compress_program_option (GZIP_PROGRAM, args->loc);
1851 break;
1853 case 'Z':
1854 set_use_compress_program_option (COMPRESS_PROGRAM, args->loc);
1855 break;
1857 case ZSTD_OPTION:
1858 set_use_compress_program_option (ZSTD_PROGRAM, args->loc);
1859 break;
1861 case ATIME_PRESERVE_OPTION:
1862 atime_preserve_option =
1863 (arg
1864 ? XARGMATCH ("--atime-preserve", arg,
1865 atime_preserve_args, atime_preserve_types)
1866 : replace_atime_preserve);
1867 if (! O_NOATIME && atime_preserve_option == system_atime_preserve)
1868 paxfatal (0, _("--atime-preserve='system' is not supported"
1869 " on this platform"));
1870 break;
1872 case CHECK_DEVICE_OPTION:
1873 check_device_option = true;
1874 break;
1876 case NO_CHECK_DEVICE_OPTION:
1877 check_device_option = false;
1878 break;
1880 case CHECKPOINT_OPTION:
1881 if (arg)
1883 char *p;
1885 if (*arg == '.')
1887 checkpoint_compile_action (".");
1888 arg++;
1890 checkpoint_option = stoint (arg, &p, NULL, 0, INTMAX_MAX);
1891 if (*p | (checkpoint_option <= 0))
1892 paxfatal (0, _("invalid --checkpoint value"));
1894 else
1895 checkpoint_option = DEFAULT_CHECKPOINT;
1896 break;
1898 case CHECKPOINT_ACTION_OPTION:
1899 checkpoint_compile_action (arg);
1900 break;
1902 case BACKUP_OPTION:
1903 backup_option = true;
1904 if (arg)
1905 args->version_control_string = arg;
1906 break;
1908 case DELAY_DIRECTORY_RESTORE_OPTION:
1909 delay_directory_restore_option = true;
1910 break;
1912 case NO_DELAY_DIRECTORY_RESTORE_OPTION:
1913 delay_directory_restore_option = false;
1914 break;
1916 case DELETE_OPTION:
1917 set_subcommand_option (DELETE_SUBCOMMAND);
1918 break;
1920 case FORCE_LOCAL_OPTION:
1921 force_local_option = true;
1922 break;
1924 case 'H':
1925 set_archive_format (arg);
1926 break;
1928 case INDEX_FILE_OPTION:
1929 index_file_name = arg;
1930 break;
1932 case IGNORE_COMMAND_ERROR_OPTION:
1933 ignore_command_error_option = true;
1934 break;
1936 case IGNORE_FAILED_READ_OPTION:
1937 ignore_failed_read_option = true;
1938 break;
1940 case KEEP_DIRECTORY_SYMLINK_OPTION:
1941 keep_directory_symlink_option = true;
1942 break;
1944 case KEEP_NEWER_FILES_OPTION:
1945 set_old_files_option (KEEP_NEWER_FILES, args->loc);
1946 break;
1948 case GROUP_OPTION:
1950 uintmax_t u = parse_owner_group (arg, TYPE_MAXIMUM (gid_t),
1951 &group_name_option);
1952 if (u == UINTMAX_MAX)
1954 group_option = -1;
1955 if (group_name_option)
1956 gname_to_gid (group_name_option, &group_option);
1958 else
1959 group_option = u;
1961 break;
1963 case GROUP_MAP_OPTION:
1964 group_map_read (arg);
1965 break;
1967 case MODE_OPTION:
1968 mode_option = mode_compile (arg);
1969 if (!mode_option)
1970 paxfatal (0, _("Invalid mode given on option"));
1971 initial_umask = umask (0);
1972 umask (initial_umask);
1973 break;
1975 case NO_IGNORE_COMMAND_ERROR_OPTION:
1976 ignore_command_error_option = false;
1977 break;
1979 case NO_OVERWRITE_DIR_OPTION:
1980 set_old_files_option (NO_OVERWRITE_DIR_OLD_FILES, args->loc);
1981 break;
1983 case NO_QUOTE_CHARS_OPTION:
1984 for (;*arg; arg++)
1985 set_char_quoting (NULL, *arg, 0);
1986 break;
1988 case NUMERIC_OWNER_OPTION:
1989 numeric_owner_option = true;
1990 break;
1992 case OCCURRENCE_OPTION:
1993 optloc_save (OC_OCCURRENCE, args->loc);
1994 if (!arg)
1995 occurrence_option = 1;
1996 else
1998 char *end;
1999 occurrence_option = stoint (arg, &end, NULL, 0, INTMAX_MAX);
2000 if (*end)
2001 paxfatal (0, "%s: %s", quotearg_colon (arg), _("Invalid number"));
2003 break;
2005 case OLD_ARCHIVE_OPTION:
2006 set_archive_format ("v7");
2007 break;
2009 case OVERWRITE_DIR_OPTION:
2010 set_old_files_option (DEFAULT_OLD_FILES, args->loc);
2011 break;
2013 case OVERWRITE_OPTION:
2014 set_old_files_option (OVERWRITE_OLD_FILES, args->loc);
2015 break;
2017 case OWNER_OPTION:
2019 uintmax_t u = parse_owner_group (arg, TYPE_MAXIMUM (uid_t),
2020 &owner_name_option);
2021 if (u == UINTMAX_MAX)
2023 owner_option = -1;
2024 if (owner_name_option)
2025 uname_to_uid (owner_name_option, &owner_option);
2027 else
2028 owner_option = u;
2030 break;
2032 case OWNER_MAP_OPTION:
2033 owner_map_read (arg);
2034 break;
2036 case QUOTE_CHARS_OPTION:
2037 for (;*arg; arg++)
2038 set_char_quoting (NULL, *arg, 1);
2039 break;
2041 case QUOTING_STYLE_OPTION:
2042 tar_set_quoting_style (arg);
2043 break;
2045 case PAX_OPTION:
2047 char *tmp = expand_pax_option (args, arg);
2048 args->pax_option = true;
2049 xheader_set_option (tmp);
2050 free (tmp);
2052 break;
2054 case POSIX_OPTION:
2055 set_archive_format ("posix");
2056 break;
2058 case RECORD_SIZE_OPTION:
2060 uintmax_t u;
2062 if (! (xstrtoumax (arg, NULL, 10, &u, TAR_SIZE_SUFFIXES) == LONGINT_OK
2063 && !ckd_add (&record_size, u, 0)
2064 && record_size <= min (SSIZE_MAX, SIZE_MAX)))
2065 paxusage ("%s: %s", quotearg_colon (arg), _("Invalid record size"));
2066 if (record_size % BLOCKSIZE != 0)
2067 paxusage (_("Record size must be a multiple of %d."), BLOCKSIZE);
2068 blocking_factor = record_size / BLOCKSIZE;
2070 break;
2072 case RECURSIVE_UNLINK_OPTION:
2073 recursive_unlink_option = true;
2074 break;
2076 case REMOVE_FILES_OPTION:
2077 remove_files_option = true;
2078 break;
2080 case RESTRICT_OPTION:
2081 restrict_option = true;
2082 break;
2084 case RMT_COMMAND_OPTION:
2085 rmt_command = arg;
2086 break;
2088 case RSH_COMMAND_OPTION:
2089 rsh_command_option = arg;
2090 break;
2092 case SHOW_DEFAULTS_OPTION:
2094 char *s = format_default_settings ();
2095 printf ("%s\n", s);
2096 close_stdout ();
2097 free (s);
2098 exit (0);
2101 case SHOW_SNAPSHOT_FIELD_RANGES_OPTION:
2102 show_snapshot_field_ranges ();
2103 close_stdout ();
2104 exit (0);
2106 case STRIP_COMPONENTS_OPTION:
2108 char *end;
2109 strip_name_components = stoint (arg, &end, NULL, 0, IDX_MAX);
2110 if (*end)
2111 paxusage ("%s: %s", quotearg_colon (arg),
2112 _("Invalid number of elements"));
2114 break;
2116 case SHOW_OMITTED_DIRS_OPTION:
2117 show_omitted_dirs_option = true;
2118 break;
2120 case SHOW_TRANSFORMED_NAMES_OPTION:
2121 show_transformed_names_option = true;
2122 break;
2124 case SORT_OPTION:
2125 savedir_sort_order = XARGMATCH ("--sort", arg,
2126 sort_mode_arg, sort_mode_flag);
2127 break;
2129 case SUFFIX_OPTION:
2130 backup_option = true;
2131 args->backup_suffix_string = arg;
2132 break;
2134 case TO_COMMAND_OPTION:
2135 if (to_command_option)
2136 paxusage (_("Only one --to-command option allowed"));
2137 to_command_option = arg;
2138 break;
2140 case TOTALS_OPTION:
2141 if (arg)
2142 set_stat_signal (arg);
2143 else
2144 totals_option = true;
2145 break;
2147 case 'I':
2148 set_use_compress_program_option (arg, args->loc);
2149 break;
2151 case VOLNO_FILE_OPTION:
2152 volno_file_option = arg;
2153 break;
2155 case NO_SAME_OWNER_OPTION:
2156 same_owner_option = -1;
2157 break;
2159 case NO_SAME_PERMISSIONS_OPTION:
2160 same_permissions_option = -1;
2161 break;
2163 case ACLS_OPTION:
2164 set_archive_format ("posix");
2165 acls_option = 1;
2166 break;
2168 case NO_ACLS_OPTION:
2169 acls_option = -1;
2170 break;
2172 case SELINUX_CONTEXT_OPTION:
2173 set_archive_format ("posix");
2174 selinux_context_option = 1;
2175 break;
2177 case NO_SELINUX_CONTEXT_OPTION:
2178 selinux_context_option = -1;
2179 break;
2181 case XATTR_OPTION:
2182 set_xattr_option (true);
2183 break;
2185 case NO_XATTR_OPTION:
2186 set_xattr_option (false);
2187 break;
2189 case XATTR_INCLUDE:
2190 case XATTR_EXCLUDE:
2191 set_xattr_option (true);
2192 xattrs_mask_add (arg, (key == XATTR_INCLUDE));
2193 break;
2195 case SAME_OWNER_OPTION:
2196 same_owner_option = 1;
2197 break;
2199 case ARGP_KEY_ERROR:
2200 if (args->loc->source == OPTS_FILE)
2201 error (0, 0, _("%s:%jd: location of the error"), args->loc->name,
2202 args->loc->line);
2203 else if (args->loc->source == OPTS_ENVIRON)
2204 error (0, 0, _("error parsing %s"), args->loc->name);
2205 exit (EX_USAGE);
2207 default:
2208 return ARGP_ERR_UNKNOWN;
2210 return 0;
2213 static struct argp_child argp_children[] = {
2214 { &names_argp, 0, NULL, GRID_FILE_NAME },
2215 { NULL }
2218 static struct argp argp = {
2219 options,
2220 parse_opt,
2221 N_("[FILE]..."),
2222 doc,
2223 argp_children,
2224 tar_help_filter,
2225 NULL
2228 void
2229 usage (int status)
2231 argp_help (&argp, stderr, ARGP_HELP_SEE, (char *) program_name);
2232 close_stdout ();
2233 exit (status);
2236 /* Parse the options for tar. */
2238 static struct argp_option const *
2239 find_argp_option_key (struct argp_option const *o, char key)
2241 for (;
2242 !(o->name == NULL
2243 && o->key == 0
2244 && o->arg == 0
2245 && o->flags == 0
2246 && o->doc == NULL); o++)
2247 if (o->key == key)
2248 return o;
2249 return NULL;
2252 static struct argp_option const *
2253 find_argp_option (struct argp *ap, char key)
2255 struct argp_option const *p = NULL;
2256 struct argp_child const *child;
2258 p = find_argp_option_key (ap->options, key);
2259 if (!p && ap->children)
2261 for (child = ap->children; child->argp; child++)
2263 p = find_argp_option_key (child->argp->options, key);
2264 if (p)
2265 break;
2268 return p;
2271 static const char *tar_authors[] = {
2272 "John Gilmore",
2273 "Jay Fenlason",
2274 NULL
2277 /* Subcommand classes */
2278 enum subcommand_class
2280 SUBCL_READ = 1 << 0, /* Reads from the archive. */
2281 SUBCL_WRITE = 1 << 1, /* Writes to the archive. */
2282 SUBCL_UPDATE = 1 << 2, /* Updates existing archive. */
2283 SUBCL_TEST = 1 << 3, /* Tests archive header or meta-info. */
2284 SUBCL_OCCUR = 1 << 4, /* Allows the use of the occurrence option. */
2287 static char const subcommand_class[] = {
2288 [UNKNOWN_SUBCOMMAND ] = 0,
2289 [APPEND_SUBCOMMAND ] = SUBCL_WRITE | SUBCL_UPDATE,
2290 [CAT_SUBCOMMAND ] = SUBCL_WRITE,
2291 [CREATE_SUBCOMMAND ] = SUBCL_WRITE,
2292 [DELETE_SUBCOMMAND ] = SUBCL_WRITE | SUBCL_UPDATE | SUBCL_OCCUR,
2293 [DIFF_SUBCOMMAND ] = SUBCL_READ | SUBCL_OCCUR,
2294 [EXTRACT_SUBCOMMAND ] = SUBCL_READ | SUBCL_OCCUR,
2295 [LIST_SUBCOMMAND ] = SUBCL_READ | SUBCL_OCCUR,
2296 [UPDATE_SUBCOMMAND ] = SUBCL_WRITE | SUBCL_UPDATE,
2297 [TEST_LABEL_SUBCOMMAND] = SUBCL_TEST
2300 /* Is subcommand_option in class(es) f? */
2301 static bool
2302 is_subcommand_class (enum subcommand_class f)
2304 return subcommand_class[subcommand_option] & f;
2307 void
2308 more_options (int argc, char **argv, struct option_locus *loc)
2310 struct tar_args args = { .loc = loc };
2311 argp_parse (&names_argp, argc, argv, ARGP_IN_ORDER|ARGP_NO_EXIT|ARGP_NO_ERRS,
2312 NULL, &args);
2315 /* Are there file names in the list? */
2316 static bool
2317 name_more_files (void)
2319 return filename_args != FILES_NONE;
2322 static void
2323 parse_default_options (struct tar_args *args)
2325 char *opts = getenv ("TAR_OPTIONS");
2326 struct wordsplit ws;
2327 struct option_locus loc = { OPTS_ENVIRON, "TAR_OPTIONS", 0, 0 };
2328 struct option_locus *save_loc_ptr;
2330 if (!opts)
2331 return;
2333 ws.ws_offs = 1;
2334 if (wordsplit (opts, &ws, WRDSF_DEFFLAGS | WRDSF_DOOFFS) != WRDSE_OK)
2335 paxfatal (0, _("cannot split TAR_OPTIONS: %s"), wordsplit_strerror (&ws));
2336 if (ws.ws_wordc)
2338 int idx;
2339 ws.ws_wordv[0] = (char *) program_name;
2340 save_loc_ptr = args->loc;
2341 args->loc = &loc;
2342 int argc;
2343 if (ckd_add (&argc, ws.ws_offs, ws.ws_wordc))
2344 paxfatal (0, _("too many options"));
2345 if (argp_parse (&argp, argc, ws.ws_wordv,
2346 ARGP_IN_ORDER | ARGP_NO_EXIT, &idx, args))
2347 abort (); /* shouldn't happen */
2348 args->loc = save_loc_ptr;
2349 if (name_more_files ())
2350 paxusage (_("non-option arguments in %s"), loc.name);
2351 /* Don't free consumed words */
2352 ws.ws_wordc = 0;
2354 wordsplit_free (&ws);
2357 static void
2358 decode_options (int argc, char **argv)
2360 int idx;
2361 struct option_locus loc = { .source = OPTS_COMMAND_LINE };
2362 struct tar_args args = { .loc = &loc };
2364 argp_version_setup ("tar", tar_authors);
2366 /* Set some default option values. */
2367 args.backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX");
2369 posixly_correct = getenv ("POSIXLY_CORRECT") != NULL;
2371 subcommand_option = UNKNOWN_SUBCOMMAND;
2372 archive_format = DEFAULT_FORMAT;
2373 blocking_factor = DEFAULT_BLOCKING;
2374 record_size = DEFAULT_BLOCKING * BLOCKSIZE;
2375 excluded = new_exclude ();
2376 hole_detection = HOLE_DETECTION_DEFAULT;
2378 newer_mtime_option.tv_sec = TYPE_MINIMUM (time_t);
2379 newer_mtime_option.tv_nsec = -1;
2380 mtime_option.tv_sec = TYPE_MINIMUM (time_t);
2381 mtime_option.tv_nsec = -1;
2382 recursion_option = FNM_LEADING_DIR;
2383 unquote_option = true;
2384 tar_sparse_major = 1;
2385 tar_sparse_minor = 0;
2387 savedir_sort_order = SAVEDIR_SORT_NONE;
2389 owner_option = -1; owner_name_option = NULL;
2390 group_option = -1; group_name_option = NULL;
2392 check_device_option = true;
2394 incremental_level = -1;
2396 seek_option = -1;
2398 /* Convert old-style tar call by exploding option element and rearranging
2399 options accordingly. */
2401 if (argc > 1 && argv[1][0] != '-')
2403 int new_argc; /* argc value for rearranged arguments */
2404 char **new_argv; /* argv value for rearranged arguments */
2405 char *const *in; /* cursor into original argv */
2406 char **out; /* cursor into rearranged argv */
2407 char buffer[3]; /* constructed option buffer */
2409 /* Initialize a constructed option. */
2411 buffer[0] = '-';
2412 buffer[2] = '\0';
2414 /* Allocate a new argument array, and copy program name in it. */
2416 idx_t new_arg_slots;
2417 if (ckd_add (&new_arg_slots, argc, strlen (argv[1]))
2418 || ckd_sub (&new_argc, new_arg_slots, 1))
2419 xalloc_die ();
2420 new_argv = xinmalloc (new_arg_slots, sizeof *new_argv);
2421 in = argv;
2422 out = new_argv;
2423 *out++ = *in++;
2425 /* Copy each old letter option as a separate option, and have the
2426 corresponding argument moved next to it. */
2428 for (char const *letter = *in++; *letter; letter++)
2430 struct argp_option const *opt;
2432 buffer[1] = *letter;
2433 *out++ = xstrdup (buffer);
2434 opt = find_argp_option (&argp, *letter);
2435 if (opt && opt->arg)
2437 if (! (in < argv + argc))
2438 paxusage (_("Old option '%c' requires an argument."), *letter);
2439 *out++ = *in++;
2443 /* Copy all remaining options. */
2445 while (in < argv + argc)
2446 *out++ = *in++;
2447 *out = 0;
2449 /* Replace the old option list by the new one. */
2451 argc = new_argc;
2452 argv = new_argv;
2455 /* Parse all options and non-options as they appear. */
2456 parse_default_options (&args);
2458 if (argp_parse (&argp, argc, argv, ARGP_IN_ORDER, &idx, &args))
2459 exit (TAREXIT_FAILURE);
2461 /* Special handling for 'o' option:
2463 GNU tar used to say "output old format".
2464 UNIX98 tar says don't chown files after extracting (we use
2465 "--no-same-owner" for this).
2467 The old GNU tar semantics is retained when used with --create
2468 option, otherwise UNIX98 semantics is assumed */
2470 if (args.o_option)
2472 if (subcommand_option == CREATE_SUBCOMMAND)
2474 /* GNU Tar <= 1.13 compatibility */
2475 set_archive_format ("v7");
2477 else
2479 /* UNIX98 compatibility */
2480 same_owner_option = -1;
2484 /* Handle operands after any "--" argument. */
2485 for (; idx < argc; idx++)
2486 name_add_name (argv[idx]);
2488 /* Derive option values and check option consistency. */
2490 if (archive_format == DEFAULT_FORMAT)
2492 if (args.pax_option)
2493 archive_format = POSIX_FORMAT;
2494 else
2495 archive_format = DEFAULT_ARCHIVE_FORMAT;
2498 if ((volume_label_option && subcommand_option == CREATE_SUBCOMMAND)
2499 || incremental_option
2500 || multi_volume_option
2501 || sparse_option)
2502 assert_format (format_mask (OLDGNU_FORMAT)
2503 | format_mask (GNU_FORMAT)
2504 | format_mask (POSIX_FORMAT));
2506 if (occurrence_option)
2508 if (!name_more_files ())
2509 paxusage (_("--occurrence is meaningless without a file list"));
2510 if (!is_subcommand_class (SUBCL_OCCUR))
2512 if (option_set_in_cl (OC_OCCURRENCE))
2513 option_conflict_error ("--occurrence",
2514 subcommand_string (subcommand_option));
2515 else
2516 occurrence_option = 0;
2520 if (archive_names == 0)
2522 /* If no archive file name given, try TAPE from the environment, or
2523 else, DEFAULT_ARCHIVE from the configuration process. */
2525 static char const *default_archive = DEFAULT_ARCHIVE;
2526 char const *tape = getenv ("TAPE");
2527 if (tape)
2528 default_archive = tape;
2529 archive_name_array = &default_archive;
2530 archive_names = 1;
2533 /* Allow multiple archives only with '-M'. */
2535 if (archive_names > 1 && !multi_volume_option)
2536 paxusage (_("Multiple archive files require '-M' option"));
2538 if (listed_incremental_option
2539 && time_option_initialized (newer_mtime_option))
2541 struct option_locus *listed_loc = optloc_lookup (OC_LISTED_INCREMENTAL);
2542 struct option_locus *newer_loc = optloc_lookup (OC_NEWER);
2543 if (optloc_eq (listed_loc, newer_loc))
2544 option_conflict_error ("--listed-incremental", "--newer");
2545 else if (listed_loc->source == OPTS_COMMAND_LINE)
2546 listed_incremental_option = NULL;
2547 else
2548 memset (&newer_mtime_option, 0, sizeof (newer_mtime_option));
2551 if (0 <= incremental_level && !listed_incremental_option)
2552 paxwarn (0, _("--level is meaningless without --listed-incremental"));
2554 if (volume_label_option)
2556 if (archive_format == GNU_FORMAT || archive_format == OLDGNU_FORMAT)
2558 int volume_label_max_len =
2559 (sizeof current_header->header.name
2560 - 1 /* for trailing '\0' */
2561 - (multi_volume_option
2562 ? (sizeof " Volume "
2563 - 1 /* for null at end of " Volume " */
2564 + INT_STRLEN_BOUND (int) /* for volume number */
2565 - 1 /* for sign, as 0 <= volno */)
2566 : 0));
2567 if (volume_label_max_len < strlen (volume_label_option))
2568 paxusage (_("%s: Volume label length exceeds %d bytes"),
2569 quotearg_colon (volume_label_option),
2570 volume_label_max_len);
2572 /* else FIXME
2573 Label length in PAX format is limited by the volume size. */
2576 if (verify_option)
2578 if (multi_volume_option)
2579 paxusage (_("Cannot verify multi-volume archives"));
2580 if (use_compress_program_option)
2581 paxusage (_("Cannot verify compressed archives"));
2582 if (!is_subcommand_class (SUBCL_WRITE))
2584 if (option_set_in_cl (OC_VERIFY))
2585 option_conflict_error ("--verify",
2586 subcommand_string (subcommand_option));
2587 else
2588 verify_option = false;
2592 if (use_compress_program_option)
2594 if (multi_volume_option)
2595 paxusage (_("Cannot use multi-volume compressed archives"));
2596 if (is_subcommand_class (SUBCL_UPDATE))
2597 paxusage (_("Cannot update compressed archives"));
2598 if (subcommand_option == CAT_SUBCOMMAND)
2599 paxusage (_("Cannot concatenate compressed archives"));
2602 if (set_mtime_command)
2604 if (set_mtime_option != USE_FILE_MTIME)
2605 paxusage (_("--mtime conflicts with --set-mtime-command"));
2606 set_mtime_option = COMMAND_MTIME;
2608 else if (set_mtime_option == CLAMP_MTIME)
2610 if (!time_option_initialized (mtime_option))
2611 paxusage (_("--clamp-mtime needs a date specified using --mtime"));
2614 /* It is no harm to use --pax-option on non-pax archives in archive
2615 reading mode. It may even be useful, since it allows to override
2616 file attributes from tar headers. Therefore I allow such usage.
2617 --gray */
2618 if (args.pax_option
2619 && archive_format != POSIX_FORMAT
2620 && !is_subcommand_class (SUBCL_READ))
2621 paxusage (_("--pax-option can be used only on POSIX archives"));
2623 /* star creates non-POSIX typed archives with xattr support, so allow the
2624 extra headers when reading */
2625 if ((acls_option > 0)
2626 && archive_format != POSIX_FORMAT
2627 && !is_subcommand_class (SUBCL_READ))
2628 paxusage (_("--acls can be used only on POSIX archives"));
2630 if ((selinux_context_option > 0)
2631 && archive_format != POSIX_FORMAT
2632 && !is_subcommand_class (SUBCL_READ))
2633 paxusage (_("--selinux can be used only on POSIX archives"));
2635 if (xattrs_option
2636 && archive_format != POSIX_FORMAT
2637 && !is_subcommand_class (SUBCL_READ))
2638 paxusage (_("--xattrs can be used only on POSIX archives"));
2640 if (starting_file_option && !is_subcommand_class (SUBCL_READ))
2642 if (option_set_in_cl (OC_STARTING_FILE))
2643 option_conflict_error ("--starting-file",
2644 subcommand_string (subcommand_option));
2645 else
2646 starting_file_option = false;
2649 if (same_order_option && !is_subcommand_class (SUBCL_READ))
2651 if (option_set_in_cl (OC_SAME_ORDER))
2652 option_conflict_error ("--same-order",
2653 subcommand_string (subcommand_option));
2654 else
2655 same_order_option = false;
2658 if (one_top_level_option)
2660 char *base;
2662 if (absolute_names_option)
2664 struct option_locus *one_top_level_loc =
2665 optloc_lookup (OC_ONE_TOP_LEVEL);
2666 struct option_locus *absolute_names_loc =
2667 optloc_lookup (OC_ABSOLUTE_NAMES);
2669 if (optloc_eq (one_top_level_loc, absolute_names_loc))
2670 option_conflict_error ("--one-top-level", "--absolute-names");
2671 else if (one_top_level_loc->source == OPTS_COMMAND_LINE)
2672 absolute_names_option = false;
2673 else
2674 one_top_level_option = false;
2677 if (one_top_level_option && !one_top_level_dir)
2679 /* If the user wants to guarantee that everything is under one
2680 directory, determine its name now and let it be created later. */
2681 base = base_name (archive_name_array[0]);
2682 one_top_level_dir = strip_compression_suffix (base);
2683 free (base);
2685 if (!one_top_level_dir)
2686 paxusage (_("Cannot deduce top-level directory name; "
2687 "please set it explicitly with --one-top-level=DIR"));
2691 /* If ready to unlink hierarchies, so we are for simpler files. */
2692 if (recursive_unlink_option)
2693 old_files_option = UNLINK_FIRST_OLD_FILES;
2695 /* Flags for accessing files to be read from or copied into. POSIX says
2696 O_NONBLOCK has unspecified effect on most types of files, but in
2697 practice it never harms and sometimes helps. */
2699 int base_open_flags =
2700 (O_BINARY | O_CLOEXEC | O_NOCTTY | O_NONBLOCK
2701 | (dereference_option ? 0 : O_NOFOLLOW)
2702 | (atime_preserve_option == system_atime_preserve ? O_NOATIME : 0));
2703 open_read_flags = O_RDONLY | base_open_flags;
2704 open_searchdir_flags = O_SEARCH | O_DIRECTORY | base_open_flags;
2706 fstatat_flags = dereference_option ? 0 : AT_SYMLINK_NOFOLLOW;
2708 if (subcommand_option == TEST_LABEL_SUBCOMMAND)
2710 /* --test-label is silent if the user has specified the label name to
2711 compare against. */
2712 if (!name_more_files ())
2713 verbose_option += verbose_option <= 2;
2715 else if (utc_option)
2716 verbose_option = 2;
2718 if (tape_length_option && tape_length_option < record_size)
2719 paxusage (_("Volume length cannot be less than record size"));
2721 if (same_order_option && listed_incremental_option)
2723 struct option_locus *preserve_order_loc = optloc_lookup (OC_SAME_ORDER);
2724 struct option_locus *listed_incremental_loc =
2725 optloc_lookup (OC_LISTED_INCREMENTAL);
2727 if (optloc_eq (preserve_order_loc, listed_incremental_loc))
2728 option_conflict_error ("--preserve-order", "--listed-incremental");
2729 else if (preserve_order_loc->source == OPTS_COMMAND_LINE)
2730 listed_incremental_option = NULL;
2731 else
2732 same_order_option = false;
2735 /* Forbid using -c with no input files whatsoever. Check that '-f -',
2736 explicit or implied, is used correctly. */
2738 switch (subcommand_option)
2740 case CREATE_SUBCOMMAND:
2741 if (!name_more_files ())
2742 paxusage (_("Cowardly refusing to create an empty archive"));
2743 if (args.compress_autodetect && archive_names
2744 && strcmp (archive_name_array[0], "-"))
2745 set_compression_program_by_suffix (archive_name_array[0],
2746 use_compress_program_option,
2747 true);
2748 break;
2750 case EXTRACT_SUBCOMMAND:
2751 case LIST_SUBCOMMAND:
2752 case DIFF_SUBCOMMAND:
2753 case TEST_LABEL_SUBCOMMAND:
2754 for (archive_name_cursor = archive_name_array;
2755 archive_name_cursor < archive_name_array + archive_names;
2756 archive_name_cursor++)
2757 if (strcmp (*archive_name_cursor, "-") == 0)
2758 request_stdin ("-f");
2759 break;
2761 case CAT_SUBCOMMAND:
2762 case UPDATE_SUBCOMMAND:
2763 case APPEND_SUBCOMMAND:
2764 for (archive_name_cursor = archive_name_array;
2765 archive_name_cursor < archive_name_array + archive_names;
2766 archive_name_cursor++)
2767 if (strcmp (*archive_name_cursor, "-") == 0)
2768 paxusage (_("Options '-Aru' are incompatible with '-f -'"));
2770 default:
2771 break;
2774 /* Initialize stdlis */
2775 if (index_file_name)
2777 stdlis = fopen (index_file_name, "w");
2778 if (! stdlis)
2779 open_fatal (index_file_name);
2781 else
2782 stdlis = to_stdout_option ? stderr : stdout;
2784 archive_name_cursor = archive_name_array;
2786 /* Prepare for generating backup names. */
2788 if (args.backup_suffix_string)
2789 simple_backup_suffix = xstrdup (args.backup_suffix_string);
2791 if (backup_option)
2793 backup_type = xget_version ("--backup", args.version_control_string);
2794 /* No backup is needed either if explicitly disabled or if
2795 the extracted files are not being written to disk. */
2796 if (backup_type == no_backups || to_stdout_option || to_command_option)
2797 backup_option = false;
2800 checkpoint_finish_compile ();
2802 report_textual_dates (&args);
2805 #ifdef ENABLE_ERROR_PRINT_PROGNAME
2806 /* The error() function from glibc correctly prefixes each message it
2807 prints with program_name as set by set_program_name. However, its
2808 replacement from gnulib, which is linked in on systems where this
2809 function is not available, prints the name returned by getprogname()
2810 instead. Due to this messages output by tar subprocess (which sets its
2811 program name to 'tar (child)') become indiscernible from those printed
2812 by the main process. In particular, this breaks the remfiles01.at and
2813 remfiles02.at test cases.
2815 To avoid this, on such systems the following helper function is used
2816 to print proper program name. Its address is assigned to the
2817 error_print_progname variable, which error() then uses instead of
2818 printing getprogname() result.
2820 static void
2821 tar_print_progname (void)
2823 fprintf (stderr, "%s: ", program_name);
2825 #endif
2827 /* Tar proper. */
2829 /* Main routine for tar. */
2831 main (int argc, char **argv)
2833 set_start_time ();
2834 set_program_name (argv[0]);
2835 #ifdef ENABLE_ERROR_PRINT_PROGNAME
2836 error_print_progname = tar_print_progname;
2837 #endif
2838 setlocale (LC_ALL, "");
2839 bindtextdomain (PACKAGE, LOCALEDIR);
2840 textdomain (PACKAGE);
2842 exit_failure = TAREXIT_FAILURE;
2843 exit_status = TAREXIT_SUCCESS;
2844 error_hook = checkpoint_flush_actions;
2846 set_quoting_style (0, DEFAULT_QUOTING_STYLE);
2848 close_stdout_set_file_name (_("stdout"));
2850 int err = stdopen ();
2851 if (err != 0)
2852 paxfatal (err, _("failed to assert availability"
2853 " of the standard file descriptors"));
2855 /* System V fork+wait does not work if SIGCHLD is ignored. */
2856 signal (SIGCHLD, SIG_DFL);
2858 /* Try to disable the ability to unlink a directory. */
2859 priv_set_remove_linkdir ();
2861 /* Decode options. */
2863 decode_options (argc, argv);
2865 name_init ();
2867 /* Main command execution. */
2869 if (volno_file_option)
2870 init_volume_number ();
2872 switch (subcommand_option)
2874 case UNKNOWN_SUBCOMMAND:
2875 paxusage (_("You must specify one of the '-Acdtrux',"
2876 " '--delete' or '--test-label' options"));
2878 case CAT_SUBCOMMAND:
2879 case UPDATE_SUBCOMMAND:
2880 case APPEND_SUBCOMMAND:
2881 update_archive ();
2882 break;
2884 case DELETE_SUBCOMMAND:
2885 delete_archive_members ();
2886 break;
2888 case CREATE_SUBCOMMAND:
2889 create_archive ();
2890 break;
2892 case EXTRACT_SUBCOMMAND:
2893 extr_init ();
2894 read_and (extract_archive);
2896 /* FIXME: should extract_finish () even if an ordinary signal is
2897 received. */
2898 extract_finish ();
2900 break;
2902 case LIST_SUBCOMMAND:
2903 read_and (list_archive);
2904 break;
2906 case DIFF_SUBCOMMAND:
2907 diff_init ();
2908 read_and (diff_archive);
2909 break;
2911 case TEST_LABEL_SUBCOMMAND:
2912 test_archive_label ();
2915 checkpoint_finish ();
2917 if (totals_option)
2918 print_total_stats ();
2920 if (check_links_option)
2921 check_links ();
2923 if (volno_file_option)
2924 closeout_volume_number ();
2926 if (exit_status == TAREXIT_FAILURE)
2927 error (0, 0, _("Exiting with failure status due to previous errors"));
2929 if (stdlis == stdout)
2930 close_stdout ();
2931 else if (ferror (stderr) || fclose (stderr) < 0)
2932 set_exit_status (TAREXIT_FAILURE);
2934 return exit_status;
2937 void
2938 tar_stat_init (struct tar_stat_info *st)
2940 memset (st, 0, sizeof (*st));
2943 /* Close the stream or file descriptor associated with ST, and remove
2944 all traces of it from ST. Return true if successful, false (with a
2945 diagnostic) otherwise. */
2946 bool
2947 tar_stat_close (struct tar_stat_info *st)
2949 int status = (st->dirstream ? closedir (st->dirstream)
2950 : 0 < st->fd ? close (st->fd)
2951 : 0);
2952 st->dirstream = 0;
2953 st->fd = 0;
2955 if (status == 0)
2956 return true;
2957 else
2959 close_diag (st->orig_file_name);
2960 return false;
2964 void
2965 tar_stat_destroy (struct tar_stat_info *st)
2967 tar_stat_close (st);
2968 xattr_map_free (&st->xattr_map);
2969 free (st->orig_file_name);
2970 free (st->file_name);
2971 free (st->link_name);
2972 free (st->uname);
2973 free (st->gname);
2974 free (st->cntx_name);
2975 free (st->acls_a_ptr);
2976 free (st->acls_d_ptr);
2977 free (st->sparse_map);
2978 free (st->dumpdir);
2979 xheader_destroy (&st->xhdr);
2980 info_free_exclist (st);
2981 memset (st, 0, sizeof (*st));
2984 /* Same as timespec_cmp, but ignore nanoseconds if current archive
2985 format does not provide sufficient resolution. */
2987 tar_timespec_cmp (struct timespec a, struct timespec b)
2989 /* Format mask for all available formats that support nanosecond
2990 timestamp resolution. */
2991 int ns_precision_format_mask = format_mask (POSIX_FORMAT);
2993 if (!(format_mask (current_format) & ns_precision_format_mask))
2994 a.tv_nsec = b.tv_nsec = 0;
2995 return timespec_cmp (a, b);
2998 /* Set tar exit status to VAL, unless it is already indicating
2999 a more serious condition. This relies on the fact that the
3000 values of TAREXIT_ constants are ranged by severity. */
3001 void
3002 set_exit_status (int val)
3004 if (val > exit_status)
3005 exit_status = val;