1 /* A tar (tape archiver) program.
3 Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1999, 2000,
4 2001, 2003 Free Software Foundation, Inc.
6 Written by John Gilmore, starting 1985-08-25.
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 2, or (at your option) any later
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.
18 You should have received a copy of the GNU General Public License along
19 with this program; if not, write to the Free Software Foundation, Inc.,
20 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
28 #if ! defined SIGCHLD && defined SIGCLD
29 # define SIGCHLD SIGCLD
32 /* The following causes "common.h" to produce definitions of all the global
33 variables, rather than just "extern" declarations of them. GNU tar does
34 depend on the system loader to preset all GLOBAL variables to neutral (or
35 zero) values; explicit initialization is usually not done. */
40 #include <localedir.h>
45 /* Local declarations. */
47 #ifndef DEFAULT_ARCHIVE_FORMAT
48 # define DEFAULT_ARCHIVE_FORMAT GNU_FORMAT
51 #ifndef DEFAULT_ARCHIVE
52 # define DEFAULT_ARCHIVE "tar.out"
55 #ifndef DEFAULT_BLOCKING
56 # define DEFAULT_BLOCKING 20
59 void usage (int) __attribute__ ((noreturn
));
63 /* Name of option using stdin. */
64 static const char *stdin_used_by
;
66 /* Doesn't return if stdin already requested. */
68 request_stdin (const char *option
)
71 USAGE_ERROR ((0, 0, _("Options `-%s' and `-%s' both want standard input"),
72 stdin_used_by
, option
));
74 stdin_used_by
= option
;
77 /* Returns true if and only if the user typed 'y' or 'Y'. */
79 confirm (const char *message_action
, const char *message_name
)
81 static FILE *confirm_file
;
82 static int confirm_file_EOF
;
86 if (archive
== 0 || stdin_used_by
)
88 confirm_file
= fopen (TTY_NAME
, "r");
90 open_fatal (TTY_NAME
);
99 fprintf (stdlis
, "%s %s?", message_action
, quote (message_name
));
103 int reply
= confirm_file_EOF
? EOF
: getc (confirm_file
);
106 for (character
= reply
;
108 character
= getc (confirm_file
))
109 if (character
== EOF
)
111 confirm_file_EOF
= 1;
112 fputc ('\n', stdlis
);
116 return reply
== 'y' || reply
== 'Y';
120 static struct fmttab
{
122 enum archive_format fmt
;
125 { "oldgnu", OLDGNU_FORMAT
},
126 { "ustar", USTAR_FORMAT
},
127 { "posix", POSIX_FORMAT
},
128 #if 0 /* not fully supported yet */
129 { "star", STAR_FORMAT
},
131 { "gnu", GNU_FORMAT
},
136 set_archive_format (char const *name
)
138 struct fmttab
const *p
;
140 for (p
= fmttab
; strcmp (p
->name
, name
) != 0; )
142 USAGE_ERROR ((0, 0, _("%s: Invalid archive format"),
143 quotearg_colon (name
)));
145 if (archive_format
!= DEFAULT_FORMAT
&& archive_format
!= p
->fmt
)
146 USAGE_ERROR ((0, 0, _("Conflicting archive format options")));
148 archive_format
= p
->fmt
;
152 archive_format_string (enum archive_format fmt
)
154 struct fmttab
const *p
;
156 for (p
= fmttab
; p
->name
; p
++)
162 #define FORMAT_MASK(n) (1<<(n))
165 assert_format(unsigned fmt_mask
)
167 if ((FORMAT_MASK(archive_format
) & fmt_mask
) == 0)
169 _("GNU features wanted on incompatible archive format")));
176 /* For long options that unconditionally set a single flag, we have getopt
177 do it. For the others, we share the code for the equivalent short
178 named option, the name of which is stored in the otherwise-unused `val'
179 field of the `struct option'; for long options that have no equivalent
180 short option, we use non-characters as pseudo short options,
181 starting at CHAR_MAX + 1 and going upwards. */
185 ANCHORED_OPTION
= CHAR_MAX
+ 1,
186 ATIME_PRESERVE_OPTION
,
195 IGNORE_FAILED_READ_OPTION
,
200 NO_IGNORE_CASE_OPTION
,
201 NO_OVERWRITE_DIR_OPTION
,
203 NO_WILDCARDS_MATCH_SLASH_OPTION
,
205 NUMERIC_OWNER_OPTION
,
213 RECURSIVE_UNLINK_OPTION
,
216 SHOW_OMITTED_DIRS_OPTION
,
220 USE_COMPRESS_PROGRAM_OPTION
,
223 WILDCARDS_MATCH_SLASH_OPTION
226 /* If nonzero, display usage information and exit. */
227 static int show_help
;
229 /* If nonzero, print the version on standard output and exit. */
230 static int show_version
;
232 static struct option long_options
[] =
234 {"absolute-names", no_argument
, 0, 'P'},
235 {"after-date", required_argument
, 0, 'N'},
236 {"anchored", no_argument
, 0, ANCHORED_OPTION
},
237 {"append", no_argument
, 0, 'r'},
238 {"atime-preserve", no_argument
, 0, ATIME_PRESERVE_OPTION
},
239 {"backup", optional_argument
, 0, BACKUP_OPTION
},
240 {"block-number", no_argument
, 0, 'R'},
241 {"blocking-factor", required_argument
, 0, 'b'},
242 {"bzip2", no_argument
, 0, 'j'},
243 {"catenate", no_argument
, 0, 'A'},
244 {"checkpoint", no_argument
, 0, CHECKPOINT_OPTION
},
245 {"check-links", no_argument
, &check_links_option
, 1},
246 {"compare", no_argument
, 0, 'd'},
247 {"compress", no_argument
, 0, 'Z'},
248 {"concatenate", no_argument
, 0, 'A'},
249 {"confirmation", no_argument
, 0, 'w'},
250 /* FIXME: --selective as a synonym for --confirmation? */
251 {"create", no_argument
, 0, 'c'},
252 {"delete", no_argument
, 0, DELETE_OPTION
},
253 {"dereference", no_argument
, 0, 'h'},
254 {"diff", no_argument
, 0, 'd'},
255 {"directory", required_argument
, 0, 'C'},
256 {"exclude", required_argument
, 0, EXCLUDE_OPTION
},
257 {"exclude-from", required_argument
, 0, 'X'},
258 {"extract", no_argument
, 0, 'x'},
259 {"file", required_argument
, 0, 'f'},
260 {"files-from", required_argument
, 0, 'T'},
261 {"force-local", no_argument
, 0, FORCE_LOCAL_OPTION
},
262 {"format", required_argument
, 0, FORMAT_OPTION
},
263 {"get", no_argument
, 0, 'x'},
264 {"group", required_argument
, 0, GROUP_OPTION
},
265 {"gunzip", no_argument
, 0, 'z'},
266 {"gzip", no_argument
, 0, 'z'},
267 {"help", no_argument
, &show_help
, 1},
268 {"ignore-case", no_argument
, 0, IGNORE_CASE_OPTION
},
269 {"ignore-failed-read", no_argument
, 0, IGNORE_FAILED_READ_OPTION
},
270 {"ignore-zeros", no_argument
, 0, 'i'},
271 /* FIXME: --ignore-end as a new name for --ignore-zeros? */
272 {"incremental", no_argument
, 0, 'G'},
273 {"index-file", required_argument
, 0, INDEX_FILE_OPTION
},
274 {"info-script", required_argument
, 0, 'F'},
275 {"interactive", no_argument
, 0, 'w'},
276 {"keep-old-files", no_argument
, 0, 'k'},
277 {"label", required_argument
, 0, 'V'},
278 {"list", no_argument
, 0, 't'},
279 {"listed-incremental", required_argument
, 0, 'g'},
280 {"mode", required_argument
, 0, MODE_OPTION
},
281 {"multi-volume", no_argument
, 0, 'M'},
282 {"new-volume-script", required_argument
, 0, 'F'},
283 {"newer", required_argument
, 0, 'N'},
284 {"newer-mtime", required_argument
, 0, NEWER_MTIME_OPTION
},
285 {"null", no_argument
, 0, NULL_OPTION
},
286 {"no-anchored", no_argument
, 0, NO_ANCHORED_OPTION
},
287 {"no-ignore-case", no_argument
, 0, NO_IGNORE_CASE_OPTION
},
288 {"no-overwrite-dir", no_argument
, 0, NO_OVERWRITE_DIR_OPTION
},
289 {"no-wildcards", no_argument
, 0, NO_WILDCARDS_OPTION
},
290 {"no-wildcards-match-slash", no_argument
, 0, NO_WILDCARDS_MATCH_SLASH_OPTION
},
291 {"no-recursion", no_argument
, &recursion_option
, 0},
292 {"no-same-owner", no_argument
, &same_owner_option
, -1},
293 {"no-same-permissions", no_argument
, &same_permissions_option
, -1},
294 {"numeric-owner", no_argument
, 0, NUMERIC_OWNER_OPTION
},
295 {"occurrence", optional_argument
, 0, OCCURRENCE_OPTION
},
296 {"old-archive", no_argument
, 0, 'o'},
297 {"one-file-system", no_argument
, 0, 'l'},
298 {"overwrite", no_argument
, 0, OVERWRITE_OPTION
},
299 {"owner", required_argument
, 0, OWNER_OPTION
},
300 {"pax-option", required_argument
, 0, PAX_OPTION
},
301 {"portability", no_argument
, 0, 'o'},
302 {"posix", no_argument
, 0, POSIX_OPTION
},
303 {"preserve", no_argument
, 0, PRESERVE_OPTION
},
304 {"preserve-order", no_argument
, 0, 's'},
305 {"preserve-permissions", no_argument
, 0, 'p'},
306 {"recursion", no_argument
, &recursion_option
, FNM_LEADING_DIR
},
307 {"recursive-unlink", no_argument
, 0, RECURSIVE_UNLINK_OPTION
},
308 {"read-full-records", no_argument
, 0, 'B'},
309 /* FIXME: --partial-blocks might be a synonym for --read-full-records? */
310 {"record-size", required_argument
, 0, RECORD_SIZE_OPTION
},
311 {"remove-files", no_argument
, 0, REMOVE_FILES_OPTION
},
312 {"rsh-command", required_argument
, 0, RSH_COMMAND_OPTION
},
313 {"same-order", no_argument
, 0, 's'},
314 {"same-owner", no_argument
, &same_owner_option
, 1},
315 {"same-permissions", no_argument
, 0, 'p'},
316 {"show-omitted-dirs", no_argument
, 0, SHOW_OMITTED_DIRS_OPTION
},
317 {"sparse", no_argument
, 0, 'S'},
318 {"starting-file", required_argument
, 0, 'K'},
319 {"strip-path", required_argument
, 0, STRIP_PATH_OPTION
},
320 {"suffix", required_argument
, 0, SUFFIX_OPTION
},
321 {"tape-length", required_argument
, 0, 'L'},
322 {"to-stdout", no_argument
, 0, 'O'},
323 {"totals", no_argument
, 0, TOTALS_OPTION
},
324 {"touch", no_argument
, 0, 'm'},
325 {"uncompress", no_argument
, 0, 'Z'},
326 {"ungzip", no_argument
, 0, 'z'},
327 {"unlink-first", no_argument
, 0, 'U'},
328 {"update", no_argument
, 0, 'u'},
329 {"use-compress-program", required_argument
, 0, USE_COMPRESS_PROGRAM_OPTION
},
330 {"verbose", no_argument
, 0, 'v'},
331 {"verify", no_argument
, 0, 'W'},
332 {"version", no_argument
, &show_version
, 1},
333 {"volno-file", required_argument
, 0, VOLNO_FILE_OPTION
},
334 {"wildcards", no_argument
, 0, WILDCARDS_OPTION
},
335 {"wildcards-match-slash", no_argument
, 0, WILDCARDS_MATCH_SLASH_OPTION
},
340 /* Print a usage message and exit with STATUS. */
344 if (status
!= TAREXIT_SUCCESS
)
345 fprintf (stderr
, _("Try `%s --help' for more information.\n"),
350 GNU `tar' saves many files together into a single tape or disk archive, and\n\
351 can restore individual files from the archive.\n"),
353 printf (_("\nUsage: %s [OPTION]... [FILE]...\n\
356 %s -cf archive.tar foo bar # Create archive.tar from files foo and bar.\n\
357 %s -tvf archive.tar # List all files in archive.tar verbosely.\n\
358 %s -xf archive.tar # Extract all files from archive.tar.\n"),
359 program_name
, program_name
, program_name
, program_name
);
362 If a long option shows an argument as mandatory, then it is mandatory\n\
363 for the equivalent short option also. Similarly for optional arguments.\n"),
367 Main operation mode:\n\
368 -t, --list list the contents of an archive\n\
369 -x, --extract, --get extract files from an archive\n\
370 -c, --create create a new archive\n\
371 -d, --diff, --compare find differences between archive and file system\n\
372 -r, --append append files to the end of an archive\n\
373 -u, --update only append files newer than copy in archive\n\
374 -A, --catenate append tar files to an archive\n\
375 --concatenate same as -A\n\
376 --delete delete from the archive (not on mag tapes!)\n"),
380 Operation modifiers:\n\
381 -W, --verify attempt to verify the archive after writing it\n\
382 --remove-files remove files after adding them to the archive\n\
383 -k, --keep-old-files don't replace existing files when extracting\n\
384 --overwrite overwrite existing files when extracting\n\
385 --no-overwrite-dir preserve metadata of existing directories\n\
386 -U, --unlink-first remove each file prior to extracting over it\n\
387 --recursive-unlink empty hierarchies prior to extracting directory\n\
388 -S, --sparse handle sparse files efficiently\n\
389 -O, --to-stdout extract files to standard output\n\
390 -G, --incremental handle old GNU-format incremental backup\n\
391 -g, --listed-incremental=FILE\n\
392 handle new GNU-format incremental backup\n\
393 --ignore-failed-read do not exit with nonzero on unreadable files\n\
394 --occurrence[=NUM] process only the NUMth occurrence of each file in\n\
395 the archive. This option is valid only in\n\
396 conjunction with one of the subcommands --delete,\n\
397 --diff, --extract or --list and when a list of\n\
398 files is given either on the command line or\n\
400 NUM defaults to 1.\n"),
404 Handling of file attributes:\n\
405 --owner=NAME force NAME as owner for added files\n\
406 --group=NAME force NAME as group for added files\n\
407 --mode=CHANGES force (symbolic) mode CHANGES for added files\n\
408 --atime-preserve don't change access times on dumped files\n\
409 -m, --modification-time don't extract file modified time\n\
410 --same-owner try extracting files with the same ownership\n\
411 --no-same-owner extract files as yourself\n\
412 --numeric-owner always use numbers for user/group names\n\
413 -p, --same-permissions extract permissions information\n\
414 --no-same-permissions do not extract permissions information\n\
415 --preserve-permissions same as -p\n\
416 -s, --same-order sort names to extract to match archive\n\
417 --preserve-order same as -s\n\
418 --preserve same as both -p and -s\n"),
422 Device selection and switching:\n\
423 -f, --file=ARCHIVE use archive file or device ARCHIVE\n\
424 --force-local archive file is local even if has a colon\n\
425 --rsh-command=COMMAND use remote COMMAND instead of rsh\n\
426 -[0-7][lmh] specify drive and density\n\
427 -M, --multi-volume create/list/extract multi-volume archive\n\
428 -L, --tape-length=NUM change tape after writing NUM x 1024 bytes\n\
429 -F, --info-script=FILE run script at end of each tape (implies -M)\n\
430 --new-volume-script=FILE same as -F FILE\n\
431 --volno-file=FILE use/update the volume number in FILE\n"),
436 -b, --blocking-factor=BLOCKS BLOCKS x 512 bytes per record\n\
437 --record-size=SIZE SIZE bytes per record, multiple of 512\n\
438 -i, --ignore-zeros ignore zeroed blocks in archive (means EOF)\n\
439 -B, --read-full-records reblock as we read (for 4.2BSD pipes)\n"),
443 Archive format selection:\n\
444 --format=FMTNAME create archive of the given format.\n\
445 FMTNAME is one of the following:\n\
446 v7 old V7 tar format\n\
447 oldgnu GNU format as per tar <= 1.12\n\
448 gnu GNU tar 1.13 format\n\
449 ustar POSIX 1003.1-1988 (ustar) format\n\
450 posix POSIX 1003.1-2001 (pax) format\n\
451 --old-archive, --portability same as --format=v7\n\
452 --posix same as --format=posix\n\
453 --pax-option keyword[[:]=value][,keyword[[:]=value], ...]\n\
454 control pax keywords\n\
455 -V, --label=NAME create archive with volume name NAME\n\
456 PATTERN at list/extract time, a globbing PATTERN\n\
457 -j, --bzip2 filter the archive through bzip2\n\
458 -z, --gzip, --ungzip filter the archive through gzip\n\
459 -Z, --compress, --uncompress filter the archive through compress\n\
460 --use-compress-program=PROG filter through PROG (must accept -d)\n"),
464 Local file selection:\n\
465 -C, --directory=DIR change to directory DIR\n\
466 -T, --files-from=NAME get names to extract or create from file NAME\n\
467 --null -T reads null-terminated names, disable -C\n\
468 --exclude=PATTERN exclude files, given as a PATTERN\n\
469 -X, --exclude-from=FILE exclude patterns listed in FILE\n\
470 --anchored exclude patterns match file name start (default)\n\
471 --no-anchored exclude patterns match after any /\n\
472 --ignore-case exclusion ignores case\n\
473 --no-ignore-case exclusion is case sensitive (default)\n\
474 --wildcards exclude patterns use wildcards (default)\n\
475 --no-wildcards exclude patterns are plain strings\n\
476 --wildcards-match-slash exclude pattern wildcards match '/' (default)\n\
477 --no-wildcards-match-slash exclude pattern wildcards do not match '/'\n\
478 -P, --absolute-names don't strip leading `/'s from file names\n\
479 -h, --dereference dump instead the files symlinks point to\n\
480 --no-recursion avoid descending automatically in directories\n\
481 -l, --one-file-system stay in local file system when creating archive\n\
482 -K, --starting-file=NAME begin at file NAME in the archive\n\
483 --strip-path=NUM strip NUM leading components from file names\n\
484 before extraction\n"),
488 -N, --newer=DATE-OR-FILE only store files newer than DATE-OR-FILE\n\
489 --newer-mtime=DATE compare date and time when data changed only\n\
490 --after-date=DATE same as -N\n"),
494 --backup[=CONTROL] backup before removal, choose version control\n\
495 --suffix=SUFFIX backup before removal, override usual suffix\n"),
499 Informative output:\n\
500 --help print this help, then exit\n\
501 --version print tar program version number, then exit\n\
502 -v, --verbose verbosely list files processed\n\
503 --checkpoint print directory names while reading the archive\n\
504 --check-links print a message if not all links are dumped\n\
505 --totals print total bytes written while creating archive\n\
506 --index-file=FILE send verbose output to FILE\n\
507 -R, --block-number show block number within archive with each message\n\
508 -w, --interactive ask for confirmation for every action\n\
509 --confirmation same as -w\n"),
513 Compatibility options:\n\
514 -o when creating, same as --old-archive\n\
515 when extracting, same as --no-same-owner\n"),
520 The backup suffix is `~', unless set with --suffix or SIMPLE_BACKUP_SUFFIX.\n\
521 The version control may be set with --backup or VERSION_CONTROL, values are:\n\
523 t, numbered make numbered backups\n\
524 nil, existing numbered if numbered backups exist, simple otherwise\n\
525 never, simple always make simple backups\n"),
529 ARCHIVE may be FILE, HOST:FILE or USER@HOST:FILE; DATE may be a textual date\n\
530 or a file name starting with `/' or `.', in which case the file's date is used.\n\
531 *This* `tar' defaults to `--format=%s -f%s -b%d'.\n"),
532 archive_format_string (DEFAULT_ARCHIVE_FORMAT
),
533 DEFAULT_ARCHIVE
, DEFAULT_BLOCKING
);
534 printf (_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT
);
539 /* Parse the options for tar. */
541 /* Available option letters are DEHIJQY and aenqy. Some are reserved:
543 e exit immediately with a nonzero exit status if unexpected errors occur
544 E use extended headers (draft POSIX headers, that is)
545 I same as T (for compatibility with Solaris tar)
546 n the archive is quickly seekable, so don't worry about random seeks
547 q stop after extracting the first occurrence of the named file
548 y per-file gzip compression
549 Y per-block gzip compression */
551 #define OPTION_STRING \
552 "-01234567ABC:F:GIK:L:MN:OPRST:UV:WX:Zb:cdf:g:hijklmoprstuvwxyz"
555 set_subcommand_option (enum subcommand subcommand
)
557 if (subcommand_option
!= UNKNOWN_SUBCOMMAND
558 && subcommand_option
!= subcommand
)
560 _("You may not specify more than one `-Acdtrux' option")));
562 subcommand_option
= subcommand
;
566 set_use_compress_program_option (const char *string
)
568 if (use_compress_program_option
&& strcmp (use_compress_program_option
, string
) != 0)
569 USAGE_ERROR ((0, 0, _("Conflicting compression options")));
571 use_compress_program_option
= string
;
575 decode_options (int argc
, char **argv
)
577 int optchar
; /* option letter */
578 int input_files
; /* number of input files */
579 char const *textual_date_option
= 0;
580 char const *backup_suffix_string
;
581 char const *version_control_string
= 0;
582 int exclude_options
= EXCLUDE_WILDCARDS
;
585 /* Set some default option values. */
587 subcommand_option
= UNKNOWN_SUBCOMMAND
;
588 archive_format
= DEFAULT_FORMAT
;
589 blocking_factor
= DEFAULT_BLOCKING
;
590 record_size
= DEFAULT_BLOCKING
* BLOCKSIZE
;
591 excluded
= new_exclude ();
592 newer_mtime_option
= TYPE_MINIMUM (time_t);
593 recursion_option
= FNM_LEADING_DIR
;
598 backup_suffix_string
= getenv ("SIMPLE_BACKUP_SUFFIX");
600 /* Convert old-style tar call by exploding option element and rearranging
601 options accordingly. */
603 if (argc
> 1 && argv
[1][0] != '-')
605 int new_argc
; /* argc value for rearranged arguments */
606 char **new_argv
; /* argv value for rearranged arguments */
607 char *const *in
; /* cursor into original argv */
608 char **out
; /* cursor into rearranged argv */
609 const char *letter
; /* cursor into old option letters */
610 char buffer
[3]; /* constructed option buffer */
611 const char *cursor
; /* cursor in OPTION_STRING */
613 /* Initialize a constructed option. */
618 /* Allocate a new argument array, and copy program name in it. */
620 new_argc
= argc
- 1 + strlen (argv
[1]);
621 new_argv
= xmalloc ((new_argc
+ 1) * sizeof (char *));
626 /* Copy each old letter option as a separate option, and have the
627 corresponding argument moved next to it. */
629 for (letter
= *in
++; *letter
; letter
++)
632 *out
++ = xstrdup (buffer
);
633 cursor
= strchr (OPTION_STRING
, *letter
);
634 if (cursor
&& cursor
[1] == ':')
636 if (in
< argv
+ argc
)
639 USAGE_ERROR ((0, 0, _("Old option `%c' requires an argument."),
644 /* Copy all remaining options. */
646 while (in
< argv
+ argc
)
650 /* Replace the old option list by the new one. */
656 /* Parse all options and non-options as they appear. */
660 prepend_default_options (getenv ("TAR_OPTIONS"), &argc
, &argv
);
662 while (optchar
= getopt_long (argc
, argv
, OPTION_STRING
, long_options
, 0),
667 usage (TAREXIT_FAILURE
);
673 /* File name or non-parsed option, because of RETURN_IN_ORDER
674 ordering triggered by the leading dash in OPTION_STRING. */
681 set_subcommand_option (CAT_SUBCOMMAND
);
687 if (! (xstrtoumax (optarg
, 0, 10, &u
, "") == LONGINT_OK
688 && u
== (blocking_factor
= u
)
689 && 0 < blocking_factor
690 && u
== (record_size
= u
* BLOCKSIZE
) / BLOCKSIZE
))
691 USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (optarg
),
692 _("Invalid blocking factor")));
697 /* Try to reblock input records. For reading 4.2BSD pipes. */
699 /* It would surely make sense to exchange -B and -R, but it seems
700 that -B has been used for a long while in Sun tar ans most
701 BSD-derived systems. This is a consequence of the block/record
702 terminology confusion. */
704 read_full_records_option
= true;
708 set_subcommand_option (CREATE_SUBCOMMAND
);
717 set_subcommand_option (DIFF_SUBCOMMAND
);
721 if (archive_names
== allocated_archive_names
)
723 allocated_archive_names
*= 2;
725 xrealloc (archive_name_array
,
726 sizeof (const char *) * allocated_archive_names
);
728 archive_name_array
[archive_names
++] = optarg
;
732 /* Since -F is only useful with -M, make it implied. Run this
733 script at the end of each tape. */
735 info_script_option
= optarg
;
736 multi_volume_option
= true;
740 listed_incremental_option
= optarg
;
741 after_date_option
= true;
745 /* We are making an incremental dump (FIXME: are we?); save
746 directories at the beginning of the archive, and include in each
747 directory its contents. */
749 incremental_option
= true;
753 /* Follow symbolic links. */
754 dereference_option
= true;
758 /* Ignore zero blocks (eofs). This can't be the default,
759 because Unix tar writes two blocks of zeros, then pads out
760 the record with garbage. */
762 ignore_zeros_option
= true;
767 _("Warning: the -I option is not supported;"
768 " perhaps you meant -j or -T?")));
772 set_use_compress_program_option ("bzip2");
776 /* Don't replace existing files. */
777 old_files_option
= KEEP_OLD_FILES
;
781 starting_file_option
= true;
786 /* When dumping directories, don't dump files/subdirectories
787 that are on other filesystems. */
789 one_file_system_option
= true;
795 if (xstrtoumax (optarg
, 0, 10, &u
, "") != LONGINT_OK
)
796 USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (optarg
),
797 _("Invalid tape length")));
798 tape_length_option
= 1024 * (tarlong
) u
;
799 multi_volume_option
= true;
808 /* Make multivolume archive: when we can't write any more into
809 the archive, re-open it, and continue writing. */
811 multi_volume_option
= true;
816 after_date_option
= true;
819 case NEWER_MTIME_OPTION
:
820 if (newer_mtime_option
!= TYPE_MINIMUM (time_t))
821 USAGE_ERROR ((0, 0, _("More than one threshold date")));
823 if (FILESYSTEM_PREFIX_LEN (optarg
) != 0
828 if (deref_stat (dereference_option
, optarg
, &st
) != 0)
831 USAGE_ERROR ((0, 0, _("Date file not found")));
833 newer_mtime_option
= st
.st_mtime
;
837 newer_mtime_option
= get_date (optarg
, 0);
838 if (newer_mtime_option
== (time_t) -1)
839 WARN ((0, 0, _("Substituting %s for unknown date format %s"),
840 tartime (newer_mtime_option
), quote (optarg
)));
842 textual_date_option
= optarg
;
846 #endif /* not MSDOS */
853 to_stdout_option
= true;
857 same_permissions_option
= true;
861 absolute_names_option
= true;
865 set_subcommand_option (APPEND_SUBCOMMAND
);
869 /* Print block numbers for debugging bad tar archives. */
871 /* It would surely make sense to exchange -B and -R, but it seems
872 that -B has been used for a long while in Sun tar ans most
873 BSD-derived systems. This is a consequence of the block/record
874 terminology confusion. */
876 block_number_option
= true;
880 /* Names to extr are sorted. */
882 same_order_option
= true;
886 sparse_option
= true;
890 set_subcommand_option (LIST_SUBCOMMAND
);
895 files_from_option
= optarg
;
899 set_subcommand_option (UPDATE_SUBCOMMAND
);
903 old_files_option
= UNLINK_FIRST_OLD_FILES
;
911 volume_label_option
= optarg
;
915 interactive_option
= true;
919 verify_option
= true;
923 set_subcommand_option (EXTRACT_SUBCOMMAND
);
927 if (add_exclude_file (add_exclude
, excluded
, optarg
,
928 exclude_options
| recursion_option
, '\n')
932 FATAL_ERROR ((0, e
, "%s", quotearg_colon (optarg
)));
938 _("Warning: the -y option is not supported;"
939 " perhaps you meant -j?")));
943 set_use_compress_program_option ("gzip");
947 set_use_compress_program_option ("compress");
950 case ANCHORED_OPTION
:
951 exclude_options
|= EXCLUDE_ANCHORED
;
954 case ATIME_PRESERVE_OPTION
:
955 atime_preserve_option
= true;
958 case CHECKPOINT_OPTION
:
959 checkpoint_option
= true;
963 backup_option
= true;
965 version_control_string
= optarg
;
969 set_subcommand_option (DELETE_SUBCOMMAND
);
973 add_exclude (excluded
, optarg
, exclude_options
| recursion_option
);
976 case FORCE_LOCAL_OPTION
:
977 force_local_option
= true;
981 set_archive_format (optarg
);
984 case INDEX_FILE_OPTION
:
985 index_file_name
= optarg
;
988 case IGNORE_CASE_OPTION
:
989 exclude_options
|= FNM_CASEFOLD
;
992 case IGNORE_FAILED_READ_OPTION
:
993 ignore_failed_read_option
= true;
997 if (! (strlen (optarg
) < GNAME_FIELD_SIZE
998 && gname_to_gid (optarg
, &group_option
)))
1001 if (xstrtoumax (optarg
, 0, 10, &g
, "") == LONGINT_OK
1005 FATAL_ERROR ((0, 0, "%s: %s", quotearg_colon (optarg
),
1006 _("%s: Invalid group")));
1012 = mode_compile (optarg
,
1013 MODE_MASK_EQUALS
| MODE_MASK_PLUS
| MODE_MASK_MINUS
);
1014 if (mode_option
== MODE_INVALID
)
1015 FATAL_ERROR ((0, 0, _("Invalid mode given on option")));
1016 if (mode_option
== MODE_MEMORY_EXHAUSTED
)
1020 case NO_ANCHORED_OPTION
:
1021 exclude_options
&= ~ EXCLUDE_ANCHORED
;
1024 case NO_IGNORE_CASE_OPTION
:
1025 exclude_options
&= ~ FNM_CASEFOLD
;
1028 case NO_OVERWRITE_DIR_OPTION
:
1029 old_files_option
= NO_OVERWRITE_DIR_OLD_FILES
;
1032 case NO_WILDCARDS_OPTION
:
1033 exclude_options
&= ~ EXCLUDE_WILDCARDS
;
1036 case NO_WILDCARDS_MATCH_SLASH_OPTION
:
1037 exclude_options
|= FNM_FILE_NAME
;
1041 filename_terminator
= '\0';
1044 case NUMERIC_OWNER_OPTION
:
1045 numeric_owner_option
= true;
1048 case OCCURRENCE_OPTION
:
1050 occurrence_option
= 1;
1054 if (xstrtoumax (optarg
, 0, 10, &u
, "") == LONGINT_OK
)
1055 occurrence_option
= u
;
1057 FATAL_ERROR ((0, 0, "%s: %s", quotearg_colon (optarg
),
1058 _("Invalid number")));
1062 case OVERWRITE_OPTION
:
1063 old_files_option
= OVERWRITE_OLD_FILES
;
1067 if (! (strlen (optarg
) < UNAME_FIELD_SIZE
1068 && uname_to_uid (optarg
, &owner_option
)))
1071 if (xstrtoumax (optarg
, 0, 10, &u
, "") == LONGINT_OK
1075 FATAL_ERROR ((0, 0, "%s: %s", quotearg_colon (optarg
),
1076 _("Invalid owner")));
1081 xheader_set_option (optarg
);
1085 set_archive_format ("posix");
1088 case PRESERVE_OPTION
:
1089 same_permissions_option
= true;
1090 same_order_option
= true;
1093 case RECORD_SIZE_OPTION
:
1096 if (! (xstrtoumax (optarg
, 0, 10, &u
, "") == LONGINT_OK
1097 && u
== (size_t) u
))
1098 USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (optarg
),
1099 _("Invalid record size")));
1101 if (record_size
% BLOCKSIZE
!= 0)
1102 USAGE_ERROR ((0, 0, _("Record size must be a multiple of %d."),
1104 blocking_factor
= record_size
/ BLOCKSIZE
;
1108 case RECURSIVE_UNLINK_OPTION
:
1109 recursive_unlink_option
= true;
1112 case REMOVE_FILES_OPTION
:
1113 remove_files_option
= true;
1116 case RSH_COMMAND_OPTION
:
1117 rsh_command_option
= optarg
;
1120 case STRIP_PATH_OPTION
:
1123 if (! (xstrtoumax (optarg
, 0, 10, &u
, "") == LONGINT_OK
1124 && u
== (size_t) u
))
1125 USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (optarg
),
1126 _("Invalid number of elements")));
1127 strip_path_elements
= u
;
1132 backup_option
= true;
1133 backup_suffix_string
= optarg
;
1137 totals_option
= true;
1140 case USE_COMPRESS_PROGRAM_OPTION
:
1141 set_use_compress_program_option (optarg
);
1144 case VOLNO_FILE_OPTION
:
1145 volno_file_option
= optarg
;
1148 case WILDCARDS_OPTION
:
1149 exclude_options
|= EXCLUDE_WILDCARDS
;
1152 case WILDCARDS_MATCH_SLASH_OPTION
:
1153 exclude_options
&= ~ FNM_FILE_NAME
;
1165 #ifdef DEVICE_PREFIX
1167 int device
= optchar
- '0';
1169 static char buf
[sizeof DEVICE_PREFIX
+ 10];
1172 density
= getopt_long (argc
, argv
, "lmh", 0, 0);
1173 strcpy (buf
, DEVICE_PREFIX
);
1174 cursor
= buf
+ strlen (buf
);
1176 #ifdef DENSITY_LETTER
1178 sprintf (cursor
, "%d%c", device
, density
);
1180 #else /* not DENSITY_LETTER */
1207 usage (TAREXIT_FAILURE
);
1209 sprintf (cursor
, "%d", device
);
1211 #endif /* not DENSITY_LETTER */
1213 if (archive_names
== allocated_archive_names
)
1215 allocated_archive_names
*= 2;
1216 archive_name_array
=
1217 xrealloc (archive_name_array
,
1218 sizeof (const char *) * allocated_archive_names
);
1220 archive_name_array
[archive_names
++] = strdup (buf
);
1224 #else /* not DEVICE_PREFIX */
1227 _("Options `-[0-7][lmh]' not supported by *this* tar")));
1229 #endif /* not DEVICE_PREFIX */
1232 /* Special handling for 'o' option:
1234 GNU tar used to say "output old format".
1235 UNIX98 tar says don't chown files after extracting (we use
1236 "--no-same-owner" for this).
1238 The old GNU tar semantics is retained when used with --create
1239 option, otherwise UNIX98 semantics is assumed */
1243 if (subcommand_option
== CREATE_SUBCOMMAND
)
1245 /* GNU Tar <= 1.13 compatibility */
1246 set_archive_format ("v7");
1250 /* UNIX98 compatibility */
1251 same_owner_option
= 1;
1255 /* Handle operands after any "--" argument. */
1256 for (; optind
< argc
; optind
++)
1258 name_add (argv
[optind
]);
1262 /* Process trivial options. */
1266 printf ("tar (%s) %s\n%s\n", PACKAGE_NAME
, PACKAGE_VERSION
,
1267 "Copyright (C) 2003 Free Software Foundation, Inc.");
1269 This program comes with NO WARRANTY, to the extent permitted by law.\n\
1270 You may redistribute it under the terms of the GNU General Public License;\n\
1271 see the file named COPYING for details."));
1273 puts (_("Written by John Gilmore and Jay Fenlason."));
1275 exit (TAREXIT_SUCCESS
);
1279 usage (TAREXIT_SUCCESS
);
1281 /* Derive option values and check option consistency. */
1283 if (archive_format
== DEFAULT_FORMAT
)
1284 archive_format
= DEFAULT_ARCHIVE_FORMAT
;
1286 if (volume_label_option
&& subcommand_option
== CREATE_SUBCOMMAND
)
1287 assert_format (FORMAT_MASK (OLDGNU_FORMAT
)
1288 | FORMAT_MASK (GNU_FORMAT
));
1290 if (incremental_option
|| multi_volume_option
)
1291 assert_format (FORMAT_MASK (OLDGNU_FORMAT
) | FORMAT_MASK (GNU_FORMAT
));
1295 assert_format (FORMAT_MASK (OLDGNU_FORMAT
)
1296 | FORMAT_MASK (GNU_FORMAT
)
1297 | FORMAT_MASK (POSIX_FORMAT
));
1299 if (occurrence_option
)
1301 if (!input_files
&& !files_from_option
)
1303 _("--occurrence is meaningless without a file list")));
1304 if (subcommand_option
!= DELETE_SUBCOMMAND
1305 && subcommand_option
!= DIFF_SUBCOMMAND
1306 && subcommand_option
!= EXTRACT_SUBCOMMAND
1307 && subcommand_option
!= LIST_SUBCOMMAND
)
1309 _("--occurrence cannot be used in the requested operation mode")));
1312 if (archive_names
== 0)
1314 /* If no archive file name given, try TAPE from the environment, or
1315 else, DEFAULT_ARCHIVE from the configuration process. */
1318 archive_name_array
[0] = getenv ("TAPE");
1319 if (! archive_name_array
[0])
1320 archive_name_array
[0] = DEFAULT_ARCHIVE
;
1323 /* Allow multiple archives only with `-M'. */
1325 if (archive_names
> 1 && !multi_volume_option
)
1327 _("Multiple archive files require `-M' option")));
1329 if (listed_incremental_option
1330 && newer_mtime_option
!= TYPE_MINIMUM (time_t))
1332 _("Cannot combine --listed-incremental with --newer")));
1334 if (volume_label_option
)
1336 size_t volume_label_max_len
=
1337 (sizeof current_header
->header
.name
1338 - 1 /* for trailing '\0' */
1339 - (multi_volume_option
1340 ? (sizeof " Volume "
1341 - 1 /* for null at end of " Volume " */
1342 + INT_STRLEN_BOUND (int) /* for volume number */
1343 - 1 /* for sign, as 0 <= volno */)
1345 if (volume_label_max_len
< strlen (volume_label_option
))
1347 ngettext ("%s: Volume label is too long (limit is %lu byte)",
1348 "%s: Volume label is too long (limit is %lu bytes)",
1349 volume_label_max_len
),
1350 quotearg_colon (volume_label_option
),
1351 (unsigned long) volume_label_max_len
));
1356 if (multi_volume_option
)
1357 USAGE_ERROR ((0, 0, _("Cannot verify multi-volume archives")));
1358 if (use_compress_program_option
)
1359 USAGE_ERROR ((0, 0, _("Cannot verify compressed archives")));
1362 if (use_compress_program_option
)
1364 if (multi_volume_option
)
1365 USAGE_ERROR ((0, 0, _("Cannot use multi-volume compressed archives")));
1366 if (subcommand_option
== UPDATE_SUBCOMMAND
)
1367 USAGE_ERROR ((0, 0, _("Cannot update compressed archives")));
1370 /* If ready to unlink hierarchies, so we are for simpler files. */
1371 if (recursive_unlink_option
)
1372 old_files_option
= UNLINK_FIRST_OLD_FILES
;
1374 /* Forbid using -c with no input files whatsoever. Check that `-f -',
1375 explicit or implied, is used correctly. */
1377 switch (subcommand_option
)
1379 case CREATE_SUBCOMMAND
:
1380 if (input_files
== 0 && !files_from_option
)
1382 _("Cowardly refusing to create an empty archive")));
1385 case EXTRACT_SUBCOMMAND
:
1386 case LIST_SUBCOMMAND
:
1387 case DIFF_SUBCOMMAND
:
1388 for (archive_name_cursor
= archive_name_array
;
1389 archive_name_cursor
< archive_name_array
+ archive_names
;
1390 archive_name_cursor
++)
1391 if (!strcmp (*archive_name_cursor
, "-"))
1392 request_stdin ("-f");
1395 case CAT_SUBCOMMAND
:
1396 case UPDATE_SUBCOMMAND
:
1397 case APPEND_SUBCOMMAND
:
1398 for (archive_name_cursor
= archive_name_array
;
1399 archive_name_cursor
< archive_name_array
+ archive_names
;
1400 archive_name_cursor
++)
1401 if (!strcmp (*archive_name_cursor
, "-"))
1403 _("Options `-Aru' are incompatible with `-f -'")));
1409 archive_name_cursor
= archive_name_array
;
1411 /* Prepare for generating backup names. */
1413 if (backup_suffix_string
)
1414 simple_backup_suffix
= xstrdup (backup_suffix_string
);
1417 backup_type
= xget_version ("--backup", version_control_string
);
1419 if (verbose_option
&& textual_date_option
)
1421 char const *treated_as
= tartime (newer_mtime_option
);
1422 if (strcmp (textual_date_option
, treated_as
) != 0)
1423 WARN ((0, 0, _("Treating date `%s' as %s"),
1424 textual_date_option
, treated_as
));
1431 /* Main routine for tar. */
1433 main (int argc
, char **argv
)
1435 #if HAVE_CLOCK_GETTIME
1436 if (clock_gettime (CLOCK_REALTIME
, &start_timespec
) != 0)
1438 start_time
= time (0);
1439 program_name
= argv
[0];
1440 setlocale (LC_ALL
, "");
1441 bindtextdomain (PACKAGE
, LOCALEDIR
);
1442 textdomain (PACKAGE
);
1444 exit_status
= TAREXIT_SUCCESS
;
1445 filename_terminator
= '\n';
1446 set_quoting_style (0, escape_quoting_style
);
1448 /* Pre-allocate a few structures. */
1450 allocated_archive_names
= 10;
1451 archive_name_array
=
1452 xmalloc (sizeof (const char *) * allocated_archive_names
);
1456 /* System V fork+wait does not work if SIGCHLD is ignored. */
1457 signal (SIGCHLD
, SIG_DFL
);
1462 /* Decode options. */
1464 decode_options (argc
, argv
);
1465 name_init (argc
, argv
);
1467 /* Main command execution. */
1469 if (volno_file_option
)
1470 init_volume_number ();
1472 switch (subcommand_option
)
1474 case UNKNOWN_SUBCOMMAND
:
1476 _("You must specify one of the `-Acdtrux' options")));
1478 case CAT_SUBCOMMAND
:
1479 case UPDATE_SUBCOMMAND
:
1480 case APPEND_SUBCOMMAND
:
1484 case DELETE_SUBCOMMAND
:
1485 delete_archive_members ();
1488 case CREATE_SUBCOMMAND
:
1493 print_total_written ();
1496 case EXTRACT_SUBCOMMAND
:
1498 read_and (extract_archive
);
1500 /* FIXME: should extract_finish () even if an ordinary signal is
1506 case LIST_SUBCOMMAND
:
1507 read_and (list_archive
);
1510 case DIFF_SUBCOMMAND
:
1512 read_and (diff_archive
);
1516 if (check_links_option
)
1519 if (volno_file_option
)
1520 closeout_volume_number ();
1522 /* Dispose of allocated memory, and return. */
1524 free (archive_name_array
);
1527 if (stdlis
!= stderr
&& (ferror (stdlis
) || fclose (stdlis
) != 0))
1528 FATAL_ERROR ((0, 0, _("Error in writing to standard output")));
1529 if (exit_status
== TAREXIT_FAILURE
)
1530 error (0, 0, _("Error exit delayed from previous errors"));
1531 if (ferror (stderr
) || fclose (stderr
) != 0)
1532 exit_status
= TAREXIT_FAILURE
;
1537 tar_stat_init (struct tar_stat_info
*st
)
1539 memset (st
, 0, sizeof (*st
));
1543 tar_stat_destroy (struct tar_stat_info
*st
)
1545 free (st
->orig_file_name
);
1546 free (st
->file_name
);
1547 free (st
->link_name
);
1550 free (st
->sparse_map
);
1551 memset (st
, 0, sizeof (*st
));