]> Dogcows Code - chaz/tar/blob - src/tar.c
Remove lint.
[chaz/tar] / src / tar.c
1 /* A tar (tape archiver) program.
2 Copyright 1988, 92,93,94,95,96,97, 1999 Free Software Foundation, Inc.
3 Written by John Gilmore, starting 1985-08-25.
4
5 This program is free software; you can redistribute it and/or modify it
6 under the terms of the GNU General Public License as published by the
7 Free Software Foundation; either version 2, or (at your option) any later
8 version.
9
10 This program is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
13 Public License for more details.
14
15 You should have received a copy of the GNU General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
18
19 #include "system.h"
20
21 #include <getopt.h>
22
23 #include <signal.h>
24 #if ! defined SIGCHLD && defined SIGCLD
25 # define SIGCHLD SIGCLD
26 #endif
27
28 /* The following causes "common.h" to produce definitions of all the global
29 variables, rather than just "extern" declarations of them. GNU tar does
30 depend on the system loader to preset all GLOBAL variables to neutral (or
31 zero) values; explicit initialization 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;
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;
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;
151
152 /* If nonzero, print the version on standard output and exit. */
153 static int show_version;
154
155 struct option long_options[] =
156 {
157 {"absolute-names", no_argument, 0, 'P'},
158 {"absolute-paths", no_argument, 0, OBSOLETE_ABSOLUTE_NAMES},
159 {"after-date", required_argument, 0, 'N'},
160 {"append", no_argument, 0, 'r'},
161 {"atime-preserve", no_argument, &atime_preserve_option, 1},
162 {"backup", optional_argument, 0, BACKUP_OPTION},
163 {"block-compress", no_argument, 0, OBSOLETE_BLOCK_COMPRESS},
164 {"block-number", no_argument, 0, 'R'},
165 {"block-size", required_argument, 0, OBSOLETE_BLOCKING_FACTOR},
166 {"blocking-factor", required_argument, 0, 'b'},
167 {"bzip2", no_argument, 0, 'I'},
168 {"catenate", no_argument, 0, 'A'},
169 {"checkpoint", no_argument, &checkpoint_option, 1},
170 {"compare", no_argument, 0, 'd'},
171 {"compress", no_argument, 0, 'Z'},
172 {"concatenate", no_argument, 0, 'A'},
173 {"confirmation", no_argument, 0, 'w'},
174 /* FIXME: --selective as a synonym for --confirmation? */
175 {"create", no_argument, 0, 'c'},
176 {"delete", no_argument, 0, DELETE_OPTION},
177 {"dereference", no_argument, 0, 'h'},
178 {"diff", no_argument, 0, 'd'},
179 {"directory", required_argument, 0, 'C'},
180 {"exclude", required_argument, 0, EXCLUDE_OPTION},
181 {"exclude-from", required_argument, 0, 'X'},
182 {"extract", no_argument, 0, 'x'},
183 {"file", required_argument, 0, 'f'},
184 {"files-from", required_argument, 0, 'T'},
185 {"force-local", no_argument, &force_local_option, 1},
186 {"get", no_argument, 0, 'x'},
187 {"group", required_argument, 0, GROUP_OPTION},
188 {"gunzip", no_argument, 0, 'z'},
189 {"gzip", no_argument, 0, 'z'},
190 {"help", no_argument, &show_help, 1},
191 {"ignore-failed-read", no_argument, &ignore_failed_read_option, 1},
192 {"ignore-zeros", no_argument, 0, 'i'},
193 /* FIXME: --ignore-end as a new name for --ignore-zeros? */
194 {"incremental", no_argument, 0, 'G'},
195 {"info-script", required_argument, 0, 'F'},
196 {"interactive", no_argument, 0, 'w'},
197 {"keep-old-files", no_argument, 0, 'k'},
198 {"label", required_argument, 0, 'V'},
199 {"list", no_argument, 0, 't'},
200 {"listed-incremental", required_argument, 0, 'g'},
201 {"mode", required_argument, 0, MODE_OPTION},
202 {"modification-time", no_argument, 0, OBSOLETE_TOUCH},
203 {"multi-volume", no_argument, 0, 'M'},
204 {"new-volume-script", required_argument, 0, 'F'},
205 {"newer", required_argument, 0, 'N'},
206 {"newer-mtime", required_argument, 0, NEWER_MTIME_OPTION},
207 {"null", no_argument, 0, NULL_OPTION},
208 {"no-recursion", no_argument, 0, NO_RECURSE_OPTION},
209 {"numeric-owner", no_argument, &numeric_owner_option, 1},
210 {"old-archive", no_argument, 0, 'o'},
211 {"one-file-system", no_argument, 0, 'l'},
212 {"owner", required_argument, 0, OWNER_OPTION},
213 {"portability", no_argument, 0, 'o'},
214 {"posix", no_argument, 0, POSIX_OPTION},
215 {"preserve", no_argument, 0, PRESERVE_OPTION},
216 {"preserve-order", no_argument, 0, 's'},
217 {"preserve-permissions", no_argument, 0, 'p'},
218 {"recursive-unlink", no_argument, &recursive_unlink_option, 1},
219 {"read-full-blocks", no_argument, 0, OBSOLETE_READ_FULL_RECORDS},
220 {"read-full-records", no_argument, 0, 'B'},
221 /* FIXME: --partial-blocks might be a synonym for --read-full-records? */
222 {"record-number", no_argument, 0, OBSOLETE_BLOCK_NUMBER},
223 {"record-size", required_argument, 0, RECORD_SIZE_OPTION},
224 {"remove-files", no_argument, &remove_files_option, 1},
225 {"rsh-command", required_argument, 0, RSH_COMMAND_OPTION},
226 {"same-order", no_argument, 0, 's'},
227 {"same-owner", no_argument, &same_owner_option, 1},
228 {"same-permissions", no_argument, 0, 'p'},
229 {"show-omitted-dirs", no_argument, &show_omitted_dirs_option, 1},
230 {"sparse", no_argument, 0, 'S'},
231 {"starting-file", required_argument, 0, 'K'},
232 {"suffix", required_argument, 0, SUFFIX_OPTION},
233 {"tape-length", required_argument, 0, 'L'},
234 {"to-stdout", no_argument, 0, 'O'},
235 {"totals", no_argument, &totals_option, 1},
236 {"touch", no_argument, 0, 'm'},
237 {"uncompress", no_argument, 0, 'Z'},
238 {"ungzip", no_argument, 0, 'z'},
239 {"unlink-first", no_argument, 0, 'U'},
240 {"update", no_argument, 0, 'u'},
241 {"use-compress-program", required_argument, 0, USE_COMPRESS_PROGRAM_OPTION},
242 {"verbose", no_argument, 0, 'v'},
243 {"verify", no_argument, 0, 'W'},
244 {"version", no_argument, &show_version, 1},
245 {"version-control", required_argument, 0, OBSOLETE_VERSION_CONTROL},
246 {"volno-file", required_argument, 0, 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 format archive\n\
344 -I, --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 removal, 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 DEHJQY 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:GIK:L:MN:OPRST:UV:WX:Zb:cdf:g:hiklmoprstuvwxz"
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 = 0;
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 = 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, 0),
538 optchar != -1)
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 triggered 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, 0, 10, &u, "") == LONGINT_OK
571 && u == (blocking_factor = u)
572 && 0 < blocking_factor
573 && u == (record_size = u * 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 =
612 xrealloc (archive_name_array,
613 sizeof (const char *) * allocated_archive_names);
614 }
615 archive_name_array[archive_names++] = optarg;
616 break;
617
618 case 'F':
619 /* Since -F is only useful with -M, make it implied. Run this
620 script at the end of each tape. */
621
622 info_script_option = optarg;
623 multi_volume_option = 1;
624 break;
625
626 case 'g':
627 listed_incremental_option = optarg;
628 after_date_option = 1;
629 /* Fall through. */
630
631 case 'G':
632 /* We are making an incremental dump (FIXME: are we?); save
633 directories at the beginning of the archive, and include in each
634 directory its contents. */
635
636 incremental_option = 1;
637 break;
638
639 case 'h':
640 /* Follow symbolic links. */
641
642 dereference_option = 1;
643 break;
644
645 case 'i':
646 /* Ignore zero blocks (eofs). This can't be the default,
647 because Unix tar writes two blocks of zeros, then pads out
648 the record with garbage. */
649
650 ignore_zeros_option = 1;
651 break;
652
653 case 'I':
654 set_use_compress_program_option ("bzip2");
655 break;
656
657 case 'k':
658 /* Don't overwrite existing files. */
659
660 keep_old_files_option = 1;
661 break;
662
663 case 'K':
664 starting_file_option = 1;
665 addname (optarg, 0);
666 break;
667
668 case 'l':
669 /* When dumping directories, don't dump files/subdirectories
670 that are on other filesystems. */
671
672 one_file_system_option = 1;
673 break;
674
675 case 'L':
676 {
677 uintmax_t u;
678 if (xstrtoumax (optarg, 0, 10, &u, "") != LONGINT_OK)
679 USAGE_ERROR ((0, 0, _("Invalid tape length")));
680 tape_length_option = 1024 * (tarlong) u;
681 multi_volume_option = 1;
682 }
683 break;
684
685 case OBSOLETE_TOUCH:
686 WARN ((0, 0, _("Obsolete option name replaced by --touch")));
687 /* Fall through. */
688
689 case 'm':
690 touch_option = 1;
691 break;
692
693 case 'M':
694 /* Make multivolume archive: when we can't write any more into
695 the archive, re-open it, and continue writing. */
696
697 multi_volume_option = 1;
698 break;
699
700 #if !MSDOS
701 case 'N':
702 after_date_option = 1;
703 /* Fall through. */
704
705 case NEWER_MTIME_OPTION:
706 if (newer_mtime_option != TYPE_MINIMUM (time_t))
707 USAGE_ERROR ((0, 0, _("More than one threshold date")));
708
709 newer_mtime_option = get_date (optarg, 0);
710 if (newer_mtime_option == (time_t) -1)
711 USAGE_ERROR ((0, 0, _("Invalid date format `%s'"), optarg));
712
713 break;
714 #endif /* not MSDOS */
715
716 case 'o':
717 if (archive_format == DEFAULT_FORMAT)
718 archive_format = V7_FORMAT;
719 else if (archive_format != V7_FORMAT)
720 USAGE_ERROR ((0, 0, _("Conflicting archive format options")));
721 break;
722
723 case 'O':
724 to_stdout_option = 1;
725 break;
726
727 case 'p':
728 same_permissions_option = 1;
729 break;
730
731 case OBSOLETE_ABSOLUTE_NAMES:
732 WARN ((0, 0, _("Obsolete option name replaced by --absolute-names")));
733 /* Fall through. */
734
735 case 'P':
736 absolute_names_option = 1;
737 break;
738
739 case 'r':
740 set_subcommand_option (APPEND_SUBCOMMAND);
741 break;
742
743 case OBSOLETE_BLOCK_NUMBER:
744 WARN ((0, 0, _("Obsolete option name replaced by --block-number")));
745 /* Fall through. */
746
747 case 'R':
748 /* Print block numbers for debugging bad tar archives. */
749
750 /* It would surely make sense to exchange -B and -R, but it seems
751 that -B has been used for a long while in Sun tar ans most
752 BSD-derived systems. This is a consequence of the block/record
753 terminology confusion. */
754
755 block_number_option = 1;
756 break;
757
758 case 's':
759 /* Names to extr are sorted. */
760
761 same_order_option = 1;
762 break;
763
764 case 'S':
765 sparse_option = 1;
766 break;
767
768 case 't':
769 set_subcommand_option (LIST_SUBCOMMAND);
770 verbose_option++;
771 break;
772
773 case 'T':
774 files_from_option = optarg;
775 break;
776
777 case 'u':
778 set_subcommand_option (UPDATE_SUBCOMMAND);
779 break;
780
781 case 'U':
782 unlink_first_option = 1;
783 break;
784
785 case 'v':
786 verbose_option++;
787 break;
788
789 case 'V':
790 volume_label_option = optarg;
791 break;
792
793 case 'w':
794 interactive_option = 1;
795 break;
796
797 case 'W':
798 verify_option = 1;
799 break;
800
801 case 'x':
802 set_subcommand_option (EXTRACT_SUBCOMMAND);
803 break;
804
805 case 'X':
806 if (add_exclude_file (add_filtered_exclude, 0, optarg, '\n') != 0)
807 FATAL_ERROR ((0, errno, "%s", optarg));
808 break;
809
810 case 'z':
811 set_use_compress_program_option ("gzip");
812 break;
813
814 case 'Z':
815 set_use_compress_program_option ("compress");
816 break;
817
818 case OBSOLETE_VERSION_CONTROL:
819 WARN ((0, 0, _("Obsolete option name replaced by --backup")));
820 /* Fall through. */
821
822 case BACKUP_OPTION:
823 backup_option = 1;
824 if (optarg)
825 version_control_string = optarg;
826 break;
827
828 case DELETE_OPTION:
829 set_subcommand_option (DELETE_SUBCOMMAND);
830 break;
831
832 case EXCLUDE_OPTION:
833 add_filtered_exclude (0, optarg);
834 break;
835
836 case GROUP_OPTION:
837 if (! (strlen (optarg) < GNAME_FIELD_SIZE
838 && gname_to_gid (optarg, &group_option)))
839 {
840 uintmax_t g;
841 if (xstrtoumax (optarg, 0, 10, &g, "") == LONGINT_OK
842 && g == (gid_t) g)
843 group_option = g;
844 else
845 FATAL_ERROR ((0, 0, _("Invalid group given on option")));
846 }
847 break;
848
849 case MODE_OPTION:
850 mode_option
851 = mode_compile (optarg,
852 MODE_MASK_EQUALS | MODE_MASK_PLUS | MODE_MASK_MINUS);
853 if (mode_option == MODE_INVALID)
854 FATAL_ERROR ((0, 0, _("Invalid mode given on option")));
855 if (mode_option == MODE_MEMORY_EXHAUSTED)
856 FATAL_ERROR ((0, 0, _("Memory exhausted")));
857 break;
858
859 case NO_RECURSE_OPTION:
860 no_recurse_option = 1;
861 break;
862
863 case NULL_OPTION:
864 filename_terminator = '\0';
865 break;
866
867 case OWNER_OPTION:
868 if (! (strlen (optarg) < UNAME_FIELD_SIZE
869 && uname_to_uid (optarg, &owner_option)))
870 {
871 uintmax_t u;
872 if (xstrtoumax (optarg, 0, 10, &u, "") == LONGINT_OK
873 && u == (uid_t) u)
874 owner_option = u;
875 else
876 FATAL_ERROR ((0, 0, _("Invalid owner given on option")));
877 }
878 break;
879
880 case POSIX_OPTION:
881 #if OLDGNU_COMPATIBILITY
882 if (archive_format == DEFAULT_FORMAT)
883 archive_format = GNU_FORMAT;
884 else if (archive_format != GNU_FORMAT)
885 USAGE_ERROR ((0, 0, _("Conflicting archive format options")));
886 #else
887 if (archive_format == DEFAULT_FORMAT)
888 archive_format = POSIX_FORMAT;
889 else if (archive_format != POSIX_FORMAT)
890 USAGE_ERROR ((0, 0, _("Conflicting archive format options")));
891 #endif
892 break;
893
894 case PRESERVE_OPTION:
895 same_permissions_option = 1;
896 same_order_option = 1;
897 break;
898
899 case RECORD_SIZE_OPTION:
900 {
901 uintmax_t u;
902 if (! (xstrtoumax (optarg, 0, 10, &u, "") == LONGINT_OK
903 && u == (size_t) u))
904 USAGE_ERROR ((0, 0, _("Invalid record size")));
905 record_size = u;
906 if (record_size % BLOCKSIZE != 0)
907 USAGE_ERROR ((0, 0, _("Record size must be a multiple of %d."),
908 BLOCKSIZE));
909 blocking_factor = record_size / BLOCKSIZE;
910 }
911 break;
912
913 case RSH_COMMAND_OPTION:
914 rsh_command_option = optarg;
915 break;
916
917 case SUFFIX_OPTION:
918 backup_option = 1;
919 backup_suffix_string = optarg;
920 break;
921
922 case VOLNO_FILE_OPTION:
923 volno_file_option = optarg;
924 break;
925
926 case USE_COMPRESS_PROGRAM_OPTION:
927 set_use_compress_program_option (optarg);
928 break;
929
930 case '0':
931 case '1':
932 case '2':
933 case '3':
934 case '4':
935 case '5':
936 case '6':
937 case '7':
938
939 #ifdef DEVICE_PREFIX
940 {
941 int device = optchar - '0';
942 int density;
943 static char buf[sizeof DEVICE_PREFIX + 10];
944 char *cursor;
945
946 density = getopt_long (argc, argv, "lmh", 0, 0);
947 strcpy (buf, DEVICE_PREFIX);
948 cursor = buf + strlen (buf);
949
950 #ifdef DENSITY_LETTER
951
952 sprintf (cursor, "%d%c", device, density);
953
954 #else /* not DENSITY_LETTER */
955
956 switch (density)
957 {
958 case 'l':
959 #ifdef LOW_NUM
960 device += LOW_NUM;
961 #endif
962 break;
963
964 case 'm':
965 #ifdef MID_NUM
966 device += MID_NUM;
967 #else
968 device += 8;
969 #endif
970 break;
971
972 case 'h':
973 #ifdef HGH_NUM
974 device += HGH_NUM;
975 #else
976 device += 16;
977 #endif
978 break;
979
980 default:
981 usage (TAREXIT_FAILURE);
982 }
983 sprintf (cursor, "%d", device);
984
985 #endif /* not DENSITY_LETTER */
986
987 if (archive_names == allocated_archive_names)
988 {
989 allocated_archive_names *= 2;
990 archive_name_array =
991 xrealloc (archive_name_array,
992 sizeof (const char *) * allocated_archive_names);
993 }
994 archive_name_array[archive_names++] = buf;
995
996 /* FIXME: How comes this works for many archives when buf is
997 not xstrdup'ed? */
998 }
999 break;
1000
1001 #else /* not DEVICE_PREFIX */
1002
1003 USAGE_ERROR ((0, 0,
1004 _("Options `-[0-7][lmh]' not supported by *this* tar")));
1005
1006 #endif /* not DEVICE_PREFIX */
1007 }
1008
1009 /* Handle operands after any "--" argument. */
1010 for (; optind < argc; optind++)
1011 {
1012 name_add (argv[optind]);
1013 input_files++;
1014 }
1015
1016 /* Process trivial options. */
1017
1018 if (show_version)
1019 {
1020 printf ("tar (GNU %s) %s\n", PACKAGE, VERSION);
1021 fputs (_("\
1022 \n\
1023 Copyright 1988, 92,93,94,95,96,97,98, 1999 Free Software Foundation, Inc.\n"),
1024 stdout);
1025 fputs (_("\
1026 This is free software; see the source for copying conditions. There is NO\n\
1027 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"),
1028 stdout);
1029 fputs (_("\
1030 \n\
1031 Written by John Gilmore and Jay Fenlason.\n"),
1032 stdout);
1033 exit (TAREXIT_SUCCESS);
1034 }
1035
1036 if (show_help)
1037 usage (TAREXIT_SUCCESS);
1038
1039 /* Derive option values and check option consistency. */
1040
1041 if (archive_format == DEFAULT_FORMAT)
1042 {
1043 #if OLDGNU_COMPATIBILITY
1044 archive_format = OLDGNU_FORMAT;
1045 #else
1046 archive_format = GNU_FORMAT;
1047 #endif
1048 }
1049
1050 if (archive_format == GNU_FORMAT && getenv ("POSIXLY_CORRECT"))
1051 archive_format = POSIX_FORMAT;
1052
1053 if ((volume_label_option
1054 || incremental_option || multi_volume_option || sparse_option)
1055 && archive_format != OLDGNU_FORMAT && archive_format != GNU_FORMAT)
1056 USAGE_ERROR ((0, 0,
1057 _("GNU features wanted on incompatible archive format")));
1058
1059 if (archive_names == 0)
1060 {
1061 /* If no archive file name given, try TAPE from the environment, or
1062 else, DEFAULT_ARCHIVE from the configuration process. */
1063
1064 archive_names = 1;
1065 archive_name_array[0] = getenv ("TAPE");
1066 if (! archive_name_array[0])
1067 archive_name_array[0] = DEFAULT_ARCHIVE;
1068 }
1069
1070 /* Allow multiple archives only with `-M'. */
1071
1072 if (archive_names > 1 && !multi_volume_option)
1073 USAGE_ERROR ((0, 0,
1074 _("Multiple archive files requires `-M' option")));
1075
1076 if (listed_incremental_option
1077 && newer_mtime_option != TYPE_MINIMUM (time_t))
1078 USAGE_ERROR ((0, 0,
1079 _("Cannot combine --listed-incremental with --newer")));
1080
1081 /* If ready to unlink hierarchies, so we are for simpler files. */
1082 if (recursive_unlink_option)
1083 unlink_first_option = 1;
1084
1085 /* Forbid using -c with no input files whatsoever. Check that `-f -',
1086 explicit or implied, is used correctly. */
1087
1088 switch (subcommand_option)
1089 {
1090 case CREATE_SUBCOMMAND:
1091 if (input_files == 0 && !files_from_option)
1092 USAGE_ERROR ((0, 0,
1093 _("Cowardly refusing to create an empty archive")));
1094 break;
1095
1096 case EXTRACT_SUBCOMMAND:
1097 case LIST_SUBCOMMAND:
1098 case DIFF_SUBCOMMAND:
1099 for (archive_name_cursor = archive_name_array;
1100 archive_name_cursor < archive_name_array + archive_names;
1101 archive_name_cursor++)
1102 if (!strcmp (*archive_name_cursor, "-"))
1103 request_stdin ("-f");
1104 break;
1105
1106 case CAT_SUBCOMMAND:
1107 case UPDATE_SUBCOMMAND:
1108 case APPEND_SUBCOMMAND:
1109 for (archive_name_cursor = archive_name_array;
1110 archive_name_cursor < archive_name_array + archive_names;
1111 archive_name_cursor++)
1112 if (!strcmp (*archive_name_cursor, "-"))
1113 USAGE_ERROR ((0, 0,
1114 _("Options `-Aru' are incompatible with `-f -'")));
1115
1116 default:
1117 break;
1118 }
1119
1120 archive_name_cursor = archive_name_array;
1121
1122 /* Prepare for generating backup names. */
1123
1124 if (backup_suffix_string)
1125 simple_backup_suffix = xstrdup (backup_suffix_string);
1126
1127 if (backup_option)
1128 backup_type = xget_version ("--backup", version_control_string);
1129 }
1130 \f
1131 /* Tar proper. */
1132
1133 /*-----------------------.
1134 | Main routine for tar. |
1135 `-----------------------*/
1136
1137 int
1138 main (int argc, char *const *argv)
1139 {
1140 program_name = argv[0];
1141 setlocale (LC_ALL, "");
1142 bindtextdomain (PACKAGE, LOCALEDIR);
1143 textdomain (PACKAGE);
1144
1145 exit_status = TAREXIT_SUCCESS;
1146 filename_terminator = '\n';
1147
1148 /* Pre-allocate a few structures. */
1149
1150 allocated_archive_names = 10;
1151 archive_name_array =
1152 xmalloc (sizeof (const char *) * allocated_archive_names);
1153 archive_names = 0;
1154
1155 #ifdef SIGCHLD
1156 /* System V fork+wait does not work if SIGCHLD is ignored. */
1157 signal (SIGCHLD, SIG_DFL);
1158 #endif
1159
1160 init_names ();
1161
1162 /* Decode options. */
1163
1164 decode_options (argc, argv);
1165 name_init (argc, argv);
1166
1167 /* Main command execution. */
1168
1169 if (volno_file_option)
1170 init_volume_number ();
1171
1172 switch (subcommand_option)
1173 {
1174 case UNKNOWN_SUBCOMMAND:
1175 USAGE_ERROR ((0, 0,
1176 _("You must specify one of the `-Acdtrux' options")));
1177
1178 case CAT_SUBCOMMAND:
1179 case UPDATE_SUBCOMMAND:
1180 case APPEND_SUBCOMMAND:
1181 update_archive ();
1182 break;
1183
1184 case DELETE_SUBCOMMAND:
1185 delete_archive_members ();
1186 break;
1187
1188 case CREATE_SUBCOMMAND:
1189 create_archive ();
1190 name_close ();
1191
1192 if (totals_option)
1193 print_total_written ();
1194 break;
1195
1196 case EXTRACT_SUBCOMMAND:
1197 extr_init ();
1198 read_and (extract_archive);
1199 break;
1200
1201 case LIST_SUBCOMMAND:
1202 read_and (list_archive);
1203 break;
1204
1205 case DIFF_SUBCOMMAND:
1206 diff_init ();
1207 read_and (diff_archive);
1208 break;
1209 }
1210
1211 if (volno_file_option)
1212 closeout_volume_number ();
1213
1214 /* Dispose of allocated memory, and return. */
1215
1216 free (archive_name_array);
1217 name_term ();
1218
1219 if (stdlis == stdout && (ferror (stdout) || fclose (stdout) != 0))
1220 FATAL_ERROR ((0, 0, _("Error in writing to standard output")));
1221 if (exit_status == TAREXIT_FAILURE)
1222 error (0, 0, _("Error exit delayed from previous errors"));
1223 exit (exit_status);
1224 }
This page took 0.089746 seconds and 5 git commands to generate.