]> Dogcows Code - chaz/tar/blob - src/tar.c
213b277921f1f17fdaf2188de16ec7040df3be32
[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 NO_RECURSE_OPTION,
136 NULL_OPTION,
137 OVERWRITE_OPTION,
138 OWNER_OPTION,
139 POSIX_OPTION,
140 PRESERVE_OPTION,
141 RECORD_SIZE_OPTION,
142 RSH_COMMAND_OPTION,
143 SUFFIX_OPTION,
144 USE_COMPRESS_PROGRAM_OPTION,
145 VOLNO_FILE_OPTION,
146
147 /* Some cleanup is being made in GNU tar long options. Using old names is
148 allowed for a while, but will also send a warning to stderr. Take old
149 names out in 1.14, or in summer 1997, whichever happens last. */
150
151 OBSOLETE_ABSOLUTE_NAMES,
152 OBSOLETE_BLOCK_COMPRESS,
153 OBSOLETE_BLOCKING_FACTOR,
154 OBSOLETE_BLOCK_NUMBER,
155 OBSOLETE_READ_FULL_RECORDS,
156 OBSOLETE_TOUCH,
157 OBSOLETE_VERSION_CONTROL
158 };
159
160 /* If nonzero, display usage information and exit. */
161 static int show_help;
162
163 /* If nonzero, print the version on standard output and exit. */
164 static int show_version;
165
166 static struct option long_options[] =
167 {
168 {"absolute-names", no_argument, 0, 'P'},
169 {"absolute-paths", no_argument, 0, OBSOLETE_ABSOLUTE_NAMES},
170 {"after-date", required_argument, 0, 'N'},
171 {"append", no_argument, 0, 'r'},
172 {"atime-preserve", no_argument, &atime_preserve_option, 1},
173 {"backup", optional_argument, 0, BACKUP_OPTION},
174 {"block-compress", no_argument, 0, OBSOLETE_BLOCK_COMPRESS},
175 {"block-number", no_argument, 0, 'R'},
176 {"block-size", required_argument, 0, OBSOLETE_BLOCKING_FACTOR},
177 {"blocking-factor", required_argument, 0, 'b'},
178 {"bzip2", no_argument, 0, 'j'},
179 {"catenate", no_argument, 0, 'A'},
180 {"checkpoint", no_argument, &checkpoint_option, 1},
181 {"compare", no_argument, 0, 'd'},
182 {"compress", no_argument, 0, 'Z'},
183 {"concatenate", no_argument, 0, 'A'},
184 {"confirmation", no_argument, 0, 'w'},
185 /* FIXME: --selective as a synonym for --confirmation? */
186 {"create", no_argument, 0, 'c'},
187 {"delete", no_argument, 0, DELETE_OPTION},
188 {"dereference", no_argument, 0, 'h'},
189 {"diff", no_argument, 0, 'd'},
190 {"directory", required_argument, 0, 'C'},
191 {"exclude", required_argument, 0, EXCLUDE_OPTION},
192 {"exclude-from", required_argument, 0, 'X'},
193 {"extract", no_argument, 0, 'x'},
194 {"file", required_argument, 0, 'f'},
195 {"files-from", required_argument, 0, 'T'},
196 {"force-local", no_argument, &force_local_option, 1},
197 {"get", no_argument, 0, 'x'},
198 {"group", required_argument, 0, GROUP_OPTION},
199 {"gunzip", no_argument, 0, 'z'},
200 {"gzip", no_argument, 0, 'z'},
201 {"help", no_argument, &show_help, 1},
202 {"ignore-failed-read", no_argument, &ignore_failed_read_option, 1},
203 {"ignore-zeros", no_argument, 0, 'i'},
204 /* FIXME: --ignore-end as a new name for --ignore-zeros? */
205 {"incremental", no_argument, 0, 'G'},
206 {"info-script", required_argument, 0, 'F'},
207 {"interactive", no_argument, 0, 'w'},
208 {"keep-old-files", no_argument, 0, 'k'},
209 {"label", required_argument, 0, 'V'},
210 {"list", no_argument, 0, 't'},
211 {"listed-incremental", required_argument, 0, 'g'},
212 {"mode", required_argument, 0, MODE_OPTION},
213 {"modification-time", no_argument, 0, OBSOLETE_TOUCH},
214 {"multi-volume", no_argument, 0, 'M'},
215 {"new-volume-script", required_argument, 0, 'F'},
216 {"newer", required_argument, 0, 'N'},
217 {"newer-mtime", required_argument, 0, NEWER_MTIME_OPTION},
218 {"null", no_argument, 0, NULL_OPTION},
219 {"no-recursion", no_argument, 0, NO_RECURSE_OPTION},
220 {"no-same-owner", no_argument, &same_owner_option, -1},
221 {"no-same-permissions", no_argument, &same_permissions_option, -1},
222 {"numeric-owner", no_argument, &numeric_owner_option, 1},
223 {"old-archive", no_argument, 0, 'o'},
224 {"one-file-system", no_argument, 0, 'l'},
225 {"overwrite", no_argument, 0, OVERWRITE_OPTION},
226 {"owner", required_argument, 0, OWNER_OPTION},
227 {"portability", no_argument, 0, 'o'},
228 {"posix", no_argument, 0, POSIX_OPTION},
229 {"preserve", no_argument, 0, PRESERVE_OPTION},
230 {"preserve-order", no_argument, 0, 's'},
231 {"preserve-permissions", no_argument, 0, 'p'},
232 {"recursive-unlink", no_argument, &recursive_unlink_option, 1},
233 {"read-full-blocks", no_argument, 0, OBSOLETE_READ_FULL_RECORDS},
234 {"read-full-records", no_argument, 0, 'B'},
235 /* FIXME: --partial-blocks might be a synonym for --read-full-records? */
236 {"record-number", no_argument, 0, OBSOLETE_BLOCK_NUMBER},
237 {"record-size", required_argument, 0, RECORD_SIZE_OPTION},
238 {"remove-files", no_argument, &remove_files_option, 1},
239 {"rsh-command", required_argument, 0, RSH_COMMAND_OPTION},
240 {"same-order", no_argument, 0, 's'},
241 {"same-owner", no_argument, &same_owner_option, 1},
242 {"same-permissions", no_argument, 0, 'p'},
243 {"show-omitted-dirs", no_argument, &show_omitted_dirs_option, 1},
244 {"sparse", no_argument, 0, 'S'},
245 {"starting-file", required_argument, 0, 'K'},
246 {"suffix", required_argument, 0, SUFFIX_OPTION},
247 {"tape-length", required_argument, 0, 'L'},
248 {"to-stdout", no_argument, 0, 'O'},
249 {"totals", no_argument, &totals_option, 1},
250 {"touch", no_argument, 0, 'm'},
251 {"uncompress", no_argument, 0, 'Z'},
252 {"ungzip", no_argument, 0, 'z'},
253 {"unlink-first", no_argument, 0, 'U'},
254 {"update", no_argument, 0, 'u'},
255 {"use-compress-program", required_argument, 0, USE_COMPRESS_PROGRAM_OPTION},
256 {"verbose", no_argument, 0, 'v'},
257 {"verify", no_argument, 0, 'W'},
258 {"version", no_argument, &show_version, 1},
259 {"version-control", required_argument, 0, OBSOLETE_VERSION_CONTROL},
260 {"volno-file", required_argument, 0, VOLNO_FILE_OPTION},
261
262 {0, 0, 0, 0}
263 };
264
265 /* Print a usage message and exit with STATUS. */
266 static void
267 usage (int status)
268 {
269 if (status != TAREXIT_SUCCESS)
270 fprintf (stderr, _("Try `%s --help' for more information.\n"),
271 program_name);
272 else
273 {
274 fputs (_("\
275 GNU `tar' saves many files together into a single tape or disk archive, and\n\
276 can restore individual files from the archive.\n"),
277 stdout);
278 printf (_("\nUsage: %s [OPTION]... [FILE]...\n\
279 \n\
280 Examples:\n\
281 %s -cf archive.tar foo bar # Create archive.tar from files foo and bar.\n\
282 %s -tvf archive.tar # List all files in archive.tar verbosely.\n\
283 %s -xf archive.tar # Extract all files from archive.tar.\n"),
284 program_name, program_name, program_name, program_name);
285 fputs (_("\
286 \n\
287 If a long option shows an argument as mandatory, then it is mandatory\n\
288 for the equivalent short option also. Similarly for optional arguments.\n"),
289 stdout);
290 fputs(_("\
291 \n\
292 Main operation mode:\n\
293 -t, --list list the contents of an archive\n\
294 -x, --extract, --get extract files from an archive\n\
295 -c, --create create a new archive\n\
296 -d, --diff, --compare find differences between archive and file system\n\
297 -r, --append append files to the end of an archive\n\
298 -u, --update only append files newer than copy in archive\n\
299 -A, --catenate append tar files to an archive\n\
300 --concatenate same as -A\n\
301 --delete delete from the archive (not on mag tapes!)\n"),
302 stdout);
303 fputs (_("\
304 \n\
305 Operation modifiers:\n\
306 -W, --verify attempt to verify the archive after writing it\n\
307 --remove-files remove files after adding them to the archive\n\
308 -k, --keep-old-files don't replace existing files when extracting\n\
309 --overwrite overwrite existing files when extracting\n\
310 -U, --unlink-first remove each file prior to extracting over it\n\
311 --recursive-unlink empty hierarchies prior to extracting directory\n\
312 -S, --sparse handle sparse files efficiently\n\
313 -O, --to-stdout extract files to standard output\n\
314 -G, --incremental handle old GNU-format incremental backup\n\
315 -g, --listed-incremental=FILE\n\
316 handle new GNU-format incremental backup\n\
317 --ignore-failed-read do not exit with nonzero on unreadable files\n"),
318 stdout);
319 fputs (_("\
320 \n\
321 Handling of file attributes:\n\
322 --owner=NAME force NAME as owner for added files\n\
323 --group=NAME force NAME as group for added files\n\
324 --mode=CHANGES force (symbolic) mode CHANGES for added files\n\
325 --atime-preserve don't change access times on dumped files\n\
326 -m, --modification-time don't extract file modified time\n\
327 --same-owner try extracting files with the same ownership\n\
328 --no-same-owner extract files as yourself\n\
329 --numeric-owner always use numbers for user/group names\n\
330 -p, --same-permissions extract permissions information\n\
331 --no-same-permissions do not extract permissions information\n\
332 --preserve-permissions same as -p\n\
333 -s, --same-order sort names to extract to match archive\n\
334 --preserve-order same as -s\n\
335 --preserve same as both -p and -s\n"),
336 stdout);
337 fputs (_("\
338 \n\
339 Device selection and switching:\n\
340 -f, --file=ARCHIVE use archive file or device ARCHIVE\n\
341 --force-local archive file is local even if has a colon\n\
342 --rsh-command=COMMAND use remote COMMAND instead of rsh\n\
343 -[0-7][lmh] specify drive and density\n\
344 -M, --multi-volume create/list/extract multi-volume archive\n\
345 -L, --tape-length=NUM change tape after writing NUM x 1024 bytes\n\
346 -F, --info-script=FILE run script at end of each tape (implies -M)\n\
347 --new-volume-script=FILE same as -F FILE\n\
348 --volno-file=FILE use/update the volume number in FILE\n"),
349 stdout);
350 fputs (_("\
351 \n\
352 Device blocking:\n\
353 -b, --blocking-factor=BLOCKS BLOCKS x 512 bytes per record\n\
354 --record-size=SIZE SIZE bytes per record, multiple of 512\n\
355 -i, --ignore-zeros ignore zeroed blocks in archive (means EOF)\n\
356 -B, --read-full-records reblock as we read (for 4.2BSD pipes)\n"),
357 stdout);
358 fputs (_("\
359 \n\
360 Archive format selection:\n\
361 -V, --label=NAME create archive with volume name NAME\n\
362 PATTERN at list/extract time, a globbing PATTERN\n\
363 -o, --old-archive, --portability write a V7 format archive\n\
364 --posix write a POSIX format archive\n\
365 -j, --bzip2 filter the archive through bzip2\n\
366 -z, --gzip, --ungzip filter the archive through gzip\n\
367 -Z, --compress, --uncompress filter the archive through compress\n\
368 --use-compress-program=PROG filter through PROG (must accept -d)\n"),
369 stdout);
370 fputs (_("\
371 \n\
372 Local file selection:\n\
373 -C, --directory=DIR change to directory DIR\n\
374 -T, -I, --files-from=NAME get names to extract or create from file NAME\n\
375 --null -T reads null-terminated names, disable -C\n\
376 --exclude=PATTERN exclude files, given as a globbing PATTERN\n\
377 -X, --exclude-from=FILE exclude globbing patterns listed in FILE\n\
378 -P, --absolute-names don't strip leading `/'s from file names\n\
379 -h, --dereference dump instead the files symlinks point to\n\
380 --no-recursion avoid descending automatically in directories\n\
381 -l, --one-file-system stay in local file system when creating archive\n\
382 -K, --starting-file=NAME begin at file NAME in the archive\n"),
383 stdout);
384 #if !MSDOS
385 fputs (_("\
386 -N, --newer=DATE only store files newer than DATE\n\
387 --newer-mtime compare date and time when data changed only\n\
388 --after-date=DATE same as -N\n"),
389 stdout);
390 #endif
391 fputs (_("\
392 --backup[=CONTROL] backup before removal, choose version control\n\
393 --suffix=SUFFIX backup before removal, override usual suffix\n"),
394 stdout);
395 fputs (_("\
396 \n\
397 Informative output:\n\
398 --help print this help, then exit\n\
399 --version print tar program version number, then exit\n\
400 -v, --verbose verbosely list files processed\n\
401 --checkpoint print directory names while reading the archive\n\
402 --totals print total bytes written while creating archive\n\
403 -R, --block-number show block number within archive with each message\n\
404 -w, --interactive ask for confirmation for every action\n\
405 --confirmation same as -w\n"),
406 stdout);
407 fputs (_("\
408 \n\
409 The backup suffix is `~', unless set with --suffix or SIMPLE_BACKUP_SUFFIX.\n\
410 The version control may be set with --backup or VERSION_CONTROL, values are:\n\
411 \n\
412 t, numbered make numbered backups\n\
413 nil, existing numbered if numbered backups exist, simple otherwise\n\
414 never, simple always make simple backups\n"),
415 stdout);
416 printf (_("\
417 \n\
418 GNU tar cannot read nor produce `--posix' archives. If POSIXLY_CORRECT\n\
419 is set in the environment, GNU extensions are disallowed with `--posix'.\n\
420 Support for POSIX is only partially implemented, don't count on it yet.\n\
421 ARCHIVE may be FILE, HOST:FILE or USER@HOST:FILE; and FILE may be a file\n\
422 or a device. *This* `tar' defaults to `-f%s -b%d'.\n"),
423 DEFAULT_ARCHIVE, DEFAULT_BLOCKING);
424 fputs (_("\nReport bugs to <bug-tar@gnu.org>.\n"), stdout);
425 }
426 exit (status);
427 }
428
429 /* Parse the options for tar. */
430
431 /* Available option letters are DEHJQY and aenqy. Some are reserved:
432
433 e exit immediately with a nonzero exit status if unexpected errors occur
434 E use extended headers (draft POSIX headers, that is)
435 n the archive is quickly seekable, so don't worry about random seeks
436 q stop after extracting the first occurrence of the named file
437 y per-file gzip compression
438 Y per-block gzip compression */
439
440 #define OPTION_STRING \
441 "-01234567ABC:F:GIK:L:MN:OPRST:UV:WX:Zb:cdf:g:hijklmoprstuvwxz"
442
443 static void
444 set_subcommand_option (enum subcommand subcommand)
445 {
446 if (subcommand_option != UNKNOWN_SUBCOMMAND
447 && subcommand_option != subcommand)
448 USAGE_ERROR ((0, 0,
449 _("You may not specify more than one `-Acdtrux' option")));
450
451 subcommand_option = subcommand;
452 }
453
454 static void
455 set_use_compress_program_option (const char *string)
456 {
457 if (use_compress_program_option && strcmp (use_compress_program_option, string) != 0)
458 USAGE_ERROR ((0, 0, _("Conflicting compression options")));
459
460 use_compress_program_option = string;
461 }
462
463 /* Ignore DUMMY (which will always be null in practice), and add
464 PATTERN to the proper set of patterns to be excluded -- either
465 patterns with slashes, or patterns without. */
466 static void
467 add_filtered_exclude (struct exclude *dummy, char const *pattern)
468 {
469 add_exclude ((strchr (pattern, '/')
470 ? excluded_with_slash
471 : excluded_without_slash),
472 pattern);
473 }
474
475 static void
476 decode_options (int argc, char **argv)
477 {
478 int optchar; /* option letter */
479 int input_files; /* number of input files */
480 const char *backup_suffix_string;
481 const char *version_control_string = 0;
482
483 /* Set some default option values. */
484
485 subcommand_option = UNKNOWN_SUBCOMMAND;
486 archive_format = DEFAULT_FORMAT;
487 blocking_factor = DEFAULT_BLOCKING;
488 record_size = DEFAULT_BLOCKING * BLOCKSIZE;
489 excluded_with_slash = new_exclude ();
490 excluded_without_slash = new_exclude ();
491 newer_mtime_option = TYPE_MINIMUM (time_t);
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 NO_RECURSE_OPTION:
889 no_recurse_option = 1;
890 break;
891
892 case NULL_OPTION:
893 filename_terminator = '\0';
894 break;
895
896 case OVERWRITE_OPTION:
897 old_files_option = OVERWRITE_OLD_FILES;
898 break;
899
900 case OWNER_OPTION:
901 if (! (strlen (optarg) < UNAME_FIELD_SIZE
902 && uname_to_uid (optarg, &owner_option)))
903 {
904 uintmax_t u;
905 if (xstrtoumax (optarg, 0, 10, &u, "") == LONGINT_OK
906 && u == (uid_t) u)
907 owner_option = u;
908 else
909 FATAL_ERROR ((0, 0, "%s: %s", quotearg_colon (optarg),
910 _("Invalid owner")));
911 }
912 break;
913
914 case POSIX_OPTION:
915 #if OLDGNU_COMPATIBILITY
916 if (archive_format == DEFAULT_FORMAT)
917 archive_format = GNU_FORMAT;
918 else if (archive_format != GNU_FORMAT)
919 USAGE_ERROR ((0, 0, _("Conflicting archive format options")));
920 #else
921 if (archive_format == DEFAULT_FORMAT)
922 archive_format = POSIX_FORMAT;
923 else if (archive_format != POSIX_FORMAT)
924 USAGE_ERROR ((0, 0, _("Conflicting archive format options")));
925 #endif
926 break;
927
928 case PRESERVE_OPTION:
929 same_permissions_option = 1;
930 same_order_option = 1;
931 break;
932
933 case RECORD_SIZE_OPTION:
934 {
935 uintmax_t u;
936 if (! (xstrtoumax (optarg, 0, 10, &u, "") == LONGINT_OK
937 && u == (size_t) u))
938 USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (optarg),
939 _("Invalid record size")));
940 record_size = u;
941 if (record_size % BLOCKSIZE != 0)
942 USAGE_ERROR ((0, 0, _("Record size must be a multiple of %d."),
943 BLOCKSIZE));
944 blocking_factor = record_size / BLOCKSIZE;
945 }
946 break;
947
948 case RSH_COMMAND_OPTION:
949 rsh_command_option = optarg;
950 break;
951
952 case SUFFIX_OPTION:
953 backup_option = 1;
954 backup_suffix_string = optarg;
955 break;
956
957 case VOLNO_FILE_OPTION:
958 volno_file_option = optarg;
959 break;
960
961 case USE_COMPRESS_PROGRAM_OPTION:
962 set_use_compress_program_option (optarg);
963 break;
964
965 case '0':
966 case '1':
967 case '2':
968 case '3':
969 case '4':
970 case '5':
971 case '6':
972 case '7':
973
974 #ifdef DEVICE_PREFIX
975 {
976 int device = optchar - '0';
977 int density;
978 static char buf[sizeof DEVICE_PREFIX + 10];
979 char *cursor;
980
981 density = getopt_long (argc, argv, "lmh", 0, 0);
982 strcpy (buf, DEVICE_PREFIX);
983 cursor = buf + strlen (buf);
984
985 #ifdef DENSITY_LETTER
986
987 sprintf (cursor, "%d%c", device, density);
988
989 #else /* not DENSITY_LETTER */
990
991 switch (density)
992 {
993 case 'l':
994 #ifdef LOW_NUM
995 device += LOW_NUM;
996 #endif
997 break;
998
999 case 'm':
1000 #ifdef MID_NUM
1001 device += MID_NUM;
1002 #else
1003 device += 8;
1004 #endif
1005 break;
1006
1007 case 'h':
1008 #ifdef HGH_NUM
1009 device += HGH_NUM;
1010 #else
1011 device += 16;
1012 #endif
1013 break;
1014
1015 default:
1016 usage (TAREXIT_FAILURE);
1017 }
1018 sprintf (cursor, "%d", device);
1019
1020 #endif /* not DENSITY_LETTER */
1021
1022 if (archive_names == allocated_archive_names)
1023 {
1024 allocated_archive_names *= 2;
1025 archive_name_array =
1026 xrealloc (archive_name_array,
1027 sizeof (const char *) * allocated_archive_names);
1028 }
1029 archive_name_array[archive_names++] = buf;
1030
1031 /* FIXME: How comes this works for many archives when buf is
1032 not xstrdup'ed? */
1033 }
1034 break;
1035
1036 #else /* not DEVICE_PREFIX */
1037
1038 USAGE_ERROR ((0, 0,
1039 _("Options `-[0-7][lmh]' not supported by *this* tar")));
1040
1041 #endif /* not DEVICE_PREFIX */
1042 }
1043
1044 /* Handle operands after any "--" argument. */
1045 for (; optind < argc; optind++)
1046 {
1047 name_add (argv[optind]);
1048 input_files++;
1049 }
1050
1051 /* Process trivial options. */
1052
1053 if (show_version)
1054 {
1055 printf ("tar (GNU %s) %s\n%s\n%s\n%s\n", PACKAGE, VERSION,
1056 "Copyright 2000 Free Software Foundation, Inc.",
1057 _("\
1058 This program comes with NO WARRANTY, to the extent permitted by law.\n\
1059 You may redistribute it under the terms of the GNU General Public License;\n\
1060 see the file named COPYING for details."),
1061 _("Written by John Gilmore and Jay Fenlason."));
1062 exit (TAREXIT_SUCCESS);
1063 }
1064
1065 if (show_help)
1066 usage (TAREXIT_SUCCESS);
1067
1068 /* Derive option values and check option consistency. */
1069
1070 if (archive_format == DEFAULT_FORMAT)
1071 {
1072 #if OLDGNU_COMPATIBILITY
1073 archive_format = OLDGNU_FORMAT;
1074 #else
1075 archive_format = GNU_FORMAT;
1076 #endif
1077 }
1078
1079 if (archive_format == GNU_FORMAT && getenv ("POSIXLY_CORRECT"))
1080 archive_format = POSIX_FORMAT;
1081
1082 if ((volume_label_option
1083 || incremental_option || multi_volume_option || sparse_option)
1084 && archive_format != OLDGNU_FORMAT && archive_format != GNU_FORMAT)
1085 USAGE_ERROR ((0, 0,
1086 _("GNU features wanted on incompatible archive format")));
1087
1088 if (archive_names == 0)
1089 {
1090 /* If no archive file name given, try TAPE from the environment, or
1091 else, DEFAULT_ARCHIVE from the configuration process. */
1092
1093 archive_names = 1;
1094 archive_name_array[0] = getenv ("TAPE");
1095 if (! archive_name_array[0])
1096 archive_name_array[0] = DEFAULT_ARCHIVE;
1097 }
1098
1099 /* Allow multiple archives only with `-M'. */
1100
1101 if (archive_names > 1 && !multi_volume_option)
1102 USAGE_ERROR ((0, 0,
1103 _("Multiple archive files requires `-M' option")));
1104
1105 if (listed_incremental_option
1106 && newer_mtime_option != TYPE_MINIMUM (time_t))
1107 USAGE_ERROR ((0, 0,
1108 _("Cannot combine --listed-incremental with --newer")));
1109
1110 if (volume_label_option)
1111 {
1112 size_t volume_label_max_len =
1113 (sizeof current_header->header.name
1114 - 1 /* for trailing '\0' */
1115 - (multi_volume_option
1116 ? (sizeof " Volume "
1117 - 1 /* for null at end of " Volume " */
1118 + INT_STRLEN_BOUND (int) /* for volume number */
1119 - 1 /* for sign, as 0 <= volno */)
1120 : 0));
1121 if (volume_label_max_len < strlen (volume_label_option))
1122 USAGE_ERROR ((0, 0,
1123 _("%s: Volume label is too long (limit is %lu bytes)"),
1124 quotearg_colon (volume_label_option),
1125 (unsigned long) volume_label_max_len));
1126 }
1127
1128 /* If ready to unlink hierarchies, so we are for simpler files. */
1129 if (recursive_unlink_option)
1130 old_files_option = UNLINK_FIRST_OLD_FILES;
1131
1132 /* Forbid using -c with no input files whatsoever. Check that `-f -',
1133 explicit or implied, is used correctly. */
1134
1135 switch (subcommand_option)
1136 {
1137 case CREATE_SUBCOMMAND:
1138 if (input_files == 0 && !files_from_option)
1139 USAGE_ERROR ((0, 0,
1140 _("Cowardly refusing to create an empty archive")));
1141 break;
1142
1143 case EXTRACT_SUBCOMMAND:
1144 case LIST_SUBCOMMAND:
1145 case DIFF_SUBCOMMAND:
1146 for (archive_name_cursor = archive_name_array;
1147 archive_name_cursor < archive_name_array + archive_names;
1148 archive_name_cursor++)
1149 if (!strcmp (*archive_name_cursor, "-"))
1150 request_stdin ("-f");
1151 break;
1152
1153 case CAT_SUBCOMMAND:
1154 case UPDATE_SUBCOMMAND:
1155 case APPEND_SUBCOMMAND:
1156 for (archive_name_cursor = archive_name_array;
1157 archive_name_cursor < archive_name_array + archive_names;
1158 archive_name_cursor++)
1159 if (!strcmp (*archive_name_cursor, "-"))
1160 USAGE_ERROR ((0, 0,
1161 _("Options `-Aru' are incompatible with `-f -'")));
1162
1163 default:
1164 break;
1165 }
1166
1167 archive_name_cursor = archive_name_array;
1168
1169 /* Prepare for generating backup names. */
1170
1171 if (backup_suffix_string)
1172 simple_backup_suffix = xstrdup (backup_suffix_string);
1173
1174 if (backup_option)
1175 backup_type = xget_version ("--backup", version_control_string);
1176 }
1177 \f
1178 /* Tar proper. */
1179
1180 /* Main routine for tar. */
1181 int
1182 main (int argc, char **argv)
1183 {
1184 #if HAVE_CLOCK_GETTIME
1185 if (clock_gettime (CLOCK_REALTIME, &start_timespec) != 0)
1186 #endif
1187 start_time = time (0);
1188 program_name = argv[0];
1189 setlocale (LC_ALL, "");
1190 bindtextdomain (PACKAGE, LOCALEDIR);
1191 textdomain (PACKAGE);
1192
1193 exit_status = TAREXIT_SUCCESS;
1194 filename_terminator = '\n';
1195 set_quoting_style (0, escape_quoting_style);
1196
1197 /* Pre-allocate a few structures. */
1198
1199 allocated_archive_names = 10;
1200 archive_name_array =
1201 xmalloc (sizeof (const char *) * allocated_archive_names);
1202 archive_names = 0;
1203
1204 #ifdef SIGCHLD
1205 /* System V fork+wait does not work if SIGCHLD is ignored. */
1206 signal (SIGCHLD, SIG_DFL);
1207 #endif
1208
1209 init_names ();
1210
1211 /* Decode options. */
1212
1213 decode_options (argc, argv);
1214 name_init (argc, argv);
1215
1216 /* Main command execution. */
1217
1218 if (volno_file_option)
1219 init_volume_number ();
1220
1221 switch (subcommand_option)
1222 {
1223 case UNKNOWN_SUBCOMMAND:
1224 USAGE_ERROR ((0, 0,
1225 _("You must specify one of the `-Acdtrux' options")));
1226
1227 case CAT_SUBCOMMAND:
1228 case UPDATE_SUBCOMMAND:
1229 case APPEND_SUBCOMMAND:
1230 update_archive ();
1231 break;
1232
1233 case DELETE_SUBCOMMAND:
1234 delete_archive_members ();
1235 break;
1236
1237 case CREATE_SUBCOMMAND:
1238 create_archive ();
1239 name_close ();
1240
1241 if (totals_option)
1242 print_total_written ();
1243 break;
1244
1245 case EXTRACT_SUBCOMMAND:
1246 extr_init ();
1247 read_and (extract_archive);
1248 extract_finish ();
1249 break;
1250
1251 case LIST_SUBCOMMAND:
1252 read_and (list_archive);
1253 break;
1254
1255 case DIFF_SUBCOMMAND:
1256 diff_init ();
1257 read_and (diff_archive);
1258 break;
1259 }
1260
1261 if (volno_file_option)
1262 closeout_volume_number ();
1263
1264 /* Dispose of allocated memory, and return. */
1265
1266 free (archive_name_array);
1267 name_term ();
1268
1269 if (stdlis == stdout && (ferror (stdout) || fclose (stdout) != 0))
1270 FATAL_ERROR ((0, 0, _("Error in writing to standard output")));
1271 if (exit_status == TAREXIT_FAILURE)
1272 error (0, 0, _("Error exit delayed from previous errors"));
1273 exit (exit_status);
1274 }
This page took 0.098472 seconds and 4 git commands to generate.