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