1 /* A tar (tape archiver) program.
3 Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1999, 2000,
4 2001, 2003, 2004 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
62 /* Name of option using stdin. */
63 static const char *stdin_used_by
;
65 /* Doesn't return if stdin already requested. */
67 request_stdin (const char *option
)
70 USAGE_ERROR ((0, 0, _("Options `-%s' and `-%s' both want standard input"),
71 stdin_used_by
, option
));
73 stdin_used_by
= option
;
76 /* Returns true if and only if the user typed 'y' or 'Y'. */
78 confirm (const char *message_action
, const char *message_name
)
80 static FILE *confirm_file
;
81 static int confirm_file_EOF
;
85 if (archive
== 0 || stdin_used_by
)
87 confirm_file
= fopen (TTY_NAME
, "r");
89 open_fatal (TTY_NAME
);
98 fprintf (stdlis
, "%s %s?", message_action
, quote (message_name
));
102 int reply
= confirm_file_EOF
? EOF
: getc (confirm_file
);
105 for (character
= reply
;
107 character
= getc (confirm_file
))
108 if (character
== EOF
)
110 confirm_file_EOF
= 1;
111 fputc ('\n', stdlis
);
115 return reply
== 'y' || reply
== 'Y';
119 static struct fmttab
{
121 enum archive_format fmt
;
124 { "oldgnu", OLDGNU_FORMAT
},
125 { "ustar", USTAR_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 archive_format
= p
->fmt
;
148 archive_format_string (enum archive_format fmt
)
150 struct fmttab
const *p
;
152 for (p
= fmttab
; p
->name
; p
++)
158 #define FORMAT_MASK(n) (1<<(n))
161 assert_format(unsigned fmt_mask
)
163 if ((FORMAT_MASK(archive_format
) & fmt_mask
) == 0)
165 _("GNU features wanted on incompatible archive format")));
172 /* For long options that unconditionally set a single flag, we have getopt
173 do it. For the others, we share the code for the equivalent short
174 named option, the name of which is stored in the otherwise-unused `val'
175 field of the `struct option'; for long options that have no equivalent
176 short option, we use non-characters as pseudo short options,
177 starting at CHAR_MAX + 1 and going upwards. */
181 ANCHORED_OPTION
= CHAR_MAX
+ 1,
182 ATIME_PRESERVE_OPTION
,
192 IGNORE_FAILED_READ_OPTION
,
194 KEEP_NEWER_FILES_OPTION
,
199 NO_IGNORE_CASE_OPTION
,
200 NO_OVERWRITE_DIR_OPTION
,
202 NO_SAME_OWNER_OPTION
,
203 NO_SAME_PERMISSIONS_OPTION
,
205 NO_WILDCARDS_MATCH_SLASH_OPTION
,
207 NUMERIC_OWNER_OPTION
,
217 RECURSIVE_UNLINK_OPTION
,
222 SHOW_DEFAULTS_OPTION
,
223 SHOW_OMITTED_DIRS_OPTION
,
224 STRIP_COMPONENTS_OPTION
,
228 USE_COMPRESS_PROGRAM_OPTION
,
233 WILDCARDS_MATCH_SLASH_OPTION
236 const char *argp_program_version
= "tar (" PACKAGE
") " VERSION
;
237 const char *argp_program_bug_address
= "<" PACKAGE_BUGREPORT
">";
238 static char doc
[] = N_("GNU `tar' saves many files together into a single tape or disk archive, and can restore individual files from the archive.\n\
241 tar -cf archive.tar foo bar # Create archive.tar from files foo and bar.\n\
242 tar -tvf archive.tar # List all files in archive.tar verbosely.\n\
243 tar -xf archive.tar # Extract all files from archive.tar.\n\
244 \vThe backup suffix is `~', unless set with --suffix or SIMPLE_BACKUP_SUFFIX.\n\
245 The version control may be set with --backup or VERSION_CONTROL, values are:\n\n\
246 t, numbered make numbered backups\n\
247 nil, existing numbered if numbered backups exist, simple otherwise\n\
248 never, simple always make simple backups\n");
251 static struct argp_option options
[] = {
253 N_("Main operation mode:"), 0},
256 N_("list the contents of an archive"), 10 },
257 {"extract", 'x', 0, 0,
258 N_("extract files from an archive"), 10 },
259 {"get", 0, 0, OPTION_ALIAS
, NULL
},
260 {"create", 'c', 0, 0,
261 N_("create a new archive"), 10 },
263 N_("find differences between archive and file system"), 10 },
264 {"compare", 0, 0, OPTION_ALIAS
, NULL
, 10},
265 {"append", 'r', 0, 0,
266 N_("append files to the end of an archive"), 10 },
267 {"update", 'u', 0, 0,
268 N_("only append files newer than copy in archive"), 10 },
269 {"catenate", 'A', 0, 0,
270 N_("append tar files to an archive"), 10 },
271 {"concatenate", 0, 0, OPTION_ALIAS
, NULL
, 10},
272 {"delete", DELETE_OPTION
, 0, 0,
273 N_("delete from the archive (not on mag tapes!)"), 10 },
276 N_("Operation modifiers:"), 20},
278 {"verify", 'W', 0, 0,
279 N_("attempt to verify the archive after writing it"), 21 },
280 {"remove-files", REMOVE_FILES_OPTION
, 0, 0,
281 N_("remove files after adding them to the archive"), 21 },
282 {"keep-old-files", 'k', 0, 0,
283 N_("don't replace existing files when extracting"), 21 },
284 {"keep-newer-files", KEEP_NEWER_FILES_OPTION
, 0, 0,
285 N_("don't replace existing files that are newer than their archive copies"), 21 },
286 {"no-overwrite-dir", NO_OVERWRITE_DIR_OPTION
, 0, 0,
287 N_("preserve metadata of existing directories"), 21 },
288 {"overwrite", OVERWRITE_OPTION
, 0, 0,
289 N_("overwrite existing files when extracting"), 21 },
290 {"unlink-first", 'U', 0, 0,
291 N_("remove each file prior to extracting over it"), 21 },
292 {"recursive-unlink", RECURSIVE_UNLINK_OPTION
, 0, 0,
293 N_("empty hierarchies prior to extracting directory"), 21 },
294 {"sparse", 'S', 0, 0,
295 N_("handle sparse files efficiently"), 21 },
296 {"to-stdout", 'O', 0, 0,
297 N_("extract files to standard output"), 21 },
298 {"incremental", 'G', 0, 0,
299 N_("handle old GNU-format incremental backup"), 21 },
300 {"listed-incremental", 'g', N_("FILE"), 0,
301 N_("handle new GNU-format incremental backup"), 21 },
302 {"ignore-failed-read", IGNORE_FAILED_READ_OPTION
, 0, 0,
303 N_("do not exit with nonzero on unreadable files"), 21 },
304 {"occurrence", OCCURRENCE_OPTION
, N_("NUMBER"), OPTION_ARG_OPTIONAL
,
305 N_("process only the NUMth occurrence of each file in the archive. This option is valid only in conjunction with one of the subcommands --delete, --diff, --extract or --list and when a list of files is given either on the command line or via -T option. NUMBER defaults to 1."), 21 },
308 N_("Handling of file attributes:"), 30 },
310 {"owner", OWNER_OPTION
, N_("NAME"), 0,
311 N_("force NAME as owner for added files"), 31 },
312 {"group", GROUP_OPTION
, N_("NAME"), 0,
313 N_("force NAME as group for added files"), 31 },
314 {"mode", MODE_OPTION
, N_("CHANGES"), 0,
315 N_("force (symbolic) mode CHANGES for added files"), 31 },
316 {"atime-preserve", ATIME_PRESERVE_OPTION
, 0, 0,
317 N_("don't change access times on dumped files"), 31 },
319 N_("don't extract file modified time"), 31 },
320 {"same-owner", SAME_OWNER_OPTION
, 0, 0,
321 N_("try extracting files with the same ownership"), 31 },
322 {"no-same-owner", NO_SAME_OWNER_OPTION
, 0, 0,
323 N_("extract files as yourself"), 31 },
324 {"numeric-owner", NUMERIC_OWNER_OPTION
, 0, 0,
325 N_("always use numbers for user/group names"), 31 },
326 {"preserve-permissions", 'p', 0, 0,
327 N_("extract permissions information"), 31 },
328 {"same-permissions", 0, 0, OPTION_ALIAS
, NULL
, 31 },
329 {"no-same-permissions", NO_SAME_PERMISSIONS_OPTION
, 0, 0,
330 N_("do not extract permissions information"), 31 },
331 {"preserve-order", 's', 0, 0,
332 N_("sort names to extract to match archive"), 31 },
333 {"same-order", 0, 0, OPTION_ALIAS
, NULL
, 31 },
334 {"preserve", PRESERVE_OPTION
, 0, 0,
335 N_("same as both -p and -s"), 31 },
338 N_("Device selection and switching:"), 40 },
340 {"file", 'f', N_("ARCHIVE"), 0,
341 N_("use archive file or device ARCHIVE"), 41 },
342 {"force-local", FORCE_LOCAL_OPTION
, 0, 0,
343 N_("archive file is local even if has a colon"), 41 },
344 {"rmt-command", RMT_COMMAND_OPTION
, N_("COMMAND"), 0,
345 N_("use given rmt COMMAND instead of rmt"), 41 },
346 {"rsh-command", RSH_COMMAND_OPTION
, N_("COMMAND"), 0,
347 N_("use remote COMMAND instead of rsh"), 41 },
349 {"-[0-7][lmh]", 0, NULL
, OPTION_DOC
,
350 N_("specify drive and density"), 41 },
352 {NULL
, '0', NULL
, OPTION_HIDDEN
, NULL
, 41 },
353 {NULL
, '1', NULL
, OPTION_HIDDEN
, NULL
, 41 },
354 {NULL
, '2', NULL
, OPTION_HIDDEN
, NULL
, 41 },
355 {NULL
, '3', NULL
, OPTION_HIDDEN
, NULL
, 41 },
356 {NULL
, '4', NULL
, OPTION_HIDDEN
, NULL
, 41 },
357 {NULL
, '5', NULL
, OPTION_HIDDEN
, NULL
, 41 },
358 {NULL
, '6', NULL
, OPTION_HIDDEN
, NULL
, 41 },
359 {NULL
, '7', NULL
, OPTION_HIDDEN
, NULL
, 41 },
360 {NULL
, '8', NULL
, OPTION_HIDDEN
, NULL
, 41 },
361 {NULL
, '9', NULL
, OPTION_HIDDEN
, NULL
, 41 },
363 {"multi-volume", 'M', 0, 0,
364 N_("create/list/extract multi-volume archive"), 41 },
365 {"tape-length", 'L', N_("NUMBER"), 0,
366 N_("change tape after writing NUMBER x 1024 bytes"), 41 },
367 {"info-script", 'F', N_("NAME"), 0,
368 N_("run script at end of each tape (implies -M)"), 41 },
369 {"new-volume-script", 0, 0, OPTION_ALIAS
, NULL
, 41 },
370 {"volno-file", VOLNO_FILE_OPTION
, N_("FILE"), 0,
371 N_("use/update the volume number in FILE"), 41 },
374 N_("Device blocking:"), 50 },
376 {"blocking-factor", 'b', N_("BLOCKS"), 0,
377 N_("BLOCKS x 512 bytes per record"), 51 },
378 {"record-size", RECORD_SIZE_OPTION
, N_("NUMBER"), 0,
379 N_("SIZE bytes per record, multiple of 512"), 51 },
380 {"ignore-zeros", 'i', 0, 0,
381 N_("ignore zeroed blocks in archive (means EOF)"), 51 },
382 {"read-full-records", 'B', 0, 0,
383 N_("reblock as we read (for 4.2BSD pipes)"), 51 },
386 N_("Archive format selection:"), 60 },
388 {"format", FORMAT_OPTION
, N_("FORMAT"), 0,
389 N_("create archive of the given format."), 61 },
391 {"", 0, NULL
, OPTION_DOC
, N_("FORMAT is one of the following:"), 62},
392 {"", 0, NULL
, OPTION_DOC
, N_("v7 old V7 tar format"), 63},
393 {"", 0, NULL
, OPTION_DOC
, N_("oldgnu GNU format as per tar <= 1.12"), 63},
394 {"", 0, NULL
, OPTION_DOC
, N_("gnu GNU tar 1.13.x format"), 63},
395 {"", 0, NULL
, OPTION_DOC
, N_("ustar POSIX 1003.1-1988 (ustar) format"), 63 },
396 {"", 0, NULL
, OPTION_DOC
, N_("posix POSIX 1003.1-2001 (pax) format"), 63 },
398 {"old-archive", OLD_ARCHIVE_OPTION
, 0, 0, /* FIXME */
399 N_("same as --format=v7"), 68 },
400 {"portability", 0, 0, OPTION_ALIAS
, NULL
, 68 },
401 {"posix", POSIX_OPTION
, 0, 0,
402 N_("same as --format=posix"), 68 },
403 {"pax-option", PAX_OPTION
, N_("keyword[[:]=value][,keyword[[:]=value], ...]"), 0,
404 N_("control pax keywords"), 68 },
405 {"label", 'V', N_("TEXT"), 0,
406 N_("create archive with volume name NAME. At list/extract time, use TEXT as a globbing pattern"), 68 },
408 N_("filter the archive through bzip2"), 68 },
410 N_("filter the archive through gzip"), 68 },
411 {"gunzip", 0, 0, OPTION_ALIAS
, NULL
, 68 },
412 {"ungzip", 0, 0, OPTION_ALIAS
, NULL
, 68 },
413 {"compress", 'Z', 0, 0,
414 N_("filter the archive through compress"), 68 },
415 {"uncompress", 0, 0, OPTION_ALIAS
, NULL
, 68 },
416 {"use-compress-program", USE_COMPRESS_PROGRAM_OPTION
, N_("PROG"), 0,
417 N_("filter through PROG (must accept -d)"), 68 },
420 N_("Local file selection:"), 70 },
422 {"directory", 'C', N_("DIR"), 0,
423 N_("change to directory DIR"), 71 },
424 {"files-from", 'T', N_("FILE-OF-NAMES"), 0,
425 N_("get names to extract or create from file NAME"), 71 },
426 {"null", NULL_OPTION
, 0, 0,
427 N_("-T reads null-terminated names, disable -C"), 71 },
428 {"exclude", EXCLUDE_OPTION
, N_("PATTERN"), 0,
429 N_("exclude files, given as a PATTERN"), 71 },
430 {"exclude-from", 'X', N_("FILE"), 0,
431 N_("exclude patterns listed in FILE"), 71 },
432 {"ignore-case", IGNORE_CASE_OPTION
, 0, 0,
433 N_("exclusion ignores case"), 71 },
434 {"anchored", ANCHORED_OPTION
, 0, 0,
435 N_("exclude patterns match file name start (default)"), 71 },
436 {"no-anchored", NO_ANCHORED_OPTION
, 0, 0,
437 N_("exclude patterns match after any /"), 71 },
438 {"no-ignore-case", NO_IGNORE_CASE_OPTION
, 0, 0,
439 N_("exclusion is case sensitive (default)"), 71 },
440 {"no-wildcards", NO_WILDCARDS_OPTION
, 0, 0,
441 N_("exclude patterns are plain strings"), 71 },
442 {"no-wildcards-match-slash", NO_WILDCARDS_MATCH_SLASH_OPTION
, 0, 0,
443 N_("exclude pattern wildcards do not match '/'"), 71 },
444 {"no-recursion", NO_RECURSION_OPTION
, 0, 0,
445 N_("avoid descending automatically in directories"), 71 },
446 {"one-file-system", 'l', 0, 0, /* FIXME: emit warning */
447 N_("stay in local file system when creating archive"), 71 },
448 {"recursion", RECURSION_OPTION
, 0, 0,
449 N_("recurse into directories (default)"), 71 },
450 {"absolute-names", 'P', 0, 0,
451 N_("don't strip leading `/'s from file names"), 71 },
452 {"dereference", 'h', 0, 0,
453 N_("dump instead the files symlinks point to"), 71 },
454 {"starting-file", 'K', N_("MEMBER-NAME"), 0,
455 N_("begin at member MEMBER-NAME in the archive"), 71 },
456 {"strip-components", STRIP_COMPONENTS_OPTION
, N_("NUMBER"), 0,
457 N_("strip NUMBER leading components from file names"), 71 },
458 {"newer", 'N', N_("DATE-OR-FILE"), 0,
459 N_("only store files newer than DATE-OR-FILE"), 71 },
460 {"newer-mtime", NEWER_MTIME_OPTION
, N_("DATE"), 0,
461 N_("compare date and time when data changed only"), 71 },
462 {"after-date", 'N', N_("DATE"), 0,
463 N_("same as -N"), 71 },
464 {"backup", BACKUP_OPTION
, N_("CONTROL"), OPTION_ARG_OPTIONAL
,
465 N_("backup before removal, choose version CONTROL"), 71 },
466 {"suffix", SUFFIX_OPTION
, N_("STRING"), 0,
467 N_("backup before removal, override usual suffix ('~' unless overridden by environment variable SIMPLE_BACKUP_SUFFIX"), 71 },
468 {"wildcards", WILDCARDS_OPTION
, 0, 0,
469 N_("exclude patterns use wildcards (default)"), 71 },
470 {"wildcards-match-slash", WILDCARDS_MATCH_SLASH_OPTION
, 0, 0,
471 N_("exclude pattern wildcards match '/' (default)"), 71 },
474 N_("Informative output:"), 80 },
476 {"verbose", 'v', 0, 0,
477 N_("verbosely list files processed"), 81 },
478 {"checkpoint", CHECKPOINT_OPTION
, 0, 0,
479 N_("print directory names while reading the archive"), 81 },
480 {"check-links", CHECK_LINKS_OPTION
, 0, 0,
481 N_("print a message if not all links are dumped"), 82 },
482 {"totals", TOTALS_OPTION
, 0, 0,
483 N_("print total bytes written while creating archive"), 82 },
484 {"utc", UTC_OPTION
, 0, 0,
485 N_("print file modification dates in UTC"), 82 },
486 {"index-file", INDEX_FILE_OPTION
, N_("FILE"), 0,
487 N_("send verbose output to FILE"), 82 },
488 {"block-number", 'R', 0, 0,
489 N_("show block number within archive with each message"), 82 },
490 {"interactive", 'w', 0, 0,
491 N_("ask for confirmation for every action"), 82 },
492 {"confirmation", 0, 0, OPTION_ALIAS
, NULL
, 82 },
493 {"show-defaults", SHOW_DEFAULTS_OPTION
, 0, 0,
494 N_("Show tar defaults"), 82 },
495 {"show-omitted-dirs", SHOW_OMITTED_DIRS_OPTION
, 0, 0,
496 N_("When listing or extracting, list each directory that does not match search criteria"), 82 },
499 N_("Compatibility options:"), 90 },
502 N_("when creating, same as --old-archive. When extracting, same as --no-same-owner"), 91 },
505 N_("Other options:"), 100 },
507 {"help", '?', 0, 0, N_("Give this help list"), -1},
508 {"usage", USAGE_OPTION
, 0, 0, N_("Give a short usage message"), -1},
509 {"license", LICENSE_OPTION
, 0, 0, N_("Print license and exit"), -1},
510 {"version", VERSION_OPTION
, 0, 0, N_("Print program version"), -1},
511 /* FIXME -V (--label) conflicts with the default short option for
518 char const *textual_date_option
;
522 char const *backup_suffix_string
;
523 char const *version_control_string
;
528 show_default_settings (FILE *stream
)
531 "--format=%s -f%s -b%d --rmt-command=%s --rsh-command=%s\n",
532 archive_format_string (DEFAULT_ARCHIVE_FORMAT
),
533 DEFAULT_ARCHIVE
, DEFAULT_BLOCKING
,
534 DEFAULT_RMT_COMMAND
, REMOTE_SHELL
);
538 set_subcommand_option (enum subcommand subcommand
)
540 if (subcommand_option
!= UNKNOWN_SUBCOMMAND
541 && subcommand_option
!= subcommand
)
543 _("You may not specify more than one `-Acdtrux' option")));
545 subcommand_option
= subcommand
;
549 set_use_compress_program_option (const char *string
)
551 if (use_compress_program_option
&& strcmp (use_compress_program_option
, string
) != 0)
552 USAGE_ERROR ((0, 0, _("Conflicting compression options")));
554 use_compress_program_option
= string
;
560 printf ("tar (%s) %s\n%s\n", PACKAGE_NAME
, PACKAGE_VERSION
,
561 "Copyright (C) 2004 Free Software Foundation, Inc.\n");
562 puts (_("Based on the work of John Gilmore and Jay Fenlason. See AUTHORS\n\
563 for complete list of authors.\n"));
564 printf (_(" GNU tar is free software; you can redistribute it and/or modify\n"
565 " it under the terms of the GNU General Public License as published by\n"
566 " the Free Software Foundation; either version 2 of the License, or\n"
567 " (at your option) any later version.\n"
569 " GNU Mailutils is distributed in the hope that it will be useful,\n"
570 " but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
571 " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
572 " GNU General Public License for more details.\n"
574 " You should have received a copy of the GNU General Public License\n"
575 " along with GNU Mailutils; if not, write to the Free Software\n"
576 " Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\n\n"));
581 parse_opt(int key
, char *arg
, struct argp_state
*state
)
583 struct tar_args
*args
= state
->input
;
588 /* File name or non-parsed option, because of ARGP_IN_ORDER */
594 set_subcommand_option (CAT_SUBCOMMAND
);
600 if (! (xstrtoumax (arg
, 0, 10, &u
, "") == LONGINT_OK
601 && u
== (blocking_factor
= u
)
602 && 0 < blocking_factor
603 && u
== (record_size
= u
* BLOCKSIZE
) / BLOCKSIZE
))
604 USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (arg
),
605 _("Invalid blocking factor")));
610 /* Try to reblock input records. For reading 4.2BSD pipes. */
612 /* It would surely make sense to exchange -B and -R, but it seems
613 that -B has been used for a long while in Sun tar and most
614 BSD-derived systems. This is a consequence of the block/record
615 terminology confusion. */
617 read_full_records_option
= true;
621 set_subcommand_option (CREATE_SUBCOMMAND
);
630 set_subcommand_option (DIFF_SUBCOMMAND
);
634 if (archive_names
== allocated_archive_names
)
636 allocated_archive_names
*= 2;
638 xrealloc (archive_name_array
,
639 sizeof (const char *) * allocated_archive_names
);
641 archive_name_array
[archive_names
++] = arg
;
645 /* Since -F is only useful with -M, make it implied. Run this
646 script at the end of each tape. */
648 info_script_option
= arg
;
649 multi_volume_option
= true;
653 listed_incremental_option
= arg
;
654 after_date_option
= true;
658 /* We are making an incremental dump (FIXME: are we?); save
659 directories at the beginning of the archive, and include in each
660 directory its contents. */
662 incremental_option
= true;
666 /* Follow symbolic links. */
667 dereference_option
= true;
671 /* Ignore zero blocks (eofs). This can't be the default,
672 because Unix tar writes two blocks of zeros, then pads out
673 the record with garbage. */
675 ignore_zeros_option
= true;
680 _("Warning: the -I option is not supported;"
681 " perhaps you meant -j or -T?")));
685 set_use_compress_program_option ("bzip2");
689 /* Don't replace existing files. */
690 old_files_option
= KEEP_OLD_FILES
;
694 starting_file_option
= true;
699 /* When dumping directories, don't dump files/subdirectories
700 that are on other filesystems. */
702 one_file_system_option
= true;
708 if (xstrtoumax (arg
, 0, 10, &u
, "") != LONGINT_OK
)
709 USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (arg
),
710 _("Invalid tape length")));
711 tape_length_option
= 1024 * (tarlong
) u
;
712 multi_volume_option
= true;
721 /* Make multivolume archive: when we can't write any more into
722 the archive, re-open it, and continue writing. */
724 multi_volume_option
= true;
729 after_date_option
= true;
732 case NEWER_MTIME_OPTION
:
733 if (NEWER_OPTION_INITIALIZED (newer_mtime_option
))
734 USAGE_ERROR ((0, 0, _("More than one threshold date")));
736 if (FILESYSTEM_PREFIX_LEN (arg
) != 0
741 if (deref_stat (dereference_option
, arg
, &st
) != 0)
744 USAGE_ERROR ((0, 0, _("Date file not found")));
746 newer_mtime_option
.tv_sec
= st
.st_mtime
;
747 newer_mtime_option
.tv_nsec
= TIMESPEC_NS (st
.st_mtim
);
751 if (! get_date (&newer_mtime_option
, arg
, NULL
))
753 WARN ((0, 0, _("Substituting %s for unknown date format %s"),
754 tartime (newer_mtime_option
.tv_sec
), quote (arg
)));
755 newer_mtime_option
.tv_nsec
= 0;
758 args
->textual_date_option
= arg
;
762 #endif /* not MSDOS */
765 args
->o_option
= true;
769 to_stdout_option
= true;
773 same_permissions_option
= true;
777 absolute_names_option
= true;
781 set_subcommand_option (APPEND_SUBCOMMAND
);
785 /* Print block numbers for debugging bad tar archives. */
787 /* It would surely make sense to exchange -B and -R, but it seems
788 that -B has been used for a long while in Sun tar ans most
789 BSD-derived systems. This is a consequence of the block/record
790 terminology confusion. */
792 block_number_option
= true;
796 /* Names to extr are sorted. */
798 same_order_option
= true;
802 sparse_option
= true;
806 set_subcommand_option (LIST_SUBCOMMAND
);
811 files_from_option
= arg
;
815 set_subcommand_option (UPDATE_SUBCOMMAND
);
819 old_files_option
= UNLINK_FIRST_OLD_FILES
;
831 volume_label_option
= arg
;
835 interactive_option
= true;
839 verify_option
= true;
843 set_subcommand_option (EXTRACT_SUBCOMMAND
);
847 if (add_exclude_file (add_exclude
, excluded
, arg
,
848 args
->exclude_options
| recursion_option
, '\n')
852 FATAL_ERROR ((0, e
, "%s", quotearg_colon (arg
)));
858 _("Warning: the -y option is not supported;"
859 " perhaps you meant -j?")));
863 set_use_compress_program_option ("gzip");
867 set_use_compress_program_option ("compress");
870 case ANCHORED_OPTION
:
871 args
->exclude_options
|= EXCLUDE_ANCHORED
;
874 case ATIME_PRESERVE_OPTION
:
875 atime_preserve_option
= true;
878 case CHECKPOINT_OPTION
:
879 checkpoint_option
= true;
883 backup_option
= true;
885 args
->version_control_string
= arg
;
889 set_subcommand_option (DELETE_SUBCOMMAND
);
893 add_exclude (excluded
, arg
, args
->exclude_options
| recursion_option
);
896 case FORCE_LOCAL_OPTION
:
897 force_local_option
= true;
901 set_archive_format (arg
);
904 case INDEX_FILE_OPTION
:
905 index_file_name
= arg
;
908 case IGNORE_CASE_OPTION
:
909 args
->exclude_options
|= FNM_CASEFOLD
;
912 case IGNORE_FAILED_READ_OPTION
:
913 ignore_failed_read_option
= true;
916 case KEEP_NEWER_FILES_OPTION
:
917 old_files_option
= KEEP_NEWER_FILES
;
921 if (! (strlen (arg
) < GNAME_FIELD_SIZE
922 && gname_to_gid (arg
, &group_option
)))
925 if (xstrtoumax (arg
, 0, 10, &g
, "") == LONGINT_OK
929 FATAL_ERROR ((0, 0, "%s: %s", quotearg_colon (arg
),
930 _("%s: Invalid group")));
937 MODE_MASK_EQUALS
| MODE_MASK_PLUS
| MODE_MASK_MINUS
);
938 if (mode_option
== MODE_INVALID
)
939 FATAL_ERROR ((0, 0, _("Invalid mode given on option")));
940 if (mode_option
== MODE_MEMORY_EXHAUSTED
)
944 case NO_ANCHORED_OPTION
:
945 args
->exclude_options
&= ~ EXCLUDE_ANCHORED
;
948 case NO_IGNORE_CASE_OPTION
:
949 args
->exclude_options
&= ~ FNM_CASEFOLD
;
952 case NO_OVERWRITE_DIR_OPTION
:
953 old_files_option
= NO_OVERWRITE_DIR_OLD_FILES
;
956 case NO_WILDCARDS_OPTION
:
957 args
->exclude_options
&= ~ EXCLUDE_WILDCARDS
;
960 case NO_WILDCARDS_MATCH_SLASH_OPTION
:
961 args
->exclude_options
|= FNM_FILE_NAME
;
965 filename_terminator
= '\0';
968 case NUMERIC_OWNER_OPTION
:
969 numeric_owner_option
= true;
972 case OCCURRENCE_OPTION
:
974 occurrence_option
= 1;
978 if (xstrtoumax (arg
, 0, 10, &u
, "") == LONGINT_OK
)
979 occurrence_option
= u
;
981 FATAL_ERROR ((0, 0, "%s: %s", quotearg_colon (arg
),
982 _("Invalid number")));
986 case OVERWRITE_OPTION
:
987 old_files_option
= OVERWRITE_OLD_FILES
;
991 if (! (strlen (arg
) < UNAME_FIELD_SIZE
992 && uname_to_uid (arg
, &owner_option
)))
995 if (xstrtoumax (arg
, 0, 10, &u
, "") == LONGINT_OK
999 FATAL_ERROR ((0, 0, "%s: %s", quotearg_colon (arg
),
1000 _("Invalid owner")));
1006 xheader_set_option (arg
);
1010 set_archive_format ("posix");
1013 case PRESERVE_OPTION
:
1014 same_permissions_option
= true;
1015 same_order_option
= true;
1018 case RECORD_SIZE_OPTION
:
1021 if (! (xstrtoumax (arg
, 0, 10, &u
, "") == LONGINT_OK
1022 && u
== (size_t) u
))
1023 USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (arg
),
1024 _("Invalid record size")));
1026 if (record_size
% BLOCKSIZE
!= 0)
1027 USAGE_ERROR ((0, 0, _("Record size must be a multiple of %d."),
1029 blocking_factor
= record_size
/ BLOCKSIZE
;
1033 case RECURSIVE_UNLINK_OPTION
:
1034 recursive_unlink_option
= true;
1037 case REMOVE_FILES_OPTION
:
1038 remove_files_option
= true;
1041 case RMT_COMMAND_OPTION
:
1042 rmt_command_option
= arg
;
1045 case RSH_COMMAND_OPTION
:
1046 rsh_command_option
= arg
;
1049 case SHOW_DEFAULTS_OPTION
:
1050 show_default_settings (stdout
);
1053 case STRIP_COMPONENTS_OPTION
:
1056 if (! (xstrtoumax (arg
, 0, 10, &u
, "") == LONGINT_OK
1057 && u
== (size_t) u
))
1058 USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (arg
),
1059 _("Invalid number of elements")));
1060 strip_name_components
= u
;
1064 case SHOW_OMITTED_DIRS_OPTION
:
1065 show_omitted_dirs_option
= true;
1069 backup_option
= true;
1070 args
->backup_suffix_string
= arg
;
1074 totals_option
= true;
1077 case USE_COMPRESS_PROGRAM_OPTION
:
1078 set_use_compress_program_option (arg
);
1081 case VOLNO_FILE_OPTION
:
1082 volno_file_option
= arg
;
1085 case WILDCARDS_OPTION
:
1086 args
->exclude_options
|= EXCLUDE_WILDCARDS
;
1089 case WILDCARDS_MATCH_SLASH_OPTION
:
1090 args
->exclude_options
&= ~ FNM_FILE_NAME
;
1093 case CHECK_LINKS_OPTION
:
1094 check_links_option
= 1;
1097 case NO_RECURSION_OPTION
:
1098 recursion_option
= 0;
1101 case NO_SAME_OWNER_OPTION
:
1102 same_owner_option
= -1;
1105 case NO_SAME_PERMISSIONS_OPTION
:
1106 same_permissions_option
= -1;
1109 case RECURSION_OPTION
:
1110 recursion_option
= FNM_LEADING_DIR
;
1113 case SAME_OWNER_OPTION
:
1114 same_owner_option
= 1;
1126 #ifdef DEVICE_PREFIX
1128 int device
= key
- '0';
1130 static char buf
[sizeof DEVICE_PREFIX
+ 10];
1134 argp_error (state
, _("Malformed density argument: '%s'"), arg
);
1136 strcpy (buf
, DEVICE_PREFIX
);
1137 cursor
= buf
+ strlen (buf
);
1139 #ifdef DENSITY_LETTER
1141 sprintf (cursor
, "%d%c", device
, arg
[0]);
1143 #else /* not DENSITY_LETTER */
1170 argp_error (state
, _("Unknown density: '%c'"), arg
[0]);
1172 sprintf (cursor
, "%d", device
);
1174 #endif /* not DENSITY_LETTER */
1176 if (archive_names
== allocated_archive_names
)
1178 allocated_archive_names
*= 2;
1179 archive_name_array
=
1180 xrealloc (archive_name_array
,
1181 sizeof (const char *) * allocated_archive_names
);
1183 archive_name_array
[archive_names
++] = strdup (buf
);
1187 #else /* not DEVICE_PREFIX */
1190 _("Options `-[0-7][lmh]' not supported by *this* tar"));
1192 #endif /* not DEVICE_PREFIX */
1195 state
->flags
|= ARGP_NO_EXIT
;
1196 argp_state_help (state
, state
->out_stream
,
1197 ARGP_HELP_STD_HELP
& ~ARGP_HELP_BUG_ADDR
);
1198 fprintf (state
->out_stream
, _("\n*This* tar defaults to:\n"));
1199 show_default_settings (state
->out_stream
);
1200 fprintf (state
->out_stream
, "\n");
1201 fprintf (state
->out_stream
, _("Report bugs to %s.\n"),
1202 argp_program_bug_address
);
1206 argp_state_help (state
, state
->out_stream
,
1207 ARGP_HELP_USAGE
| ARGP_HELP_EXIT_OK
);
1210 case VERSION_OPTION
:
1211 fprintf (state
->out_stream
, "%s\n", argp_program_version
);
1214 case LICENSE_OPTION
:
1219 return ARGP_ERR_UNKNOWN
;
1224 static struct argp argp
= {
1237 argp_help (&argp
, stderr
, ARGP_HELP_SEE
, program_name
);
1241 /* Parse the options for tar. */
1243 static struct argp_option
*
1244 find_argp_option (struct argp_option
*options
, int letter
)
1247 !(options
->name
== NULL
1248 && options
->key
== 0
1249 && options
->arg
== 0
1251 && options
->doc
== NULL
); options
++)
1252 if (options
->key
== letter
)
1259 Available option letters are DEHIJQY and aenqy. Some are reserved:
1261 e exit immediately with a nonzero exit status if unexpected errors occur
1262 E use extended headers (draft POSIX headers, that is)
1263 I same as T (for compatibility with Solaris tar)
1264 n the archive is quickly seekable, so don't worry about random seeks
1265 q stop after extracting the first occurrence of the named file
1266 y per-file gzip compression
1267 Y per-block gzip compression */
1270 decode_options (int argc
, char **argv
)
1272 int optchar
; /* option letter */
1274 struct tar_args args
;
1276 /* Set some default option values. */
1277 args
.textual_date_option
= NULL
;
1278 args
.exclude_options
= EXCLUDE_WILDCARDS
;
1280 args
.pax_option
= 0;
1281 args
.backup_suffix_string
= getenv ("SIMPLE_BACKUP_SUFFIX");
1282 args
.version_control_string
= 0;
1283 args
.input_files
= 0;
1286 subcommand_option
= UNKNOWN_SUBCOMMAND
;
1287 archive_format
= DEFAULT_FORMAT
;
1288 blocking_factor
= DEFAULT_BLOCKING
;
1289 record_size
= DEFAULT_BLOCKING
* BLOCKSIZE
;
1290 excluded
= new_exclude ();
1291 newer_mtime_option
.tv_sec
= TYPE_MINIMUM (time_t);
1292 newer_mtime_option
.tv_nsec
= -1;
1293 recursion_option
= FNM_LEADING_DIR
;
1298 /* Convert old-style tar call by exploding option element and rearranging
1299 options accordingly. */
1301 if (argc
> 1 && argv
[1][0] != '-')
1303 int new_argc
; /* argc value for rearranged arguments */
1304 char **new_argv
; /* argv value for rearranged arguments */
1305 char *const *in
; /* cursor into original argv */
1306 char **out
; /* cursor into rearranged argv */
1307 const char *letter
; /* cursor into old option letters */
1308 char buffer
[3]; /* constructed option buffer */
1310 /* Initialize a constructed option. */
1315 /* Allocate a new argument array, and copy program name in it. */
1317 new_argc
= argc
- 1 + strlen (argv
[1]);
1318 new_argv
= xmalloc ((new_argc
+ 1) * sizeof (char *));
1323 /* Copy each old letter option as a separate option, and have the
1324 corresponding argument moved next to it. */
1326 for (letter
= *in
++; *letter
; letter
++)
1328 struct argp_option
*opt
;
1330 buffer
[1] = *letter
;
1331 *out
++ = xstrdup (buffer
);
1332 opt
= find_argp_option (options
, *letter
);
1333 if (opt
&& opt
->arg
)
1335 if (in
< argv
+ argc
)
1338 USAGE_ERROR ((0, 0, _("Old option `%c' requires an argument."),
1343 /* Copy all remaining options. */
1345 while (in
< argv
+ argc
)
1349 /* Replace the old option list by the new one. */
1355 /* Parse all options and non-options as they appear. */
1357 prepend_default_options (getenv ("TAR_OPTIONS"), &argc
, &argv
);
1359 if (argp_parse (&argp
, argc
, argv
, ARGP_IN_ORDER
|ARGP_NO_HELP
,
1361 exit (1); /* FIXME */
1364 /* Special handling for 'o' option:
1366 GNU tar used to say "output old format".
1367 UNIX98 tar says don't chown files after extracting (we use
1368 "--no-same-owner" for this).
1370 The old GNU tar semantics is retained when used with --create
1371 option, otherwise UNIX98 semantics is assumed */
1375 if (subcommand_option
== CREATE_SUBCOMMAND
)
1377 /* GNU Tar <= 1.13 compatibility */
1378 set_archive_format ("v7");
1382 /* UNIX98 compatibility */
1383 same_owner_option
= 1;
1387 /* Handle operands after any "--" argument. */
1388 for (; index
< argc
; index
++)
1390 name_add (argv
[index
]);
1394 /* Derive option values and check option consistency. */
1396 if (archive_format
== DEFAULT_FORMAT
)
1398 if (args
.pax_option
)
1399 archive_format
= POSIX_FORMAT
;
1401 archive_format
= DEFAULT_ARCHIVE_FORMAT
;
1404 if (volume_label_option
&& subcommand_option
== CREATE_SUBCOMMAND
)
1405 assert_format (FORMAT_MASK (OLDGNU_FORMAT
)
1406 | FORMAT_MASK (GNU_FORMAT
));
1409 if (incremental_option
|| multi_volume_option
)
1410 assert_format (FORMAT_MASK (OLDGNU_FORMAT
) | FORMAT_MASK (GNU_FORMAT
));
1413 assert_format (FORMAT_MASK (OLDGNU_FORMAT
)
1414 | FORMAT_MASK (GNU_FORMAT
)
1415 | FORMAT_MASK (POSIX_FORMAT
));
1417 if (occurrence_option
)
1419 if (!args
.input_files
&& !files_from_option
)
1421 _("--occurrence is meaningless without a file list")));
1422 if (subcommand_option
!= DELETE_SUBCOMMAND
1423 && subcommand_option
!= DIFF_SUBCOMMAND
1424 && subcommand_option
!= EXTRACT_SUBCOMMAND
1425 && subcommand_option
!= LIST_SUBCOMMAND
)
1427 _("--occurrence cannot be used in the requested operation mode")));
1430 if (archive_names
== 0)
1432 /* If no archive file name given, try TAPE from the environment, or
1433 else, DEFAULT_ARCHIVE from the configuration process. */
1436 archive_name_array
[0] = getenv ("TAPE");
1437 if (! archive_name_array
[0])
1438 archive_name_array
[0] = DEFAULT_ARCHIVE
;
1441 /* Allow multiple archives only with `-M'. */
1443 if (archive_names
> 1 && !multi_volume_option
)
1445 _("Multiple archive files require `-M' option")));
1447 if (listed_incremental_option
1448 && NEWER_OPTION_INITIALIZED (newer_mtime_option
))
1450 _("Cannot combine --listed-incremental with --newer")));
1452 if (volume_label_option
)
1454 size_t volume_label_max_len
=
1455 (sizeof current_header
->header
.name
1456 - 1 /* for trailing '\0' */
1457 - (multi_volume_option
1458 ? (sizeof " Volume "
1459 - 1 /* for null at end of " Volume " */
1460 + INT_STRLEN_BOUND (int) /* for volume number */
1461 - 1 /* for sign, as 0 <= volno */)
1463 if (volume_label_max_len
< strlen (volume_label_option
))
1465 ngettext ("%s: Volume label is too long (limit is %lu byte)",
1466 "%s: Volume label is too long (limit is %lu bytes)",
1467 volume_label_max_len
),
1468 quotearg_colon (volume_label_option
),
1469 (unsigned long) volume_label_max_len
));
1474 if (multi_volume_option
)
1475 USAGE_ERROR ((0, 0, _("Cannot verify multi-volume archives")));
1476 if (use_compress_program_option
)
1477 USAGE_ERROR ((0, 0, _("Cannot verify compressed archives")));
1480 if (use_compress_program_option
)
1482 if (multi_volume_option
)
1483 USAGE_ERROR ((0, 0, _("Cannot use multi-volume compressed archives")));
1484 if (subcommand_option
== UPDATE_SUBCOMMAND
)
1485 USAGE_ERROR ((0, 0, _("Cannot update compressed archives")));
1488 /* It is no harm to use --pax-option on non-pax archives in archive
1489 reading mode. It may even be useful, since it allows to override
1490 file attributes from tar headers. Therefore I allow such usage.
1493 && archive_format
!= POSIX_FORMAT
1494 && (subcommand_option
!= EXTRACT_SUBCOMMAND
1495 || subcommand_option
!= DIFF_SUBCOMMAND
1496 || subcommand_option
!= LIST_SUBCOMMAND
))
1497 USAGE_ERROR ((0, 0, _("--pax-option can be used only on POSIX archives")));
1499 /* If ready to unlink hierarchies, so we are for simpler files. */
1500 if (recursive_unlink_option
)
1501 old_files_option
= UNLINK_FIRST_OLD_FILES
;
1506 if (!rmt_command_option
)
1507 rmt_command_option
= DEFAULT_RMT_COMMAND
;
1509 /* Forbid using -c with no input files whatsoever. Check that `-f -',
1510 explicit or implied, is used correctly. */
1512 switch (subcommand_option
)
1514 case CREATE_SUBCOMMAND
:
1515 if (args
.input_files
== 0 && !files_from_option
)
1517 _("Cowardly refusing to create an empty archive")));
1520 case EXTRACT_SUBCOMMAND
:
1521 case LIST_SUBCOMMAND
:
1522 case DIFF_SUBCOMMAND
:
1523 for (archive_name_cursor
= archive_name_array
;
1524 archive_name_cursor
< archive_name_array
+ archive_names
;
1525 archive_name_cursor
++)
1526 if (!strcmp (*archive_name_cursor
, "-"))
1527 request_stdin ("-f");
1530 case CAT_SUBCOMMAND
:
1531 case UPDATE_SUBCOMMAND
:
1532 case APPEND_SUBCOMMAND
:
1533 for (archive_name_cursor
= archive_name_array
;
1534 archive_name_cursor
< archive_name_array
+ archive_names
;
1535 archive_name_cursor
++)
1536 if (!strcmp (*archive_name_cursor
, "-"))
1538 _("Options `-Aru' are incompatible with `-f -'")));
1544 archive_name_cursor
= archive_name_array
;
1546 /* Prepare for generating backup names. */
1548 if (args
.backup_suffix_string
)
1549 simple_backup_suffix
= xstrdup (args
.backup_suffix_string
);
1552 backup_type
= xget_version ("--backup", args
.version_control_string
);
1554 if (verbose_option
&& args
.textual_date_option
)
1556 /* FIXME: tartime should support nanoseconds, too, so that this
1557 comparison doesn't complain about lost nanoseconds. */
1558 char const *treated_as
= tartime (newer_mtime_option
.tv_sec
);
1559 if (strcmp (args
.textual_date_option
, treated_as
) != 0)
1561 ngettext ("Treating date `%s' as %s + %ld nanosecond",
1562 "Treating date `%s' as %s + %ld nanoseconds",
1563 newer_mtime_option
.tv_nsec
),
1564 args
.textual_date_option
, treated_as
,
1565 newer_mtime_option
.tv_nsec
));
1572 /* Main routine for tar. */
1574 main (int argc
, char **argv
)
1576 #if HAVE_CLOCK_GETTIME
1577 if (clock_gettime (CLOCK_REALTIME
, &start_timespec
) != 0)
1579 start_time
= time (0);
1580 program_name
= argv
[0];
1581 setlocale (LC_ALL
, "");
1582 bindtextdomain (PACKAGE
, LOCALEDIR
);
1583 textdomain (PACKAGE
);
1585 exit_status
= TAREXIT_SUCCESS
;
1586 filename_terminator
= '\n';
1587 set_quoting_style (0, escape_quoting_style
);
1589 /* Pre-allocate a few structures. */
1591 allocated_archive_names
= 10;
1592 archive_name_array
=
1593 xmalloc (sizeof (const char *) * allocated_archive_names
);
1597 /* System V fork+wait does not work if SIGCHLD is ignored. */
1598 signal (SIGCHLD
, SIG_DFL
);
1603 /* Decode options. */
1605 decode_options (argc
, argv
);
1608 /* Main command execution. */
1610 if (volno_file_option
)
1611 init_volume_number ();
1613 switch (subcommand_option
)
1615 case UNKNOWN_SUBCOMMAND
:
1617 _("You must specify one of the `-Acdtrux' options")));
1619 case CAT_SUBCOMMAND
:
1620 case UPDATE_SUBCOMMAND
:
1621 case APPEND_SUBCOMMAND
:
1625 case DELETE_SUBCOMMAND
:
1626 delete_archive_members ();
1629 case CREATE_SUBCOMMAND
:
1634 print_total_written ();
1637 case EXTRACT_SUBCOMMAND
:
1639 read_and (extract_archive
);
1641 /* FIXME: should extract_finish () even if an ordinary signal is
1647 case LIST_SUBCOMMAND
:
1648 read_and (list_archive
);
1651 case DIFF_SUBCOMMAND
:
1653 read_and (diff_archive
);
1657 if (check_links_option
)
1660 if (volno_file_option
)
1661 closeout_volume_number ();
1663 /* Dispose of allocated memory, and return. */
1665 free (archive_name_array
);
1668 if (stdlis
!= stderr
&& (ferror (stdlis
) || fclose (stdlis
) != 0))
1669 FATAL_ERROR ((0, 0, _("Error in writing to standard output")));
1670 if (exit_status
== TAREXIT_FAILURE
)
1671 error (0, 0, _("Error exit delayed from previous errors"));
1672 if (ferror (stderr
) || fclose (stderr
) != 0)
1673 exit_status
= TAREXIT_FAILURE
;
1678 tar_stat_init (struct tar_stat_info
*st
)
1680 memset (st
, 0, sizeof (*st
));
1684 tar_stat_destroy (struct tar_stat_info
*st
)
1686 free (st
->orig_file_name
);
1687 free (st
->file_name
);
1688 free (st
->link_name
);
1691 free (st
->sparse_map
);
1692 memset (st
, 0, sizeof (*st
));