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
,
191 IGNORE_FAILED_READ_OPTION
,
193 KEEP_NEWER_FILES_OPTION
,
198 NO_IGNORE_CASE_OPTION
,
199 NO_OVERWRITE_DIR_OPTION
,
201 NO_SAME_OWNER_OPTION
,
202 NO_SAME_PERMISSIONS_OPTION
,
204 NO_WILDCARDS_MATCH_SLASH_OPTION
,
206 NUMERIC_OWNER_OPTION
,
216 RECURSIVE_UNLINK_OPTION
,
221 SHOW_DEFAULTS_OPTION
,
222 SHOW_OMITTED_DIRS_OPTION
,
223 STRIP_COMPONENTS_OPTION
,
227 USE_COMPRESS_PROGRAM_OPTION
,
232 WILDCARDS_MATCH_SLASH_OPTION
235 const char *argp_program_version
= "tar (" PACKAGE
") " VERSION
;
236 const char *argp_program_bug_address
= "<" PACKAGE_BUGREPORT
">";
237 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\
240 tar -cf archive.tar foo bar # Create archive.tar from files foo and bar.\n\
241 tar -tvf archive.tar # List all files in archive.tar verbosely.\n\
242 tar -xf archive.tar # Extract all files from archive.tar.\n\
243 \vThe backup suffix is `~', unless set with --suffix or SIMPLE_BACKUP_SUFFIX.\n\
244 The version control may be set with --backup or VERSION_CONTROL, values are:\n\n\
245 t, numbered make numbered backups\n\
246 nil, existing numbered if numbered backups exist, simple otherwise\n\
247 never, simple always make simple backups\n");
252 Available option letters are DEIJQY and aenqy. Consider the following
255 [For Solaris tar compatibility]
256 e exit immediately with a nonzero exit status if unexpected errors occur
257 E use extended headers (--format=posix)
258 [q alias for --occurrence=1 =/= this would better be used for quiet?]
259 n the archive is quickly seekable, so don't worry about random seeks
260 [I same as T =/= will harm star compatibility]
262 y per-file gzip compression
263 Y per-block gzip compression */
265 static struct argp_option options
[] = {
267 N_("Main operation mode:"), 0},
270 N_("list the contents of an archive"), 10 },
271 {"extract", 'x', 0, 0,
272 N_("extract files from an archive"), 10 },
273 {"get", 0, 0, OPTION_ALIAS
, NULL
},
274 {"create", 'c', 0, 0,
275 N_("create a new archive"), 10 },
277 N_("find differences between archive and file system"), 10 },
278 {"compare", 0, 0, OPTION_ALIAS
, NULL
, 10},
279 {"append", 'r', 0, 0,
280 N_("append files to the end of an archive"), 10 },
281 {"update", 'u', 0, 0,
282 N_("only append files newer than copy in archive"), 10 },
283 {"catenate", 'A', 0, 0,
284 N_("append tar files to an archive"), 10 },
285 {"concatenate", 0, 0, OPTION_ALIAS
, NULL
, 10},
286 {"delete", DELETE_OPTION
, 0, 0,
287 N_("delete from the archive (not on mag tapes!)"), 10 },
290 N_("Operation modifiers:"), 20},
292 {"verify", 'W', 0, 0,
293 N_("attempt to verify the archive after writing it"), 21 },
294 {"remove-files", REMOVE_FILES_OPTION
, 0, 0,
295 N_("remove files after adding them to the archive"), 21 },
296 {"keep-old-files", 'k', 0, 0,
297 N_("don't replace existing files when extracting"), 21 },
298 {"keep-newer-files", KEEP_NEWER_FILES_OPTION
, 0, 0,
299 N_("don't replace existing files that are newer than their archive copies"), 21 },
300 {"no-overwrite-dir", NO_OVERWRITE_DIR_OPTION
, 0, 0,
301 N_("preserve metadata of existing directories"), 21 },
302 {"overwrite", OVERWRITE_OPTION
, 0, 0,
303 N_("overwrite existing files when extracting"), 21 },
304 {"unlink-first", 'U', 0, 0,
305 N_("remove each file prior to extracting over it"), 21 },
306 {"recursive-unlink", RECURSIVE_UNLINK_OPTION
, 0, 0,
307 N_("empty hierarchies prior to extracting directory"), 21 },
308 {"sparse", 'S', 0, 0,
309 N_("handle sparse files efficiently"), 21 },
310 {"to-stdout", 'O', 0, 0,
311 N_("extract files to standard output"), 21 },
312 {"incremental", 'G', 0, 0,
313 N_("handle old GNU-format incremental backup"), 21 },
314 {"listed-incremental", 'g', N_("FILE"), 0,
315 N_("handle new GNU-format incremental backup"), 21 },
316 {"ignore-failed-read", IGNORE_FAILED_READ_OPTION
, 0, 0,
317 N_("do not exit with nonzero on unreadable files"), 21 },
318 {"occurrence", OCCURRENCE_OPTION
, N_("NUMBER"), OPTION_ARG_OPTIONAL
,
319 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 },
322 N_("Handling of file attributes:"), 30 },
324 {"owner", OWNER_OPTION
, N_("NAME"), 0,
325 N_("force NAME as owner for added files"), 31 },
326 {"group", GROUP_OPTION
, N_("NAME"), 0,
327 N_("force NAME as group for added files"), 31 },
328 {"mode", MODE_OPTION
, N_("CHANGES"), 0,
329 N_("force (symbolic) mode CHANGES for added files"), 31 },
330 {"atime-preserve", ATIME_PRESERVE_OPTION
, 0, 0,
331 N_("don't change access times on dumped files"), 31 },
333 N_("don't extract file modified time"), 31 },
334 {"same-owner", SAME_OWNER_OPTION
, 0, 0,
335 N_("try extracting files with the same ownership"), 31 },
336 {"no-same-owner", NO_SAME_OWNER_OPTION
, 0, 0,
337 N_("extract files as yourself"), 31 },
338 {"numeric-owner", NUMERIC_OWNER_OPTION
, 0, 0,
339 N_("always use numbers for user/group names"), 31 },
340 {"preserve-permissions", 'p', 0, 0,
341 N_("extract permissions information"), 31 },
342 {"same-permissions", 0, 0, OPTION_ALIAS
, NULL
, 31 },
343 {"no-same-permissions", NO_SAME_PERMISSIONS_OPTION
, 0, 0,
344 N_("do not extract permissions information"), 31 },
345 {"preserve-order", 's', 0, 0,
346 N_("sort names to extract to match archive"), 31 },
347 {"same-order", 0, 0, OPTION_ALIAS
, NULL
, 31 },
348 {"preserve", PRESERVE_OPTION
, 0, 0,
349 N_("same as both -p and -s"), 31 },
352 N_("Device selection and switching:"), 40 },
354 {"file", 'f', N_("ARCHIVE"), 0,
355 N_("use archive file or device ARCHIVE"), 41 },
356 {"force-local", FORCE_LOCAL_OPTION
, 0, 0,
357 N_("archive file is local even if has a colon"), 41 },
358 {"rmt-command", RMT_COMMAND_OPTION
, N_("COMMAND"), 0,
359 N_("use given rmt COMMAND instead of rmt"), 41 },
360 {"rsh-command", RSH_COMMAND_OPTION
, N_("COMMAND"), 0,
361 N_("use remote COMMAND instead of rsh"), 41 },
363 {"-[0-7][lmh]", 0, NULL
, OPTION_DOC
,
364 N_("specify drive and density"), 41 },
366 {NULL
, '0', NULL
, OPTION_HIDDEN
, NULL
, 41 },
367 {NULL
, '1', NULL
, OPTION_HIDDEN
, NULL
, 41 },
368 {NULL
, '2', NULL
, OPTION_HIDDEN
, NULL
, 41 },
369 {NULL
, '3', NULL
, OPTION_HIDDEN
, NULL
, 41 },
370 {NULL
, '4', NULL
, OPTION_HIDDEN
, NULL
, 41 },
371 {NULL
, '5', NULL
, OPTION_HIDDEN
, NULL
, 41 },
372 {NULL
, '6', NULL
, OPTION_HIDDEN
, NULL
, 41 },
373 {NULL
, '7', NULL
, OPTION_HIDDEN
, NULL
, 41 },
374 {NULL
, '8', NULL
, OPTION_HIDDEN
, NULL
, 41 },
375 {NULL
, '9', NULL
, OPTION_HIDDEN
, NULL
, 41 },
377 {"multi-volume", 'M', 0, 0,
378 N_("create/list/extract multi-volume archive"), 41 },
379 {"tape-length", 'L', N_("NUMBER"), 0,
380 N_("change tape after writing NUMBER x 1024 bytes"), 41 },
381 {"info-script", 'F', N_("NAME"), 0,
382 N_("run script at end of each tape (implies -M)"), 41 },
383 {"new-volume-script", 0, 0, OPTION_ALIAS
, NULL
, 41 },
384 {"volno-file", VOLNO_FILE_OPTION
, N_("FILE"), 0,
385 N_("use/update the volume number in FILE"), 41 },
388 N_("Device blocking:"), 50 },
390 {"blocking-factor", 'b', N_("BLOCKS"), 0,
391 N_("BLOCKS x 512 bytes per record"), 51 },
392 {"record-size", RECORD_SIZE_OPTION
, N_("NUMBER"), 0,
393 N_("SIZE bytes per record, multiple of 512"), 51 },
394 {"ignore-zeros", 'i', 0, 0,
395 N_("ignore zeroed blocks in archive (means EOF)"), 51 },
396 {"read-full-records", 'B', 0, 0,
397 N_("reblock as we read (for 4.2BSD pipes)"), 51 },
400 N_("Archive format selection:"), 60 },
402 {"format", 'H', N_("FORMAT"), 0,
403 N_("create archive of the given format."), 61 },
405 {"", 0, NULL
, OPTION_DOC
, N_("FORMAT is one of the following:"), 62},
406 {"", 0, NULL
, OPTION_DOC
, N_("v7 old V7 tar format"), 63},
407 {"", 0, NULL
, OPTION_DOC
, N_("oldgnu GNU format as per tar <= 1.12"), 63},
408 {"", 0, NULL
, OPTION_DOC
, N_("gnu GNU tar 1.13.x format"), 63},
409 {"", 0, NULL
, OPTION_DOC
, N_("ustar POSIX 1003.1-1988 (ustar) format"), 63 },
410 {"", 0, NULL
, OPTION_DOC
, N_("posix POSIX 1003.1-2001 (pax) format"), 63 },
412 {"old-archive", OLD_ARCHIVE_OPTION
, 0, 0, /* FIXME */
413 N_("same as --format=v7"), 68 },
414 {"portability", 0, 0, OPTION_ALIAS
, NULL
, 68 },
415 {"posix", POSIX_OPTION
, 0, 0,
416 N_("same as --format=posix"), 68 },
417 {"pax-option", PAX_OPTION
, N_("keyword[[:]=value][,keyword[[:]=value], ...]"), 0,
418 N_("control pax keywords"), 68 },
419 {"label", 'V', N_("TEXT"), 0,
420 N_("create archive with volume name NAME. At list/extract time, use TEXT as a globbing pattern"), 68 },
422 N_("filter the archive through bzip2"), 68 },
424 N_("filter the archive through gzip"), 68 },
425 {"gunzip", 0, 0, OPTION_ALIAS
, NULL
, 68 },
426 {"ungzip", 0, 0, OPTION_ALIAS
, NULL
, 68 },
427 {"compress", 'Z', 0, 0,
428 N_("filter the archive through compress"), 68 },
429 {"uncompress", 0, 0, OPTION_ALIAS
, NULL
, 68 },
430 {"use-compress-program", USE_COMPRESS_PROGRAM_OPTION
, N_("PROG"), 0,
431 N_("filter through PROG (must accept -d)"), 68 },
434 N_("Local file selection:"), 70 },
436 {"directory", 'C', N_("DIR"), 0,
437 N_("change to directory DIR"), 71 },
438 {"files-from", 'T', N_("FILE-OF-NAMES"), 0,
439 N_("get names to extract or create from file NAME"), 71 },
440 {"null", NULL_OPTION
, 0, 0,
441 N_("-T reads null-terminated names, disable -C"), 71 },
442 {"exclude", EXCLUDE_OPTION
, N_("PATTERN"), 0,
443 N_("exclude files, given as a PATTERN"), 71 },
444 {"exclude-from", 'X', N_("FILE"), 0,
445 N_("exclude patterns listed in FILE"), 71 },
446 {"ignore-case", IGNORE_CASE_OPTION
, 0, 0,
447 N_("exclusion ignores case"), 71 },
448 {"anchored", ANCHORED_OPTION
, 0, 0,
449 N_("exclude patterns match file name start (default)"), 71 },
450 {"no-anchored", NO_ANCHORED_OPTION
, 0, 0,
451 N_("exclude patterns match after any /"), 71 },
452 {"no-ignore-case", NO_IGNORE_CASE_OPTION
, 0, 0,
453 N_("exclusion is case sensitive (default)"), 71 },
454 {"no-wildcards", NO_WILDCARDS_OPTION
, 0, 0,
455 N_("exclude patterns are plain strings"), 71 },
456 {"no-wildcards-match-slash", NO_WILDCARDS_MATCH_SLASH_OPTION
, 0, 0,
457 N_("exclude pattern wildcards do not match '/'"), 71 },
458 {"no-recursion", NO_RECURSION_OPTION
, 0, 0,
459 N_("avoid descending automatically in directories"), 71 },
460 {"one-file-system", 'l', 0, 0, /* FIXME: emit warning */
461 N_("stay in local file system when creating archive"), 71 },
462 {"recursion", RECURSION_OPTION
, 0, 0,
463 N_("recurse into directories (default)"), 71 },
464 {"absolute-names", 'P', 0, 0,
465 N_("don't strip leading `/'s from file names"), 71 },
466 {"dereference", 'h', 0, 0,
467 N_("dump instead the files symlinks point to"), 71 },
468 {"starting-file", 'K', N_("MEMBER-NAME"), 0,
469 N_("begin at member MEMBER-NAME in the archive"), 71 },
470 {"strip-components", STRIP_COMPONENTS_OPTION
, N_("NUMBER"), 0,
471 N_("strip NUMBER leading components from file names"), 71 },
472 {"newer", 'N', N_("DATE-OR-FILE"), 0,
473 N_("only store files newer than DATE-OR-FILE"), 71 },
474 {"newer-mtime", NEWER_MTIME_OPTION
, N_("DATE"), 0,
475 N_("compare date and time when data changed only"), 71 },
476 {"after-date", 'N', N_("DATE"), 0,
477 N_("same as -N"), 71 },
478 {"backup", BACKUP_OPTION
, N_("CONTROL"), OPTION_ARG_OPTIONAL
,
479 N_("backup before removal, choose version CONTROL"), 71 },
480 {"suffix", SUFFIX_OPTION
, N_("STRING"), 0,
481 N_("backup before removal, override usual suffix ('~' unless overridden by environment variable SIMPLE_BACKUP_SUFFIX"), 71 },
482 {"wildcards", WILDCARDS_OPTION
, 0, 0,
483 N_("exclude patterns use wildcards (default)"), 71 },
484 {"wildcards-match-slash", WILDCARDS_MATCH_SLASH_OPTION
, 0, 0,
485 N_("exclude pattern wildcards match '/' (default)"), 71 },
488 N_("Informative output:"), 80 },
490 {"verbose", 'v', 0, 0,
491 N_("verbosely list files processed"), 81 },
492 {"checkpoint", CHECKPOINT_OPTION
, 0, 0,
493 N_("print directory names while reading the archive"), 81 },
494 {"check-links", CHECK_LINKS_OPTION
, 0, 0,
495 N_("print a message if not all links are dumped"), 82 },
496 {"totals", TOTALS_OPTION
, 0, 0,
497 N_("print total bytes written while creating archive"), 82 },
498 {"utc", UTC_OPTION
, 0, 0,
499 N_("print file modification dates in UTC"), 82 },
500 {"index-file", INDEX_FILE_OPTION
, N_("FILE"), 0,
501 N_("send verbose output to FILE"), 82 },
502 {"block-number", 'R', 0, 0,
503 N_("show block number within archive with each message"), 82 },
504 {"interactive", 'w', 0, 0,
505 N_("ask for confirmation for every action"), 82 },
506 {"confirmation", 0, 0, OPTION_ALIAS
, NULL
, 82 },
507 {"show-defaults", SHOW_DEFAULTS_OPTION
, 0, 0,
508 N_("Show tar defaults"), 82 },
509 {"show-omitted-dirs", SHOW_OMITTED_DIRS_OPTION
, 0, 0,
510 N_("When listing or extracting, list each directory that does not match search criteria"), 82 },
513 N_("Compatibility options:"), 90 },
516 N_("when creating, same as --old-archive. When extracting, same as --no-same-owner"), 91 },
519 N_("Other options:"), 100 },
521 {"help", '?', 0, 0, N_("Give this help list"), -1},
522 {"usage", USAGE_OPTION
, 0, 0, N_("Give a short usage message"), -1},
523 {"license", LICENSE_OPTION
, 0, 0, N_("Print license and exit"), -1},
524 {"version", VERSION_OPTION
, 0, 0, N_("Print program version"), -1},
525 /* FIXME -V (--label) conflicts with the default short option for
532 char const *textual_date_option
;
536 char const *backup_suffix_string
;
537 char const *version_control_string
;
542 show_default_settings (FILE *stream
)
545 "--format=%s -f%s -b%d --rmt-command=%s --rsh-command=%s\n",
546 archive_format_string (DEFAULT_ARCHIVE_FORMAT
),
547 DEFAULT_ARCHIVE
, DEFAULT_BLOCKING
,
548 DEFAULT_RMT_COMMAND
, REMOTE_SHELL
);
552 set_subcommand_option (enum subcommand subcommand
)
554 if (subcommand_option
!= UNKNOWN_SUBCOMMAND
555 && subcommand_option
!= subcommand
)
557 _("You may not specify more than one `-Acdtrux' option")));
559 subcommand_option
= subcommand
;
563 set_use_compress_program_option (const char *string
)
565 if (use_compress_program_option
566 && strcmp (use_compress_program_option
, string
) != 0)
567 USAGE_ERROR ((0, 0, _("Conflicting compression options")));
569 use_compress_program_option
= string
;
575 printf ("tar (%s) %s\n%s\n", PACKAGE_NAME
, PACKAGE_VERSION
,
576 "Copyright (C) 2004 Free Software Foundation, Inc.\n");
577 puts (_("Based on the work of John Gilmore and Jay Fenlason. See AUTHORS\n\
578 for complete list of authors.\n"));
579 printf (_(" GNU tar is free software; you can redistribute it and/or modify\n"
580 " it under the terms of the GNU General Public License as published by\n"
581 " the Free Software Foundation; either version 2 of the License, or\n"
582 " (at your option) any later version.\n"
584 " GNU Mailutils is distributed in the hope that it will be useful,\n"
585 " but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
586 " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
587 " GNU General Public License for more details.\n"
589 " You should have received a copy of the GNU General Public License\n"
590 " along with GNU Mailutils; if not, write to the Free Software\n"
591 " Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\n\n"));
596 parse_opt(int key
, char *arg
, struct argp_state
*state
)
598 struct tar_args
*args
= state
->input
;
603 /* File name or non-parsed option, because of ARGP_IN_ORDER */
609 set_subcommand_option (CAT_SUBCOMMAND
);
615 if (! (xstrtoumax (arg
, 0, 10, &u
, "") == LONGINT_OK
616 && u
== (blocking_factor
= u
)
617 && 0 < blocking_factor
618 && u
== (record_size
= u
* BLOCKSIZE
) / BLOCKSIZE
))
619 USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (arg
),
620 _("Invalid blocking factor")));
625 /* Try to reblock input records. For reading 4.2BSD pipes. */
627 /* It would surely make sense to exchange -B and -R, but it seems
628 that -B has been used for a long while in Sun tar and most
629 BSD-derived systems. This is a consequence of the block/record
630 terminology confusion. */
632 read_full_records_option
= true;
636 set_subcommand_option (CREATE_SUBCOMMAND
);
645 set_subcommand_option (DIFF_SUBCOMMAND
);
649 if (archive_names
== allocated_archive_names
)
651 allocated_archive_names
*= 2;
653 xrealloc (archive_name_array
,
654 sizeof (const char *) * allocated_archive_names
);
656 archive_name_array
[archive_names
++] = arg
;
660 /* Since -F is only useful with -M, make it implied. Run this
661 script at the end of each tape. */
663 info_script_option
= arg
;
664 multi_volume_option
= true;
668 listed_incremental_option
= arg
;
669 after_date_option
= true;
673 /* We are making an incremental dump (FIXME: are we?); save
674 directories at the beginning of the archive, and include in each
675 directory its contents. */
677 incremental_option
= true;
681 /* Follow symbolic links. */
682 dereference_option
= true;
686 /* Ignore zero blocks (eofs). This can't be the default,
687 because Unix tar writes two blocks of zeros, then pads out
688 the record with garbage. */
690 ignore_zeros_option
= true;
695 _("Warning: the -I option is not supported;"
696 " perhaps you meant -j or -T?")));
700 set_use_compress_program_option ("bzip2");
704 /* Don't replace existing files. */
705 old_files_option
= KEEP_OLD_FILES
;
709 starting_file_option
= true;
714 /* When dumping directories, don't dump files/subdirectories
715 that are on other filesystems. */
717 one_file_system_option
= true;
723 if (xstrtoumax (arg
, 0, 10, &u
, "") != LONGINT_OK
)
724 USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (arg
),
725 _("Invalid tape length")));
726 tape_length_option
= 1024 * (tarlong
) u
;
727 multi_volume_option
= true;
736 /* Make multivolume archive: when we can't write any more into
737 the archive, re-open it, and continue writing. */
739 multi_volume_option
= true;
744 after_date_option
= true;
747 case NEWER_MTIME_OPTION
:
748 if (NEWER_OPTION_INITIALIZED (newer_mtime_option
))
749 USAGE_ERROR ((0, 0, _("More than one threshold date")));
751 if (FILESYSTEM_PREFIX_LEN (arg
) != 0
756 if (deref_stat (dereference_option
, arg
, &st
) != 0)
759 USAGE_ERROR ((0, 0, _("Date file not found")));
761 newer_mtime_option
.tv_sec
= st
.st_mtime
;
762 newer_mtime_option
.tv_nsec
= TIMESPEC_NS (st
.st_mtim
);
766 if (! get_date (&newer_mtime_option
, arg
, NULL
))
768 WARN ((0, 0, _("Substituting %s for unknown date format %s"),
769 tartime (newer_mtime_option
.tv_sec
), quote (arg
)));
770 newer_mtime_option
.tv_nsec
= 0;
773 args
->textual_date_option
= arg
;
777 #endif /* not MSDOS */
780 args
->o_option
= true;
784 to_stdout_option
= true;
788 same_permissions_option
= true;
792 absolute_names_option
= true;
796 set_subcommand_option (APPEND_SUBCOMMAND
);
800 /* Print block numbers for debugging bad tar archives. */
802 /* It would surely make sense to exchange -B and -R, but it seems
803 that -B has been used for a long while in Sun tar ans most
804 BSD-derived systems. This is a consequence of the block/record
805 terminology confusion. */
807 block_number_option
= true;
811 /* Names to extr are sorted. */
813 same_order_option
= true;
817 sparse_option
= true;
821 set_subcommand_option (LIST_SUBCOMMAND
);
826 files_from_option
= arg
;
830 set_subcommand_option (UPDATE_SUBCOMMAND
);
834 old_files_option
= UNLINK_FIRST_OLD_FILES
;
846 volume_label_option
= arg
;
850 interactive_option
= true;
854 verify_option
= true;
858 set_subcommand_option (EXTRACT_SUBCOMMAND
);
862 if (add_exclude_file (add_exclude
, excluded
, arg
,
863 args
->exclude_options
| recursion_option
, '\n')
867 FATAL_ERROR ((0, e
, "%s", quotearg_colon (arg
)));
873 _("Warning: the -y option is not supported;"
874 " perhaps you meant -j?")));
878 set_use_compress_program_option ("gzip");
882 set_use_compress_program_option ("compress");
885 case ANCHORED_OPTION
:
886 args
->exclude_options
|= EXCLUDE_ANCHORED
;
889 case ATIME_PRESERVE_OPTION
:
890 atime_preserve_option
= true;
893 case CHECKPOINT_OPTION
:
894 checkpoint_option
= true;
898 backup_option
= true;
900 args
->version_control_string
= arg
;
904 set_subcommand_option (DELETE_SUBCOMMAND
);
908 add_exclude (excluded
, arg
, args
->exclude_options
| recursion_option
);
911 case FORCE_LOCAL_OPTION
:
912 force_local_option
= true;
916 set_archive_format (arg
);
919 case INDEX_FILE_OPTION
:
920 index_file_name
= arg
;
923 case IGNORE_CASE_OPTION
:
924 args
->exclude_options
|= FNM_CASEFOLD
;
927 case IGNORE_FAILED_READ_OPTION
:
928 ignore_failed_read_option
= true;
931 case KEEP_NEWER_FILES_OPTION
:
932 old_files_option
= KEEP_NEWER_FILES
;
936 if (! (strlen (arg
) < GNAME_FIELD_SIZE
937 && gname_to_gid (arg
, &group_option
)))
940 if (xstrtoumax (arg
, 0, 10, &g
, "") == LONGINT_OK
944 FATAL_ERROR ((0, 0, "%s: %s", quotearg_colon (arg
),
945 _("%s: Invalid group")));
952 MODE_MASK_EQUALS
| MODE_MASK_PLUS
| MODE_MASK_MINUS
);
953 if (mode_option
== MODE_INVALID
)
954 FATAL_ERROR ((0, 0, _("Invalid mode given on option")));
955 if (mode_option
== MODE_MEMORY_EXHAUSTED
)
959 case NO_ANCHORED_OPTION
:
960 args
->exclude_options
&= ~ EXCLUDE_ANCHORED
;
963 case NO_IGNORE_CASE_OPTION
:
964 args
->exclude_options
&= ~ FNM_CASEFOLD
;
967 case NO_OVERWRITE_DIR_OPTION
:
968 old_files_option
= NO_OVERWRITE_DIR_OLD_FILES
;
971 case NO_WILDCARDS_OPTION
:
972 args
->exclude_options
&= ~ EXCLUDE_WILDCARDS
;
975 case NO_WILDCARDS_MATCH_SLASH_OPTION
:
976 args
->exclude_options
|= FNM_FILE_NAME
;
980 filename_terminator
= '\0';
983 case NUMERIC_OWNER_OPTION
:
984 numeric_owner_option
= true;
987 case OCCURRENCE_OPTION
:
989 occurrence_option
= 1;
993 if (xstrtoumax (arg
, 0, 10, &u
, "") == LONGINT_OK
)
994 occurrence_option
= u
;
996 FATAL_ERROR ((0, 0, "%s: %s", quotearg_colon (arg
),
997 _("Invalid number")));
1001 case OVERWRITE_OPTION
:
1002 old_files_option
= OVERWRITE_OLD_FILES
;
1006 if (! (strlen (arg
) < UNAME_FIELD_SIZE
1007 && uname_to_uid (arg
, &owner_option
)))
1010 if (xstrtoumax (arg
, 0, 10, &u
, "") == LONGINT_OK
1014 FATAL_ERROR ((0, 0, "%s: %s", quotearg_colon (arg
),
1015 _("Invalid owner")));
1021 xheader_set_option (arg
);
1025 set_archive_format ("posix");
1028 case PRESERVE_OPTION
:
1029 same_permissions_option
= true;
1030 same_order_option
= true;
1033 case RECORD_SIZE_OPTION
:
1036 if (! (xstrtoumax (arg
, 0, 10, &u
, "") == LONGINT_OK
1037 && u
== (size_t) u
))
1038 USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (arg
),
1039 _("Invalid record size")));
1041 if (record_size
% BLOCKSIZE
!= 0)
1042 USAGE_ERROR ((0, 0, _("Record size must be a multiple of %d."),
1044 blocking_factor
= record_size
/ BLOCKSIZE
;
1048 case RECURSIVE_UNLINK_OPTION
:
1049 recursive_unlink_option
= true;
1052 case REMOVE_FILES_OPTION
:
1053 remove_files_option
= true;
1056 case RMT_COMMAND_OPTION
:
1057 rmt_command_option
= arg
;
1060 case RSH_COMMAND_OPTION
:
1061 rsh_command_option
= arg
;
1064 case SHOW_DEFAULTS_OPTION
:
1065 show_default_settings (stdout
);
1068 case STRIP_COMPONENTS_OPTION
:
1071 if (! (xstrtoumax (arg
, 0, 10, &u
, "") == LONGINT_OK
1072 && u
== (size_t) u
))
1073 USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (arg
),
1074 _("Invalid number of elements")));
1075 strip_name_components
= u
;
1079 case SHOW_OMITTED_DIRS_OPTION
:
1080 show_omitted_dirs_option
= true;
1084 backup_option
= true;
1085 args
->backup_suffix_string
= arg
;
1089 totals_option
= true;
1092 case USE_COMPRESS_PROGRAM_OPTION
:
1093 set_use_compress_program_option (arg
);
1096 case VOLNO_FILE_OPTION
:
1097 volno_file_option
= arg
;
1100 case WILDCARDS_OPTION
:
1101 args
->exclude_options
|= EXCLUDE_WILDCARDS
;
1104 case WILDCARDS_MATCH_SLASH_OPTION
:
1105 args
->exclude_options
&= ~ FNM_FILE_NAME
;
1108 case CHECK_LINKS_OPTION
:
1109 check_links_option
= 1;
1112 case NO_RECURSION_OPTION
:
1113 recursion_option
= 0;
1116 case NO_SAME_OWNER_OPTION
:
1117 same_owner_option
= -1;
1120 case NO_SAME_PERMISSIONS_OPTION
:
1121 same_permissions_option
= -1;
1124 case RECURSION_OPTION
:
1125 recursion_option
= FNM_LEADING_DIR
;
1128 case SAME_OWNER_OPTION
:
1129 same_owner_option
= 1;
1141 #ifdef DEVICE_PREFIX
1143 int device
= key
- '0';
1145 static char buf
[sizeof DEVICE_PREFIX
+ 10];
1149 argp_error (state
, _("Malformed density argument: '%s'"), arg
);
1151 strcpy (buf
, DEVICE_PREFIX
);
1152 cursor
= buf
+ strlen (buf
);
1154 #ifdef DENSITY_LETTER
1156 sprintf (cursor
, "%d%c", device
, arg
[0]);
1158 #else /* not DENSITY_LETTER */
1185 argp_error (state
, _("Unknown density: '%c'"), arg
[0]);
1187 sprintf (cursor
, "%d", device
);
1189 #endif /* not DENSITY_LETTER */
1191 if (archive_names
== allocated_archive_names
)
1193 allocated_archive_names
*= 2;
1194 archive_name_array
=
1195 xrealloc (archive_name_array
,
1196 sizeof (const char *) * allocated_archive_names
);
1198 archive_name_array
[archive_names
++] = strdup (buf
);
1202 #else /* not DEVICE_PREFIX */
1205 _("Options `-[0-7][lmh]' not supported by *this* tar"));
1207 #endif /* not DEVICE_PREFIX */
1210 state
->flags
|= ARGP_NO_EXIT
;
1211 argp_state_help (state
, state
->out_stream
,
1212 ARGP_HELP_STD_HELP
& ~ARGP_HELP_BUG_ADDR
);
1213 fprintf (state
->out_stream
, _("\n*This* tar defaults to:\n"));
1214 show_default_settings (state
->out_stream
);
1215 fprintf (state
->out_stream
, "\n");
1216 fprintf (state
->out_stream
, _("Report bugs to %s.\n"),
1217 argp_program_bug_address
);
1221 argp_state_help (state
, state
->out_stream
,
1222 ARGP_HELP_USAGE
| ARGP_HELP_EXIT_OK
);
1225 case VERSION_OPTION
:
1226 fprintf (state
->out_stream
, "%s\n", argp_program_version
);
1229 case LICENSE_OPTION
:
1234 return ARGP_ERR_UNKNOWN
;
1239 static struct argp argp
= {
1252 argp_help (&argp
, stderr
, ARGP_HELP_SEE
, program_name
);
1256 /* Parse the options for tar. */
1258 static struct argp_option
*
1259 find_argp_option (struct argp_option
*options
, int letter
)
1262 !(options
->name
== NULL
1263 && options
->key
== 0
1264 && options
->arg
== 0
1266 && options
->doc
== NULL
); options
++)
1267 if (options
->key
== letter
)
1273 decode_options (int argc
, char **argv
)
1275 int optchar
; /* option letter */
1277 struct tar_args args
;
1279 /* Set some default option values. */
1280 args
.textual_date_option
= NULL
;
1281 args
.exclude_options
= EXCLUDE_WILDCARDS
;
1283 args
.pax_option
= 0;
1284 args
.backup_suffix_string
= getenv ("SIMPLE_BACKUP_SUFFIX");
1285 args
.version_control_string
= 0;
1286 args
.input_files
= 0;
1289 subcommand_option
= UNKNOWN_SUBCOMMAND
;
1290 archive_format
= DEFAULT_FORMAT
;
1291 blocking_factor
= DEFAULT_BLOCKING
;
1292 record_size
= DEFAULT_BLOCKING
* BLOCKSIZE
;
1293 excluded
= new_exclude ();
1294 newer_mtime_option
.tv_sec
= TYPE_MINIMUM (time_t);
1295 newer_mtime_option
.tv_nsec
= -1;
1296 recursion_option
= FNM_LEADING_DIR
;
1301 /* Convert old-style tar call by exploding option element and rearranging
1302 options accordingly. */
1304 if (argc
> 1 && argv
[1][0] != '-')
1306 int new_argc
; /* argc value for rearranged arguments */
1307 char **new_argv
; /* argv value for rearranged arguments */
1308 char *const *in
; /* cursor into original argv */
1309 char **out
; /* cursor into rearranged argv */
1310 const char *letter
; /* cursor into old option letters */
1311 char buffer
[3]; /* constructed option buffer */
1313 /* Initialize a constructed option. */
1318 /* Allocate a new argument array, and copy program name in it. */
1320 new_argc
= argc
- 1 + strlen (argv
[1]);
1321 new_argv
= xmalloc ((new_argc
+ 1) * sizeof (char *));
1326 /* Copy each old letter option as a separate option, and have the
1327 corresponding argument moved next to it. */
1329 for (letter
= *in
++; *letter
; letter
++)
1331 struct argp_option
*opt
;
1333 buffer
[1] = *letter
;
1334 *out
++ = xstrdup (buffer
);
1335 opt
= find_argp_option (options
, *letter
);
1336 if (opt
&& opt
->arg
)
1338 if (in
< argv
+ argc
)
1341 USAGE_ERROR ((0, 0, _("Old option `%c' requires an argument."),
1346 /* Copy all remaining options. */
1348 while (in
< argv
+ argc
)
1352 /* Replace the old option list by the new one. */
1358 /* Parse all options and non-options as they appear. */
1360 prepend_default_options (getenv ("TAR_OPTIONS"), &argc
, &argv
);
1362 if (argp_parse (&argp
, argc
, argv
, ARGP_IN_ORDER
|ARGP_NO_HELP
,
1364 exit (1); /* FIXME */
1367 /* Special handling for 'o' option:
1369 GNU tar used to say "output old format".
1370 UNIX98 tar says don't chown files after extracting (we use
1371 "--no-same-owner" for this).
1373 The old GNU tar semantics is retained when used with --create
1374 option, otherwise UNIX98 semantics is assumed */
1378 if (subcommand_option
== CREATE_SUBCOMMAND
)
1380 /* GNU Tar <= 1.13 compatibility */
1381 set_archive_format ("v7");
1385 /* UNIX98 compatibility */
1386 same_owner_option
= 1;
1390 /* Handle operands after any "--" argument. */
1391 for (; index
< argc
; index
++)
1393 name_add (argv
[index
]);
1397 /* Derive option values and check option consistency. */
1399 if (archive_format
== DEFAULT_FORMAT
)
1401 if (args
.pax_option
)
1402 archive_format
= POSIX_FORMAT
;
1404 archive_format
= DEFAULT_ARCHIVE_FORMAT
;
1407 if (volume_label_option
&& subcommand_option
== CREATE_SUBCOMMAND
)
1408 assert_format (FORMAT_MASK (OLDGNU_FORMAT
)
1409 | FORMAT_MASK (GNU_FORMAT
));
1412 if (incremental_option
|| multi_volume_option
)
1413 assert_format (FORMAT_MASK (OLDGNU_FORMAT
) | FORMAT_MASK (GNU_FORMAT
));
1416 assert_format (FORMAT_MASK (OLDGNU_FORMAT
)
1417 | FORMAT_MASK (GNU_FORMAT
)
1418 | FORMAT_MASK (POSIX_FORMAT
));
1420 if (occurrence_option
)
1422 if (!args
.input_files
&& !files_from_option
)
1424 _("--occurrence is meaningless without a file list")));
1425 if (subcommand_option
!= DELETE_SUBCOMMAND
1426 && subcommand_option
!= DIFF_SUBCOMMAND
1427 && subcommand_option
!= EXTRACT_SUBCOMMAND
1428 && subcommand_option
!= LIST_SUBCOMMAND
)
1430 _("--occurrence cannot be used in the requested operation mode")));
1433 if (archive_names
== 0)
1435 /* If no archive file name given, try TAPE from the environment, or
1436 else, DEFAULT_ARCHIVE from the configuration process. */
1439 archive_name_array
[0] = getenv ("TAPE");
1440 if (! archive_name_array
[0])
1441 archive_name_array
[0] = DEFAULT_ARCHIVE
;
1444 /* Allow multiple archives only with `-M'. */
1446 if (archive_names
> 1 && !multi_volume_option
)
1448 _("Multiple archive files require `-M' option")));
1450 if (listed_incremental_option
1451 && NEWER_OPTION_INITIALIZED (newer_mtime_option
))
1453 _("Cannot combine --listed-incremental with --newer")));
1455 if (volume_label_option
)
1457 size_t volume_label_max_len
=
1458 (sizeof current_header
->header
.name
1459 - 1 /* for trailing '\0' */
1460 - (multi_volume_option
1461 ? (sizeof " Volume "
1462 - 1 /* for null at end of " Volume " */
1463 + INT_STRLEN_BOUND (int) /* for volume number */
1464 - 1 /* for sign, as 0 <= volno */)
1466 if (volume_label_max_len
< strlen (volume_label_option
))
1468 ngettext ("%s: Volume label is too long (limit is %lu byte)",
1469 "%s: Volume label is too long (limit is %lu bytes)",
1470 volume_label_max_len
),
1471 quotearg_colon (volume_label_option
),
1472 (unsigned long) volume_label_max_len
));
1477 if (multi_volume_option
)
1478 USAGE_ERROR ((0, 0, _("Cannot verify multi-volume archives")));
1479 if (use_compress_program_option
)
1480 USAGE_ERROR ((0, 0, _("Cannot verify compressed archives")));
1483 if (use_compress_program_option
)
1485 if (multi_volume_option
)
1486 USAGE_ERROR ((0, 0, _("Cannot use multi-volume compressed archives")));
1487 if (subcommand_option
== UPDATE_SUBCOMMAND
)
1488 USAGE_ERROR ((0, 0, _("Cannot update compressed archives")));
1491 /* It is no harm to use --pax-option on non-pax archives in archive
1492 reading mode. It may even be useful, since it allows to override
1493 file attributes from tar headers. Therefore I allow such usage.
1496 && archive_format
!= POSIX_FORMAT
1497 && (subcommand_option
!= EXTRACT_SUBCOMMAND
1498 || subcommand_option
!= DIFF_SUBCOMMAND
1499 || subcommand_option
!= LIST_SUBCOMMAND
))
1500 USAGE_ERROR ((0, 0, _("--pax-option can be used only on POSIX archives")));
1502 /* If ready to unlink hierarchies, so we are for simpler files. */
1503 if (recursive_unlink_option
)
1504 old_files_option
= UNLINK_FIRST_OLD_FILES
;
1509 if (!rmt_command_option
)
1510 rmt_command_option
= DEFAULT_RMT_COMMAND
;
1512 /* Forbid using -c with no input files whatsoever. Check that `-f -',
1513 explicit or implied, is used correctly. */
1515 switch (subcommand_option
)
1517 case CREATE_SUBCOMMAND
:
1518 if (args
.input_files
== 0 && !files_from_option
)
1520 _("Cowardly refusing to create an empty archive")));
1523 case EXTRACT_SUBCOMMAND
:
1524 case LIST_SUBCOMMAND
:
1525 case DIFF_SUBCOMMAND
:
1526 for (archive_name_cursor
= archive_name_array
;
1527 archive_name_cursor
< archive_name_array
+ archive_names
;
1528 archive_name_cursor
++)
1529 if (!strcmp (*archive_name_cursor
, "-"))
1530 request_stdin ("-f");
1533 case CAT_SUBCOMMAND
:
1534 case UPDATE_SUBCOMMAND
:
1535 case APPEND_SUBCOMMAND
:
1536 for (archive_name_cursor
= archive_name_array
;
1537 archive_name_cursor
< archive_name_array
+ archive_names
;
1538 archive_name_cursor
++)
1539 if (!strcmp (*archive_name_cursor
, "-"))
1541 _("Options `-Aru' are incompatible with `-f -'")));
1547 archive_name_cursor
= archive_name_array
;
1549 /* Prepare for generating backup names. */
1551 if (args
.backup_suffix_string
)
1552 simple_backup_suffix
= xstrdup (args
.backup_suffix_string
);
1555 backup_type
= xget_version ("--backup", args
.version_control_string
);
1557 if (verbose_option
&& args
.textual_date_option
)
1559 /* FIXME: tartime should support nanoseconds, too, so that this
1560 comparison doesn't complain about lost nanoseconds. */
1561 char const *treated_as
= tartime (newer_mtime_option
.tv_sec
);
1562 if (strcmp (args
.textual_date_option
, treated_as
) != 0)
1564 ngettext ("Treating date `%s' as %s + %ld nanosecond",
1565 "Treating date `%s' as %s + %ld nanoseconds",
1566 newer_mtime_option
.tv_nsec
),
1567 args
.textual_date_option
, treated_as
,
1568 newer_mtime_option
.tv_nsec
));
1575 /* Main routine for tar. */
1577 main (int argc
, char **argv
)
1579 #if HAVE_CLOCK_GETTIME
1580 if (clock_gettime (CLOCK_REALTIME
, &start_timespec
) != 0)
1582 start_time
= time (0);
1583 program_name
= argv
[0];
1584 setlocale (LC_ALL
, "");
1585 bindtextdomain (PACKAGE
, LOCALEDIR
);
1586 textdomain (PACKAGE
);
1588 exit_status
= TAREXIT_SUCCESS
;
1589 filename_terminator
= '\n';
1590 set_quoting_style (0, escape_quoting_style
);
1592 /* Pre-allocate a few structures. */
1594 allocated_archive_names
= 10;
1595 archive_name_array
=
1596 xmalloc (sizeof (const char *) * allocated_archive_names
);
1600 /* System V fork+wait does not work if SIGCHLD is ignored. */
1601 signal (SIGCHLD
, SIG_DFL
);
1606 /* Decode options. */
1608 decode_options (argc
, argv
);
1611 /* Main command execution. */
1613 if (volno_file_option
)
1614 init_volume_number ();
1616 switch (subcommand_option
)
1618 case UNKNOWN_SUBCOMMAND
:
1620 _("You must specify one of the `-Acdtrux' options")));
1622 case CAT_SUBCOMMAND
:
1623 case UPDATE_SUBCOMMAND
:
1624 case APPEND_SUBCOMMAND
:
1628 case DELETE_SUBCOMMAND
:
1629 delete_archive_members ();
1632 case CREATE_SUBCOMMAND
:
1637 print_total_written ();
1640 case EXTRACT_SUBCOMMAND
:
1642 read_and (extract_archive
);
1644 /* FIXME: should extract_finish () even if an ordinary signal is
1650 case LIST_SUBCOMMAND
:
1651 read_and (list_archive
);
1654 case DIFF_SUBCOMMAND
:
1656 read_and (diff_archive
);
1660 if (check_links_option
)
1663 if (volno_file_option
)
1664 closeout_volume_number ();
1666 /* Dispose of allocated memory, and return. */
1668 free (archive_name_array
);
1671 if (stdlis
!= stderr
&& (ferror (stdlis
) || fclose (stdlis
) != 0))
1672 FATAL_ERROR ((0, 0, _("Error in writing to standard output")));
1673 if (exit_status
== TAREXIT_FAILURE
)
1674 error (0, 0, _("Error exit delayed from previous errors"));
1675 if (ferror (stderr
) || fclose (stderr
) != 0)
1676 exit_status
= TAREXIT_FAILURE
;
1681 tar_stat_init (struct tar_stat_info
*st
)
1683 memset (st
, 0, sizeof (*st
));
1687 tar_stat_destroy (struct tar_stat_info
*st
)
1689 free (st
->orig_file_name
);
1690 free (st
->file_name
);
1691 free (st
->link_name
);
1694 free (st
->sparse_map
);
1695 memset (st
, 0, sizeof (*st
));