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 ustar POSIX 1003.1-1988 (ustar) format\n\
449 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 -V, --label=NAME create archive with volume name NAME\n\
454 PATTERN at list/extract time, a globbing PATTERN\n\
455 -j, --bzip2 filter the archive through bzip2\n\
456 -z, --gzip, --ungzip filter the archive through gzip\n\
457 -Z, --compress, --uncompress filter the archive through compress\n\
458 --use-compress-program=PROG filter through PROG (must accept -d)\n"),
462 Local file selection:\n\
463 -C, --directory=DIR change to directory DIR\n\
464 -T, --files-from=NAME get names to extract or create from file NAME\n\
465 --null -T reads null-terminated names, disable -C\n\
466 --exclude=PATTERN exclude files, given as a PATTERN\n\
467 -X, --exclude-from=FILE exclude patterns listed in FILE\n\
468 --anchored exclude patterns match file name start (default)\n\
469 --no-anchored exclude patterns match after any /\n\
470 --ignore-case exclusion ignores case\n\
471 --no-ignore-case exclusion is case sensitive (default)\n\
472 --wildcards exclude patterns use wildcards (default)\n\
473 --no-wildcards exclude patterns are plain strings\n\
474 --wildcards-match-slash exclude pattern wildcards match '/' (default)\n\
475 --no-wildcards-match-slash exclude pattern wildcards do not match '/'\n\
476 -P, --absolute-names don't strip leading `/'s from file names\n\
477 -h, --dereference dump instead the files symlinks point to\n\
478 --no-recursion avoid descending automatically in directories\n\
479 -l, --one-file-system stay in local file system when creating archive\n\
480 -K, --starting-file=NAME begin at file NAME in the archive\n\
481 --strip-path=NUM strip NUM leading components from file names\n\
482 before extraction\n"),
486 -N, --newer=DATE-OR-FILE only store files newer than DATE-OR-FILE\n\
487 --newer-mtime=DATE compare date and time when data changed only\n\
488 --after-date=DATE same as -N\n"),
492 --backup[=CONTROL] backup before removal, choose version control\n\
493 --suffix=SUFFIX backup before removal, override usual suffix\n"),
497 Informative output:\n\
498 --help print this help, then exit\n\
499 --version print tar program version number, then exit\n\
500 -v, --verbose verbosely list files processed\n\
501 --checkpoint print directory names while reading the archive\n\
502 --check-links print a message if not all links are dumped\n\
503 --totals print total bytes written while creating archive\n\
504 --index-file=FILE send verbose output to FILE\n\
505 -R, --block-number show block number within archive with each message\n\
506 -w, --interactive ask for confirmation for every action\n\
507 --confirmation same as -w\n"),
511 Compatibility options:\n\
512 -o when creating, same as --old-archive\n\
513 when extracting, same as --no-same-owner\n"),
518 The backup suffix is `~', unless set with --suffix or SIMPLE_BACKUP_SUFFIX.\n\
519 The version control may be set with --backup or VERSION_CONTROL, values are:\n\
521 t, numbered make numbered backups\n\
522 nil, existing numbered if numbered backups exist, simple otherwise\n\
523 never, simple always make simple backups\n"),
527 ARCHIVE may be FILE, HOST:FILE or USER@HOST:FILE; DATE may be a textual date\n\
528 or a file name starting with `/' or `.', in which case the file's date is used.\n\
529 *This* `tar' defaults to `--format=%s -f%s -b%d'.\n"),
530 archive_format_string (DEFAULT_ARCHIVE_FORMAT
),
531 DEFAULT_ARCHIVE
, DEFAULT_BLOCKING
);
532 printf (_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT
);
537 /* Parse the options for tar. */
539 /* Available option letters are DEHIJQY and aenqy. Some are reserved:
541 e exit immediately with a nonzero exit status if unexpected errors occur
542 E use extended headers (draft POSIX headers, that is)
543 I same as T (for compatibility with Solaris tar)
544 n the archive is quickly seekable, so don't worry about random seeks
545 q stop after extracting the first occurrence of the named file
546 y per-file gzip compression
547 Y per-block gzip compression */
549 #define OPTION_STRING \
550 "-01234567ABC:F:GIK:L:MN:OPRST:UV:WX:Zb:cdf:g:hijklmoprstuvwxyz"
553 set_subcommand_option (enum subcommand subcommand
)
555 if (subcommand_option
!= UNKNOWN_SUBCOMMAND
556 && subcommand_option
!= subcommand
)
558 _("You may not specify more than one `-Acdtrux' option")));
560 subcommand_option
= subcommand
;
564 set_use_compress_program_option (const char *string
)
566 if (use_compress_program_option
&& strcmp (use_compress_program_option
, string
) != 0)
567 USAGE_ERROR ((0, 0, _("Conflicting compression options")));
569 use_compress_program_option
= string
;
573 decode_options (int argc
, char **argv
)
575 int optchar
; /* option letter */
576 int input_files
; /* number of input files */
577 char const *textual_date_option
= 0;
578 char const *backup_suffix_string
;
579 char const *version_control_string
= 0;
580 int exclude_options
= EXCLUDE_WILDCARDS
;
583 /* Set some default option values. */
585 subcommand_option
= UNKNOWN_SUBCOMMAND
;
586 archive_format
= DEFAULT_FORMAT
;
587 blocking_factor
= DEFAULT_BLOCKING
;
588 record_size
= DEFAULT_BLOCKING
* BLOCKSIZE
;
589 excluded
= new_exclude ();
590 newer_mtime_option
= TYPE_MINIMUM (time_t);
591 recursion_option
= FNM_LEADING_DIR
;
596 backup_suffix_string
= getenv ("SIMPLE_BACKUP_SUFFIX");
598 /* Convert old-style tar call by exploding option element and rearranging
599 options accordingly. */
601 if (argc
> 1 && argv
[1][0] != '-')
603 int new_argc
; /* argc value for rearranged arguments */
604 char **new_argv
; /* argv value for rearranged arguments */
605 char *const *in
; /* cursor into original argv */
606 char **out
; /* cursor into rearranged argv */
607 const char *letter
; /* cursor into old option letters */
608 char buffer
[3]; /* constructed option buffer */
609 const char *cursor
; /* cursor in OPTION_STRING */
611 /* Initialize a constructed option. */
616 /* Allocate a new argument array, and copy program name in it. */
618 new_argc
= argc
- 1 + strlen (argv
[1]);
619 new_argv
= xmalloc ((new_argc
+ 1) * sizeof (char *));
624 /* Copy each old letter option as a separate option, and have the
625 corresponding argument moved next to it. */
627 for (letter
= *in
++; *letter
; letter
++)
630 *out
++ = xstrdup (buffer
);
631 cursor
= strchr (OPTION_STRING
, *letter
);
632 if (cursor
&& cursor
[1] == ':')
634 if (in
< argv
+ argc
)
637 USAGE_ERROR ((0, 0, _("Old option `%c' requires an argument."),
642 /* Copy all remaining options. */
644 while (in
< argv
+ argc
)
648 /* Replace the old option list by the new one. */
654 /* Parse all options and non-options as they appear. */
658 prepend_default_options (getenv ("TAR_OPTIONS"), &argc
, &argv
);
660 while (optchar
= getopt_long (argc
, argv
, OPTION_STRING
, long_options
, 0),
665 usage (TAREXIT_FAILURE
);
671 /* File name or non-parsed option, because of RETURN_IN_ORDER
672 ordering triggered by the leading dash in OPTION_STRING. */
679 set_subcommand_option (CAT_SUBCOMMAND
);
685 if (! (xstrtoumax (optarg
, 0, 10, &u
, "") == LONGINT_OK
686 && u
== (blocking_factor
= u
)
687 && 0 < blocking_factor
688 && u
== (record_size
= u
* BLOCKSIZE
) / BLOCKSIZE
))
689 USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (optarg
),
690 _("Invalid blocking factor")));
695 /* Try to reblock input records. For reading 4.2BSD pipes. */
697 /* It would surely make sense to exchange -B and -R, but it seems
698 that -B has been used for a long while in Sun tar ans most
699 BSD-derived systems. This is a consequence of the block/record
700 terminology confusion. */
702 read_full_records_option
= true;
706 set_subcommand_option (CREATE_SUBCOMMAND
);
715 set_subcommand_option (DIFF_SUBCOMMAND
);
719 if (archive_names
== allocated_archive_names
)
721 allocated_archive_names
*= 2;
723 xrealloc (archive_name_array
,
724 sizeof (const char *) * allocated_archive_names
);
726 archive_name_array
[archive_names
++] = optarg
;
730 /* Since -F is only useful with -M, make it implied. Run this
731 script at the end of each tape. */
733 info_script_option
= optarg
;
734 multi_volume_option
= true;
738 listed_incremental_option
= optarg
;
739 after_date_option
= true;
743 /* We are making an incremental dump (FIXME: are we?); save
744 directories at the beginning of the archive, and include in each
745 directory its contents. */
747 incremental_option
= true;
751 /* Follow symbolic links. */
752 dereference_option
= true;
756 /* Ignore zero blocks (eofs). This can't be the default,
757 because Unix tar writes two blocks of zeros, then pads out
758 the record with garbage. */
760 ignore_zeros_option
= true;
765 _("Warning: the -I option is not supported;"
766 " perhaps you meant -j or -T?")));
770 set_use_compress_program_option ("bzip2");
774 /* Don't replace existing files. */
775 old_files_option
= KEEP_OLD_FILES
;
779 starting_file_option
= true;
784 /* When dumping directories, don't dump files/subdirectories
785 that are on other filesystems. */
787 one_file_system_option
= true;
793 if (xstrtoumax (optarg
, 0, 10, &u
, "") != LONGINT_OK
)
794 USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (optarg
),
795 _("Invalid tape length")));
796 tape_length_option
= 1024 * (tarlong
) u
;
797 multi_volume_option
= true;
806 /* Make multivolume archive: when we can't write any more into
807 the archive, re-open it, and continue writing. */
809 multi_volume_option
= true;
814 after_date_option
= true;
817 case NEWER_MTIME_OPTION
:
818 if (newer_mtime_option
!= TYPE_MINIMUM (time_t))
819 USAGE_ERROR ((0, 0, _("More than one threshold date")));
821 if (FILESYSTEM_PREFIX_LEN (optarg
) != 0
826 if (deref_stat (dereference_option
, optarg
, &st
) != 0)
829 USAGE_ERROR ((0, 0, _("Date file not found")));
831 newer_mtime_option
= st
.st_mtime
;
835 newer_mtime_option
= get_date (optarg
, 0);
836 if (newer_mtime_option
== (time_t) -1)
837 WARN ((0, 0, _("Substituting %s for unknown date format %s"),
838 tartime (newer_mtime_option
), quote (optarg
)));
840 textual_date_option
= optarg
;
844 #endif /* not MSDOS */
851 to_stdout_option
= true;
855 same_permissions_option
= true;
859 absolute_names_option
= true;
863 set_subcommand_option (APPEND_SUBCOMMAND
);
867 /* Print block numbers for debugging bad tar archives. */
869 /* It would surely make sense to exchange -B and -R, but it seems
870 that -B has been used for a long while in Sun tar ans most
871 BSD-derived systems. This is a consequence of the block/record
872 terminology confusion. */
874 block_number_option
= true;
878 /* Names to extr are sorted. */
880 same_order_option
= true;
884 sparse_option
= true;
888 set_subcommand_option (LIST_SUBCOMMAND
);
893 files_from_option
= optarg
;
897 set_subcommand_option (UPDATE_SUBCOMMAND
);
901 old_files_option
= UNLINK_FIRST_OLD_FILES
;
909 volume_label_option
= optarg
;
913 interactive_option
= true;
917 verify_option
= true;
921 set_subcommand_option (EXTRACT_SUBCOMMAND
);
925 if (add_exclude_file (add_exclude
, excluded
, optarg
,
926 exclude_options
| recursion_option
, '\n')
930 FATAL_ERROR ((0, e
, "%s", quotearg_colon (optarg
)));
936 _("Warning: the -y option is not supported;"
937 " perhaps you meant -j?")));
941 set_use_compress_program_option ("gzip");
945 set_use_compress_program_option ("compress");
948 case ANCHORED_OPTION
:
949 exclude_options
|= EXCLUDE_ANCHORED
;
952 case ATIME_PRESERVE_OPTION
:
953 atime_preserve_option
= true;
956 case CHECKPOINT_OPTION
:
957 checkpoint_option
= true;
961 backup_option
= true;
963 version_control_string
= optarg
;
967 set_subcommand_option (DELETE_SUBCOMMAND
);
971 add_exclude (excluded
, optarg
, exclude_options
| recursion_option
);
974 case FORCE_LOCAL_OPTION
:
975 force_local_option
= true;
979 set_archive_format (optarg
);
982 case INDEX_FILE_OPTION
:
983 index_file_name
= optarg
;
986 case IGNORE_CASE_OPTION
:
987 exclude_options
|= FNM_CASEFOLD
;
990 case IGNORE_FAILED_READ_OPTION
:
991 ignore_failed_read_option
= true;
995 if (! (strlen (optarg
) < GNAME_FIELD_SIZE
996 && gname_to_gid (optarg
, &group_option
)))
999 if (xstrtoumax (optarg
, 0, 10, &g
, "") == LONGINT_OK
1003 FATAL_ERROR ((0, 0, "%s: %s", quotearg_colon (optarg
),
1004 _("%s: Invalid group")));
1010 = mode_compile (optarg
,
1011 MODE_MASK_EQUALS
| MODE_MASK_PLUS
| MODE_MASK_MINUS
);
1012 if (mode_option
== MODE_INVALID
)
1013 FATAL_ERROR ((0, 0, _("Invalid mode given on option")));
1014 if (mode_option
== MODE_MEMORY_EXHAUSTED
)
1018 case NO_ANCHORED_OPTION
:
1019 exclude_options
&= ~ EXCLUDE_ANCHORED
;
1022 case NO_IGNORE_CASE_OPTION
:
1023 exclude_options
&= ~ FNM_CASEFOLD
;
1026 case NO_OVERWRITE_DIR_OPTION
:
1027 old_files_option
= NO_OVERWRITE_DIR_OLD_FILES
;
1030 case NO_WILDCARDS_OPTION
:
1031 exclude_options
&= ~ EXCLUDE_WILDCARDS
;
1034 case NO_WILDCARDS_MATCH_SLASH_OPTION
:
1035 exclude_options
|= FNM_FILE_NAME
;
1039 filename_terminator
= '\0';
1042 case NUMERIC_OWNER_OPTION
:
1043 numeric_owner_option
= true;
1046 case OCCURRENCE_OPTION
:
1048 occurrence_option
= 1;
1052 if (xstrtoumax (optarg
, 0, 10, &u
, "") == LONGINT_OK
)
1053 occurrence_option
= u
;
1055 FATAL_ERROR ((0, 0, "%s: %s", quotearg_colon (optarg
),
1056 _("Invalid number")));
1060 case OVERWRITE_OPTION
:
1061 old_files_option
= OVERWRITE_OLD_FILES
;
1065 if (! (strlen (optarg
) < UNAME_FIELD_SIZE
1066 && uname_to_uid (optarg
, &owner_option
)))
1069 if (xstrtoumax (optarg
, 0, 10, &u
, "") == LONGINT_OK
1073 FATAL_ERROR ((0, 0, "%s: %s", quotearg_colon (optarg
),
1074 _("Invalid owner")));
1079 xheader_set_option (optarg
);
1083 set_archive_format ("posix");
1086 case PRESERVE_OPTION
:
1087 same_permissions_option
= true;
1088 same_order_option
= true;
1091 case RECORD_SIZE_OPTION
:
1094 if (! (xstrtoumax (optarg
, 0, 10, &u
, "") == LONGINT_OK
1095 && u
== (size_t) u
))
1096 USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (optarg
),
1097 _("Invalid record size")));
1099 if (record_size
% BLOCKSIZE
!= 0)
1100 USAGE_ERROR ((0, 0, _("Record size must be a multiple of %d."),
1102 blocking_factor
= record_size
/ BLOCKSIZE
;
1106 case RECURSIVE_UNLINK_OPTION
:
1107 recursive_unlink_option
= true;
1110 case REMOVE_FILES_OPTION
:
1111 remove_files_option
= true;
1114 case RSH_COMMAND_OPTION
:
1115 rsh_command_option
= optarg
;
1118 case STRIP_PATH_OPTION
:
1121 if (! (xstrtoumax (optarg
, 0, 10, &u
, "") == LONGINT_OK
1122 && u
== (size_t) u
))
1123 USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (optarg
),
1124 _("Invalid number of elements")));
1125 strip_path_elements
= u
;
1130 backup_option
= true;
1131 backup_suffix_string
= optarg
;
1135 totals_option
= true;
1138 case USE_COMPRESS_PROGRAM_OPTION
:
1139 set_use_compress_program_option (optarg
);
1142 case VOLNO_FILE_OPTION
:
1143 volno_file_option
= optarg
;
1146 case WILDCARDS_OPTION
:
1147 exclude_options
|= EXCLUDE_WILDCARDS
;
1150 case WILDCARDS_MATCH_SLASH_OPTION
:
1151 exclude_options
&= ~ FNM_FILE_NAME
;
1163 #ifdef DEVICE_PREFIX
1165 int device
= optchar
- '0';
1167 static char buf
[sizeof DEVICE_PREFIX
+ 10];
1170 density
= getopt_long (argc
, argv
, "lmh", 0, 0);
1171 strcpy (buf
, DEVICE_PREFIX
);
1172 cursor
= buf
+ strlen (buf
);
1174 #ifdef DENSITY_LETTER
1176 sprintf (cursor
, "%d%c", device
, density
);
1178 #else /* not DENSITY_LETTER */
1205 usage (TAREXIT_FAILURE
);
1207 sprintf (cursor
, "%d", device
);
1209 #endif /* not DENSITY_LETTER */
1211 if (archive_names
== allocated_archive_names
)
1213 allocated_archive_names
*= 2;
1214 archive_name_array
=
1215 xrealloc (archive_name_array
,
1216 sizeof (const char *) * allocated_archive_names
);
1218 archive_name_array
[archive_names
++] = strdup (buf
);
1222 #else /* not DEVICE_PREFIX */
1225 _("Options `-[0-7][lmh]' not supported by *this* tar")));
1227 #endif /* not DEVICE_PREFIX */
1230 /* Special handling for 'o' option:
1232 GNU tar used to say "output old format".
1233 UNIX98 tar says don't chown files after extracting (we use
1234 "--no-same-owner" for this).
1236 The old GNU tar semantics is retained when used with --create
1237 option, otherwise UNIX98 semantics is assumed */
1241 if (subcommand_option
== CREATE_SUBCOMMAND
)
1243 /* GNU Tar <= 1.13 compatibility */
1244 set_archive_format ("v7");
1248 /* UNIX98 compatibility */
1249 same_owner_option
= 1;
1253 /* Handle operands after any "--" argument. */
1254 for (; optind
< argc
; optind
++)
1256 name_add (argv
[optind
]);
1260 /* Process trivial options. */
1264 printf ("tar (%s) %s\n%s\n", PACKAGE_NAME
, PACKAGE_VERSION
,
1265 "Copyright (C) 2003 Free Software Foundation, Inc.");
1267 This program comes with NO WARRANTY, to the extent permitted by law.\n\
1268 You may redistribute it under the terms of the GNU General Public License;\n\
1269 see the file named COPYING for details."));
1271 puts (_("Written by John Gilmore and Jay Fenlason."));
1273 exit (TAREXIT_SUCCESS
);
1277 usage (TAREXIT_SUCCESS
);
1279 /* Derive option values and check option consistency. */
1281 if (archive_format
== DEFAULT_FORMAT
)
1282 archive_format
= DEFAULT_ARCHIVE_FORMAT
;
1284 if (volume_label_option
&& subcommand_option
== CREATE_SUBCOMMAND
)
1285 assert_format (FORMAT_MASK (OLDGNU_FORMAT
)
1286 | FORMAT_MASK (GNU_FORMAT
));
1288 if (incremental_option
1289 || multi_volume_option
1291 assert_format (FORMAT_MASK (OLDGNU_FORMAT
)
1292 | FORMAT_MASK (GNU_FORMAT
)
1293 | FORMAT_MASK (POSIX_FORMAT
));
1295 if (occurrence_option
)
1297 if (!input_files
&& !files_from_option
)
1299 _("--occurrence is meaningless without file list")));
1300 if (subcommand_option
!= DELETE_SUBCOMMAND
1301 && subcommand_option
!= DIFF_SUBCOMMAND
1302 && subcommand_option
!= EXTRACT_SUBCOMMAND
1303 && subcommand_option
!= LIST_SUBCOMMAND
)
1305 _("--occurrence cannot be used in the requested operation mode")));
1308 if (archive_names
== 0)
1310 /* If no archive file name given, try TAPE from the environment, or
1311 else, DEFAULT_ARCHIVE from the configuration process. */
1314 archive_name_array
[0] = getenv ("TAPE");
1315 if (! archive_name_array
[0])
1316 archive_name_array
[0] = DEFAULT_ARCHIVE
;
1319 /* Allow multiple archives only with `-M'. */
1321 if (archive_names
> 1 && !multi_volume_option
)
1323 _("Multiple archive files require `-M' option")));
1325 if (listed_incremental_option
1326 && newer_mtime_option
!= TYPE_MINIMUM (time_t))
1328 _("Cannot combine --listed-incremental with --newer")));
1330 if (volume_label_option
)
1332 size_t volume_label_max_len
=
1333 (sizeof current_header
->header
.name
1334 - 1 /* for trailing '\0' */
1335 - (multi_volume_option
1336 ? (sizeof " Volume "
1337 - 1 /* for null at end of " Volume " */
1338 + INT_STRLEN_BOUND (int) /* for volume number */
1339 - 1 /* for sign, as 0 <= volno */)
1341 if (volume_label_max_len
< strlen (volume_label_option
))
1343 ngettext ("%s: Volume label is too long (limit is %lu byte)",
1344 "%s: Volume label is too long (limit is %lu bytes)",
1345 volume_label_max_len
),
1346 quotearg_colon (volume_label_option
),
1347 (unsigned long) volume_label_max_len
));
1352 if (multi_volume_option
)
1353 USAGE_ERROR ((0, 0, _("Cannot verify multi-volume archives")));
1354 if (use_compress_program_option
)
1355 USAGE_ERROR ((0, 0, _("Cannot verify compressed archives")));
1358 if (use_compress_program_option
)
1360 if (multi_volume_option
)
1361 USAGE_ERROR ((0, 0, _("Cannot use multi-volume compressed archives")));
1362 if (subcommand_option
== UPDATE_SUBCOMMAND
)
1363 USAGE_ERROR ((0, 0, _("Cannot update compressed archives")));
1366 /* If ready to unlink hierarchies, so we are for simpler files. */
1367 if (recursive_unlink_option
)
1368 old_files_option
= UNLINK_FIRST_OLD_FILES
;
1370 /* Forbid using -c with no input files whatsoever. Check that `-f -',
1371 explicit or implied, is used correctly. */
1373 switch (subcommand_option
)
1375 case CREATE_SUBCOMMAND
:
1376 if (input_files
== 0 && !files_from_option
)
1378 _("Cowardly refusing to create an empty archive")));
1381 case EXTRACT_SUBCOMMAND
:
1382 case LIST_SUBCOMMAND
:
1383 case DIFF_SUBCOMMAND
:
1384 for (archive_name_cursor
= archive_name_array
;
1385 archive_name_cursor
< archive_name_array
+ archive_names
;
1386 archive_name_cursor
++)
1387 if (!strcmp (*archive_name_cursor
, "-"))
1388 request_stdin ("-f");
1391 case CAT_SUBCOMMAND
:
1392 case UPDATE_SUBCOMMAND
:
1393 case APPEND_SUBCOMMAND
:
1394 for (archive_name_cursor
= archive_name_array
;
1395 archive_name_cursor
< archive_name_array
+ archive_names
;
1396 archive_name_cursor
++)
1397 if (!strcmp (*archive_name_cursor
, "-"))
1399 _("Options `-Aru' are incompatible with `-f -'")));
1405 archive_name_cursor
= archive_name_array
;
1407 /* Prepare for generating backup names. */
1409 if (backup_suffix_string
)
1410 simple_backup_suffix
= xstrdup (backup_suffix_string
);
1413 backup_type
= xget_version ("--backup", version_control_string
);
1415 if (verbose_option
&& textual_date_option
)
1417 char const *treated_as
= tartime (newer_mtime_option
);
1418 if (strcmp (textual_date_option
, treated_as
) != 0)
1419 WARN ((0, 0, _("Treating date `%s' as %s"),
1420 textual_date_option
, treated_as
));
1427 /* Main routine for tar. */
1429 main (int argc
, char **argv
)
1431 #if HAVE_CLOCK_GETTIME
1432 if (clock_gettime (CLOCK_REALTIME
, &start_timespec
) != 0)
1434 start_time
= time (0);
1435 program_name
= argv
[0];
1436 setlocale (LC_ALL
, "");
1437 bindtextdomain (PACKAGE
, LOCALEDIR
);
1438 textdomain (PACKAGE
);
1440 exit_status
= TAREXIT_SUCCESS
;
1441 filename_terminator
= '\n';
1442 set_quoting_style (0, escape_quoting_style
);
1444 /* Pre-allocate a few structures. */
1446 allocated_archive_names
= 10;
1447 archive_name_array
=
1448 xmalloc (sizeof (const char *) * allocated_archive_names
);
1452 /* System V fork+wait does not work if SIGCHLD is ignored. */
1453 signal (SIGCHLD
, SIG_DFL
);
1458 /* Decode options. */
1460 decode_options (argc
, argv
);
1461 name_init (argc
, argv
);
1463 /* Main command execution. */
1465 if (volno_file_option
)
1466 init_volume_number ();
1468 switch (subcommand_option
)
1470 case UNKNOWN_SUBCOMMAND
:
1472 _("You must specify one of the `-Acdtrux' options")));
1474 case CAT_SUBCOMMAND
:
1475 case UPDATE_SUBCOMMAND
:
1476 case APPEND_SUBCOMMAND
:
1480 case DELETE_SUBCOMMAND
:
1481 delete_archive_members ();
1484 case CREATE_SUBCOMMAND
:
1489 print_total_written ();
1492 case EXTRACT_SUBCOMMAND
:
1494 read_and (extract_archive
);
1496 /* FIXME: should extract_finish () even if an ordinary signal is
1502 case LIST_SUBCOMMAND
:
1503 read_and (list_archive
);
1506 case DIFF_SUBCOMMAND
:
1508 read_and (diff_archive
);
1512 if (check_links_option
)
1515 if (volno_file_option
)
1516 closeout_volume_number ();
1518 /* Dispose of allocated memory, and return. */
1520 free (archive_name_array
);
1523 if (stdlis
!= stderr
&& (ferror (stdlis
) || fclose (stdlis
) != 0))
1524 FATAL_ERROR ((0, 0, _("Error in writing to standard output")));
1525 if (exit_status
== TAREXIT_FAILURE
)
1526 error (0, 0, _("Error exit delayed from previous errors"));
1527 if (ferror (stderr
) || fclose (stderr
) != 0)
1528 exit_status
= TAREXIT_FAILURE
;
1533 tar_stat_init (struct tar_stat_info
*st
)
1535 memset (st
, 0, sizeof (*st
));
1539 tar_stat_destroy (struct tar_stat_info
*st
)
1541 free (st
->orig_file_name
);
1542 free (st
->file_name
);
1543 free (st
->link_name
);
1546 free (st
->sparse_map
);
1547 memset (st
, 0, sizeof (*st
));