]> Dogcows Code - chaz/tar/blob - src/tar.c
Changes for compatibility with Slackware installation scripts.
[chaz/tar] / src / tar.c
1 /* A tar (tape archiver) program.
2
3 Copyright 1988, 1992-1997, 1999-2001, 2003-2007, 2012-2013 Free
4 Software Foundation, Inc.
5
6 Written by John Gilmore, starting 1985-08-25.
7
8 This program is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by the
10 Free Software Foundation; either version 3, or (at your option) any later
11 version.
12
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
16 Public License for more details.
17
18 You should have received a copy of the GNU General Public License along
19 with this program. If not, see <http://www.gnu.org/licenses/>. */
20
21 #include <system.h>
22
23 #include <fnmatch.h>
24 #include <argp.h>
25 #include <argp-namefrob.h>
26 #include <argp-fmtstream.h>
27 #include <argp-version-etc.h>
28
29 #include <signal.h>
30 #if ! defined SIGCHLD && defined SIGCLD
31 # define SIGCHLD SIGCLD
32 #endif
33
34 /* The following causes "common.h" to produce definitions of all the global
35 variables, rather than just "extern" declarations of them. GNU tar does
36 depend on the system loader to preset all GLOBAL variables to neutral (or
37 zero) values; explicit initialization is usually not done. */
38 #define GLOBAL
39 #include "common.h"
40
41 #include <argmatch.h>
42 #include <closeout.h>
43 #include <configmake.h>
44 #include <exitfail.h>
45 #include <parse-datetime.h>
46 #include <rmt.h>
47 #include <rmt-command.h>
48 #include <prepargs.h>
49 #include <quotearg.h>
50 #include <version-etc.h>
51 #include <xstrtol.h>
52 #include <stdopen.h>
53 #include <priv-set.h>
54
55 /* Local declarations. */
56
57 #ifndef DEFAULT_ARCHIVE_FORMAT
58 # define DEFAULT_ARCHIVE_FORMAT GNU_FORMAT
59 #endif
60
61 #ifndef DEFAULT_ARCHIVE
62 # define DEFAULT_ARCHIVE "tar.out"
63 #endif
64
65 #ifndef DEFAULT_BLOCKING
66 # define DEFAULT_BLOCKING 20
67 #endif
68
69 /* Print a message if not all links are dumped */
70 static int check_links_option;
71
72 /* Number of allocated tape drive names. */
73 static size_t allocated_archive_names;
74
75 \f
76 /* Miscellaneous. */
77
78 /* Name of option using stdin. */
79 static const char *stdin_used_by;
80
81 /* Doesn't return if stdin already requested. */
82 void
83 request_stdin (const char *option)
84 {
85 if (stdin_used_by)
86 USAGE_ERROR ((0, 0, _("Options '-%s' and '-%s' both want standard input"),
87 stdin_used_by, option));
88
89 stdin_used_by = option;
90 }
91
92 extern int rpmatch (char const *response);
93
94 /* Returns true if and only if the user typed an affirmative response. */
95 int
96 confirm (const char *message_action, const char *message_name)
97 {
98 static FILE *confirm_file;
99 static int confirm_file_EOF;
100 bool status = false;
101
102 if (!confirm_file)
103 {
104 if (archive == 0 || stdin_used_by)
105 {
106 confirm_file = fopen (TTY_NAME, "r");
107 if (! confirm_file)
108 open_fatal (TTY_NAME);
109 }
110 else
111 {
112 request_stdin ("-w");
113 confirm_file = stdin;
114 }
115 }
116
117 fprintf (stdlis, "%s %s?", message_action, quote (message_name));
118 fflush (stdlis);
119
120 if (!confirm_file_EOF)
121 {
122 char *response = NULL;
123 size_t response_size = 0;
124 if (getline (&response, &response_size, confirm_file) < 0)
125 confirm_file_EOF = 1;
126 else
127 status = rpmatch (response) > 0;
128 free (response);
129 }
130
131 if (confirm_file_EOF)
132 {
133 fputc ('\n', stdlis);
134 fflush (stdlis);
135 }
136
137 return status;
138 }
139
140 static struct fmttab {
141 char const *name;
142 enum archive_format fmt;
143 } const fmttab[] = {
144 { "v7", V7_FORMAT },
145 { "oldgnu", OLDGNU_FORMAT },
146 { "ustar", USTAR_FORMAT },
147 { "posix", POSIX_FORMAT },
148 #if 0 /* not fully supported yet */
149 { "star", STAR_FORMAT },
150 #endif
151 { "gnu", GNU_FORMAT },
152 { "pax", POSIX_FORMAT }, /* An alias for posix */
153 { NULL, 0 }
154 };
155
156 static void
157 set_archive_format (char const *name)
158 {
159 struct fmttab const *p;
160
161 for (p = fmttab; strcmp (p->name, name) != 0; )
162 if (! (++p)->name)
163 USAGE_ERROR ((0, 0, _("%s: Invalid archive format"),
164 quotearg_colon (name)));
165
166 archive_format = p->fmt;
167 }
168
169 const char *
170 archive_format_string (enum archive_format fmt)
171 {
172 struct fmttab const *p;
173
174 for (p = fmttab; p->name; p++)
175 if (p->fmt == fmt)
176 return p->name;
177 return "unknown?";
178 }
179
180 #define FORMAT_MASK(n) (1<<(n))
181
182 static void
183 assert_format(unsigned fmt_mask)
184 {
185 if ((FORMAT_MASK (archive_format) & fmt_mask) == 0)
186 USAGE_ERROR ((0, 0,
187 _("GNU features wanted on incompatible archive format")));
188 }
189
190 const char *
191 subcommand_string (enum subcommand c)
192 {
193 switch (c)
194 {
195 case UNKNOWN_SUBCOMMAND:
196 return "unknown?";
197
198 case APPEND_SUBCOMMAND:
199 return "-r";
200
201 case CAT_SUBCOMMAND:
202 return "-A";
203
204 case CREATE_SUBCOMMAND:
205 return "-c";
206
207 case DELETE_SUBCOMMAND:
208 return "-D";
209
210 case DIFF_SUBCOMMAND:
211 return "-d";
212
213 case EXTRACT_SUBCOMMAND:
214 return "-x";
215
216 case LIST_SUBCOMMAND:
217 return "-t";
218
219 case UPDATE_SUBCOMMAND:
220 return "-u";
221
222 case TEST_LABEL_SUBCOMMAND:
223 return "--test-label";
224 }
225 abort ();
226 }
227
228 static void
229 tar_list_quoting_styles (struct obstack *stk, char const *prefix)
230 {
231 int i;
232 size_t prefixlen = strlen (prefix);
233
234 for (i = 0; quoting_style_args[i]; i++)
235 {
236 obstack_grow (stk, prefix, prefixlen);
237 obstack_grow (stk, quoting_style_args[i],
238 strlen (quoting_style_args[i]));
239 obstack_1grow (stk, '\n');
240 }
241 }
242
243 static void
244 tar_set_quoting_style (char *arg)
245 {
246 int i;
247
248 for (i = 0; quoting_style_args[i]; i++)
249 if (strcmp (arg, quoting_style_args[i]) == 0)
250 {
251 set_quoting_style (NULL, i);
252 return;
253 }
254 FATAL_ERROR ((0, 0,
255 _("Unknown quoting style '%s'. Try '%s --quoting-style=help' to get a list."), arg, program_invocation_short_name));
256 }
257
258 \f
259 /* Options. */
260
261 enum
262 {
263 ACLS_OPTION = CHAR_MAX + 1,
264 ANCHORED_OPTION,
265 ATIME_PRESERVE_OPTION,
266 BACKUP_OPTION,
267 CHECK_DEVICE_OPTION,
268 CHECKPOINT_OPTION,
269 CHECKPOINT_ACTION_OPTION,
270 DELAY_DIRECTORY_RESTORE_OPTION,
271 HARD_DEREFERENCE_OPTION,
272 DELETE_OPTION,
273 EXCLUDE_BACKUPS_OPTION,
274 EXCLUDE_CACHES_OPTION,
275 EXCLUDE_CACHES_UNDER_OPTION,
276 EXCLUDE_CACHES_ALL_OPTION,
277 EXCLUDE_OPTION,
278 EXCLUDE_TAG_OPTION,
279 EXCLUDE_TAG_UNDER_OPTION,
280 EXCLUDE_TAG_ALL_OPTION,
281 EXCLUDE_VCS_OPTION,
282 FORCE_LOCAL_OPTION,
283 FULL_TIME_OPTION,
284 GROUP_OPTION,
285 IGNORE_CASE_OPTION,
286 IGNORE_COMMAND_ERROR_OPTION,
287 IGNORE_FAILED_READ_OPTION,
288 INDEX_FILE_OPTION,
289 KEEP_DIRECTORY_SYMLINK_OPTION,
290 KEEP_NEWER_FILES_OPTION,
291 LEVEL_OPTION,
292 LZIP_OPTION,
293 LZMA_OPTION,
294 LZOP_OPTION,
295 MODE_OPTION,
296 MTIME_OPTION,
297 NEWER_MTIME_OPTION,
298 NO_ACLS_OPTION,
299 NO_ANCHORED_OPTION,
300 NO_AUTO_COMPRESS_OPTION,
301 NO_CHECK_DEVICE_OPTION,
302 NO_DELAY_DIRECTORY_RESTORE_OPTION,
303 NO_IGNORE_CASE_OPTION,
304 NO_IGNORE_COMMAND_ERROR_OPTION,
305 NO_NULL_OPTION,
306 NO_OVERWRITE_DIR_OPTION,
307 NO_QUOTE_CHARS_OPTION,
308 NO_RECURSION_OPTION,
309 NO_SAME_OWNER_OPTION,
310 NO_SAME_PERMISSIONS_OPTION,
311 NO_SEEK_OPTION,
312 NO_SELINUX_CONTEXT_OPTION,
313 NO_UNQUOTE_OPTION,
314 NO_WILDCARDS_MATCH_SLASH_OPTION,
315 NO_WILDCARDS_OPTION,
316 NO_XATTR_OPTION,
317 NULL_OPTION,
318 NUMERIC_OWNER_OPTION,
319 OCCURRENCE_OPTION,
320 OLD_ARCHIVE_OPTION,
321 ONE_FILE_SYSTEM_OPTION,
322 OVERWRITE_DIR_OPTION,
323 OVERWRITE_OPTION,
324 OWNER_OPTION,
325 PAX_OPTION,
326 POSIX_OPTION,
327 PRESERVE_OPTION,
328 QUOTE_CHARS_OPTION,
329 QUOTING_STYLE_OPTION,
330 RECORD_SIZE_OPTION,
331 RECURSION_OPTION,
332 RECURSIVE_UNLINK_OPTION,
333 REMOVE_FILES_OPTION,
334 RESTRICT_OPTION,
335 RMT_COMMAND_OPTION,
336 RSH_COMMAND_OPTION,
337 SAME_OWNER_OPTION,
338 SELINUX_CONTEXT_OPTION,
339 SHOW_DEFAULTS_OPTION,
340 SHOW_OMITTED_DIRS_OPTION,
341 SHOW_SNAPSHOT_FIELD_RANGES_OPTION,
342 SHOW_TRANSFORMED_NAMES_OPTION,
343 SKIP_OLD_FILES_OPTION,
344 SPARSE_VERSION_OPTION,
345 STRIP_COMPONENTS_OPTION,
346 SUFFIX_OPTION,
347 TEST_LABEL_OPTION,
348 TOTALS_OPTION,
349 TO_COMMAND_OPTION,
350 TRANSFORM_OPTION,
351 UNQUOTE_OPTION,
352 UTC_OPTION,
353 VOLNO_FILE_OPTION,
354 WARNING_OPTION,
355 WILDCARDS_MATCH_SLASH_OPTION,
356 WILDCARDS_OPTION,
357 XATTR_OPTION,
358 XATTR_EXCLUDE,
359 XATTR_INCLUDE
360 };
361
362 const char *argp_program_version = "tar (" PACKAGE_NAME ") " VERSION;
363 const char *argp_program_bug_address = "<" PACKAGE_BUGREPORT ">";
364 static char const doc[] = N_("\
365 GNU 'tar' saves many files together into a single tape or disk archive, \
366 and can restore individual files from the archive.\n\
367 \n\
368 Examples:\n\
369 tar -cf archive.tar foo bar # Create archive.tar from files foo and bar.\n\
370 tar -tvf archive.tar # List all files in archive.tar verbosely.\n\
371 tar -xf archive.tar # Extract all files from archive.tar.\n")
372 "\v"
373 N_("The backup suffix is '~', unless set with --suffix or SIMPLE_BACKUP_SUFFIX.\n\
374 The version control may be set with --backup or VERSION_CONTROL, values are:\n\n\
375 none, off never make backups\n\
376 t, numbered make numbered backups\n\
377 nil, existing numbered if numbered backups exist, simple otherwise\n\
378 never, simple always make simple backups\n");
379
380
381 /* NOTE:
382
383 Available option letters are DEQY and eqy. Consider the following
384 assignments:
385
386 [For Solaris tar compatibility =/= Is it important at all?]
387 e exit immediately with a nonzero exit status if unexpected errors occur
388 E use extended headers (--format=posix)
389
390 [q alias for --occurrence=1 =/= this would better be used for quiet?]
391
392 y per-file gzip compression
393 Y per-block gzip compression.
394
395 Additionally, the 'n' letter is assigned for option --seek, which
396 is probably not needed and should be marked as deprecated, so that
397 -n may become available in the future.
398 */
399
400 static struct argp_option options[] = {
401 #define GRID 10
402 {NULL, 0, NULL, 0,
403 N_("Main operation mode:"), GRID },
404
405 {"list", 't', 0, 0,
406 N_("list the contents of an archive"), GRID+1 },
407 {"extract", 'x', 0, 0,
408 N_("extract files from an archive"), GRID+1 },
409 {"get", 0, 0, OPTION_ALIAS, NULL, GRID+1 },
410 {"create", 'c', 0, 0,
411 N_("create a new archive"), GRID+1 },
412 {"diff", 'd', 0, 0,
413 N_("find differences between archive and file system"), GRID+1 },
414 {"compare", 0, 0, OPTION_ALIAS, NULL, GRID+1 },
415 {"append", 'r', 0, 0,
416 N_("append files to the end of an archive"), GRID+1 },
417 {"update", 'u', 0, 0,
418 N_("only append files newer than copy in archive"), GRID+1 },
419 {"catenate", 'A', 0, 0,
420 N_("append tar files to an archive"), GRID+1 },
421 {"concatenate", 0, 0, OPTION_ALIAS, NULL, GRID+1 },
422 {"delete", DELETE_OPTION, 0, 0,
423 N_("delete from the archive (not on mag tapes!)"), GRID+1 },
424 {"test-label", TEST_LABEL_OPTION, NULL, 0,
425 N_("test the archive volume label and exit"), GRID+1 },
426 #undef GRID
427
428 #define GRID 20
429 {NULL, 0, NULL, 0,
430 N_("Operation modifiers:"), GRID },
431
432 {"sparse", 'S', 0, 0,
433 N_("handle sparse files efficiently"), GRID+1 },
434 {"sparse-version", SPARSE_VERSION_OPTION, N_("MAJOR[.MINOR]"), 0,
435 N_("set version of the sparse format to use (implies --sparse)"), GRID+1},
436 {"incremental", 'G', 0, 0,
437 N_("handle old GNU-format incremental backup"), GRID+1 },
438 {"listed-incremental", 'g', N_("FILE"), 0,
439 N_("handle new GNU-format incremental backup"), GRID+1 },
440 {"level", LEVEL_OPTION, N_("NUMBER"), 0,
441 N_("dump level for created listed-incremental archive"), GRID+1 },
442 {"ignore-failed-read", IGNORE_FAILED_READ_OPTION, 0, 0,
443 N_("do not exit with nonzero on unreadable files"), GRID+1 },
444 {"occurrence", OCCURRENCE_OPTION, N_("NUMBER"), OPTION_ARG_OPTIONAL,
445 N_("process only the NUMBERth occurrence of each file in the archive;"
446 " this option is valid only in conjunction with one of the subcommands"
447 " --delete, --diff, --extract or --list and when a list of files"
448 " is given either on the command line or via the -T option;"
449 " NUMBER defaults to 1"), GRID+1 },
450 {"seek", 'n', NULL, 0,
451 N_("archive is seekable"), GRID+1 },
452 {"no-seek", NO_SEEK_OPTION, NULL, 0,
453 N_("archive is not seekable"), GRID+1 },
454 {"no-check-device", NO_CHECK_DEVICE_OPTION, NULL, 0,
455 N_("do not check device numbers when creating incremental archives"),
456 GRID+1 },
457 {"check-device", CHECK_DEVICE_OPTION, NULL, 0,
458 N_("check device numbers when creating incremental archives (default)"),
459 GRID+1 },
460 #undef GRID
461
462 #define GRID 30
463 {NULL, 0, NULL, 0,
464 N_("Overwrite control:"), GRID },
465
466 {"verify", 'W', 0, 0,
467 N_("attempt to verify the archive after writing it"), GRID+1 },
468 {"remove-files", REMOVE_FILES_OPTION, 0, 0,
469 N_("remove files after adding them to the archive"), GRID+1 },
470 {"keep-old-files", 'k', 0, 0,
471 N_("don't replace existing files when extracting, "
472 "treat them as errors"), GRID+1 },
473 {"skip-old-files", SKIP_OLD_FILES_OPTION, 0, 0,
474 N_("don't replace existing files when extracting, silently skip over them"),
475 GRID+1 },
476 {"keep-newer-files", KEEP_NEWER_FILES_OPTION, 0, 0,
477 N_("don't replace existing files that are newer than their archive copies"), GRID+1 },
478 {"overwrite", OVERWRITE_OPTION, 0, 0,
479 N_("overwrite existing files when extracting"), GRID+1 },
480 {"unlink-first", 'U', 0, 0,
481 N_("remove each file prior to extracting over it"), GRID+1 },
482 {"recursive-unlink", RECURSIVE_UNLINK_OPTION, 0, 0,
483 N_("empty hierarchies prior to extracting directory"), GRID+1 },
484 {"no-overwrite-dir", NO_OVERWRITE_DIR_OPTION, 0, 0,
485 N_("preserve metadata of existing directories"), GRID+1 },
486 {"overwrite-dir", OVERWRITE_DIR_OPTION, 0, 0,
487 N_("overwrite metadata of existing directories when extracting (default)"),
488 GRID+1 },
489 {"keep-directory-symlink", KEEP_DIRECTORY_SYMLINK_OPTION, 0, 0,
490 N_("preserve existing symlinks to directories when extracting"),
491 GRID+1 },
492 #undef GRID
493
494 #define GRID 40
495 {NULL, 0, NULL, 0,
496 N_("Select output stream:"), GRID },
497
498 {"to-stdout", 'O', 0, 0,
499 N_("extract files to standard output"), GRID+1 },
500 {"to-command", TO_COMMAND_OPTION, N_("COMMAND"), 0,
501 N_("pipe extracted files to another program"), GRID+1 },
502 {"ignore-command-error", IGNORE_COMMAND_ERROR_OPTION, 0, 0,
503 N_("ignore exit codes of children"), GRID+1 },
504 {"no-ignore-command-error", NO_IGNORE_COMMAND_ERROR_OPTION, 0, 0,
505 N_("treat non-zero exit codes of children as error"), GRID+1 },
506 #undef GRID
507
508 #define GRID 50
509 {NULL, 0, NULL, 0,
510 N_("Handling of file attributes:"), GRID },
511
512 {"owner", OWNER_OPTION, N_("NAME"), 0,
513 N_("force NAME as owner for added files"), GRID+1 },
514 {"group", GROUP_OPTION, N_("NAME"), 0,
515 N_("force NAME as group for added files"), GRID+1 },
516 {"mtime", MTIME_OPTION, N_("DATE-OR-FILE"), 0,
517 N_("set mtime for added files from DATE-OR-FILE"), GRID+1 },
518 {"mode", MODE_OPTION, N_("CHANGES"), 0,
519 N_("force (symbolic) mode CHANGES for added files"), GRID+1 },
520 {"atime-preserve", ATIME_PRESERVE_OPTION,
521 N_("METHOD"), OPTION_ARG_OPTIONAL,
522 N_("preserve access times on dumped files, either by restoring the times"
523 " after reading (METHOD='replace'; default) or by not setting the times"
524 " in the first place (METHOD='system')"), GRID+1 },
525 {"touch", 'm', 0, 0,
526 N_("don't extract file modified time"), GRID+1 },
527 {"same-owner", SAME_OWNER_OPTION, 0, 0,
528 N_("try extracting files with the same ownership as exists in the archive (default for superuser)"), GRID+1 },
529 {"no-same-owner", NO_SAME_OWNER_OPTION, 0, 0,
530 N_("extract files as yourself (default for ordinary users)"), GRID+1 },
531 {"numeric-owner", NUMERIC_OWNER_OPTION, 0, 0,
532 N_("always use numbers for user/group names"), GRID+1 },
533 {"preserve-permissions", 'p', 0, 0,
534 N_("extract information about file permissions (default for superuser)"),
535 GRID+1 },
536 {"same-permissions", 0, 0, OPTION_ALIAS, NULL, GRID+1 },
537 {"no-same-permissions", NO_SAME_PERMISSIONS_OPTION, 0, 0,
538 N_("apply the user's umask when extracting permissions from the archive (default for ordinary users)"), GRID+1 },
539 {"preserve-order", 's', 0, 0,
540 N_("sort names to extract to match archive"), GRID+1 },
541 {"same-order", 0, 0, OPTION_ALIAS, NULL, GRID+1 },
542 {"preserve", PRESERVE_OPTION, 0, 0,
543 N_("same as both -p and -s"), GRID+1 },
544 {"delay-directory-restore", DELAY_DIRECTORY_RESTORE_OPTION, 0, 0,
545 N_("delay setting modification times and permissions of extracted"
546 " directories until the end of extraction"), GRID+1 },
547 {"no-delay-directory-restore", NO_DELAY_DIRECTORY_RESTORE_OPTION, 0, 0,
548 N_("cancel the effect of --delay-directory-restore option"), GRID+1 },
549 #undef GRID
550
551 #define GRID 55
552 {NULL, 0, NULL, 0,
553 N_("Handling of extended file attributes:"), GRID },
554
555 {"xattrs", XATTR_OPTION, 0, 0,
556 N_("Enable extended attributes support"), GRID+1 },
557 {"no-xattrs", NO_XATTR_OPTION, 0, 0,
558 N_("Disable extended attributes support"), GRID+1 },
559 {"xattrs-include", XATTR_INCLUDE, N_("MASK"), 0,
560 N_("specify the include pattern for xattr keys"), GRID+1 },
561 {"xattrs-exclude", XATTR_EXCLUDE, N_("MASK"), 0,
562 N_("specify the exclude pattern for xattr keys"), GRID+1 },
563 {"selinux", SELINUX_CONTEXT_OPTION, 0, 0,
564 N_("Enable the SELinux context support"), GRID+1 },
565 {"no-selinux", NO_SELINUX_CONTEXT_OPTION, 0, 0,
566 N_("Disable the SELinux context support"), GRID+1 },
567 {"acls", ACLS_OPTION, 0, 0,
568 N_("Enable the POSIX ACLs support"), GRID+1 },
569 {"no-acls", NO_ACLS_OPTION, 0, 0,
570 N_("Disable the POSIX ACLs support"), GRID+1 },
571 #undef GRID
572
573 #define GRID 60
574 {NULL, 0, NULL, 0,
575 N_("Device selection and switching:"), GRID },
576
577 {"file", 'f', N_("ARCHIVE"), 0,
578 N_("use archive file or device ARCHIVE"), GRID+1 },
579 {"force-local", FORCE_LOCAL_OPTION, 0, 0,
580 N_("archive file is local even if it has a colon"), GRID+1 },
581 {"rmt-command", RMT_COMMAND_OPTION, N_("COMMAND"), 0,
582 N_("use given rmt COMMAND instead of rmt"), GRID+1 },
583 {"rsh-command", RSH_COMMAND_OPTION, N_("COMMAND"), 0,
584 N_("use remote COMMAND instead of rsh"), GRID+1 },
585 #ifdef DEVICE_PREFIX
586 {"-[0-7][lmh]", 0, NULL, OPTION_DOC, /* It is OK, since 'name' will never be
587 translated */
588 N_("specify drive and density"), GRID+1 },
589 #endif
590 {NULL, '0', NULL, OPTION_HIDDEN, NULL, GRID+1 },
591 {NULL, '1', NULL, OPTION_HIDDEN, NULL, GRID+1 },
592 {NULL, '2', NULL, OPTION_HIDDEN, NULL, GRID+1 },
593 {NULL, '3', NULL, OPTION_HIDDEN, NULL, GRID+1 },
594 {NULL, '4', NULL, OPTION_HIDDEN, NULL, GRID+1 },
595 {NULL, '5', NULL, OPTION_HIDDEN, NULL, GRID+1 },
596 {NULL, '6', NULL, OPTION_HIDDEN, NULL, GRID+1 },
597 {NULL, '7', NULL, OPTION_HIDDEN, NULL, GRID+1 },
598 {NULL, '8', NULL, OPTION_HIDDEN, NULL, GRID+1 },
599 {NULL, '9', NULL, OPTION_HIDDEN, NULL, GRID+1 },
600
601 {"multi-volume", 'M', 0, 0,
602 N_("create/list/extract multi-volume archive"), GRID+1 },
603 {"tape-length", 'L', N_("NUMBER"), 0,
604 N_("change tape after writing NUMBER x 1024 bytes"), GRID+1 },
605 {"info-script", 'F', N_("NAME"), 0,
606 N_("run script at end of each tape (implies -M)"), GRID+1 },
607 {"new-volume-script", 0, 0, OPTION_ALIAS, NULL, GRID+1 },
608 {"volno-file", VOLNO_FILE_OPTION, N_("FILE"), 0,
609 N_("use/update the volume number in FILE"), GRID+1 },
610 #undef GRID
611
612 #define GRID 70
613 {NULL, 0, NULL, 0,
614 N_("Device blocking:"), GRID },
615
616 {"blocking-factor", 'b', N_("BLOCKS"), 0,
617 N_("BLOCKS x 512 bytes per record"), GRID+1 },
618 {"record-size", RECORD_SIZE_OPTION, N_("NUMBER"), 0,
619 N_("NUMBER of bytes per record, multiple of 512"), GRID+1 },
620 {"ignore-zeros", 'i', 0, 0,
621 N_("ignore zeroed blocks in archive (means EOF)"), GRID+1 },
622 {"read-full-records", 'B', 0, 0,
623 N_("reblock as we read (for 4.2BSD pipes)"), GRID+1 },
624 #undef GRID
625
626 #define GRID 80
627 {NULL, 0, NULL, 0,
628 N_("Archive format selection:"), GRID },
629
630 {"format", 'H', N_("FORMAT"), 0,
631 N_("create archive of the given format"), GRID+1 },
632
633 {NULL, 0, NULL, 0, N_("FORMAT is one of the following:"), GRID+2 },
634 {" v7", 0, NULL, OPTION_DOC|OPTION_NO_TRANS, N_("old V7 tar format"),
635 GRID+3 },
636 {" oldgnu", 0, NULL, OPTION_DOC|OPTION_NO_TRANS,
637 N_("GNU format as per tar <= 1.12"), GRID+3 },
638 {" gnu", 0, NULL, OPTION_DOC|OPTION_NO_TRANS,
639 N_("GNU tar 1.13.x format"), GRID+3 },
640 {" ustar", 0, NULL, OPTION_DOC|OPTION_NO_TRANS,
641 N_("POSIX 1003.1-1988 (ustar) format"), GRID+3 },
642 {" pax", 0, NULL, OPTION_DOC|OPTION_NO_TRANS,
643 N_("POSIX 1003.1-2001 (pax) format"), GRID+3 },
644 {" posix", 0, NULL, OPTION_DOC|OPTION_NO_TRANS, N_("same as pax"), GRID+3 },
645
646 {"old-archive", OLD_ARCHIVE_OPTION, 0, 0, /* FIXME */
647 N_("same as --format=v7"), GRID+8 },
648 {"portability", 0, 0, OPTION_ALIAS, NULL, GRID+8 },
649 {"posix", POSIX_OPTION, 0, 0,
650 N_("same as --format=posix"), GRID+8 },
651 {"pax-option", PAX_OPTION, N_("keyword[[:]=value][,keyword[[:]=value]]..."), 0,
652 N_("control pax keywords"), GRID+8 },
653 {"label", 'V', N_("TEXT"), 0,
654 N_("create archive with volume name TEXT; at list/extract time, use TEXT as a globbing pattern for volume name"), GRID+8 },
655 #undef GRID
656
657 #define GRID 90
658 {NULL, 0, NULL, 0,
659 N_("Compression options:"), GRID },
660 {"auto-compress", 'a', 0, 0,
661 N_("use archive suffix to determine the compression program"), GRID+1 },
662 {"no-auto-compress", NO_AUTO_COMPRESS_OPTION, 0, 0,
663 N_("do not use archive suffix to determine the compression program"),
664 GRID+1 },
665 {"use-compress-program", 'I', N_("PROG"), 0,
666 N_("filter through PROG (must accept -d)"), GRID+1 },
667 /* Note: docstrings for the options below are generated by tar_help_filter */
668 {"bzip2", 'j', 0, 0, NULL, GRID+1 },
669 {"gzip", 'z', 0, 0, NULL, GRID+1 },
670 {"gunzip", 0, 0, OPTION_ALIAS, NULL, GRID+1 },
671 {"ungzip", 0, 0, OPTION_ALIAS, NULL, GRID+1 },
672 {"compress", 'Z', 0, 0, NULL, GRID+1 },
673 {"uncompress", 0, 0, OPTION_ALIAS, NULL, GRID+1 },
674 {"lzip", LZIP_OPTION, 0, 0, NULL, GRID+1 },
675 {"lzma", LZMA_OPTION, 0, 0, NULL, GRID+1 },
676 {"lzop", LZOP_OPTION, 0, 0, NULL, GRID+1 },
677 {"xz", 'J', 0, 0, NULL, GRID+1 },
678 #undef GRID
679
680 #define GRID 100
681 {NULL, 0, NULL, 0,
682 N_("Local file selection:"), GRID },
683
684 {"add-file", ARGP_KEY_ARG, N_("FILE"), 0,
685 N_("add given FILE to the archive (useful if its name starts with a dash)"), GRID+1 },
686 {"directory", 'C', N_("DIR"), 0,
687 N_("change to directory DIR"), GRID+1 },
688 {"files-from", 'T', N_("FILE"), 0,
689 N_("get names to extract or create from FILE"), GRID+1 },
690 {"null", NULL_OPTION, 0, 0,
691 N_("-T reads null-terminated names, disable -C"), GRID+1 },
692 {"no-null", NO_NULL_OPTION, 0, 0,
693 N_("disable the effect of the previous --null option"), GRID+1 },
694 {"unquote", UNQUOTE_OPTION, 0, 0,
695 N_("unquote filenames read with -T (default)"), GRID+1 },
696 {"no-unquote", NO_UNQUOTE_OPTION, 0, 0,
697 N_("do not unquote filenames read with -T"), GRID+1 },
698 {"exclude", EXCLUDE_OPTION, N_("PATTERN"), 0,
699 N_("exclude files, given as a PATTERN"), GRID+1 },
700 {"exclude-from", 'X', N_("FILE"), 0,
701 N_("exclude patterns listed in FILE"), GRID+1 },
702 {"exclude-caches", EXCLUDE_CACHES_OPTION, 0, 0,
703 N_("exclude contents of directories containing CACHEDIR.TAG, "
704 "except for the tag file itself"), GRID+1 },
705 {"exclude-caches-under", EXCLUDE_CACHES_UNDER_OPTION, 0, 0,
706 N_("exclude everything under directories containing CACHEDIR.TAG"),
707 GRID+1 },
708 {"exclude-caches-all", EXCLUDE_CACHES_ALL_OPTION, 0, 0,
709 N_("exclude directories containing CACHEDIR.TAG"), GRID+1 },
710 {"exclude-tag", EXCLUDE_TAG_OPTION, N_("FILE"), 0,
711 N_("exclude contents of directories containing FILE, except"
712 " for FILE itself"), GRID+1 },
713 {"exclude-tag-under", EXCLUDE_TAG_UNDER_OPTION, N_("FILE"), 0,
714 N_("exclude everything under directories containing FILE"), GRID+1 },
715 {"exclude-tag-all", EXCLUDE_TAG_ALL_OPTION, N_("FILE"), 0,
716 N_("exclude directories containing FILE"), GRID+1 },
717 {"exclude-vcs", EXCLUDE_VCS_OPTION, NULL, 0,
718 N_("exclude version control system directories"), GRID+1 },
719 {"exclude-backups", EXCLUDE_BACKUPS_OPTION, NULL, 0,
720 N_("exclude backup and lock files"), GRID+1 },
721 {"no-recursion", NO_RECURSION_OPTION, 0, 0,
722 N_("avoid descending automatically in directories"), GRID+1 },
723 {"one-file-system", ONE_FILE_SYSTEM_OPTION, 0, 0,
724 N_("stay in local file system when creating archive"), GRID+1 },
725 {"recursion", RECURSION_OPTION, 0, 0,
726 N_("recurse into directories (default)"), GRID+1 },
727 {"absolute-names", 'P', 0, 0,
728 N_("don't strip leading '/'s from file names"), GRID+1 },
729 {"dereference", 'h', 0, 0,
730 N_("follow symlinks; archive and dump the files they point to"), GRID+1 },
731 {"hard-dereference", HARD_DEREFERENCE_OPTION, 0, 0,
732 N_("follow hard links; archive and dump the files they refer to"), GRID+1 },
733 {"starting-file", 'K', N_("MEMBER-NAME"), 0,
734 N_("begin at member MEMBER-NAME in the archive"), GRID+1 },
735 {"newer", 'N', N_("DATE-OR-FILE"), 0,
736 N_("only store files newer than DATE-OR-FILE"), GRID+1 },
737 {"after-date", 0, 0, OPTION_ALIAS, NULL, GRID+1 },
738 {"newer-mtime", NEWER_MTIME_OPTION, N_("DATE"), 0,
739 N_("compare date and time when data changed only"), GRID+1 },
740 {"backup", BACKUP_OPTION, N_("CONTROL"), OPTION_ARG_OPTIONAL,
741 N_("backup before removal, choose version CONTROL"), GRID+1 },
742 {"suffix", SUFFIX_OPTION, N_("STRING"), 0,
743 N_("backup before removal, override usual suffix ('~' unless overridden by environment variable SIMPLE_BACKUP_SUFFIX)"), GRID+1 },
744 #undef GRID
745
746 #define GRID 110
747 {NULL, 0, NULL, 0,
748 N_("File name transformations:"), GRID },
749 {"strip-components", STRIP_COMPONENTS_OPTION, N_("NUMBER"), 0,
750 N_("strip NUMBER leading components from file names on extraction"),
751 GRID+1 },
752 {"transform", TRANSFORM_OPTION, N_("EXPRESSION"), 0,
753 N_("use sed replace EXPRESSION to transform file names"), GRID+1 },
754 {"xform", 0, 0, OPTION_ALIAS, NULL, GRID+1 },
755 #undef GRID
756
757 #define GRID 120
758 {NULL, 0, NULL, 0,
759 N_("File name matching options (affect both exclude and include patterns):"),
760 GRID },
761 {"ignore-case", IGNORE_CASE_OPTION, 0, 0,
762 N_("ignore case"), GRID+1 },
763 {"anchored", ANCHORED_OPTION, 0, 0,
764 N_("patterns match file name start"), GRID+1 },
765 {"no-anchored", NO_ANCHORED_OPTION, 0, 0,
766 N_("patterns match after any '/' (default for exclusion)"), GRID+1 },
767 {"no-ignore-case", NO_IGNORE_CASE_OPTION, 0, 0,
768 N_("case sensitive matching (default)"), GRID+1 },
769 {"wildcards", WILDCARDS_OPTION, 0, 0,
770 N_("use wildcards (default for exclusion)"), GRID+1 },
771 {"no-wildcards", NO_WILDCARDS_OPTION, 0, 0,
772 N_("verbatim string matching"), GRID+1 },
773 {"no-wildcards-match-slash", NO_WILDCARDS_MATCH_SLASH_OPTION, 0, 0,
774 N_("wildcards do not match '/'"), GRID+1 },
775 {"wildcards-match-slash", WILDCARDS_MATCH_SLASH_OPTION, 0, 0,
776 N_("wildcards match '/' (default for exclusion)"), GRID+1 },
777 #undef GRID
778
779 #define GRID 130
780 {NULL, 0, NULL, 0,
781 N_("Informative output:"), GRID },
782
783 {"verbose", 'v', 0, 0,
784 N_("verbosely list files processed"), GRID+1 },
785 {"warning", WARNING_OPTION, N_("KEYWORD"), 0,
786 N_("warning control"), GRID+1 },
787 {"checkpoint", CHECKPOINT_OPTION, N_("NUMBER"), OPTION_ARG_OPTIONAL,
788 N_("display progress messages every NUMBERth record (default 10)"),
789 GRID+1 },
790 {"checkpoint-action", CHECKPOINT_ACTION_OPTION, N_("ACTION"), 0,
791 N_("execute ACTION on each checkpoint"),
792 GRID+1 },
793 {"check-links", 'l', 0, 0,
794 N_("print a message if not all links are dumped"), GRID+1 },
795 {"totals", TOTALS_OPTION, N_("SIGNAL"), OPTION_ARG_OPTIONAL,
796 N_("print total bytes after processing the archive; "
797 "with an argument - print total bytes when this SIGNAL is delivered; "
798 "Allowed signals are: SIGHUP, SIGQUIT, SIGINT, SIGUSR1 and SIGUSR2; "
799 "the names without SIG prefix are also accepted"), GRID+1 },
800 {"utc", UTC_OPTION, 0, 0,
801 N_("print file modification times in UTC"), GRID+1 },
802 {"full-time", FULL_TIME_OPTION, 0, 0,
803 N_("print file time to its full resolution"), GRID+1 },
804 {"index-file", INDEX_FILE_OPTION, N_("FILE"), 0,
805 N_("send verbose output to FILE"), GRID+1 },
806 {"block-number", 'R', 0, 0,
807 N_("show block number within archive with each message"), GRID+1 },
808 {"interactive", 'w', 0, 0,
809 N_("ask for confirmation for every action"), GRID+1 },
810 {"confirmation", 0, 0, OPTION_ALIAS, NULL, GRID+1 },
811 {"show-defaults", SHOW_DEFAULTS_OPTION, 0, 0,
812 N_("show tar defaults"), GRID+1 },
813 {"show-snapshot-field-ranges", SHOW_SNAPSHOT_FIELD_RANGES_OPTION, 0, 0,
814 N_("show valid ranges for snapshot-file fields"), GRID+1 },
815 {"show-omitted-dirs", SHOW_OMITTED_DIRS_OPTION, 0, 0,
816 N_("when listing or extracting, list each directory that does not match search criteria"), GRID+1 },
817 {"show-transformed-names", SHOW_TRANSFORMED_NAMES_OPTION, 0, 0,
818 N_("show file or archive names after transformation"),
819 GRID+1 },
820 {"show-stored-names", 0, 0, OPTION_ALIAS, NULL, GRID+1 },
821 {"quoting-style", QUOTING_STYLE_OPTION, N_("STYLE"), 0,
822 N_("set name quoting style; see below for valid STYLE values"), GRID+1 },
823 {"quote-chars", QUOTE_CHARS_OPTION, N_("STRING"), 0,
824 N_("additionally quote characters from STRING"), GRID+1 },
825 {"no-quote-chars", NO_QUOTE_CHARS_OPTION, N_("STRING"), 0,
826 N_("disable quoting for characters from STRING"), GRID+1 },
827 #undef GRID
828
829 #define GRID 140
830 {NULL, 0, NULL, 0,
831 N_("Compatibility options:"), GRID },
832
833 {NULL, 'o', 0, 0,
834 N_("when creating, same as --old-archive; when extracting, same as --no-same-owner"), GRID+1 },
835 #undef GRID
836
837 #define GRID 150
838 {NULL, 0, NULL, 0,
839 N_("Other options:"), GRID },
840
841 {"restrict", RESTRICT_OPTION, 0, 0,
842 N_("disable use of some potentially harmful options"), -1 },
843 #undef GRID
844
845 {0, 0, 0, 0, 0, 0}
846 };
847
848 static char const *const atime_preserve_args[] =
849 {
850 "replace", "system", NULL
851 };
852
853 static enum atime_preserve const atime_preserve_types[] =
854 {
855 replace_atime_preserve, system_atime_preserve
856 };
857
858 /* Make sure atime_preserve_types has as much entries as atime_preserve_args
859 (minus 1 for NULL guard) */
860 ARGMATCH_VERIFY (atime_preserve_args, atime_preserve_types);
861
862 /* Wildcard matching settings */
863 enum wildcards
864 {
865 default_wildcards, /* For exclusion == enable_wildcards,
866 for inclusion == disable_wildcards */
867 disable_wildcards,
868 enable_wildcards
869 };
870
871 struct tar_args /* Variables used during option parsing */
872 {
873 struct textual_date *textual_date; /* Keeps the arguments to --newer-mtime
874 and/or --date option if they are
875 textual dates */
876 enum wildcards wildcards; /* Wildcard settings (--wildcards/
877 --no-wildcards) */
878 int matching_flags; /* exclude_fnmatch options */
879 int include_anchored; /* Pattern anchoring options used for
880 file inclusion */
881 bool o_option; /* True if -o option was given */
882 bool pax_option; /* True if --pax-option was given */
883 char const *backup_suffix_string; /* --suffix option argument */
884 char const *version_control_string; /* --backup option argument */
885 bool input_files; /* True if some input files where given */
886 int compress_autodetect; /* True if compression autodetection should
887 be attempted when creating archives */
888 };
889
890 \f
891 #define MAKE_EXCL_OPTIONS(args) \
892 ((((args)->wildcards != disable_wildcards) ? EXCLUDE_WILDCARDS : 0) \
893 | (args)->matching_flags \
894 | recursion_option)
895
896 #define MAKE_INCL_OPTIONS(args) \
897 ((((args)->wildcards == enable_wildcards) ? EXCLUDE_WILDCARDS : 0) \
898 | (args)->include_anchored \
899 | (args)->matching_flags \
900 | recursion_option)
901
902 static char const * const vcs_file_table[] = {
903 /* CVS: */
904 "CVS",
905 ".cvsignore",
906 /* RCS: */
907 "RCS",
908 /* SCCS: */
909 "SCCS",
910 /* SVN: */
911 ".svn",
912 /* git: */
913 ".git",
914 ".gitignore",
915 /* Arch: */
916 ".arch-ids",
917 "{arch}",
918 "=RELEASE-ID",
919 "=meta-update",
920 "=update",
921 /* Bazaar */
922 ".bzr",
923 ".bzrignore",
924 ".bzrtags",
925 /* Mercurial */
926 ".hg",
927 ".hgignore",
928 ".hgtags",
929 /* darcs */
930 "_darcs",
931 NULL
932 };
933
934 static char const * const backup_file_table[] = {
935 ".#*",
936 "*~",
937 "#*#",
938 NULL
939 };
940
941 static void
942 add_exclude_array (char const * const * fv, int opts)
943 {
944 int i;
945
946 for (i = 0; fv[i]; i++)
947 add_exclude (excluded, fv[i], opts);
948 }
949
950 \f
951 static char *
952 format_default_settings (void)
953 {
954 return xasprintf (
955 "--format=%s -f%s -b%d --quoting-style=%s --rmt-command=%s"
956 #ifdef REMOTE_SHELL
957 " --rsh-command=%s"
958 #endif
959 ,
960 archive_format_string (DEFAULT_ARCHIVE_FORMAT),
961 DEFAULT_ARCHIVE, DEFAULT_BLOCKING,
962 quoting_style_args[DEFAULT_QUOTING_STYLE],
963 DEFAULT_RMT_COMMAND
964 #ifdef REMOTE_SHELL
965 , REMOTE_SHELL
966 #endif
967 );
968 }
969
970 \f
971 static void
972 set_subcommand_option (enum subcommand subcommand)
973 {
974 if (subcommand_option != UNKNOWN_SUBCOMMAND
975 && subcommand_option != subcommand)
976 USAGE_ERROR ((0, 0,
977 _("You may not specify more than one '-Acdtrux', '--delete' or '--test-label' option")));
978
979 subcommand_option = subcommand;
980 }
981
982 static void
983 set_use_compress_program_option (const char *string)
984 {
985 if (use_compress_program_option
986 && strcmp (use_compress_program_option, string) != 0)
987 USAGE_ERROR ((0, 0, _("Conflicting compression options")));
988
989 use_compress_program_option = string;
990 }
991 \f
992 static RETSIGTYPE
993 sigstat (int signo)
994 {
995 compute_duration ();
996 print_total_stats ();
997 #ifndef HAVE_SIGACTION
998 signal (signo, sigstat);
999 #endif
1000 }
1001
1002 static void
1003 stat_on_signal (int signo)
1004 {
1005 #ifdef HAVE_SIGACTION
1006 # ifndef SA_RESTART
1007 # define SA_RESTART 0
1008 # endif
1009 struct sigaction act;
1010 act.sa_handler = sigstat;
1011 sigemptyset (&act.sa_mask);
1012 act.sa_flags = SA_RESTART;
1013 sigaction (signo, &act, NULL);
1014 #else
1015 signal (signo, sigstat);
1016 #endif
1017 }
1018
1019 static void
1020 set_stat_signal (const char *name)
1021 {
1022 static struct sigtab
1023 {
1024 char const *name;
1025 int signo;
1026 } const sigtab[] = {
1027 { "SIGUSR1", SIGUSR1 },
1028 { "USR1", SIGUSR1 },
1029 { "SIGUSR2", SIGUSR2 },
1030 { "USR2", SIGUSR2 },
1031 { "SIGHUP", SIGHUP },
1032 { "HUP", SIGHUP },
1033 { "SIGINT", SIGINT },
1034 { "INT", SIGINT },
1035 { "SIGQUIT", SIGQUIT },
1036 { "QUIT", SIGQUIT }
1037 };
1038 struct sigtab const *p;
1039
1040 for (p = sigtab; p < sigtab + sizeof (sigtab) / sizeof (sigtab[0]); p++)
1041 if (strcmp (p->name, name) == 0)
1042 {
1043 stat_on_signal (p->signo);
1044 return;
1045 }
1046 FATAL_ERROR ((0, 0, _("Unknown signal name: %s"), name));
1047 }
1048
1049 \f
1050 struct textual_date
1051 {
1052 struct textual_date *next;
1053 struct timespec ts;
1054 const char *option;
1055 char *date;
1056 };
1057
1058 static int
1059 get_date_or_file (struct tar_args *args, const char *option,
1060 const char *str, struct timespec *ts)
1061 {
1062 if (FILE_SYSTEM_PREFIX_LEN (str) != 0
1063 || ISSLASH (*str)
1064 || *str == '.')
1065 {
1066 struct stat st;
1067 if (stat (str, &st) != 0)
1068 {
1069 stat_error (str);
1070 USAGE_ERROR ((0, 0, _("Date sample file not found")));
1071 }
1072 *ts = get_stat_mtime (&st);
1073 }
1074 else
1075 {
1076 if (! parse_datetime (ts, str, NULL))
1077 {
1078 WARN ((0, 0, _("Substituting %s for unknown date format %s"),
1079 tartime (*ts, false), quote (str)));
1080 ts->tv_nsec = 0;
1081 return 1;
1082 }
1083 else
1084 {
1085 struct textual_date *p = xmalloc (sizeof (*p));
1086 p->ts = *ts;
1087 p->option = option;
1088 p->date = xstrdup (str);
1089 p->next = args->textual_date;
1090 args->textual_date = p;
1091 }
1092 }
1093 return 0;
1094 }
1095
1096 static void
1097 report_textual_dates (struct tar_args *args)
1098 {
1099 struct textual_date *p;
1100 for (p = args->textual_date; p; )
1101 {
1102 struct textual_date *next = p->next;
1103 if (verbose_option)
1104 {
1105 char const *treated_as = tartime (p->ts, true);
1106 if (strcmp (p->date, treated_as) != 0)
1107 WARN ((0, 0, _("Option %s: Treating date '%s' as %s"),
1108 p->option, p->date, treated_as));
1109 }
1110 free (p->date);
1111 free (p);
1112 p = next;
1113 }
1114 }
1115
1116 \f
1117 static bool files_from_option; /* When set, tar will not refuse to create
1118 empty archives */
1119
1120 /* Default density numbers for [0-9][lmh] device specifications */
1121
1122 #if defined DEVICE_PREFIX && !defined DENSITY_LETTER
1123 # ifndef LOW_DENSITY_NUM
1124 # define LOW_DENSITY_NUM 0
1125 # endif
1126
1127 # ifndef MID_DENSITY_NUM
1128 # define MID_DENSITY_NUM 8
1129 # endif
1130
1131 # ifndef HIGH_DENSITY_NUM
1132 # define HIGH_DENSITY_NUM 16
1133 # endif
1134 #endif
1135
1136 \f
1137 static char *
1138 tar_help_filter (int key, const char *text, void *input)
1139 {
1140 struct obstack stk;
1141 char *s;
1142
1143 switch (key)
1144 {
1145 default:
1146 s = (char*) text;
1147 break;
1148
1149 case 'j':
1150 s = xasprintf (_("filter the archive through %s"), BZIP2_PROGRAM);
1151 break;
1152
1153 case 'z':
1154 s = xasprintf (_("filter the archive through %s"), GZIP_PROGRAM);
1155 break;
1156
1157 case 'Z':
1158 s = xasprintf (_("filter the archive through %s"), COMPRESS_PROGRAM);
1159 break;
1160
1161 case LZIP_OPTION:
1162 s = xasprintf (_("filter the archive through %s"), LZIP_PROGRAM);
1163 break;
1164
1165 case LZMA_OPTION:
1166 s = xasprintf (_("filter the archive through %s"), LZMA_PROGRAM);
1167 break;
1168
1169 case 'J':
1170 s = xasprintf (_("filter the archive through %s"), XZ_PROGRAM);
1171 break;
1172
1173 case ARGP_KEY_HELP_EXTRA:
1174 {
1175 const char *tstr;
1176
1177 obstack_init (&stk);
1178 tstr = _("Valid arguments for the --quoting-style option are:");
1179 obstack_grow (&stk, tstr, strlen (tstr));
1180 obstack_grow (&stk, "\n\n", 2);
1181 tar_list_quoting_styles (&stk, " ");
1182 tstr = _("\n*This* tar defaults to:\n");
1183 obstack_grow (&stk, tstr, strlen (tstr));
1184 s = format_default_settings ();
1185 obstack_grow (&stk, s, strlen (s));
1186 obstack_1grow (&stk, '\n');
1187 obstack_1grow (&stk, 0);
1188 s = xstrdup (obstack_finish (&stk));
1189 obstack_free (&stk, NULL);
1190 }
1191 }
1192 return s;
1193 }
1194 \f
1195 static char *
1196 expand_pax_option (struct tar_args *targs, const char *arg)
1197 {
1198 struct obstack stk;
1199 char *res;
1200
1201 obstack_init (&stk);
1202 while (*arg)
1203 {
1204 size_t seglen = strcspn (arg, ",");
1205 char *p = memchr (arg, '=', seglen);
1206 if (p)
1207 {
1208 size_t len = p - arg + 1;
1209 obstack_grow (&stk, arg, len);
1210 len = seglen - len;
1211 for (++p; *p && isspace ((unsigned char) *p); p++)
1212 len--;
1213 if (*p == '{' && p[len-1] == '}')
1214 {
1215 struct timespec ts;
1216 char *tmp = xmalloc (len);
1217 memcpy (tmp, p + 1, len-2);
1218 tmp[len-2] = 0;
1219 if (get_date_or_file (targs, "--pax-option", tmp, &ts) == 0)
1220 {
1221 char buf[TIMESPEC_STRSIZE_BOUND];
1222 char const *s = code_timespec (ts, buf);
1223 obstack_grow (&stk, s, strlen (s));
1224 }
1225 else
1226 obstack_grow (&stk, p, len);
1227 free (tmp);
1228 }
1229 else
1230 obstack_grow (&stk, p, len);
1231 }
1232 else
1233 obstack_grow (&stk, arg, seglen);
1234
1235 arg += seglen;
1236 if (*arg)
1237 {
1238 obstack_1grow (&stk, *arg);
1239 arg++;
1240 }
1241 }
1242 obstack_1grow (&stk, 0);
1243 res = xstrdup (obstack_finish (&stk));
1244 obstack_free (&stk, NULL);
1245 return res;
1246 }
1247
1248 \f
1249 static uintmax_t
1250 parse_owner_group (char *arg, uintmax_t field_max, char const **name_option)
1251 {
1252 uintmax_t u = UINTMAX_MAX;
1253 char *end;
1254 char const *name = 0;
1255 char const *invalid_num = 0;
1256 char *colon = strchr (arg, ':');
1257
1258 if (colon)
1259 {
1260 char const *num = colon + 1;
1261 *colon = '\0';
1262 if (*arg)
1263 name = arg;
1264 if (num && (! (xstrtoumax (num, &end, 10, &u, "") == LONGINT_OK
1265 && u <= field_max)))
1266 invalid_num = num;
1267 }
1268 else
1269 {
1270 uintmax_t u1;
1271 switch ('0' <= *arg && *arg <= '9'
1272 ? xstrtoumax (arg, &end, 10, &u1, "")
1273 : LONGINT_INVALID)
1274 {
1275 default:
1276 name = arg;
1277 break;
1278
1279 case LONGINT_OK:
1280 if (u1 <= field_max)
1281 {
1282 u = u1;
1283 break;
1284 }
1285 /* Fall through. */
1286 case LONGINT_OVERFLOW:
1287 invalid_num = arg;
1288 break;
1289 }
1290 }
1291
1292 if (invalid_num)
1293 FATAL_ERROR ((0, 0, "%s: %s", quotearg_colon (invalid_num),
1294 _("Invalid owner or group ID")));
1295 if (name)
1296 *name_option = name;
1297 return u;
1298 }
1299
1300 #define TAR_SIZE_SUFFIXES "bBcGgkKMmPTtw"
1301
1302 /* Either NL or NUL, as decided by the --null option. */
1303 static char filename_terminator;
1304
1305 static error_t
1306 parse_opt (int key, char *arg, struct argp_state *state)
1307 {
1308 struct tar_args *args = state->input;
1309
1310 switch (key)
1311 {
1312 case ARGP_KEY_ARG:
1313 /* File name or non-parsed option, because of ARGP_IN_ORDER */
1314 name_add_name (arg, MAKE_INCL_OPTIONS (args));
1315 args->input_files = true;
1316 break;
1317
1318 case 'A':
1319 set_subcommand_option (CAT_SUBCOMMAND);
1320 break;
1321
1322 case 'a':
1323 args->compress_autodetect = true;
1324 break;
1325
1326 case NO_AUTO_COMPRESS_OPTION:
1327 args->compress_autodetect = false;
1328 break;
1329
1330 case 'b':
1331 {
1332 uintmax_t u;
1333 if (! (xstrtoumax (arg, 0, 10, &u, "") == LONGINT_OK
1334 && u == (blocking_factor = u)
1335 && 0 < blocking_factor
1336 && u == (record_size = u * BLOCKSIZE) / BLOCKSIZE))
1337 USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (arg),
1338 _("Invalid blocking factor")));
1339 }
1340 break;
1341
1342 case 'B':
1343 /* Try to reblock input records. For reading 4.2BSD pipes. */
1344
1345 /* It would surely make sense to exchange -B and -R, but it seems
1346 that -B has been used for a long while in Sun tar and most
1347 BSD-derived systems. This is a consequence of the block/record
1348 terminology confusion. */
1349
1350 read_full_records_option = true;
1351 break;
1352
1353 case 'c':
1354 set_subcommand_option (CREATE_SUBCOMMAND);
1355 break;
1356
1357 case 'C':
1358 name_add_dir (arg);
1359 break;
1360
1361 case 'd':
1362 set_subcommand_option (DIFF_SUBCOMMAND);
1363 break;
1364
1365 case 'f':
1366 if (archive_names == allocated_archive_names)
1367 archive_name_array = x2nrealloc (archive_name_array,
1368 &allocated_archive_names,
1369 sizeof (archive_name_array[0]));
1370
1371 archive_name_array[archive_names++] = arg;
1372 break;
1373
1374 case 'F':
1375 /* Since -F is only useful with -M, make it implied. Run this
1376 script at the end of each tape. */
1377
1378 info_script_option = arg;
1379 multi_volume_option = true;
1380 break;
1381
1382 case FULL_TIME_OPTION:
1383 full_time_option = true;
1384 break;
1385
1386 case 'g':
1387 listed_incremental_option = arg;
1388 after_date_option = true;
1389 /* Fall through. */
1390
1391 case 'G':
1392 /* We are making an incremental dump (FIXME: are we?); save
1393 directories at the beginning of the archive, and include in each
1394 directory its contents. */
1395
1396 incremental_option = true;
1397 break;
1398
1399 case 'h':
1400 /* Follow symbolic links. */
1401 dereference_option = true;
1402 break;
1403
1404 case HARD_DEREFERENCE_OPTION:
1405 hard_dereference_option = true;
1406 break;
1407
1408 case 'i':
1409 /* Ignore zero blocks (eofs). This can't be the default,
1410 because Unix tar writes two blocks of zeros, then pads out
1411 the record with garbage. */
1412
1413 ignore_zeros_option = true;
1414 break;
1415
1416 case 'j':
1417 set_use_compress_program_option (BZIP2_PROGRAM);
1418 break;
1419
1420 case 'J':
1421 set_use_compress_program_option (XZ_PROGRAM);
1422 break;
1423
1424 case 'k':
1425 /* Don't replace existing files. */
1426 old_files_option = KEEP_OLD_FILES;
1427 break;
1428
1429 case 'K':
1430 starting_file_option = true;
1431 addname (arg, 0, true, NULL);
1432 break;
1433
1434 case ONE_FILE_SYSTEM_OPTION:
1435 /* When dumping directories, don't dump files/subdirectories
1436 that are on other filesystems. */
1437 one_file_system_option = true;
1438 break;
1439
1440 case 'l':
1441 check_links_option = 1;
1442 break;
1443
1444 case 'L':
1445 {
1446 uintmax_t u;
1447 char *p;
1448
1449 if (xstrtoumax (arg, &p, 10, &u, TAR_SIZE_SUFFIXES) != LONGINT_OK)
1450 USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (arg),
1451 _("Invalid tape length")));
1452 if (p > arg && !strchr (TAR_SIZE_SUFFIXES, p[-1]))
1453 tape_length_option = 1024 * (tarlong) u;
1454 else
1455 tape_length_option = (tarlong) u;
1456 multi_volume_option = true;
1457 }
1458 break;
1459
1460 case LEVEL_OPTION:
1461 {
1462 char *p;
1463 incremental_level = strtoul (arg, &p, 10);
1464 if (*p)
1465 USAGE_ERROR ((0, 0, _("Invalid incremental level value")));
1466 }
1467 break;
1468
1469 case LZIP_OPTION:
1470 set_use_compress_program_option (LZIP_PROGRAM);
1471 break;
1472
1473 case LZMA_OPTION:
1474 set_use_compress_program_option (LZMA_PROGRAM);
1475 break;
1476
1477 case LZOP_OPTION:
1478 set_use_compress_program_option (LZOP_PROGRAM);
1479 break;
1480
1481 case 'm':
1482 touch_option = true;
1483 break;
1484
1485 case 'M':
1486 /* Make multivolume archive: when we can't write any more into
1487 the archive, re-open it, and continue writing. */
1488
1489 multi_volume_option = true;
1490 break;
1491
1492 case MTIME_OPTION:
1493 get_date_or_file (args, "--mtime", arg, &mtime_option);
1494 set_mtime_option = true;
1495 break;
1496
1497 case 'n':
1498 seek_option = 1;
1499 break;
1500
1501 case NO_SEEK_OPTION:
1502 seek_option = 0;
1503 break;
1504
1505 case 'N':
1506 after_date_option = true;
1507 /* Fall through. */
1508
1509 case NEWER_MTIME_OPTION:
1510 if (NEWER_OPTION_INITIALIZED (newer_mtime_option))
1511 USAGE_ERROR ((0, 0, _("More than one threshold date")));
1512 get_date_or_file (args,
1513 key == NEWER_MTIME_OPTION ? "--newer-mtime"
1514 : "--after-date", arg, &newer_mtime_option);
1515 break;
1516
1517 case 'o':
1518 args->o_option = true;
1519 break;
1520
1521 case 'O':
1522 to_stdout_option = true;
1523 break;
1524
1525 case 'p':
1526 same_permissions_option = true;
1527 break;
1528
1529 case 'P':
1530 absolute_names_option = true;
1531 break;
1532
1533 case 'r':
1534 set_subcommand_option (APPEND_SUBCOMMAND);
1535 break;
1536
1537 case 'R':
1538 /* Print block numbers for debugging bad tar archives. */
1539
1540 /* It would surely make sense to exchange -B and -R, but it seems
1541 that -B has been used for a long while in Sun tar and most
1542 BSD-derived systems. This is a consequence of the block/record
1543 terminology confusion. */
1544
1545 block_number_option = true;
1546 break;
1547
1548 case 's':
1549 /* Names to extract are sorted. */
1550
1551 same_order_option = true;
1552 break;
1553
1554 case 'S':
1555 sparse_option = true;
1556 break;
1557
1558 case SKIP_OLD_FILES_OPTION:
1559 old_files_option = SKIP_OLD_FILES;
1560 break;
1561
1562 case SPARSE_VERSION_OPTION:
1563 sparse_option = true;
1564 {
1565 char *p;
1566 tar_sparse_major = strtoul (arg, &p, 10);
1567 if (*p)
1568 {
1569 if (*p != '.')
1570 USAGE_ERROR ((0, 0, _("Invalid sparse version value")));
1571 tar_sparse_minor = strtoul (p + 1, &p, 10);
1572 if (*p)
1573 USAGE_ERROR ((0, 0, _("Invalid sparse version value")));
1574 }
1575 }
1576 break;
1577
1578 case 't':
1579 set_subcommand_option (LIST_SUBCOMMAND);
1580 verbose_option++;
1581 break;
1582
1583 case TEST_LABEL_OPTION:
1584 set_subcommand_option (TEST_LABEL_SUBCOMMAND);
1585 break;
1586
1587 case 'T':
1588 name_add_file (arg, filename_terminator);
1589 /* Indicate we've been given -T option. This is for backward
1590 compatibility only, so that `tar cfT archive /dev/null will
1591 succeed */
1592 files_from_option = true;
1593 break;
1594
1595 case 'u':
1596 set_subcommand_option (UPDATE_SUBCOMMAND);
1597 break;
1598
1599 case 'U':
1600 old_files_option = UNLINK_FIRST_OLD_FILES;
1601 break;
1602
1603 case UTC_OPTION:
1604 utc_option = true;
1605 break;
1606
1607 case 'v':
1608 verbose_option++;
1609 warning_option |= WARN_VERBOSE_WARNINGS;
1610 break;
1611
1612 case 'V':
1613 volume_label_option = arg;
1614 break;
1615
1616 case 'w':
1617 interactive_option = true;
1618 break;
1619
1620 case 'W':
1621 verify_option = true;
1622 break;
1623
1624 case 'x':
1625 set_subcommand_option (EXTRACT_SUBCOMMAND);
1626 break;
1627
1628 case 'X':
1629 if (add_exclude_file (add_exclude, excluded, arg,
1630 MAKE_EXCL_OPTIONS (args), '\n')
1631 != 0)
1632 {
1633 int e = errno;
1634 FATAL_ERROR ((0, e, "%s", quotearg_colon (arg)));
1635 }
1636 break;
1637
1638 case 'z':
1639 set_use_compress_program_option (GZIP_PROGRAM);
1640 break;
1641
1642 case 'Z':
1643 set_use_compress_program_option (COMPRESS_PROGRAM);
1644 break;
1645
1646 case ANCHORED_OPTION:
1647 args->matching_flags |= EXCLUDE_ANCHORED;
1648 break;
1649
1650 case ATIME_PRESERVE_OPTION:
1651 atime_preserve_option =
1652 (arg
1653 ? XARGMATCH ("--atime-preserve", arg,
1654 atime_preserve_args, atime_preserve_types)
1655 : replace_atime_preserve);
1656 if (! O_NOATIME && atime_preserve_option == system_atime_preserve)
1657 FATAL_ERROR ((0, 0,
1658 _("--atime-preserve='system' is not supported"
1659 " on this platform")));
1660 break;
1661
1662 case CHECK_DEVICE_OPTION:
1663 check_device_option = true;
1664 break;
1665
1666 case NO_CHECK_DEVICE_OPTION:
1667 check_device_option = false;
1668 break;
1669
1670 case CHECKPOINT_OPTION:
1671 if (arg)
1672 {
1673 char *p;
1674
1675 if (*arg == '.')
1676 {
1677 checkpoint_compile_action (".");
1678 arg++;
1679 }
1680 checkpoint_option = strtoul (arg, &p, 0);
1681 if (*p)
1682 FATAL_ERROR ((0, 0,
1683 _("--checkpoint value is not an integer")));
1684 }
1685 else
1686 checkpoint_option = DEFAULT_CHECKPOINT;
1687 break;
1688
1689 case CHECKPOINT_ACTION_OPTION:
1690 checkpoint_compile_action (arg);
1691 break;
1692
1693 case BACKUP_OPTION:
1694 backup_option = true;
1695 if (arg)
1696 args->version_control_string = arg;
1697 break;
1698
1699 case DELAY_DIRECTORY_RESTORE_OPTION:
1700 delay_directory_restore_option = true;
1701 break;
1702
1703 case NO_DELAY_DIRECTORY_RESTORE_OPTION:
1704 delay_directory_restore_option = false;
1705 break;
1706
1707 case DELETE_OPTION:
1708 set_subcommand_option (DELETE_SUBCOMMAND);
1709 break;
1710
1711 case EXCLUDE_BACKUPS_OPTION:
1712 add_exclude_array (backup_file_table, EXCLUDE_WILDCARDS);
1713 break;
1714
1715 case EXCLUDE_OPTION:
1716 add_exclude (excluded, arg, MAKE_EXCL_OPTIONS (args));
1717 break;
1718
1719 case EXCLUDE_CACHES_OPTION:
1720 add_exclusion_tag ("CACHEDIR.TAG", exclusion_tag_contents,
1721 cachedir_file_p);
1722 break;
1723
1724 case EXCLUDE_CACHES_UNDER_OPTION:
1725 add_exclusion_tag ("CACHEDIR.TAG", exclusion_tag_under,
1726 cachedir_file_p);
1727 break;
1728
1729 case EXCLUDE_CACHES_ALL_OPTION:
1730 add_exclusion_tag ("CACHEDIR.TAG", exclusion_tag_all,
1731 cachedir_file_p);
1732 break;
1733
1734 case EXCLUDE_TAG_OPTION:
1735 add_exclusion_tag (arg, exclusion_tag_contents, NULL);
1736 break;
1737
1738 case EXCLUDE_TAG_UNDER_OPTION:
1739 add_exclusion_tag (arg, exclusion_tag_under, NULL);
1740 break;
1741
1742 case EXCLUDE_TAG_ALL_OPTION:
1743 add_exclusion_tag (arg, exclusion_tag_all, NULL);
1744 break;
1745
1746 case EXCLUDE_VCS_OPTION:
1747 add_exclude_array (vcs_file_table, 0);
1748 break;
1749
1750 case FORCE_LOCAL_OPTION:
1751 force_local_option = true;
1752 break;
1753
1754 case 'H':
1755 set_archive_format (arg);
1756 break;
1757
1758 case INDEX_FILE_OPTION:
1759 index_file_name = arg;
1760 break;
1761
1762 case IGNORE_CASE_OPTION:
1763 args->matching_flags |= FNM_CASEFOLD;
1764 break;
1765
1766 case IGNORE_COMMAND_ERROR_OPTION:
1767 ignore_command_error_option = true;
1768 break;
1769
1770 case IGNORE_FAILED_READ_OPTION:
1771 ignore_failed_read_option = true;
1772 break;
1773
1774 case KEEP_DIRECTORY_SYMLINK_OPTION:
1775 keep_directory_symlink_option = true;
1776 break;
1777
1778 case KEEP_NEWER_FILES_OPTION:
1779 old_files_option = KEEP_NEWER_FILES;
1780 break;
1781
1782 case GROUP_OPTION:
1783 {
1784 uintmax_t u = parse_owner_group (arg, TYPE_MAXIMUM (gid_t),
1785 &group_name_option);
1786 if (u == UINTMAX_MAX)
1787 {
1788 group_option = -1;
1789 if (group_name_option)
1790 gname_to_gid (group_name_option, &group_option);
1791 }
1792 else
1793 group_option = u;
1794 }
1795 break;
1796
1797 case MODE_OPTION:
1798 mode_option = mode_compile (arg);
1799 if (!mode_option)
1800 FATAL_ERROR ((0, 0, _("Invalid mode given on option")));
1801 initial_umask = umask (0);
1802 umask (initial_umask);
1803 break;
1804
1805 case NO_ANCHORED_OPTION:
1806 args->include_anchored = 0; /* Clear the default for comman line args */
1807 args->matching_flags &= ~ EXCLUDE_ANCHORED;
1808 break;
1809
1810 case NO_IGNORE_CASE_OPTION:
1811 args->matching_flags &= ~ FNM_CASEFOLD;
1812 break;
1813
1814 case NO_IGNORE_COMMAND_ERROR_OPTION:
1815 ignore_command_error_option = false;
1816 break;
1817
1818 case NO_OVERWRITE_DIR_OPTION:
1819 old_files_option = NO_OVERWRITE_DIR_OLD_FILES;
1820 break;
1821
1822 case NO_QUOTE_CHARS_OPTION:
1823 for (;*arg; arg++)
1824 set_char_quoting (NULL, *arg, 0);
1825 break;
1826
1827 case NO_WILDCARDS_OPTION:
1828 args->wildcards = disable_wildcards;
1829 break;
1830
1831 case NO_WILDCARDS_MATCH_SLASH_OPTION:
1832 args->matching_flags |= FNM_FILE_NAME;
1833 break;
1834
1835 case NULL_OPTION:
1836 filename_terminator = '\0';
1837 break;
1838
1839 case NO_NULL_OPTION:
1840 filename_terminator = '\n';
1841 break;
1842
1843 case NUMERIC_OWNER_OPTION:
1844 numeric_owner_option = true;
1845 break;
1846
1847 case OCCURRENCE_OPTION:
1848 if (!arg)
1849 occurrence_option = 1;
1850 else
1851 {
1852 uintmax_t u;
1853 if (xstrtoumax (arg, 0, 10, &u, "") == LONGINT_OK)
1854 occurrence_option = u;
1855 else
1856 FATAL_ERROR ((0, 0, "%s: %s", quotearg_colon (arg),
1857 _("Invalid number")));
1858 }
1859 break;
1860
1861 case OLD_ARCHIVE_OPTION:
1862 set_archive_format ("v7");
1863 break;
1864
1865 case OVERWRITE_DIR_OPTION:
1866 old_files_option = DEFAULT_OLD_FILES;
1867 break;
1868
1869 case OVERWRITE_OPTION:
1870 old_files_option = OVERWRITE_OLD_FILES;
1871 break;
1872
1873 case OWNER_OPTION:
1874 {
1875 uintmax_t u = parse_owner_group (arg, TYPE_MAXIMUM (uid_t),
1876 &owner_name_option);
1877 if (u == UINTMAX_MAX)
1878 {
1879 owner_option = -1;
1880 if (owner_name_option)
1881 uname_to_uid (owner_name_option, &owner_option);
1882 }
1883 else
1884 owner_option = u;
1885 }
1886 break;
1887
1888 case QUOTE_CHARS_OPTION:
1889 for (;*arg; arg++)
1890 set_char_quoting (NULL, *arg, 1);
1891 break;
1892
1893 case QUOTING_STYLE_OPTION:
1894 tar_set_quoting_style (arg);
1895 break;
1896
1897 case PAX_OPTION:
1898 {
1899 char *tmp = expand_pax_option (args, arg);
1900 args->pax_option = true;
1901 xheader_set_option (tmp);
1902 free (tmp);
1903 }
1904 break;
1905
1906 case POSIX_OPTION:
1907 set_archive_format ("posix");
1908 break;
1909
1910 case PRESERVE_OPTION:
1911 /* FIXME: What it is good for? */
1912 same_permissions_option = true;
1913 same_order_option = true;
1914 WARN ((0, 0, _("The --preserve option is deprecated, "
1915 "use --preserve-permissions --preserve-order instead")));
1916 break;
1917
1918 case RECORD_SIZE_OPTION:
1919 {
1920 uintmax_t u;
1921
1922 if (! (xstrtoumax (arg, NULL, 10, &u, TAR_SIZE_SUFFIXES) == LONGINT_OK
1923 && u == (size_t) u))
1924 USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (arg),
1925 _("Invalid record size")));
1926 record_size = u;
1927 if (record_size % BLOCKSIZE != 0)
1928 USAGE_ERROR ((0, 0, _("Record size must be a multiple of %d."),
1929 BLOCKSIZE));
1930 blocking_factor = record_size / BLOCKSIZE;
1931 }
1932 break;
1933
1934 case RECURSIVE_UNLINK_OPTION:
1935 recursive_unlink_option = true;
1936 break;
1937
1938 case REMOVE_FILES_OPTION:
1939 remove_files_option = true;
1940 break;
1941
1942 case RESTRICT_OPTION:
1943 restrict_option = true;
1944 break;
1945
1946 case RMT_COMMAND_OPTION:
1947 rmt_command = arg;
1948 break;
1949
1950 case RSH_COMMAND_OPTION:
1951 rsh_command_option = arg;
1952 break;
1953
1954 case SHOW_DEFAULTS_OPTION:
1955 {
1956 char *s = format_default_settings ();
1957 printf ("%s\n", s);
1958 close_stdout ();
1959 free (s);
1960 exit (0);
1961 }
1962
1963 case SHOW_SNAPSHOT_FIELD_RANGES_OPTION:
1964 show_snapshot_field_ranges ();
1965 close_stdout ();
1966 exit (0);
1967
1968 case STRIP_COMPONENTS_OPTION:
1969 {
1970 uintmax_t u;
1971 if (! (xstrtoumax (arg, 0, 10, &u, "") == LONGINT_OK
1972 && u == (size_t) u))
1973 USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (arg),
1974 _("Invalid number of elements")));
1975 strip_name_components = u;
1976 }
1977 break;
1978
1979 case SHOW_OMITTED_DIRS_OPTION:
1980 show_omitted_dirs_option = true;
1981 break;
1982
1983 case SHOW_TRANSFORMED_NAMES_OPTION:
1984 show_transformed_names_option = true;
1985 break;
1986
1987 case SUFFIX_OPTION:
1988 backup_option = true;
1989 args->backup_suffix_string = arg;
1990 break;
1991
1992 case TO_COMMAND_OPTION:
1993 if (to_command_option)
1994 USAGE_ERROR ((0, 0, _("Only one --to-command option allowed")));
1995 to_command_option = arg;
1996 break;
1997
1998 case TOTALS_OPTION:
1999 if (arg)
2000 set_stat_signal (arg);
2001 else
2002 totals_option = true;
2003 break;
2004
2005 case TRANSFORM_OPTION:
2006 set_transform_expr (arg);
2007 break;
2008
2009 case 'I':
2010 set_use_compress_program_option (arg);
2011 break;
2012
2013 case VOLNO_FILE_OPTION:
2014 volno_file_option = arg;
2015 break;
2016
2017 case WILDCARDS_OPTION:
2018 args->wildcards = enable_wildcards;
2019 break;
2020
2021 case WILDCARDS_MATCH_SLASH_OPTION:
2022 args->matching_flags &= ~ FNM_FILE_NAME;
2023 break;
2024
2025 case NO_RECURSION_OPTION:
2026 recursion_option = 0;
2027 break;
2028
2029 case NO_SAME_OWNER_OPTION:
2030 same_owner_option = -1;
2031 break;
2032
2033 case NO_SAME_PERMISSIONS_OPTION:
2034 same_permissions_option = -1;
2035 break;
2036
2037 case ACLS_OPTION:
2038 set_archive_format ("posix");
2039 acls_option = 1;
2040 break;
2041
2042 case NO_ACLS_OPTION:
2043 acls_option = -1;
2044 break;
2045
2046 case SELINUX_CONTEXT_OPTION:
2047 set_archive_format ("posix");
2048 selinux_context_option = 1;
2049 break;
2050
2051 case NO_SELINUX_CONTEXT_OPTION:
2052 selinux_context_option = -1;
2053 break;
2054
2055 case XATTR_OPTION:
2056 set_archive_format ("posix");
2057 xattrs_option = 1;
2058 break;
2059
2060 case NO_XATTR_OPTION:
2061 xattrs_option = -1;
2062 break;
2063
2064 case XATTR_INCLUDE:
2065 case XATTR_EXCLUDE:
2066 xattrs_mask_add (arg, (key == XATTR_INCLUDE));
2067 break;
2068
2069 case RECURSION_OPTION:
2070 recursion_option = FNM_LEADING_DIR;
2071 break;
2072
2073 case SAME_OWNER_OPTION:
2074 same_owner_option = 1;
2075 break;
2076
2077 case UNQUOTE_OPTION:
2078 unquote_option = true;
2079 break;
2080
2081 case NO_UNQUOTE_OPTION:
2082 unquote_option = false;
2083 break;
2084
2085 case WARNING_OPTION:
2086 set_warning_option (arg);
2087 break;
2088
2089 case '0':
2090 case '1':
2091 case '2':
2092 case '3':
2093 case '4':
2094 case '5':
2095 case '6':
2096 case '7':
2097
2098 #ifdef DEVICE_PREFIX
2099 {
2100 int device = key - '0';
2101 int density;
2102 static char buf[sizeof DEVICE_PREFIX + 10];
2103 char *cursor;
2104
2105 if (arg[1])
2106 argp_error (state, _("Malformed density argument: %s"), quote (arg));
2107
2108 strcpy (buf, DEVICE_PREFIX);
2109 cursor = buf + strlen (buf);
2110
2111 #ifdef DENSITY_LETTER
2112
2113 sprintf (cursor, "%d%c", device, arg[0]);
2114
2115 #else /* not DENSITY_LETTER */
2116
2117 switch (arg[0])
2118 {
2119 case 'l':
2120 device += LOW_DENSITY_NUM;
2121 break;
2122
2123 case 'm':
2124 device += MID_DENSITY_NUM;
2125 break;
2126
2127 case 'h':
2128 device += HIGH_DENSITY_NUM;
2129 break;
2130
2131 default:
2132 argp_error (state, _("Unknown density: '%c'"), arg[0]);
2133 }
2134 sprintf (cursor, "%d", device);
2135
2136 #endif /* not DENSITY_LETTER */
2137
2138 if (archive_names == allocated_archive_names)
2139 archive_name_array = x2nrealloc (archive_name_array,
2140 &allocated_archive_names,
2141 sizeof (archive_name_array[0]));
2142 archive_name_array[archive_names++] = xstrdup (buf);
2143 }
2144 break;
2145
2146 #else /* not DEVICE_PREFIX */
2147
2148 argp_error (state,
2149 _("Options '-[0-7][lmh]' not supported by *this* tar"));
2150
2151 #endif /* not DEVICE_PREFIX */
2152
2153 default:
2154 return ARGP_ERR_UNKNOWN;
2155 }
2156 return 0;
2157 }
2158
2159 static struct argp argp = {
2160 options,
2161 parse_opt,
2162 N_("[FILE]..."),
2163 doc,
2164 NULL,
2165 tar_help_filter,
2166 NULL
2167 };
2168
2169 void
2170 usage (int status)
2171 {
2172 argp_help (&argp, stderr, ARGP_HELP_SEE, (char*) program_name);
2173 close_stdout ();
2174 exit (status);
2175 }
2176
2177 /* Parse the options for tar. */
2178
2179 static struct argp_option *
2180 find_argp_option (struct argp_option *o, int letter)
2181 {
2182 for (;
2183 !(o->name == NULL
2184 && o->key == 0
2185 && o->arg == 0
2186 && o->flags == 0
2187 && o->doc == NULL); o++)
2188 if (o->key == letter)
2189 return o;
2190 return NULL;
2191 }
2192
2193 static const char *tar_authors[] = {
2194 "John Gilmore",
2195 "Jay Fenlason",
2196 NULL
2197 };
2198 \f
2199 /* Subcommand classes */
2200 #define SUBCL_READ 0x01 /* subcommand reads from the archive */
2201 #define SUBCL_WRITE 0x02 /* subcommand writes to the archive */
2202 #define SUBCL_UPDATE 0x04 /* subcommand updates existing archive */
2203 #define SUBCL_TEST 0x08 /* subcommand tests archive header or meta-info */
2204 #define SUBCL_OCCUR 0x10 /* subcommand allows the use of the occurrence
2205 option */
2206
2207 static int subcommand_class[] = {
2208 /* UNKNOWN_SUBCOMMAND */ 0,
2209 /* APPEND_SUBCOMMAND */ SUBCL_WRITE|SUBCL_UPDATE,
2210 /* CAT_SUBCOMMAND */ SUBCL_WRITE,
2211 /* CREATE_SUBCOMMAND */ SUBCL_WRITE,
2212 /* DELETE_SUBCOMMAND */ SUBCL_WRITE|SUBCL_UPDATE|SUBCL_OCCUR,
2213 /* DIFF_SUBCOMMAND */ SUBCL_READ|SUBCL_OCCUR,
2214 /* EXTRACT_SUBCOMMAND */ SUBCL_READ|SUBCL_OCCUR,
2215 /* LIST_SUBCOMMAND */ SUBCL_READ|SUBCL_OCCUR,
2216 /* UPDATE_SUBCOMMAND */ SUBCL_WRITE|SUBCL_UPDATE,
2217 /* TEST_LABEL_SUBCOMMAND */ SUBCL_TEST
2218 };
2219
2220 /* Return t if the subcommand_option is in class(es) f */
2221 #define IS_SUBCOMMAND_CLASS(f) (subcommand_class[subcommand_option] & (f))
2222
2223 static struct tar_args args;
2224
2225 static void
2226 decode_options (int argc, char **argv)
2227 {
2228 int idx;
2229
2230 argp_version_setup ("tar", tar_authors);
2231
2232 /* Set some default option values. */
2233 args.textual_date = NULL;
2234 args.wildcards = default_wildcards;
2235 args.matching_flags = 0;
2236 args.include_anchored = EXCLUDE_ANCHORED;
2237 args.o_option = false;
2238 args.pax_option = false;
2239 args.backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX");
2240 args.version_control_string = 0;
2241 args.input_files = false;
2242 args.compress_autodetect = false;
2243
2244 subcommand_option = UNKNOWN_SUBCOMMAND;
2245 archive_format = DEFAULT_FORMAT;
2246 blocking_factor = DEFAULT_BLOCKING;
2247 record_size = DEFAULT_BLOCKING * BLOCKSIZE;
2248 excluded = new_exclude ();
2249 newer_mtime_option.tv_sec = TYPE_MINIMUM (time_t);
2250 newer_mtime_option.tv_nsec = -1;
2251 recursion_option = FNM_LEADING_DIR;
2252 unquote_option = true;
2253 tar_sparse_major = 1;
2254 tar_sparse_minor = 0;
2255
2256 owner_option = -1; owner_name_option = NULL;
2257 group_option = -1; group_name_option = NULL;
2258
2259 check_device_option = true;
2260
2261 incremental_level = -1;
2262
2263 seek_option = -1;
2264
2265 /* Convert old-style tar call by exploding option element and rearranging
2266 options accordingly. */
2267
2268 if (argc > 1 && argv[1][0] != '-')
2269 {
2270 int new_argc; /* argc value for rearranged arguments */
2271 char **new_argv; /* argv value for rearranged arguments */
2272 char *const *in; /* cursor into original argv */
2273 char **out; /* cursor into rearranged argv */
2274 const char *letter; /* cursor into old option letters */
2275 char buffer[3]; /* constructed option buffer */
2276
2277 /* Initialize a constructed option. */
2278
2279 buffer[0] = '-';
2280 buffer[2] = '\0';
2281
2282 /* Allocate a new argument array, and copy program name in it. */
2283
2284 new_argc = argc - 1 + strlen (argv[1]);
2285 new_argv = xmalloc ((new_argc + 1) * sizeof (char *));
2286 in = argv;
2287 out = new_argv;
2288 *out++ = *in++;
2289
2290 /* Copy each old letter option as a separate option, and have the
2291 corresponding argument moved next to it. */
2292
2293 for (letter = *in++; *letter; letter++)
2294 {
2295 struct argp_option *opt;
2296
2297 buffer[1] = *letter;
2298 *out++ = xstrdup (buffer);
2299 opt = find_argp_option (options, *letter);
2300 if (opt && opt->arg)
2301 {
2302 if (in < argv + argc)
2303 *out++ = *in++;
2304 else
2305 USAGE_ERROR ((0, 0, _("Old option '%c' requires an argument."),
2306 *letter));
2307 }
2308 }
2309
2310 /* Copy all remaining options. */
2311
2312 while (in < argv + argc)
2313 *out++ = *in++;
2314 *out = 0;
2315
2316 /* Replace the old option list by the new one. */
2317
2318 argc = new_argc;
2319 argv = new_argv;
2320 }
2321
2322 /* Parse all options and non-options as they appear. */
2323
2324 prepend_default_options (getenv ("TAR_OPTIONS"), &argc, &argv);
2325
2326 if (argp_parse (&argp, argc, argv, ARGP_IN_ORDER, &idx, &args))
2327 exit (TAREXIT_FAILURE);
2328
2329 /* Special handling for 'o' option:
2330
2331 GNU tar used to say "output old format".
2332 UNIX98 tar says don't chown files after extracting (we use
2333 "--no-same-owner" for this).
2334
2335 The old GNU tar semantics is retained when used with --create
2336 option, otherwise UNIX98 semantics is assumed */
2337
2338 if (args.o_option)
2339 {
2340 if (subcommand_option == CREATE_SUBCOMMAND)
2341 {
2342 /* GNU Tar <= 1.13 compatibility */
2343 set_archive_format ("v7");
2344 }
2345 else
2346 {
2347 /* UNIX98 compatibility */
2348 same_owner_option = -1;
2349 }
2350 }
2351
2352 /* Handle operands after any "--" argument. */
2353 for (; idx < argc; idx++)
2354 {
2355 name_add_name (argv[idx], MAKE_INCL_OPTIONS (&args));
2356 args.input_files = true;
2357 }
2358
2359 /* Warn about implicit use of the wildcards in command line arguments.
2360 See TODO */
2361 warn_regex_usage = args.wildcards == default_wildcards;
2362
2363 /* Derive option values and check option consistency. */
2364
2365 if (archive_format == DEFAULT_FORMAT)
2366 {
2367 if (args.pax_option)
2368 archive_format = POSIX_FORMAT;
2369 else
2370 archive_format = DEFAULT_ARCHIVE_FORMAT;
2371 }
2372
2373 if ((volume_label_option && subcommand_option == CREATE_SUBCOMMAND)
2374 || incremental_option
2375 || multi_volume_option
2376 || sparse_option)
2377 assert_format (FORMAT_MASK (OLDGNU_FORMAT)
2378 | FORMAT_MASK (GNU_FORMAT)
2379 | FORMAT_MASK (POSIX_FORMAT));
2380
2381 if (occurrence_option)
2382 {
2383 if (!args.input_files)
2384 USAGE_ERROR ((0, 0,
2385 _("--occurrence is meaningless without a file list")));
2386 if (!IS_SUBCOMMAND_CLASS (SUBCL_OCCUR))
2387 USAGE_ERROR ((0, 0,
2388 _("--occurrence cannot be used with %s"),
2389 subcommand_string (subcommand_option)));
2390 }
2391
2392 if (archive_names == 0)
2393 {
2394 /* If no archive file name given, try TAPE from the environment, or
2395 else, DEFAULT_ARCHIVE from the configuration process. */
2396
2397 archive_names = 1;
2398 archive_name_array[0] = getenv ("TAPE");
2399 if (! archive_name_array[0])
2400 archive_name_array[0] = DEFAULT_ARCHIVE;
2401 }
2402
2403 /* Allow multiple archives only with '-M'. */
2404
2405 if (archive_names > 1 && !multi_volume_option)
2406 USAGE_ERROR ((0, 0,
2407 _("Multiple archive files require '-M' option")));
2408
2409 if (listed_incremental_option
2410 && NEWER_OPTION_INITIALIZED (newer_mtime_option))
2411 USAGE_ERROR ((0, 0,
2412 _("Cannot combine --listed-incremental with --newer")));
2413 if (incremental_level != -1 && !listed_incremental_option)
2414 WARN ((0, 0,
2415 _("--level is meaningless without --listed-incremental")));
2416
2417 if (volume_label_option)
2418 {
2419 if (archive_format == GNU_FORMAT || archive_format == OLDGNU_FORMAT)
2420 {
2421 size_t volume_label_max_len =
2422 (sizeof current_header->header.name
2423 - 1 /* for trailing '\0' */
2424 - (multi_volume_option
2425 ? (sizeof " Volume "
2426 - 1 /* for null at end of " Volume " */
2427 + INT_STRLEN_BOUND (int) /* for volume number */
2428 - 1 /* for sign, as 0 <= volno */)
2429 : 0));
2430 if (volume_label_max_len < strlen (volume_label_option))
2431 USAGE_ERROR ((0, 0,
2432 ngettext ("%s: Volume label is too long (limit is %lu byte)",
2433 "%s: Volume label is too long (limit is %lu bytes)",
2434 volume_label_max_len),
2435 quotearg_colon (volume_label_option),
2436 (unsigned long) volume_label_max_len));
2437 }
2438 /* else FIXME
2439 Label length in PAX format is limited by the volume size. */
2440 }
2441
2442 if (verify_option)
2443 {
2444 if (multi_volume_option)
2445 USAGE_ERROR ((0, 0, _("Cannot verify multi-volume archives")));
2446 if (use_compress_program_option)
2447 USAGE_ERROR ((0, 0, _("Cannot verify compressed archives")));
2448 if (!IS_SUBCOMMAND_CLASS (SUBCL_WRITE))
2449 USAGE_ERROR ((0, 0, _("--verify cannot be used with %s"),
2450 subcommand_string (subcommand_option)));
2451 }
2452
2453 if (use_compress_program_option)
2454 {
2455 if (multi_volume_option)
2456 USAGE_ERROR ((0, 0, _("Cannot use multi-volume compressed archives")));
2457 if (IS_SUBCOMMAND_CLASS (SUBCL_UPDATE))
2458 USAGE_ERROR ((0, 0, _("Cannot update compressed archives")));
2459 if (subcommand_option == CAT_SUBCOMMAND)
2460 USAGE_ERROR ((0, 0, _("Cannot concatenate compressed archives")));
2461 }
2462
2463 /* It is no harm to use --pax-option on non-pax archives in archive
2464 reading mode. It may even be useful, since it allows to override
2465 file attributes from tar headers. Therefore I allow such usage.
2466 --gray */
2467 if (args.pax_option
2468 && archive_format != POSIX_FORMAT
2469 && !IS_SUBCOMMAND_CLASS (SUBCL_READ))
2470 USAGE_ERROR ((0, 0, _("--pax-option can be used only on POSIX archives")));
2471
2472 /* star creates non-POSIX typed archives with xattr support, so allow the
2473 extra headers when reading */
2474 if ((acls_option > 0)
2475 && archive_format != POSIX_FORMAT
2476 && !IS_SUBCOMMAND_CLASS (SUBCL_READ))
2477 USAGE_ERROR ((0, 0, _("--acls can be used only on POSIX archives")));
2478
2479 if ((selinux_context_option > 0)
2480 && archive_format != POSIX_FORMAT
2481 && !IS_SUBCOMMAND_CLASS (SUBCL_READ))
2482 USAGE_ERROR ((0, 0, _("--selinux can be used only on POSIX archives")));
2483
2484 if ((xattrs_option > 0)
2485 && archive_format != POSIX_FORMAT
2486 && !IS_SUBCOMMAND_CLASS (SUBCL_READ))
2487 USAGE_ERROR ((0, 0, _("--xattrs can be used only on POSIX archives")));
2488
2489 /* If ready to unlink hierarchies, so we are for simpler files. */
2490 if (recursive_unlink_option)
2491 old_files_option = UNLINK_FIRST_OLD_FILES;
2492
2493 /* Flags for accessing files to be read from or copied into. POSIX says
2494 O_NONBLOCK has unspecified effect on most types of files, but in
2495 practice it never harms and sometimes helps. */
2496 {
2497 int base_open_flags =
2498 (O_BINARY | O_CLOEXEC | O_NOCTTY | O_NONBLOCK
2499 | (dereference_option ? 0 : O_NOFOLLOW)
2500 | (atime_preserve_option == system_atime_preserve ? O_NOATIME : 0));
2501 open_read_flags = O_RDONLY | base_open_flags;
2502 open_searchdir_flags = O_SEARCH | O_DIRECTORY | base_open_flags;
2503 }
2504 fstatat_flags = dereference_option ? 0 : AT_SYMLINK_NOFOLLOW;
2505
2506 if (subcommand_option == TEST_LABEL_SUBCOMMAND)
2507 {
2508 /* --test-label is silent if the user has specified the label name to
2509 compare against. */
2510 if (!args.input_files)
2511 verbose_option++;
2512 }
2513 else if (utc_option)
2514 verbose_option = 2;
2515
2516 if (tape_length_option && tape_length_option < record_size)
2517 USAGE_ERROR ((0, 0, _("Volume length cannot be less than record size")));
2518
2519 if (same_order_option && listed_incremental_option)
2520 USAGE_ERROR ((0, 0, _("--preserve-order is not compatible with "
2521 "--listed-incremental")));
2522
2523 /* Forbid using -c with no input files whatsoever. Check that '-f -',
2524 explicit or implied, is used correctly. */
2525
2526 switch (subcommand_option)
2527 {
2528 case CREATE_SUBCOMMAND:
2529 if (!args.input_files && !files_from_option)
2530 USAGE_ERROR ((0, 0,
2531 _("Cowardly refusing to create an empty archive")));
2532 if (args.compress_autodetect && archive_names
2533 && strcmp (archive_name_array[0], "-"))
2534 set_compression_program_by_suffix (archive_name_array[0],
2535 use_compress_program_option);
2536 break;
2537
2538 case EXTRACT_SUBCOMMAND:
2539 case LIST_SUBCOMMAND:
2540 case DIFF_SUBCOMMAND:
2541 case TEST_LABEL_SUBCOMMAND:
2542 for (archive_name_cursor = archive_name_array;
2543 archive_name_cursor < archive_name_array + archive_names;
2544 archive_name_cursor++)
2545 if (!strcmp (*archive_name_cursor, "-"))
2546 request_stdin ("-f");
2547 break;
2548
2549 case CAT_SUBCOMMAND:
2550 case UPDATE_SUBCOMMAND:
2551 case APPEND_SUBCOMMAND:
2552 for (archive_name_cursor = archive_name_array;
2553 archive_name_cursor < archive_name_array + archive_names;
2554 archive_name_cursor++)
2555 if (!strcmp (*archive_name_cursor, "-"))
2556 USAGE_ERROR ((0, 0,
2557 _("Options '-Aru' are incompatible with '-f -'")));
2558
2559 default:
2560 break;
2561 }
2562
2563 /* Initialize stdlis */
2564 if (index_file_name)
2565 {
2566 stdlis = fopen (index_file_name, "w");
2567 if (! stdlis)
2568 open_fatal (index_file_name);
2569 }
2570 else
2571 stdlis = to_stdout_option ? stderr : stdout;
2572
2573 archive_name_cursor = archive_name_array;
2574
2575 /* Prepare for generating backup names. */
2576
2577 if (args.backup_suffix_string)
2578 simple_backup_suffix = xstrdup (args.backup_suffix_string);
2579
2580 if (backup_option)
2581 {
2582 backup_type = xget_version ("--backup", args.version_control_string);
2583 /* No backup is needed either if explicitely disabled or if
2584 the extracted files are not being written to disk. */
2585 if (backup_type == no_backups || EXTRACT_OVER_PIPE)
2586 backup_option = false;
2587 }
2588
2589 checkpoint_finish_compile ();
2590
2591 report_textual_dates (&args);
2592 }
2593
2594 void
2595 more_options (int argc, char **argv)
2596 {
2597 int idx;
2598 if (argp_parse (&argp, argc, argv, ARGP_IN_ORDER,
2599 &idx, &args))
2600 exit (TAREXIT_FAILURE);
2601 }
2602 \f
2603 /* Tar proper. */
2604
2605 /* Main routine for tar. */
2606 int
2607 main (int argc, char **argv)
2608 {
2609 set_start_time ();
2610 set_program_name (argv[0]);
2611
2612 setlocale (LC_ALL, "");
2613 bindtextdomain (PACKAGE, LOCALEDIR);
2614 textdomain (PACKAGE);
2615
2616 exit_failure = TAREXIT_FAILURE;
2617 exit_status = TAREXIT_SUCCESS;
2618 filename_terminator = '\n';
2619 set_quoting_style (0, DEFAULT_QUOTING_STYLE);
2620
2621 /* Make sure we have first three descriptors available */
2622 stdopen ();
2623
2624 /* Pre-allocate a few structures. */
2625
2626 allocated_archive_names = 10;
2627 archive_name_array =
2628 xmalloc (sizeof (const char *) * allocated_archive_names);
2629 archive_names = 0;
2630
2631 /* System V fork+wait does not work if SIGCHLD is ignored. */
2632 signal (SIGCHLD, SIG_DFL);
2633
2634 /* Try to disable the ability to unlink a directory. */
2635 priv_set_remove_linkdir ();
2636
2637 /* Decode options. */
2638
2639 decode_options (argc, argv);
2640
2641 name_init ();
2642
2643 /* Main command execution. */
2644
2645 if (volno_file_option)
2646 init_volume_number ();
2647
2648 switch (subcommand_option)
2649 {
2650 case UNKNOWN_SUBCOMMAND:
2651 USAGE_ERROR ((0, 0,
2652 _("You must specify one of the '-Acdtrux', '--delete' or '--test-label' options")));
2653
2654 case CAT_SUBCOMMAND:
2655 case UPDATE_SUBCOMMAND:
2656 case APPEND_SUBCOMMAND:
2657 update_archive ();
2658 break;
2659
2660 case DELETE_SUBCOMMAND:
2661 delete_archive_members ();
2662 break;
2663
2664 case CREATE_SUBCOMMAND:
2665 create_archive ();
2666 break;
2667
2668 case EXTRACT_SUBCOMMAND:
2669 extr_init ();
2670 read_and (extract_archive);
2671
2672 /* FIXME: should extract_finish () even if an ordinary signal is
2673 received. */
2674 extract_finish ();
2675
2676 break;
2677
2678 case LIST_SUBCOMMAND:
2679 read_and (list_archive);
2680 break;
2681
2682 case DIFF_SUBCOMMAND:
2683 diff_init ();
2684 read_and (diff_archive);
2685 break;
2686
2687 case TEST_LABEL_SUBCOMMAND:
2688 test_archive_label ();
2689 }
2690
2691 if (totals_option)
2692 print_total_stats ();
2693
2694 if (check_links_option)
2695 check_links ();
2696
2697 if (volno_file_option)
2698 closeout_volume_number ();
2699
2700 /* Dispose of allocated memory, and return. */
2701
2702 free (archive_name_array);
2703 xattrs_clear_setup ();
2704 name_term ();
2705
2706 if (exit_status == TAREXIT_FAILURE)
2707 error (0, 0, _("Exiting with failure status due to previous errors"));
2708
2709 if (stdlis == stdout)
2710 close_stdout ();
2711 else if (ferror (stderr) || fclose (stderr) != 0)
2712 set_exit_status (TAREXIT_FAILURE);
2713
2714 return exit_status;
2715 }
2716
2717 void
2718 tar_stat_init (struct tar_stat_info *st)
2719 {
2720 memset (st, 0, sizeof (*st));
2721 }
2722
2723 /* Close the stream or file descriptor associated with ST, and remove
2724 all traces of it from ST. Return true if successful, false (with a
2725 diagnostic) otherwise. */
2726 bool
2727 tar_stat_close (struct tar_stat_info *st)
2728 {
2729 int status = (st->dirstream ? closedir (st->dirstream)
2730 : 0 < st->fd ? close (st->fd)
2731 : 0);
2732 st->dirstream = 0;
2733 st->fd = 0;
2734
2735 if (status == 0)
2736 return true;
2737 else
2738 {
2739 close_diag (st->orig_file_name);
2740 return false;
2741 }
2742 }
2743
2744 void
2745 tar_stat_destroy (struct tar_stat_info *st)
2746 {
2747 tar_stat_close (st);
2748 xheader_xattr_free (st->xattr_map, st->xattr_map_size);
2749 free (st->orig_file_name);
2750 free (st->file_name);
2751 free (st->link_name);
2752 free (st->uname);
2753 free (st->gname);
2754 free (st->cntx_name);
2755 free (st->acls_a_ptr);
2756 free (st->acls_d_ptr);
2757 free (st->sparse_map);
2758 free (st->dumpdir);
2759 xheader_destroy (&st->xhdr);
2760 memset (st, 0, sizeof (*st));
2761 }
2762
2763 /* Format mask for all available formats that support nanosecond
2764 timestamp resolution. */
2765 #define NS_PRECISION_FORMAT_MASK FORMAT_MASK (POSIX_FORMAT)
2766
2767 /* Same as timespec_cmp, but ignore nanoseconds if current archive
2768 format does not provide sufficient resolution. */
2769 int
2770 tar_timespec_cmp (struct timespec a, struct timespec b)
2771 {
2772 if (!(FORMAT_MASK (current_format) & NS_PRECISION_FORMAT_MASK))
2773 a.tv_nsec = b.tv_nsec = 0;
2774 return timespec_cmp (a, b);
2775 }
2776
2777 /* Set tar exit status to VAL, unless it is already indicating
2778 a more serious condition. This relies on the fact that the
2779 values of TAREXIT_ constants are ranged by severity. */
2780 void
2781 set_exit_status (int val)
2782 {
2783 if (val > exit_status)
2784 exit_status = val;
2785 }
This page took 0.155688 seconds and 4 git commands to generate.