]> Dogcows Code - chaz/tar/blob - src/tar.c
cd2849545a3ddf4ff8c6e3451a7181a7d5a78f69
[chaz/tar] / src / tar.c
1 /* A tar (tape archiver) program.
2
3 Copyright 1988, 1992-1997, 1999-2001, 2003-2007, 2012-2014 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, N_("DIR"), OPTION_ARG_OPTIONAL,
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 one_top_level_dir = arg;
1451 break;
1452
1453 case 'l':
1454 check_links_option = 1;
1455 break;
1456
1457 case 'L':
1458 {
1459 uintmax_t u;
1460 char *p;
1461
1462 if (xstrtoumax (arg, &p, 10, &u, TAR_SIZE_SUFFIXES) != LONGINT_OK)
1463 USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (arg),
1464 _("Invalid tape length")));
1465 if (p > arg && !strchr (TAR_SIZE_SUFFIXES, p[-1]))
1466 tape_length_option = 1024 * (tarlong) u;
1467 else
1468 tape_length_option = (tarlong) u;
1469 multi_volume_option = true;
1470 }
1471 break;
1472
1473 case LEVEL_OPTION:
1474 {
1475 char *p;
1476 incremental_level = strtoul (arg, &p, 10);
1477 if (*p)
1478 USAGE_ERROR ((0, 0, _("Invalid incremental level value")));
1479 }
1480 break;
1481
1482 case LZIP_OPTION:
1483 set_use_compress_program_option (LZIP_PROGRAM);
1484 break;
1485
1486 case LZMA_OPTION:
1487 set_use_compress_program_option (LZMA_PROGRAM);
1488 break;
1489
1490 case LZOP_OPTION:
1491 set_use_compress_program_option (LZOP_PROGRAM);
1492 break;
1493
1494 case 'm':
1495 touch_option = true;
1496 break;
1497
1498 case 'M':
1499 /* Make multivolume archive: when we can't write any more into
1500 the archive, re-open it, and continue writing. */
1501
1502 multi_volume_option = true;
1503 break;
1504
1505 case MTIME_OPTION:
1506 get_date_or_file (args, "--mtime", arg, &mtime_option);
1507 set_mtime_option = true;
1508 break;
1509
1510 case 'n':
1511 seek_option = 1;
1512 break;
1513
1514 case NO_SEEK_OPTION:
1515 seek_option = 0;
1516 break;
1517
1518 case 'N':
1519 after_date_option = true;
1520 /* Fall through. */
1521
1522 case NEWER_MTIME_OPTION:
1523 if (NEWER_OPTION_INITIALIZED (newer_mtime_option))
1524 USAGE_ERROR ((0, 0, _("More than one threshold date")));
1525 get_date_or_file (args,
1526 key == NEWER_MTIME_OPTION ? "--newer-mtime"
1527 : "--after-date", arg, &newer_mtime_option);
1528 break;
1529
1530 case 'o':
1531 args->o_option = true;
1532 break;
1533
1534 case 'O':
1535 to_stdout_option = true;
1536 break;
1537
1538 case 'p':
1539 same_permissions_option = true;
1540 break;
1541
1542 case 'P':
1543 absolute_names_option = true;
1544 break;
1545
1546 case 'r':
1547 set_subcommand_option (APPEND_SUBCOMMAND);
1548 break;
1549
1550 case 'R':
1551 /* Print block numbers for debugging bad tar archives. */
1552
1553 /* It would surely make sense to exchange -B and -R, but it seems
1554 that -B has been used for a long while in Sun tar and most
1555 BSD-derived systems. This is a consequence of the block/record
1556 terminology confusion. */
1557
1558 block_number_option = true;
1559 break;
1560
1561 case 's':
1562 /* Names to extract are sorted. */
1563
1564 same_order_option = true;
1565 break;
1566
1567 case 'S':
1568 sparse_option = true;
1569 break;
1570
1571 case SKIP_OLD_FILES_OPTION:
1572 old_files_option = SKIP_OLD_FILES;
1573 break;
1574
1575 case SPARSE_VERSION_OPTION:
1576 sparse_option = true;
1577 {
1578 char *p;
1579 tar_sparse_major = strtoul (arg, &p, 10);
1580 if (*p)
1581 {
1582 if (*p != '.')
1583 USAGE_ERROR ((0, 0, _("Invalid sparse version value")));
1584 tar_sparse_minor = strtoul (p + 1, &p, 10);
1585 if (*p)
1586 USAGE_ERROR ((0, 0, _("Invalid sparse version value")));
1587 }
1588 }
1589 break;
1590
1591 case 't':
1592 set_subcommand_option (LIST_SUBCOMMAND);
1593 verbose_option++;
1594 break;
1595
1596 case TEST_LABEL_OPTION:
1597 set_subcommand_option (TEST_LABEL_SUBCOMMAND);
1598 break;
1599
1600 case 'T':
1601 name_add_file (arg, filename_terminator);
1602 /* Indicate we've been given -T option. This is for backward
1603 compatibility only, so that `tar cfT archive /dev/null will
1604 succeed */
1605 files_from_option = true;
1606 break;
1607
1608 case 'u':
1609 set_subcommand_option (UPDATE_SUBCOMMAND);
1610 break;
1611
1612 case 'U':
1613 old_files_option = UNLINK_FIRST_OLD_FILES;
1614 break;
1615
1616 case UTC_OPTION:
1617 utc_option = true;
1618 break;
1619
1620 case 'v':
1621 verbose_option++;
1622 warning_option |= WARN_VERBOSE_WARNINGS;
1623 break;
1624
1625 case 'V':
1626 volume_label_option = arg;
1627 break;
1628
1629 case 'w':
1630 interactive_option = true;
1631 break;
1632
1633 case 'W':
1634 verify_option = true;
1635 break;
1636
1637 case 'x':
1638 set_subcommand_option (EXTRACT_SUBCOMMAND);
1639 break;
1640
1641 case 'X':
1642 if (add_exclude_file (add_exclude, excluded, arg,
1643 MAKE_EXCL_OPTIONS (args), '\n')
1644 != 0)
1645 {
1646 int e = errno;
1647 FATAL_ERROR ((0, e, "%s", quotearg_colon (arg)));
1648 }
1649 break;
1650
1651 case 'z':
1652 set_use_compress_program_option (GZIP_PROGRAM);
1653 break;
1654
1655 case 'Z':
1656 set_use_compress_program_option (COMPRESS_PROGRAM);
1657 break;
1658
1659 case ANCHORED_OPTION:
1660 args->matching_flags |= EXCLUDE_ANCHORED;
1661 break;
1662
1663 case ATIME_PRESERVE_OPTION:
1664 atime_preserve_option =
1665 (arg
1666 ? XARGMATCH ("--atime-preserve", arg,
1667 atime_preserve_args, atime_preserve_types)
1668 : replace_atime_preserve);
1669 if (! O_NOATIME && atime_preserve_option == system_atime_preserve)
1670 FATAL_ERROR ((0, 0,
1671 _("--atime-preserve='system' is not supported"
1672 " on this platform")));
1673 break;
1674
1675 case CHECK_DEVICE_OPTION:
1676 check_device_option = true;
1677 break;
1678
1679 case NO_CHECK_DEVICE_OPTION:
1680 check_device_option = false;
1681 break;
1682
1683 case CHECKPOINT_OPTION:
1684 if (arg)
1685 {
1686 char *p;
1687
1688 if (*arg == '.')
1689 {
1690 checkpoint_compile_action (".");
1691 arg++;
1692 }
1693 checkpoint_option = strtoul (arg, &p, 0);
1694 if (*p)
1695 FATAL_ERROR ((0, 0,
1696 _("--checkpoint value is not an integer")));
1697 }
1698 else
1699 checkpoint_option = DEFAULT_CHECKPOINT;
1700 break;
1701
1702 case CHECKPOINT_ACTION_OPTION:
1703 checkpoint_compile_action (arg);
1704 break;
1705
1706 case BACKUP_OPTION:
1707 backup_option = true;
1708 if (arg)
1709 args->version_control_string = arg;
1710 break;
1711
1712 case DELAY_DIRECTORY_RESTORE_OPTION:
1713 delay_directory_restore_option = true;
1714 break;
1715
1716 case NO_DELAY_DIRECTORY_RESTORE_OPTION:
1717 delay_directory_restore_option = false;
1718 break;
1719
1720 case DELETE_OPTION:
1721 set_subcommand_option (DELETE_SUBCOMMAND);
1722 break;
1723
1724 case EXCLUDE_BACKUPS_OPTION:
1725 add_exclude_array (backup_file_table, EXCLUDE_WILDCARDS);
1726 break;
1727
1728 case EXCLUDE_OPTION:
1729 add_exclude (excluded, arg, MAKE_EXCL_OPTIONS (args));
1730 break;
1731
1732 case EXCLUDE_CACHES_OPTION:
1733 add_exclusion_tag ("CACHEDIR.TAG", exclusion_tag_contents,
1734 cachedir_file_p);
1735 break;
1736
1737 case EXCLUDE_CACHES_UNDER_OPTION:
1738 add_exclusion_tag ("CACHEDIR.TAG", exclusion_tag_under,
1739 cachedir_file_p);
1740 break;
1741
1742 case EXCLUDE_CACHES_ALL_OPTION:
1743 add_exclusion_tag ("CACHEDIR.TAG", exclusion_tag_all,
1744 cachedir_file_p);
1745 break;
1746
1747 case EXCLUDE_TAG_OPTION:
1748 add_exclusion_tag (arg, exclusion_tag_contents, NULL);
1749 break;
1750
1751 case EXCLUDE_TAG_UNDER_OPTION:
1752 add_exclusion_tag (arg, exclusion_tag_under, NULL);
1753 break;
1754
1755 case EXCLUDE_TAG_ALL_OPTION:
1756 add_exclusion_tag (arg, exclusion_tag_all, NULL);
1757 break;
1758
1759 case EXCLUDE_VCS_OPTION:
1760 add_exclude_array (vcs_file_table, 0);
1761 break;
1762
1763 case FORCE_LOCAL_OPTION:
1764 force_local_option = true;
1765 break;
1766
1767 case 'H':
1768 set_archive_format (arg);
1769 break;
1770
1771 case INDEX_FILE_OPTION:
1772 index_file_name = arg;
1773 break;
1774
1775 case IGNORE_CASE_OPTION:
1776 args->matching_flags |= FNM_CASEFOLD;
1777 break;
1778
1779 case IGNORE_COMMAND_ERROR_OPTION:
1780 ignore_command_error_option = true;
1781 break;
1782
1783 case IGNORE_FAILED_READ_OPTION:
1784 ignore_failed_read_option = true;
1785 break;
1786
1787 case KEEP_DIRECTORY_SYMLINK_OPTION:
1788 keep_directory_symlink_option = true;
1789 break;
1790
1791 case KEEP_NEWER_FILES_OPTION:
1792 old_files_option = KEEP_NEWER_FILES;
1793 break;
1794
1795 case GROUP_OPTION:
1796 {
1797 uintmax_t u = parse_owner_group (arg, TYPE_MAXIMUM (gid_t),
1798 &group_name_option);
1799 if (u == UINTMAX_MAX)
1800 {
1801 group_option = -1;
1802 if (group_name_option)
1803 gname_to_gid (group_name_option, &group_option);
1804 }
1805 else
1806 group_option = u;
1807 }
1808 break;
1809
1810 case MODE_OPTION:
1811 mode_option = mode_compile (arg);
1812 if (!mode_option)
1813 FATAL_ERROR ((0, 0, _("Invalid mode given on option")));
1814 initial_umask = umask (0);
1815 umask (initial_umask);
1816 break;
1817
1818 case NO_ANCHORED_OPTION:
1819 args->include_anchored = 0; /* Clear the default for comman line args */
1820 args->matching_flags &= ~ EXCLUDE_ANCHORED;
1821 break;
1822
1823 case NO_IGNORE_CASE_OPTION:
1824 args->matching_flags &= ~ FNM_CASEFOLD;
1825 break;
1826
1827 case NO_IGNORE_COMMAND_ERROR_OPTION:
1828 ignore_command_error_option = false;
1829 break;
1830
1831 case NO_OVERWRITE_DIR_OPTION:
1832 old_files_option = NO_OVERWRITE_DIR_OLD_FILES;
1833 break;
1834
1835 case NO_QUOTE_CHARS_OPTION:
1836 for (;*arg; arg++)
1837 set_char_quoting (NULL, *arg, 0);
1838 break;
1839
1840 case NO_WILDCARDS_OPTION:
1841 args->wildcards = disable_wildcards;
1842 break;
1843
1844 case NO_WILDCARDS_MATCH_SLASH_OPTION:
1845 args->matching_flags |= FNM_FILE_NAME;
1846 break;
1847
1848 case NULL_OPTION:
1849 filename_terminator = '\0';
1850 break;
1851
1852 case NO_NULL_OPTION:
1853 filename_terminator = '\n';
1854 break;
1855
1856 case NUMERIC_OWNER_OPTION:
1857 numeric_owner_option = true;
1858 break;
1859
1860 case OCCURRENCE_OPTION:
1861 if (!arg)
1862 occurrence_option = 1;
1863 else
1864 {
1865 uintmax_t u;
1866 if (xstrtoumax (arg, 0, 10, &u, "") == LONGINT_OK)
1867 occurrence_option = u;
1868 else
1869 FATAL_ERROR ((0, 0, "%s: %s", quotearg_colon (arg),
1870 _("Invalid number")));
1871 }
1872 break;
1873
1874 case OLD_ARCHIVE_OPTION:
1875 set_archive_format ("v7");
1876 break;
1877
1878 case OVERWRITE_DIR_OPTION:
1879 old_files_option = DEFAULT_OLD_FILES;
1880 break;
1881
1882 case OVERWRITE_OPTION:
1883 old_files_option = OVERWRITE_OLD_FILES;
1884 break;
1885
1886 case OWNER_OPTION:
1887 {
1888 uintmax_t u = parse_owner_group (arg, TYPE_MAXIMUM (uid_t),
1889 &owner_name_option);
1890 if (u == UINTMAX_MAX)
1891 {
1892 owner_option = -1;
1893 if (owner_name_option)
1894 uname_to_uid (owner_name_option, &owner_option);
1895 }
1896 else
1897 owner_option = u;
1898 }
1899 break;
1900
1901 case QUOTE_CHARS_OPTION:
1902 for (;*arg; arg++)
1903 set_char_quoting (NULL, *arg, 1);
1904 break;
1905
1906 case QUOTING_STYLE_OPTION:
1907 tar_set_quoting_style (arg);
1908 break;
1909
1910 case PAX_OPTION:
1911 {
1912 char *tmp = expand_pax_option (args, arg);
1913 args->pax_option = true;
1914 xheader_set_option (tmp);
1915 free (tmp);
1916 }
1917 break;
1918
1919 case POSIX_OPTION:
1920 set_archive_format ("posix");
1921 break;
1922
1923 case PRESERVE_OPTION:
1924 /* FIXME: What it is good for? */
1925 same_permissions_option = true;
1926 same_order_option = true;
1927 WARN ((0, 0, _("The --preserve option is deprecated, "
1928 "use --preserve-permissions --preserve-order instead")));
1929 break;
1930
1931 case RECORD_SIZE_OPTION:
1932 {
1933 uintmax_t u;
1934
1935 if (! (xstrtoumax (arg, NULL, 10, &u, TAR_SIZE_SUFFIXES) == LONGINT_OK
1936 && u == (size_t) u))
1937 USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (arg),
1938 _("Invalid record size")));
1939 record_size = u;
1940 if (record_size % BLOCKSIZE != 0)
1941 USAGE_ERROR ((0, 0, _("Record size must be a multiple of %d."),
1942 BLOCKSIZE));
1943 blocking_factor = record_size / BLOCKSIZE;
1944 }
1945 break;
1946
1947 case RECURSIVE_UNLINK_OPTION:
1948 recursive_unlink_option = true;
1949 break;
1950
1951 case REMOVE_FILES_OPTION:
1952 remove_files_option = true;
1953 break;
1954
1955 case RESTRICT_OPTION:
1956 restrict_option = true;
1957 break;
1958
1959 case RMT_COMMAND_OPTION:
1960 rmt_command = arg;
1961 break;
1962
1963 case RSH_COMMAND_OPTION:
1964 rsh_command_option = arg;
1965 break;
1966
1967 case SHOW_DEFAULTS_OPTION:
1968 {
1969 char *s = format_default_settings ();
1970 printf ("%s\n", s);
1971 close_stdout ();
1972 free (s);
1973 exit (0);
1974 }
1975
1976 case SHOW_SNAPSHOT_FIELD_RANGES_OPTION:
1977 show_snapshot_field_ranges ();
1978 close_stdout ();
1979 exit (0);
1980
1981 case STRIP_COMPONENTS_OPTION:
1982 {
1983 uintmax_t u;
1984 if (! (xstrtoumax (arg, 0, 10, &u, "") == LONGINT_OK
1985 && u == (size_t) u))
1986 USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (arg),
1987 _("Invalid number of elements")));
1988 strip_name_components = u;
1989 }
1990 break;
1991
1992 case SHOW_OMITTED_DIRS_OPTION:
1993 show_omitted_dirs_option = true;
1994 break;
1995
1996 case SHOW_TRANSFORMED_NAMES_OPTION:
1997 show_transformed_names_option = true;
1998 break;
1999
2000 case SUFFIX_OPTION:
2001 backup_option = true;
2002 args->backup_suffix_string = arg;
2003 break;
2004
2005 case TO_COMMAND_OPTION:
2006 if (to_command_option)
2007 USAGE_ERROR ((0, 0, _("Only one --to-command option allowed")));
2008 to_command_option = arg;
2009 break;
2010
2011 case TOTALS_OPTION:
2012 if (arg)
2013 set_stat_signal (arg);
2014 else
2015 totals_option = true;
2016 break;
2017
2018 case TRANSFORM_OPTION:
2019 set_transform_expr (arg);
2020 break;
2021
2022 case 'I':
2023 set_use_compress_program_option (arg);
2024 break;
2025
2026 case VOLNO_FILE_OPTION:
2027 volno_file_option = arg;
2028 break;
2029
2030 case WILDCARDS_OPTION:
2031 args->wildcards = enable_wildcards;
2032 break;
2033
2034 case WILDCARDS_MATCH_SLASH_OPTION:
2035 args->matching_flags &= ~ FNM_FILE_NAME;
2036 break;
2037
2038 case NO_RECURSION_OPTION:
2039 recursion_option = 0;
2040 break;
2041
2042 case NO_SAME_OWNER_OPTION:
2043 same_owner_option = -1;
2044 break;
2045
2046 case NO_SAME_PERMISSIONS_OPTION:
2047 same_permissions_option = -1;
2048 break;
2049
2050 case ACLS_OPTION:
2051 set_archive_format ("posix");
2052 acls_option = 1;
2053 break;
2054
2055 case NO_ACLS_OPTION:
2056 acls_option = -1;
2057 break;
2058
2059 case SELINUX_CONTEXT_OPTION:
2060 set_archive_format ("posix");
2061 selinux_context_option = 1;
2062 break;
2063
2064 case NO_SELINUX_CONTEXT_OPTION:
2065 selinux_context_option = -1;
2066 break;
2067
2068 case XATTR_OPTION:
2069 set_archive_format ("posix");
2070 xattrs_option = 1;
2071 break;
2072
2073 case NO_XATTR_OPTION:
2074 xattrs_option = -1;
2075 break;
2076
2077 case XATTR_INCLUDE:
2078 case XATTR_EXCLUDE:
2079 xattrs_mask_add (arg, (key == XATTR_INCLUDE));
2080 break;
2081
2082 case RECURSION_OPTION:
2083 recursion_option = FNM_LEADING_DIR;
2084 break;
2085
2086 case SAME_OWNER_OPTION:
2087 same_owner_option = 1;
2088 break;
2089
2090 case UNQUOTE_OPTION:
2091 unquote_option = true;
2092 break;
2093
2094 case NO_UNQUOTE_OPTION:
2095 unquote_option = false;
2096 break;
2097
2098 case WARNING_OPTION:
2099 set_warning_option (arg);
2100 break;
2101
2102 case '0':
2103 case '1':
2104 case '2':
2105 case '3':
2106 case '4':
2107 case '5':
2108 case '6':
2109 case '7':
2110
2111 #ifdef DEVICE_PREFIX
2112 {
2113 int device = key - '0';
2114 int density;
2115 static char buf[sizeof DEVICE_PREFIX + 10];
2116 char *cursor;
2117
2118 if (arg[1])
2119 argp_error (state, _("Malformed density argument: %s"), quote (arg));
2120
2121 strcpy (buf, DEVICE_PREFIX);
2122 cursor = buf + strlen (buf);
2123
2124 #ifdef DENSITY_LETTER
2125
2126 sprintf (cursor, "%d%c", device, arg[0]);
2127
2128 #else /* not DENSITY_LETTER */
2129
2130 switch (arg[0])
2131 {
2132 case 'l':
2133 device += LOW_DENSITY_NUM;
2134 break;
2135
2136 case 'm':
2137 device += MID_DENSITY_NUM;
2138 break;
2139
2140 case 'h':
2141 device += HIGH_DENSITY_NUM;
2142 break;
2143
2144 default:
2145 argp_error (state, _("Unknown density: '%c'"), arg[0]);
2146 }
2147 sprintf (cursor, "%d", device);
2148
2149 #endif /* not DENSITY_LETTER */
2150
2151 if (archive_names == allocated_archive_names)
2152 archive_name_array = x2nrealloc (archive_name_array,
2153 &allocated_archive_names,
2154 sizeof (archive_name_array[0]));
2155 archive_name_array[archive_names++] = xstrdup (buf);
2156 }
2157 break;
2158
2159 #else /* not DEVICE_PREFIX */
2160
2161 argp_error (state,
2162 _("Options '-[0-7][lmh]' not supported by *this* tar"));
2163
2164 #endif /* not DEVICE_PREFIX */
2165
2166 default:
2167 return ARGP_ERR_UNKNOWN;
2168 }
2169 return 0;
2170 }
2171
2172 static struct argp argp = {
2173 options,
2174 parse_opt,
2175 N_("[FILE]..."),
2176 doc,
2177 NULL,
2178 tar_help_filter,
2179 NULL
2180 };
2181
2182 void
2183 usage (int status)
2184 {
2185 argp_help (&argp, stderr, ARGP_HELP_SEE, (char*) program_name);
2186 close_stdout ();
2187 exit (status);
2188 }
2189
2190 /* Parse the options for tar. */
2191
2192 static struct argp_option *
2193 find_argp_option (struct argp_option *o, int letter)
2194 {
2195 for (;
2196 !(o->name == NULL
2197 && o->key == 0
2198 && o->arg == 0
2199 && o->flags == 0
2200 && o->doc == NULL); o++)
2201 if (o->key == letter)
2202 return o;
2203 return NULL;
2204 }
2205
2206 static const char *tar_authors[] = {
2207 "John Gilmore",
2208 "Jay Fenlason",
2209 NULL
2210 };
2211 \f
2212 /* Subcommand classes */
2213 #define SUBCL_READ 0x01 /* subcommand reads from the archive */
2214 #define SUBCL_WRITE 0x02 /* subcommand writes to the archive */
2215 #define SUBCL_UPDATE 0x04 /* subcommand updates existing archive */
2216 #define SUBCL_TEST 0x08 /* subcommand tests archive header or meta-info */
2217 #define SUBCL_OCCUR 0x10 /* subcommand allows the use of the occurrence
2218 option */
2219
2220 static int subcommand_class[] = {
2221 /* UNKNOWN_SUBCOMMAND */ 0,
2222 /* APPEND_SUBCOMMAND */ SUBCL_WRITE|SUBCL_UPDATE,
2223 /* CAT_SUBCOMMAND */ SUBCL_WRITE,
2224 /* CREATE_SUBCOMMAND */ SUBCL_WRITE,
2225 /* DELETE_SUBCOMMAND */ SUBCL_WRITE|SUBCL_UPDATE|SUBCL_OCCUR,
2226 /* DIFF_SUBCOMMAND */ SUBCL_READ|SUBCL_OCCUR,
2227 /* EXTRACT_SUBCOMMAND */ SUBCL_READ|SUBCL_OCCUR,
2228 /* LIST_SUBCOMMAND */ SUBCL_READ|SUBCL_OCCUR,
2229 /* UPDATE_SUBCOMMAND */ SUBCL_WRITE|SUBCL_UPDATE,
2230 /* TEST_LABEL_SUBCOMMAND */ SUBCL_TEST
2231 };
2232
2233 /* Return t if the subcommand_option is in class(es) f */
2234 #define IS_SUBCOMMAND_CLASS(f) (subcommand_class[subcommand_option] & (f))
2235
2236 static struct tar_args args;
2237
2238 static void
2239 decode_options (int argc, char **argv)
2240 {
2241 int idx;
2242
2243 argp_version_setup ("tar", tar_authors);
2244
2245 /* Set some default option values. */
2246 args.textual_date = NULL;
2247 args.wildcards = default_wildcards;
2248 args.matching_flags = 0;
2249 args.include_anchored = EXCLUDE_ANCHORED;
2250 args.o_option = false;
2251 args.pax_option = false;
2252 args.backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX");
2253 args.version_control_string = 0;
2254 args.input_files = false;
2255 args.compress_autodetect = false;
2256
2257 subcommand_option = UNKNOWN_SUBCOMMAND;
2258 archive_format = DEFAULT_FORMAT;
2259 blocking_factor = DEFAULT_BLOCKING;
2260 record_size = DEFAULT_BLOCKING * BLOCKSIZE;
2261 excluded = new_exclude ();
2262 newer_mtime_option.tv_sec = TYPE_MINIMUM (time_t);
2263 newer_mtime_option.tv_nsec = -1;
2264 recursion_option = FNM_LEADING_DIR;
2265 unquote_option = true;
2266 tar_sparse_major = 1;
2267 tar_sparse_minor = 0;
2268
2269 owner_option = -1; owner_name_option = NULL;
2270 group_option = -1; group_name_option = NULL;
2271
2272 check_device_option = true;
2273
2274 incremental_level = -1;
2275
2276 seek_option = -1;
2277
2278 /* Convert old-style tar call by exploding option element and rearranging
2279 options accordingly. */
2280
2281 if (argc > 1 && argv[1][0] != '-')
2282 {
2283 int new_argc; /* argc value for rearranged arguments */
2284 char **new_argv; /* argv value for rearranged arguments */
2285 char *const *in; /* cursor into original argv */
2286 char **out; /* cursor into rearranged argv */
2287 const char *letter; /* cursor into old option letters */
2288 char buffer[3]; /* constructed option buffer */
2289
2290 /* Initialize a constructed option. */
2291
2292 buffer[0] = '-';
2293 buffer[2] = '\0';
2294
2295 /* Allocate a new argument array, and copy program name in it. */
2296
2297 new_argc = argc - 1 + strlen (argv[1]);
2298 new_argv = xmalloc ((new_argc + 1) * sizeof (char *));
2299 in = argv;
2300 out = new_argv;
2301 *out++ = *in++;
2302
2303 /* Copy each old letter option as a separate option, and have the
2304 corresponding argument moved next to it. */
2305
2306 for (letter = *in++; *letter; letter++)
2307 {
2308 struct argp_option *opt;
2309
2310 buffer[1] = *letter;
2311 *out++ = xstrdup (buffer);
2312 opt = find_argp_option (options, *letter);
2313 if (opt && opt->arg)
2314 {
2315 if (in < argv + argc)
2316 *out++ = *in++;
2317 else
2318 USAGE_ERROR ((0, 0, _("Old option '%c' requires an argument."),
2319 *letter));
2320 }
2321 }
2322
2323 /* Copy all remaining options. */
2324
2325 while (in < argv + argc)
2326 *out++ = *in++;
2327 *out = 0;
2328
2329 /* Replace the old option list by the new one. */
2330
2331 argc = new_argc;
2332 argv = new_argv;
2333 }
2334
2335 /* Parse all options and non-options as they appear. */
2336
2337 prepend_default_options (getenv ("TAR_OPTIONS"), &argc, &argv);
2338
2339 if (argp_parse (&argp, argc, argv, ARGP_IN_ORDER, &idx, &args))
2340 exit (TAREXIT_FAILURE);
2341
2342 /* Special handling for 'o' option:
2343
2344 GNU tar used to say "output old format".
2345 UNIX98 tar says don't chown files after extracting (we use
2346 "--no-same-owner" for this).
2347
2348 The old GNU tar semantics is retained when used with --create
2349 option, otherwise UNIX98 semantics is assumed */
2350
2351 if (args.o_option)
2352 {
2353 if (subcommand_option == CREATE_SUBCOMMAND)
2354 {
2355 /* GNU Tar <= 1.13 compatibility */
2356 set_archive_format ("v7");
2357 }
2358 else
2359 {
2360 /* UNIX98 compatibility */
2361 same_owner_option = -1;
2362 }
2363 }
2364
2365 /* Handle operands after any "--" argument. */
2366 for (; idx < argc; idx++)
2367 {
2368 name_add_name (argv[idx], MAKE_INCL_OPTIONS (&args));
2369 args.input_files = true;
2370 }
2371
2372 /* Warn about implicit use of the wildcards in command line arguments.
2373 See TODO */
2374 warn_regex_usage = args.wildcards == default_wildcards;
2375
2376 /* Derive option values and check option consistency. */
2377
2378 if (archive_format == DEFAULT_FORMAT)
2379 {
2380 if (args.pax_option)
2381 archive_format = POSIX_FORMAT;
2382 else
2383 archive_format = DEFAULT_ARCHIVE_FORMAT;
2384 }
2385
2386 if ((volume_label_option && subcommand_option == CREATE_SUBCOMMAND)
2387 || incremental_option
2388 || multi_volume_option
2389 || sparse_option)
2390 assert_format (FORMAT_MASK (OLDGNU_FORMAT)
2391 | FORMAT_MASK (GNU_FORMAT)
2392 | FORMAT_MASK (POSIX_FORMAT));
2393
2394 if (occurrence_option)
2395 {
2396 if (!args.input_files)
2397 USAGE_ERROR ((0, 0,
2398 _("--occurrence is meaningless without a file list")));
2399 if (!IS_SUBCOMMAND_CLASS (SUBCL_OCCUR))
2400 USAGE_ERROR ((0, 0,
2401 _("--occurrence cannot be used with %s"),
2402 subcommand_string (subcommand_option)));
2403 }
2404
2405 if (one_top_level_option && absolute_names_option)
2406 USAGE_ERROR ((0, 0, _("--one-top-level cannot be used with --absolute-names")));
2407
2408 if (archive_names == 0)
2409 {
2410 /* If no archive file name given, try TAPE from the environment, or
2411 else, DEFAULT_ARCHIVE from the configuration process. */
2412
2413 archive_names = 1;
2414 archive_name_array[0] = getenv ("TAPE");
2415 if (! archive_name_array[0])
2416 archive_name_array[0] = DEFAULT_ARCHIVE;
2417 }
2418
2419 /* Allow multiple archives only with '-M'. */
2420
2421 if (archive_names > 1 && !multi_volume_option)
2422 USAGE_ERROR ((0, 0,
2423 _("Multiple archive files require '-M' option")));
2424
2425 if (listed_incremental_option
2426 && NEWER_OPTION_INITIALIZED (newer_mtime_option))
2427 USAGE_ERROR ((0, 0,
2428 _("Cannot combine --listed-incremental with --newer")));
2429 if (incremental_level != -1 && !listed_incremental_option)
2430 WARN ((0, 0,
2431 _("--level is meaningless without --listed-incremental")));
2432
2433 if (volume_label_option)
2434 {
2435 if (archive_format == GNU_FORMAT || archive_format == OLDGNU_FORMAT)
2436 {
2437 size_t volume_label_max_len =
2438 (sizeof current_header->header.name
2439 - 1 /* for trailing '\0' */
2440 - (multi_volume_option
2441 ? (sizeof " Volume "
2442 - 1 /* for null at end of " Volume " */
2443 + INT_STRLEN_BOUND (int) /* for volume number */
2444 - 1 /* for sign, as 0 <= volno */)
2445 : 0));
2446 if (volume_label_max_len < strlen (volume_label_option))
2447 USAGE_ERROR ((0, 0,
2448 ngettext ("%s: Volume label is too long (limit is %lu byte)",
2449 "%s: Volume label is too long (limit is %lu bytes)",
2450 volume_label_max_len),
2451 quotearg_colon (volume_label_option),
2452 (unsigned long) volume_label_max_len));
2453 }
2454 /* else FIXME
2455 Label length in PAX format is limited by the volume size. */
2456 }
2457
2458 if (verify_option)
2459 {
2460 if (multi_volume_option)
2461 USAGE_ERROR ((0, 0, _("Cannot verify multi-volume archives")));
2462 if (use_compress_program_option)
2463 USAGE_ERROR ((0, 0, _("Cannot verify compressed archives")));
2464 if (!IS_SUBCOMMAND_CLASS (SUBCL_WRITE))
2465 USAGE_ERROR ((0, 0, _("--verify cannot be used with %s"),
2466 subcommand_string (subcommand_option)));
2467 }
2468
2469 if (use_compress_program_option)
2470 {
2471 if (multi_volume_option)
2472 USAGE_ERROR ((0, 0, _("Cannot use multi-volume compressed archives")));
2473 if (IS_SUBCOMMAND_CLASS (SUBCL_UPDATE))
2474 USAGE_ERROR ((0, 0, _("Cannot update compressed archives")));
2475 if (subcommand_option == CAT_SUBCOMMAND)
2476 USAGE_ERROR ((0, 0, _("Cannot concatenate compressed archives")));
2477 }
2478
2479 /* It is no harm to use --pax-option on non-pax archives in archive
2480 reading mode. It may even be useful, since it allows to override
2481 file attributes from tar headers. Therefore I allow such usage.
2482 --gray */
2483 if (args.pax_option
2484 && archive_format != POSIX_FORMAT
2485 && !IS_SUBCOMMAND_CLASS (SUBCL_READ))
2486 USAGE_ERROR ((0, 0, _("--pax-option can be used only on POSIX archives")));
2487
2488 /* star creates non-POSIX typed archives with xattr support, so allow the
2489 extra headers when reading */
2490 if ((acls_option > 0)
2491 && archive_format != POSIX_FORMAT
2492 && !IS_SUBCOMMAND_CLASS (SUBCL_READ))
2493 USAGE_ERROR ((0, 0, _("--acls can be used only on POSIX archives")));
2494
2495 if ((selinux_context_option > 0)
2496 && archive_format != POSIX_FORMAT
2497 && !IS_SUBCOMMAND_CLASS (SUBCL_READ))
2498 USAGE_ERROR ((0, 0, _("--selinux can be used only on POSIX archives")));
2499
2500 if ((xattrs_option > 0)
2501 && archive_format != POSIX_FORMAT
2502 && !IS_SUBCOMMAND_CLASS (SUBCL_READ))
2503 USAGE_ERROR ((0, 0, _("--xattrs can be used only on POSIX archives")));
2504
2505 if ((starting_file_option || same_order_option)
2506 && !IS_SUBCOMMAND_CLASS (SUBCL_READ))
2507 USAGE_ERROR ((0, 0,
2508 _("--%s option cannot be used with %s"),
2509 starting_file_option ? "starting-file" : "same-order",
2510 subcommand_string (subcommand_option)));
2511
2512 /* If ready to unlink hierarchies, so we are for simpler files. */
2513 if (recursive_unlink_option)
2514 old_files_option = UNLINK_FIRST_OLD_FILES;
2515
2516 /* Flags for accessing files to be read from or copied into. POSIX says
2517 O_NONBLOCK has unspecified effect on most types of files, but in
2518 practice it never harms and sometimes helps. */
2519 {
2520 int base_open_flags =
2521 (O_BINARY | O_CLOEXEC | O_NOCTTY | O_NONBLOCK
2522 | (dereference_option ? 0 : O_NOFOLLOW)
2523 | (atime_preserve_option == system_atime_preserve ? O_NOATIME : 0));
2524 open_read_flags = O_RDONLY | base_open_flags;
2525 open_searchdir_flags = O_SEARCH | O_DIRECTORY | base_open_flags;
2526 }
2527 fstatat_flags = dereference_option ? 0 : AT_SYMLINK_NOFOLLOW;
2528
2529 if (subcommand_option == TEST_LABEL_SUBCOMMAND)
2530 {
2531 /* --test-label is silent if the user has specified the label name to
2532 compare against. */
2533 if (!args.input_files)
2534 verbose_option++;
2535 }
2536 else if (utc_option)
2537 verbose_option = 2;
2538
2539 if (tape_length_option && tape_length_option < record_size)
2540 USAGE_ERROR ((0, 0, _("Volume length cannot be less than record size")));
2541
2542 if (same_order_option && listed_incremental_option)
2543 USAGE_ERROR ((0, 0, _("--preserve-order is not compatible with "
2544 "--listed-incremental")));
2545
2546 /* Forbid using -c with no input files whatsoever. Check that '-f -',
2547 explicit or implied, is used correctly. */
2548
2549 switch (subcommand_option)
2550 {
2551 case CREATE_SUBCOMMAND:
2552 if (!args.input_files && !files_from_option)
2553 USAGE_ERROR ((0, 0,
2554 _("Cowardly refusing to create an empty archive")));
2555 if (args.compress_autodetect && archive_names
2556 && strcmp (archive_name_array[0], "-"))
2557 set_compression_program_by_suffix (archive_name_array[0],
2558 use_compress_program_option);
2559 break;
2560
2561 case EXTRACT_SUBCOMMAND:
2562 case LIST_SUBCOMMAND:
2563 case DIFF_SUBCOMMAND:
2564 case TEST_LABEL_SUBCOMMAND:
2565 for (archive_name_cursor = archive_name_array;
2566 archive_name_cursor < archive_name_array + archive_names;
2567 archive_name_cursor++)
2568 if (!strcmp (*archive_name_cursor, "-"))
2569 request_stdin ("-f");
2570 break;
2571
2572 case CAT_SUBCOMMAND:
2573 case UPDATE_SUBCOMMAND:
2574 case APPEND_SUBCOMMAND:
2575 for (archive_name_cursor = archive_name_array;
2576 archive_name_cursor < archive_name_array + archive_names;
2577 archive_name_cursor++)
2578 if (!strcmp (*archive_name_cursor, "-"))
2579 USAGE_ERROR ((0, 0,
2580 _("Options '-Aru' are incompatible with '-f -'")));
2581
2582 default:
2583 break;
2584 }
2585
2586 /* Initialize stdlis */
2587 if (index_file_name)
2588 {
2589 stdlis = fopen (index_file_name, "w");
2590 if (! stdlis)
2591 open_fatal (index_file_name);
2592 }
2593 else
2594 stdlis = to_stdout_option ? stderr : stdout;
2595
2596 archive_name_cursor = archive_name_array;
2597
2598 /* Prepare for generating backup names. */
2599
2600 if (args.backup_suffix_string)
2601 simple_backup_suffix = xstrdup (args.backup_suffix_string);
2602
2603 if (backup_option)
2604 {
2605 backup_type = xget_version ("--backup", args.version_control_string);
2606 /* No backup is needed either if explicitely disabled or if
2607 the extracted files are not being written to disk. */
2608 if (backup_type == no_backups || EXTRACT_OVER_PIPE)
2609 backup_option = false;
2610 }
2611
2612 checkpoint_finish_compile ();
2613
2614 report_textual_dates (&args);
2615 }
2616
2617 void
2618 more_options (int argc, char **argv)
2619 {
2620 int idx;
2621 if (argp_parse (&argp, argc, argv, ARGP_IN_ORDER,
2622 &idx, &args))
2623 exit (TAREXIT_FAILURE);
2624 }
2625 \f
2626 /* Tar proper. */
2627
2628 /* Main routine for tar. */
2629 int
2630 main (int argc, char **argv)
2631 {
2632 set_start_time ();
2633 set_program_name (argv[0]);
2634
2635 setlocale (LC_ALL, "");
2636 bindtextdomain (PACKAGE, LOCALEDIR);
2637 textdomain (PACKAGE);
2638
2639 exit_failure = TAREXIT_FAILURE;
2640 exit_status = TAREXIT_SUCCESS;
2641 error_hook = checkpoint_flush_actions;
2642
2643 filename_terminator = '\n';
2644 set_quoting_style (0, DEFAULT_QUOTING_STYLE);
2645
2646 /* Make sure we have first three descriptors available */
2647 stdopen ();
2648
2649 /* Pre-allocate a few structures. */
2650
2651 allocated_archive_names = 10;
2652 archive_name_array =
2653 xmalloc (sizeof (const char *) * allocated_archive_names);
2654 archive_names = 0;
2655
2656 /* System V fork+wait does not work if SIGCHLD is ignored. */
2657 signal (SIGCHLD, SIG_DFL);
2658
2659 /* Try to disable the ability to unlink a directory. */
2660 priv_set_remove_linkdir ();
2661
2662 /* Decode options. */
2663
2664 decode_options (argc, argv);
2665
2666 name_init ();
2667
2668 /* Main command execution. */
2669
2670 if (volno_file_option)
2671 init_volume_number ();
2672
2673 switch (subcommand_option)
2674 {
2675 case UNKNOWN_SUBCOMMAND:
2676 USAGE_ERROR ((0, 0,
2677 _("You must specify one of the '-Acdtrux', '--delete' or '--test-label' options")));
2678
2679 case CAT_SUBCOMMAND:
2680 case UPDATE_SUBCOMMAND:
2681 case APPEND_SUBCOMMAND:
2682 update_archive ();
2683 break;
2684
2685 case DELETE_SUBCOMMAND:
2686 delete_archive_members ();
2687 break;
2688
2689 case CREATE_SUBCOMMAND:
2690 create_archive ();
2691 break;
2692
2693 case EXTRACT_SUBCOMMAND:
2694 extr_init ();
2695 read_and (extract_archive);
2696
2697 /* FIXME: should extract_finish () even if an ordinary signal is
2698 received. */
2699 extract_finish ();
2700
2701 break;
2702
2703 case LIST_SUBCOMMAND:
2704 read_and (list_archive);
2705 break;
2706
2707 case DIFF_SUBCOMMAND:
2708 diff_init ();
2709 read_and (diff_archive);
2710 break;
2711
2712 case TEST_LABEL_SUBCOMMAND:
2713 test_archive_label ();
2714 }
2715
2716 checkpoint_finish ();
2717
2718 if (totals_option)
2719 print_total_stats ();
2720
2721 if (check_links_option)
2722 check_links ();
2723
2724 if (volno_file_option)
2725 closeout_volume_number ();
2726
2727 /* Dispose of allocated memory, and return. */
2728
2729 free (archive_name_array);
2730 xattrs_clear_setup ();
2731 name_term ();
2732
2733 if (exit_status == TAREXIT_FAILURE)
2734 error (0, 0, _("Exiting with failure status due to previous errors"));
2735
2736 if (stdlis == stdout)
2737 close_stdout ();
2738 else if (ferror (stderr) || fclose (stderr) != 0)
2739 set_exit_status (TAREXIT_FAILURE);
2740
2741 return exit_status;
2742 }
2743
2744 void
2745 tar_stat_init (struct tar_stat_info *st)
2746 {
2747 memset (st, 0, sizeof (*st));
2748 }
2749
2750 /* Close the stream or file descriptor associated with ST, and remove
2751 all traces of it from ST. Return true if successful, false (with a
2752 diagnostic) otherwise. */
2753 bool
2754 tar_stat_close (struct tar_stat_info *st)
2755 {
2756 int status = (st->dirstream ? closedir (st->dirstream)
2757 : 0 < st->fd ? close (st->fd)
2758 : 0);
2759 st->dirstream = 0;
2760 st->fd = 0;
2761
2762 if (status == 0)
2763 return true;
2764 else
2765 {
2766 close_diag (st->orig_file_name);
2767 return false;
2768 }
2769 }
2770
2771 void
2772 tar_stat_destroy (struct tar_stat_info *st)
2773 {
2774 tar_stat_close (st);
2775 xheader_xattr_free (st->xattr_map, st->xattr_map_size);
2776 free (st->orig_file_name);
2777 free (st->file_name);
2778 free (st->link_name);
2779 free (st->uname);
2780 free (st->gname);
2781 free (st->cntx_name);
2782 free (st->acls_a_ptr);
2783 free (st->acls_d_ptr);
2784 free (st->sparse_map);
2785 free (st->dumpdir);
2786 xheader_destroy (&st->xhdr);
2787 memset (st, 0, sizeof (*st));
2788 }
2789
2790 /* Format mask for all available formats that support nanosecond
2791 timestamp resolution. */
2792 #define NS_PRECISION_FORMAT_MASK FORMAT_MASK (POSIX_FORMAT)
2793
2794 /* Same as timespec_cmp, but ignore nanoseconds if current archive
2795 format does not provide sufficient resolution. */
2796 int
2797 tar_timespec_cmp (struct timespec a, struct timespec b)
2798 {
2799 if (!(FORMAT_MASK (current_format) & NS_PRECISION_FORMAT_MASK))
2800 a.tv_nsec = b.tv_nsec = 0;
2801 return timespec_cmp (a, b);
2802 }
2803
2804 /* Set tar exit status to VAL, unless it is already indicating
2805 a more serious condition. This relies on the fact that the
2806 values of TAREXIT_ constants are ranged by severity. */
2807 void
2808 set_exit_status (int val)
2809 {
2810 if (val > exit_status)
2811 exit_status = val;
2812 }
This page took 0.212853 seconds and 3 git commands to generate.