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