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