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