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