Removed accumulator stuff in favor of obstack.
[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-OR-FILE     only store files newer than DATE-OR-FILE\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 (volume_label_option && subcommand_option == CREATE_SUBCOMMAND)
1279     assert_format (FORMAT_MASK (OLDGNU_FORMAT)
1280                    | FORMAT_MASK (GNU_FORMAT));
1281
1282   if (incremental_option
1283       || multi_volume_option
1284       || sparse_option)
1285     assert_format (FORMAT_MASK (OLDGNU_FORMAT)
1286                    | FORMAT_MASK (GNU_FORMAT)
1287                    | FORMAT_MASK (POSIX_FORMAT));
1288   
1289   if (occurrence_option)
1290     {
1291       if (!input_files && !files_from_option)
1292         USAGE_ERROR ((0, 0,
1293                       _("--occurrence is meaningless without file list")));
1294       if (subcommand_option != DELETE_SUBCOMMAND
1295           && subcommand_option != DIFF_SUBCOMMAND
1296           && subcommand_option != EXTRACT_SUBCOMMAND
1297           && subcommand_option != LIST_SUBCOMMAND)
1298             USAGE_ERROR ((0, 0,
1299                           _("--occurrence cannot be used in the requested operation mode")));
1300     }
1301   
1302   if (archive_names == 0)
1303     {
1304       /* If no archive file name given, try TAPE from the environment, or
1305          else, DEFAULT_ARCHIVE from the configuration process.  */
1306
1307       archive_names = 1;
1308       archive_name_array[0] = getenv ("TAPE");
1309       if (! archive_name_array[0])
1310         archive_name_array[0] = DEFAULT_ARCHIVE;
1311     }
1312
1313   /* Allow multiple archives only with `-M'.  */
1314
1315   if (archive_names > 1 && !multi_volume_option)
1316     USAGE_ERROR ((0, 0,
1317                   _("Multiple archive files require `-M' option")));
1318
1319   if (listed_incremental_option
1320       && newer_mtime_option != TYPE_MINIMUM (time_t))
1321     USAGE_ERROR ((0, 0,
1322                   _("Cannot combine --listed-incremental with --newer")));
1323
1324   if (volume_label_option)
1325     {
1326       size_t volume_label_max_len =
1327         (sizeof current_header->header.name
1328          - 1 /* for trailing '\0' */
1329          - (multi_volume_option
1330             ? (sizeof " Volume "
1331                - 1 /* for null at end of " Volume " */
1332                + INT_STRLEN_BOUND (int) /* for volume number */
1333                - 1 /* for sign, as 0 <= volno */)
1334             : 0));
1335       if (volume_label_max_len < strlen (volume_label_option))
1336         USAGE_ERROR ((0, 0,
1337                       ngettext ("%s: Volume label is too long (limit is %lu byte)",
1338                                 "%s: Volume label is too long (limit is %lu bytes)",
1339                                 volume_label_max_len),
1340                       quotearg_colon (volume_label_option),
1341                       (unsigned long) volume_label_max_len));
1342     }
1343
1344   if (verify_option)
1345     {
1346       if (multi_volume_option)
1347         USAGE_ERROR ((0, 0, _("Cannot verify multi-volume archives")));
1348       if (use_compress_program_option)
1349         USAGE_ERROR ((0, 0, _("Cannot verify compressed archives")));
1350     }
1351
1352   if (use_compress_program_option)
1353     {
1354       if (multi_volume_option)
1355         USAGE_ERROR ((0, 0, _("Cannot use multi-volume compressed archives")));
1356       if (subcommand_option == UPDATE_SUBCOMMAND)
1357         USAGE_ERROR ((0, 0, _("Cannot update compressed archives")));
1358     }
1359   
1360   /* If ready to unlink hierarchies, so we are for simpler files.  */
1361   if (recursive_unlink_option)
1362     old_files_option = UNLINK_FIRST_OLD_FILES;
1363
1364   /* Forbid using -c with no input files whatsoever.  Check that `-f -',
1365      explicit or implied, is used correctly.  */
1366
1367   switch (subcommand_option)
1368     {
1369     case CREATE_SUBCOMMAND:
1370       if (input_files == 0 && !files_from_option)
1371         USAGE_ERROR ((0, 0,
1372                       _("Cowardly refusing to create an empty archive")));
1373       break;
1374
1375     case EXTRACT_SUBCOMMAND:
1376     case LIST_SUBCOMMAND:
1377     case DIFF_SUBCOMMAND:
1378       for (archive_name_cursor = archive_name_array;
1379            archive_name_cursor < archive_name_array + archive_names;
1380            archive_name_cursor++)
1381         if (!strcmp (*archive_name_cursor, "-"))
1382           request_stdin ("-f");
1383       break;
1384
1385     case CAT_SUBCOMMAND:
1386     case UPDATE_SUBCOMMAND:
1387     case APPEND_SUBCOMMAND:
1388       for (archive_name_cursor = archive_name_array;
1389            archive_name_cursor < archive_name_array + archive_names;
1390            archive_name_cursor++)
1391         if (!strcmp (*archive_name_cursor, "-"))
1392           USAGE_ERROR ((0, 0,
1393                         _("Options `-Aru' are incompatible with `-f -'")));
1394
1395     default:
1396       break;
1397     }
1398
1399   archive_name_cursor = archive_name_array;
1400
1401   /* Prepare for generating backup names.  */
1402
1403   if (backup_suffix_string)
1404     simple_backup_suffix = xstrdup (backup_suffix_string);
1405
1406   if (backup_option)
1407     backup_type = xget_version ("--backup", version_control_string);
1408
1409   if (verbose_option && textual_date_option)
1410     {
1411       char const *treated_as = tartime (newer_mtime_option);
1412       if (strcmp (textual_date_option, treated_as) != 0)
1413         WARN ((0, 0, _("Treating date `%s' as %s"),
1414                textual_date_option, treated_as));
1415     }
1416 }
1417
1418 \f
1419 /* Tar proper.  */
1420
1421 /* Main routine for tar.  */
1422 int
1423 main (int argc, char **argv)
1424 {
1425 #if HAVE_CLOCK_GETTIME
1426   if (clock_gettime (CLOCK_REALTIME, &start_timespec) != 0)
1427 #endif
1428     start_time = time (0);
1429   program_name = argv[0];
1430   setlocale (LC_ALL, "");
1431   bindtextdomain (PACKAGE, LOCALEDIR);
1432   textdomain (PACKAGE);
1433
1434   exit_status = TAREXIT_SUCCESS;
1435   filename_terminator = '\n';
1436   set_quoting_style (0, escape_quoting_style);
1437
1438   /* Pre-allocate a few structures.  */
1439
1440   allocated_archive_names = 10;
1441   archive_name_array =
1442     xmalloc (sizeof (const char *) * allocated_archive_names);
1443   archive_names = 0;
1444
1445 #ifdef SIGCHLD
1446   /* System V fork+wait does not work if SIGCHLD is ignored.  */
1447   signal (SIGCHLD, SIG_DFL);
1448 #endif
1449
1450   init_names ();
1451
1452   /* Decode options.  */
1453
1454   decode_options (argc, argv);
1455   name_init (argc, argv);
1456
1457   /* Main command execution.  */
1458
1459   if (volno_file_option)
1460     init_volume_number ();
1461
1462   switch (subcommand_option)
1463     {
1464     case UNKNOWN_SUBCOMMAND:
1465       USAGE_ERROR ((0, 0,
1466                     _("You must specify one of the `-Acdtrux' options")));
1467
1468     case CAT_SUBCOMMAND:
1469     case UPDATE_SUBCOMMAND:
1470     case APPEND_SUBCOMMAND:
1471       update_archive ();
1472       break;
1473
1474     case DELETE_SUBCOMMAND:
1475       delete_archive_members ();
1476       break;
1477
1478     case CREATE_SUBCOMMAND:
1479       create_archive ();
1480       name_close ();
1481
1482       if (totals_option)
1483         print_total_written ();
1484       break;
1485
1486     case EXTRACT_SUBCOMMAND:
1487       extr_init ();
1488       read_and (extract_archive);
1489
1490       /* FIXME: should extract_finish () even if an ordinary signal is
1491          received.  */
1492       extract_finish ();
1493
1494       break;
1495
1496     case LIST_SUBCOMMAND:
1497       read_and (list_archive);
1498       break;
1499
1500     case DIFF_SUBCOMMAND:
1501       diff_init ();
1502       read_and (diff_archive);
1503       break;
1504     }
1505
1506   if (check_links_option)
1507       check_links ();
1508
1509   if (volno_file_option)
1510     closeout_volume_number ();
1511
1512   /* Dispose of allocated memory, and return.  */
1513
1514   free (archive_name_array);
1515   name_term ();
1516
1517   if (stdlis != stderr && (ferror (stdlis) || fclose (stdlis) != 0))
1518     FATAL_ERROR ((0, 0, _("Error in writing to standard output")));
1519   if (exit_status == TAREXIT_FAILURE)
1520     error (0, 0, _("Error exit delayed from previous errors"));
1521   if (ferror (stderr) || fclose (stderr) != 0)
1522     exit_status = TAREXIT_FAILURE;
1523   return exit_status;
1524 }
1525
1526 void
1527 tar_stat_init (struct tar_stat_info *st)
1528 {
1529   memset (st, 0, sizeof (*st));
1530 }
1531      
1532 void
1533 tar_stat_destroy (struct tar_stat_info *st)
1534 {
1535   free (st->orig_file_name);
1536   free (st->file_name);
1537   free (st->link_name);
1538   free (st->uname);
1539   free (st->gname);
1540   free (st->sparse_map);
1541   memset (st, 0, sizeof (*st));
1542 }
1543