]> git.gag.com Git - debian/tar/blob - src/tar.c
35d8dd8c793c7cdc4095f3fd697f5066ba2b83ef
[debian/tar] / src / tar.c
1 /* A tar (tape archiver) program.
2    Copyright (C) 1988, 92,93,94,95,96,97, 1999 Free Software Foundation, Inc.
3    Written by John Gilmore, starting 1985-08-25.
4
5    This program is free software; you can redistribute it and/or modify it
6    under the terms of the GNU General Public License as published by the
7    Free Software Foundation; either version 2, or (at your option) any later
8    version.
9
10    This program is distributed in the hope that it will be useful, but
11    WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
13    Public License for more details.
14
15    You should have received a copy of the GNU General Public License along
16    with this program; if not, write to the Free Software Foundation, Inc.,
17    59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
18
19 #include "system.h"
20
21 #include <getopt.h>
22
23 /* The following causes "common.h" to produce definitions of all the global
24    variables, rather than just "extern" declarations of them.  GNU tar does
25    depend on the system loader to preset all GLOBAL variables to neutral (or
26    zero) values, explicit initialisation is usually not done.  */
27 #define GLOBAL
28 #include "common.h"
29
30 #include "xstrtol.h"
31
32 time_t get_date ();
33
34 /* Local declarations.  */
35
36 #ifndef DEFAULT_ARCHIVE
37 # define DEFAULT_ARCHIVE "tar.out"
38 #endif
39
40 #ifndef DEFAULT_BLOCKING
41 # define DEFAULT_BLOCKING 20
42 #endif
43
44 static void usage PARAMS ((int));
45 \f
46 /* Miscellaneous.  */
47
48 /*----------------------------------------------.
49 | Doesn't return if stdin already requested.    |
50 `----------------------------------------------*/
51
52 /* Name of option using stdin.  */
53 static const char *stdin_used_by = NULL;
54
55 void
56 request_stdin (const char *option)
57 {
58   if (stdin_used_by)
59     USAGE_ERROR ((0, 0, _("Options `-%s' and `-%s' both want standard input"),
60                   stdin_used_by, option));
61
62   stdin_used_by = option;
63 }
64
65 /*--------------------------------------------------------.
66 | Returns true if and only if the user typed 'y' or 'Y'.  |
67 `--------------------------------------------------------*/
68
69 int
70 confirm (const char *message_action, const char *message_name)
71 {
72   static FILE *confirm_file = NULL;
73
74   if (!confirm_file)
75     {
76       if (archive == 0 || stdin_used_by)
77         confirm_file = fopen (TTY_NAME, "r");
78       else
79         {
80           request_stdin ("-w");
81           confirm_file = stdin;
82         }
83
84       if (!confirm_file)
85         FATAL_ERROR ((0, 0, _("Cannot read confirmation from user")));
86     }
87
88   fprintf (stdlis, "%s %s?", message_action, message_name);
89   fflush (stdlis);
90
91   {
92     int reply = getc (confirm_file);
93     int character;
94
95     for (character = reply;
96          character != '\n' && character != EOF;
97          character = getc (confirm_file))
98       continue;
99     return reply == 'y' || reply == 'Y';
100   }
101 }
102 \f
103 /* Options.  */
104
105 /* For long options that unconditionally set a single flag, we have getopt
106    do it.  For the others, we share the code for the equivalent short
107    named option, the name of which is stored in the otherwise-unused `val'
108    field of the `struct option'; for long options that have no equivalent
109    short option, we use nongraphic characters as pseudo short option
110    characters, starting at 2 and going upwards.  */
111
112 #define BACKUP_OPTION                   2
113 #define DELETE_OPTION                   3
114 #define EXCLUDE_OPTION                  4
115 #define GROUP_OPTION                    5
116 #define MODE_OPTION                     6
117 #define NEWER_MTIME_OPTION              7
118 #define NO_RECURSE_OPTION               8
119 #define NULL_OPTION                     9
120 #define OWNER_OPTION                    10
121 #define POSIX_OPTION                    11
122 #define PRESERVE_OPTION                 12
123 #define RECORD_SIZE_OPTION              13
124 #define RSH_COMMAND_OPTION              14
125 #define SUFFIX_OPTION                   15
126 #define USE_COMPRESS_PROGRAM_OPTION     16
127 #define VOLNO_FILE_OPTION               17
128
129 /* Some cleanup is being made in GNU tar long options.  Using old names is
130    allowed for a while, but will also send a warning to stderr.  Take old
131    names out in 1.14, or in summer 1997, whichever happens last.  We use
132    nongraphic characters as pseudo short option characters, starting at 31
133    and going downwards.  */
134
135 #define OBSOLETE_ABSOLUTE_NAMES         31
136 #define OBSOLETE_BLOCK_COMPRESS         30
137 #define OBSOLETE_BLOCKING_FACTOR        29
138 #define OBSOLETE_BLOCK_NUMBER           28
139 #define OBSOLETE_READ_FULL_RECORDS      27
140 #define OBSOLETE_TOUCH                  26
141 #define OBSOLETE_VERSION_CONTROL        25
142
143 /* If nonzero, display usage information and exit.  */
144 static int show_help = 0;
145
146 /* If nonzero, print the version on standard output and exit.  */
147 static int show_version = 0;
148
149 struct option long_options[] =
150 {
151   {"absolute-names", no_argument, NULL, 'P'},
152   {"absolute-paths", no_argument, NULL, OBSOLETE_ABSOLUTE_NAMES},
153   {"after-date", required_argument, NULL, 'N'},
154   {"append", no_argument, NULL, 'r'},
155   {"atime-preserve", no_argument, &atime_preserve_option, 1},
156   {"backup", optional_argument, NULL, BACKUP_OPTION},
157   {"block-compress", no_argument, NULL, OBSOLETE_BLOCK_COMPRESS},
158   {"block-number", no_argument, NULL, 'R'},
159   {"block-size", required_argument, NULL, OBSOLETE_BLOCKING_FACTOR},
160   {"blocking-factor", required_argument, NULL, 'b'},
161   {"catenate", no_argument, NULL, 'A'},
162   {"checkpoint", no_argument, &checkpoint_option, 1},
163   {"compare", no_argument, NULL, 'd'},
164   {"compress", no_argument, NULL, 'Z'},
165   {"concatenate", no_argument, NULL, 'A'},
166   {"confirmation", no_argument, NULL, 'w'},
167   /* FIXME: --selective as a synonym for --confirmation?  */
168   {"create", no_argument, NULL, 'c'},
169   {"delete", no_argument, NULL, DELETE_OPTION},
170   {"dereference", no_argument, NULL, 'h'},
171   {"diff", no_argument, NULL, 'd'},
172   {"directory", required_argument, NULL, 'C'},
173   {"ending-file", required_argument, NULL, 'E'},
174   {"exclude", required_argument, NULL, EXCLUDE_OPTION},
175   {"exclude-from", required_argument, NULL, 'X'},
176   {"extract", no_argument, NULL, 'x'},
177   {"file", required_argument, NULL, 'f'},
178   {"files-from", required_argument, NULL, 'T'},
179   {"force-local", no_argument, &force_local_option, 1},
180   {"get", no_argument, NULL, 'x'},
181   {"group", required_argument, NULL, GROUP_OPTION},
182   {"gunzip", no_argument, NULL, 'z'},
183   {"gzip", no_argument, NULL, 'z'},
184   {"help", no_argument, &show_help, 1},
185   {"ignore-failed-read", no_argument, &ignore_failed_read_option, 1},
186   {"ignore-zeros", no_argument, NULL, 'i'},
187   /* FIXME: --ignore-end as a new name for --ignore-zeros?  */
188   {"incremental", no_argument, NULL, 'G'},
189   {"info-script", required_argument, NULL, 'F'},
190   {"interactive", no_argument, NULL, 'w'},
191   {"keep-old-files", no_argument, NULL, 'k'},
192   {"label", required_argument, NULL, 'V'},
193   {"list", no_argument, NULL, 't'},
194   {"listed-incremental", required_argument, NULL, 'g'},
195   {"mode", required_argument, NULL, MODE_OPTION},
196   {"modification-time", no_argument, NULL, OBSOLETE_TOUCH},
197   {"multi-volume", no_argument, NULL, 'M'},
198   {"new-volume-script", required_argument, NULL, 'F'},
199   {"newer", required_argument, NULL, 'N'},
200   {"newer-mtime", required_argument, NULL, NEWER_MTIME_OPTION},
201   {"null", no_argument, NULL, NULL_OPTION},
202   {"no-recursion", no_argument, NULL, NO_RECURSE_OPTION},
203   {"numeric-owner", no_argument, &numeric_owner_option, 1},
204   {"old-archive", no_argument, NULL, 'o'},
205   {"one-file-system", no_argument, NULL, 'l'},
206   {"owner", required_argument, NULL, OWNER_OPTION},
207   {"portability", no_argument, NULL, 'o'},
208   {"posix", no_argument, NULL, POSIX_OPTION},
209   {"preserve", no_argument, NULL, PRESERVE_OPTION},
210   {"preserve-order", no_argument, NULL, 's'},
211   {"preserve-permissions", no_argument, NULL, 'p'},
212   {"recursive-unlink", no_argument, &recursive_unlink_option, 1},
213   {"read-full-blocks", no_argument, NULL, OBSOLETE_READ_FULL_RECORDS},
214   {"read-full-records", no_argument, NULL, 'B'},
215   /* FIXME: --partial-blocks might be a synonym for --read-full-records?  */
216   {"record-number", no_argument, NULL, OBSOLETE_BLOCK_NUMBER},
217   {"record-size", required_argument, NULL, RECORD_SIZE_OPTION},
218   {"remove-files", no_argument, &remove_files_option, 1},
219   {"rsh-command", required_argument, NULL, RSH_COMMAND_OPTION},
220   {"same-order", no_argument, NULL, 's'},
221   {"same-owner", no_argument, &same_owner_option, 1},
222   {"same-permissions", no_argument, NULL, 'p'},
223   {"show-omitted-dirs", no_argument, &show_omitted_dirs_option, 1},
224   {"sparse", no_argument, NULL, 'S'},
225   {"starting-file", required_argument, NULL, 'K'},
226   {"suffix", required_argument, NULL, SUFFIX_OPTION},
227   {"tape-length", required_argument, NULL, 'L'},
228   {"to-stdout", no_argument, NULL, 'O'},
229   {"totals", no_argument, &totals_option, 1},
230   {"touch", no_argument, NULL, 'm'},
231   {"uncompress", no_argument, NULL, 'Z'},
232   {"ungzip", no_argument, NULL, 'z'},
233   {"unlink-first", no_argument, NULL, 'U'},
234   {"update", no_argument, NULL, 'u'},
235   {"use-compress-program", required_argument, NULL, USE_COMPRESS_PROGRAM_OPTION},
236   {"verbose", no_argument, NULL, 'v'},
237   {"verify", no_argument, NULL, 'W'},
238   {"version", no_argument, &show_version, 1},
239   {"version-control", required_argument, NULL, OBSOLETE_VERSION_CONTROL},
240   {"volno-file", required_argument, NULL, VOLNO_FILE_OPTION},
241
242   {0, 0, 0, 0}
243 };
244
245 /*---------------------------------------------.
246 | Print a usage message and exit with STATUS.  |
247 `---------------------------------------------*/
248
249 static void
250 usage (int status)
251 {
252   if (status != TAREXIT_SUCCESS)
253     fprintf (stderr, _("Try `%s --help' for more information.\n"),
254              program_name);
255   else
256     {
257       fputs (_("\
258 GNU `tar' saves many files together into a single tape or disk archive, and\n\
259 can restore individual files from the archive.\n"),
260              stdout);
261       printf (_("\nUsage: %s [OPTION]... [FILE]...\n"), program_name);
262       fputs (_("\
263 \n\
264 If a long option shows an argument as mandatory, then it is mandatory\n\
265 for the equivalent short option also.  Similarly for optional arguments.\n"),
266              stdout);
267       fputs(_("\
268 \n\
269 Main operation mode:\n\
270   -t, --list              list the contents of an archive\n\
271   -x, --extract, --get    extract files from an archive\n\
272   -c, --create            create a new archive\n\
273   -d, --diff, --compare   find differences between archive and file system\n\
274   -r, --append            append files to the end of an archive\n\
275   -u, --update            only append files newer than copy in archive\n\
276   -A, --catenate          append tar files to an archive\n\
277       --concatenate       same as -A\n\
278       --delete            delete from the archive (not on mag tapes!)\n"),
279             stdout);
280       fputs (_("\
281 \n\
282 Operation modifiers:\n\
283   -W, --verify               attempt to verify the archive after writing it\n\
284       --remove-files         remove files after adding them to the archive\n\
285   -k, --keep-old-files       don't overwrite existing files when extracting\n\
286   -U, --unlink-first         remove each file prior to extracting over it\n\
287       --recursive-unlink     empty hierarchies prior to extracting directory\n\
288   -S, --sparse               handle sparse files efficiently\n\
289   -O, --to-stdout            extract files to standard output\n\
290   -G, --incremental          handle old GNU-format incremental backup\n\
291   -g, --listed-incremental   handle new GNU-format incremental backup\n\
292       --ignore-failed-read   do not exit with nonzero on unreadable files\n"),
293              stdout);
294       fputs (_("\
295 \n\
296 Handling of file attributes:\n\
297       --owner=NAME             force NAME as owner for added files\n\
298       --group=NAME             force NAME as group for added files\n\
299       --mode=CHANGES           force (symbolic) mode CHANGES for added files\n\
300       --atime-preserve         don't change access times on dumped files\n\
301   -m, --modification-time      don't extract file modified time\n\
302       --same-owner             try extracting files with the same ownership\n\
303       --numeric-owner          always use numbers for user/group names\n\
304   -p, --same-permissions       extract all protection information\n\
305       --preserve-permissions   same as -p\n\
306   -s, --same-order             sort names to extract to match archive\n\
307       --preserve-order         same as -s\n\
308       --preserve               same as both -p and -s\n"),
309              stdout);
310       fputs (_("\
311 \n\
312 Device selection and switching:\n\
313   -f, --file=ARCHIVE             use archive file or device ARCHIVE\n\
314       --force-local              archive file is local even if has a colon\n\
315       --rsh-command=COMMAND      use remote COMMAND instead of rsh\n\
316   -[0-7][lmh]                    specify drive and density\n\
317   -M, --multi-volume             create/list/extract multi-volume archive\n\
318   -L, --tape-length=NUM          change tape after writing NUM x 1024 bytes\n\
319   -F, --info-script=FILE         run script at end of each tape (implies -M)\n\
320       --new-volume-script=FILE   same as -F FILE\n\
321       --volno-file=FILE          use/update the volume number in FILE\n"),
322              stdout);
323       fputs (_("\
324 \n\
325 Device blocking:\n\
326   -b, --blocking-factor=BLOCKS   BLOCKS x 512 bytes per record\n\
327       --record-size=SIZE         SIZE bytes per record, multiple of 512\n\
328   -i, --ignore-zeros             ignore zeroed blocks in archive (means EOF)\n\
329   -B, --read-full-records        reblock as we read (for 4.2BSD pipes)\n"),
330              stdout);
331       fputs (_("\
332 \n\
333 Archive format selection:\n\
334   -V, --label=NAME                   create archive with volume name NAME\n\
335               PATTERN                at list/extract time, a globbing PATTERN\n\
336   -o, --old-archive, --portability   write a V7 format archive\n\
337       --posix                        write a POSIX conformant archive\n\
338   -z, --gzip, --ungzip               filter the archive through gzip\n\
339   -Z, --compress, --uncompress       filter the archive through compress\n\
340       --use-compress-program=PROG    filter through PROG (must accept -d)\n"),
341              stdout);
342       fputs (_("\
343 \n\
344 Local file selection:\n\
345   -C, --directory=DIR          change to directory DIR\n\
346   -T, --files-from=NAME        get names to extract or create from file NAME\n\
347       --null                   -T reads null-terminated names, disable -C\n\
348       --exclude=PATTERN        exclude files, given as a globbing PATTERN\n\
349   -X, --exclude-from=FILE      exclude globbing patterns listed in FILE\n\
350   -P, --absolute-names         don't strip leading `/'s from file names\n\
351   -h, --dereference            dump instead the files symlinks point to\n\
352       --no-recursion           avoid descending automatically in directories\n\
353   -l, --one-file-system        stay in local file system when creating archive\n\
354   -E, --ending-file=NAME       end reading the archive before file NAME\n\
355   -K, --starting-file=NAME     begin at file NAME in the archive\n"),
356              stdout);
357 #if !MSDOS
358       fputs (_("\
359   -N, --newer=DATE             only store files newer than DATE\n\
360       --newer-mtime            compare date and time when data changed only\n\
361       --after-date=DATE        same as -N\n"),
362              stdout);
363 #endif
364       fputs (_("\
365       --backup[=CONTROL]       backup before removal, choose version control\n\
366       --suffix=SUFFIX          backup before removel, override usual suffix\n"),
367              stdout);
368       fputs (_("\
369 \n\
370 Informative output:\n\
371       --help            print this help, then exit\n\
372       --version         print tar program version number, then exit\n\
373   -v, --verbose         verbosely list files processed\n\
374       --checkpoint      print directory names while reading the archive\n\
375       --totals          print total bytes written while creating archive\n\
376   -R, --block-number    show block number within archive with each message\n\
377   -w, --interactive     ask for confirmation for every action\n\
378       --confirmation    same as -w\n"),
379              stdout);
380       fputs (_("\
381 \n\
382 The backup suffix is `~', unless set with --suffix or SIMPLE_BACKUP_SUFFIX.\n\
383 The version control may be set with --backup or VERSION_CONTROL, values are:\n\
384 \n\
385   t, numbered     make numbered backups\n\
386   nil, existing   numbered if numbered backups exist, simple otherwise\n\
387   never, simple   always make simple backups\n"),
388              stdout);
389       printf (_("\
390 \n\
391 GNU tar cannot read nor produce `--posix' archives.  If POSIXLY_CORRECT\n\
392 is set in the environment, GNU extensions are disallowed with `--posix'.\n\
393 Support for POSIX is only partially implemented, don't count on it yet.\n\
394 ARCHIVE may be FILE, HOST:FILE or USER@HOST:FILE; and FILE may be a file\n\
395 or a device.  *This* `tar' defaults to `-f%s -b%d'.\n"),
396               DEFAULT_ARCHIVE, DEFAULT_BLOCKING);
397       fputs (_("\
398 \n\
399 Report bugs to <tar-bugs@gnu.org>.\n"),
400                stdout);
401     }
402   exit (status);
403 }
404
405 /*----------------------------.
406 | Parse the options for tar.  |
407 `----------------------------*/
408
409 /* Available option letters are DHIJQY and aejnqy.  Some are reserved:
410
411    y  per-file gzip compression
412    Y  per-block gzip compression */
413
414 #define OPTION_STRING \
415   "-01234567ABC:E:F:GK:L:MN:OPRST:UV:WX:Zb:cdf:g:hiklmoprstuvwxz"
416
417 static void
418 set_subcommand_option (enum subcommand subcommand)
419 {
420   if (subcommand_option != UNKNOWN_SUBCOMMAND
421       && subcommand_option != subcommand)
422     USAGE_ERROR ((0, 0,
423                   _("You may not specify more than one `-Acdtrux' option")));
424
425   subcommand_option = subcommand;
426 }
427
428 static void
429 set_use_compress_program_option (const char *string)
430 {
431   if (use_compress_program_option && strcmp (use_compress_program_option, string) != 0)
432     USAGE_ERROR ((0, 0, _("Conflicting compression options")));
433
434   use_compress_program_option = string;
435 }
436
437 static void
438 decode_options (int argc, char *const *argv)
439 {
440   int optchar;                  /* option letter */
441   int input_files;              /* number of input files */
442   const char *backup_suffix_string;
443   const char *version_control_string = NULL;
444
445   /* Set some default option values.  */
446
447   subcommand_option = UNKNOWN_SUBCOMMAND;
448   archive_format = DEFAULT_FORMAT;
449   blocking_factor = DEFAULT_BLOCKING;
450   record_size = DEFAULT_BLOCKING * BLOCKSIZE;
451
452   owner_option = -1;
453   group_option = -1;
454
455   backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX");
456
457   /* Convert old-style tar call by exploding option element and rearranging
458      options accordingly.  */
459
460   if (argc > 1 && argv[1][0] != '-')
461     {
462       int new_argc;             /* argc value for rearranged arguments */
463       char **new_argv;          /* argv value for rearranged arguments */
464       char *const *in;          /* cursor into original argv */
465       char **out;               /* cursor into rearranged argv */
466       const char *letter;       /* cursor into old option letters */
467       char buffer[3];           /* constructed option buffer */
468       const char *cursor;       /* cursor in OPTION_STRING */
469
470       /* Initialize a constructed option.  */
471
472       buffer[0] = '-';
473       buffer[2] = '\0';
474
475       /* Allocate a new argument array, and copy program name in it.  */
476
477       new_argc = argc - 1 + strlen (argv[1]);
478       new_argv = (char **) xmalloc (new_argc * sizeof (char *));
479       in = argv;
480       out = new_argv;
481       *out++ = *in++;
482
483       /* Copy each old letter option as a separate option, and have the
484          corresponding argument moved next to it.  */
485
486       for (letter = *in++; *letter; letter++)
487         {
488           buffer[1] = *letter;
489           *out++ = xstrdup (buffer);
490           cursor = strchr (OPTION_STRING, *letter);
491           if (cursor && cursor[1] == ':')
492             {
493               if (in < argv + argc)
494                 *out++ = *in++;
495               else
496                 USAGE_ERROR ((0, 0, _("Old option `%c' requires an argument."),
497                               *letter));
498             }
499         }
500
501       /* Copy all remaining options.  */
502
503       while (in < argv + argc)
504         *out++ = *in++;
505
506       /* Replace the old option list by the new one.  */
507
508       argc = new_argc;
509       argv = new_argv;
510     }
511
512   /* Parse all options and non-options as they appear.  */
513
514   input_files = 0;
515
516   while (optchar = getopt_long (argc, argv, OPTION_STRING, long_options, NULL),
517          optchar != EOF)
518     switch (optchar)
519       {
520       case '?':
521         usage (TAREXIT_FAILURE);
522
523       case 0:
524         break;
525
526       case 1:
527         /* File name or non-parsed option, because of RETURN_IN_ORDER
528            ordering triggerred by the leading dash in OPTION_STRING.  */
529
530         name_add (optarg);
531         input_files++;
532         break;
533
534       case 'A':
535         set_subcommand_option (CAT_SUBCOMMAND);
536         break;
537
538       case OBSOLETE_BLOCK_COMPRESS:
539         WARN ((0, 0, _("Obsolete option, now implied by --blocking-factor")));
540         break;
541
542       case OBSOLETE_BLOCKING_FACTOR:
543         WARN ((0, 0, _("Obsolete option name replaced by --blocking-factor")));
544         /* Fall through.  */
545
546       case 'b':
547         {
548           long l;
549           if (! (xstrtol (optarg, (char **) 0, 10, &l, "") == LONGINT_OK
550                  && l == (blocking_factor = l)
551                  && 0 < blocking_factor
552                  && l == (record_size = l * (size_t) BLOCKSIZE) / BLOCKSIZE))
553             USAGE_ERROR ((0, 0, _("Invalid blocking factor")));
554         }
555         break;
556
557       case OBSOLETE_READ_FULL_RECORDS:
558         WARN ((0, 0,
559                _("Obsolete option name replaced by --read-full-records")));
560         /* Fall through.  */
561
562       case 'B':
563         /* Try to reblock input records.  For reading 4.2BSD pipes.  */
564
565         /* It would surely make sense to exchange -B and -R, but it seems
566            that -B has been used for a long while in Sun tar ans most
567            BSD-derived systems.  This is a consequence of the block/record
568            terminology confusion.  */
569
570         read_full_records_option = 1;
571         break;
572
573       case 'c':
574         set_subcommand_option (CREATE_SUBCOMMAND);
575         break;
576
577       case 'C':
578         name_add ("-C");
579         name_add (optarg);
580         break;
581
582       case 'd':
583         set_subcommand_option (DIFF_SUBCOMMAND);
584         break;
585
586       case 'E':
587         ending_file_option = optarg;
588         break;
589
590       case 'f':
591         if (archive_names == allocated_archive_names)
592           {
593             allocated_archive_names *= 2;
594             archive_name_array = (const char **)
595               xrealloc (archive_name_array,
596                         sizeof (const char *) * allocated_archive_names);
597           }
598         archive_name_array[archive_names++] = optarg;
599         break;
600
601       case 'F':
602         /* Since -F is only useful with -M, make it implied.  Run this
603            script at the end of each tape.  */
604
605         info_script_option = optarg;
606         multi_volume_option = 1;
607         break;
608
609       case 'g':
610         listed_incremental_option = optarg;
611         /* Fall through.  */
612
613       case 'G':
614         /* We are making an incremental dump (FIXME: are we?); save
615            directories at the beginning of the archive, and include in each
616            directory its contents.  */
617
618         incremental_option = 1;
619         break;
620
621       case 'h':
622         /* Follow symbolic links.  */
623
624         dereference_option = 1;
625         break;
626
627       case 'i':
628         /* Ignore zero blocks (eofs).  This can't be the default,
629            because Unix tar writes two blocks of zeros, then pads out
630            the record with garbage.  */
631
632         ignore_zeros_option = 1;
633         break;
634
635       case 'k':
636         /* Don't overwrite existing files.  */
637
638         keep_old_files_option = 1;
639         break;
640
641       case 'K':
642         starting_file_option = 1;
643         addname (optarg);
644         break;
645
646       case 'l':
647         /* When dumping directories, don't dump files/subdirectories
648            that are on other filesystems.  */
649
650         one_file_system_option = 1;
651         break;
652
653       case 'L':
654         {
655           unsigned long u;
656           if (xstrtoul (optarg, (char **) 0, 10, &u, "") != LONG_MAX)
657             USAGE_ERROR ((0, 0, _("Invalid tape length")));
658           clear_tarlong (tape_length_option);
659           add_to_tarlong (tape_length_option, u);
660           mult_tarlong (tape_length_option, 1024);
661           multi_volume_option = 1;
662         }
663         break;
664
665       case OBSOLETE_TOUCH:
666         WARN ((0, 0, _("Obsolete option name replaced by --touch")));
667         /* Fall through.  */
668
669       case 'm':
670         touch_option = 1;
671         break;
672
673       case 'M':
674         /* Make multivolume archive: when we can't write any more into
675            the archive, re-open it, and continue writing.  */
676
677         multi_volume_option = 1;
678         break;
679
680 #if !MSDOS
681       case 'N':
682         after_date_option = 1;
683         /* Fall through.  */
684
685       case NEWER_MTIME_OPTION:
686         if (newer_mtime_option)
687           USAGE_ERROR ((0, 0, _("More than one threshold date")));
688
689         newer_mtime_option = get_date (optarg, (voidstar) 0);
690         if (newer_mtime_option == (time_t) -1)
691           USAGE_ERROR ((0, 0, _("Invalid date format `%s'"), optarg));
692
693         break;
694 #endif /* not MSDOS */
695
696       case 'o':
697         if (archive_format == DEFAULT_FORMAT)
698           archive_format = V7_FORMAT;
699         else if (archive_format != V7_FORMAT)
700           USAGE_ERROR ((0, 0, _("Conflicting archive format options")));
701         break;
702
703       case 'O':
704         to_stdout_option = 1;
705         break;
706
707       case 'p':
708         same_permissions_option = 1;
709         break;
710
711       case OBSOLETE_ABSOLUTE_NAMES:
712         WARN ((0, 0, _("Obsolete option name replaced by --absolute-names")));
713         /* Fall through.  */
714
715       case 'P':
716         absolute_names_option = 1;
717         break;
718
719       case 'r':
720         set_subcommand_option (APPEND_SUBCOMMAND);
721         break;
722
723       case OBSOLETE_BLOCK_NUMBER:
724         WARN ((0, 0, _("Obsolete option name replaced by --block-number")));
725         /* Fall through.  */
726
727       case 'R':
728         /* Print block numbers for debugging bad tar archives.  */
729
730         /* It would surely make sense to exchange -B and -R, but it seems
731            that -B has been used for a long while in Sun tar ans most
732            BSD-derived systems.  This is a consequence of the block/record
733            terminology confusion.  */
734
735         block_number_option = 1;
736         break;
737
738       case 's':
739         /* Names to extr are sorted.  */
740
741         same_order_option = 1;
742         break;
743
744       case 'S':
745         sparse_option = 1;
746         break;
747
748       case 't':
749         set_subcommand_option (LIST_SUBCOMMAND);
750         verbose_option++;
751         break;
752
753       case 'T':
754         files_from_option = optarg;
755         break;
756
757       case 'u':
758         set_subcommand_option (UPDATE_SUBCOMMAND);
759         break;
760
761       case 'U':
762         unlink_first_option = 1;
763         break;
764
765       case 'v':
766         verbose_option++;
767         break;
768
769       case 'V':
770         volume_label_option = optarg;
771         break;
772
773       case 'w':
774         interactive_option = 1;
775         break;
776
777       case 'W':
778         verify_option = 1;
779         break;
780
781       case 'x':
782         set_subcommand_option (EXTRACT_SUBCOMMAND);
783         break;
784
785       case 'X':
786         exclude_option = 1;
787         add_exclude_file (optarg);
788         break;
789
790       case 'z':
791         set_use_compress_program_option ("gzip");
792         break;
793
794       case 'Z':
795         set_use_compress_program_option ("compress");
796         break;
797
798       case OBSOLETE_VERSION_CONTROL:
799         WARN ((0, 0, _("Obsolete option name replaced by --backup")));
800         /* Fall through.  */
801
802       case BACKUP_OPTION:
803         backup_option = 1;
804         if (optarg)
805           version_control_string = optarg;
806         break;
807
808       case DELETE_OPTION:
809         set_subcommand_option (DELETE_SUBCOMMAND);
810         break;
811
812       case EXCLUDE_OPTION:
813         exclude_option = 1;
814         add_exclude (optarg);
815         break;
816
817       case GROUP_OPTION:
818         if (! (strlen (optarg) < GNAME_FIELD_SIZE
819                && gname_to_gid (optarg, &group_option)))
820           {
821             uintmax_t g;
822             if (xstrtoumax (optarg, (char **) 0, 10, &g, "") == LONGINT_OK
823                 && g == (gid_t) g)
824               group_option = g;
825             else
826               ERROR ((TAREXIT_FAILURE, 0, _("Invalid group given on option")));
827           }
828         break;
829
830       case MODE_OPTION:
831         mode_option
832           = mode_compile (optarg,
833                           MODE_MASK_EQUALS | MODE_MASK_PLUS | MODE_MASK_MINUS);
834         if (mode_option == MODE_INVALID)
835           ERROR ((TAREXIT_FAILURE, 0, _("Invalid mode given on option")));
836         if (mode_option == MODE_MEMORY_EXHAUSTED)
837           ERROR ((TAREXIT_FAILURE, 0, _("Memory exhausted")));
838         break;
839
840       case NO_RECURSE_OPTION:
841         no_recurse_option = 1;
842         break;
843
844       case NULL_OPTION:
845         filename_terminator = '\0';
846         break;
847
848       case OWNER_OPTION:
849         if (! (strlen (optarg) < UNAME_FIELD_SIZE
850                && uname_to_uid (optarg, &owner_option)))
851           {
852             uintmax_t u;
853             if (xstrtoumax (optarg, (char **) 0, 10, &u, "") == LONGINT_OK
854                 && u == (uid_t) u)
855               owner_option = u;
856             else
857               ERROR ((TAREXIT_FAILURE, 0, _("Invalid owner given on option")));
858           }
859         break;
860
861       case POSIX_OPTION:
862 #if OLDGNU_COMPATIBILITY
863         if (archive_format == DEFAULT_FORMAT)
864           archive_format = GNU_FORMAT;
865         else if (archive_format != GNU_FORMAT)
866           USAGE_ERROR ((0, 0, _("Conflicting archive format options")));
867 #else
868         if (archive_format == DEFAULT_FORMAT)
869           archive_format = POSIX_FORMAT;
870         else if (archive_format != POSIX_FORMAT)
871           USAGE_ERROR ((0, 0, _("Conflicting archive format options")));
872 #endif
873         break;
874
875       case PRESERVE_OPTION:
876         same_permissions_option = 1;
877         same_order_option = 1;
878         break;
879
880       case RECORD_SIZE_OPTION:
881         {
882           uintmax_t u;
883           if (! (xstrtoumax (optarg, (char **) 0, 10, &u, "") == LONG_MAX
884                  && u == (size_t) u))
885             USAGE_ERROR ((0, 0, _("Invalid record size")));
886           record_size = u;
887           if (record_size % BLOCKSIZE != 0)
888             USAGE_ERROR ((0, 0, _("Record size must be a multiple of %d."),
889                           BLOCKSIZE));
890           blocking_factor = record_size / BLOCKSIZE;
891         }
892         break;
893
894       case RSH_COMMAND_OPTION:
895         rsh_command_option = optarg;
896         break;
897
898       case SUFFIX_OPTION:
899         backup_option = 1;
900         backup_suffix_string = optarg;
901         break;
902
903       case VOLNO_FILE_OPTION:
904         volno_file_option = optarg;
905         break;
906
907       case USE_COMPRESS_PROGRAM_OPTION:
908         set_use_compress_program_option (optarg);
909         break;
910
911       case '0':
912       case '1':
913       case '2':
914       case '3':
915       case '4':
916       case '5':
917       case '6':
918       case '7':
919
920 #ifdef DEVICE_PREFIX
921         {
922           int device = optchar - '0';
923           int density;
924           static char buf[sizeof DEVICE_PREFIX + 10];
925           char *cursor;
926
927           density = getopt_long (argc, argv, "lmh", NULL, NULL);
928           strcpy (buf, DEVICE_PREFIX);
929           cursor = buf + strlen (buf);
930
931 #ifdef DENSITY_LETTER
932
933           sprintf (cursor, "%d%c", device, density);
934
935 #else /* not DENSITY_LETTER */
936
937           switch (density)
938             {
939             case 'l':
940 #ifdef LOW_NUM
941               device += LOW_NUM;
942 #endif
943               break;
944
945             case 'm':
946 #ifdef MID_NUM
947               device += MID_NUM;
948 #else
949               device += 8;
950 #endif
951               break;
952
953             case 'h':
954 #ifdef HGH_NUM
955               device += HGH_NUM;
956 #else
957               device += 16;
958 #endif
959               break;
960
961             default:
962               usage (TAREXIT_FAILURE);
963             }
964           sprintf (cursor, "%d", device);
965
966 #endif /* not DENSITY_LETTER */
967
968           if (archive_names == allocated_archive_names)
969             {
970               allocated_archive_names *= 2;
971               archive_name_array = (const char **)
972                 xrealloc (archive_name_array,
973                           sizeof (const char *) * allocated_archive_names);
974             }
975           archive_name_array[archive_names++] = buf;
976
977           /* FIXME: How comes this works for many archives when buf is
978              not xstrdup'ed?  */
979         }
980         break;
981
982 #else /* not DEVICE_PREFIX */
983
984         USAGE_ERROR ((0, 0,
985                       _("Options `-[0-7][lmh]' not supported by *this* tar")));
986
987 #endif /* not DEVICE_PREFIX */
988       }
989
990   /* Process trivial options.  */
991
992   if (show_version)
993     {
994       printf ("tar (GNU %s) %s\n", PACKAGE, VERSION);
995       fputs (_("\
996 \n\
997 Copyright (C) 1988, 92,93,94,95,96,97,98, 1999 Free Software Foundation, Inc.\n"),
998              stdout);
999       fputs (_("\
1000 This is free software; see the source for copying conditions.  There is NO\n\
1001 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"),
1002              stdout);
1003       fputs (_("\
1004 \n\
1005 Written by John Gilmore and Jay Fenlason.\n"),
1006              stdout);
1007       exit (TAREXIT_SUCCESS);
1008     }
1009
1010   if (show_help)
1011     usage (TAREXIT_SUCCESS);
1012
1013   /* Derive option values and check option consistency.  */
1014
1015   if (archive_format == DEFAULT_FORMAT)
1016     {
1017 #if OLDGNU_COMPATIBILITY
1018       archive_format = OLDGNU_FORMAT;
1019 #else
1020       archive_format = GNU_FORMAT;
1021 #endif
1022     }
1023
1024   if (archive_format == GNU_FORMAT && getenv ("POSIXLY_CORRECT"))
1025     archive_format = POSIX_FORMAT;
1026
1027   if ((volume_label_option != NULL
1028        || incremental_option || multi_volume_option || sparse_option)
1029       && archive_format != OLDGNU_FORMAT && archive_format != GNU_FORMAT)
1030     USAGE_ERROR ((0, 0,
1031                   _("GNU features wanted on incompatible archive format")));
1032
1033   if (archive_names == 0)
1034     {
1035       /* If no archive file name given, try TAPE from the environment, or
1036          else, DEFAULT_ARCHIVE from the configuration process.  */
1037
1038       archive_names = 1;
1039       archive_name_array[0] = getenv ("TAPE");
1040       if (archive_name_array[0] == NULL)
1041         archive_name_array[0] = DEFAULT_ARCHIVE;
1042     }
1043
1044   /* Allow multiple archives only with `-M'.  */
1045
1046   if (archive_names > 1 && !multi_volume_option)
1047     USAGE_ERROR ((0, 0,
1048                   _("Multiple archive files requires `-M' option")));
1049
1050   /* If ready to unlink hierarchies, so we are for simpler files.  */
1051   if (recursive_unlink_option)
1052     unlink_first_option = 1;
1053
1054   /* Forbid using -c with no input files whatsoever.  Check that `-f -',
1055      explicit or implied, is used correctly.  */
1056
1057   switch (subcommand_option)
1058     {
1059     case CREATE_SUBCOMMAND:
1060       if (input_files == 0 && !files_from_option)
1061         USAGE_ERROR ((0, 0,
1062                       _("Cowardly refusing to create an empty archive")));
1063       break;
1064
1065     case EXTRACT_SUBCOMMAND:
1066     case LIST_SUBCOMMAND:
1067     case DIFF_SUBCOMMAND:
1068       for (archive_name_cursor = archive_name_array;
1069            archive_name_cursor < archive_name_array + archive_names;
1070            archive_name_cursor++)
1071         if (!strcmp (*archive_name_cursor, "-"))
1072           request_stdin ("-f");
1073       break;
1074
1075     case CAT_SUBCOMMAND:
1076     case UPDATE_SUBCOMMAND:
1077     case APPEND_SUBCOMMAND:
1078       for (archive_name_cursor = archive_name_array;
1079            archive_name_cursor < archive_name_array + archive_names;
1080            archive_name_cursor++)
1081         if (!strcmp (*archive_name_cursor, "-"))
1082           USAGE_ERROR ((0, 0,
1083                         _("Options `-Aru' are incompatible with `-f -'")));
1084
1085     default:
1086       break;
1087     }
1088
1089   archive_name_cursor = archive_name_array;
1090
1091   /* Prepare for generating backup names.  */
1092
1093   if (backup_suffix_string)
1094     simple_backup_suffix = xstrdup (backup_suffix_string);
1095
1096   if (backup_option)
1097     backup_type = xget_version ("--backup", version_control_string);
1098 }
1099 \f
1100 /* Tar proper.  */
1101
1102 /*-----------------------.
1103 | Main routine for tar.  |
1104 `-----------------------*/
1105
1106 int
1107 main (int argc, char *const *argv)
1108 {
1109   program_name = argv[0];
1110   setlocale (LC_ALL, "");
1111   bindtextdomain (PACKAGE, LOCALEDIR);
1112   textdomain (PACKAGE);
1113
1114   exit_status = TAREXIT_SUCCESS;
1115   filename_terminator = '\n';
1116
1117   /* Pre-allocate a few structures.  */
1118
1119   allocated_archive_names = 10;
1120   archive_name_array = (const char **)
1121     xmalloc (sizeof (const char *) * allocated_archive_names);
1122   archive_names = 0;
1123
1124   init_names ();
1125
1126   /* Decode options.  */
1127
1128   decode_options (argc, argv);
1129   name_init (argc, argv);
1130
1131   /* Main command execution.  */
1132
1133   if (volno_file_option)
1134     init_volume_number ();
1135
1136   switch (subcommand_option)
1137     {
1138     case UNKNOWN_SUBCOMMAND:
1139       USAGE_ERROR ((0, 0,
1140                     _("You must specify one of the `-Acdtrux' options")));
1141
1142     case CAT_SUBCOMMAND:
1143     case UPDATE_SUBCOMMAND:
1144     case APPEND_SUBCOMMAND:
1145       update_archive ();
1146       break;
1147
1148     case DELETE_SUBCOMMAND:
1149       delete_archive_members ();
1150       break;
1151
1152     case CREATE_SUBCOMMAND:
1153       if (totals_option)
1154         init_total_written ();
1155
1156       create_archive ();
1157       name_close ();
1158
1159       if (totals_option)
1160         print_total_written ();
1161       break;
1162
1163     case EXTRACT_SUBCOMMAND:
1164       extr_init ();
1165       read_and (extract_archive);
1166       break;
1167
1168     case LIST_SUBCOMMAND:
1169       read_and (list_archive);
1170       break;
1171
1172     case DIFF_SUBCOMMAND:
1173       diff_init ();
1174       read_and (diff_archive);
1175       break;
1176     }
1177
1178   if (volno_file_option)
1179     closeout_volume_number ();
1180
1181   /* Dispose of allocated memory, and return.  */
1182
1183   free (archive_name_array);
1184   name_term ();
1185
1186   if (exit_status == TAREXIT_FAILURE)
1187     error (0, 0, _("Error exit delayed from previous errors"));
1188   exit (exit_status);
1189 }