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
},
131 { "pax", POSIX_FORMAT
}, /* An alias for posix */
136 set_archive_format (char const *name
)
138 struct fmttab
const *p
;
140 for (p
= fmttab
; strcmp (p
->name
, name
) != 0; )
142 USAGE_ERROR ((0, 0, _("%s: Invalid archive format"),
143 quotearg_colon (name
)));
145 archive_format
= p
->fmt
;
149 archive_format_string (enum archive_format fmt
)
151 struct fmttab
const *p
;
153 for (p
= fmttab
; p
->name
; p
++)
159 #define FORMAT_MASK(n) (1<<(n))
162 assert_format(unsigned fmt_mask
)
164 if ((FORMAT_MASK(archive_format
) & fmt_mask
) == 0)
166 _("GNU features wanted on incompatible archive format")));
173 /* For long options that unconditionally set a single flag, we have getopt
174 do it. For the others, we share the code for the equivalent short
175 named option, the name of which is stored in the otherwise-unused `val'
176 field of the `struct option'; for long options that have no equivalent
177 short option, we use non-characters as pseudo short options,
178 starting at CHAR_MAX + 1 and going upwards. */
182 ANCHORED_OPTION
= CHAR_MAX
+ 1,
183 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");
253 Available option letters are DEIJQY and aeqy. Consider the following
256 [For Solaris tar compatibility]
257 e exit immediately with a nonzero exit status if unexpected errors occur
258 E use extended headers (--format=posix)
259 [q alias for --occurrence=1 =/= this would better be used for quiet?]
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 },
320 {"seek", 'n', NULL
, 0,
321 N_("Archive is seekable"), 21 },
324 N_("Handling of file attributes:"), 30 },
326 {"owner", OWNER_OPTION
, N_("NAME"), 0,
327 N_("force NAME as owner for added files"), 31 },
328 {"group", GROUP_OPTION
, N_("NAME"), 0,
329 N_("force NAME as group for added files"), 31 },
330 {"mode", MODE_OPTION
, N_("CHANGES"), 0,
331 N_("force (symbolic) mode CHANGES for added files"), 31 },
332 {"atime-preserve", ATIME_PRESERVE_OPTION
, 0, 0,
333 N_("don't change access times on dumped files"), 31 },
335 N_("don't extract file modified time"), 31 },
336 {"same-owner", SAME_OWNER_OPTION
, 0, 0,
337 N_("try extracting files with the same ownership"), 31 },
338 {"no-same-owner", NO_SAME_OWNER_OPTION
, 0, 0,
339 N_("extract files as yourself"), 31 },
340 {"numeric-owner", NUMERIC_OWNER_OPTION
, 0, 0,
341 N_("always use numbers for user/group names"), 31 },
342 {"preserve-permissions", 'p', 0, 0,
343 N_("extract permissions information"), 31 },
344 {"same-permissions", 0, 0, OPTION_ALIAS
, NULL
, 31 },
345 {"no-same-permissions", NO_SAME_PERMISSIONS_OPTION
, 0, 0,
346 N_("do not extract permissions information"), 31 },
347 {"preserve-order", 's', 0, 0,
348 N_("sort names to extract to match archive"), 31 },
349 {"same-order", 0, 0, OPTION_ALIAS
, NULL
, 31 },
350 {"preserve", PRESERVE_OPTION
, 0, 0,
351 N_("same as both -p and -s"), 31 },
354 N_("Device selection and switching:"), 40 },
356 {"file", 'f', N_("ARCHIVE"), 0,
357 N_("use archive file or device ARCHIVE"), 41 },
358 {"force-local", FORCE_LOCAL_OPTION
, 0, 0,
359 N_("archive file is local even if has a colon"), 41 },
360 {"rmt-command", RMT_COMMAND_OPTION
, N_("COMMAND"), 0,
361 N_("use given rmt COMMAND instead of rmt"), 41 },
362 {"rsh-command", RSH_COMMAND_OPTION
, N_("COMMAND"), 0,
363 N_("use remote COMMAND instead of rsh"), 41 },
365 {"-[0-7][lmh]", 0, NULL
, OPTION_DOC
,
366 N_("specify drive and density"), 41 },
368 {NULL
, '0', NULL
, OPTION_HIDDEN
, NULL
, 41 },
369 {NULL
, '1', NULL
, OPTION_HIDDEN
, NULL
, 41 },
370 {NULL
, '2', NULL
, OPTION_HIDDEN
, NULL
, 41 },
371 {NULL
, '3', NULL
, OPTION_HIDDEN
, NULL
, 41 },
372 {NULL
, '4', NULL
, OPTION_HIDDEN
, NULL
, 41 },
373 {NULL
, '5', NULL
, OPTION_HIDDEN
, NULL
, 41 },
374 {NULL
, '6', NULL
, OPTION_HIDDEN
, NULL
, 41 },
375 {NULL
, '7', NULL
, OPTION_HIDDEN
, NULL
, 41 },
376 {NULL
, '8', NULL
, OPTION_HIDDEN
, NULL
, 41 },
377 {NULL
, '9', NULL
, OPTION_HIDDEN
, NULL
, 41 },
379 {"multi-volume", 'M', 0, 0,
380 N_("create/list/extract multi-volume archive"), 41 },
381 {"tape-length", 'L', N_("NUMBER"), 0,
382 N_("change tape after writing NUMBER x 1024 bytes"), 41 },
383 {"info-script", 'F', N_("NAME"), 0,
384 N_("run script at end of each tape (implies -M)"), 41 },
385 {"new-volume-script", 0, 0, OPTION_ALIAS
, NULL
, 41 },
386 {"volno-file", VOLNO_FILE_OPTION
, N_("FILE"), 0,
387 N_("use/update the volume number in FILE"), 41 },
390 N_("Device blocking:"), 50 },
392 {"blocking-factor", 'b', N_("BLOCKS"), 0,
393 N_("BLOCKS x 512 bytes per record"), 51 },
394 {"record-size", RECORD_SIZE_OPTION
, N_("NUMBER"), 0,
395 N_("SIZE bytes per record, multiple of 512"), 51 },
396 {"ignore-zeros", 'i', 0, 0,
397 N_("ignore zeroed blocks in archive (means EOF)"), 51 },
398 {"read-full-records", 'B', 0, 0,
399 N_("reblock as we read (for 4.2BSD pipes)"), 51 },
402 N_("Archive format selection:"), 60 },
404 {"format", 'H', N_("FORMAT"), 0,
405 N_("create archive of the given format."), 61 },
407 {"", 0, NULL
, OPTION_DOC
, N_("FORMAT is one of the following:"), 62},
408 {"", 0, NULL
, OPTION_DOC
, N_("v7 old V7 tar format"), 63},
409 {"", 0, NULL
, OPTION_DOC
, N_("oldgnu GNU format as per tar <= 1.12"), 63},
410 {"", 0, NULL
, OPTION_DOC
, N_("gnu GNU tar 1.13.x format"), 63},
411 {"", 0, NULL
, OPTION_DOC
, N_("ustar POSIX 1003.1-1988 (ustar) format"), 63 },
412 {"", 0, NULL
, OPTION_DOC
, N_("posix POSIX 1003.1-2001 (pax) format"), 63 },
414 {"old-archive", OLD_ARCHIVE_OPTION
, 0, 0, /* FIXME */
415 N_("same as --format=v7"), 68 },
416 {"portability", 0, 0, OPTION_ALIAS
, NULL
, 68 },
417 {"posix", POSIX_OPTION
, 0, 0,
418 N_("same as --format=posix"), 68 },
419 {"pax-option", PAX_OPTION
, N_("keyword[[:]=value][,keyword[[:]=value], ...]"), 0,
420 N_("control pax keywords"), 68 },
421 {"label", 'V', N_("TEXT"), 0,
422 N_("create archive with volume name NAME. At list/extract time, use TEXT as a globbing pattern"), 68 },
424 N_("filter the archive through bzip2"), 68 },
426 N_("filter the archive through gzip"), 68 },
427 {"gunzip", 0, 0, OPTION_ALIAS
, NULL
, 68 },
428 {"ungzip", 0, 0, OPTION_ALIAS
, NULL
, 68 },
429 {"compress", 'Z', 0, 0,
430 N_("filter the archive through compress"), 68 },
431 {"uncompress", 0, 0, OPTION_ALIAS
, NULL
, 68 },
432 {"use-compress-program", USE_COMPRESS_PROGRAM_OPTION
, N_("PROG"), 0,
433 N_("filter through PROG (must accept -d)"), 68 },
436 N_("Local file selection:"), 70 },
438 {"directory", 'C', N_("DIR"), 0,
439 N_("change to directory DIR"), 71 },
440 {"files-from", 'T', N_("FILE-OF-NAMES"), 0,
441 N_("get names to extract or create from file NAME"), 71 },
442 {"null", NULL_OPTION
, 0, 0,
443 N_("-T reads null-terminated names, disable -C"), 71 },
444 {"exclude", EXCLUDE_OPTION
, N_("PATTERN"), 0,
445 N_("exclude files, given as a PATTERN"), 71 },
446 {"exclude-from", 'X', N_("FILE"), 0,
447 N_("exclude patterns listed in FILE"), 71 },
448 {"ignore-case", IGNORE_CASE_OPTION
, 0, 0,
449 N_("exclusion ignores case"), 71 },
450 {"anchored", ANCHORED_OPTION
, 0, 0,
451 N_("exclude patterns match file name start (default)"), 71 },
452 {"no-anchored", NO_ANCHORED_OPTION
, 0, 0,
453 N_("exclude patterns match after any /"), 71 },
454 {"no-ignore-case", NO_IGNORE_CASE_OPTION
, 0, 0,
455 N_("exclusion is case sensitive (default)"), 71 },
456 {"no-wildcards", NO_WILDCARDS_OPTION
, 0, 0,
457 N_("exclude patterns are plain strings"), 71 },
458 {"no-wildcards-match-slash", NO_WILDCARDS_MATCH_SLASH_OPTION
, 0, 0,
459 N_("exclude pattern wildcards do not match '/'"), 71 },
460 {"no-recursion", NO_RECURSION_OPTION
, 0, 0,
461 N_("avoid descending automatically in directories"), 71 },
462 {"one-file-system", 'l', 0, 0, /* FIXME: emit warning */
463 N_("stay in local file system when creating archive"), 71 },
464 {"recursion", RECURSION_OPTION
, 0, 0,
465 N_("recurse into directories (default)"), 71 },
466 {"absolute-names", 'P', 0, 0,
467 N_("don't strip leading `/'s from file names"), 71 },
468 {"dereference", 'h', 0, 0,
469 N_("dump instead the files symlinks point to"), 71 },
470 {"starting-file", 'K', N_("MEMBER-NAME"), 0,
471 N_("begin at member MEMBER-NAME in the archive"), 71 },
472 {"strip-components", STRIP_COMPONENTS_OPTION
, N_("NUMBER"), 0,
473 N_("strip NUMBER leading components from file names"), 71 },
474 {"newer", 'N', N_("DATE-OR-FILE"), 0,
475 N_("only store files newer than DATE-OR-FILE"), 71 },
476 {"newer-mtime", NEWER_MTIME_OPTION
, N_("DATE"), 0,
477 N_("compare date and time when data changed only"), 71 },
478 {"after-date", 'N', N_("DATE"), 0,
479 N_("same as -N"), 71 },
480 {"backup", BACKUP_OPTION
, N_("CONTROL"), OPTION_ARG_OPTIONAL
,
481 N_("backup before removal, choose version CONTROL"), 71 },
482 {"suffix", SUFFIX_OPTION
, N_("STRING"), 0,
483 N_("backup before removal, override usual suffix ('~' unless overridden by environment variable SIMPLE_BACKUP_SUFFIX"), 71 },
484 {"wildcards", WILDCARDS_OPTION
, 0, 0,
485 N_("exclude patterns use wildcards (default)"), 71 },
486 {"wildcards-match-slash", WILDCARDS_MATCH_SLASH_OPTION
, 0, 0,
487 N_("exclude pattern wildcards match '/' (default)"), 71 },
490 N_("Informative output:"), 80 },
492 {"verbose", 'v', 0, 0,
493 N_("verbosely list files processed"), 81 },
494 {"checkpoint", CHECKPOINT_OPTION
, 0, 0,
495 N_("display progress messages every 10th record"), 81 },
496 {"check-links", CHECK_LINKS_OPTION
, 0, 0,
497 N_("print a message if not all links are dumped"), 82 },
498 {"totals", TOTALS_OPTION
, 0, 0,
499 N_("print total bytes written while creating archive"), 82 },
500 {"utc", UTC_OPTION
, 0, 0,
501 N_("print file modification dates in UTC"), 82 },
502 {"index-file", INDEX_FILE_OPTION
, N_("FILE"), 0,
503 N_("send verbose output to FILE"), 82 },
504 {"block-number", 'R', 0, 0,
505 N_("show block number within archive with each message"), 82 },
506 {"interactive", 'w', 0, 0,
507 N_("ask for confirmation for every action"), 82 },
508 {"confirmation", 0, 0, OPTION_ALIAS
, NULL
, 82 },
509 {"show-defaults", SHOW_DEFAULTS_OPTION
, 0, 0,
510 N_("Show tar defaults"), 82 },
511 {"show-omitted-dirs", SHOW_OMITTED_DIRS_OPTION
, 0, 0,
512 N_("When listing or extracting, list each directory that does not match search criteria"), 82 },
515 N_("Compatibility options:"), 90 },
518 N_("when creating, same as --old-archive. When extracting, same as --no-same-owner"), 91 },
521 N_("Other options:"), 100 },
523 {"help", '?', 0, 0, N_("Give this help list"), -1},
524 {"usage", USAGE_OPTION
, 0, 0, N_("Give a short usage message"), -1},
525 {"license", LICENSE_OPTION
, 0, 0, N_("Print license and exit"), -1},
526 {"version", VERSION_OPTION
, 0, 0, N_("Print program version"), -1},
527 /* FIXME -V (--label) conflicts with the default short option for
534 char const *textual_date_option
;
538 char const *backup_suffix_string
;
539 char const *version_control_string
;
544 show_default_settings (FILE *stream
)
547 "--format=%s -f%s -b%d --rmt-command=%s --rsh-command=%s\n",
548 archive_format_string (DEFAULT_ARCHIVE_FORMAT
),
549 DEFAULT_ARCHIVE
, DEFAULT_BLOCKING
,
550 DEFAULT_RMT_COMMAND
, REMOTE_SHELL
);
554 set_subcommand_option (enum subcommand subcommand
)
556 if (subcommand_option
!= UNKNOWN_SUBCOMMAND
557 && subcommand_option
!= subcommand
)
559 _("You may not specify more than one `-Acdtrux' option")));
561 subcommand_option
= subcommand
;
565 set_use_compress_program_option (const char *string
)
567 if (use_compress_program_option
568 && strcmp (use_compress_program_option
, string
) != 0)
569 USAGE_ERROR ((0, 0, _("Conflicting compression options")));
571 use_compress_program_option
= string
;
577 printf ("tar (%s) %s\n%s\n", PACKAGE_NAME
, PACKAGE_VERSION
,
578 "Copyright (C) 2004 Free Software Foundation, Inc.\n");
579 puts (_("Based on the work of John Gilmore and Jay Fenlason. See AUTHORS\n\
580 for complete list of authors.\n"));
581 printf (_(" GNU tar is free software; you can redistribute it and/or modify\n"
582 " it under the terms of the GNU General Public License as published by\n"
583 " the Free Software Foundation; either version 2 of the License, or\n"
584 " (at your option) any later version.\n"
586 " GNU Mailutils is distributed in the hope that it will be useful,\n"
587 " but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
588 " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
589 " GNU General Public License for more details.\n"
591 " You should have received a copy of the GNU General Public License\n"
592 " along with GNU Mailutils; if not, write to the Free Software\n"
593 " Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\n\n"));
598 parse_opt(int key
, char *arg
, struct argp_state
*state
)
600 struct tar_args
*args
= state
->input
;
605 /* File name or non-parsed option, because of ARGP_IN_ORDER */
611 set_subcommand_option (CAT_SUBCOMMAND
);
617 if (! (xstrtoumax (arg
, 0, 10, &u
, "") == LONGINT_OK
618 && u
== (blocking_factor
= u
)
619 && 0 < blocking_factor
620 && u
== (record_size
= u
* BLOCKSIZE
) / BLOCKSIZE
))
621 USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (arg
),
622 _("Invalid blocking factor")));
627 /* Try to reblock input records. For reading 4.2BSD pipes. */
629 /* It would surely make sense to exchange -B and -R, but it seems
630 that -B has been used for a long while in Sun tar and most
631 BSD-derived systems. This is a consequence of the block/record
632 terminology confusion. */
634 read_full_records_option
= true;
638 set_subcommand_option (CREATE_SUBCOMMAND
);
647 set_subcommand_option (DIFF_SUBCOMMAND
);
651 if (archive_names
== allocated_archive_names
)
653 allocated_archive_names
*= 2;
655 xrealloc (archive_name_array
,
656 sizeof (const char *) * allocated_archive_names
);
658 archive_name_array
[archive_names
++] = arg
;
662 /* Since -F is only useful with -M, make it implied. Run this
663 script at the end of each tape. */
665 info_script_option
= arg
;
666 multi_volume_option
= true;
670 listed_incremental_option
= arg
;
671 after_date_option
= true;
675 /* We are making an incremental dump (FIXME: are we?); save
676 directories at the beginning of the archive, and include in each
677 directory its contents. */
679 incremental_option
= true;
683 /* Follow symbolic links. */
684 dereference_option
= true;
688 /* Ignore zero blocks (eofs). This can't be the default,
689 because Unix tar writes two blocks of zeros, then pads out
690 the record with garbage. */
692 ignore_zeros_option
= true;
697 _("Warning: the -I option is not supported;"
698 " perhaps you meant -j or -T?")));
702 set_use_compress_program_option ("bzip2");
706 /* Don't replace existing files. */
707 old_files_option
= KEEP_OLD_FILES
;
711 starting_file_option
= true;
716 /* When dumping directories, don't dump files/subdirectories
717 that are on other filesystems. */
719 one_file_system_option
= true;
725 if (xstrtoumax (arg
, 0, 10, &u
, "") != LONGINT_OK
)
726 USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (arg
),
727 _("Invalid tape length")));
728 tape_length_option
= 1024 * (tarlong
) u
;
729 multi_volume_option
= true;
738 /* Make multivolume archive: when we can't write any more into
739 the archive, re-open it, and continue writing. */
741 multi_volume_option
= true;
745 seekable_archive
= true;
750 after_date_option
= true;
753 case NEWER_MTIME_OPTION
:
754 if (NEWER_OPTION_INITIALIZED (newer_mtime_option
))
755 USAGE_ERROR ((0, 0, _("More than one threshold date")));
757 if (FILESYSTEM_PREFIX_LEN (arg
) != 0
762 if (deref_stat (dereference_option
, arg
, &st
) != 0)
765 USAGE_ERROR ((0, 0, _("Date file not found")));
767 newer_mtime_option
.tv_sec
= st
.st_mtime
;
768 newer_mtime_option
.tv_nsec
= TIMESPEC_NS (st
.st_mtim
);
772 if (! get_date (&newer_mtime_option
, arg
, NULL
))
774 WARN ((0, 0, _("Substituting %s for unknown date format %s"),
775 tartime (newer_mtime_option
.tv_sec
), quote (arg
)));
776 newer_mtime_option
.tv_nsec
= 0;
779 args
->textual_date_option
= arg
;
783 #endif /* not MSDOS */
786 args
->o_option
= true;
790 to_stdout_option
= true;
794 same_permissions_option
= true;
798 absolute_names_option
= true;
802 set_subcommand_option (APPEND_SUBCOMMAND
);
806 /* Print block numbers for debugging bad tar archives. */
808 /* It would surely make sense to exchange -B and -R, but it seems
809 that -B has been used for a long while in Sun tar ans most
810 BSD-derived systems. This is a consequence of the block/record
811 terminology confusion. */
813 block_number_option
= true;
817 /* Names to extr are sorted. */
819 same_order_option
= true;
823 sparse_option
= true;
827 set_subcommand_option (LIST_SUBCOMMAND
);
832 files_from_option
= arg
;
836 set_subcommand_option (UPDATE_SUBCOMMAND
);
840 old_files_option
= UNLINK_FIRST_OLD_FILES
;
852 volume_label_option
= arg
;
856 interactive_option
= true;
860 verify_option
= true;
864 set_subcommand_option (EXTRACT_SUBCOMMAND
);
868 if (add_exclude_file (add_exclude
, excluded
, arg
,
869 args
->exclude_options
| recursion_option
, '\n')
873 FATAL_ERROR ((0, e
, "%s", quotearg_colon (arg
)));
879 _("Warning: the -y option is not supported;"
880 " perhaps you meant -j?")));
884 set_use_compress_program_option ("gzip");
888 set_use_compress_program_option ("compress");
891 case ANCHORED_OPTION
:
892 args
->exclude_options
|= EXCLUDE_ANCHORED
;
895 case ATIME_PRESERVE_OPTION
:
896 atime_preserve_option
= true;
899 case CHECKPOINT_OPTION
:
900 checkpoint_option
= true;
904 backup_option
= true;
906 args
->version_control_string
= arg
;
910 set_subcommand_option (DELETE_SUBCOMMAND
);
914 add_exclude (excluded
, arg
, args
->exclude_options
| recursion_option
);
917 case FORCE_LOCAL_OPTION
:
918 force_local_option
= true;
922 set_archive_format (arg
);
925 case INDEX_FILE_OPTION
:
926 index_file_name
= arg
;
929 case IGNORE_CASE_OPTION
:
930 args
->exclude_options
|= FNM_CASEFOLD
;
933 case IGNORE_FAILED_READ_OPTION
:
934 ignore_failed_read_option
= true;
937 case KEEP_NEWER_FILES_OPTION
:
938 old_files_option
= KEEP_NEWER_FILES
;
942 if (! (strlen (arg
) < GNAME_FIELD_SIZE
943 && gname_to_gid (arg
, &group_option
)))
946 if (xstrtoumax (arg
, 0, 10, &g
, "") == LONGINT_OK
950 FATAL_ERROR ((0, 0, "%s: %s", quotearg_colon (arg
),
951 _("%s: Invalid group")));
958 MODE_MASK_EQUALS
| MODE_MASK_PLUS
| MODE_MASK_MINUS
);
959 if (mode_option
== MODE_INVALID
)
960 FATAL_ERROR ((0, 0, _("Invalid mode given on option")));
961 if (mode_option
== MODE_MEMORY_EXHAUSTED
)
965 case NO_ANCHORED_OPTION
:
966 args
->exclude_options
&= ~ EXCLUDE_ANCHORED
;
969 case NO_IGNORE_CASE_OPTION
:
970 args
->exclude_options
&= ~ FNM_CASEFOLD
;
973 case NO_OVERWRITE_DIR_OPTION
:
974 old_files_option
= NO_OVERWRITE_DIR_OLD_FILES
;
977 case NO_WILDCARDS_OPTION
:
978 args
->exclude_options
&= ~ EXCLUDE_WILDCARDS
;
981 case NO_WILDCARDS_MATCH_SLASH_OPTION
:
982 args
->exclude_options
|= FNM_FILE_NAME
;
986 filename_terminator
= '\0';
989 case NUMERIC_OWNER_OPTION
:
990 numeric_owner_option
= true;
993 case OCCURRENCE_OPTION
:
995 occurrence_option
= 1;
999 if (xstrtoumax (arg
, 0, 10, &u
, "") == LONGINT_OK
)
1000 occurrence_option
= u
;
1002 FATAL_ERROR ((0, 0, "%s: %s", quotearg_colon (arg
),
1003 _("Invalid number")));
1007 case OVERWRITE_OPTION
:
1008 old_files_option
= OVERWRITE_OLD_FILES
;
1012 if (! (strlen (arg
) < UNAME_FIELD_SIZE
1013 && uname_to_uid (arg
, &owner_option
)))
1016 if (xstrtoumax (arg
, 0, 10, &u
, "") == LONGINT_OK
1020 FATAL_ERROR ((0, 0, "%s: %s", quotearg_colon (arg
),
1021 _("Invalid owner")));
1027 xheader_set_option (arg
);
1031 set_archive_format ("posix");
1034 case PRESERVE_OPTION
:
1035 same_permissions_option
= true;
1036 same_order_option
= true;
1039 case RECORD_SIZE_OPTION
:
1042 if (! (xstrtoumax (arg
, 0, 10, &u
, "") == LONGINT_OK
1043 && u
== (size_t) u
))
1044 USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (arg
),
1045 _("Invalid record size")));
1047 if (record_size
% BLOCKSIZE
!= 0)
1048 USAGE_ERROR ((0, 0, _("Record size must be a multiple of %d."),
1050 blocking_factor
= record_size
/ BLOCKSIZE
;
1054 case RECURSIVE_UNLINK_OPTION
:
1055 recursive_unlink_option
= true;
1058 case REMOVE_FILES_OPTION
:
1059 remove_files_option
= true;
1062 case RMT_COMMAND_OPTION
:
1063 rmt_command_option
= arg
;
1066 case RSH_COMMAND_OPTION
:
1067 rsh_command_option
= arg
;
1070 case SHOW_DEFAULTS_OPTION
:
1071 show_default_settings (stdout
);
1074 case STRIP_COMPONENTS_OPTION
:
1077 if (! (xstrtoumax (arg
, 0, 10, &u
, "") == LONGINT_OK
1078 && u
== (size_t) u
))
1079 USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (arg
),
1080 _("Invalid number of elements")));
1081 strip_name_components
= u
;
1085 case SHOW_OMITTED_DIRS_OPTION
:
1086 show_omitted_dirs_option
= true;
1090 backup_option
= true;
1091 args
->backup_suffix_string
= arg
;
1095 totals_option
= true;
1098 case USE_COMPRESS_PROGRAM_OPTION
:
1099 set_use_compress_program_option (arg
);
1102 case VOLNO_FILE_OPTION
:
1103 volno_file_option
= arg
;
1106 case WILDCARDS_OPTION
:
1107 args
->exclude_options
|= EXCLUDE_WILDCARDS
;
1110 case WILDCARDS_MATCH_SLASH_OPTION
:
1111 args
->exclude_options
&= ~ FNM_FILE_NAME
;
1114 case CHECK_LINKS_OPTION
:
1115 check_links_option
= 1;
1118 case NO_RECURSION_OPTION
:
1119 recursion_option
= 0;
1122 case NO_SAME_OWNER_OPTION
:
1123 same_owner_option
= -1;
1126 case NO_SAME_PERMISSIONS_OPTION
:
1127 same_permissions_option
= -1;
1130 case RECURSION_OPTION
:
1131 recursion_option
= FNM_LEADING_DIR
;
1134 case SAME_OWNER_OPTION
:
1135 same_owner_option
= 1;
1147 #ifdef DEVICE_PREFIX
1149 int device
= key
- '0';
1151 static char buf
[sizeof DEVICE_PREFIX
+ 10];
1155 argp_error (state
, _("Malformed density argument: '%s'"), arg
);
1157 strcpy (buf
, DEVICE_PREFIX
);
1158 cursor
= buf
+ strlen (buf
);
1160 #ifdef DENSITY_LETTER
1162 sprintf (cursor
, "%d%c", device
, arg
[0]);
1164 #else /* not DENSITY_LETTER */
1191 argp_error (state
, _("Unknown density: '%c'"), arg
[0]);
1193 sprintf (cursor
, "%d", device
);
1195 #endif /* not DENSITY_LETTER */
1197 if (archive_names
== allocated_archive_names
)
1199 allocated_archive_names
*= 2;
1200 archive_name_array
=
1201 xrealloc (archive_name_array
,
1202 sizeof (const char *) * allocated_archive_names
);
1204 archive_name_array
[archive_names
++] = strdup (buf
);
1208 #else /* not DEVICE_PREFIX */
1211 _("Options `-[0-7][lmh]' not supported by *this* tar"));
1213 #endif /* not DEVICE_PREFIX */
1216 state
->flags
|= ARGP_NO_EXIT
;
1217 argp_state_help (state
, state
->out_stream
,
1218 ARGP_HELP_STD_HELP
& ~ARGP_HELP_BUG_ADDR
);
1219 fprintf (state
->out_stream
, _("\n*This* tar defaults to:\n"));
1220 show_default_settings (state
->out_stream
);
1221 fprintf (state
->out_stream
, "\n");
1222 fprintf (state
->out_stream
, _("Report bugs to %s.\n"),
1223 argp_program_bug_address
);
1227 argp_state_help (state
, state
->out_stream
,
1228 ARGP_HELP_USAGE
| ARGP_HELP_EXIT_OK
);
1231 case VERSION_OPTION
:
1232 fprintf (state
->out_stream
, "%s\n", argp_program_version
);
1235 case LICENSE_OPTION
:
1240 return ARGP_ERR_UNKNOWN
;
1245 static struct argp argp
= {
1258 argp_help (&argp
, stderr
, ARGP_HELP_SEE
, program_name
);
1262 /* Parse the options for tar. */
1264 static struct argp_option
*
1265 find_argp_option (struct argp_option
*options
, int letter
)
1268 !(options
->name
== NULL
1269 && options
->key
== 0
1270 && options
->arg
== 0
1272 && options
->doc
== NULL
); options
++)
1273 if (options
->key
== letter
)
1279 decode_options (int argc
, char **argv
)
1281 int optchar
; /* option letter */
1283 struct tar_args args
;
1285 /* Set some default option values. */
1286 args
.textual_date_option
= NULL
;
1287 args
.exclude_options
= EXCLUDE_WILDCARDS
;
1289 args
.pax_option
= 0;
1290 args
.backup_suffix_string
= getenv ("SIMPLE_BACKUP_SUFFIX");
1291 args
.version_control_string
= 0;
1292 args
.input_files
= 0;
1295 subcommand_option
= UNKNOWN_SUBCOMMAND
;
1296 archive_format
= DEFAULT_FORMAT
;
1297 blocking_factor
= DEFAULT_BLOCKING
;
1298 record_size
= DEFAULT_BLOCKING
* BLOCKSIZE
;
1299 excluded
= new_exclude ();
1300 newer_mtime_option
.tv_sec
= TYPE_MINIMUM (time_t);
1301 newer_mtime_option
.tv_nsec
= -1;
1302 recursion_option
= FNM_LEADING_DIR
;
1307 /* Convert old-style tar call by exploding option element and rearranging
1308 options accordingly. */
1310 if (argc
> 1 && argv
[1][0] != '-')
1312 int new_argc
; /* argc value for rearranged arguments */
1313 char **new_argv
; /* argv value for rearranged arguments */
1314 char *const *in
; /* cursor into original argv */
1315 char **out
; /* cursor into rearranged argv */
1316 const char *letter
; /* cursor into old option letters */
1317 char buffer
[3]; /* constructed option buffer */
1319 /* Initialize a constructed option. */
1324 /* Allocate a new argument array, and copy program name in it. */
1326 new_argc
= argc
- 1 + strlen (argv
[1]);
1327 new_argv
= xmalloc ((new_argc
+ 1) * sizeof (char *));
1332 /* Copy each old letter option as a separate option, and have the
1333 corresponding argument moved next to it. */
1335 for (letter
= *in
++; *letter
; letter
++)
1337 struct argp_option
*opt
;
1339 buffer
[1] = *letter
;
1340 *out
++ = xstrdup (buffer
);
1341 opt
= find_argp_option (options
, *letter
);
1342 if (opt
&& opt
->arg
)
1344 if (in
< argv
+ argc
)
1347 USAGE_ERROR ((0, 0, _("Old option `%c' requires an argument."),
1352 /* Copy all remaining options. */
1354 while (in
< argv
+ argc
)
1358 /* Replace the old option list by the new one. */
1364 /* Parse all options and non-options as they appear. */
1366 prepend_default_options (getenv ("TAR_OPTIONS"), &argc
, &argv
);
1368 if (argp_parse (&argp
, argc
, argv
, ARGP_IN_ORDER
|ARGP_NO_HELP
,
1370 exit (1); /* FIXME */
1373 /* Special handling for 'o' option:
1375 GNU tar used to say "output old format".
1376 UNIX98 tar says don't chown files after extracting (we use
1377 "--no-same-owner" for this).
1379 The old GNU tar semantics is retained when used with --create
1380 option, otherwise UNIX98 semantics is assumed */
1384 if (subcommand_option
== CREATE_SUBCOMMAND
)
1386 /* GNU Tar <= 1.13 compatibility */
1387 set_archive_format ("v7");
1391 /* UNIX98 compatibility */
1392 same_owner_option
= 1;
1396 /* Handle operands after any "--" argument. */
1397 for (; index
< argc
; index
++)
1399 name_add (argv
[index
]);
1403 /* Derive option values and check option consistency. */
1405 if (archive_format
== DEFAULT_FORMAT
)
1407 if (args
.pax_option
)
1408 archive_format
= POSIX_FORMAT
;
1410 archive_format
= DEFAULT_ARCHIVE_FORMAT
;
1413 if (volume_label_option
&& subcommand_option
== CREATE_SUBCOMMAND
)
1414 assert_format (FORMAT_MASK (OLDGNU_FORMAT
)
1415 | FORMAT_MASK (GNU_FORMAT
));
1418 if (incremental_option
|| multi_volume_option
)
1419 assert_format (FORMAT_MASK (OLDGNU_FORMAT
) | FORMAT_MASK (GNU_FORMAT
));
1422 assert_format (FORMAT_MASK (OLDGNU_FORMAT
)
1423 | FORMAT_MASK (GNU_FORMAT
)
1424 | FORMAT_MASK (POSIX_FORMAT
));
1426 if (occurrence_option
)
1428 if (!args
.input_files
&& !files_from_option
)
1430 _("--occurrence is meaningless without a file list")));
1431 if (subcommand_option
!= DELETE_SUBCOMMAND
1432 && subcommand_option
!= DIFF_SUBCOMMAND
1433 && subcommand_option
!= EXTRACT_SUBCOMMAND
1434 && subcommand_option
!= LIST_SUBCOMMAND
)
1436 _("--occurrence cannot be used in the requested operation mode")));
1439 if (archive_names
== 0)
1441 /* If no archive file name given, try TAPE from the environment, or
1442 else, DEFAULT_ARCHIVE from the configuration process. */
1445 archive_name_array
[0] = getenv ("TAPE");
1446 if (! archive_name_array
[0])
1447 archive_name_array
[0] = DEFAULT_ARCHIVE
;
1450 /* Allow multiple archives only with `-M'. */
1452 if (archive_names
> 1 && !multi_volume_option
)
1454 _("Multiple archive files require `-M' option")));
1456 if (listed_incremental_option
1457 && NEWER_OPTION_INITIALIZED (newer_mtime_option
))
1459 _("Cannot combine --listed-incremental with --newer")));
1461 if (volume_label_option
)
1463 size_t volume_label_max_len
=
1464 (sizeof current_header
->header
.name
1465 - 1 /* for trailing '\0' */
1466 - (multi_volume_option
1467 ? (sizeof " Volume "
1468 - 1 /* for null at end of " Volume " */
1469 + INT_STRLEN_BOUND (int) /* for volume number */
1470 - 1 /* for sign, as 0 <= volno */)
1472 if (volume_label_max_len
< strlen (volume_label_option
))
1474 ngettext ("%s: Volume label is too long (limit is %lu byte)",
1475 "%s: Volume label is too long (limit is %lu bytes)",
1476 volume_label_max_len
),
1477 quotearg_colon (volume_label_option
),
1478 (unsigned long) volume_label_max_len
));
1483 if (multi_volume_option
)
1484 USAGE_ERROR ((0, 0, _("Cannot verify multi-volume archives")));
1485 if (use_compress_program_option
)
1486 USAGE_ERROR ((0, 0, _("Cannot verify compressed archives")));
1489 if (use_compress_program_option
)
1491 if (multi_volume_option
)
1492 USAGE_ERROR ((0, 0, _("Cannot use multi-volume compressed archives")));
1493 if (subcommand_option
== UPDATE_SUBCOMMAND
)
1494 USAGE_ERROR ((0, 0, _("Cannot update compressed archives")));
1497 /* It is no harm to use --pax-option on non-pax archives in archive
1498 reading mode. It may even be useful, since it allows to override
1499 file attributes from tar headers. Therefore I allow such usage.
1502 && archive_format
!= POSIX_FORMAT
1503 && (subcommand_option
!= EXTRACT_SUBCOMMAND
1504 || subcommand_option
!= DIFF_SUBCOMMAND
1505 || subcommand_option
!= LIST_SUBCOMMAND
))
1506 USAGE_ERROR ((0, 0, _("--pax-option can be used only on POSIX archives")));
1508 /* If ready to unlink hierarchies, so we are for simpler files. */
1509 if (recursive_unlink_option
)
1510 old_files_option
= UNLINK_FIRST_OLD_FILES
;
1515 if (!rmt_command_option
)
1516 rmt_command_option
= DEFAULT_RMT_COMMAND
;
1518 /* Forbid using -c with no input files whatsoever. Check that `-f -',
1519 explicit or implied, is used correctly. */
1521 switch (subcommand_option
)
1523 case CREATE_SUBCOMMAND
:
1524 if (args
.input_files
== 0 && !files_from_option
)
1526 _("Cowardly refusing to create an empty archive")));
1529 case EXTRACT_SUBCOMMAND
:
1530 case LIST_SUBCOMMAND
:
1531 case DIFF_SUBCOMMAND
:
1532 for (archive_name_cursor
= archive_name_array
;
1533 archive_name_cursor
< archive_name_array
+ archive_names
;
1534 archive_name_cursor
++)
1535 if (!strcmp (*archive_name_cursor
, "-"))
1536 request_stdin ("-f");
1539 case CAT_SUBCOMMAND
:
1540 case UPDATE_SUBCOMMAND
:
1541 case APPEND_SUBCOMMAND
:
1542 for (archive_name_cursor
= archive_name_array
;
1543 archive_name_cursor
< archive_name_array
+ archive_names
;
1544 archive_name_cursor
++)
1545 if (!strcmp (*archive_name_cursor
, "-"))
1547 _("Options `-Aru' are incompatible with `-f -'")));
1553 archive_name_cursor
= archive_name_array
;
1555 /* Prepare for generating backup names. */
1557 if (args
.backup_suffix_string
)
1558 simple_backup_suffix
= xstrdup (args
.backup_suffix_string
);
1561 backup_type
= xget_version ("--backup", args
.version_control_string
);
1563 if (verbose_option
&& args
.textual_date_option
)
1565 /* FIXME: tartime should support nanoseconds, too, so that this
1566 comparison doesn't complain about lost nanoseconds. */
1567 char const *treated_as
= tartime (newer_mtime_option
.tv_sec
);
1568 if (strcmp (args
.textual_date_option
, treated_as
) != 0)
1570 ngettext ("Treating date `%s' as %s + %ld nanosecond",
1571 "Treating date `%s' as %s + %ld nanoseconds",
1572 newer_mtime_option
.tv_nsec
),
1573 args
.textual_date_option
, treated_as
,
1574 newer_mtime_option
.tv_nsec
));
1581 /* Main routine for tar. */
1583 main (int argc
, char **argv
)
1585 #if HAVE_CLOCK_GETTIME
1586 if (clock_gettime (CLOCK_REALTIME
, &start_timespec
) != 0)
1588 start_time
= time (0);
1589 program_name
= argv
[0];
1590 setlocale (LC_ALL
, "");
1591 bindtextdomain (PACKAGE
, LOCALEDIR
);
1592 textdomain (PACKAGE
);
1594 exit_status
= TAREXIT_SUCCESS
;
1595 filename_terminator
= '\n';
1596 set_quoting_style (0, escape_quoting_style
);
1598 /* Pre-allocate a few structures. */
1600 allocated_archive_names
= 10;
1601 archive_name_array
=
1602 xmalloc (sizeof (const char *) * allocated_archive_names
);
1606 /* System V fork+wait does not work if SIGCHLD is ignored. */
1607 signal (SIGCHLD
, SIG_DFL
);
1612 /* Decode options. */
1614 decode_options (argc
, argv
);
1617 /* Main command execution. */
1619 if (volno_file_option
)
1620 init_volume_number ();
1622 switch (subcommand_option
)
1624 case UNKNOWN_SUBCOMMAND
:
1626 _("You must specify one of the `-Acdtrux' options")));
1628 case CAT_SUBCOMMAND
:
1629 case UPDATE_SUBCOMMAND
:
1630 case APPEND_SUBCOMMAND
:
1634 case DELETE_SUBCOMMAND
:
1635 delete_archive_members ();
1638 case CREATE_SUBCOMMAND
:
1643 print_total_written ();
1646 case EXTRACT_SUBCOMMAND
:
1648 read_and (extract_archive
);
1650 /* FIXME: should extract_finish () even if an ordinary signal is
1656 case LIST_SUBCOMMAND
:
1657 read_and (list_archive
);
1660 case DIFF_SUBCOMMAND
:
1662 read_and (diff_archive
);
1666 if (check_links_option
)
1669 if (volno_file_option
)
1670 closeout_volume_number ();
1672 /* Dispose of allocated memory, and return. */
1674 free (archive_name_array
);
1677 if (stdlis
!= stderr
&& (ferror (stdlis
) || fclose (stdlis
) != 0))
1678 FATAL_ERROR ((0, 0, _("Error in writing to standard output")));
1679 if (exit_status
== TAREXIT_FAILURE
)
1680 error (0, 0, _("Error exit delayed from previous errors"));
1681 if (ferror (stderr
) || fclose (stderr
) != 0)
1682 exit_status
= TAREXIT_FAILURE
;
1687 tar_stat_init (struct tar_stat_info
*st
)
1689 memset (st
, 0, sizeof (*st
));
1693 tar_stat_destroy (struct tar_stat_info
*st
)
1695 free (st
->orig_file_name
);
1696 free (st
->file_name
);
1697 free (st
->link_name
);
1700 free (st
->sparse_map
);
1701 memset (st
, 0, sizeof (*st
));