Add the DragonFly cvs id and perform general cleanups on cvs/rcs/sccs ids. Most
[dragonfly.git] / contrib / tar / src / tar.c
1 /* A tar (tape archiver) program.
2
3    Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1999, 2000, 2001
4    Free Software Foundation, Inc.
5
6    Written by John Gilmore, starting 1985-08-25.
7
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
11    version.
12
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.
17
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.  */
21
22 /* $FreeBSD: src/contrib/tar/src/tar.c,v 1.2.2.1 2002/07/14 13:19:44 sobomax Exp $ */
23 /* $DragonFly: src/contrib/tar/src/Attic/tar.c,v 1.2 2003/06/17 04:24:06 dillon Exp $ */
24
25 #include "system.h"
26
27 #include <fnmatch.h>
28 #include <getopt.h>
29
30 #include <signal.h>
31 #if ! defined SIGCHLD && defined SIGCLD
32 # define SIGCHLD SIGCLD
33 #endif
34
35 /* The following causes "common.h" to produce definitions of all the global
36    variables, rather than just "extern" declarations of them.  GNU tar does
37    depend on the system loader to preset all GLOBAL variables to neutral (or
38    zero) values; explicit initialization is usually not done.  */
39 #define GLOBAL
40 #include "common.h"
41
42 #include <print-copyr.h>
43 #include <localedir.h>
44 #include <prepargs.h>
45 #include <quotearg.h>
46 #include <xstrtol.h>
47
48 time_t get_date ();
49
50 /* Local declarations.  */
51
52 #ifndef DEFAULT_ARCHIVE
53 # define DEFAULT_ARCHIVE "tar.out"
54 #endif
55
56 #ifndef DEFAULT_BLOCKING
57 # define DEFAULT_BLOCKING 20
58 #endif
59
60 static void usage PARAMS ((int)) __attribute__ ((noreturn));
61 \f
62 /* Miscellaneous.  */
63
64 /* Name of option using stdin.  */
65 static const char *stdin_used_by;
66
67 /* Doesn't return if stdin already requested.  */
68 void
69 request_stdin (const char *option)
70 {
71   if (stdin_used_by)
72     USAGE_ERROR ((0, 0, _("Options `-%s' and `-%s' both want standard input"),
73                   stdin_used_by, option));
74
75   stdin_used_by = option;
76 }
77
78 /* Returns true if and only if the user typed 'y' or 'Y'.  */
79 int
80 confirm (const char *message_action, const char *message_name)
81 {
82   static FILE *confirm_file;
83   static int confirm_file_EOF;
84
85   if (!confirm_file)
86     {
87       if (archive == 0 || stdin_used_by)
88         {
89           confirm_file = fopen (TTY_NAME, "r");
90           if (! confirm_file)
91             open_fatal (TTY_NAME);
92         }
93       else
94         {
95           request_stdin ("-w");
96           confirm_file = stdin;
97         }
98     }
99
100   fprintf (stdlis, "%s %s?", message_action, quote (message_name));
101   fflush (stdlis);
102
103   {
104     int reply = confirm_file_EOF ? EOF : getc (confirm_file);
105     int character;
106
107     for (character = reply;
108          character != '\n';
109          character = getc (confirm_file))
110       if (character == EOF)
111         {
112           confirm_file_EOF = 1;
113           fputc ('\n', stdlis);
114           fflush (stdlis);
115           break;
116         }
117     return reply == 'y' || reply == 'Y';
118   }
119 }
120 \f
121 /* Options.  */
122
123 /* For long options that unconditionally set a single flag, we have getopt
124    do it.  For the others, we share the code for the equivalent short
125    named option, the name of which is stored in the otherwise-unused `val'
126    field of the `struct option'; for long options that have no equivalent
127    short option, we use non-characters as pseudo short options,
128    starting at CHAR_MAX + 1 and going upwards.  */
129
130 enum
131 {
132   ANCHORED_OPTION = CHAR_MAX + 1,
133   BACKUP_OPTION,
134   DELETE_OPTION,
135   EXCLUDE_OPTION,
136   GROUP_OPTION,
137   IGNORE_CASE_OPTION,
138   MODE_OPTION,
139   NEWER_MTIME_OPTION,
140   NO_ANCHORED_OPTION,
141   NO_IGNORE_CASE_OPTION,
142   NO_WILDCARDS_OPTION,
143   NO_WILDCARDS_MATCH_SLASH_OPTION,
144   NULL_OPTION,
145   OVERWRITE_OPTION,
146   OVERWRITE_DIR_OPTION,
147   OWNER_OPTION,
148   POSIX_OPTION,
149   PRESERVE_OPTION,
150   RECORD_SIZE_OPTION,
151   RSH_COMMAND_OPTION,
152   SUFFIX_OPTION,
153   USE_COMPRESS_PROGRAM_OPTION,
154   VOLNO_FILE_OPTION,
155   WILDCARDS_OPTION,
156   WILDCARDS_MATCH_SLASH_OPTION,
157
158   /* Some cleanup is being made in GNU tar long options.  Using old names is
159      allowed for a while, but will also send a warning to stderr.  Take old
160      names out in 1.14, or in summer 1997, whichever happens last.  */
161
162   OBSOLETE_ABSOLUTE_NAMES,
163   OBSOLETE_BLOCK_COMPRESS,
164   OBSOLETE_BLOCKING_FACTOR,
165   OBSOLETE_BLOCK_NUMBER,
166   OBSOLETE_READ_FULL_RECORDS,
167   OBSOLETE_TOUCH,
168   OBSOLETE_VERSION_CONTROL
169 };
170
171 /* If nonzero, display usage information and exit.  */
172 static int show_help;
173
174 /* If nonzero, print the version on standard output and exit.  */
175 static int show_version;
176
177 static struct option long_options[] =
178 {
179   {"absolute-names", no_argument, 0, 'P'},
180   {"absolute-paths", no_argument, 0, OBSOLETE_ABSOLUTE_NAMES},
181   {"after-date", required_argument, 0, 'N'},
182   {"anchored", no_argument, 0, ANCHORED_OPTION},
183   {"append", no_argument, 0, 'r'},
184   {"atime-preserve", no_argument, &atime_preserve_option, 1},
185   {"backup", optional_argument, 0, BACKUP_OPTION},
186   {"block-compress", no_argument, 0, OBSOLETE_BLOCK_COMPRESS},
187   {"block-number", no_argument, 0, 'R'},
188   {"block-size", required_argument, 0, OBSOLETE_BLOCKING_FACTOR},
189   {"blocking-factor", required_argument, 0, 'b'},
190   {"bzip", no_argument, 0, 'j'},
191   {"bzip2", no_argument, 0, 'j'},
192   {"bunzip2", no_argument, 0, 'j'},
193   {"catenate", no_argument, 0, 'A'},
194   {"checkpoint", no_argument, &checkpoint_option, 1},
195   {"compare", no_argument, 0, 'd'},
196   {"compress", no_argument, 0, 'Z'},
197   {"concatenate", no_argument, 0, 'A'},
198   {"confirmation", no_argument, 0, 'w'},
199   /* FIXME: --selective as a synonym for --confirmation?  */
200   {"create", no_argument, 0, 'c'},
201   {"delete", no_argument, 0, DELETE_OPTION},
202   {"dereference", no_argument, 0, 'h'},
203   {"diff", no_argument, 0, 'd'},
204   {"directory", required_argument, 0, 'C'},
205   {"exclude", required_argument, 0, EXCLUDE_OPTION},
206   {"exclude-from", required_argument, 0, 'X'},
207   {"extract", no_argument, 0, 'x'},
208   {"fast-read", no_argument, &fast_read_option, 1},
209   {"file", required_argument, 0, 'f'},
210   {"files-from", required_argument, 0, 'T'},
211   {"force-local", no_argument, &force_local_option, 1},
212   {"get", no_argument, 0, 'x'},
213   {"group", required_argument, 0, GROUP_OPTION},
214   {"gunzip", no_argument, 0, 'z'},
215   {"gzip", no_argument, 0, 'z'},
216   {"help", no_argument, &show_help, 1},
217   {"ignore-case", no_argument, 0, IGNORE_CASE_OPTION},
218   {"ignore-failed-read", no_argument, &ignore_failed_read_option, 1},
219   {"ignore-zeros", no_argument, 0, 'i'},
220   /* FIXME: --ignore-end as a new name for --ignore-zeros?  */
221   {"incremental", no_argument, 0, 'G'},
222   {"info-script", required_argument, 0, 'F'},
223   {"interactive", no_argument, 0, 'w'},
224   {"keep-old-files", no_argument, 0, 'k'},
225   {"label", required_argument, 0, 'V'},
226   {"list", no_argument, 0, 't'},
227   {"listed-incremental", required_argument, 0, 'g'},
228   {"mode", required_argument, 0, MODE_OPTION},
229   {"modification-time", no_argument, 0, OBSOLETE_TOUCH},
230   {"multi-volume", no_argument, 0, 'M'},
231   {"new-volume-script", required_argument, 0, 'F'},
232   {"newer", required_argument, 0, 'N'},
233   {"newer-mtime", required_argument, 0, NEWER_MTIME_OPTION},
234   {"null", no_argument, 0, NULL_OPTION},
235   {"no-anchored", no_argument, 0, NO_ANCHORED_OPTION},
236   {"no-ignore-case", no_argument, 0, NO_IGNORE_CASE_OPTION},
237   {"no-wildcards", no_argument, 0, NO_WILDCARDS_OPTION},
238   {"no-wildcards-match-slash", no_argument, 0, NO_WILDCARDS_MATCH_SLASH_OPTION},
239   {"norecurse", no_argument, &recursion_option, 0},
240   {"no-recursion", no_argument, &recursion_option, 0},
241   {"no-same-owner", no_argument, &same_owner_option, -1},
242   {"no-same-permissions", no_argument, &same_permissions_option, -1},
243   {"numeric-owner", no_argument, &numeric_owner_option, 1},
244   {"old-archive", no_argument, 0, 'o'},
245   {"one-file-system", no_argument, 0, 'l'},
246   {"overwrite", no_argument, 0, OVERWRITE_OPTION},
247   {"overwrite-dir", no_argument, 0, OVERWRITE_DIR_OPTION},
248   {"owner", required_argument, 0, OWNER_OPTION},
249   {"portability", no_argument, 0, 'o'},
250   {"posix", no_argument, 0, POSIX_OPTION},
251   {"preserve", no_argument, 0, PRESERVE_OPTION},
252   {"preserve-order", no_argument, 0, 's'},
253   {"preserve-permissions", no_argument, 0, 'p'},
254   {"recursion", no_argument, &recursion_option, FNM_LEADING_DIR},
255   {"recursive-unlink", no_argument, &recursive_unlink_option, 1},
256   {"read-full-blocks", no_argument, 0, OBSOLETE_READ_FULL_RECORDS},
257   {"read-full-records", no_argument, 0, 'B'},
258   /* FIXME: --partial-blocks might be a synonym for --read-full-records?  */
259   {"record-number", no_argument, 0, OBSOLETE_BLOCK_NUMBER},
260   {"record-size", required_argument, 0, RECORD_SIZE_OPTION},
261   {"remove-files", no_argument, &remove_files_option, 1},
262   {"rsh-command", required_argument, 0, RSH_COMMAND_OPTION},
263   {"same-order", no_argument, 0, 's'},
264   {"same-owner", no_argument, &same_owner_option, 1},
265   {"same-permissions", no_argument, 0, 'p'},
266   {"show-omitted-dirs", no_argument, &show_omitted_dirs_option, 1},
267   {"sparse", no_argument, 0, 'S'},
268   {"starting-file", required_argument, 0, 'K'},
269   {"suffix", required_argument, 0, SUFFIX_OPTION},
270   {"tape-length", required_argument, 0, 'L'},
271   {"to-stdout", no_argument, 0, 'O'},
272   {"totals", no_argument, &totals_option, 1},
273   {"touch", no_argument, 0, 'm'},
274   {"uncompress", no_argument, 0, 'Z'},
275   {"ungzip", no_argument, 0, 'z'},
276   {"unlink", no_argument, 0, 'U'},
277   {"unlink-first", no_argument, 0, 'U'},
278   {"update", no_argument, 0, 'u'},
279   {"use-compress-program", required_argument, 0, USE_COMPRESS_PROGRAM_OPTION},
280   {"verbose", no_argument, 0, 'v'},
281   {"verify", no_argument, 0, 'W'},
282   {"version", no_argument, &show_version, 1},
283   {"version-control", required_argument, 0, OBSOLETE_VERSION_CONTROL},
284   {"volno-file", required_argument, 0, VOLNO_FILE_OPTION},
285   {"wildcards", no_argument, 0, WILDCARDS_OPTION},
286   {"wildcards-match-slash", no_argument, 0, WILDCARDS_MATCH_SLASH_OPTION},
287
288   {0, 0, 0, 0}
289 };
290
291 /* Print a usage message and exit with STATUS.  */
292 static void
293 usage (int status)
294 {
295   if (status != TAREXIT_SUCCESS)
296     fprintf (stderr, _("Try `%s --help' for more information.\n"),
297              program_name);
298   else
299     {
300       fputs (_("\
301 GNU `tar' saves many files together into a single tape or disk archive, and\n\
302 can restore individual files from the archive.\n"),
303              stdout);
304       printf (_("\nUsage: %s [OPTION]... [FILE]...\n\
305 \n\
306 Examples:\n\
307   %s -cf archive.tar foo bar  # Create archive.tar from files foo and bar.\n\
308   %s -tvf archive.tar         # List all files in archive.tar verbosely.\n\
309   %s -xf archive.tar          # Extract all files from archive.tar.\n"),
310              program_name, program_name, program_name, program_name);
311       fputs (_("\
312 \n\
313 If a long option shows an argument as mandatory, then it is mandatory\n\
314 for the equivalent short option also.  Similarly for optional arguments.\n"),
315              stdout);
316       fputs(_("\
317 \n\
318 Main operation mode:\n\
319   -t, --list              list the contents of an archive\n\
320   -x, --extract, --get    extract files from an archive\n\
321   -c, --create            create a new archive\n\
322   -d, --diff, --compare   find differences between archive and file system\n\
323   -r, --append            append files to the end of an archive\n\
324   -u, --update            only append files newer than copy in archive\n\
325   -A, --catenate          append tar files to an archive\n\
326       --concatenate       same as -A\n\
327       --delete            delete from the archive (not on mag tapes!)\n"),
328             stdout);
329       fputs (_("\
330 \n\
331 Operation modifiers:\n\
332   -W, --verify               attempt to verify the archive after writing it\n\
333       --remove-files         remove files after adding them to the archive\n\
334   -k, --keep-old-files       don't replace existing files when extracting\n\
335       --overwrite            overwrite existing files when extracting\n\
336       --overwrite-dir        overwrite directory metadata when extracting\n\
337   -U, --unlink,\n\
338       --unlink-first         remove each file prior to extracting over it\n\
339       --recursive-unlink     empty hierarchies prior to extracting directory\n\
340   -S, --sparse               handle sparse files efficiently\n\
341   -O, --to-stdout            extract files to standard output\n\
342   -G, --incremental          handle old GNU-format incremental backup\n\
343   -g, --listed-incremental=FILE\n\
344                              handle new GNU-format incremental backup\n\
345       --ignore-failed-read   do not exit with nonzero on unreadable files\n\
346       --fast-read            stop after desired names in archive have been found\n"),
347             stdout);
348       fputs (_("\
349 \n\
350 Handling of file attributes:\n\
351       --owner=NAME             force NAME as owner for added files\n\
352       --group=NAME             force NAME as group for added files\n\
353       --mode=CHANGES           force (symbolic) mode CHANGES for added files\n\
354       --atime-preserve         don't change access times on dumped files\n\
355   -m, --modification-time      don't extract file modified time\n\
356       --same-owner             try extracting files with the same ownership\n\
357       --show-omitted-dirs      show omitted directories while processing the\n\
358                                archive\n\
359       --no-same-owner          extract files as yourself\n\
360       --numeric-owner          always use numbers for user/group names\n\
361   -p, --same-permissions       extract permissions information\n\
362       --no-same-permissions    do not extract permissions information\n\
363       --preserve-permissions   same as -p\n\
364   -s, --same-order             sort names to extract to match archive\n\
365       --preserve-order         same as -s\n\
366       --preserve               same as both -p and -s\n"),
367              stdout);
368       fputs (_("\
369 \n\
370 Device selection and switching:\n\
371   -f, --file=ARCHIVE             use archive file or device ARCHIVE\n\
372       --force-local              archive file is local even if it has a colon\n\
373       --rsh-command=COMMAND      use remote COMMAND instead of rsh\n\
374   -[0-7][lmh]                    specify drive and density\n\
375   -M, --multi-volume             create/list/extract multi-volume archive\n\
376   -L, --tape-length=NUM          change tape after writing NUM x 1024 bytes\n\
377   -F, --info-script=FILE         run script at end of each tape (implies -M)\n\
378       --new-volume-script=FILE   same as -F FILE\n\
379       --volno-file=FILE          use/update the volume number in FILE\n"),
380              stdout);
381       fputs (_("\
382 \n\
383 Device blocking:\n\
384   -b, --blocking-factor=BLOCKS   BLOCKS x 512 bytes per record\n\
385       --record-size=SIZE         SIZE bytes per record, multiple of 512\n\
386   -i, --ignore-zeros             ignore zeroed blocks in archive (means EOF)\n\
387   -B, --read-full-records        reblock as we read (for 4.2BSD pipes)\n"),
388              stdout);
389       fputs (_("\
390 \n\
391 Archive format selection:\n\
392   -V, --label=NAME                   create archive with volume name NAME\n\
393               PATTERN                at list/extract time, a globbing PATTERN\n\
394   -o, --old-archive, --portability   write a V7 format archive\n\
395       --posix                        write a POSIX format archive\n\
396   -j, -y, --bzip, --bzip2, --bunzip2 filter the archive through bzip2\n\
397   -z, --gzip, --ungzip               filter the archive through gzip\n\
398   -Z, --compress, --uncompress       filter the archive through compress\n\
399       --use-compress-program=PROG    filter through PROG (must accept -d)\n"),
400              stdout);
401       fputs (_("\
402 \n\
403 Local file selection:\n\
404   -C, --directory=DIR          change to directory DIR\n\
405   -T, -I, --files-from=NAME    get names to extract or create from file NAME\n\
406       --null                   -T reads null-terminated names, disable -C\n\
407       --exclude=PATTERN        exclude files, given as a a globbing PATTERN\n\
408   -X, --exclude-from=FILE      exclude patterns listed in FILE\n\
409       --anchored               exclude patterns match file name start (default)\n\
410       --no-anchored            exclude patterns match after any /\n\
411       --ignore-case            exclusion ignores case\n\
412       --no-ignore-case         exclusion is case sensitive (default)\n\
413       --wildcards              exclude patterns use wildcards (default)\n\
414       --no-wildcards           exclude patterns are plain strings\n\
415       --wildcards-match-slash  exclude pattern wildcards match '/' (default)\n\
416       --no-wildcards-match-slash exclude pattern wildcards do not match '/'\n\
417   -P, --absolute-names         don't strip leading `/'s from file names\n\
418   -h, --dereference            dump instead the files symlinks point to\n\
419   -n, --norecurse\n\
420       --no-recursion           avoid descending automatically in directories\n\
421   -l, --one-file-system        stay in local file system when creating archive\n\
422   -K, --starting-file=NAME     begin at file NAME in the archive\n"),
423              stdout);
424 #if !MSDOS
425       fputs (_("\
426   -N, --newer=DATE             only store files with creation time newer than\n\
427                                DATE\n\
428       --newer-mtime=DATE       only store files with modification time newer\n\
429                                than DATE\n\
430       --after-date=DATE        same as -N\n"),
431              stdout);
432 #endif
433       fputs (_("\
434       --backup[=CONTROL]       backup before removal, choose version control\n\
435       --suffix=SUFFIX          backup before removal, override usual suffix\n"),
436              stdout);
437       fputs (_("\
438 \n\
439 Informative output:\n\
440       --help            print this help, then exit\n\
441       --version         print tar program version number, then exit\n\
442   -v, --verbose         verbosely list files processed\n\
443       --checkpoint      print number of buffer reads/writes\n\
444       --totals          print total bytes written while creating archive\n\
445   -R, --block-number    show block number within archive with each message\n\
446   -w, --interactive     ask for confirmation for every action\n\
447       --confirmation    same as -w\n"),
448              stdout);
449       fputs (_("\
450 \n\
451 The backup suffix is `~', unless set with --suffix or SIMPLE_BACKUP_SUFFIX.\n\
452 The version control may be set with --backup or VERSION_CONTROL, values are:\n\
453 \n\
454   t, numbered     make numbered backups\n\
455   nil, existing   numbered if numbered backups exist, simple otherwise\n\
456   never, simple   always make simple backups\n"),
457              stdout);
458       printf (_("\
459 \n\
460 GNU tar cannot read nor produce `--posix' archives.  If POSIXLY_CORRECT\n\
461 is set in the environment, GNU extensions are disallowed with `--posix'.\n\
462 Support for POSIX is only partially implemented, don't count on it yet.\n\
463 ARCHIVE may be FILE, HOST:FILE or USER@HOST:FILE; DATE may be a textual date\n\
464 or a file name starting with `/' or `.', in which case the file's date is used.\n\
465 *This* `tar' defaults to `-f%s -b%d'.\n"),
466               DEFAULT_ARCHIVE, DEFAULT_BLOCKING);
467       fputs (_("\nReport bugs to <bug-tar@gnu.org>.\n"), stdout);
468     }
469   exit (status);
470 }
471
472 /* Parse the options for tar.  */
473
474 /* Available option letters are DEHIJQY and aenqy.  Some are reserved:
475
476    e  exit immediately with a nonzero exit status if unexpected errors occur
477    E  use extended headers (draft POSIX headers, that is)
478    I  same as T (for compatibility with Solaris tar)
479    n  the archive is quickly seekable, so don't worry about random seeks
480    q  stop after extracting the first occurrence of the named file
481    y  per-file gzip compression
482    Y  per-block gzip compression */
483
484 #define OPTION_STRING \
485   "-01234567ABC:F:GI:K:L:MnN:OPRST:UV:WX:Zb:cdf:g:hijklmoprstuvwxyz"
486
487 static void
488 set_subcommand_option (enum subcommand subcommand)
489 {
490   if (subcommand_option != UNKNOWN_SUBCOMMAND
491       && subcommand_option != subcommand)
492     USAGE_ERROR ((0, 0,
493                   _("You may not specify more than one `-Acdtrux' option")));
494
495   subcommand_option = subcommand;
496 }
497
498 static void
499 set_use_compress_program_option (const char *string)
500 {
501   if (use_compress_program_option && strcmp (use_compress_program_option, string) != 0)
502     USAGE_ERROR ((0, 0, _("Conflicting compression options")));
503
504   use_compress_program_option = string;
505 }
506
507 static void
508 decode_options (int argc, char **argv)
509 {
510   int optchar;                  /* option letter */
511   int input_files;              /* number of input files */
512   const char *backup_suffix_string;
513   const char *version_control_string = 0;
514   int exclude_options = EXCLUDE_WILDCARDS;
515
516   /* Set some default option values.  */
517
518   subcommand_option = UNKNOWN_SUBCOMMAND;
519   archive_format = DEFAULT_FORMAT;
520   blocking_factor = DEFAULT_BLOCKING;
521   record_size = DEFAULT_BLOCKING * BLOCKSIZE;
522   excluded = new_exclude ();
523   newer_mtime_option = TYPE_MINIMUM (time_t);
524   recursion_option = FNM_LEADING_DIR;
525   namelist_freed = 0;
526
527   owner_option = -1;
528   group_option = -1;
529
530   backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX");
531
532   /* Convert old-style tar call by exploding option element and rearranging
533      options accordingly.  */
534
535   if (argc > 1 && argv[1][0] != '-')
536     {
537       int new_argc;             /* argc value for rearranged arguments */
538       char **new_argv;          /* argv value for rearranged arguments */
539       char *const *in;          /* cursor into original argv */
540       char **out;               /* cursor into rearranged argv */
541       const char *letter;       /* cursor into old option letters */
542       char buffer[3];           /* constructed option buffer */
543       const char *cursor;       /* cursor in OPTION_STRING */
544
545       /* Initialize a constructed option.  */
546
547       buffer[0] = '-';
548       buffer[2] = '\0';
549
550       /* Allocate a new argument array, and copy program name in it.  */
551
552       new_argc = argc - 1 + strlen (argv[1]);
553       new_argv = xmalloc (new_argc * sizeof (char *));
554       in = argv;
555       out = new_argv;
556       *out++ = *in++;
557
558       /* Copy each old letter option as a separate option, and have the
559          corresponding argument moved next to it.  */
560
561       for (letter = *in++; *letter; letter++)
562         {
563           buffer[1] = *letter;
564           *out++ = xstrdup (buffer);
565           cursor = strchr (OPTION_STRING, *letter);
566           if (cursor && cursor[1] == ':')
567             {
568               if (in < argv + argc)
569                 *out++ = *in++;
570               else
571                 USAGE_ERROR ((0, 0, _("Old option `%c' requires an argument."),
572                               *letter));
573             }
574         }
575
576       /* Copy all remaining options.  */
577
578       while (in < argv + argc)
579         *out++ = *in++;
580
581       /* Replace the old option list by the new one.  */
582
583       argc = new_argc;
584       argv = new_argv;
585     }
586
587   /* Parse all options and non-options as they appear.  */
588
589   input_files = 0;
590
591   prepend_default_options (getenv ("TAR_OPTIONS"), &argc, &argv);
592
593   while (optchar = getopt_long (argc, argv, OPTION_STRING, long_options, 0),
594          optchar != -1)
595     switch (optchar)
596       {
597       case '?':
598         usage (TAREXIT_FAILURE);
599
600       case 0:
601         break;
602
603       case 1:
604         /* File name or non-parsed option, because of RETURN_IN_ORDER
605            ordering triggered by the leading dash in OPTION_STRING.  */
606
607         name_add (optarg);
608         input_files++;
609         break;
610
611       case 'A':
612         set_subcommand_option (CAT_SUBCOMMAND);
613         break;
614
615       case OBSOLETE_BLOCK_COMPRESS:
616         WARN ((0, 0, _("Obsolete option, now implied by --blocking-factor")));
617         break;
618
619       case OBSOLETE_BLOCKING_FACTOR:
620         WARN ((0, 0, _("Obsolete option name replaced by --blocking-factor")));
621         /* Fall through.  */
622
623       case 'b':
624         {
625           uintmax_t u;
626           if (! (xstrtoumax (optarg, 0, 10, &u, "") == LONGINT_OK
627                  && u == (blocking_factor = u)
628                  && 0 < blocking_factor
629                  && u == (record_size = u * BLOCKSIZE) / BLOCKSIZE))
630             USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (optarg),
631                           _("Invalid blocking factor")));
632         }
633         break;
634
635       case OBSOLETE_READ_FULL_RECORDS:
636         WARN ((0, 0,
637                _("Obsolete option name replaced by --read-full-records")));
638         /* Fall through.  */
639
640       case 'B':
641         /* Try to reblock input records.  For reading 4.2BSD pipes.  */
642
643         /* It would surely make sense to exchange -B and -R, but it seems
644            that -B has been used for a long while in Sun tar ans most
645            BSD-derived systems.  This is a consequence of the block/record
646            terminology confusion.  */
647
648         read_full_records_option = 1;
649         break;
650
651       case 'c':
652         set_subcommand_option (CREATE_SUBCOMMAND);
653         break;
654
655       case 'C':
656         name_add ("-C");
657         name_add (optarg);
658         break;
659
660       case 'd':
661         set_subcommand_option (DIFF_SUBCOMMAND);
662         break;
663
664       case 'f':
665         if (archive_names == allocated_archive_names)
666           {
667             allocated_archive_names *= 2;
668             archive_name_array =
669               xrealloc (archive_name_array,
670                         sizeof (const char *) * allocated_archive_names);
671           }
672         archive_name_array[archive_names++] = optarg;
673         break;
674
675       case 'F':
676         /* Since -F is only useful with -M, make it implied.  Run this
677            script at the end of each tape.  */
678
679         info_script_option = optarg;
680         multi_volume_option = 1;
681         break;
682
683       case 'g':
684         listed_incremental_option = optarg;
685         after_date_option = 1;
686         /* Fall through.  */
687
688       case 'G':
689         /* We are making an incremental dump (FIXME: are we?); save
690            directories at the beginning of the archive, and include in each
691            directory its contents.  */
692
693         incremental_option = 1;
694         break;
695
696       case 'h':
697         /* Follow symbolic links.  */
698
699         dereference_option = 1;
700         break;
701
702       case 'i':
703         /* Ignore zero blocks (eofs).  This can't be the default,
704            because Unix tar writes two blocks of zeros, then pads out
705            the record with garbage.  */
706
707         ignore_zeros_option = 1;
708         break;
709
710       case 'j':
711       case 'y':
712         set_use_compress_program_option ("bzip2");
713         break;
714
715       case 'k':
716         /* Don't replace existing files.  */
717         old_files_option = KEEP_OLD_FILES;
718         break;
719
720       case 'K':
721         starting_file_option = 1;
722         addname (optarg, 0);
723         break;
724
725       case 'l':
726         /* When dumping directories, don't dump files/subdirectories
727            that are on other filesystems.  */
728
729         one_file_system_option = 1;
730         break;
731
732       case 'L':
733         {
734           uintmax_t u;
735           if (xstrtoumax (optarg, 0, 10, &u, "") != LONGINT_OK)
736             USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (optarg),
737                           _("Invalid tape length")));
738           tape_length_option = 1024 * (tarlong) u;
739           multi_volume_option = 1;
740         }
741         break;
742
743       case OBSOLETE_TOUCH:
744         WARN ((0, 0, _("Obsolete option name replaced by --touch")));
745         /* Fall through.  */
746
747       case 'm':
748         touch_option = 1;
749         break;
750
751       case 'M':
752         /* Make multivolume archive: when we can't write any more into
753            the archive, re-open it, and continue writing.  */
754
755         multi_volume_option = 1;
756         break;
757
758       case 'n':
759         recursion_option = 0;
760         break;
761
762 #if !MSDOS
763       case 'N':
764         after_date_option = 1;
765         /* Fall through.  */
766
767       case NEWER_MTIME_OPTION:
768         if (newer_mtime_option != TYPE_MINIMUM (time_t))
769           USAGE_ERROR ((0, 0, _("More than one threshold date")));
770
771         if (FILESYSTEM_PREFIX_LEN (optarg) != 0
772             || ISSLASH (*optarg)
773             || *optarg == '.')
774           {
775             struct stat st;
776             if (deref_stat (dereference_option, optarg, &st) != 0)
777               {
778                 stat_error (optarg);
779                 USAGE_ERROR ((0, 0, _("Date file not found")));
780               }
781             newer_mtime_option = st.st_mtime;
782           }
783         else
784           {
785             newer_mtime_option = get_date (optarg, 0);
786             if (newer_mtime_option == (time_t) -1)
787               WARN ((0, 0, _("Substituting %s for unknown date format %s"),
788                      tartime (newer_mtime_option), quote (optarg)));
789           }
790
791         break;
792 #endif /* not MSDOS */
793
794       case 'o':
795         if (archive_format == DEFAULT_FORMAT)
796           archive_format = V7_FORMAT;
797         else if (archive_format != V7_FORMAT)
798           USAGE_ERROR ((0, 0, _("Conflicting archive format options")));
799         break;
800
801       case 'O':
802         to_stdout_option = 1;
803         break;
804
805       case 'p':
806         same_permissions_option = 1;
807         break;
808
809       case OBSOLETE_ABSOLUTE_NAMES:
810         WARN ((0, 0, _("Obsolete option name replaced by --absolute-names")));
811         /* Fall through.  */
812
813       case 'P':
814         absolute_names_option = 1;
815         break;
816
817       case 'r':
818         set_subcommand_option (APPEND_SUBCOMMAND);
819         break;
820
821       case OBSOLETE_BLOCK_NUMBER:
822         WARN ((0, 0, _("Obsolete option name replaced by --block-number")));
823         /* Fall through.  */
824
825       case 'R':
826         /* Print block numbers for debugging bad tar archives.  */
827
828         /* It would surely make sense to exchange -B and -R, but it seems
829            that -B has been used for a long while in Sun tar ans most
830            BSD-derived systems.  This is a consequence of the block/record
831            terminology confusion.  */
832
833         block_number_option = 1;
834         break;
835
836       case 's':
837         /* Names to extr are sorted.  */
838
839         same_order_option = 1;
840         break;
841
842       case 'S':
843         sparse_option = 1;
844         break;
845
846       case 't':
847         set_subcommand_option (LIST_SUBCOMMAND);
848         verbose_option++;
849         break;
850
851       case 'T':
852       case 'I':
853         files_from_option = optarg;
854         break;
855
856       case 'u':
857         set_subcommand_option (UPDATE_SUBCOMMAND);
858         break;
859
860       case 'U':
861         old_files_option = UNLINK_FIRST_OLD_FILES;
862         break;
863
864       case 'v':
865         verbose_option++;
866         break;
867
868       case 'V':
869         volume_label_option = optarg;
870         break;
871
872       case 'w':
873         interactive_option = 1;
874         break;
875
876       case 'W':
877         verify_option = 1;
878         break;
879
880       case 'x':
881         set_subcommand_option (EXTRACT_SUBCOMMAND);
882         break;
883
884       case 'X':
885         if (add_exclude_file (add_exclude, excluded, optarg,
886                               exclude_options | recursion_option, '\n')
887             != 0)
888           {
889             int e = errno;
890             FATAL_ERROR ((0, e, "%s", quotearg_colon (optarg)));
891           }
892         break;
893
894       case 'z':
895         set_use_compress_program_option ("gzip");
896         break;
897
898       case 'Z':
899         set_use_compress_program_option ("compress");
900         break;
901
902       case OBSOLETE_VERSION_CONTROL:
903         WARN ((0, 0, _("Obsolete option name replaced by --backup")));
904         /* Fall through.  */
905
906       case ANCHORED_OPTION:
907         exclude_options |= EXCLUDE_ANCHORED;
908         break;
909
910       case BACKUP_OPTION:
911         backup_option = 1;
912         if (optarg)
913           version_control_string = optarg;
914         break;
915
916       case DELETE_OPTION:
917         set_subcommand_option (DELETE_SUBCOMMAND);
918         break;
919
920       case EXCLUDE_OPTION:
921         add_exclude (excluded, optarg, exclude_options | recursion_option);
922         break;
923
924       case IGNORE_CASE_OPTION:
925         exclude_options |= FNM_CASEFOLD;
926         break;
927
928       case GROUP_OPTION:
929         if (! (strlen (optarg) < GNAME_FIELD_SIZE
930                && gname_to_gid (optarg, &group_option)))
931           {
932             uintmax_t g;
933             if (xstrtoumax (optarg, 0, 10, &g, "") == LONGINT_OK
934                 && g == (gid_t) g)
935               group_option = g;
936             else
937               FATAL_ERROR ((0, 0, "%s: %s", quotearg_colon (optarg),
938                             _("%s: Invalid group")));
939           }
940         break;
941
942       case MODE_OPTION:
943         mode_option
944           = mode_compile (optarg,
945                           MODE_MASK_EQUALS | MODE_MASK_PLUS | MODE_MASK_MINUS);
946         if (mode_option == MODE_INVALID)
947           FATAL_ERROR ((0, 0, _("Invalid mode given on option")));
948         if (mode_option == MODE_MEMORY_EXHAUSTED)
949           xalloc_die ();
950         break;
951
952       case NO_ANCHORED_OPTION:
953         exclude_options &= ~ EXCLUDE_ANCHORED;
954         break;
955
956       case NO_IGNORE_CASE_OPTION:
957         exclude_options &= ~ FNM_CASEFOLD;
958         break;
959
960       case NO_WILDCARDS_OPTION:
961         exclude_options &= ~ EXCLUDE_WILDCARDS;
962         break;
963
964       case NO_WILDCARDS_MATCH_SLASH_OPTION:
965         exclude_options |= FNM_FILE_NAME;
966         break;
967
968       case NULL_OPTION:
969         filename_terminator = '\0';
970         break;
971
972       case OVERWRITE_OPTION:
973         old_files_option = OVERWRITE_OLD_FILES;
974         break;
975
976       case OVERWRITE_DIR_OPTION:
977         old_files_option = OVERWRITE_OLD_DIRS;
978         break;
979
980       case OWNER_OPTION:
981         if (! (strlen (optarg) < UNAME_FIELD_SIZE
982                && uname_to_uid (optarg, &owner_option)))
983           {
984             uintmax_t u;
985             if (xstrtoumax (optarg, 0, 10, &u, "") == LONGINT_OK
986                 && u == (uid_t) u)
987               owner_option = u;
988             else
989               FATAL_ERROR ((0, 0, "%s: %s", quotearg_colon (optarg),
990                             _("Invalid owner")));
991           }
992         break;
993
994       case POSIX_OPTION:
995 #if OLDGNU_COMPATIBILITY
996         if (archive_format == DEFAULT_FORMAT)
997           archive_format = GNU_FORMAT;
998         else if (archive_format != GNU_FORMAT)
999           USAGE_ERROR ((0, 0, _("Conflicting archive format options")));
1000 #else
1001         if (archive_format == DEFAULT_FORMAT)
1002           archive_format = POSIX_FORMAT;
1003         else if (archive_format != POSIX_FORMAT)
1004           USAGE_ERROR ((0, 0, _("Conflicting archive format options")));
1005 #endif
1006         break;
1007
1008       case PRESERVE_OPTION:
1009         same_permissions_option = 1;
1010         same_order_option = 1;
1011         break;
1012
1013       case RECORD_SIZE_OPTION:
1014         {
1015           uintmax_t u;
1016           if (! (xstrtoumax (optarg, 0, 10, &u, "") == LONGINT_OK
1017                  && u == (size_t) u))
1018             USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (optarg),
1019                           _("Invalid record size")));
1020           record_size = u;
1021           if (record_size % BLOCKSIZE != 0)
1022             USAGE_ERROR ((0, 0, _("Record size must be a multiple of %d."),
1023                           BLOCKSIZE));
1024           blocking_factor = record_size / BLOCKSIZE;
1025         }
1026         break;
1027
1028       case RSH_COMMAND_OPTION:
1029         rsh_command_option = optarg;
1030         break;
1031
1032       case SUFFIX_OPTION:
1033         backup_option = 1;
1034         backup_suffix_string = optarg;
1035         break;
1036
1037       case USE_COMPRESS_PROGRAM_OPTION:
1038         set_use_compress_program_option (optarg);
1039         break;
1040
1041       case VOLNO_FILE_OPTION:
1042         volno_file_option = optarg;
1043         break;
1044
1045       case WILDCARDS_OPTION:
1046         exclude_options |= EXCLUDE_WILDCARDS;
1047         break;
1048
1049       case WILDCARDS_MATCH_SLASH_OPTION:
1050         exclude_options &= ~ FNM_FILE_NAME;
1051         break;
1052
1053       case '0':
1054       case '1':
1055       case '2':
1056       case '3':
1057       case '4':
1058       case '5':
1059       case '6':
1060       case '7':
1061
1062 #ifdef DEVICE_PREFIX
1063         {
1064           int device = optchar - '0';
1065           int density;
1066           static char buf[sizeof DEVICE_PREFIX + 10];
1067           char *cursor;
1068
1069           density = getopt_long (argc, argv, "lmh", 0, 0);
1070           strcpy (buf, DEVICE_PREFIX);
1071           cursor = buf + strlen (buf);
1072
1073 #ifdef DENSITY_LETTER
1074
1075           sprintf (cursor, "%d%c", device, density);
1076
1077 #else /* not DENSITY_LETTER */
1078
1079           switch (density)
1080             {
1081             case 'l':
1082 #ifdef LOW_NUM
1083               device += LOW_NUM;
1084 #endif
1085               break;
1086
1087             case 'm':
1088 #ifdef MID_NUM
1089               device += MID_NUM;
1090 #else
1091               device += 8;
1092 #endif
1093               break;
1094
1095             case 'h':
1096 #ifdef HGH_NUM
1097               device += HGH_NUM;
1098 #else
1099               device += 16;
1100 #endif
1101               break;
1102
1103             default:
1104               usage (TAREXIT_FAILURE);
1105             }
1106           sprintf (cursor, "%d", device);
1107
1108 #endif /* not DENSITY_LETTER */
1109
1110           if (archive_names == allocated_archive_names)
1111             {
1112               allocated_archive_names *= 2;
1113               archive_name_array =
1114                 xrealloc (archive_name_array,
1115                           sizeof (const char *) * allocated_archive_names);
1116             }
1117           archive_name_array[archive_names++] = buf;
1118
1119           /* FIXME: How comes this works for many archives when buf is
1120              not xstrdup'ed?  */
1121         }
1122         break;
1123
1124 #else /* not DEVICE_PREFIX */
1125
1126         USAGE_ERROR ((0, 0,
1127                       _("Options `-[0-7][lmh]' not supported by *this* tar")));
1128
1129 #endif /* not DEVICE_PREFIX */
1130       }
1131
1132   /* Handle operands after any "--" argument.  */
1133   for (; optind < argc; optind++)
1134     {
1135       name_add (argv[optind]);
1136       input_files++;
1137     }
1138
1139   /* Process trivial options.  */
1140
1141   if (show_version)
1142     {
1143       printf ("tar (GNU %s) %s\n", PACKAGE, VERSION);
1144       print_copyright ("2001 Free Software Foundation, Inc.");
1145       puts (_("\
1146 This program comes with NO WARRANTY, to the extent permitted by law.\n\
1147 You may redistribute it under the terms of the GNU General Public License;\n\
1148 see the file named COPYING for details."));
1149
1150       puts (_("Written by John Gilmore and Jay Fenlason."));
1151
1152       exit (TAREXIT_SUCCESS);
1153     }
1154
1155   if (show_help)
1156     usage (TAREXIT_SUCCESS);
1157
1158   /* Derive option values and check option consistency.  */
1159
1160   if (archive_format == DEFAULT_FORMAT)
1161     {
1162 #if OLDGNU_COMPATIBILITY
1163       archive_format = OLDGNU_FORMAT;
1164 #else
1165       archive_format = GNU_FORMAT;
1166 #endif
1167     }
1168
1169   if (archive_format == GNU_FORMAT && getenv ("POSIXLY_CORRECT"))
1170     archive_format = POSIX_FORMAT;
1171
1172   if ((volume_label_option
1173        || incremental_option || multi_volume_option || sparse_option)
1174       && archive_format != OLDGNU_FORMAT && archive_format != GNU_FORMAT)
1175     USAGE_ERROR ((0, 0,
1176                   _("GNU features wanted on incompatible archive format")));
1177
1178   if (archive_names == 0)
1179     {
1180       /* If no archive file name given, try TAPE from the environment, or
1181          else, DEFAULT_ARCHIVE from the configuration process.  */
1182
1183       archive_names = 1;
1184       archive_name_array[0] = getenv ("TAPE");
1185       if (! archive_name_array[0])
1186         archive_name_array[0] = DEFAULT_ARCHIVE;
1187     }
1188
1189   /* Allow multiple archives only with `-M'.  */
1190
1191   if (archive_names > 1 && !multi_volume_option)
1192     USAGE_ERROR ((0, 0,
1193                   _("Multiple archive files requires `-M' option")));
1194
1195   if (listed_incremental_option
1196       && newer_mtime_option != TYPE_MINIMUM (time_t))
1197     USAGE_ERROR ((0, 0,
1198                   _("Cannot combine --listed-incremental with --newer")));
1199
1200   if (volume_label_option)
1201     {
1202       size_t volume_label_max_len =
1203         (sizeof current_header->header.name
1204          - 1 /* for trailing '\0' */
1205          - (multi_volume_option
1206             ? (sizeof " Volume "
1207                - 1 /* for null at end of " Volume " */
1208                + INT_STRLEN_BOUND (int) /* for volume number */
1209                - 1 /* for sign, as 0 <= volno */)
1210             : 0));
1211       if (volume_label_max_len < strlen (volume_label_option))
1212         USAGE_ERROR ((0, 0,
1213                       _("%s: Volume label is too long (limit is %lu bytes)"),
1214                       quotearg_colon (volume_label_option),
1215                       (unsigned long) volume_label_max_len));
1216     }
1217
1218   /* If ready to unlink hierarchies, so we are for simpler files.  */
1219   if (recursive_unlink_option)
1220     old_files_option = UNLINK_FIRST_OLD_FILES;
1221
1222   /* Forbid using -c with no input files whatsoever.  Check that `-f -',
1223      explicit or implied, is used correctly.  */
1224
1225   switch (subcommand_option)
1226     {
1227     case CREATE_SUBCOMMAND:
1228       if (input_files == 0 && !files_from_option)
1229         USAGE_ERROR ((0, 0,
1230                       _("Cowardly refusing to create an empty archive")));
1231       break;
1232
1233     case EXTRACT_SUBCOMMAND:
1234     case LIST_SUBCOMMAND:
1235     case DIFF_SUBCOMMAND:
1236       for (archive_name_cursor = archive_name_array;
1237            archive_name_cursor < archive_name_array + archive_names;
1238            archive_name_cursor++)
1239         if (!strcmp (*archive_name_cursor, "-"))
1240           request_stdin ("-f");
1241       break;
1242
1243     case CAT_SUBCOMMAND:
1244     case UPDATE_SUBCOMMAND:
1245     case APPEND_SUBCOMMAND:
1246       for (archive_name_cursor = archive_name_array;
1247            archive_name_cursor < archive_name_array + archive_names;
1248            archive_name_cursor++)
1249         if (!strcmp (*archive_name_cursor, "-"))
1250           USAGE_ERROR ((0, 0,
1251                         _("Options `-Aru' are incompatible with `-f -'")));
1252
1253     default:
1254       break;
1255     }
1256
1257   archive_name_cursor = archive_name_array;
1258
1259   /* Prepare for generating backup names.  */
1260
1261   if (backup_suffix_string)
1262     simple_backup_suffix = xstrdup (backup_suffix_string);
1263
1264   if (backup_option)
1265     backup_type = xget_version ("--backup", version_control_string);
1266 }
1267 \f
1268 /* Tar proper.  */
1269
1270 /* Main routine for tar.  */
1271 int
1272 main (int argc, char **argv)
1273 {
1274 #if HAVE_CLOCK_GETTIME
1275   if (clock_gettime (CLOCK_REALTIME, &start_timespec) != 0)
1276 #endif
1277     start_time = time (0);
1278   program_name = argv[0];
1279   (void) setlocale (LC_ALL, "");
1280   bindtextdomain (PACKAGE, LOCALEDIR);
1281   textdomain (PACKAGE);
1282
1283   exit_status = TAREXIT_SUCCESS;
1284   filename_terminator = '\n';
1285   set_quoting_style (0, escape_quoting_style);
1286
1287   /* Pre-allocate a few structures.  */
1288
1289   allocated_archive_names = 10;
1290   archive_name_array =
1291     xmalloc (sizeof (const char *) * allocated_archive_names);
1292   archive_names = 0;
1293
1294 #ifdef SIGCHLD
1295   /* System V fork+wait does not work if SIGCHLD is ignored.  */
1296   signal (SIGCHLD, SIG_DFL);
1297 #endif
1298
1299   init_names ();
1300
1301   /* Decode options.  */
1302
1303   decode_options (argc, argv);
1304   name_init (argc, argv);
1305
1306   /* Main command execution.  */
1307
1308   if (volno_file_option)
1309     init_volume_number ();
1310
1311   switch (subcommand_option)
1312     {
1313     case UNKNOWN_SUBCOMMAND:
1314       USAGE_ERROR ((0, 0,
1315                     _("You must specify one of the `-Acdtrux' options")));
1316
1317     case CAT_SUBCOMMAND:
1318     case UPDATE_SUBCOMMAND:
1319     case APPEND_SUBCOMMAND:
1320       update_archive ();
1321       break;
1322
1323     case DELETE_SUBCOMMAND:
1324       delete_archive_members ();
1325       break;
1326
1327     case CREATE_SUBCOMMAND:
1328       create_archive ();
1329       name_close ();
1330
1331       if (totals_option)
1332         print_total_written ();
1333       break;
1334
1335     case EXTRACT_SUBCOMMAND:
1336       extr_init ();
1337       read_and (extract_archive);
1338       extract_finish ();
1339       break;
1340
1341     case LIST_SUBCOMMAND:
1342       read_and (list_archive);
1343       break;
1344
1345     case DIFF_SUBCOMMAND:
1346       diff_init ();
1347       read_and (diff_archive);
1348       break;
1349     }
1350
1351   if (volno_file_option)
1352     closeout_volume_number ();
1353
1354   /* Dispose of allocated memory, and return.  */
1355
1356   free (archive_name_array);
1357   name_term ();
1358
1359   if (stdlis == stdout && (ferror (stdout) || fclose (stdout) != 0))
1360     FATAL_ERROR ((0, 0, _("Error in writing to standard output")));
1361   if (exit_status == TAREXIT_FAILURE)
1362     error (0, 0, _("Error exit delayed from previous errors"));
1363   exit (exit_status);
1364 }