]> Dogcows Code - chaz/tar/blob - src/tar.c
(long_options, usage, OPTION_STRING, decode_options):
[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 {"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 /* Fall through. */
629
630 case 'G':
631 /* We are making an incremental dump (FIXME: are we?); save
632 directories at the beginning of the archive, and include in each
633 directory its contents. */
634
635 incremental_option = 1;
636 break;
637
638 case 'h':
639 /* Follow symbolic links. */
640
641 dereference_option = 1;
642 break;
643
644 case 'i':
645 /* Ignore zero blocks (eofs). This can't be the default,
646 because Unix tar writes two blocks of zeros, then pads out
647 the record with garbage. */
648
649 ignore_zeros_option = 1;
650 break;
651
652 case 'k':
653 /* Don't overwrite existing files. */
654
655 keep_old_files_option = 1;
656 break;
657
658 case 'K':
659 starting_file_option = 1;
660 addname (optarg);
661 break;
662
663 case 'l':
664 /* When dumping directories, don't dump files/subdirectories
665 that are on other filesystems. */
666
667 one_file_system_option = 1;
668 break;
669
670 case 'L':
671 {
672 uintmax_t u;
673 if (xstrtoumax (optarg, (char **) 0, 10, &u, "") != LONG_MAX)
674 USAGE_ERROR ((0, 0, _("Invalid tape length")));
675 tape_length_option = 1024 * (tarlong) u;
676 multi_volume_option = 1;
677 }
678 break;
679
680 case OBSOLETE_TOUCH:
681 WARN ((0, 0, _("Obsolete option name replaced by --touch")));
682 /* Fall through. */
683
684 case 'm':
685 touch_option = 1;
686 break;
687
688 case 'M':
689 /* Make multivolume archive: when we can't write any more into
690 the archive, re-open it, and continue writing. */
691
692 multi_volume_option = 1;
693 break;
694
695 #if !MSDOS
696 case 'N':
697 after_date_option = 1;
698 /* Fall through. */
699
700 case NEWER_MTIME_OPTION:
701 if (newer_mtime_option != TYPE_MINIMUM (time_t))
702 USAGE_ERROR ((0, 0, _("More than one threshold date")));
703
704 newer_mtime_option = get_date (optarg, (voidstar) 0);
705 if (newer_mtime_option == (time_t) -1)
706 USAGE_ERROR ((0, 0, _("Invalid date format `%s'"), optarg));
707
708 break;
709 #endif /* not MSDOS */
710
711 case 'o':
712 if (archive_format == DEFAULT_FORMAT)
713 archive_format = V7_FORMAT;
714 else if (archive_format != V7_FORMAT)
715 USAGE_ERROR ((0, 0, _("Conflicting archive format options")));
716 break;
717
718 case 'O':
719 to_stdout_option = 1;
720 break;
721
722 case 'p':
723 same_permissions_option = 1;
724 break;
725
726 case OBSOLETE_ABSOLUTE_NAMES:
727 WARN ((0, 0, _("Obsolete option name replaced by --absolute-names")));
728 /* Fall through. */
729
730 case 'P':
731 absolute_names_option = 1;
732 break;
733
734 case 'r':
735 set_subcommand_option (APPEND_SUBCOMMAND);
736 break;
737
738 case OBSOLETE_BLOCK_NUMBER:
739 WARN ((0, 0, _("Obsolete option name replaced by --block-number")));
740 /* Fall through. */
741
742 case 'R':
743 /* Print block numbers for debugging bad tar archives. */
744
745 /* It would surely make sense to exchange -B and -R, but it seems
746 that -B has been used for a long while in Sun tar ans most
747 BSD-derived systems. This is a consequence of the block/record
748 terminology confusion. */
749
750 block_number_option = 1;
751 break;
752
753 case 's':
754 /* Names to extr are sorted. */
755
756 same_order_option = 1;
757 break;
758
759 case 'S':
760 sparse_option = 1;
761 break;
762
763 case 't':
764 set_subcommand_option (LIST_SUBCOMMAND);
765 verbose_option++;
766 break;
767
768 case 'T':
769 files_from_option = optarg;
770 break;
771
772 case 'u':
773 set_subcommand_option (UPDATE_SUBCOMMAND);
774 break;
775
776 case 'U':
777 unlink_first_option = 1;
778 break;
779
780 case 'v':
781 verbose_option++;
782 break;
783
784 case 'V':
785 volume_label_option = optarg;
786 break;
787
788 case 'w':
789 interactive_option = 1;
790 break;
791
792 case 'W':
793 verify_option = 1;
794 break;
795
796 case 'x':
797 set_subcommand_option (EXTRACT_SUBCOMMAND);
798 break;
799
800 case 'X':
801 if (add_exclude_file (NULL, add_filtered_exclude, optarg, '\n') != 0)
802 FATAL_ERROR ((0, errno, "%s", optarg));
803 break;
804
805 case 'y':
806 set_use_compress_program_option ("bzip2");
807 break;
808
809 case 'z':
810 set_use_compress_program_option ("gzip");
811 break;
812
813 case 'Z':
814 set_use_compress_program_option ("compress");
815 break;
816
817 case OBSOLETE_VERSION_CONTROL:
818 WARN ((0, 0, _("Obsolete option name replaced by --backup")));
819 /* Fall through. */
820
821 case BACKUP_OPTION:
822 backup_option = 1;
823 if (optarg)
824 version_control_string = optarg;
825 break;
826
827 case DELETE_OPTION:
828 set_subcommand_option (DELETE_SUBCOMMAND);
829 break;
830
831 case EXCLUDE_OPTION:
832 add_filtered_exclude (NULL, optarg);
833 break;
834
835 case GROUP_OPTION:
836 if (! (strlen (optarg) < GNAME_FIELD_SIZE
837 && gname_to_gid (optarg, &group_option)))
838 {
839 uintmax_t g;
840 if (xstrtoumax (optarg, (char **) 0, 10, &g, "") == LONGINT_OK
841 && g == (gid_t) g)
842 group_option = g;
843 else
844 FATAL_ERROR ((0, 0, _("Invalid group given on option")));
845 }
846 break;
847
848 case MODE_OPTION:
849 mode_option
850 = mode_compile (optarg,
851 MODE_MASK_EQUALS | MODE_MASK_PLUS | MODE_MASK_MINUS);
852 if (mode_option == MODE_INVALID)
853 FATAL_ERROR ((0, 0, _("Invalid mode given on option")));
854 if (mode_option == MODE_MEMORY_EXHAUSTED)
855 FATAL_ERROR ((0, 0, _("Memory exhausted")));
856 break;
857
858 case NO_RECURSE_OPTION:
859 no_recurse_option = 1;
860 break;
861
862 case NULL_OPTION:
863 filename_terminator = '\0';
864 break;
865
866 case OWNER_OPTION:
867 if (! (strlen (optarg) < UNAME_FIELD_SIZE
868 && uname_to_uid (optarg, &owner_option)))
869 {
870 uintmax_t u;
871 if (xstrtoumax (optarg, (char **) 0, 10, &u, "") == LONGINT_OK
872 && u == (uid_t) u)
873 owner_option = u;
874 else
875 FATAL_ERROR ((0, 0, _("Invalid owner given on option")));
876 }
877 break;
878
879 case POSIX_OPTION:
880 #if OLDGNU_COMPATIBILITY
881 if (archive_format == DEFAULT_FORMAT)
882 archive_format = GNU_FORMAT;
883 else if (archive_format != GNU_FORMAT)
884 USAGE_ERROR ((0, 0, _("Conflicting archive format options")));
885 #else
886 if (archive_format == DEFAULT_FORMAT)
887 archive_format = POSIX_FORMAT;
888 else if (archive_format != POSIX_FORMAT)
889 USAGE_ERROR ((0, 0, _("Conflicting archive format options")));
890 #endif
891 break;
892
893 case PRESERVE_OPTION:
894 same_permissions_option = 1;
895 same_order_option = 1;
896 break;
897
898 case RECORD_SIZE_OPTION:
899 {
900 uintmax_t u;
901 if (! (xstrtoumax (optarg, (char **) 0, 10, &u, "") == LONG_MAX
902 && u == (size_t) u))
903 USAGE_ERROR ((0, 0, _("Invalid record size")));
904 record_size = u;
905 if (record_size % BLOCKSIZE != 0)
906 USAGE_ERROR ((0, 0, _("Record size must be a multiple of %d."),
907 BLOCKSIZE));
908 blocking_factor = record_size / BLOCKSIZE;
909 }
910 break;
911
912 case RSH_COMMAND_OPTION:
913 rsh_command_option = optarg;
914 break;
915
916 case SUFFIX_OPTION:
917 backup_option = 1;
918 backup_suffix_string = optarg;
919 break;
920
921 case VOLNO_FILE_OPTION:
922 volno_file_option = optarg;
923 break;
924
925 case USE_COMPRESS_PROGRAM_OPTION:
926 set_use_compress_program_option (optarg);
927 break;
928
929 case '0':
930 case '1':
931 case '2':
932 case '3':
933 case '4':
934 case '5':
935 case '6':
936 case '7':
937
938 #ifdef DEVICE_PREFIX
939 {
940 int device = optchar - '0';
941 int density;
942 static char buf[sizeof DEVICE_PREFIX + 10];
943 char *cursor;
944
945 density = getopt_long (argc, argv, "lmh", NULL, NULL);
946 strcpy (buf, DEVICE_PREFIX);
947 cursor = buf + strlen (buf);
948
949 #ifdef DENSITY_LETTER
950
951 sprintf (cursor, "%d%c", device, density);
952
953 #else /* not DENSITY_LETTER */
954
955 switch (density)
956 {
957 case 'l':
958 #ifdef LOW_NUM
959 device += LOW_NUM;
960 #endif
961 break;
962
963 case 'm':
964 #ifdef MID_NUM
965 device += MID_NUM;
966 #else
967 device += 8;
968 #endif
969 break;
970
971 case 'h':
972 #ifdef HGH_NUM
973 device += HGH_NUM;
974 #else
975 device += 16;
976 #endif
977 break;
978
979 default:
980 usage (TAREXIT_FAILURE);
981 }
982 sprintf (cursor, "%d", device);
983
984 #endif /* not DENSITY_LETTER */
985
986 if (archive_names == allocated_archive_names)
987 {
988 allocated_archive_names *= 2;
989 archive_name_array = (const char **)
990 xrealloc (archive_name_array,
991 sizeof (const char *) * allocated_archive_names);
992 }
993 archive_name_array[archive_names++] = buf;
994
995 /* FIXME: How comes this works for many archives when buf is
996 not xstrdup'ed? */
997 }
998 break;
999
1000 #else /* not DEVICE_PREFIX */
1001
1002 USAGE_ERROR ((0, 0,
1003 _("Options `-[0-7][lmh]' not supported by *this* tar")));
1004
1005 #endif /* not DEVICE_PREFIX */
1006 }
1007
1008 /* Process trivial options. */
1009
1010 if (show_version)
1011 {
1012 printf ("tar (GNU %s) %s\n", PACKAGE, VERSION);
1013 fputs (_("\
1014 \n\
1015 Copyright (C) 1988, 92,93,94,95,96,97,98, 1999 Free Software Foundation, Inc.\n"),
1016 stdout);
1017 fputs (_("\
1018 This is free software; see the source for copying conditions. There is NO\n\
1019 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"),
1020 stdout);
1021 fputs (_("\
1022 \n\
1023 Written by John Gilmore and Jay Fenlason.\n"),
1024 stdout);
1025 exit (TAREXIT_SUCCESS);
1026 }
1027
1028 if (show_help)
1029 usage (TAREXIT_SUCCESS);
1030
1031 /* Derive option values and check option consistency. */
1032
1033 if (archive_format == DEFAULT_FORMAT)
1034 {
1035 #if OLDGNU_COMPATIBILITY
1036 archive_format = OLDGNU_FORMAT;
1037 #else
1038 archive_format = GNU_FORMAT;
1039 #endif
1040 }
1041
1042 if (archive_format == GNU_FORMAT && getenv ("POSIXLY_CORRECT"))
1043 archive_format = POSIX_FORMAT;
1044
1045 if ((volume_label_option != NULL
1046 || incremental_option || multi_volume_option || sparse_option)
1047 && archive_format != OLDGNU_FORMAT && archive_format != GNU_FORMAT)
1048 USAGE_ERROR ((0, 0,
1049 _("GNU features wanted on incompatible archive format")));
1050
1051 if (archive_names == 0)
1052 {
1053 /* If no archive file name given, try TAPE from the environment, or
1054 else, DEFAULT_ARCHIVE from the configuration process. */
1055
1056 archive_names = 1;
1057 archive_name_array[0] = getenv ("TAPE");
1058 if (archive_name_array[0] == NULL)
1059 archive_name_array[0] = DEFAULT_ARCHIVE;
1060 }
1061
1062 /* Allow multiple archives only with `-M'. */
1063
1064 if (archive_names > 1 && !multi_volume_option)
1065 USAGE_ERROR ((0, 0,
1066 _("Multiple archive files requires `-M' option")));
1067
1068 /* If ready to unlink hierarchies, so we are for simpler files. */
1069 if (recursive_unlink_option)
1070 unlink_first_option = 1;
1071
1072 /* Forbid using -c with no input files whatsoever. Check that `-f -',
1073 explicit or implied, is used correctly. */
1074
1075 switch (subcommand_option)
1076 {
1077 case CREATE_SUBCOMMAND:
1078 if (input_files == 0 && !files_from_option)
1079 USAGE_ERROR ((0, 0,
1080 _("Cowardly refusing to create an empty archive")));
1081 break;
1082
1083 case EXTRACT_SUBCOMMAND:
1084 case LIST_SUBCOMMAND:
1085 case DIFF_SUBCOMMAND:
1086 for (archive_name_cursor = archive_name_array;
1087 archive_name_cursor < archive_name_array + archive_names;
1088 archive_name_cursor++)
1089 if (!strcmp (*archive_name_cursor, "-"))
1090 request_stdin ("-f");
1091 break;
1092
1093 case CAT_SUBCOMMAND:
1094 case UPDATE_SUBCOMMAND:
1095 case APPEND_SUBCOMMAND:
1096 for (archive_name_cursor = archive_name_array;
1097 archive_name_cursor < archive_name_array + archive_names;
1098 archive_name_cursor++)
1099 if (!strcmp (*archive_name_cursor, "-"))
1100 USAGE_ERROR ((0, 0,
1101 _("Options `-Aru' are incompatible with `-f -'")));
1102
1103 default:
1104 break;
1105 }
1106
1107 archive_name_cursor = archive_name_array;
1108
1109 /* Prepare for generating backup names. */
1110
1111 if (backup_suffix_string)
1112 simple_backup_suffix = xstrdup (backup_suffix_string);
1113
1114 if (backup_option)
1115 backup_type = xget_version ("--backup", version_control_string);
1116 }
1117 \f
1118 /* Tar proper. */
1119
1120 /*-----------------------.
1121 | Main routine for tar. |
1122 `-----------------------*/
1123
1124 int
1125 main (int argc, char *const *argv)
1126 {
1127 program_name = argv[0];
1128 setlocale (LC_ALL, "");
1129 bindtextdomain (PACKAGE, LOCALEDIR);
1130 textdomain (PACKAGE);
1131
1132 exit_status = TAREXIT_SUCCESS;
1133 filename_terminator = '\n';
1134
1135 /* Pre-allocate a few structures. */
1136
1137 allocated_archive_names = 10;
1138 archive_name_array = (const char **)
1139 xmalloc (sizeof (const char *) * allocated_archive_names);
1140 archive_names = 0;
1141
1142 #ifdef SIGCHLD
1143 /* System V fork+wait does not work if SIGCHLD is ignored. */
1144 signal (SIGCHLD, SIG_DFL);
1145 #endif
1146
1147 init_names ();
1148
1149 /* Decode options. */
1150
1151 decode_options (argc, argv);
1152 name_init (argc, argv);
1153
1154 /* Main command execution. */
1155
1156 if (volno_file_option)
1157 init_volume_number ();
1158
1159 switch (subcommand_option)
1160 {
1161 case UNKNOWN_SUBCOMMAND:
1162 USAGE_ERROR ((0, 0,
1163 _("You must specify one of the `-Acdtrux' options")));
1164
1165 case CAT_SUBCOMMAND:
1166 case UPDATE_SUBCOMMAND:
1167 case APPEND_SUBCOMMAND:
1168 update_archive ();
1169 break;
1170
1171 case DELETE_SUBCOMMAND:
1172 delete_archive_members ();
1173 break;
1174
1175 case CREATE_SUBCOMMAND:
1176 create_archive ();
1177 name_close ();
1178
1179 if (totals_option)
1180 print_total_written ();
1181 break;
1182
1183 case EXTRACT_SUBCOMMAND:
1184 extr_init ();
1185 read_and (extract_archive);
1186 break;
1187
1188 case LIST_SUBCOMMAND:
1189 read_and (list_archive);
1190 break;
1191
1192 case DIFF_SUBCOMMAND:
1193 diff_init ();
1194 read_and (diff_archive);
1195 break;
1196 }
1197
1198 if (volno_file_option)
1199 closeout_volume_number ();
1200
1201 /* Dispose of allocated memory, and return. */
1202
1203 free (archive_name_array);
1204 name_term ();
1205
1206 if (exit_status == TAREXIT_FAILURE)
1207 error (0, 0, _("Error exit delayed from previous errors"));
1208 exit (exit_status);
1209 }
This page took 0.087953 seconds and 5 git commands to generate.