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