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