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