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