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