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