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