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