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