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 static 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 { "posix", POSIX_FORMAT
},
127 #if 0 /* not fully supported yet */
128 { "star", STAR_FORMAT
},
130 { "gnu", GNU_FORMAT
},
135 set_archive_format (char const *name
)
137 struct fmttab
const *p
;
139 for (p
= fmttab
; strcmp (p
->name
, name
) != 0; )
141 USAGE_ERROR ((0, 0, _("%s: Invalid archive format"),
142 quotearg_colon (name
)));
144 if (archive_format
!= DEFAULT_FORMAT
&& archive_format
!= p
->fmt
)
145 USAGE_ERROR ((0, 0, _("Conflicting archive format options")));
147 archive_format
= p
->fmt
;
151 archive_format_string (enum archive_format fmt
)
153 struct fmttab
const *p
;
155 for (p
= fmttab
; p
->name
; p
++)
164 /* For long options that unconditionally set a single flag, we have getopt
165 do it. For the others, we share the code for the equivalent short
166 named option, the name of which is stored in the otherwise-unused `val'
167 field of the `struct option'; for long options that have no equivalent
168 short option, we use non-characters as pseudo short options,
169 starting at CHAR_MAX + 1 and going upwards. */
173 ANCHORED_OPTION
= CHAR_MAX
+ 1,
174 ATIME_PRESERVE_OPTION
,
183 IGNORE_FAILED_READ_OPTION
,
188 NO_IGNORE_CASE_OPTION
,
189 NO_OVERWRITE_DIR_OPTION
,
191 NO_WILDCARDS_MATCH_SLASH_OPTION
,
193 NUMERIC_OWNER_OPTION
,
199 RECURSIVE_UNLINK_OPTION
,
202 SHOW_OMITTED_DIRS_OPTION
,
206 USE_COMPRESS_PROGRAM_OPTION
,
209 WILDCARDS_MATCH_SLASH_OPTION
,
212 /* If nonzero, display usage information and exit. */
213 static int show_help
;
215 /* If nonzero, print the version on standard output and exit. */
216 static int show_version
;
218 static struct option long_options
[] =
220 {"absolute-names", no_argument
, 0, 'P'},
221 {"after-date", required_argument
, 0, 'N'},
222 {"anchored", no_argument
, 0, ANCHORED_OPTION
},
223 {"append", no_argument
, 0, 'r'},
224 {"atime-preserve", no_argument
, 0, ATIME_PRESERVE_OPTION
},
225 {"backup", optional_argument
, 0, BACKUP_OPTION
},
226 {"block-number", no_argument
, 0, 'R'},
227 {"blocking-factor", required_argument
, 0, 'b'},
228 {"bzip2", no_argument
, 0, 'j'},
229 {"catenate", no_argument
, 0, 'A'},
230 {"checkpoint", no_argument
, 0, CHECKPOINT_OPTION
},
231 {"check-links", no_argument
, &check_links_option
, 1},
232 {"compare", no_argument
, 0, 'd'},
233 {"compress", no_argument
, 0, 'Z'},
234 {"concatenate", no_argument
, 0, 'A'},
235 {"confirmation", no_argument
, 0, 'w'},
236 /* FIXME: --selective as a synonym for --confirmation? */
237 {"create", no_argument
, 0, 'c'},
238 {"delete", no_argument
, 0, DELETE_OPTION
},
239 {"dereference", no_argument
, 0, 'h'},
240 {"diff", no_argument
, 0, 'd'},
241 {"directory", required_argument
, 0, 'C'},
242 {"exclude", required_argument
, 0, EXCLUDE_OPTION
},
243 {"exclude-from", required_argument
, 0, 'X'},
244 {"extract", no_argument
, 0, 'x'},
245 {"file", required_argument
, 0, 'f'},
246 {"files-from", required_argument
, 0, 'T'},
247 {"force-local", no_argument
, 0, FORCE_LOCAL_OPTION
},
248 {"format", required_argument
, 0, FORMAT_OPTION
},
249 {"get", no_argument
, 0, 'x'},
250 {"group", required_argument
, 0, GROUP_OPTION
},
251 {"gunzip", no_argument
, 0, 'z'},
252 {"gzip", no_argument
, 0, 'z'},
253 {"help", no_argument
, &show_help
, 1},
254 {"ignore-case", no_argument
, 0, IGNORE_CASE_OPTION
},
255 {"ignore-failed-read", no_argument
, 0, IGNORE_FAILED_READ_OPTION
},
256 {"ignore-zeros", no_argument
, 0, 'i'},
257 /* FIXME: --ignore-end as a new name for --ignore-zeros? */
258 {"incremental", no_argument
, 0, 'G'},
259 {"index-file", required_argument
, 0, INDEX_FILE_OPTION
},
260 {"info-script", required_argument
, 0, 'F'},
261 {"interactive", no_argument
, 0, 'w'},
262 {"keep-old-files", no_argument
, 0, 'k'},
263 {"label", required_argument
, 0, 'V'},
264 {"list", no_argument
, 0, 't'},
265 {"listed-incremental", required_argument
, 0, 'g'},
266 {"mode", required_argument
, 0, MODE_OPTION
},
267 {"multi-volume", no_argument
, 0, 'M'},
268 {"new-volume-script", required_argument
, 0, 'F'},
269 {"newer", required_argument
, 0, 'N'},
270 {"newer-mtime", required_argument
, 0, NEWER_MTIME_OPTION
},
271 {"null", no_argument
, 0, NULL_OPTION
},
272 {"no-anchored", no_argument
, 0, NO_ANCHORED_OPTION
},
273 {"no-ignore-case", no_argument
, 0, NO_IGNORE_CASE_OPTION
},
274 {"no-overwrite-dir", no_argument
, 0, NO_OVERWRITE_DIR_OPTION
},
275 {"no-wildcards", no_argument
, 0, NO_WILDCARDS_OPTION
},
276 {"no-wildcards-match-slash", no_argument
, 0, NO_WILDCARDS_MATCH_SLASH_OPTION
},
277 {"no-recursion", no_argument
, &recursion_option
, 0},
278 {"no-same-owner", no_argument
, &same_owner_option
, -1},
279 {"no-same-permissions", no_argument
, &same_permissions_option
, -1},
280 {"numeric-owner", no_argument
, 0, NUMERIC_OWNER_OPTION
},
281 {"old-archive", no_argument
, 0, 'o'},
282 {"one-file-system", no_argument
, 0, 'l'},
283 {"overwrite", no_argument
, 0, OVERWRITE_OPTION
},
284 {"owner", required_argument
, 0, OWNER_OPTION
},
285 {"portability", no_argument
, 0, 'o'},
286 {"posix", no_argument
, 0, POSIX_OPTION
},
287 {"preserve", no_argument
, 0, PRESERVE_OPTION
},
288 {"preserve-order", no_argument
, 0, 's'},
289 {"preserve-permissions", no_argument
, 0, 'p'},
290 {"recursion", no_argument
, &recursion_option
, FNM_LEADING_DIR
},
291 {"recursive-unlink", no_argument
, 0, RECURSIVE_UNLINK_OPTION
},
292 {"read-full-records", no_argument
, 0, 'B'},
293 /* FIXME: --partial-blocks might be a synonym for --read-full-records? */
294 {"record-size", required_argument
, 0, RECORD_SIZE_OPTION
},
295 {"remove-files", no_argument
, 0, REMOVE_FILES_OPTION
},
296 {"rsh-command", required_argument
, 0, RSH_COMMAND_OPTION
},
297 {"same-order", no_argument
, 0, 's'},
298 {"same-owner", no_argument
, &same_owner_option
, 1},
299 {"same-permissions", no_argument
, 0, 'p'},
300 {"show-omitted-dirs", no_argument
, 0, SHOW_OMITTED_DIRS_OPTION
},
301 {"sparse", no_argument
, 0, 'S'},
302 {"starting-file", required_argument
, 0, 'K'},
303 {"strip-path", required_argument
, 0, STRIP_PATH_OPTION
},
304 {"suffix", required_argument
, 0, SUFFIX_OPTION
},
305 {"tape-length", required_argument
, 0, 'L'},
306 {"to-stdout", no_argument
, 0, 'O'},
307 {"totals", no_argument
, 0, TOTALS_OPTION
},
308 {"touch", no_argument
, 0, 'm'},
309 {"uncompress", no_argument
, 0, 'Z'},
310 {"ungzip", no_argument
, 0, 'z'},
311 {"unlink-first", no_argument
, 0, 'U'},
312 {"update", no_argument
, 0, 'u'},
313 {"use-compress-program", required_argument
, 0, USE_COMPRESS_PROGRAM_OPTION
},
314 {"verbose", no_argument
, 0, 'v'},
315 {"verify", no_argument
, 0, 'W'},
316 {"version", no_argument
, &show_version
, 1},
317 {"volno-file", required_argument
, 0, VOLNO_FILE_OPTION
},
318 {"wildcards", no_argument
, 0, WILDCARDS_OPTION
},
319 {"wildcards-match-slash", no_argument
, 0, WILDCARDS_MATCH_SLASH_OPTION
},
324 /* Print a usage message and exit with STATUS. */
328 if (status
!= TAREXIT_SUCCESS
)
329 fprintf (stderr
, _("Try `%s --help' for more information.\n"),
334 GNU `tar' saves many files together into a single tape or disk archive, and\n\
335 can restore individual files from the archive.\n"),
337 printf (_("\nUsage: %s [OPTION]... [FILE]...\n\
340 %s -cf archive.tar foo bar # Create archive.tar from files foo and bar.\n\
341 %s -tvf archive.tar # List all files in archive.tar verbosely.\n\
342 %s -xf archive.tar # Extract all files from archive.tar.\n"),
343 program_name
, program_name
, program_name
, program_name
);
346 If a long option shows an argument as mandatory, then it is mandatory\n\
347 for the equivalent short option also. Similarly for optional arguments.\n"),
351 Main operation mode:\n\
352 -t, --list list the contents of an archive\n\
353 -x, --extract, --get extract files from an archive\n\
354 -c, --create create a new archive\n\
355 -d, --diff, --compare find differences between archive and file system\n\
356 -r, --append append files to the end of an archive\n\
357 -u, --update only append files newer than copy in archive\n\
358 -A, --catenate append tar files to an archive\n\
359 --concatenate same as -A\n\
360 --delete delete from the archive (not on mag tapes!)\n"),
364 Operation modifiers:\n\
365 -W, --verify attempt to verify the archive after writing it\n\
366 --remove-files remove files after adding them to the archive\n\
367 -k, --keep-old-files don't replace existing files when extracting\n\
368 --overwrite overwrite existing files when extracting\n\
369 --no-overwrite-dir preserve metadata of existing directories\n\
370 -U, --unlink-first remove each file prior to extracting over it\n\
371 --recursive-unlink empty hierarchies prior to extracting directory\n\
372 -S, --sparse handle sparse files efficiently\n\
373 -O, --to-stdout extract files to standard output\n\
374 -G, --incremental handle old GNU-format incremental backup\n\
375 -g, --listed-incremental=FILE\n\
376 handle new GNU-format incremental backup\n\
377 --ignore-failed-read do not exit with nonzero on unreadable files\n"),
381 Handling of file attributes:\n\
382 --owner=NAME force NAME as owner for added files\n\
383 --group=NAME force NAME as group for added files\n\
384 --mode=CHANGES force (symbolic) mode CHANGES for added files\n\
385 --atime-preserve don't change access times on dumped files\n\
386 -m, --modification-time don't extract file modified time\n\
387 --same-owner try extracting files with the same ownership\n\
388 --no-same-owner extract files as yourself\n\
389 --numeric-owner always use numbers for user/group names\n\
390 -p, --same-permissions extract permissions information\n\
391 --no-same-permissions do not extract permissions information\n\
392 --preserve-permissions same as -p\n\
393 -s, --same-order sort names to extract to match archive\n\
394 --preserve-order same as -s\n\
395 --preserve same as both -p and -s\n"),
399 Device selection and switching:\n\
400 -f, --file=ARCHIVE use archive file or device ARCHIVE\n\
401 --force-local archive file is local even if has a colon\n\
402 --rsh-command=COMMAND use remote COMMAND instead of rsh\n\
403 -[0-7][lmh] specify drive and density\n\
404 -M, --multi-volume create/list/extract multi-volume archive\n\
405 -L, --tape-length=NUM change tape after writing NUM x 1024 bytes\n\
406 -F, --info-script=FILE run script at end of each tape (implies -M)\n\
407 --new-volume-script=FILE same as -F FILE\n\
408 --volno-file=FILE use/update the volume number in FILE\n"),
413 -b, --blocking-factor=BLOCKS BLOCKS x 512 bytes per record\n\
414 --record-size=SIZE SIZE bytes per record, multiple of 512\n\
415 -i, --ignore-zeros ignore zeroed blocks in archive (means EOF)\n\
416 -B, --read-full-records reblock as we read (for 4.2BSD pipes)\n"),
420 Archive format selection:\n\
421 --format=FMTNAME create archive of the given format.\n\
422 FMTNAME is one of the following:\n\
423 v7 old V7 tar format\n\
424 oldgnu GNU format as per tar <= 1.12\n\
425 posix POSIX 1003.1-2001 tar format\n\
427 --old-archive, --portability same as --format=v7\n\
428 --posix same as --format=posix\n\
429 -V, --label=NAME create archive with volume name NAME\n\
430 PATTERN at list/extract time, a globbing PATTERN\n\
431 -j, --bzip2 filter the archive through bzip2\n\
432 -z, --gzip, --ungzip filter the archive through gzip\n\
433 -Z, --compress, --uncompress filter the archive through compress\n\
434 --use-compress-program=PROG filter through PROG (must accept -d)\n"),
438 Local file selection:\n\
439 -C, --directory=DIR change to directory DIR\n\
440 -T, --files-from=NAME get names to extract or create from file NAME\n\
441 --null -T reads null-terminated names, disable -C\n\
442 --exclude=PATTERN exclude files, given as a PATTERN\n\
443 -X, --exclude-from=FILE exclude patterns listed in FILE\n\
444 --anchored exclude patterns match file name start (default)\n\
445 --no-anchored exclude patterns match after any /\n\
446 --ignore-case exclusion ignores case\n\
447 --no-ignore-case exclusion is case sensitive (default)\n\
448 --wildcards exclude patterns use wildcards (default)\n\
449 --no-wildcards exclude patterns are plain strings\n\
450 --wildcards-match-slash exclude pattern wildcards match '/' (default)\n\
451 --no-wildcards-match-slash exclude pattern wildcards do not match '/'\n\
452 -P, --absolute-names don't strip leading `/'s from file names\n\
453 -h, --dereference dump instead the files symlinks point to\n\
454 --no-recursion avoid descending automatically in directories\n\
455 -l, --one-file-system stay in local file system when creating archive\n\
456 -K, --starting-file=NAME begin at file NAME in the archive\n\
457 --strip-path=NUM strip NUM leading components from file names\n\
458 before extraction\n"),
462 -N, --newer=DATE only store files newer than DATE\n\
463 --newer-mtime=DATE compare date and time when data changed only\n\
464 --after-date=DATE same as -N\n"),
468 --backup[=CONTROL] backup before removal, choose version control\n\
469 --suffix=SUFFIX backup before removal, override usual suffix\n"),
473 Informative output:\n\
474 --help print this help, then exit\n\
475 --version print tar program version number, then exit\n\
476 -v, --verbose verbosely list files processed\n\
477 --checkpoint print directory names while reading the archive\n\
478 --check-links print a message if not all links are dumped\n\
479 --totals print total bytes written while creating archive\n\
480 --index-file=FILE send verbose output to FILE\n\
481 -R, --block-number show block number within archive with each message\n\
482 -w, --interactive ask for confirmation for every action\n\
483 --confirmation same as -w\n"),
487 Compatibility options:\n\
488 -o when creating, same as --old-archive\n\
489 when extracting, same as --no-same-owner\n"),
494 The backup suffix is `~', unless set with --suffix or SIMPLE_BACKUP_SUFFIX.\n\
495 The version control may be set with --backup or VERSION_CONTROL, values are:\n\
497 t, numbered make numbered backups\n\
498 nil, existing numbered if numbered backups exist, simple otherwise\n\
499 never, simple always make simple backups\n"),
503 ARCHIVE may be FILE, HOST:FILE or USER@HOST:FILE; DATE may be a textual date\n\
504 or a file name starting with `/' or `.', in which case the file's date is used.\n\
505 *This* `tar' defaults to `--format=%s -f%s -b%d'.\n"),
506 archive_format_string (DEFAULT_ARCHIVE_FORMAT
),
507 DEFAULT_ARCHIVE
, DEFAULT_BLOCKING
);
508 printf (_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT
);
513 /* Parse the options for tar. */
515 /* Available option letters are DEHIJQY and aenqy. Some are reserved:
517 e exit immediately with a nonzero exit status if unexpected errors occur
518 E use extended headers (draft POSIX headers, that is)
519 I same as T (for compatibility with Solaris tar)
520 n the archive is quickly seekable, so don't worry about random seeks
521 q stop after extracting the first occurrence of the named file
522 y per-file gzip compression
523 Y per-block gzip compression */
525 #define OPTION_STRING \
526 "-01234567ABC:F:GIK:L:MN:OPRST:UV:WX:Zb:cdf:g:hijklmoprstuvwxyz"
529 set_subcommand_option (enum subcommand subcommand
)
531 if (subcommand_option
!= UNKNOWN_SUBCOMMAND
532 && subcommand_option
!= subcommand
)
534 _("You may not specify more than one `-Acdtrux' option")));
536 subcommand_option
= subcommand
;
540 set_use_compress_program_option (const char *string
)
542 if (use_compress_program_option
&& strcmp (use_compress_program_option
, string
) != 0)
543 USAGE_ERROR ((0, 0, _("Conflicting compression options")));
545 use_compress_program_option
= string
;
549 decode_options (int argc
, char **argv
)
551 int optchar
; /* option letter */
552 int input_files
; /* number of input files */
553 char const *textual_date_option
= 0;
554 char const *backup_suffix_string
;
555 char const *version_control_string
= 0;
556 int exclude_options
= EXCLUDE_WILDCARDS
;
559 /* Set some default option values. */
561 subcommand_option
= UNKNOWN_SUBCOMMAND
;
562 archive_format
= DEFAULT_FORMAT
;
563 blocking_factor
= DEFAULT_BLOCKING
;
564 record_size
= DEFAULT_BLOCKING
* BLOCKSIZE
;
565 excluded
= new_exclude ();
566 newer_mtime_option
= TYPE_MINIMUM (time_t);
567 recursion_option
= FNM_LEADING_DIR
;
572 backup_suffix_string
= getenv ("SIMPLE_BACKUP_SUFFIX");
574 /* Convert old-style tar call by exploding option element and rearranging
575 options accordingly. */
577 if (argc
> 1 && argv
[1][0] != '-')
579 int new_argc
; /* argc value for rearranged arguments */
580 char **new_argv
; /* argv value for rearranged arguments */
581 char *const *in
; /* cursor into original argv */
582 char **out
; /* cursor into rearranged argv */
583 const char *letter
; /* cursor into old option letters */
584 char buffer
[3]; /* constructed option buffer */
585 const char *cursor
; /* cursor in OPTION_STRING */
587 /* Initialize a constructed option. */
592 /* Allocate a new argument array, and copy program name in it. */
594 new_argc
= argc
- 1 + strlen (argv
[1]);
595 new_argv
= xmalloc ((new_argc
+ 1) * sizeof (char *));
600 /* Copy each old letter option as a separate option, and have the
601 corresponding argument moved next to it. */
603 for (letter
= *in
++; *letter
; letter
++)
606 *out
++ = xstrdup (buffer
);
607 cursor
= strchr (OPTION_STRING
, *letter
);
608 if (cursor
&& cursor
[1] == ':')
610 if (in
< argv
+ argc
)
613 USAGE_ERROR ((0, 0, _("Old option `%c' requires an argument."),
618 /* Copy all remaining options. */
620 while (in
< argv
+ argc
)
624 /* Replace the old option list by the new one. */
630 /* Parse all options and non-options as they appear. */
634 prepend_default_options (getenv ("TAR_OPTIONS"), &argc
, &argv
);
636 while (optchar
= getopt_long (argc
, argv
, OPTION_STRING
, long_options
, 0),
641 usage (TAREXIT_FAILURE
);
647 /* File name or non-parsed option, because of RETURN_IN_ORDER
648 ordering triggered by the leading dash in OPTION_STRING. */
655 set_subcommand_option (CAT_SUBCOMMAND
);
661 if (! (xstrtoumax (optarg
, 0, 10, &u
, "") == LONGINT_OK
662 && u
== (blocking_factor
= u
)
663 && 0 < blocking_factor
664 && u
== (record_size
= u
* BLOCKSIZE
) / BLOCKSIZE
))
665 USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (optarg
),
666 _("Invalid blocking factor")));
671 /* Try to reblock input records. For reading 4.2BSD pipes. */
673 /* It would surely make sense to exchange -B and -R, but it seems
674 that -B has been used for a long while in Sun tar ans most
675 BSD-derived systems. This is a consequence of the block/record
676 terminology confusion. */
678 read_full_records_option
= true;
682 set_subcommand_option (CREATE_SUBCOMMAND
);
691 set_subcommand_option (DIFF_SUBCOMMAND
);
695 if (archive_names
== allocated_archive_names
)
697 allocated_archive_names
*= 2;
699 xrealloc (archive_name_array
,
700 sizeof (const char *) * allocated_archive_names
);
702 archive_name_array
[archive_names
++] = optarg
;
706 /* Since -F is only useful with -M, make it implied. Run this
707 script at the end of each tape. */
709 info_script_option
= optarg
;
710 multi_volume_option
= true;
714 listed_incremental_option
= optarg
;
715 after_date_option
= true;
719 /* We are making an incremental dump (FIXME: are we?); save
720 directories at the beginning of the archive, and include in each
721 directory its contents. */
723 incremental_option
= true;
727 /* Follow symbolic links. */
728 dereference_option
= true;
732 /* Ignore zero blocks (eofs). This can't be the default,
733 because Unix tar writes two blocks of zeros, then pads out
734 the record with garbage. */
736 ignore_zeros_option
= true;
741 _("Warning: the -I option is not supported;"
742 " perhaps you meant -j or -T?")));
746 set_use_compress_program_option ("bzip2");
750 /* Don't replace existing files. */
751 old_files_option
= KEEP_OLD_FILES
;
755 starting_file_option
= true;
760 /* When dumping directories, don't dump files/subdirectories
761 that are on other filesystems. */
763 one_file_system_option
= true;
769 if (xstrtoumax (optarg
, 0, 10, &u
, "") != LONGINT_OK
)
770 USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (optarg
),
771 _("Invalid tape length")));
772 tape_length_option
= 1024 * (tarlong
) u
;
773 multi_volume_option
= true;
782 /* Make multivolume archive: when we can't write any more into
783 the archive, re-open it, and continue writing. */
785 multi_volume_option
= true;
790 after_date_option
= true;
793 case NEWER_MTIME_OPTION
:
794 if (newer_mtime_option
!= TYPE_MINIMUM (time_t))
795 USAGE_ERROR ((0, 0, _("More than one threshold date")));
797 if (FILESYSTEM_PREFIX_LEN (optarg
) != 0
802 if (deref_stat (dereference_option
, optarg
, &st
) != 0)
805 USAGE_ERROR ((0, 0, _("Date file not found")));
807 newer_mtime_option
= st
.st_mtime
;
811 newer_mtime_option
= get_date (optarg
, 0);
812 if (newer_mtime_option
== (time_t) -1)
813 WARN ((0, 0, _("Substituting %s for unknown date format %s"),
814 tartime (newer_mtime_option
), quote (optarg
)));
816 textual_date_option
= optarg
;
820 #endif /* not MSDOS */
827 to_stdout_option
= true;
831 same_permissions_option
= true;
835 absolute_names_option
= true;
839 set_subcommand_option (APPEND_SUBCOMMAND
);
843 /* Print block numbers for debugging bad tar archives. */
845 /* It would surely make sense to exchange -B and -R, but it seems
846 that -B has been used for a long while in Sun tar ans most
847 BSD-derived systems. This is a consequence of the block/record
848 terminology confusion. */
850 block_number_option
= true;
854 /* Names to extr are sorted. */
856 same_order_option
= true;
860 sparse_option
= true;
864 set_subcommand_option (LIST_SUBCOMMAND
);
869 files_from_option
= optarg
;
873 set_subcommand_option (UPDATE_SUBCOMMAND
);
877 old_files_option
= UNLINK_FIRST_OLD_FILES
;
885 volume_label_option
= optarg
;
889 interactive_option
= true;
893 verify_option
= true;
897 set_subcommand_option (EXTRACT_SUBCOMMAND
);
901 if (add_exclude_file (add_exclude
, excluded
, optarg
,
902 exclude_options
| recursion_option
, '\n')
906 FATAL_ERROR ((0, e
, "%s", quotearg_colon (optarg
)));
912 _("Warning: the -y option is not supported;"
913 " perhaps you meant -j?")));
917 set_use_compress_program_option ("gzip");
921 set_use_compress_program_option ("compress");
924 case ANCHORED_OPTION
:
925 exclude_options
|= EXCLUDE_ANCHORED
;
928 case ATIME_PRESERVE_OPTION
:
929 atime_preserve_option
= true;
932 case CHECKPOINT_OPTION
:
933 checkpoint_option
= true;
937 backup_option
= true;
939 version_control_string
= optarg
;
943 set_subcommand_option (DELETE_SUBCOMMAND
);
947 add_exclude (excluded
, optarg
, exclude_options
| recursion_option
);
950 case FORCE_LOCAL_OPTION
:
951 force_local_option
= true;
955 set_archive_format (optarg
);
958 case INDEX_FILE_OPTION
:
959 index_file_name
= optarg
;
962 case IGNORE_CASE_OPTION
:
963 exclude_options
|= FNM_CASEFOLD
;
966 case IGNORE_FAILED_READ_OPTION
:
967 ignore_failed_read_option
= true;
971 if (! (strlen (optarg
) < GNAME_FIELD_SIZE
972 && gname_to_gid (optarg
, &group_option
)))
975 if (xstrtoumax (optarg
, 0, 10, &g
, "") == LONGINT_OK
979 FATAL_ERROR ((0, 0, "%s: %s", quotearg_colon (optarg
),
980 _("%s: Invalid group")));
986 = mode_compile (optarg
,
987 MODE_MASK_EQUALS
| MODE_MASK_PLUS
| MODE_MASK_MINUS
);
988 if (mode_option
== MODE_INVALID
)
989 FATAL_ERROR ((0, 0, _("Invalid mode given on option")));
990 if (mode_option
== MODE_MEMORY_EXHAUSTED
)
994 case NO_ANCHORED_OPTION
:
995 exclude_options
&= ~ EXCLUDE_ANCHORED
;
998 case NO_IGNORE_CASE_OPTION
:
999 exclude_options
&= ~ FNM_CASEFOLD
;
1002 case NO_OVERWRITE_DIR_OPTION
:
1003 old_files_option
= NO_OVERWRITE_DIR_OLD_FILES
;
1006 case NO_WILDCARDS_OPTION
:
1007 exclude_options
&= ~ EXCLUDE_WILDCARDS
;
1010 case NO_WILDCARDS_MATCH_SLASH_OPTION
:
1011 exclude_options
|= FNM_FILE_NAME
;
1015 filename_terminator
= '\0';
1018 case NUMERIC_OWNER_OPTION
:
1019 numeric_owner_option
= true;
1022 case OVERWRITE_OPTION
:
1023 old_files_option
= OVERWRITE_OLD_FILES
;
1027 if (! (strlen (optarg
) < UNAME_FIELD_SIZE
1028 && uname_to_uid (optarg
, &owner_option
)))
1031 if (xstrtoumax (optarg
, 0, 10, &u
, "") == LONGINT_OK
1035 FATAL_ERROR ((0, 0, "%s: %s", quotearg_colon (optarg
),
1036 _("Invalid owner")));
1041 set_archive_format ("posix");
1044 case PRESERVE_OPTION
:
1045 same_permissions_option
= true;
1046 same_order_option
= true;
1049 case RECORD_SIZE_OPTION
:
1052 if (! (xstrtoumax (optarg
, 0, 10, &u
, "") == LONGINT_OK
1053 && u
== (size_t) u
))
1054 USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (optarg
),
1055 _("Invalid record size")));
1057 if (record_size
% BLOCKSIZE
!= 0)
1058 USAGE_ERROR ((0, 0, _("Record size must be a multiple of %d."),
1060 blocking_factor
= record_size
/ BLOCKSIZE
;
1064 case RECURSIVE_UNLINK_OPTION
:
1065 recursive_unlink_option
= true;
1068 case REMOVE_FILES_OPTION
:
1069 remove_files_option
= true;
1072 case RSH_COMMAND_OPTION
:
1073 rsh_command_option
= optarg
;
1076 case STRIP_PATH_OPTION
:
1079 if (! (xstrtoumax (optarg
, 0, 10, &u
, "") == LONGINT_OK
1080 && u
== (size_t) u
))
1081 USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (optarg
),
1082 _("Invalid number of elements")));
1083 strip_path_elements
= u
;
1088 backup_option
= true;
1089 backup_suffix_string
= optarg
;
1093 totals_option
= true;
1096 case USE_COMPRESS_PROGRAM_OPTION
:
1097 set_use_compress_program_option (optarg
);
1100 case VOLNO_FILE_OPTION
:
1101 volno_file_option
= optarg
;
1104 case WILDCARDS_OPTION
:
1105 exclude_options
|= EXCLUDE_WILDCARDS
;
1108 case WILDCARDS_MATCH_SLASH_OPTION
:
1109 exclude_options
&= ~ FNM_FILE_NAME
;
1121 #ifdef DEVICE_PREFIX
1123 int device
= optchar
- '0';
1125 static char buf
[sizeof DEVICE_PREFIX
+ 10];
1128 density
= getopt_long (argc
, argv
, "lmh", 0, 0);
1129 strcpy (buf
, DEVICE_PREFIX
);
1130 cursor
= buf
+ strlen (buf
);
1132 #ifdef DENSITY_LETTER
1134 sprintf (cursor
, "%d%c", device
, density
);
1136 #else /* not DENSITY_LETTER */
1163 usage (TAREXIT_FAILURE
);
1165 sprintf (cursor
, "%d", device
);
1167 #endif /* not DENSITY_LETTER */
1169 if (archive_names
== allocated_archive_names
)
1171 allocated_archive_names
*= 2;
1172 archive_name_array
=
1173 xrealloc (archive_name_array
,
1174 sizeof (const char *) * allocated_archive_names
);
1176 archive_name_array
[archive_names
++] = strdup (buf
);
1180 #else /* not DEVICE_PREFIX */
1183 _("Options `-[0-7][lmh]' not supported by *this* tar")));
1185 #endif /* not DEVICE_PREFIX */
1188 /* Special handling for 'o' option:
1190 GNU tar used to say "output old format".
1191 UNIX98 tar says don't chown files after extracting (we use
1192 "--no-same-owner" for this).
1194 The old GNU tar semantics is retained when used with --create
1195 option, otherwise UNIX98 semantics is assumed */
1199 if (subcommand_option
== CREATE_SUBCOMMAND
)
1201 /* GNU Tar <= 1.13 compatibility */
1202 set_archive_format ("v7");
1206 /* UNIX98 compatibility */
1207 same_owner_option
= 1;
1211 /* Handle operands after any "--" argument. */
1212 for (; optind
< argc
; optind
++)
1214 name_add (argv
[optind
]);
1218 /* Process trivial options. */
1222 printf ("tar (%s) %s\n%s\n", PACKAGE_NAME
, PACKAGE_VERSION
,
1223 "Copyright (C) 2003 Free Software Foundation, Inc.");
1225 This program comes with NO WARRANTY, to the extent permitted by law.\n\
1226 You may redistribute it under the terms of the GNU General Public License;\n\
1227 see the file named COPYING for details."));
1229 puts (_("Written by John Gilmore and Jay Fenlason."));
1231 exit (TAREXIT_SUCCESS
);
1235 usage (TAREXIT_SUCCESS
);
1237 /* Derive option values and check option consistency. */
1239 if (archive_format
== DEFAULT_FORMAT
)
1240 archive_format
= DEFAULT_ARCHIVE_FORMAT
;
1242 if (archive_format
== GNU_FORMAT
&& getenv ("POSIXLY_CORRECT"))
1243 archive_format
= POSIX_FORMAT
;
1245 if (((volume_label_option
&& subcommand_option
== CREATE_SUBCOMMAND
)
1246 || incremental_option
|| multi_volume_option
|| sparse_option
)
1247 && archive_format
!= OLDGNU_FORMAT
&& archive_format
!= GNU_FORMAT
)
1249 _("GNU features wanted on incompatible archive format")));
1251 if (archive_names
== 0)
1253 /* If no archive file name given, try TAPE from the environment, or
1254 else, DEFAULT_ARCHIVE from the configuration process. */
1257 archive_name_array
[0] = getenv ("TAPE");
1258 if (! archive_name_array
[0])
1259 archive_name_array
[0] = DEFAULT_ARCHIVE
;
1262 /* Allow multiple archives only with `-M'. */
1264 if (archive_names
> 1 && !multi_volume_option
)
1266 _("Multiple archive files requires `-M' option")));
1268 if (listed_incremental_option
1269 && newer_mtime_option
!= TYPE_MINIMUM (time_t))
1271 _("Cannot combine --listed-incremental with --newer")));
1273 if (volume_label_option
)
1275 size_t volume_label_max_len
=
1276 (sizeof current_header
->header
.name
1277 - 1 /* for trailing '\0' */
1278 - (multi_volume_option
1279 ? (sizeof " Volume "
1280 - 1 /* for null at end of " Volume " */
1281 + INT_STRLEN_BOUND (int) /* for volume number */
1282 - 1 /* for sign, as 0 <= volno */)
1284 if (volume_label_max_len
< strlen (volume_label_option
))
1286 ngettext ("%s: Volume label is too long (limit is %lu byte)",
1287 "%s: Volume label is too long (limit is %lu bytes)",
1288 volume_label_max_len
),
1289 quotearg_colon (volume_label_option
),
1290 (unsigned long) volume_label_max_len
));
1293 /* If ready to unlink hierarchies, so we are for simpler files. */
1294 if (recursive_unlink_option
)
1295 old_files_option
= UNLINK_FIRST_OLD_FILES
;
1297 /* Forbid using -c with no input files whatsoever. Check that `-f -',
1298 explicit or implied, is used correctly. */
1300 switch (subcommand_option
)
1302 case CREATE_SUBCOMMAND
:
1303 if (input_files
== 0 && !files_from_option
)
1305 _("Cowardly refusing to create an empty archive")));
1308 case EXTRACT_SUBCOMMAND
:
1309 case LIST_SUBCOMMAND
:
1310 case DIFF_SUBCOMMAND
:
1311 for (archive_name_cursor
= archive_name_array
;
1312 archive_name_cursor
< archive_name_array
+ archive_names
;
1313 archive_name_cursor
++)
1314 if (!strcmp (*archive_name_cursor
, "-"))
1315 request_stdin ("-f");
1318 case CAT_SUBCOMMAND
:
1319 case UPDATE_SUBCOMMAND
:
1320 case APPEND_SUBCOMMAND
:
1321 for (archive_name_cursor
= archive_name_array
;
1322 archive_name_cursor
< archive_name_array
+ archive_names
;
1323 archive_name_cursor
++)
1324 if (!strcmp (*archive_name_cursor
, "-"))
1326 _("Options `-Aru' are incompatible with `-f -'")));
1332 archive_name_cursor
= archive_name_array
;
1334 /* Prepare for generating backup names. */
1336 if (backup_suffix_string
)
1337 simple_backup_suffix
= xstrdup (backup_suffix_string
);
1340 backup_type
= xget_version ("--backup", version_control_string
);
1342 if (verbose_option
&& textual_date_option
)
1344 char const *treated_as
= tartime (newer_mtime_option
);
1345 if (strcmp (textual_date_option
, treated_as
) != 0)
1346 WARN ((0, 0, _("Treating date `%s' as %s"),
1347 textual_date_option
, treated_as
));
1353 /* Main routine for tar. */
1355 main (int argc
, char **argv
)
1357 #if HAVE_CLOCK_GETTIME
1358 if (clock_gettime (CLOCK_REALTIME
, &start_timespec
) != 0)
1360 start_time
= time (0);
1361 program_name
= argv
[0];
1362 setlocale (LC_ALL
, "");
1363 bindtextdomain (PACKAGE
, LOCALEDIR
);
1364 textdomain (PACKAGE
);
1366 exit_status
= TAREXIT_SUCCESS
;
1367 filename_terminator
= '\n';
1368 set_quoting_style (0, escape_quoting_style
);
1370 /* Pre-allocate a few structures. */
1372 allocated_archive_names
= 10;
1373 archive_name_array
=
1374 xmalloc (sizeof (const char *) * allocated_archive_names
);
1378 /* System V fork+wait does not work if SIGCHLD is ignored. */
1379 signal (SIGCHLD
, SIG_DFL
);
1384 /* Decode options. */
1386 decode_options (argc
, argv
);
1387 name_init (argc
, argv
);
1389 /* Main command execution. */
1391 if (volno_file_option
)
1392 init_volume_number ();
1394 switch (subcommand_option
)
1396 case UNKNOWN_SUBCOMMAND
:
1398 _("You must specify one of the `-Acdtrux' options")));
1400 case CAT_SUBCOMMAND
:
1401 case UPDATE_SUBCOMMAND
:
1402 case APPEND_SUBCOMMAND
:
1406 case DELETE_SUBCOMMAND
:
1407 delete_archive_members ();
1410 case CREATE_SUBCOMMAND
:
1415 print_total_written ();
1418 case EXTRACT_SUBCOMMAND
:
1420 read_and (extract_archive
);
1422 /* FIXME: should extract_finish () even if an ordinary signal is
1428 case LIST_SUBCOMMAND
:
1429 read_and (list_archive
);
1432 case DIFF_SUBCOMMAND
:
1434 read_and (diff_archive
);
1438 if (check_links_option
)
1441 if (volno_file_option
)
1442 closeout_volume_number ();
1444 /* Dispose of allocated memory, and return. */
1446 free (archive_name_array
);
1449 if (stdlis
!= stderr
&& (ferror (stdlis
) || fclose (stdlis
) != 0))
1450 FATAL_ERROR ((0, 0, _("Error in writing to standard output")));
1451 if (exit_status
== TAREXIT_FAILURE
)
1452 error (0, 0, _("Error exit delayed from previous errors"));
1453 if (ferror (stderr
) || fclose (stderr
) != 0)
1454 exit_status
= TAREXIT_FAILURE
;
1459 destroy_stat (struct tar_stat_info
*st
)
1461 free (st
->orig_file_name
);
1462 free (st
->file_name
);
1463 free (st
->link_name
);
1466 memset (st
, 0, sizeof (*st
));