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