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