]> Dogcows Code - chaz/tar/blob - src/tar.c
Documented --pax-option
[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 if (archive_format != DEFAULT_FORMAT && archive_format != p->fmt)
146 USAGE_ERROR ((0, 0, _("Conflicting archive format options")));
147
148 archive_format = p->fmt;
149 }
150
151 static const char *
152 archive_format_string (enum archive_format fmt)
153 {
154 struct fmttab const *p;
155
156 for (p = fmttab; p->name; p++)
157 if (p->fmt == fmt)
158 return p->name;
159 return "unknown?";
160 }
161
162 #define FORMAT_MASK(n) (1<<(n))
163
164 static void
165 assert_format(unsigned fmt_mask)
166 {
167 if ((FORMAT_MASK(archive_format) & fmt_mask) == 0)
168 USAGE_ERROR ((0, 0,
169 _("GNU features wanted on incompatible archive format")));
170 }
171
172
173 \f
174 /* Options. */
175
176 /* For long options that unconditionally set a single flag, we have getopt
177 do it. For the others, we share the code for the equivalent short
178 named option, the name of which is stored in the otherwise-unused `val'
179 field of the `struct option'; for long options that have no equivalent
180 short option, we use non-characters as pseudo short options,
181 starting at CHAR_MAX + 1 and going upwards. */
182
183 enum
184 {
185 ANCHORED_OPTION = CHAR_MAX + 1,
186 ATIME_PRESERVE_OPTION,
187 BACKUP_OPTION,
188 CHECKPOINT_OPTION,
189 DELETE_OPTION,
190 EXCLUDE_OPTION,
191 FORCE_LOCAL_OPTION,
192 FORMAT_OPTION,
193 GROUP_OPTION,
194 IGNORE_CASE_OPTION,
195 IGNORE_FAILED_READ_OPTION,
196 INDEX_FILE_OPTION,
197 MODE_OPTION,
198 NEWER_MTIME_OPTION,
199 NO_ANCHORED_OPTION,
200 NO_IGNORE_CASE_OPTION,
201 NO_OVERWRITE_DIR_OPTION,
202 NO_WILDCARDS_OPTION,
203 NO_WILDCARDS_MATCH_SLASH_OPTION,
204 NULL_OPTION,
205 NUMERIC_OWNER_OPTION,
206 OCCURRENCE_OPTION,
207 OVERWRITE_OPTION,
208 OWNER_OPTION,
209 PAX_OPTION,
210 POSIX_OPTION,
211 PRESERVE_OPTION,
212 RECORD_SIZE_OPTION,
213 RECURSIVE_UNLINK_OPTION,
214 REMOVE_FILES_OPTION,
215 RSH_COMMAND_OPTION,
216 SHOW_OMITTED_DIRS_OPTION,
217 STRIP_PATH_OPTION,
218 SUFFIX_OPTION,
219 TOTALS_OPTION,
220 USE_COMPRESS_PROGRAM_OPTION,
221 VOLNO_FILE_OPTION,
222 WILDCARDS_OPTION,
223 WILDCARDS_MATCH_SLASH_OPTION
224 };
225
226 /* If nonzero, display usage information and exit. */
227 static int show_help;
228
229 /* If nonzero, print the version on standard output and exit. */
230 static int show_version;
231
232 static struct option long_options[] =
233 {
234 {"absolute-names", no_argument, 0, 'P'},
235 {"after-date", required_argument, 0, 'N'},
236 {"anchored", no_argument, 0, ANCHORED_OPTION},
237 {"append", no_argument, 0, 'r'},
238 {"atime-preserve", no_argument, 0, ATIME_PRESERVE_OPTION},
239 {"backup", optional_argument, 0, BACKUP_OPTION},
240 {"block-number", no_argument, 0, 'R'},
241 {"blocking-factor", required_argument, 0, 'b'},
242 {"bzip2", no_argument, 0, 'j'},
243 {"catenate", no_argument, 0, 'A'},
244 {"checkpoint", no_argument, 0, CHECKPOINT_OPTION},
245 {"check-links", no_argument, &check_links_option, 1},
246 {"compare", no_argument, 0, 'd'},
247 {"compress", no_argument, 0, 'Z'},
248 {"concatenate", no_argument, 0, 'A'},
249 {"confirmation", no_argument, 0, 'w'},
250 /* FIXME: --selective as a synonym for --confirmation? */
251 {"create", no_argument, 0, 'c'},
252 {"delete", no_argument, 0, DELETE_OPTION},
253 {"dereference", no_argument, 0, 'h'},
254 {"diff", no_argument, 0, 'd'},
255 {"directory", required_argument, 0, 'C'},
256 {"exclude", required_argument, 0, EXCLUDE_OPTION},
257 {"exclude-from", required_argument, 0, 'X'},
258 {"extract", no_argument, 0, 'x'},
259 {"file", required_argument, 0, 'f'},
260 {"files-from", required_argument, 0, 'T'},
261 {"force-local", no_argument, 0, FORCE_LOCAL_OPTION},
262 {"format", required_argument, 0, FORMAT_OPTION},
263 {"get", no_argument, 0, 'x'},
264 {"group", required_argument, 0, GROUP_OPTION},
265 {"gunzip", no_argument, 0, 'z'},
266 {"gzip", no_argument, 0, 'z'},
267 {"help", no_argument, &show_help, 1},
268 {"ignore-case", no_argument, 0, IGNORE_CASE_OPTION},
269 {"ignore-failed-read", no_argument, 0, IGNORE_FAILED_READ_OPTION},
270 {"ignore-zeros", no_argument, 0, 'i'},
271 /* FIXME: --ignore-end as a new name for --ignore-zeros? */
272 {"incremental", no_argument, 0, 'G'},
273 {"index-file", required_argument, 0, INDEX_FILE_OPTION},
274 {"info-script", required_argument, 0, 'F'},
275 {"interactive", no_argument, 0, 'w'},
276 {"keep-old-files", no_argument, 0, 'k'},
277 {"label", required_argument, 0, 'V'},
278 {"list", no_argument, 0, 't'},
279 {"listed-incremental", required_argument, 0, 'g'},
280 {"mode", required_argument, 0, MODE_OPTION},
281 {"multi-volume", no_argument, 0, 'M'},
282 {"new-volume-script", required_argument, 0, 'F'},
283 {"newer", required_argument, 0, 'N'},
284 {"newer-mtime", required_argument, 0, NEWER_MTIME_OPTION},
285 {"null", no_argument, 0, NULL_OPTION},
286 {"no-anchored", no_argument, 0, NO_ANCHORED_OPTION},
287 {"no-ignore-case", no_argument, 0, NO_IGNORE_CASE_OPTION},
288 {"no-overwrite-dir", no_argument, 0, NO_OVERWRITE_DIR_OPTION},
289 {"no-wildcards", no_argument, 0, NO_WILDCARDS_OPTION},
290 {"no-wildcards-match-slash", no_argument, 0, NO_WILDCARDS_MATCH_SLASH_OPTION},
291 {"no-recursion", no_argument, &recursion_option, 0},
292 {"no-same-owner", no_argument, &same_owner_option, -1},
293 {"no-same-permissions", no_argument, &same_permissions_option, -1},
294 {"numeric-owner", no_argument, 0, NUMERIC_OWNER_OPTION},
295 {"occurrence", optional_argument, 0, OCCURRENCE_OPTION},
296 {"old-archive", no_argument, 0, 'o'},
297 {"one-file-system", no_argument, 0, 'l'},
298 {"overwrite", no_argument, 0, OVERWRITE_OPTION},
299 {"owner", required_argument, 0, OWNER_OPTION},
300 {"pax-option", required_argument, 0, PAX_OPTION},
301 {"portability", no_argument, 0, 'o'},
302 {"posix", no_argument, 0, POSIX_OPTION},
303 {"preserve", no_argument, 0, PRESERVE_OPTION},
304 {"preserve-order", no_argument, 0, 's'},
305 {"preserve-permissions", no_argument, 0, 'p'},
306 {"recursion", no_argument, &recursion_option, FNM_LEADING_DIR},
307 {"recursive-unlink", no_argument, 0, RECURSIVE_UNLINK_OPTION},
308 {"read-full-records", no_argument, 0, 'B'},
309 /* FIXME: --partial-blocks might be a synonym for --read-full-records? */
310 {"record-size", required_argument, 0, RECORD_SIZE_OPTION},
311 {"remove-files", no_argument, 0, REMOVE_FILES_OPTION},
312 {"rsh-command", required_argument, 0, RSH_COMMAND_OPTION},
313 {"same-order", no_argument, 0, 's'},
314 {"same-owner", no_argument, &same_owner_option, 1},
315 {"same-permissions", no_argument, 0, 'p'},
316 {"show-omitted-dirs", no_argument, 0, SHOW_OMITTED_DIRS_OPTION},
317 {"sparse", no_argument, 0, 'S'},
318 {"starting-file", required_argument, 0, 'K'},
319 {"strip-path", required_argument, 0, STRIP_PATH_OPTION },
320 {"suffix", required_argument, 0, SUFFIX_OPTION},
321 {"tape-length", required_argument, 0, 'L'},
322 {"to-stdout", no_argument, 0, 'O'},
323 {"totals", no_argument, 0, TOTALS_OPTION},
324 {"touch", no_argument, 0, 'm'},
325 {"uncompress", no_argument, 0, 'Z'},
326 {"ungzip", no_argument, 0, 'z'},
327 {"unlink-first", no_argument, 0, 'U'},
328 {"update", no_argument, 0, 'u'},
329 {"use-compress-program", required_argument, 0, USE_COMPRESS_PROGRAM_OPTION},
330 {"verbose", no_argument, 0, 'v'},
331 {"verify", no_argument, 0, 'W'},
332 {"version", no_argument, &show_version, 1},
333 {"volno-file", required_argument, 0, VOLNO_FILE_OPTION},
334 {"wildcards", no_argument, 0, WILDCARDS_OPTION},
335 {"wildcards-match-slash", no_argument, 0, WILDCARDS_MATCH_SLASH_OPTION},
336
337 {0, 0, 0, 0}
338 };
339
340 /* Print a usage message and exit with STATUS. */
341 void
342 usage (int status)
343 {
344 if (status != TAREXIT_SUCCESS)
345 fprintf (stderr, _("Try `%s --help' for more information.\n"),
346 program_name);
347 else
348 {
349 fputs (_("\
350 GNU `tar' saves many files together into a single tape or disk archive, and\n\
351 can restore individual files from the archive.\n"),
352 stdout);
353 printf (_("\nUsage: %s [OPTION]... [FILE]...\n\
354 \n\
355 Examples:\n\
356 %s -cf archive.tar foo bar # Create archive.tar from files foo and bar.\n\
357 %s -tvf archive.tar # List all files in archive.tar verbosely.\n\
358 %s -xf archive.tar # Extract all files from archive.tar.\n"),
359 program_name, program_name, program_name, program_name);
360 fputs (_("\
361 \n\
362 If a long option shows an argument as mandatory, then it is mandatory\n\
363 for the equivalent short option also. Similarly for optional arguments.\n"),
364 stdout);
365 fputs(_("\
366 \n\
367 Main operation mode:\n\
368 -t, --list list the contents of an archive\n\
369 -x, --extract, --get extract files from an archive\n\
370 -c, --create create a new archive\n\
371 -d, --diff, --compare find differences between archive and file system\n\
372 -r, --append append files to the end of an archive\n\
373 -u, --update only append files newer than copy in archive\n\
374 -A, --catenate append tar files to an archive\n\
375 --concatenate same as -A\n\
376 --delete delete from the archive (not on mag tapes!)\n"),
377 stdout);
378 fputs (_("\
379 \n\
380 Operation modifiers:\n\
381 -W, --verify attempt to verify the archive after writing it\n\
382 --remove-files remove files after adding them to the archive\n\
383 -k, --keep-old-files don't replace existing files when extracting\n\
384 --overwrite overwrite existing files when extracting\n\
385 --no-overwrite-dir preserve metadata of existing directories\n\
386 -U, --unlink-first remove each file prior to extracting over it\n\
387 --recursive-unlink empty hierarchies prior to extracting directory\n\
388 -S, --sparse handle sparse files efficiently\n\
389 -O, --to-stdout extract files to standard output\n\
390 -G, --incremental handle old GNU-format incremental backup\n\
391 -g, --listed-incremental=FILE\n\
392 handle new GNU-format incremental backup\n\
393 --ignore-failed-read do not exit with nonzero on unreadable files\n\
394 --occurrence[=NUM] process only the NUMth occurrence of each file in\n\
395 the archive. This option is valid only in\n\
396 conjunction with one of the subcommands --delete,\n\
397 --diff, --extract or --list and when a list of\n\
398 files is given either on the command line or\n\
399 via -T option.\n\
400 NUM defaults to 1.\n"),
401 stdout);
402 fputs (_("\
403 \n\
404 Handling of file attributes:\n\
405 --owner=NAME force NAME as owner for added files\n\
406 --group=NAME force NAME as group for added files\n\
407 --mode=CHANGES force (symbolic) mode CHANGES for added files\n\
408 --atime-preserve don't change access times on dumped files\n\
409 -m, --modification-time don't extract file modified time\n\
410 --same-owner try extracting files with the same ownership\n\
411 --no-same-owner extract files as yourself\n\
412 --numeric-owner always use numbers for user/group names\n\
413 -p, --same-permissions extract permissions information\n\
414 --no-same-permissions do not extract permissions information\n\
415 --preserve-permissions same as -p\n\
416 -s, --same-order sort names to extract to match archive\n\
417 --preserve-order same as -s\n\
418 --preserve same as both -p and -s\n"),
419 stdout);
420 fputs (_("\
421 \n\
422 Device selection and switching:\n\
423 -f, --file=ARCHIVE use archive file or device ARCHIVE\n\
424 --force-local archive file is local even if has a colon\n\
425 --rsh-command=COMMAND use remote COMMAND instead of rsh\n\
426 -[0-7][lmh] specify drive and density\n\
427 -M, --multi-volume create/list/extract multi-volume archive\n\
428 -L, --tape-length=NUM change tape after writing NUM x 1024 bytes\n\
429 -F, --info-script=FILE run script at end of each tape (implies -M)\n\
430 --new-volume-script=FILE same as -F FILE\n\
431 --volno-file=FILE use/update the volume number in FILE\n"),
432 stdout);
433 fputs (_("\
434 \n\
435 Device blocking:\n\
436 -b, --blocking-factor=BLOCKS BLOCKS x 512 bytes per record\n\
437 --record-size=SIZE SIZE bytes per record, multiple of 512\n\
438 -i, --ignore-zeros ignore zeroed blocks in archive (means EOF)\n\
439 -B, --read-full-records reblock as we read (for 4.2BSD pipes)\n"),
440 stdout);
441 fputs (_("\
442 \n\
443 Archive format selection:\n\
444 --format=FMTNAME create archive of the given format.\n\
445 FMTNAME is one of the following:\n\
446 v7 old V7 tar format\n\
447 oldgnu GNU format as per tar <= 1.12\n\
448 gnu GNU tar 1.13 format\n\
449 ustar POSIX 1003.1-1988 (ustar) format\n\
450 posix POSIX 1003.1-2001 (pax) format\n\
451 --old-archive, --portability same as --format=v7\n\
452 --posix same as --format=posix\n\
453 --pax-option keyword[[:]=value][,keyword[[:]=value], ...]\n\
454 control pax keywords\n\
455 -V, --label=NAME create archive with volume name NAME\n\
456 PATTERN at list/extract time, a globbing PATTERN\n\
457 -j, --bzip2 filter the archive through bzip2\n\
458 -z, --gzip, --ungzip filter the archive through gzip\n\
459 -Z, --compress, --uncompress filter the archive through compress\n\
460 --use-compress-program=PROG filter through PROG (must accept -d)\n"),
461 stdout);
462 fputs (_("\
463 \n\
464 Local file selection:\n\
465 -C, --directory=DIR change to directory DIR\n\
466 -T, --files-from=NAME get names to extract or create from file NAME\n\
467 --null -T reads null-terminated names, disable -C\n\
468 --exclude=PATTERN exclude files, given as a PATTERN\n\
469 -X, --exclude-from=FILE exclude patterns listed in FILE\n\
470 --anchored exclude patterns match file name start (default)\n\
471 --no-anchored exclude patterns match after any /\n\
472 --ignore-case exclusion ignores case\n\
473 --no-ignore-case exclusion is case sensitive (default)\n\
474 --wildcards exclude patterns use wildcards (default)\n\
475 --no-wildcards exclude patterns are plain strings\n\
476 --wildcards-match-slash exclude pattern wildcards match '/' (default)\n\
477 --no-wildcards-match-slash exclude pattern wildcards do not match '/'\n\
478 -P, --absolute-names don't strip leading `/'s from file names\n\
479 -h, --dereference dump instead the files symlinks point to\n\
480 --no-recursion avoid descending automatically in directories\n\
481 -l, --one-file-system stay in local file system when creating archive\n\
482 -K, --starting-file=NAME begin at file NAME in the archive\n\
483 --strip-path=NUM strip NUM leading components from file names\n\
484 before extraction\n"),
485 stdout);
486 #if !MSDOS
487 fputs (_("\
488 -N, --newer=DATE-OR-FILE only store files newer than DATE-OR-FILE\n\
489 --newer-mtime=DATE compare date and time when data changed only\n\
490 --after-date=DATE same as -N\n"),
491 stdout);
492 #endif
493 fputs (_("\
494 --backup[=CONTROL] backup before removal, choose version control\n\
495 --suffix=SUFFIX backup before removal, override usual suffix\n"),
496 stdout);
497 fputs (_("\
498 \n\
499 Informative output:\n\
500 --help print this help, then exit\n\
501 --version print tar program version number, then exit\n\
502 -v, --verbose verbosely list files processed\n\
503 --checkpoint print directory names while reading the archive\n\
504 --check-links print a message if not all links are dumped\n\
505 --totals print total bytes written while creating archive\n\
506 --index-file=FILE send verbose output to FILE\n\
507 -R, --block-number show block number within archive with each message\n\
508 -w, --interactive ask for confirmation for every action\n\
509 --confirmation same as -w\n"),
510 stdout);
511 fputs (_("\
512 \n\
513 Compatibility options:\n\
514 -o when creating, same as --old-archive\n\
515 when extracting, same as --no-same-owner\n"),
516 stdout);
517
518 fputs (_("\
519 \n\
520 The backup suffix is `~', unless set with --suffix or SIMPLE_BACKUP_SUFFIX.\n\
521 The version control may be set with --backup or VERSION_CONTROL, values are:\n\
522 \n\
523 t, numbered make numbered backups\n\
524 nil, existing numbered if numbered backups exist, simple otherwise\n\
525 never, simple always make simple backups\n"),
526 stdout);
527 printf (_("\
528 \n\
529 ARCHIVE may be FILE, HOST:FILE or USER@HOST:FILE; DATE may be a textual date\n\
530 or a file name starting with `/' or `.', in which case the file's date is used.\n\
531 *This* `tar' defaults to `--format=%s -f%s -b%d'.\n"),
532 archive_format_string (DEFAULT_ARCHIVE_FORMAT),
533 DEFAULT_ARCHIVE, DEFAULT_BLOCKING);
534 printf (_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
535 }
536 exit (status);
537 }
538
539 /* Parse the options for tar. */
540
541 /* Available option letters are DEHIJQY and aenqy. Some are reserved:
542
543 e exit immediately with a nonzero exit status if unexpected errors occur
544 E use extended headers (draft POSIX headers, that is)
545 I same as T (for compatibility with Solaris tar)
546 n the archive is quickly seekable, so don't worry about random seeks
547 q stop after extracting the first occurrence of the named file
548 y per-file gzip compression
549 Y per-block gzip compression */
550
551 #define OPTION_STRING \
552 "-01234567ABC:F:GIK:L:MN:OPRST:UV:WX:Zb:cdf:g:hijklmoprstuvwxyz"
553
554 static void
555 set_subcommand_option (enum subcommand subcommand)
556 {
557 if (subcommand_option != UNKNOWN_SUBCOMMAND
558 && subcommand_option != subcommand)
559 USAGE_ERROR ((0, 0,
560 _("You may not specify more than one `-Acdtrux' option")));
561
562 subcommand_option = subcommand;
563 }
564
565 static void
566 set_use_compress_program_option (const char *string)
567 {
568 if (use_compress_program_option && strcmp (use_compress_program_option, string) != 0)
569 USAGE_ERROR ((0, 0, _("Conflicting compression options")));
570
571 use_compress_program_option = string;
572 }
573
574 static void
575 decode_options (int argc, char **argv)
576 {
577 int optchar; /* option letter */
578 int input_files; /* number of input files */
579 char const *textual_date_option = 0;
580 char const *backup_suffix_string;
581 char const *version_control_string = 0;
582 int exclude_options = EXCLUDE_WILDCARDS;
583 bool o_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 xheader_set_option (optarg);
1082 break;
1083
1084 case POSIX_OPTION:
1085 set_archive_format ("posix");
1086 break;
1087
1088 case PRESERVE_OPTION:
1089 same_permissions_option = true;
1090 same_order_option = true;
1091 break;
1092
1093 case RECORD_SIZE_OPTION:
1094 {
1095 uintmax_t u;
1096 if (! (xstrtoumax (optarg, 0, 10, &u, "") == LONGINT_OK
1097 && u == (size_t) u))
1098 USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (optarg),
1099 _("Invalid record size")));
1100 record_size = u;
1101 if (record_size % BLOCKSIZE != 0)
1102 USAGE_ERROR ((0, 0, _("Record size must be a multiple of %d."),
1103 BLOCKSIZE));
1104 blocking_factor = record_size / BLOCKSIZE;
1105 }
1106 break;
1107
1108 case RECURSIVE_UNLINK_OPTION:
1109 recursive_unlink_option = true;
1110 break;
1111
1112 case REMOVE_FILES_OPTION:
1113 remove_files_option = true;
1114 break;
1115
1116 case RSH_COMMAND_OPTION:
1117 rsh_command_option = optarg;
1118 break;
1119
1120 case STRIP_PATH_OPTION:
1121 {
1122 uintmax_t u;
1123 if (! (xstrtoumax (optarg, 0, 10, &u, "") == LONGINT_OK
1124 && u == (size_t) u))
1125 USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (optarg),
1126 _("Invalid number of elements")));
1127 strip_path_elements = u;
1128 }
1129 break;
1130
1131 case SUFFIX_OPTION:
1132 backup_option = true;
1133 backup_suffix_string = optarg;
1134 break;
1135
1136 case TOTALS_OPTION:
1137 totals_option = true;
1138 break;
1139
1140 case USE_COMPRESS_PROGRAM_OPTION:
1141 set_use_compress_program_option (optarg);
1142 break;
1143
1144 case VOLNO_FILE_OPTION:
1145 volno_file_option = optarg;
1146 break;
1147
1148 case WILDCARDS_OPTION:
1149 exclude_options |= EXCLUDE_WILDCARDS;
1150 break;
1151
1152 case WILDCARDS_MATCH_SLASH_OPTION:
1153 exclude_options &= ~ FNM_FILE_NAME;
1154 break;
1155
1156 case '0':
1157 case '1':
1158 case '2':
1159 case '3':
1160 case '4':
1161 case '5':
1162 case '6':
1163 case '7':
1164
1165 #ifdef DEVICE_PREFIX
1166 {
1167 int device = optchar - '0';
1168 int density;
1169 static char buf[sizeof DEVICE_PREFIX + 10];
1170 char *cursor;
1171
1172 density = getopt_long (argc, argv, "lmh", 0, 0);
1173 strcpy (buf, DEVICE_PREFIX);
1174 cursor = buf + strlen (buf);
1175
1176 #ifdef DENSITY_LETTER
1177
1178 sprintf (cursor, "%d%c", device, density);
1179
1180 #else /* not DENSITY_LETTER */
1181
1182 switch (density)
1183 {
1184 case 'l':
1185 #ifdef LOW_NUM
1186 device += LOW_NUM;
1187 #endif
1188 break;
1189
1190 case 'm':
1191 #ifdef MID_NUM
1192 device += MID_NUM;
1193 #else
1194 device += 8;
1195 #endif
1196 break;
1197
1198 case 'h':
1199 #ifdef HGH_NUM
1200 device += HGH_NUM;
1201 #else
1202 device += 16;
1203 #endif
1204 break;
1205
1206 default:
1207 usage (TAREXIT_FAILURE);
1208 }
1209 sprintf (cursor, "%d", device);
1210
1211 #endif /* not DENSITY_LETTER */
1212
1213 if (archive_names == allocated_archive_names)
1214 {
1215 allocated_archive_names *= 2;
1216 archive_name_array =
1217 xrealloc (archive_name_array,
1218 sizeof (const char *) * allocated_archive_names);
1219 }
1220 archive_name_array[archive_names++] = strdup (buf);
1221 }
1222 break;
1223
1224 #else /* not DEVICE_PREFIX */
1225
1226 USAGE_ERROR ((0, 0,
1227 _("Options `-[0-7][lmh]' not supported by *this* tar")));
1228
1229 #endif /* not DEVICE_PREFIX */
1230 }
1231
1232 /* Special handling for 'o' option:
1233
1234 GNU tar used to say "output old format".
1235 UNIX98 tar says don't chown files after extracting (we use
1236 "--no-same-owner" for this).
1237
1238 The old GNU tar semantics is retained when used with --create
1239 option, otherwise UNIX98 semantics is assumed */
1240
1241 if (o_option)
1242 {
1243 if (subcommand_option == CREATE_SUBCOMMAND)
1244 {
1245 /* GNU Tar <= 1.13 compatibility */
1246 set_archive_format ("v7");
1247 }
1248 else
1249 {
1250 /* UNIX98 compatibility */
1251 same_owner_option = 1;
1252 }
1253 }
1254
1255 /* Handle operands after any "--" argument. */
1256 for (; optind < argc; optind++)
1257 {
1258 name_add (argv[optind]);
1259 input_files++;
1260 }
1261
1262 /* Process trivial options. */
1263
1264 if (show_version)
1265 {
1266 printf ("tar (%s) %s\n%s\n", PACKAGE_NAME, PACKAGE_VERSION,
1267 "Copyright (C) 2003 Free Software Foundation, Inc.");
1268 puts (_("\
1269 This program comes with NO WARRANTY, to the extent permitted by law.\n\
1270 You may redistribute it under the terms of the GNU General Public License;\n\
1271 see the file named COPYING for details."));
1272
1273 puts (_("Written by John Gilmore and Jay Fenlason."));
1274
1275 exit (TAREXIT_SUCCESS);
1276 }
1277
1278 if (show_help)
1279 usage (TAREXIT_SUCCESS);
1280
1281 /* Derive option values and check option consistency. */
1282
1283 if (archive_format == DEFAULT_FORMAT)
1284 archive_format = DEFAULT_ARCHIVE_FORMAT;
1285
1286 if (volume_label_option && subcommand_option == CREATE_SUBCOMMAND)
1287 assert_format (FORMAT_MASK (OLDGNU_FORMAT)
1288 | FORMAT_MASK (GNU_FORMAT));
1289
1290 if (incremental_option || multi_volume_option)
1291 assert_format (FORMAT_MASK (OLDGNU_FORMAT) | FORMAT_MASK (GNU_FORMAT));
1292
1293
1294 if (sparse_option)
1295 assert_format (FORMAT_MASK (OLDGNU_FORMAT)
1296 | FORMAT_MASK (GNU_FORMAT)
1297 | FORMAT_MASK (POSIX_FORMAT));
1298
1299 if (occurrence_option)
1300 {
1301 if (!input_files && !files_from_option)
1302 USAGE_ERROR ((0, 0,
1303 _("--occurrence is meaningless without a file list")));
1304 if (subcommand_option != DELETE_SUBCOMMAND
1305 && subcommand_option != DIFF_SUBCOMMAND
1306 && subcommand_option != EXTRACT_SUBCOMMAND
1307 && subcommand_option != LIST_SUBCOMMAND)
1308 USAGE_ERROR ((0, 0,
1309 _("--occurrence cannot be used in the requested operation mode")));
1310 }
1311
1312 if (archive_names == 0)
1313 {
1314 /* If no archive file name given, try TAPE from the environment, or
1315 else, DEFAULT_ARCHIVE from the configuration process. */
1316
1317 archive_names = 1;
1318 archive_name_array[0] = getenv ("TAPE");
1319 if (! archive_name_array[0])
1320 archive_name_array[0] = DEFAULT_ARCHIVE;
1321 }
1322
1323 /* Allow multiple archives only with `-M'. */
1324
1325 if (archive_names > 1 && !multi_volume_option)
1326 USAGE_ERROR ((0, 0,
1327 _("Multiple archive files require `-M' option")));
1328
1329 if (listed_incremental_option
1330 && newer_mtime_option != TYPE_MINIMUM (time_t))
1331 USAGE_ERROR ((0, 0,
1332 _("Cannot combine --listed-incremental with --newer")));
1333
1334 if (volume_label_option)
1335 {
1336 size_t volume_label_max_len =
1337 (sizeof current_header->header.name
1338 - 1 /* for trailing '\0' */
1339 - (multi_volume_option
1340 ? (sizeof " Volume "
1341 - 1 /* for null at end of " Volume " */
1342 + INT_STRLEN_BOUND (int) /* for volume number */
1343 - 1 /* for sign, as 0 <= volno */)
1344 : 0));
1345 if (volume_label_max_len < strlen (volume_label_option))
1346 USAGE_ERROR ((0, 0,
1347 ngettext ("%s: Volume label is too long (limit is %lu byte)",
1348 "%s: Volume label is too long (limit is %lu bytes)",
1349 volume_label_max_len),
1350 quotearg_colon (volume_label_option),
1351 (unsigned long) volume_label_max_len));
1352 }
1353
1354 if (verify_option)
1355 {
1356 if (multi_volume_option)
1357 USAGE_ERROR ((0, 0, _("Cannot verify multi-volume archives")));
1358 if (use_compress_program_option)
1359 USAGE_ERROR ((0, 0, _("Cannot verify compressed archives")));
1360 }
1361
1362 if (use_compress_program_option)
1363 {
1364 if (multi_volume_option)
1365 USAGE_ERROR ((0, 0, _("Cannot use multi-volume compressed archives")));
1366 if (subcommand_option == UPDATE_SUBCOMMAND)
1367 USAGE_ERROR ((0, 0, _("Cannot update compressed archives")));
1368 }
1369
1370 /* If ready to unlink hierarchies, so we are for simpler files. */
1371 if (recursive_unlink_option)
1372 old_files_option = UNLINK_FIRST_OLD_FILES;
1373
1374 /* Forbid using -c with no input files whatsoever. Check that `-f -',
1375 explicit or implied, is used correctly. */
1376
1377 switch (subcommand_option)
1378 {
1379 case CREATE_SUBCOMMAND:
1380 if (input_files == 0 && !files_from_option)
1381 USAGE_ERROR ((0, 0,
1382 _("Cowardly refusing to create an empty archive")));
1383 break;
1384
1385 case EXTRACT_SUBCOMMAND:
1386 case LIST_SUBCOMMAND:
1387 case DIFF_SUBCOMMAND:
1388 for (archive_name_cursor = archive_name_array;
1389 archive_name_cursor < archive_name_array + archive_names;
1390 archive_name_cursor++)
1391 if (!strcmp (*archive_name_cursor, "-"))
1392 request_stdin ("-f");
1393 break;
1394
1395 case CAT_SUBCOMMAND:
1396 case UPDATE_SUBCOMMAND:
1397 case APPEND_SUBCOMMAND:
1398 for (archive_name_cursor = archive_name_array;
1399 archive_name_cursor < archive_name_array + archive_names;
1400 archive_name_cursor++)
1401 if (!strcmp (*archive_name_cursor, "-"))
1402 USAGE_ERROR ((0, 0,
1403 _("Options `-Aru' are incompatible with `-f -'")));
1404
1405 default:
1406 break;
1407 }
1408
1409 archive_name_cursor = archive_name_array;
1410
1411 /* Prepare for generating backup names. */
1412
1413 if (backup_suffix_string)
1414 simple_backup_suffix = xstrdup (backup_suffix_string);
1415
1416 if (backup_option)
1417 backup_type = xget_version ("--backup", version_control_string);
1418
1419 if (verbose_option && textual_date_option)
1420 {
1421 char const *treated_as = tartime (newer_mtime_option);
1422 if (strcmp (textual_date_option, treated_as) != 0)
1423 WARN ((0, 0, _("Treating date `%s' as %s"),
1424 textual_date_option, treated_as));
1425 }
1426 }
1427
1428 \f
1429 /* Tar proper. */
1430
1431 /* Main routine for tar. */
1432 int
1433 main (int argc, char **argv)
1434 {
1435 #if HAVE_CLOCK_GETTIME
1436 if (clock_gettime (CLOCK_REALTIME, &start_timespec) != 0)
1437 #endif
1438 start_time = time (0);
1439 program_name = argv[0];
1440 setlocale (LC_ALL, "");
1441 bindtextdomain (PACKAGE, LOCALEDIR);
1442 textdomain (PACKAGE);
1443
1444 exit_status = TAREXIT_SUCCESS;
1445 filename_terminator = '\n';
1446 set_quoting_style (0, escape_quoting_style);
1447
1448 /* Pre-allocate a few structures. */
1449
1450 allocated_archive_names = 10;
1451 archive_name_array =
1452 xmalloc (sizeof (const char *) * allocated_archive_names);
1453 archive_names = 0;
1454
1455 #ifdef SIGCHLD
1456 /* System V fork+wait does not work if SIGCHLD is ignored. */
1457 signal (SIGCHLD, SIG_DFL);
1458 #endif
1459
1460 init_names ();
1461
1462 /* Decode options. */
1463
1464 decode_options (argc, argv);
1465 name_init (argc, argv);
1466
1467 /* Main command execution. */
1468
1469 if (volno_file_option)
1470 init_volume_number ();
1471
1472 switch (subcommand_option)
1473 {
1474 case UNKNOWN_SUBCOMMAND:
1475 USAGE_ERROR ((0, 0,
1476 _("You must specify one of the `-Acdtrux' options")));
1477
1478 case CAT_SUBCOMMAND:
1479 case UPDATE_SUBCOMMAND:
1480 case APPEND_SUBCOMMAND:
1481 update_archive ();
1482 break;
1483
1484 case DELETE_SUBCOMMAND:
1485 delete_archive_members ();
1486 break;
1487
1488 case CREATE_SUBCOMMAND:
1489 create_archive ();
1490 name_close ();
1491
1492 if (totals_option)
1493 print_total_written ();
1494 break;
1495
1496 case EXTRACT_SUBCOMMAND:
1497 extr_init ();
1498 read_and (extract_archive);
1499
1500 /* FIXME: should extract_finish () even if an ordinary signal is
1501 received. */
1502 extract_finish ();
1503
1504 break;
1505
1506 case LIST_SUBCOMMAND:
1507 read_and (list_archive);
1508 break;
1509
1510 case DIFF_SUBCOMMAND:
1511 diff_init ();
1512 read_and (diff_archive);
1513 break;
1514 }
1515
1516 if (check_links_option)
1517 check_links ();
1518
1519 if (volno_file_option)
1520 closeout_volume_number ();
1521
1522 /* Dispose of allocated memory, and return. */
1523
1524 free (archive_name_array);
1525 name_term ();
1526
1527 if (stdlis != stderr && (ferror (stdlis) || fclose (stdlis) != 0))
1528 FATAL_ERROR ((0, 0, _("Error in writing to standard output")));
1529 if (exit_status == TAREXIT_FAILURE)
1530 error (0, 0, _("Error exit delayed from previous errors"));
1531 if (ferror (stderr) || fclose (stderr) != 0)
1532 exit_status = TAREXIT_FAILURE;
1533 return exit_status;
1534 }
1535
1536 void
1537 tar_stat_init (struct tar_stat_info *st)
1538 {
1539 memset (st, 0, sizeof (*st));
1540 }
1541
1542 void
1543 tar_stat_destroy (struct tar_stat_info *st)
1544 {
1545 free (st->orig_file_name);
1546 free (st->file_name);
1547 free (st->link_name);
1548 free (st->uname);
1549 free (st->gname);
1550 free (st->sparse_map);
1551 memset (st, 0, sizeof (*st));
1552 }
1553
This page took 0.101438 seconds and 5 git commands to generate.