source: trunk/essentials/app-arch/tar/src/tar.c

Last change on this file was 3342, checked in by bird, 18 years ago

tar 1.16.1

File size: 64.2 KB
Line 
1/* A tar (tape archiver) program.
2
3 Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1999, 2000,
4 2001, 2003, 2004, 2005, 2006 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 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
21
22#include <system.h>
23
24#include <fnmatch.h>
25#include <getline.h>
26#include <argp.h>
27#include <argp-namefrob.h>
28#include <argp-fmtstream.h>
29
30#include <signal.h>
31#if ! defined SIGCHLD && defined SIGCLD
32# define SIGCHLD SIGCLD
33#endif
34
35/* The following causes "common.h" to produce definitions of all the global
36 variables, rather than just "extern" declarations of them. GNU tar does
37 depend on the system loader to preset all GLOBAL variables to neutral (or
38 zero) values; explicit initialization is usually not done. */
39#define GLOBAL
40#include "common.h"
41
42#include <argmatch.h>
43#include <closeout.h>
44#include <configmake.h>
45#include <exitfail.h>
46#include <getdate.h>
47#include <rmt.h>
48#include <rmt-command.h>
49#include <prepargs.h>
50#include <quotearg.h>
51#include <version-etc.h>
52#include <xstrtol.h>
53#include <stdopen.h>
54
55/* Local declarations. */
56
57#ifndef DEFAULT_ARCHIVE_FORMAT
58# define DEFAULT_ARCHIVE_FORMAT GNU_FORMAT
59#endif
60
61#ifndef DEFAULT_ARCHIVE
62# define DEFAULT_ARCHIVE "tar.out"
63#endif
64
65#ifndef DEFAULT_BLOCKING
66# define DEFAULT_BLOCKING 20
67#endif
68
69
70
71/* Miscellaneous. */
72
73/* Name of option using stdin. */
74static const char *stdin_used_by;
75
76/* Doesn't return if stdin already requested. */
77void
78request_stdin (const char *option)
79{
80 if (stdin_used_by)
81 USAGE_ERROR ((0, 0, _("Options `-%s' and `-%s' both want standard input"),
82 stdin_used_by, option));
83
84 stdin_used_by = option;
85}
86
87extern int rpmatch (char const *response);
88
89/* Returns true if and only if the user typed an affirmative response. */
90int
91confirm (const char *message_action, const char *message_name)
92{
93 static FILE *confirm_file;
94 static int confirm_file_EOF;
95 bool status = false;
96
97 if (!confirm_file)
98 {
99 if (archive == 0 || stdin_used_by)
100 {
101 confirm_file = fopen (TTY_NAME, "r");
102 if (! confirm_file)
103 open_fatal (TTY_NAME);
104 }
105 else
106 {
107 request_stdin ("-w");
108 confirm_file = stdin;
109 }
110 }
111
112 fprintf (stdlis, "%s %s?", message_action, quote (message_name));
113 fflush (stdlis);
114
115 if (!confirm_file_EOF)
116 {
117 char *response = NULL;
118 size_t response_size = 0;
119 if (getline (&response, &response_size, confirm_file) < 0)
120 confirm_file_EOF = 1;
121 else
122 status = rpmatch (response) > 0;
123 free (response);
124 }
125
126 if (confirm_file_EOF)
127 {
128 fputc ('\n', stdlis);
129 fflush (stdlis);
130 }
131
132 return status;
133}
134
135static struct fmttab {
136 char const *name;
137 enum archive_format fmt;
138} const fmttab[] = {
139 { "v7", V7_FORMAT },
140 { "oldgnu", OLDGNU_FORMAT },
141 { "ustar", USTAR_FORMAT },
142 { "posix", POSIX_FORMAT },
143#if 0 /* not fully supported yet */
144 { "star", STAR_FORMAT },
145#endif
146 { "gnu", GNU_FORMAT },
147 { "pax", POSIX_FORMAT }, /* An alias for posix */
148 { NULL, 0 }
149};
150
151static void
152set_archive_format (char const *name)
153{
154 struct fmttab const *p;
155
156 for (p = fmttab; strcmp (p->name, name) != 0; )
157 if (! (++p)->name)
158 USAGE_ERROR ((0, 0, _("%s: Invalid archive format"),
159 quotearg_colon (name)));
160
161 archive_format = p->fmt;
162}
163
164const char *
165archive_format_string (enum archive_format fmt)
166{
167 struct fmttab const *p;
168
169 for (p = fmttab; p->name; p++)
170 if (p->fmt == fmt)
171 return p->name;
172 return "unknown?";
173}
174
175#define FORMAT_MASK(n) (1<<(n))
176
177static void
178assert_format(unsigned fmt_mask)
179{
180 if ((FORMAT_MASK (archive_format) & fmt_mask) == 0)
181 USAGE_ERROR ((0, 0,
182 _("GNU features wanted on incompatible archive format")));
183}
184
185const char *
186subcommand_string (enum subcommand c)
187{
188 switch (c)
189 {
190 case UNKNOWN_SUBCOMMAND:
191 return "unknown?";
192
193 case APPEND_SUBCOMMAND:
194 return "-r";
195
196 case CAT_SUBCOMMAND:
197 return "-A";
198
199 case CREATE_SUBCOMMAND:
200 return "-c";
201
202 case DELETE_SUBCOMMAND:
203 return "-D";
204
205 case DIFF_SUBCOMMAND:
206 return "-d";
207
208 case EXTRACT_SUBCOMMAND:
209 return "-x";
210
211 case LIST_SUBCOMMAND:
212 return "-t";
213
214 case UPDATE_SUBCOMMAND:
215 return "-u";
216
217 default:
218 abort ();
219 }
220}
221
222void
223tar_list_quoting_styles (argp_fmtstream_t fs, char *prefix)
224{
225 int i;
226
227 for (i = 0; quoting_style_args[i]; i++)
228 argp_fmtstream_printf (fs, "%s%s\n", prefix, quoting_style_args[i]);
229}
230
231void
232tar_set_quoting_style (char *arg)
233{
234 int i;
235
236 for (i = 0; quoting_style_args[i]; i++)
237 if (strcmp (arg, quoting_style_args[i]) == 0)
238 {
239 set_quoting_style (NULL, i);
240 return;
241 }
242 FATAL_ERROR ((0, 0,
243 _("Unknown quoting style `%s'. Try `%s --quoting-style=help' to get a list."), arg, program_invocation_short_name));
244}
245
246
247
248/* Options. */
249
250enum
251{
252 ANCHORED_OPTION = CHAR_MAX + 1,
253 ATIME_PRESERVE_OPTION,
254 BACKUP_OPTION,
255 CHECKPOINT_OPTION,
256 DELAY_DIRECTORY_RESTORE_OPTION,
257 DELETE_OPTION,
258 EXCLUDE_CACHES_OPTION,
259 EXCLUDE_OPTION,
260 EXCLUDE_TAG_OPTION,
261 FORCE_LOCAL_OPTION,
262 GROUP_OPTION,
263 HANG_OPTION,
264 IGNORE_CASE_OPTION,
265 IGNORE_COMMAND_ERROR_OPTION,
266 IGNORE_FAILED_READ_OPTION,
267 INDEX_FILE_OPTION,
268 KEEP_NEWER_FILES_OPTION,
269 MODE_OPTION,
270 MTIME_OPTION,
271 NEWER_MTIME_OPTION,
272 NO_ANCHORED_OPTION,
273 NO_DELAY_DIRECTORY_RESTORE_OPTION,
274 NO_IGNORE_CASE_OPTION,
275 NO_IGNORE_COMMAND_ERROR_OPTION,
276 NO_OVERWRITE_DIR_OPTION,
277 NO_QUOTE_CHARS_OPTION,
278 NO_RECURSION_OPTION,
279 NO_SAME_OWNER_OPTION,
280 NO_SAME_PERMISSIONS_OPTION,
281 NO_UNQUOTE_OPTION,
282 NO_WILDCARDS_MATCH_SLASH_OPTION,
283 NO_WILDCARDS_OPTION,
284 NULL_OPTION,
285 NUMERIC_OWNER_OPTION,
286 OCCURRENCE_OPTION,
287 OLD_ARCHIVE_OPTION,
288 ONE_FILE_SYSTEM_OPTION,
289 OVERWRITE_DIR_OPTION,
290 OVERWRITE_OPTION,
291 OWNER_OPTION,
292 PAX_OPTION,
293 POSIX_OPTION,
294 PRESERVE_OPTION,
295 QUOTE_CHARS_OPTION,
296 QUOTING_STYLE_OPTION,
297 RECORD_SIZE_OPTION,
298 RECURSION_OPTION,
299 RECURSIVE_UNLINK_OPTION,
300 REMOVE_FILES_OPTION,
301 RESTRICT_OPTION,
302 RMT_COMMAND_OPTION,
303 RSH_COMMAND_OPTION,
304 SAME_OWNER_OPTION,
305 SHOW_DEFAULTS_OPTION,
306 SHOW_OMITTED_DIRS_OPTION,
307 SHOW_TRANSFORMED_NAMES_OPTION,
308 SPARSE_VERSION_OPTION,
309 STRIP_COMPONENTS_OPTION,
310 SUFFIX_OPTION,
311 TEST_LABEL_OPTION,
312 TOTALS_OPTION,
313 TO_COMMAND_OPTION,
314 TRANSFORM_OPTION,
315 UNQUOTE_OPTION,
316 USAGE_OPTION,
317 USE_COMPRESS_PROGRAM_OPTION,
318 UTC_OPTION,
319 VERSION_OPTION,
320 VOLNO_FILE_OPTION,
321 WILDCARDS_MATCH_SLASH_OPTION,
322 WILDCARDS_OPTION
323};
324
325const char *argp_program_version = "tar (" PACKAGE_NAME ") " VERSION;
326const char *argp_program_bug_address = "<" PACKAGE_BUGREPORT ">";
327static char const doc[] = N_("\
328GNU `tar' saves many files together into a single tape or disk archive, \
329and can restore individual files from the archive.\n\
330\n\
331Examples:\n\
332 tar -cf archive.tar foo bar # Create archive.tar from files foo and bar.\n\
333 tar -tvf archive.tar # List all files in archive.tar verbosely.\n\
334 tar -xf archive.tar # Extract all files from archive.tar.\n")
335"\v"
336N_("The backup suffix is `~', unless set with --suffix or SIMPLE_BACKUP_SUFFIX.\n\
337The version control may be set with --backup or VERSION_CONTROL, values are:\n\n\
338 none, off never make backups\n\
339 t, numbered make numbered backups\n\
340 nil, existing numbered if numbered backups exist, simple otherwise\n\
341 never, simple always make simple backups\n");
342
343
344/* NOTE:
345
346 Available option letters are DEIJQY and aeqy. Consider the following
347 assignments:
348
349 [For Solaris tar compatibility =/= Is it important at all?]
350 e exit immediately with a nonzero exit status if unexpected errors occur
351 E use extended headers (--format=posix)
352
353 [q alias for --occurrence=1 =/= this would better be used for quiet?]
354 [I same as T =/= will harm star compatibility]
355
356 y per-file gzip compression
357 Y per-block gzip compression */
358
359static struct argp_option options[] = {
360#define GRID 10
361 {NULL, 0, NULL, 0,
362 N_("Main operation mode:"), GRID },
363
364 {"list", 't', 0, 0,
365 N_("list the contents of an archive"), GRID+1 },
366 {"extract", 'x', 0, 0,
367 N_("extract files from an archive"), GRID+1 },
368 {"get", 0, 0, OPTION_ALIAS, NULL, GRID+1 },
369 {"create", 'c', 0, 0,
370 N_("create a new archive"), GRID+1 },
371 {"diff", 'd', 0, 0,
372 N_("find differences between archive and file system"), GRID+1 },
373 {"compare", 0, 0, OPTION_ALIAS, NULL, GRID+1 },
374 {"append", 'r', 0, 0,
375 N_("append files to the end of an archive"), GRID+1 },
376 {"update", 'u', 0, 0,
377 N_("only append files newer than copy in archive"), GRID+1 },
378 {"catenate", 'A', 0, 0,
379 N_("append tar files to an archive"), GRID+1 },
380 {"concatenate", 0, 0, OPTION_ALIAS, NULL, GRID+1 },
381 {"delete", DELETE_OPTION, 0, 0,
382 N_("delete from the archive (not on mag tapes!)"), GRID+1 },
383 {"test-label", TEST_LABEL_OPTION, NULL, 0,
384 N_("test the archive volume label and exit"), GRID+1 },
385#undef GRID
386
387#define GRID 20
388 {NULL, 0, NULL, 0,
389 N_("Operation modifiers:"), GRID },
390
391 {"sparse", 'S', 0, 0,
392 N_("handle sparse files efficiently"), GRID+1 },
393 {"sparse-version", SPARSE_VERSION_OPTION, N_("MAJOR[.MINOR]"), 0,
394 N_("set version of the sparse format to use (implies --sparse)"), GRID+1},
395 {"incremental", 'G', 0, 0,
396 N_("handle old GNU-format incremental backup"), GRID+1 },
397 {"listed-incremental", 'g', N_("FILE"), 0,
398 N_("handle new GNU-format incremental backup"), GRID+1 },
399 {"ignore-failed-read", IGNORE_FAILED_READ_OPTION, 0, 0,
400 N_("do not exit with nonzero on unreadable files"), GRID+1 },
401 {"occurrence", OCCURRENCE_OPTION, N_("NUMBER"), OPTION_ARG_OPTIONAL,
402 N_("process only the NUMBERth occurrence of each file in the archive;"
403 " this option is valid only in conjunction with one of the subcommands"
404 " --delete, --diff, --extract or --list and when a list of files"
405 " is given either on the command line or via the -T option;"
406 " NUMBER defaults to 1"), GRID+1 },
407 {"seek", 'n', NULL, 0,
408 N_("archive is seekable"), GRID+1 },
409#undef GRID
410
411#define GRID 30
412 {NULL, 0, NULL, 0,
413 N_("Overwrite control:"), GRID },
414
415 {"verify", 'W', 0, 0,
416 N_("attempt to verify the archive after writing it"), GRID+1 },
417 {"remove-files", REMOVE_FILES_OPTION, 0, 0,
418 N_("remove files after adding them to the archive"), GRID+1 },
419 {"keep-old-files", 'k', 0, 0,
420 N_("don't replace existing files when extracting"), GRID+1 },
421 {"keep-newer-files", KEEP_NEWER_FILES_OPTION, 0, 0,
422 N_("don't replace existing files that are newer than their archive copies"), GRID+1 },
423 {"overwrite", OVERWRITE_OPTION, 0, 0,
424 N_("overwrite existing files when extracting"), GRID+1 },
425 {"unlink-first", 'U', 0, 0,
426 N_("remove each file prior to extracting over it"), GRID+1 },
427 {"recursive-unlink", RECURSIVE_UNLINK_OPTION, 0, 0,
428 N_("empty hierarchies prior to extracting directory"), GRID+1 },
429 {"no-overwrite-dir", NO_OVERWRITE_DIR_OPTION, 0, 0,
430 N_("preserve metadata of existing directories"), GRID+1 },
431 {"overwrite-dir", OVERWRITE_DIR_OPTION, 0, 0,
432 N_("overwrite metadata of existing directories when extracting (default)"),
433 GRID+1 },
434#undef GRID
435
436#define GRID 40
437 {NULL, 0, NULL, 0,
438 N_("Select output stream:"), GRID },
439
440 {"to-stdout", 'O', 0, 0,
441 N_("extract files to standard output"), GRID+1 },
442 {"to-command", TO_COMMAND_OPTION, N_("COMMAND"), 0,
443 N_("pipe extracted files to another program"), GRID+1 },
444 {"ignore-command-error", IGNORE_COMMAND_ERROR_OPTION, 0, 0,
445 N_("ignore exit codes of children"), GRID+1 },
446 {"no-ignore-command-error", NO_IGNORE_COMMAND_ERROR_OPTION, 0, 0,
447 N_("treat non-zero exit codes of children as error"), GRID+1 },
448#undef GRID
449
450#define GRID 50
451 {NULL, 0, NULL, 0,
452 N_("Handling of file attributes:"), GRID },
453
454 {"owner", OWNER_OPTION, N_("NAME"), 0,
455 N_("force NAME as owner for added files"), GRID+1 },
456 {"group", GROUP_OPTION, N_("NAME"), 0,
457 N_("force NAME as group for added files"), GRID+1 },
458 {"mtime", MTIME_OPTION, N_("DATE-OR-FILE"), 0,
459 N_("set mtime for added files from DATE-OR-FILE"), GRID+1 },
460 {"mode", MODE_OPTION, N_("CHANGES"), 0,
461 N_("force (symbolic) mode CHANGES for added files"), GRID+1 },
462 {"atime-preserve", ATIME_PRESERVE_OPTION,
463 N_("METHOD"), OPTION_ARG_OPTIONAL,
464 N_("preserve access times on dumped files, either by restoring the times"
465 " after reading (METHOD='replace'; default) or by not setting the times"
466 " in the first place (METHOD='system')"), GRID+1 },
467 {"touch", 'm', 0, 0,
468 N_("don't extract file modified time"), GRID+1 },
469 {"same-owner", SAME_OWNER_OPTION, 0, 0,
470 N_("try extracting files with the same ownership"), GRID+1 },
471 {"no-same-owner", NO_SAME_OWNER_OPTION, 0, 0,
472 N_("extract files as yourself"), GRID+1 },
473 {"numeric-owner", NUMERIC_OWNER_OPTION, 0, 0,
474 N_("always use numbers for user/group names"), GRID+1 },
475 {"preserve-permissions", 'p', 0, 0,
476 N_("extract information about file permissions (default for superuser)"),
477 GRID+1 },
478 {"same-permissions", 0, 0, OPTION_ALIAS, NULL, GRID+1 },
479 {"no-same-permissions", NO_SAME_PERMISSIONS_OPTION, 0, 0,
480 N_("apply the user's umask when extracting permissions from the archive (default for ordinary users)"), GRID+1 },
481 {"preserve-order", 's', 0, 0,
482 N_("sort names to extract to match archive"), GRID+1 },
483 {"same-order", 0, 0, OPTION_ALIAS, NULL, GRID+1 },
484 {"preserve", PRESERVE_OPTION, 0, 0,
485 N_("same as both -p and -s"), GRID+1 },
486 {"delay-directory-restore", DELAY_DIRECTORY_RESTORE_OPTION, 0, 0,
487 N_("delay setting modification times and permissions of extracted"
488 " directories until the end of extraction"), GRID+1 },
489 {"no-delay-directory-restore", NO_DELAY_DIRECTORY_RESTORE_OPTION, 0, 0,
490 N_("cancel the effect of --delay-directory-restore option"), GRID+1 },
491#undef GRID
492
493#define GRID 60
494 {NULL, 0, NULL, 0,
495 N_("Device selection and switching:"), GRID },
496
497 {"file", 'f', N_("ARCHIVE"), 0,
498 N_("use archive file or device ARCHIVE"), GRID+1 },
499 {"force-local", FORCE_LOCAL_OPTION, 0, 0,
500 N_("archive file is local even if it has a colon"), GRID+1 },
501 {"rmt-command", RMT_COMMAND_OPTION, N_("COMMAND"), 0,
502 N_("use given rmt COMMAND instead of rmt"), GRID+1 },
503 {"rsh-command", RSH_COMMAND_OPTION, N_("COMMAND"), 0,
504 N_("use remote COMMAND instead of rsh"), GRID+1 },
505#ifdef DEVICE_PREFIX
506 {"-[0-7][lmh]", 0, NULL, OPTION_DOC, /* It is OK, since `name' will never be
507 translated */
508 N_("specify drive and density"), GRID+1 },
509#endif
510 {NULL, '0', NULL, OPTION_HIDDEN, NULL, GRID+1 },
511 {NULL, '1', NULL, OPTION_HIDDEN, NULL, GRID+1 },
512 {NULL, '2', NULL, OPTION_HIDDEN, NULL, GRID+1 },
513 {NULL, '3', NULL, OPTION_HIDDEN, NULL, GRID+1 },
514 {NULL, '4', NULL, OPTION_HIDDEN, NULL, GRID+1 },
515 {NULL, '5', NULL, OPTION_HIDDEN, NULL, GRID+1 },
516 {NULL, '6', NULL, OPTION_HIDDEN, NULL, GRID+1 },
517 {NULL, '7', NULL, OPTION_HIDDEN, NULL, GRID+1 },
518 {NULL, '8', NULL, OPTION_HIDDEN, NULL, GRID+1 },
519 {NULL, '9', NULL, OPTION_HIDDEN, NULL, GRID+1 },
520
521 {"multi-volume", 'M', 0, 0,
522 N_("create/list/extract multi-volume archive"), GRID+1 },
523 {"tape-length", 'L', N_("NUMBER"), 0,
524 N_("change tape after writing NUMBER x 1024 bytes"), GRID+1 },
525 {"info-script", 'F', N_("NAME"), 0,
526 N_("run script at end of each tape (implies -M)"), GRID+1 },
527 {"new-volume-script", 0, 0, OPTION_ALIAS, NULL, GRID+1 },
528 {"volno-file", VOLNO_FILE_OPTION, N_("FILE"), 0,
529 N_("use/update the volume number in FILE"), GRID+1 },
530#undef GRID
531
532#define GRID 70
533 {NULL, 0, NULL, 0,
534 N_("Device blocking:"), GRID },
535
536 {"blocking-factor", 'b', N_("BLOCKS"), 0,
537 N_("BLOCKS x 512 bytes per record"), GRID+1 },
538 {"record-size", RECORD_SIZE_OPTION, N_("NUMBER"), 0,
539 N_("NUMBER of bytes per record, multiple of 512"), GRID+1 },
540 {"ignore-zeros", 'i', 0, 0,
541 N_("ignore zeroed blocks in archive (means EOF)"), GRID+1 },
542 {"read-full-records", 'B', 0, 0,
543 N_("reblock as we read (for 4.2BSD pipes)"), GRID+1 },
544#undef GRID
545
546#define GRID 80
547 {NULL, 0, NULL, 0,
548 N_("Archive format selection:"), GRID },
549
550 {"format", 'H', N_("FORMAT"), 0,
551 N_("create archive of the given format"), GRID+1 },
552
553 {NULL, 0, NULL, 0, N_("FORMAT is one of the following:"), GRID+2 },
554 {" v7", 0, NULL, OPTION_DOC|OPTION_NO_TRANS, N_("old V7 tar format"),
555 GRID+3 },
556 {" oldgnu", 0, NULL, OPTION_DOC|OPTION_NO_TRANS,
557 N_("GNU format as per tar <= 1.12"), GRID+3 },
558 {" gnu", 0, NULL, OPTION_DOC|OPTION_NO_TRANS,
559 N_("GNU tar 1.13.x format"), GRID+3 },
560 {" ustar", 0, NULL, OPTION_DOC|OPTION_NO_TRANS,
561 N_("POSIX 1003.1-1988 (ustar) format"), GRID+3 },
562 {" pax", 0, NULL, OPTION_DOC|OPTION_NO_TRANS,
563 N_("POSIX 1003.1-2001 (pax) format"), GRID+3 },
564 {" posix", 0, NULL, OPTION_DOC|OPTION_NO_TRANS, N_("same as pax"), GRID+3 },
565
566 {"old-archive", OLD_ARCHIVE_OPTION, 0, 0, /* FIXME */
567 N_("same as --format=v7"), GRID+8 },
568 {"portability", 0, 0, OPTION_ALIAS, NULL, GRID+8 },
569 {"posix", POSIX_OPTION, 0, 0,
570 N_("same as --format=posix"), GRID+8 },
571 {"pax-option", PAX_OPTION, N_("keyword[[:]=value][,keyword[[:]=value]]..."), 0,
572 N_("control pax keywords"), GRID+8 },
573 {"label", 'V', N_("TEXT"), 0,
574 N_("create archive with volume name TEXT; at list/extract time, use TEXT as a globbing pattern for volume name"), GRID+8 },
575 {"bzip2", 'j', 0, 0,
576 N_("filter the archive through bzip2"), GRID+8 },
577 {"gzip", 'z', 0, 0,
578 N_("filter the archive through gzip"), GRID+8 },
579 {"gunzip", 0, 0, OPTION_ALIAS, NULL, GRID+8 },
580 {"ungzip", 0, 0, OPTION_ALIAS, NULL, GRID+8 },
581 {"compress", 'Z', 0, 0,
582 N_("filter the archive through compress"), GRID+8 },
583 {"uncompress", 0, 0, OPTION_ALIAS, NULL, GRID+8 },
584 {"use-compress-program", USE_COMPRESS_PROGRAM_OPTION, N_("PROG"), 0,
585 N_("filter through PROG (must accept -d)"), GRID+8 },
586#undef GRID
587
588#define GRID 90
589 {NULL, 0, NULL, 0,
590 N_("Local file selection:"), GRID },
591
592 {"add-file", ARGP_KEY_ARG, N_("FILE"), 0,
593 N_("add given FILE to the archive (useful if its name starts with a dash)"), GRID+1 },
594 {"directory", 'C', N_("DIR"), 0,
595 N_("change to directory DIR"), GRID+1 },
596 {"files-from", 'T', N_("FILE"), 0,
597 N_("get names to extract or create from FILE"), GRID+1 },
598 {"null", NULL_OPTION, 0, 0,
599 N_("-T reads null-terminated names, disable -C"), GRID+1 },
600 {"unquote", UNQUOTE_OPTION, 0, 0,
601 N_("unquote filenames read with -T (default)"), GRID+1 },
602 {"no-unquote", NO_UNQUOTE_OPTION, 0, 0,
603 N_("do not unquote filenames read with -T"), GRID+1 },
604 {"exclude", EXCLUDE_OPTION, N_("PATTERN"), 0,
605 N_("exclude files, given as a PATTERN"), GRID+1 },
606 {"exclude-from", 'X', N_("FILE"), 0,
607 N_("exclude patterns listed in FILE"), GRID+1 },
608 {"exclude-caches", EXCLUDE_CACHES_OPTION, 0, 0,
609 N_("exclude directories containing a cache tag"), GRID+1 },
610 {"exclude-tag", EXCLUDE_TAG_OPTION, N_("FILE"), 0,
611 N_("exclude directories containing FILE"), GRID+1 },
612 {"no-recursion", NO_RECURSION_OPTION, 0, 0,
613 N_("avoid descending automatically in directories"), GRID+1 },
614 {"one-file-system", ONE_FILE_SYSTEM_OPTION, 0, 0,
615 N_("stay in local file system when creating archive"), GRID+1 },
616 {"recursion", RECURSION_OPTION, 0, 0,
617 N_("recurse into directories (default)"), GRID+1 },
618 {"absolute-names", 'P', 0, 0,
619 N_("don't strip leading `/'s from file names"), GRID+1 },
620 {"dereference", 'h', 0, 0,
621 N_("follow symlinks; archive and dump the files they point to"), GRID+1 },
622 {"starting-file", 'K', N_("MEMBER-NAME"), 0,
623 N_("begin at member MEMBER-NAME in the archive"), GRID+1 },
624 {"newer", 'N', N_("DATE-OR-FILE"), 0,
625 N_("only store files newer than DATE-OR-FILE"), GRID+1 },
626 {"after-date", 0, 0, OPTION_ALIAS, NULL, GRID+1 },
627 {"newer-mtime", NEWER_MTIME_OPTION, N_("DATE"), 0,
628 N_("compare date and time when data changed only"), GRID+1 },
629 {"backup", BACKUP_OPTION, N_("CONTROL"), OPTION_ARG_OPTIONAL,
630 N_("backup before removal, choose version CONTROL"), GRID+1 },
631 {"suffix", SUFFIX_OPTION, N_("STRING"), 0,
632 N_("backup before removal, override usual suffix ('~' unless overridden by environment variable SIMPLE_BACKUP_SUFFIX)"), GRID+1 },
633#undef GRID
634
635#define GRID 92
636 {NULL, 0, NULL, 0,
637 N_("File name transformations:"), GRID },
638 {"strip-components", STRIP_COMPONENTS_OPTION, N_("NUMBER"), 0,
639 N_("strip NUMBER leading components from file names on extraction"),
640 GRID+1 },
641 {"transform", TRANSFORM_OPTION, N_("EXPRESSION"), 0,
642 N_("use sed replace EXPRESSION to transform file names"), GRID+1 },
643#undef GRID
644
645#define GRID 95
646 {NULL, 0, NULL, 0,
647 N_("File name matching options (affect both exclude and include patterns):"),
648 GRID },
649 {"ignore-case", IGNORE_CASE_OPTION, 0, 0,
650 N_("ignore case"), GRID+1 },
651 {"anchored", ANCHORED_OPTION, 0, 0,
652 N_("patterns match file name start"), GRID+1 },
653 {"no-anchored", NO_ANCHORED_OPTION, 0, 0,
654 N_("patterns match after any `/' (default for exclusion)"), GRID+1 },
655 {"no-ignore-case", NO_IGNORE_CASE_OPTION, 0, 0,
656 N_("case sensitive matching (default)"), GRID+1 },
657 {"wildcards", WILDCARDS_OPTION, 0, 0,
658 N_("use wildcards (default for exclusion)"), GRID+1 },
659 {"no-wildcards", NO_WILDCARDS_OPTION, 0, 0,
660 N_("verbatim string matching"), GRID+1 },
661 {"no-wildcards-match-slash", NO_WILDCARDS_MATCH_SLASH_OPTION, 0, 0,
662 N_("wildcards do not match `/'"), GRID+1 },
663 {"wildcards-match-slash", WILDCARDS_MATCH_SLASH_OPTION, 0, 0,
664 N_("wildcards match `/' (default for exclusion)"), GRID+1 },
665#undef GRID
666
667#define GRID 100
668 {NULL, 0, NULL, 0,
669 N_("Informative output:"), GRID },
670
671 {"verbose", 'v', 0, 0,
672 N_("verbosely list files processed"), GRID+1 },
673 {"checkpoint", CHECKPOINT_OPTION, N_("[.]NUMBER"), OPTION_ARG_OPTIONAL,
674 N_("display progress messages every NUMBERth record (default 10)"),
675 GRID+1 },
676 {"check-links", 'l', 0, 0,
677 N_("print a message if not all links are dumped"), GRID+1 },
678 {"totals", TOTALS_OPTION, N_("SIGNAL"), OPTION_ARG_OPTIONAL,
679 N_("print total bytes after processing the archive; "
680 "with an argument - print total bytes when this SIGNAL is delivered; "
681 "Allowed signals are: SIGHUP, SIGQUIT, SIGINT, SIGUSR1 and SIGUSR2; "
682 "the names without SIG prefix are also accepted"), GRID+1 },
683 {"utc", UTC_OPTION, 0, 0,
684 N_("print file modification dates in UTC"), GRID+1 },
685 {"index-file", INDEX_FILE_OPTION, N_("FILE"), 0,
686 N_("send verbose output to FILE"), GRID+1 },
687 {"block-number", 'R', 0, 0,
688 N_("show block number within archive with each message"), GRID+1 },
689 {"interactive", 'w', 0, 0,
690 N_("ask for confirmation for every action"), GRID+1 },
691 {"confirmation", 0, 0, OPTION_ALIAS, NULL, GRID+1 },
692 {"show-defaults", SHOW_DEFAULTS_OPTION, 0, 0,
693 N_("show tar defaults"), GRID+1 },
694 {"show-omitted-dirs", SHOW_OMITTED_DIRS_OPTION, 0, 0,
695 N_("when listing or extracting, list each directory that does not match search criteria"), GRID+1 },
696 {"show-transformed-names", SHOW_TRANSFORMED_NAMES_OPTION, 0, 0,
697 N_("show file or archive names after transformation"),
698 GRID+1 },
699 {"show-stored-names", 0, 0, OPTION_ALIAS, NULL, GRID+1 },
700 {"quoting-style", QUOTING_STYLE_OPTION, N_("STYLE"), 0,
701 N_("set name quoting style; see below for valid STYLE values"), GRID+1 },
702 {"quote-chars", QUOTE_CHARS_OPTION, N_("STRING"), 0,
703 N_("additionally quote characters from STRING"), GRID+1 },
704 {"no-quote-chars", NO_QUOTE_CHARS_OPTION, N_("STRING"), 0,
705 N_("disable quoting for characters from STRING"), GRID+1 },
706#undef GRID
707
708#define GRID 110
709 {NULL, 0, NULL, 0,
710 N_("Compatibility options:"), GRID },
711
712 {NULL, 'o', 0, 0,
713 N_("when creating, same as --old-archive; when extracting, same as --no-same-owner"), GRID+1 },
714#undef GRID
715
716#define GRID 120
717 {NULL, 0, NULL, 0,
718 N_("Other options:"), GRID },
719
720 {"restrict", RESTRICT_OPTION, 0, 0,
721 N_("disable use of some potentially harmful options"), -1 },
722
723 {"help", '?', 0, 0, N_("give this help list"), -1},
724 {"usage", USAGE_OPTION, 0, 0, N_("give a short usage message"), -1},
725 {"version", VERSION_OPTION, 0, 0, N_("print program version"), -1},
726 /* FIXME -V (--label) conflicts with the default short option for
727 --version */
728 {"HANG", HANG_OPTION, "SECS", OPTION_ARG_OPTIONAL | OPTION_HIDDEN,
729 N_("hang for SECS seconds (default 3600)"), 0},
730#undef GRID
731
732 {0, 0, 0, 0, 0, 0}
733};
734
735static char const *const atime_preserve_args[] =
736{
737 "replace", "system", NULL
738};
739
740static enum atime_preserve const atime_preserve_types[] =
741{
742 replace_atime_preserve, system_atime_preserve
743};
744
745/* Make sure atime_preserve_types has as much entries as atime_preserve_args
746 (minus 1 for NULL guard) */
747ARGMATCH_VERIFY (atime_preserve_args, atime_preserve_types);
748
749/* Wildcard matching settings */
750enum wildcards
751 {
752 default_wildcards, /* For exclusion == enable_wildcards,
753 for inclusion == disable_wildcards */
754 disable_wildcards,
755 enable_wildcards
756 };
757
758struct tar_args /* Variables used during option parsing */
759{
760 struct textual_date *textual_date; /* Keeps the arguments to --newer-mtime
761 and/or --date option if they are
762 textual dates */
763 enum wildcards wildcards; /* Wildcard settings (--wildcards/
764 --no-wildcards) */
765 int matching_flags; /* exclude_fnmatch options */
766 int include_anchored; /* Pattern anchoring options used for
767 file inclusion */
768 bool o_option; /* True if -o option was given */
769 bool pax_option; /* True if --pax-option was given */
770 char const *backup_suffix_string; /* --suffix option argument */
771 char const *version_control_string; /* --backup option argument */
772 bool input_files; /* True if some input files where given */
773};
774
775#define MAKE_EXCL_OPTIONS(args) \
776 ((((args)->wildcards != disable_wildcards) ? EXCLUDE_WILDCARDS : 0) \
777 | (args)->matching_flags \
778 | recursion_option)
779
780#define MAKE_INCL_OPTIONS(args) \
781 ((((args)->wildcards == enable_wildcards) ? EXCLUDE_WILDCARDS : 0) \
782 | (args)->include_anchored \
783 | (args)->matching_flags \
784 | recursion_option)
785
786#ifdef REMOTE_SHELL
787# define DECL_SHOW_DEFAULT_SETTINGS(stream, printer) \
788{ \
789 printer (stream, \
790 "--format=%s -f%s -b%d --quoting-style=%s --rmt-command=%s", \
791 archive_format_string (DEFAULT_ARCHIVE_FORMAT), \
792 DEFAULT_ARCHIVE, DEFAULT_BLOCKING, \
793 quoting_style_args[DEFAULT_QUOTING_STYLE], \
794 DEFAULT_RMT_COMMAND); \
795 printer (stream, " --rsh-command=%s", REMOTE_SHELL); \
796 printer (stream, "\n"); \
797}
798#else
799# define DECL_SHOW_DEFAULT_SETTINGS(stream, printer) \
800{ \
801 printer (stream, \
802 "--format=%s -f%s -b%d --quoting-style=%s --rmt-command=%s", \
803 archive_format_string (DEFAULT_ARCHIVE_FORMAT), \
804 DEFAULT_ARCHIVE, DEFAULT_BLOCKING, \
805 quoting_style_args[DEFAULT_QUOTING_STYLE], \
806 DEFAULT_RMT_COMMAND); \
807 printer (stream, "\n"); \
808}
809#endif
810
811static void
812show_default_settings (FILE *fp)
813 DECL_SHOW_DEFAULT_SETTINGS(fp, fprintf)
814
815static void
816show_default_settings_fs (argp_fmtstream_t fs)
817 DECL_SHOW_DEFAULT_SETTINGS(fs, argp_fmtstream_printf)
818
819static void
820set_subcommand_option (enum subcommand subcommand)
821{
822 if (subcommand_option != UNKNOWN_SUBCOMMAND
823 && subcommand_option != subcommand)
824 USAGE_ERROR ((0, 0,
825 _("You may not specify more than one `-Acdtrux' option")));
826
827 subcommand_option = subcommand;
828}
829
830static void
831set_use_compress_program_option (const char *string)
832{
833 if (use_compress_program_option
834 && strcmp (use_compress_program_option, string) != 0)
835 USAGE_ERROR ((0, 0, _("Conflicting compression options")));
836
837 use_compress_program_option = string;
838}
839
840
841static RETSIGTYPE
842sigstat (int signo)
843{
844 compute_duration ();
845 print_total_stats ();
846#ifndef HAVE_SIGACTION
847 signal (signo, sigstat);
848#endif
849}
850
851static void
852stat_on_signal (int signo)
853{
854#ifdef HAVE_SIGACTION
855 struct sigaction act;
856 act.sa_handler = sigstat;
857 sigemptyset (&act.sa_mask);
858 act.sa_flags = 0;
859 sigaction (signo, &act, NULL);
860#else
861 signal (signo, sigstat);
862#endif
863}
864
865void
866set_stat_signal (const char *name)
867{
868 static struct sigtab
869 {
870 char *name;
871 int signo;
872 } sigtab[] = {
873 { "SIGUSR1", SIGUSR1 },
874 { "USR1", SIGUSR1 },
875 { "SIGUSR2", SIGUSR2 },
876 { "USR2", SIGUSR2 },
877 { "SIGHUP", SIGHUP },
878 { "HUP", SIGHUP },
879 { "SIGINT", SIGINT },
880 { "INT", SIGINT },
881 { "SIGQUIT", SIGQUIT },
882 { "QUIT", SIGQUIT }
883 };
884 struct sigtab *p;
885
886 for (p = sigtab; p < sigtab + sizeof (sigtab) / sizeof (sigtab[0]); p++)
887 if (strcmp (p->name, name) == 0)
888 {
889 stat_on_signal (p->signo);
890 return;
891 }
892 FATAL_ERROR ((0, 0, _("Unknown signal name: %s"), name));
893}
894
895
896
897struct textual_date
898{
899 struct textual_date *next;
900 struct timespec *ts;
901 const char *option;
902 const char *date;
903};
904
905static void
906get_date_or_file (struct tar_args *args, const char *option,
907 const char *str, struct timespec *ts)
908{
909 if (FILE_SYSTEM_PREFIX_LEN (str) != 0
910 || ISSLASH (*str)
911 || *str == '.')
912 {
913 struct stat st;
914 if (deref_stat (dereference_option, str, &st) != 0)
915 {
916 stat_error (str);
917 USAGE_ERROR ((0, 0, _("Date sample file not found")));
918 }
919 *ts = get_stat_mtime (&st);
920 }
921 else
922 {
923 if (! get_date (ts, str, NULL))
924 {
925 WARN ((0, 0, _("Substituting %s for unknown date format %s"),
926 tartime (*ts, false), quote (str)));
927 ts->tv_nsec = 0;
928 }
929 else
930 {
931 struct textual_date *p = xmalloc (sizeof (*p));
932 p->ts = ts;
933 p->option = option;
934 p->date = str;
935 p->next = args->textual_date;
936 args->textual_date = p;
937 }
938 }
939}
940
941static void
942report_textual_dates (struct tar_args *args)
943{
944 struct textual_date *p;
945 for (p = args->textual_date; p; )
946 {
947 struct textual_date *next = p->next;
948 char const *treated_as = tartime (*p->ts, true);
949 if (strcmp (p->date, treated_as) != 0)
950 WARN ((0, 0, _("Option %s: Treating date `%s' as %s"),
951 p->option, p->date, treated_as));
952 free (p);
953 p = next;
954 }
955}
956
957
958
959static volatile int _argp_hang;
960
961enum read_file_list_state /* Result of reading file name from the list file */
962 {
963 file_list_success, /* OK, name read successfully */
964 file_list_end, /* End of list file */
965 file_list_zero, /* Zero separator encountered where it should not */
966 file_list_skip /* Empty (zero-length) entry encountered, skip it */
967 };
968
969/* Read from FP a sequence of characters up to FILENAME_TERMINATOR and put them
970 into STK.
971 */
972static enum read_file_list_state
973read_name_from_file (FILE *fp, struct obstack *stk)
974{
975 int c;
976 size_t counter = 0;
977
978 for (c = getc (fp); c != EOF && c != filename_terminator; c = getc (fp))
979 {
980 if (c == 0)
981 {
982 /* We have read a zero separator. The file possibly is
983 zero-separated */
984 return file_list_zero;
985 }
986 obstack_1grow (stk, c);
987 counter++;
988 }
989
990 if (counter == 0 && c != EOF)
991 return file_list_skip;
992
993 obstack_1grow (stk, 0);
994
995 return (counter == 0 && c == EOF) ? file_list_end : file_list_success;
996}
997
998
999
1000static bool files_from_option; /* When set, tar will not refuse to create
1001 empty archives */
1002static struct obstack argv_stk; /* Storage for additional command line options
1003 read using -T option */
1004
1005/* Prevent recursive inclusion of the same file */
1006struct file_id_list
1007{
1008 struct file_id_list *next;
1009 ino_t ino;
1010 dev_t dev;
1011};
1012
1013static struct file_id_list *file_id_list;
1014
1015static void
1016add_file_id (const char *filename)
1017{
1018 struct file_id_list *p;
1019 struct stat st;
1020
1021 if (stat (filename, &st))
1022 stat_fatal (filename);
1023 for (p = file_id_list; p; p = p->next)
1024 if (p->ino == st.st_ino && p->dev == st.st_dev)
1025 {
1026 FATAL_ERROR ((0, 0, _("%s: file list already read"),
1027 quotearg_colon (filename)));
1028 }
1029 p = xmalloc (sizeof *p);
1030 p->next = file_id_list;
1031 p->ino = st.st_ino;
1032 p->dev = st.st_dev;
1033 file_id_list = p;
1034}
1035
1036/* Default density numbers for [0-9][lmh] device specifications */
1037
1038#ifndef LOW_DENSITY_NUM
1039# define LOW_DENSITY_NUM 0
1040#endif
1041
1042#ifndef MID_DENSITY_NUM
1043# define MID_DENSITY_NUM 8
1044#endif
1045
1046#ifndef HIGH_DENSITY_NUM
1047# define HIGH_DENSITY_NUM 16
1048#endif
1049
1050static void
1051update_argv (const char *filename, struct argp_state *state)
1052{
1053 FILE *fp;
1054 size_t count = 0, i;
1055 char *start, *p;
1056 char **new_argv;
1057 size_t new_argc;
1058 bool is_stdin = false;
1059 enum read_file_list_state read_state;
1060
1061 if (!strcmp (filename, "-"))
1062 {
1063 is_stdin = true;
1064 request_stdin ("-T");
1065 fp = stdin;
1066 }
1067 else
1068 {
1069 add_file_id (filename);
1070 if ((fp = fopen (filename, "r")) == NULL)
1071 open_fatal (filename);
1072 }
1073
1074 while ((read_state = read_name_from_file (fp, &argv_stk)) != file_list_end)
1075 {
1076 switch (read_state)
1077 {
1078 case file_list_success:
1079 count++;
1080 break;
1081
1082 case file_list_end: /* won't happen, just to pacify gcc */
1083 break;
1084
1085 case file_list_zero:
1086 {
1087 size_t size;
1088
1089 WARN ((0, 0, N_("%s: file name read contains nul character"),
1090 quotearg_colon (filename)));
1091
1092 /* Prepare new stack contents */
1093 size = obstack_object_size (&argv_stk);
1094 p = obstack_finish (&argv_stk);
1095 for (; size > 0; size--, p++)
1096 if (*p)
1097 obstack_1grow (&argv_stk, *p);
1098 else
1099 obstack_1grow (&argv_stk, '\n');
1100 obstack_1grow (&argv_stk, 0);
1101 count = 1;
1102 /* Read rest of files using new filename terminator */
1103 filename_terminator = 0;
1104 break;
1105 }
1106
1107 case file_list_skip:
1108 break;
1109 }
1110 }
1111
1112 if (!is_stdin)
1113 fclose (fp);
1114
1115 if (count == 0)
1116 return;
1117
1118 start = obstack_finish (&argv_stk);
1119
1120 if (filename_terminator == 0)
1121 for (p = start; *p; p += strlen (p) + 1)
1122 if (p[0] == '-')
1123 count++;
1124
1125 new_argc = state->argc + count;
1126 new_argv = xmalloc (sizeof (state->argv[0]) * (new_argc + 1));
1127 memcpy (new_argv, state->argv, sizeof (state->argv[0]) * (state->argc + 1));
1128 state->argv = new_argv;
1129 memmove (&state->argv[state->next + count], &state->argv[state->next],
1130 (state->argc - state->next + 1) * sizeof (state->argv[0]));
1131
1132 state->argc = new_argc;
1133
1134 for (i = state->next, p = start; *p; p += strlen (p) + 1, i++)
1135 {
1136 if (filename_terminator == 0 && p[0] == '-')
1137 state->argv[i++] = "--add-file";
1138 state->argv[i] = p;
1139 }
1140}
1141
1142
1143
1144static void
1145tar_help (struct argp_state *state)
1146{
1147 argp_fmtstream_t fs;
1148 state->flags |= ARGP_NO_EXIT;
1149 argp_state_help (state, state->out_stream,
1150 ARGP_HELP_STD_HELP & ~ARGP_HELP_BUG_ADDR);
1151 /* FIXME: use struct uparams.rmargin (from argp-help.c) instead of 79 */
1152 fs = argp_make_fmtstream (state->out_stream, 0, 79, 0);
1153
1154 argp_fmtstream_printf (fs, "\n%s\n\n",
1155 _("Valid arguments for --quoting-style options are:"));
1156 tar_list_quoting_styles (fs, " ");
1157
1158 argp_fmtstream_puts (fs, _("\n*This* tar defaults to:\n"));
1159 show_default_settings_fs (fs);
1160 argp_fmtstream_putc (fs, '\n');
1161 argp_fmtstream_printf (fs, _("Report bugs to %s.\n"),
1162 argp_program_bug_address);
1163 argp_fmtstream_free (fs);
1164}
1165
1166
1167static error_t
1168parse_opt (int key, char *arg, struct argp_state *state)
1169{
1170 struct tar_args *args = state->input;
1171
1172 switch (key)
1173 {
1174 case ARGP_KEY_ARG:
1175 /* File name or non-parsed option, because of ARGP_IN_ORDER */
1176 name_add_name (arg, MAKE_INCL_OPTIONS (args));
1177 args->input_files = true;
1178 break;
1179
1180 case 'A':
1181 set_subcommand_option (CAT_SUBCOMMAND);
1182 break;
1183
1184 case 'b':
1185 {
1186 uintmax_t u;
1187 if (! (xstrtoumax (arg, 0, 10, &u, "") == LONGINT_OK
1188 && u == (blocking_factor = u)
1189 && 0 < blocking_factor
1190 && u == (record_size = u * BLOCKSIZE) / BLOCKSIZE))
1191 USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (arg),
1192 _("Invalid blocking factor")));
1193 }
1194 break;
1195
1196 case 'B':
1197 /* Try to reblock input records. For reading 4.2BSD pipes. */
1198
1199 /* It would surely make sense to exchange -B and -R, but it seems
1200 that -B has been used for a long while in Sun tar and most
1201 BSD-derived systems. This is a consequence of the block/record
1202 terminology confusion. */
1203
1204 read_full_records_option = true;
1205 break;
1206
1207 case 'c':
1208 set_subcommand_option (CREATE_SUBCOMMAND);
1209 break;
1210
1211 case 'C':
1212 name_add_dir (arg);
1213 break;
1214
1215 case 'd':
1216 set_subcommand_option (DIFF_SUBCOMMAND);
1217 break;
1218
1219 case 'f':
1220 if (archive_names == allocated_archive_names)
1221 archive_name_array = x2nrealloc (archive_name_array,
1222 &allocated_archive_names,
1223 sizeof (archive_name_array[0]));
1224
1225 archive_name_array[archive_names++] = arg;
1226 break;
1227
1228 case 'F':
1229 /* Since -F is only useful with -M, make it implied. Run this
1230 script at the end of each tape. */
1231
1232 info_script_option = arg;
1233 multi_volume_option = true;
1234 break;
1235
1236 case 'g':
1237 listed_incremental_option = arg;
1238 after_date_option = true;
1239 /* Fall through. */
1240
1241 case 'G':
1242 /* We are making an incremental dump (FIXME: are we?); save
1243 directories at the beginning of the archive, and include in each
1244 directory its contents. */
1245
1246 incremental_option = true;
1247 break;
1248
1249 case 'h':
1250 /* Follow symbolic links. */
1251 dereference_option = true;
1252 break;
1253
1254 case 'i':
1255 /* Ignore zero blocks (eofs). This can't be the default,
1256 because Unix tar writes two blocks of zeros, then pads out
1257 the record with garbage. */
1258
1259 ignore_zeros_option = true;
1260 break;
1261
1262 case 'I':
1263 USAGE_ERROR ((0, 0,
1264 _("Warning: the -I option is not supported;"
1265 " perhaps you meant -j or -T?")));
1266 break;
1267
1268 case 'j':
1269 set_use_compress_program_option ("bzip2");
1270 break;
1271
1272 case 'k':
1273 /* Don't replace existing files. */
1274 old_files_option = KEEP_OLD_FILES;
1275 break;
1276
1277 case 'K':
1278 starting_file_option = true;
1279 addname (arg, 0);
1280 break;
1281
1282 case ONE_FILE_SYSTEM_OPTION:
1283 /* When dumping directories, don't dump files/subdirectories
1284 that are on other filesystems. */
1285 one_file_system_option = true;
1286 break;
1287
1288 case 'l':
1289 check_links_option = 1;
1290 break;
1291
1292 case 'L':
1293 {
1294 uintmax_t u;
1295 if (xstrtoumax (arg, 0, 10, &u, "") != LONGINT_OK)
1296 USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (arg),
1297 _("Invalid tape length")));
1298 tape_length_option = 1024 * (tarlong) u;
1299 multi_volume_option = true;
1300 }
1301 break;
1302
1303 case 'm':
1304 touch_option = true;
1305 break;
1306
1307 case 'M':
1308 /* Make multivolume archive: when we can't write any more into
1309 the archive, re-open it, and continue writing. */
1310
1311 multi_volume_option = true;
1312 break;
1313
1314 case MTIME_OPTION:
1315 get_date_or_file (args, "--mtime", arg, &mtime_option);
1316 set_mtime_option = true;
1317 break;
1318
1319 case 'n':
1320 seekable_archive = true;
1321 break;
1322
1323 case 'N':
1324 after_date_option = true;
1325 /* Fall through. */
1326
1327 case NEWER_MTIME_OPTION:
1328 if (NEWER_OPTION_INITIALIZED (newer_mtime_option))
1329 USAGE_ERROR ((0, 0, _("More than one threshold date")));
1330 get_date_or_file (args,
1331 key == NEWER_MTIME_OPTION ? "--newer-mtime"
1332 : "--after-date", arg, &newer_mtime_option);
1333 break;
1334
1335 case 'o':
1336 args->o_option = true;
1337 break;
1338
1339 case 'O':
1340 to_stdout_option = true;
1341 break;
1342
1343 case 'p':
1344 same_permissions_option = true;
1345 break;
1346
1347 case 'P':
1348 absolute_names_option = true;
1349 break;
1350
1351 case 'r':
1352 set_subcommand_option (APPEND_SUBCOMMAND);
1353 break;
1354
1355 case 'R':
1356 /* Print block numbers for debugging bad tar archives. */
1357
1358 /* It would surely make sense to exchange -B and -R, but it seems
1359 that -B has been used for a long while in Sun tar and most
1360 BSD-derived systems. This is a consequence of the block/record
1361 terminology confusion. */
1362
1363 block_number_option = true;
1364 break;
1365
1366 case 's':
1367 /* Names to extract are sorted. */
1368
1369 same_order_option = true;
1370 break;
1371
1372 case 'S':
1373 sparse_option = true;
1374 break;
1375
1376 case SPARSE_VERSION_OPTION:
1377 sparse_option = true;
1378 {
1379 char *p;
1380 tar_sparse_major = strtoul (arg, &p, 10);
1381 if (*p)
1382 {
1383 if (*p != '.')
1384 USAGE_ERROR ((0, 0, _("Invalid sparse version value")));
1385 tar_sparse_minor = strtoul (p + 1, &p, 10);
1386 if (*p)
1387 USAGE_ERROR ((0, 0, _("Invalid sparse version value")));
1388 }
1389 }
1390 break;
1391
1392 case 't':
1393 set_subcommand_option (LIST_SUBCOMMAND);
1394 verbose_option++;
1395 break;
1396
1397 case TEST_LABEL_OPTION:
1398 set_subcommand_option (LIST_SUBCOMMAND);
1399 test_label_option = true;
1400 break;
1401
1402 case 'T':
1403 update_argv (arg, state);
1404 /* Indicate we've been given -T option. This is for backward
1405 compatibility only, so that `tar cfT archive /dev/null will
1406 succeed */
1407 files_from_option = true;
1408 break;
1409
1410 case 'u':
1411 set_subcommand_option (UPDATE_SUBCOMMAND);
1412 break;
1413
1414 case 'U':
1415 old_files_option = UNLINK_FIRST_OLD_FILES;
1416 break;
1417
1418 case UTC_OPTION:
1419 utc_option = true;
1420 break;
1421
1422 case 'v':
1423 verbose_option++;
1424 break;
1425
1426 case 'V':
1427 volume_label_option = arg;
1428 break;
1429
1430 case 'w':
1431 interactive_option = true;
1432 break;
1433
1434 case 'W':
1435 verify_option = true;
1436 break;
1437
1438 case 'x':
1439 set_subcommand_option (EXTRACT_SUBCOMMAND);
1440 break;
1441
1442 case 'X':
1443 if (add_exclude_file (add_exclude, excluded, arg,
1444 MAKE_EXCL_OPTIONS (args), '\n')
1445 != 0)
1446 {
1447 int e = errno;
1448 FATAL_ERROR ((0, e, "%s", quotearg_colon (arg)));
1449 }
1450 break;
1451
1452 case 'z':
1453 set_use_compress_program_option ("gzip");
1454 break;
1455
1456 case 'Z':
1457 set_use_compress_program_option ("compress");
1458 break;
1459
1460 case ANCHORED_OPTION:
1461 args->matching_flags |= EXCLUDE_ANCHORED;
1462 break;
1463
1464 case ATIME_PRESERVE_OPTION:
1465 atime_preserve_option =
1466 (arg
1467 ? XARGMATCH ("--atime-preserve", arg,
1468 atime_preserve_args, atime_preserve_types)
1469 : replace_atime_preserve);
1470 if (! O_NOATIME && atime_preserve_option == system_atime_preserve)
1471 FATAL_ERROR ((0, 0,
1472 _("--atime-preserve='system' is not supported"
1473 " on this platform")));
1474 break;
1475
1476 case CHECKPOINT_OPTION:
1477 if (arg)
1478 {
1479 char *p;
1480
1481 if (*arg == '.')
1482 {
1483 checkpoint_style = checkpoint_dot;
1484 arg++;
1485 }
1486 checkpoint_option = strtoul (arg, &p, 0);
1487 if (*p)
1488 FATAL_ERROR ((0, 0,
1489 _("--checkpoint value is not an integer")));
1490 }
1491 else
1492 checkpoint_option = 10;
1493 break;
1494
1495 case BACKUP_OPTION:
1496 backup_option = true;
1497 if (arg)
1498 args->version_control_string = arg;
1499 break;
1500
1501 case DELAY_DIRECTORY_RESTORE_OPTION:
1502 delay_directory_restore_option = true;
1503 break;
1504
1505 case NO_DELAY_DIRECTORY_RESTORE_OPTION:
1506 delay_directory_restore_option = false;
1507 break;
1508
1509 case DELETE_OPTION:
1510 set_subcommand_option (DELETE_SUBCOMMAND);
1511 break;
1512
1513 case EXCLUDE_OPTION:
1514 add_exclude (excluded, arg, MAKE_EXCL_OPTIONS (args));
1515 break;
1516
1517 case EXCLUDE_CACHES_OPTION:
1518 exclude_caches_option = true;
1519 break;
1520
1521 case EXCLUDE_TAG_OPTION:
1522 add_exclude_tag (arg);
1523 break;
1524
1525 case FORCE_LOCAL_OPTION:
1526 force_local_option = true;
1527 break;
1528
1529 case 'H':
1530 set_archive_format (arg);
1531 break;
1532
1533 case INDEX_FILE_OPTION:
1534 index_file_name = arg;
1535 break;
1536
1537 case IGNORE_CASE_OPTION:
1538 args->matching_flags |= FNM_CASEFOLD;
1539 break;
1540
1541 case IGNORE_COMMAND_ERROR_OPTION:
1542 ignore_command_error_option = true;
1543 break;
1544
1545 case IGNORE_FAILED_READ_OPTION:
1546 ignore_failed_read_option = true;
1547 break;
1548
1549 case KEEP_NEWER_FILES_OPTION:
1550 old_files_option = KEEP_NEWER_FILES;
1551 break;
1552
1553 case GROUP_OPTION:
1554 if (! (strlen (arg) < GNAME_FIELD_SIZE
1555 && gname_to_gid (arg, &group_option)))
1556 {
1557 uintmax_t g;
1558 if (xstrtoumax (arg, 0, 10, &g, "") == LONGINT_OK
1559 && g == (gid_t) g)
1560 group_option = g;
1561 else
1562 FATAL_ERROR ((0, 0, "%s: %s", quotearg_colon (arg),
1563 _("%s: Invalid group")));
1564 }
1565 break;
1566
1567 case MODE_OPTION:
1568 mode_option = mode_compile (arg);
1569 if (!mode_option)
1570 FATAL_ERROR ((0, 0, _("Invalid mode given on option")));
1571 initial_umask = umask (0);
1572 umask (initial_umask);
1573 break;
1574
1575 case NO_ANCHORED_OPTION:
1576 args->include_anchored = 0; /* Clear the default for comman line args */
1577 args->matching_flags &= ~ EXCLUDE_ANCHORED;
1578 break;
1579
1580 case NO_IGNORE_CASE_OPTION:
1581 args->matching_flags &= ~ FNM_CASEFOLD;
1582 break;
1583
1584 case NO_IGNORE_COMMAND_ERROR_OPTION:
1585 ignore_command_error_option = false;
1586 break;
1587
1588 case NO_OVERWRITE_DIR_OPTION:
1589 old_files_option = NO_OVERWRITE_DIR_OLD_FILES;
1590 break;
1591
1592 case NO_QUOTE_CHARS_OPTION:
1593 for (;*arg; arg++)
1594 set_char_quoting (NULL, *arg, 0);
1595 break;
1596
1597 case NO_WILDCARDS_OPTION:
1598 args->wildcards = disable_wildcards;
1599 break;
1600
1601 case NO_WILDCARDS_MATCH_SLASH_OPTION:
1602 args->matching_flags |= FNM_FILE_NAME;
1603 break;
1604
1605 case NULL_OPTION:
1606 filename_terminator = '\0';
1607 break;
1608
1609 case NUMERIC_OWNER_OPTION:
1610 numeric_owner_option = true;
1611 break;
1612
1613 case OCCURRENCE_OPTION:
1614 if (!arg)
1615 occurrence_option = 1;
1616 else
1617 {
1618 uintmax_t u;
1619 if (xstrtoumax (arg, 0, 10, &u, "") == LONGINT_OK)
1620 occurrence_option = u;
1621 else
1622 FATAL_ERROR ((0, 0, "%s: %s", quotearg_colon (arg),
1623 _("Invalid number")));
1624 }
1625 break;
1626
1627 case OVERWRITE_DIR_OPTION:
1628 old_files_option = DEFAULT_OLD_FILES;
1629 break;
1630
1631 case OVERWRITE_OPTION:
1632 old_files_option = OVERWRITE_OLD_FILES;
1633 break;
1634
1635 case OWNER_OPTION:
1636 if (! (strlen (arg) < UNAME_FIELD_SIZE
1637 && uname_to_uid (arg, &owner_option)))
1638 {
1639 uintmax_t u;
1640 if (xstrtoumax (arg, 0, 10, &u, "") == LONGINT_OK
1641 && u == (uid_t) u)
1642 owner_option = u;
1643 else
1644 FATAL_ERROR ((0, 0, "%s: %s", quotearg_colon (arg),
1645 _("Invalid owner")));
1646 }
1647 break;
1648
1649 case QUOTE_CHARS_OPTION:
1650 for (;*arg; arg++)
1651 set_char_quoting (NULL, *arg, 1);
1652 break;
1653
1654 case QUOTING_STYLE_OPTION:
1655 tar_set_quoting_style (arg);
1656 break;
1657
1658 case PAX_OPTION:
1659 args->pax_option = true;
1660 xheader_set_option (arg);
1661 break;
1662
1663 case POSIX_OPTION:
1664 set_archive_format ("posix");
1665 break;
1666
1667 case PRESERVE_OPTION:
1668 /* FIXME: What it is good for? */
1669 same_permissions_option = true;
1670 same_order_option = true;
1671 break;
1672
1673 case RECORD_SIZE_OPTION:
1674 {
1675 uintmax_t u;
1676 if (! (xstrtoumax (arg, 0, 10, &u, "") == LONGINT_OK
1677 && u == (size_t) u))
1678 USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (arg),
1679 _("Invalid record size")));
1680 record_size = u;
1681 if (record_size % BLOCKSIZE != 0)
1682 USAGE_ERROR ((0, 0, _("Record size must be a multiple of %d."),
1683 BLOCKSIZE));
1684 blocking_factor = record_size / BLOCKSIZE;
1685 }
1686 break;
1687
1688 case RECURSIVE_UNLINK_OPTION:
1689 recursive_unlink_option = true;
1690 break;
1691
1692 case REMOVE_FILES_OPTION:
1693 remove_files_option = true;
1694 break;
1695
1696 case RESTRICT_OPTION:
1697 restrict_option = true;
1698 break;
1699
1700 case RMT_COMMAND_OPTION:
1701 rmt_command = arg;
1702 break;
1703
1704 case RSH_COMMAND_OPTION:
1705 rsh_command_option = arg;
1706 break;
1707
1708 case SHOW_DEFAULTS_OPTION:
1709 show_default_settings (stdout);
1710 close_stdout ();
1711 exit (0);
1712
1713 case STRIP_COMPONENTS_OPTION:
1714 {
1715 uintmax_t u;
1716 if (! (xstrtoumax (arg, 0, 10, &u, "") == LONGINT_OK
1717 && u == (size_t) u))
1718 USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (arg),
1719 _("Invalid number of elements")));
1720 strip_name_components = u;
1721 }
1722 break;
1723
1724 case SHOW_OMITTED_DIRS_OPTION:
1725 show_omitted_dirs_option = true;
1726 break;
1727
1728 case SHOW_TRANSFORMED_NAMES_OPTION:
1729 show_transformed_names_option = true;
1730 break;
1731
1732 case SUFFIX_OPTION:
1733 backup_option = true;
1734 args->backup_suffix_string = arg;
1735 break;
1736
1737 case TO_COMMAND_OPTION:
1738 if (to_command_option)
1739 USAGE_ERROR ((0, 0, _("Only one --to-command option allowed")));
1740 to_command_option = arg;
1741 break;
1742
1743 case TOTALS_OPTION:
1744 if (arg)
1745 set_stat_signal (arg);
1746 else
1747 totals_option = true;
1748 break;
1749
1750 case TRANSFORM_OPTION:
1751 set_transform_expr (arg);
1752 break;
1753
1754 case USE_COMPRESS_PROGRAM_OPTION:
1755 set_use_compress_program_option (arg);
1756 break;
1757
1758 case VOLNO_FILE_OPTION:
1759 volno_file_option = arg;
1760 break;
1761
1762 case WILDCARDS_OPTION:
1763 args->wildcards = enable_wildcards;
1764 break;
1765
1766 case WILDCARDS_MATCH_SLASH_OPTION:
1767 args->matching_flags &= ~ FNM_FILE_NAME;
1768 break;
1769
1770 case NO_RECURSION_OPTION:
1771 recursion_option = 0;
1772 break;
1773
1774 case NO_SAME_OWNER_OPTION:
1775 same_owner_option = -1;
1776 break;
1777
1778 case NO_SAME_PERMISSIONS_OPTION:
1779 same_permissions_option = -1;
1780 break;
1781
1782 case RECURSION_OPTION:
1783 recursion_option = FNM_LEADING_DIR;
1784 break;
1785
1786 case SAME_OWNER_OPTION:
1787 same_owner_option = 1;
1788 break;
1789
1790 case UNQUOTE_OPTION:
1791 unquote_option = true;
1792 break;
1793
1794 case NO_UNQUOTE_OPTION:
1795 unquote_option = false;
1796 break;
1797
1798 case '0':
1799 case '1':
1800 case '2':
1801 case '3':
1802 case '4':
1803 case '5':
1804 case '6':
1805 case '7':
1806
1807#ifdef DEVICE_PREFIX
1808 {
1809 int device = key - '0';
1810 int density;
1811 static char buf[sizeof DEVICE_PREFIX + 10];
1812 char *cursor;
1813
1814 if (arg[1])
1815 argp_error (state, _("Malformed density argument: %s"), quote (arg));
1816
1817 strcpy (buf, DEVICE_PREFIX);
1818 cursor = buf + strlen (buf);
1819
1820#ifdef DENSITY_LETTER
1821
1822 sprintf (cursor, "%d%c", device, arg[0]);
1823
1824#else /* not DENSITY_LETTER */
1825
1826 switch (arg[0])
1827 {
1828 case 'l':
1829 device += LOW_DENSITY_NUM;
1830 break;
1831
1832 case 'm':
1833 device += MID_DENSITY_NUM;
1834 break;
1835
1836 case 'h':
1837 device += HIGH_DENSITY_NUM;
1838 break;
1839
1840 default:
1841 argp_error (state, _("Unknown density: `%c'"), arg[0]);
1842 }
1843 sprintf (cursor, "%d", device);
1844
1845#endif /* not DENSITY_LETTER */
1846
1847 if (archive_names == allocated_archive_names)
1848 archive_name_array = x2nrealloc (archive_name_array,
1849 &allocated_archive_names,
1850 sizeof (archive_name_array[0]));
1851 archive_name_array[archive_names++] = xstrdup (buf);
1852 }
1853 break;
1854
1855#else /* not DEVICE_PREFIX */
1856
1857 argp_error (state,
1858 _("Options `-[0-7][lmh]' not supported by *this* tar"));
1859
1860#endif /* not DEVICE_PREFIX */
1861
1862 case '?':
1863 tar_help (state);
1864 close_stdout ();
1865 exit (0);
1866
1867 case USAGE_OPTION:
1868 argp_state_help (state, state->out_stream, ARGP_HELP_USAGE);
1869 close_stdout ();
1870 exit (0);
1871
1872 case VERSION_OPTION:
1873 version_etc (state->out_stream, "tar", PACKAGE_NAME, VERSION,
1874 "John Gilmore", "Jay Fenlason", (char *) NULL);
1875 close_stdout ();
1876 exit (0);
1877
1878 case HANG_OPTION:
1879 _argp_hang = atoi (arg ? arg : "3600");
1880 while (_argp_hang-- > 0)
1881 sleep (1);
1882 break;
1883
1884 default:
1885 return ARGP_ERR_UNKNOWN;
1886 }
1887 return 0;
1888}
1889
1890static struct argp argp = {
1891 options,
1892 parse_opt,
1893 N_("[FILE]..."),
1894 doc,
1895 NULL,
1896 NULL,
1897 NULL
1898};
1899
1900void
1901usage (int status)
1902{
1903 argp_help (&argp, stderr, ARGP_HELP_SEE, (char*) program_name);
1904 close_stdout ();
1905 exit (status);
1906}
1907
1908/* Parse the options for tar. */
1909
1910static struct argp_option *
1911find_argp_option (struct argp_option *options, int letter)
1912{
1913 for (;
1914 !(options->name == NULL
1915 && options->key == 0
1916 && options->arg == 0
1917 && options->flags == 0
1918 && options->doc == NULL); options++)
1919 if (options->key == letter)
1920 return options;
1921 return NULL;
1922}
1923
1924static void
1925decode_options (int argc, char **argv)
1926{
1927 int index;
1928 struct tar_args args;
1929
1930 /* Set some default option values. */
1931 args.textual_date = NULL;
1932 args.wildcards = default_wildcards;
1933 args.matching_flags = 0;
1934 args.include_anchored = EXCLUDE_ANCHORED;
1935 args.o_option = false;
1936 args.pax_option = false;
1937 args.backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX");
1938 args.version_control_string = 0;
1939 args.input_files = false;
1940
1941 subcommand_option = UNKNOWN_SUBCOMMAND;
1942 archive_format = DEFAULT_FORMAT;
1943 blocking_factor = DEFAULT_BLOCKING;
1944 record_size = DEFAULT_BLOCKING * BLOCKSIZE;
1945 excluded = new_exclude ();
1946 newer_mtime_option.tv_sec = TYPE_MINIMUM (time_t);
1947 newer_mtime_option.tv_nsec = -1;
1948 recursion_option = FNM_LEADING_DIR;
1949 unquote_option = true;
1950 tar_sparse_major = 1;
1951 tar_sparse_minor = 0;
1952
1953 owner_option = -1;
1954 group_option = -1;
1955
1956 /* Convert old-style tar call by exploding option element and rearranging
1957 options accordingly. */
1958
1959 if (argc > 1 && argv[1][0] != '-')
1960 {
1961 int new_argc; /* argc value for rearranged arguments */
1962 char **new_argv; /* argv value for rearranged arguments */
1963 char *const *in; /* cursor into original argv */
1964 char **out; /* cursor into rearranged argv */
1965 const char *letter; /* cursor into old option letters */
1966 char buffer[3]; /* constructed option buffer */
1967
1968 /* Initialize a constructed option. */
1969
1970 buffer[0] = '-';
1971 buffer[2] = '\0';
1972
1973 /* Allocate a new argument array, and copy program name in it. */
1974
1975 new_argc = argc - 1 + strlen (argv[1]);
1976 new_argv = xmalloc ((new_argc + 1) * sizeof (char *));
1977 in = argv;
1978 out = new_argv;
1979 *out++ = *in++;
1980
1981 /* Copy each old letter option as a separate option, and have the
1982 corresponding argument moved next to it. */
1983
1984 for (letter = *in++; *letter; letter++)
1985 {
1986 struct argp_option *opt;
1987
1988 buffer[1] = *letter;
1989 *out++ = xstrdup (buffer);
1990 opt = find_argp_option (options, *letter);
1991 if (opt && opt->arg)
1992 {
1993 if (in < argv + argc)
1994 *out++ = *in++;
1995 else
1996 USAGE_ERROR ((0, 0, _("Old option `%c' requires an argument."),
1997 *letter));
1998 }
1999 }
2000
2001 /* Copy all remaining options. */
2002
2003 while (in < argv + argc)
2004 *out++ = *in++;
2005 *out = 0;
2006
2007 /* Replace the old option list by the new one. */
2008
2009 argc = new_argc;
2010 argv = new_argv;
2011 }
2012
2013 /* Parse all options and non-options as they appear. */
2014
2015 prepend_default_options (getenv ("TAR_OPTIONS"), &argc, &argv);
2016
2017 if (argp_parse (&argp, argc, argv, ARGP_IN_ORDER|ARGP_NO_HELP,
2018 &index, &args))
2019 exit (TAREXIT_FAILURE);
2020
2021
2022 /* Special handling for 'o' option:
2023
2024 GNU tar used to say "output old format".
2025 UNIX98 tar says don't chown files after extracting (we use
2026 "--no-same-owner" for this).
2027
2028 The old GNU tar semantics is retained when used with --create
2029 option, otherwise UNIX98 semantics is assumed */
2030
2031 if (args.o_option)
2032 {
2033 if (subcommand_option == CREATE_SUBCOMMAND)
2034 {
2035 /* GNU Tar <= 1.13 compatibility */
2036 set_archive_format ("v7");
2037 }
2038 else
2039 {
2040 /* UNIX98 compatibility */
2041 same_owner_option = -1;
2042 }
2043 }
2044
2045 /* Handle operands after any "--" argument. */
2046 for (; index < argc; index++)
2047 {
2048 name_add_name (argv[index], MAKE_INCL_OPTIONS (&args));
2049 args.input_files = true;
2050 }
2051
2052 /* Warn about implicit use of the wildcards in command line arguments.
2053 See TODO */
2054 warn_regex_usage = args.wildcards == default_wildcards;
2055
2056 /* Derive option values and check option consistency. */
2057
2058 if (archive_format == DEFAULT_FORMAT)
2059 {
2060 if (args.pax_option)
2061 archive_format = POSIX_FORMAT;
2062 else
2063 archive_format = DEFAULT_ARCHIVE_FORMAT;
2064 }
2065
2066 if ((volume_label_option && subcommand_option == CREATE_SUBCOMMAND)
2067 || incremental_option
2068 || multi_volume_option
2069 || sparse_option)
2070 assert_format (FORMAT_MASK (OLDGNU_FORMAT)
2071 | FORMAT_MASK (GNU_FORMAT)
2072 | FORMAT_MASK (POSIX_FORMAT));
2073
2074 if (occurrence_option)
2075 {
2076 if (!args.input_files)
2077 USAGE_ERROR ((0, 0,
2078 _("--occurrence is meaningless without a file list")));
2079 if (subcommand_option != DELETE_SUBCOMMAND
2080 && subcommand_option != DIFF_SUBCOMMAND
2081 && subcommand_option != EXTRACT_SUBCOMMAND
2082 && subcommand_option != LIST_SUBCOMMAND)
2083 USAGE_ERROR ((0, 0,
2084 _("--occurrence cannot be used in the requested operation mode")));
2085 }
2086
2087 if (seekable_archive && subcommand_option == DELETE_SUBCOMMAND)
2088 {
2089 /* The current code in delete.c is based on the assumption that
2090 skip_member() reads all data from the archive. So, we should
2091 make sure it won't use seeks. On the other hand, the same code
2092 depends on the ability to backspace a record in the archive,
2093 so setting seekable_archive to false is technically incorrect.
2094 However, it is tested only in skip_member(), so it's not a
2095 problem. */
2096 seekable_archive = false;
2097 }
2098
2099 if (archive_names == 0)
2100 {
2101 /* If no archive file name given, try TAPE from the environment, or
2102 else, DEFAULT_ARCHIVE from the configuration process. */
2103
2104 archive_names = 1;
2105 archive_name_array[0] = getenv ("TAPE");
2106 if (! archive_name_array[0])
2107 archive_name_array[0] = DEFAULT_ARCHIVE;
2108 }
2109
2110 /* Allow multiple archives only with `-M'. */
2111
2112 if (archive_names > 1 && !multi_volume_option)
2113 USAGE_ERROR ((0, 0,
2114 _("Multiple archive files require `-M' option")));
2115
2116 if (listed_incremental_option
2117 && NEWER_OPTION_INITIALIZED (newer_mtime_option))
2118 USAGE_ERROR ((0, 0,
2119 _("Cannot combine --listed-incremental with --newer")));
2120
2121 if (volume_label_option)
2122 {
2123 if (archive_format == GNU_FORMAT || archive_format == OLDGNU_FORMAT)
2124 {
2125 size_t volume_label_max_len =
2126 (sizeof current_header->header.name
2127 - 1 /* for trailing '\0' */
2128 - (multi_volume_option
2129 ? (sizeof " Volume "
2130 - 1 /* for null at end of " Volume " */
2131 + INT_STRLEN_BOUND (int) /* for volume number */
2132 - 1 /* for sign, as 0 <= volno */)
2133 : 0));
2134 if (volume_label_max_len < strlen (volume_label_option))
2135 USAGE_ERROR ((0, 0,
2136 ngettext ("%s: Volume label is too long (limit is %lu byte)",
2137 "%s: Volume label is too long (limit is %lu bytes)",
2138 volume_label_max_len),
2139 quotearg_colon (volume_label_option),
2140 (unsigned long) volume_label_max_len));
2141 }
2142 /* else FIXME
2143 Label length in PAX format is limited by the volume size. */
2144 }
2145
2146 if (verify_option)
2147 {
2148 if (multi_volume_option)
2149 USAGE_ERROR ((0, 0, _("Cannot verify multi-volume archives")));
2150 if (use_compress_program_option)
2151 USAGE_ERROR ((0, 0, _("Cannot verify compressed archives")));
2152 }
2153
2154 if (use_compress_program_option)
2155 {
2156 if (multi_volume_option)
2157 USAGE_ERROR ((0, 0, _("Cannot use multi-volume compressed archives")));
2158 if (subcommand_option == UPDATE_SUBCOMMAND
2159 || subcommand_option == APPEND_SUBCOMMAND
2160 || subcommand_option == DELETE_SUBCOMMAND)
2161 USAGE_ERROR ((0, 0, _("Cannot update compressed archives")));
2162 if (subcommand_option == CAT_SUBCOMMAND)
2163 USAGE_ERROR ((0, 0, _("Cannot concatenate compressed archives")));
2164 }
2165
2166 /* It is no harm to use --pax-option on non-pax archives in archive
2167 reading mode. It may even be useful, since it allows to override
2168 file attributes from tar headers. Therefore I allow such usage.
2169 --gray */
2170 if (args.pax_option
2171 && archive_format != POSIX_FORMAT
2172 && (subcommand_option != EXTRACT_SUBCOMMAND
2173 || subcommand_option != DIFF_SUBCOMMAND
2174 || subcommand_option != LIST_SUBCOMMAND))
2175 USAGE_ERROR ((0, 0, _("--pax-option can be used only on POSIX archives")));
2176
2177 /* If ready to unlink hierarchies, so we are for simpler files. */
2178 if (recursive_unlink_option)
2179 old_files_option = UNLINK_FIRST_OLD_FILES;
2180
2181
2182 if (test_label_option)
2183 {
2184 /* --test-label is silent if the user has specified the label name to
2185 compare against. */
2186 if (!args.input_files)
2187 verbose_option++;
2188 }
2189 else if (utc_option)
2190 verbose_option = 2;
2191
2192 /* Forbid using -c with no input files whatsoever. Check that `-f -',
2193 explicit or implied, is used correctly. */
2194
2195 switch (subcommand_option)
2196 {
2197 case CREATE_SUBCOMMAND:
2198 if (!args.input_files && !files_from_option)
2199 USAGE_ERROR ((0, 0,
2200 _("Cowardly refusing to create an empty archive")));
2201 break;
2202
2203 case EXTRACT_SUBCOMMAND:
2204 case LIST_SUBCOMMAND:
2205 case DIFF_SUBCOMMAND:
2206 for (archive_name_cursor = archive_name_array;
2207 archive_name_cursor < archive_name_array + archive_names;
2208 archive_name_cursor++)
2209 if (!strcmp (*archive_name_cursor, "-"))
2210 request_stdin ("-f");
2211 break;
2212
2213 case CAT_SUBCOMMAND:
2214 case UPDATE_SUBCOMMAND:
2215 case APPEND_SUBCOMMAND:
2216 for (archive_name_cursor = archive_name_array;
2217 archive_name_cursor < archive_name_array + archive_names;
2218 archive_name_cursor++)
2219 if (!strcmp (*archive_name_cursor, "-"))
2220 USAGE_ERROR ((0, 0,
2221 _("Options `-Aru' are incompatible with `-f -'")));
2222
2223 default:
2224 break;
2225 }
2226
2227 /* Initialize stdlis */
2228 if (index_file_name)
2229 {
2230 stdlis = fopen (index_file_name, "w");
2231 if (! stdlis)
2232 open_error (index_file_name);
2233 }
2234 else
2235 stdlis = to_stdout_option ? stderr : stdout;
2236
2237 archive_name_cursor = archive_name_array;
2238
2239 /* Prepare for generating backup names. */
2240
2241 if (args.backup_suffix_string)
2242 simple_backup_suffix = xstrdup (args.backup_suffix_string);
2243
2244 if (backup_option)
2245 {
2246 backup_type = xget_version ("--backup", args.version_control_string);
2247 /* No backup is needed either if explicitely disabled or if
2248 the extracted files are not being written to disk. */
2249 if (backup_type == no_backups || EXTRACT_OVER_PIPE)
2250 backup_option = false;
2251 }
2252
2253 if (verbose_option)
2254 report_textual_dates (&args);
2255}
2256
2257
2258
2259/* Tar proper. */
2260
2261/* Main routine for tar. */
2262int
2263main (int argc, char **argv)
2264{
2265 set_start_time ();
2266 program_name = argv[0];
2267
2268 setlocale (LC_ALL, "");
2269 bindtextdomain (PACKAGE, LOCALEDIR);
2270 textdomain (PACKAGE);
2271
2272 exit_failure = TAREXIT_FAILURE;
2273 exit_status = TAREXIT_SUCCESS;
2274 filename_terminator = '\n';
2275 set_quoting_style (0, DEFAULT_QUOTING_STYLE);
2276
2277 /* Make sure we have first three descriptors available */
2278 stdopen ();
2279
2280 /* Close all inherited open descriptors, except for the first three */
2281 closeopen ();
2282
2283 /* Pre-allocate a few structures. */
2284
2285 allocated_archive_names = 10;
2286 archive_name_array =
2287 xmalloc (sizeof (const char *) * allocated_archive_names);
2288 archive_names = 0;
2289
2290 obstack_init (&argv_stk);
2291
2292#ifdef SIGCHLD
2293 /* System V fork+wait does not work if SIGCHLD is ignored. */
2294 signal (SIGCHLD, SIG_DFL);
2295#endif
2296
2297 /* Decode options. */
2298
2299 decode_options (argc, argv);
2300 name_init ();
2301
2302 /* Main command execution. */
2303
2304 if (volno_file_option)
2305 init_volume_number ();
2306
2307 switch (subcommand_option)
2308 {
2309 case UNKNOWN_SUBCOMMAND:
2310 USAGE_ERROR ((0, 0,
2311 _("You must specify one of the `-Acdtrux' options")));
2312
2313 case CAT_SUBCOMMAND:
2314 case UPDATE_SUBCOMMAND:
2315 case APPEND_SUBCOMMAND:
2316 update_archive ();
2317 break;
2318
2319 case DELETE_SUBCOMMAND:
2320 delete_archive_members ();
2321 break;
2322
2323 case CREATE_SUBCOMMAND:
2324 create_archive ();
2325 break;
2326
2327 case EXTRACT_SUBCOMMAND:
2328 extr_init ();
2329 read_and (extract_archive);
2330
2331 /* FIXME: should extract_finish () even if an ordinary signal is
2332 received. */
2333 extract_finish ();
2334
2335 break;
2336
2337 case LIST_SUBCOMMAND:
2338 read_and (list_archive);
2339 break;
2340
2341 case DIFF_SUBCOMMAND:
2342 diff_init ();
2343 read_and (diff_archive);
2344 break;
2345 }
2346
2347 if (totals_option)
2348 print_total_stats ();
2349
2350 if (check_links_option)
2351 check_links ();
2352
2353 if (volno_file_option)
2354 closeout_volume_number ();
2355
2356 /* Dispose of allocated memory, and return. */
2357
2358 free (archive_name_array);
2359 name_term ();
2360
2361 if (exit_status == TAREXIT_FAILURE)
2362 error (0, 0, _("Error exit delayed from previous errors"));
2363
2364 if (stdlis == stdout)
2365 close_stdout ();
2366 else if (ferror (stderr) || fclose (stderr) != 0)
2367 exit_status = TAREXIT_FAILURE;
2368
2369 return exit_status;
2370}
2371
2372void
2373tar_stat_init (struct tar_stat_info *st)
2374{
2375 memset (st, 0, sizeof (*st));
2376}
2377
2378void
2379tar_stat_destroy (struct tar_stat_info *st)
2380{
2381 free (st->orig_file_name);
2382 free (st->file_name);
2383 free (st->link_name);
2384 free (st->uname);
2385 free (st->gname);
2386 free (st->sparse_map);
2387 free (st->dumpdir);
2388 memset (st, 0, sizeof (*st));
2389}
2390
2391/* Format mask for all available formats that support nanosecond
2392 timestamp resolution. */
2393#define NS_PRECISION_FORMAT_MASK FORMAT_MASK (POSIX_FORMAT)
2394
2395/* Same as timespec_cmp, but ignore nanoseconds if current archive
2396 format does not provide sufficient resolution. */
2397int
2398tar_timespec_cmp (struct timespec a, struct timespec b)
2399{
2400 if (!(FORMAT_MASK (current_format) & NS_PRECISION_FORMAT_MASK))
2401 a.tv_nsec = b.tv_nsec = 0;
2402 return timespec_cmp (a, b);
2403}
Note: See TracBrowser for help on using the repository browser.