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