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