]> Dogcows Code - chaz/tar/blob - src/tar.c
tar: remove lint
[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 opts)
901 {
902 int i;
903
904 for (i = 0; fv[i]; i++)
905 add_exclude (excluded, fv[i], opts);
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 #if defined DEVICE_PREFIX && !defined DENSITY_LETTER
1156 # ifndef LOW_DENSITY_NUM
1157 # define LOW_DENSITY_NUM 0
1158 # endif
1159
1160 # ifndef MID_DENSITY_NUM
1161 # define MID_DENSITY_NUM 8
1162 # endif
1163
1164 # ifndef HIGH_DENSITY_NUM
1165 # define HIGH_DENSITY_NUM 16
1166 # endif
1167 #endif
1168
1169 static void
1170 update_argv (const char *filename, struct argp_state *state)
1171 {
1172 FILE *fp;
1173 size_t count = 0, i;
1174 char *start, *p;
1175 char **new_argv;
1176 size_t new_argc;
1177 bool is_stdin = false;
1178 enum read_file_list_state read_state;
1179 int term = filename_terminator;
1180
1181 if (!strcmp (filename, "-"))
1182 {
1183 is_stdin = true;
1184 request_stdin ("-T");
1185 fp = stdin;
1186 }
1187 else
1188 {
1189 add_file_id (filename);
1190 if ((fp = fopen (filename, "r")) == NULL)
1191 open_fatal (filename);
1192 }
1193
1194 while ((read_state = read_name_from_file (fp, &argv_stk, term))
1195 != file_list_end)
1196 {
1197 switch (read_state)
1198 {
1199 case file_list_success:
1200 count++;
1201 break;
1202
1203 case file_list_end: /* won't happen, just to pacify gcc */
1204 break;
1205
1206 case file_list_zero:
1207 {
1208 size_t size;
1209
1210 WARNOPT (WARN_FILENAME_WITH_NULS,
1211 (0, 0, N_("%s: file name read contains nul character"),
1212 quotearg_colon (filename)));
1213
1214 /* Prepare new stack contents */
1215 size = obstack_object_size (&argv_stk);
1216 p = obstack_finish (&argv_stk);
1217 for (; size > 0; size--, p++)
1218 if (*p)
1219 obstack_1grow (&argv_stk, *p);
1220 else
1221 obstack_1grow (&argv_stk, '\n');
1222 obstack_1grow (&argv_stk, 0);
1223 count = 1;
1224 /* Read rest of files using new filename terminator */
1225 term = 0;
1226 break;
1227 }
1228
1229 case file_list_skip:
1230 break;
1231 }
1232 }
1233
1234 if (!is_stdin)
1235 fclose (fp);
1236
1237 if (count == 0)
1238 return;
1239
1240 start = obstack_finish (&argv_stk);
1241
1242 if (term == 0)
1243 for (p = start; *p; p += strlen (p) + 1)
1244 if (p[0] == '-')
1245 count++;
1246
1247 new_argc = state->argc + count;
1248 new_argv = xmalloc (sizeof (state->argv[0]) * (new_argc + 1));
1249 memcpy (new_argv, state->argv, sizeof (state->argv[0]) * (state->argc + 1));
1250 state->argv = new_argv;
1251 memmove (&state->argv[state->next + count], &state->argv[state->next],
1252 (state->argc - state->next + 1) * sizeof (state->argv[0]));
1253
1254 state->argc = new_argc;
1255
1256 for (i = state->next, p = start; *p; p += strlen (p) + 1, i++)
1257 {
1258 if (term == 0 && p[0] == '-')
1259 state->argv[i++] = "--add-file";
1260 state->argv[i] = p;
1261 }
1262 }
1263
1264 \f
1265 static char *
1266 tar_help_filter (int key, const char *text, void *input)
1267 {
1268 struct obstack stk;
1269 char *s;
1270
1271 switch (key)
1272 {
1273 default:
1274 s = (char*) text;
1275 break;
1276
1277 case 'j':
1278 s = xasprintf (_("filter the archive through %s"), BZIP2_PROGRAM);
1279 break;
1280
1281 case 'z':
1282 s = xasprintf (_("filter the archive through %s"), GZIP_PROGRAM);
1283 break;
1284
1285 case 'Z':
1286 s = xasprintf (_("filter the archive through %s"), COMPRESS_PROGRAM);
1287 break;
1288
1289 case LZIP_OPTION:
1290 s = xasprintf (_("filter the archive through %s"), LZIP_PROGRAM);
1291 break;
1292
1293 case LZMA_OPTION:
1294 s = xasprintf (_("filter the archive through %s"), LZMA_PROGRAM);
1295 break;
1296
1297 case 'J':
1298 s = xasprintf (_("filter the archive through %s"), XZ_PROGRAM);
1299 break;
1300
1301 case ARGP_KEY_HELP_EXTRA:
1302 {
1303 const char *tstr;
1304
1305 obstack_init (&stk);
1306 tstr = _("Valid arguments for the --quoting-style option are:");
1307 obstack_grow (&stk, tstr, strlen (tstr));
1308 obstack_grow (&stk, "\n\n", 2);
1309 tar_list_quoting_styles (&stk, " ");
1310 tstr = _("\n*This* tar defaults to:\n");
1311 obstack_grow (&stk, tstr, strlen (tstr));
1312 s = format_default_settings ();
1313 obstack_grow (&stk, s, strlen (s));
1314 obstack_1grow (&stk, '\n');
1315 obstack_1grow (&stk, 0);
1316 s = xstrdup (obstack_finish (&stk));
1317 obstack_free (&stk, NULL);
1318 }
1319 }
1320 return s;
1321 }
1322 \f
1323 static char *
1324 expand_pax_option (struct tar_args *targs, const char *arg)
1325 {
1326 struct obstack stk;
1327 char *res;
1328
1329 obstack_init (&stk);
1330 while (*arg)
1331 {
1332 size_t seglen = strcspn (arg, ",");
1333 char *p = memchr (arg, '=', seglen);
1334 if (p)
1335 {
1336 size_t len = p - arg + 1;
1337 obstack_grow (&stk, arg, len);
1338 len = seglen - len;
1339 for (++p; *p && isspace ((unsigned char) *p); p++)
1340 len--;
1341 if (*p == '{' && p[len-1] == '}')
1342 {
1343 struct timespec ts;
1344 char *tmp = xmalloc (len);
1345 memcpy (tmp, p + 1, len-2);
1346 tmp[len-2] = 0;
1347 if (get_date_or_file (targs, "--pax-option", tmp, &ts) == 0)
1348 {
1349 char buf[UINTMAX_STRSIZE_BOUND], *s;
1350 s = umaxtostr (ts.tv_sec, buf);
1351 obstack_grow (&stk, s, strlen (s));
1352 }
1353 else
1354 obstack_grow (&stk, p, len);
1355 free (tmp);
1356 }
1357 else
1358 obstack_grow (&stk, p, len);
1359 }
1360 else
1361 obstack_grow (&stk, arg, seglen);
1362
1363 arg += seglen;
1364 if (*arg)
1365 {
1366 obstack_1grow (&stk, *arg);
1367 arg++;
1368 }
1369 }
1370 obstack_1grow (&stk, 0);
1371 res = xstrdup (obstack_finish (&stk));
1372 obstack_free (&stk, NULL);
1373 return res;
1374 }
1375
1376 \f
1377 static uintmax_t
1378 parse_owner_group (char *arg, uintmax_t field_max, char const **name_option)
1379 {
1380 uintmax_t u = UINTMAX_MAX;
1381 char *end;
1382 char const *name = 0;
1383 char const *invalid_num = 0;
1384 char *colon = strchr (arg, ':');
1385
1386 if (colon)
1387 {
1388 char const *num = colon + 1;
1389 *colon = '\0';
1390 if (*arg)
1391 name = arg;
1392 if (num && (! (xstrtoumax (num, &end, 10, &u, "") == LONGINT_OK
1393 && u <= field_max)))
1394 invalid_num = num;
1395 }
1396 else
1397 {
1398 uintmax_t u1;
1399 switch ('0' <= *arg && *arg <= '9'
1400 ? xstrtoumax (arg, &end, 10, &u1, "")
1401 : LONGINT_INVALID)
1402 {
1403 default:
1404 name = arg;
1405 break;
1406
1407 case LONGINT_OK:
1408 if (u1 <= field_max)
1409 {
1410 u = u1;
1411 break;
1412 }
1413 /* Fall through. */
1414 case LONGINT_OVERFLOW:
1415 invalid_num = arg;
1416 break;
1417 }
1418 }
1419
1420 if (invalid_num)
1421 FATAL_ERROR ((0, 0, "%s: %s", quotearg_colon (invalid_num),
1422 _("Invalid owner or group ID")));
1423 if (name)
1424 *name_option = name;
1425 return u;
1426 }
1427
1428 #define TAR_SIZE_SUFFIXES "bBcGgkKMmPTtw"
1429
1430 static error_t
1431 parse_opt (int key, char *arg, struct argp_state *state)
1432 {
1433 struct tar_args *args = state->input;
1434
1435 switch (key)
1436 {
1437 case ARGP_KEY_ARG:
1438 /* File name or non-parsed option, because of ARGP_IN_ORDER */
1439 name_add_name (arg, MAKE_INCL_OPTIONS (args));
1440 args->input_files = true;
1441 break;
1442
1443 case 'A':
1444 set_subcommand_option (CAT_SUBCOMMAND);
1445 break;
1446
1447 case 'a':
1448 args->compress_autodetect = true;
1449 break;
1450
1451 case NO_AUTO_COMPRESS_OPTION:
1452 args->compress_autodetect = false;
1453 break;
1454
1455 case 'b':
1456 {
1457 uintmax_t u;
1458 if (! (xstrtoumax (arg, 0, 10, &u, "") == LONGINT_OK
1459 && u == (blocking_factor = u)
1460 && 0 < blocking_factor
1461 && u == (record_size = u * BLOCKSIZE) / BLOCKSIZE))
1462 USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (arg),
1463 _("Invalid blocking factor")));
1464 }
1465 break;
1466
1467 case 'B':
1468 /* Try to reblock input records. For reading 4.2BSD pipes. */
1469
1470 /* It would surely make sense to exchange -B and -R, but it seems
1471 that -B has been used for a long while in Sun tar and most
1472 BSD-derived systems. This is a consequence of the block/record
1473 terminology confusion. */
1474
1475 read_full_records_option = true;
1476 break;
1477
1478 case 'c':
1479 set_subcommand_option (CREATE_SUBCOMMAND);
1480 break;
1481
1482 case 'C':
1483 name_add_dir (arg);
1484 break;
1485
1486 case 'd':
1487 set_subcommand_option (DIFF_SUBCOMMAND);
1488 break;
1489
1490 case 'f':
1491 if (archive_names == allocated_archive_names)
1492 archive_name_array = x2nrealloc (archive_name_array,
1493 &allocated_archive_names,
1494 sizeof (archive_name_array[0]));
1495
1496 archive_name_array[archive_names++] = arg;
1497 break;
1498
1499 case 'F':
1500 /* Since -F is only useful with -M, make it implied. Run this
1501 script at the end of each tape. */
1502
1503 info_script_option = arg;
1504 multi_volume_option = true;
1505 break;
1506
1507 case FULL_TIME_OPTION:
1508 full_time_option = true;
1509 break;
1510
1511 case 'g':
1512 listed_incremental_option = arg;
1513 after_date_option = true;
1514 /* Fall through. */
1515
1516 case 'G':
1517 /* We are making an incremental dump (FIXME: are we?); save
1518 directories at the beginning of the archive, and include in each
1519 directory its contents. */
1520
1521 incremental_option = true;
1522 break;
1523
1524 case 'h':
1525 /* Follow symbolic links. */
1526 dereference_option = true;
1527 break;
1528
1529 case HARD_DEREFERENCE_OPTION:
1530 hard_dereference_option = true;
1531 break;
1532
1533 case 'i':
1534 /* Ignore zero blocks (eofs). This can't be the default,
1535 because Unix tar writes two blocks of zeros, then pads out
1536 the record with garbage. */
1537
1538 ignore_zeros_option = true;
1539 break;
1540
1541 case 'j':
1542 set_use_compress_program_option (BZIP2_PROGRAM);
1543 break;
1544
1545 case 'J':
1546 set_use_compress_program_option (XZ_PROGRAM);
1547 break;
1548
1549 case 'k':
1550 /* Don't replace existing files. */
1551 old_files_option = KEEP_OLD_FILES;
1552 break;
1553
1554 case 'K':
1555 starting_file_option = true;
1556 addname (arg, 0, true, NULL);
1557 break;
1558
1559 case ONE_FILE_SYSTEM_OPTION:
1560 /* When dumping directories, don't dump files/subdirectories
1561 that are on other filesystems. */
1562 one_file_system_option = true;
1563 break;
1564
1565 case 'l':
1566 check_links_option = 1;
1567 break;
1568
1569 case 'L':
1570 {
1571 uintmax_t u;
1572 char *p;
1573
1574 if (xstrtoumax (arg, &p, 10, &u, TAR_SIZE_SUFFIXES) != LONGINT_OK)
1575 USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (arg),
1576 _("Invalid tape length")));
1577 if (p > arg && !strchr (TAR_SIZE_SUFFIXES, p[-1]))
1578 tape_length_option = 1024 * (tarlong) u;
1579 else
1580 tape_length_option = (tarlong) u;
1581 multi_volume_option = true;
1582 }
1583 break;
1584
1585 case LEVEL_OPTION:
1586 {
1587 char *p;
1588 incremental_level = strtoul (arg, &p, 10);
1589 if (*p)
1590 USAGE_ERROR ((0, 0, _("Invalid incremental level value")));
1591 }
1592 break;
1593
1594 case LZIP_OPTION:
1595 set_use_compress_program_option (LZIP_PROGRAM);
1596 break;
1597
1598 case LZMA_OPTION:
1599 set_use_compress_program_option (LZMA_PROGRAM);
1600 break;
1601
1602 case LZOP_OPTION:
1603 set_use_compress_program_option (LZOP_PROGRAM);
1604 break;
1605
1606 case 'm':
1607 touch_option = true;
1608 break;
1609
1610 case 'M':
1611 /* Make multivolume archive: when we can't write any more into
1612 the archive, re-open it, and continue writing. */
1613
1614 multi_volume_option = true;
1615 break;
1616
1617 case MTIME_OPTION:
1618 get_date_or_file (args, "--mtime", arg, &mtime_option);
1619 set_mtime_option = true;
1620 break;
1621
1622 case 'n':
1623 seek_option = 1;
1624 break;
1625
1626 case NO_SEEK_OPTION:
1627 seek_option = 0;
1628 break;
1629
1630 case 'N':
1631 after_date_option = true;
1632 /* Fall through. */
1633
1634 case NEWER_MTIME_OPTION:
1635 if (NEWER_OPTION_INITIALIZED (newer_mtime_option))
1636 USAGE_ERROR ((0, 0, _("More than one threshold date")));
1637 get_date_or_file (args,
1638 key == NEWER_MTIME_OPTION ? "--newer-mtime"
1639 : "--after-date", arg, &newer_mtime_option);
1640 break;
1641
1642 case 'o':
1643 args->o_option = true;
1644 break;
1645
1646 case 'O':
1647 to_stdout_option = true;
1648 break;
1649
1650 case 'p':
1651 same_permissions_option = true;
1652 break;
1653
1654 case 'P':
1655 absolute_names_option = true;
1656 break;
1657
1658 case 'r':
1659 set_subcommand_option (APPEND_SUBCOMMAND);
1660 break;
1661
1662 case 'R':
1663 /* Print block numbers for debugging bad tar archives. */
1664
1665 /* It would surely make sense to exchange -B and -R, but it seems
1666 that -B has been used for a long while in Sun tar and most
1667 BSD-derived systems. This is a consequence of the block/record
1668 terminology confusion. */
1669
1670 block_number_option = true;
1671 break;
1672
1673 case 's':
1674 /* Names to extract are sorted. */
1675
1676 same_order_option = true;
1677 break;
1678
1679 case 'S':
1680 sparse_option = true;
1681 break;
1682
1683 case SKIP_OLD_FILES_OPTION:
1684 old_files_option = SKIP_OLD_FILES;
1685 break;
1686
1687 case SPARSE_VERSION_OPTION:
1688 sparse_option = true;
1689 {
1690 char *p;
1691 tar_sparse_major = strtoul (arg, &p, 10);
1692 if (*p)
1693 {
1694 if (*p != '.')
1695 USAGE_ERROR ((0, 0, _("Invalid sparse version value")));
1696 tar_sparse_minor = strtoul (p + 1, &p, 10);
1697 if (*p)
1698 USAGE_ERROR ((0, 0, _("Invalid sparse version value")));
1699 }
1700 }
1701 break;
1702
1703 case 't':
1704 set_subcommand_option (LIST_SUBCOMMAND);
1705 verbose_option++;
1706 break;
1707
1708 case TEST_LABEL_OPTION:
1709 set_subcommand_option (TEST_LABEL_SUBCOMMAND);
1710 break;
1711
1712 case 'T':
1713 update_argv (arg, state);
1714 /* Indicate we've been given -T option. This is for backward
1715 compatibility only, so that `tar cfT archive /dev/null will
1716 succeed */
1717 files_from_option = true;
1718 break;
1719
1720 case 'u':
1721 set_subcommand_option (UPDATE_SUBCOMMAND);
1722 break;
1723
1724 case 'U':
1725 old_files_option = UNLINK_FIRST_OLD_FILES;
1726 break;
1727
1728 case UTC_OPTION:
1729 utc_option = true;
1730 break;
1731
1732 case 'v':
1733 verbose_option++;
1734 warning_option |= WARN_VERBOSE_WARNINGS;
1735 break;
1736
1737 case 'V':
1738 volume_label_option = arg;
1739 break;
1740
1741 case 'w':
1742 interactive_option = true;
1743 break;
1744
1745 case 'W':
1746 verify_option = true;
1747 break;
1748
1749 case 'x':
1750 set_subcommand_option (EXTRACT_SUBCOMMAND);
1751 break;
1752
1753 case 'X':
1754 if (add_exclude_file (add_exclude, excluded, arg,
1755 MAKE_EXCL_OPTIONS (args), '\n')
1756 != 0)
1757 {
1758 int e = errno;
1759 FATAL_ERROR ((0, e, "%s", quotearg_colon (arg)));
1760 }
1761 break;
1762
1763 case 'z':
1764 set_use_compress_program_option (GZIP_PROGRAM);
1765 break;
1766
1767 case 'Z':
1768 set_use_compress_program_option (COMPRESS_PROGRAM);
1769 break;
1770
1771 case ANCHORED_OPTION:
1772 args->matching_flags |= EXCLUDE_ANCHORED;
1773 break;
1774
1775 case ATIME_PRESERVE_OPTION:
1776 atime_preserve_option =
1777 (arg
1778 ? XARGMATCH ("--atime-preserve", arg,
1779 atime_preserve_args, atime_preserve_types)
1780 : replace_atime_preserve);
1781 if (! O_NOATIME && atime_preserve_option == system_atime_preserve)
1782 FATAL_ERROR ((0, 0,
1783 _("--atime-preserve='system' is not supported"
1784 " on this platform")));
1785 break;
1786
1787 case CHECK_DEVICE_OPTION:
1788 check_device_option = true;
1789 break;
1790
1791 case NO_CHECK_DEVICE_OPTION:
1792 check_device_option = false;
1793 break;
1794
1795 case CHECKPOINT_OPTION:
1796 if (arg)
1797 {
1798 char *p;
1799
1800 if (*arg == '.')
1801 {
1802 checkpoint_compile_action (".");
1803 arg++;
1804 }
1805 checkpoint_option = strtoul (arg, &p, 0);
1806 if (*p)
1807 FATAL_ERROR ((0, 0,
1808 _("--checkpoint value is not an integer")));
1809 }
1810 else
1811 checkpoint_option = DEFAULT_CHECKPOINT;
1812 break;
1813
1814 case CHECKPOINT_ACTION_OPTION:
1815 checkpoint_compile_action (arg);
1816 break;
1817
1818 case BACKUP_OPTION:
1819 backup_option = true;
1820 if (arg)
1821 args->version_control_string = arg;
1822 break;
1823
1824 case DELAY_DIRECTORY_RESTORE_OPTION:
1825 delay_directory_restore_option = true;
1826 break;
1827
1828 case NO_DELAY_DIRECTORY_RESTORE_OPTION:
1829 delay_directory_restore_option = false;
1830 break;
1831
1832 case DELETE_OPTION:
1833 set_subcommand_option (DELETE_SUBCOMMAND);
1834 break;
1835
1836 case EXCLUDE_BACKUPS_OPTION:
1837 add_exclude_array (backup_file_table, EXCLUDE_WILDCARDS);
1838 break;
1839
1840 case EXCLUDE_OPTION:
1841 add_exclude (excluded, arg, MAKE_EXCL_OPTIONS (args));
1842 break;
1843
1844 case EXCLUDE_CACHES_OPTION:
1845 add_exclusion_tag ("CACHEDIR.TAG", exclusion_tag_contents,
1846 cachedir_file_p);
1847 break;
1848
1849 case EXCLUDE_CACHES_UNDER_OPTION:
1850 add_exclusion_tag ("CACHEDIR.TAG", exclusion_tag_under,
1851 cachedir_file_p);
1852 break;
1853
1854 case EXCLUDE_CACHES_ALL_OPTION:
1855 add_exclusion_tag ("CACHEDIR.TAG", exclusion_tag_all,
1856 cachedir_file_p);
1857 break;
1858
1859 case EXCLUDE_TAG_OPTION:
1860 add_exclusion_tag (arg, exclusion_tag_contents, NULL);
1861 break;
1862
1863 case EXCLUDE_TAG_UNDER_OPTION:
1864 add_exclusion_tag (arg, exclusion_tag_under, NULL);
1865 break;
1866
1867 case EXCLUDE_TAG_ALL_OPTION:
1868 add_exclusion_tag (arg, exclusion_tag_all, NULL);
1869 break;
1870
1871 case EXCLUDE_VCS_OPTION:
1872 add_exclude_array (vcs_file_table, 0);
1873 break;
1874
1875 case FORCE_LOCAL_OPTION:
1876 force_local_option = true;
1877 break;
1878
1879 case 'H':
1880 set_archive_format (arg);
1881 break;
1882
1883 case INDEX_FILE_OPTION:
1884 index_file_name = arg;
1885 break;
1886
1887 case IGNORE_CASE_OPTION:
1888 args->matching_flags |= FNM_CASEFOLD;
1889 break;
1890
1891 case IGNORE_COMMAND_ERROR_OPTION:
1892 ignore_command_error_option = true;
1893 break;
1894
1895 case IGNORE_FAILED_READ_OPTION:
1896 ignore_failed_read_option = true;
1897 break;
1898
1899 case KEEP_NEWER_FILES_OPTION:
1900 old_files_option = KEEP_NEWER_FILES;
1901 break;
1902
1903 case GROUP_OPTION:
1904 {
1905 uintmax_t u = parse_owner_group (arg, TYPE_MAXIMUM (gid_t),
1906 &group_name_option);
1907 if (u == UINTMAX_MAX)
1908 {
1909 group_option = -1;
1910 if (group_name_option)
1911 gname_to_gid (group_name_option, &group_option);
1912 }
1913 else
1914 group_option = u;
1915 }
1916 break;
1917
1918 case MODE_OPTION:
1919 mode_option = mode_compile (arg);
1920 if (!mode_option)
1921 FATAL_ERROR ((0, 0, _("Invalid mode given on option")));
1922 initial_umask = umask (0);
1923 umask (initial_umask);
1924 break;
1925
1926 case NO_ANCHORED_OPTION:
1927 args->include_anchored = 0; /* Clear the default for comman line args */
1928 args->matching_flags &= ~ EXCLUDE_ANCHORED;
1929 break;
1930
1931 case NO_IGNORE_CASE_OPTION:
1932 args->matching_flags &= ~ FNM_CASEFOLD;
1933 break;
1934
1935 case NO_IGNORE_COMMAND_ERROR_OPTION:
1936 ignore_command_error_option = false;
1937 break;
1938
1939 case NO_OVERWRITE_DIR_OPTION:
1940 old_files_option = NO_OVERWRITE_DIR_OLD_FILES;
1941 break;
1942
1943 case NO_QUOTE_CHARS_OPTION:
1944 for (;*arg; arg++)
1945 set_char_quoting (NULL, *arg, 0);
1946 break;
1947
1948 case NO_WILDCARDS_OPTION:
1949 args->wildcards = disable_wildcards;
1950 break;
1951
1952 case NO_WILDCARDS_MATCH_SLASH_OPTION:
1953 args->matching_flags |= FNM_FILE_NAME;
1954 break;
1955
1956 case NULL_OPTION:
1957 filename_terminator = '\0';
1958 break;
1959
1960 case NO_NULL_OPTION:
1961 filename_terminator = '\n';
1962 break;
1963
1964 case NUMERIC_OWNER_OPTION:
1965 numeric_owner_option = true;
1966 break;
1967
1968 case OCCURRENCE_OPTION:
1969 if (!arg)
1970 occurrence_option = 1;
1971 else
1972 {
1973 uintmax_t u;
1974 if (xstrtoumax (arg, 0, 10, &u, "") == LONGINT_OK)
1975 occurrence_option = u;
1976 else
1977 FATAL_ERROR ((0, 0, "%s: %s", quotearg_colon (arg),
1978 _("Invalid number")));
1979 }
1980 break;
1981
1982 case OVERWRITE_DIR_OPTION:
1983 old_files_option = DEFAULT_OLD_FILES;
1984 break;
1985
1986 case OVERWRITE_OPTION:
1987 old_files_option = OVERWRITE_OLD_FILES;
1988 break;
1989
1990 case OWNER_OPTION:
1991 {
1992 uintmax_t u = parse_owner_group (arg, TYPE_MAXIMUM (uid_t),
1993 &owner_name_option);
1994 if (u == UINTMAX_MAX)
1995 {
1996 owner_option = -1;
1997 if (owner_name_option)
1998 uname_to_uid (owner_name_option, &owner_option);
1999 }
2000 else
2001 owner_option = u;
2002 }
2003 break;
2004
2005 case QUOTE_CHARS_OPTION:
2006 for (;*arg; arg++)
2007 set_char_quoting (NULL, *arg, 1);
2008 break;
2009
2010 case QUOTING_STYLE_OPTION:
2011 tar_set_quoting_style (arg);
2012 break;
2013
2014 case PAX_OPTION:
2015 {
2016 char *tmp = expand_pax_option (args, arg);
2017 args->pax_option = true;
2018 xheader_set_option (tmp);
2019 free (tmp);
2020 }
2021 break;
2022
2023 case POSIX_OPTION:
2024 set_archive_format ("posix");
2025 break;
2026
2027 case PRESERVE_OPTION:
2028 /* FIXME: What it is good for? */
2029 same_permissions_option = true;
2030 same_order_option = true;
2031 WARN ((0, 0, _("The --preserve option is deprecated, "
2032 "use --preserve-permissions --preserve-order instead")));
2033 break;
2034
2035 case RECORD_SIZE_OPTION:
2036 {
2037 uintmax_t u;
2038
2039 if (! (xstrtoumax (arg, NULL, 10, &u, TAR_SIZE_SUFFIXES) == LONGINT_OK
2040 && u == (size_t) u))
2041 USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (arg),
2042 _("Invalid record size")));
2043 record_size = u;
2044 if (record_size % BLOCKSIZE != 0)
2045 USAGE_ERROR ((0, 0, _("Record size must be a multiple of %d."),
2046 BLOCKSIZE));
2047 blocking_factor = record_size / BLOCKSIZE;
2048 }
2049 break;
2050
2051 case RECURSIVE_UNLINK_OPTION:
2052 recursive_unlink_option = true;
2053 break;
2054
2055 case REMOVE_FILES_OPTION:
2056 remove_files_option = true;
2057 break;
2058
2059 case RESTRICT_OPTION:
2060 restrict_option = true;
2061 break;
2062
2063 case RMT_COMMAND_OPTION:
2064 rmt_command = arg;
2065 break;
2066
2067 case RSH_COMMAND_OPTION:
2068 rsh_command_option = arg;
2069 break;
2070
2071 case SHOW_DEFAULTS_OPTION:
2072 {
2073 char *s = format_default_settings ();
2074 printf ("%s\n", s);
2075 close_stdout ();
2076 free (s);
2077 exit (0);
2078 }
2079
2080 case STRIP_COMPONENTS_OPTION:
2081 {
2082 uintmax_t u;
2083 if (! (xstrtoumax (arg, 0, 10, &u, "") == LONGINT_OK
2084 && u == (size_t) u))
2085 USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (arg),
2086 _("Invalid number of elements")));
2087 strip_name_components = u;
2088 }
2089 break;
2090
2091 case SHOW_OMITTED_DIRS_OPTION:
2092 show_omitted_dirs_option = true;
2093 break;
2094
2095 case SHOW_TRANSFORMED_NAMES_OPTION:
2096 show_transformed_names_option = true;
2097 break;
2098
2099 case SUFFIX_OPTION:
2100 backup_option = true;
2101 args->backup_suffix_string = arg;
2102 break;
2103
2104 case TO_COMMAND_OPTION:
2105 if (to_command_option)
2106 USAGE_ERROR ((0, 0, _("Only one --to-command option allowed")));
2107 to_command_option = arg;
2108 break;
2109
2110 case TOTALS_OPTION:
2111 if (arg)
2112 set_stat_signal (arg);
2113 else
2114 totals_option = true;
2115 break;
2116
2117 case TRANSFORM_OPTION:
2118 set_transform_expr (arg);
2119 break;
2120
2121 case 'I':
2122 set_use_compress_program_option (arg);
2123 break;
2124
2125 case VOLNO_FILE_OPTION:
2126 volno_file_option = arg;
2127 break;
2128
2129 case WILDCARDS_OPTION:
2130 args->wildcards = enable_wildcards;
2131 break;
2132
2133 case WILDCARDS_MATCH_SLASH_OPTION:
2134 args->matching_flags &= ~ FNM_FILE_NAME;
2135 break;
2136
2137 case NO_RECURSION_OPTION:
2138 recursion_option = 0;
2139 break;
2140
2141 case NO_SAME_OWNER_OPTION:
2142 same_owner_option = -1;
2143 break;
2144
2145 case NO_SAME_PERMISSIONS_OPTION:
2146 same_permissions_option = -1;
2147 break;
2148
2149 case RECURSION_OPTION:
2150 recursion_option = FNM_LEADING_DIR;
2151 break;
2152
2153 case SAME_OWNER_OPTION:
2154 same_owner_option = 1;
2155 break;
2156
2157 case UNQUOTE_OPTION:
2158 unquote_option = true;
2159 break;
2160
2161 case NO_UNQUOTE_OPTION:
2162 unquote_option = false;
2163 break;
2164
2165 case WARNING_OPTION:
2166 set_warning_option (arg);
2167 break;
2168
2169 case '0':
2170 case '1':
2171 case '2':
2172 case '3':
2173 case '4':
2174 case '5':
2175 case '6':
2176 case '7':
2177
2178 #ifdef DEVICE_PREFIX
2179 {
2180 int device = key - '0';
2181 int density;
2182 static char buf[sizeof DEVICE_PREFIX + 10];
2183 char *cursor;
2184
2185 if (arg[1])
2186 argp_error (state, _("Malformed density argument: %s"), quote (arg));
2187
2188 strcpy (buf, DEVICE_PREFIX);
2189 cursor = buf + strlen (buf);
2190
2191 #ifdef DENSITY_LETTER
2192
2193 sprintf (cursor, "%d%c", device, arg[0]);
2194
2195 #else /* not DENSITY_LETTER */
2196
2197 switch (arg[0])
2198 {
2199 case 'l':
2200 device += LOW_DENSITY_NUM;
2201 break;
2202
2203 case 'm':
2204 device += MID_DENSITY_NUM;
2205 break;
2206
2207 case 'h':
2208 device += HIGH_DENSITY_NUM;
2209 break;
2210
2211 default:
2212 argp_error (state, _("Unknown density: '%c'"), arg[0]);
2213 }
2214 sprintf (cursor, "%d", device);
2215
2216 #endif /* not DENSITY_LETTER */
2217
2218 if (archive_names == allocated_archive_names)
2219 archive_name_array = x2nrealloc (archive_name_array,
2220 &allocated_archive_names,
2221 sizeof (archive_name_array[0]));
2222 archive_name_array[archive_names++] = xstrdup (buf);
2223 }
2224 break;
2225
2226 #else /* not DEVICE_PREFIX */
2227
2228 argp_error (state,
2229 _("Options '-[0-7][lmh]' not supported by *this* tar"));
2230
2231 #endif /* not DEVICE_PREFIX */
2232
2233 default:
2234 return ARGP_ERR_UNKNOWN;
2235 }
2236 return 0;
2237 }
2238
2239 static struct argp argp = {
2240 options,
2241 parse_opt,
2242 N_("[FILE]..."),
2243 doc,
2244 NULL,
2245 tar_help_filter,
2246 NULL
2247 };
2248
2249 void
2250 usage (int status)
2251 {
2252 argp_help (&argp, stderr, ARGP_HELP_SEE, (char*) program_name);
2253 close_stdout ();
2254 exit (status);
2255 }
2256
2257 /* Parse the options for tar. */
2258
2259 static struct argp_option *
2260 find_argp_option (struct argp_option *o, int letter)
2261 {
2262 for (;
2263 !(o->name == NULL
2264 && o->key == 0
2265 && o->arg == 0
2266 && o->flags == 0
2267 && o->doc == NULL); o++)
2268 if (o->key == letter)
2269 return o;
2270 return NULL;
2271 }
2272
2273 static const char *tar_authors[] = {
2274 "John Gilmore",
2275 "Jay Fenlason",
2276 NULL
2277 };
2278
2279 static void
2280 decode_options (int argc, char **argv)
2281 {
2282 int idx;
2283 struct tar_args args;
2284
2285 argp_version_setup ("tar", tar_authors);
2286
2287 /* Set some default option values. */
2288 args.textual_date = NULL;
2289 args.wildcards = default_wildcards;
2290 args.matching_flags = 0;
2291 args.include_anchored = EXCLUDE_ANCHORED;
2292 args.o_option = false;
2293 args.pax_option = false;
2294 args.backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX");
2295 args.version_control_string = 0;
2296 args.input_files = false;
2297 args.compress_autodetect = false;
2298
2299 subcommand_option = UNKNOWN_SUBCOMMAND;
2300 archive_format = DEFAULT_FORMAT;
2301 blocking_factor = DEFAULT_BLOCKING;
2302 record_size = DEFAULT_BLOCKING * BLOCKSIZE;
2303 excluded = new_exclude ();
2304 newer_mtime_option.tv_sec = TYPE_MINIMUM (time_t);
2305 newer_mtime_option.tv_nsec = -1;
2306 recursion_option = FNM_LEADING_DIR;
2307 unquote_option = true;
2308 tar_sparse_major = 1;
2309 tar_sparse_minor = 0;
2310
2311 owner_option = -1; owner_name_option = NULL;
2312 group_option = -1; group_name_option = NULL;
2313
2314 check_device_option = true;
2315
2316 incremental_level = -1;
2317
2318 seek_option = -1;
2319
2320 /* Convert old-style tar call by exploding option element and rearranging
2321 options accordingly. */
2322
2323 if (argc > 1 && argv[1][0] != '-')
2324 {
2325 int new_argc; /* argc value for rearranged arguments */
2326 char **new_argv; /* argv value for rearranged arguments */
2327 char *const *in; /* cursor into original argv */
2328 char **out; /* cursor into rearranged argv */
2329 const char *letter; /* cursor into old option letters */
2330 char buffer[3]; /* constructed option buffer */
2331
2332 /* Initialize a constructed option. */
2333
2334 buffer[0] = '-';
2335 buffer[2] = '\0';
2336
2337 /* Allocate a new argument array, and copy program name in it. */
2338
2339 new_argc = argc - 1 + strlen (argv[1]);
2340 new_argv = xmalloc ((new_argc + 1) * sizeof (char *));
2341 in = argv;
2342 out = new_argv;
2343 *out++ = *in++;
2344
2345 /* Copy each old letter option as a separate option, and have the
2346 corresponding argument moved next to it. */
2347
2348 for (letter = *in++; *letter; letter++)
2349 {
2350 struct argp_option *opt;
2351
2352 buffer[1] = *letter;
2353 *out++ = xstrdup (buffer);
2354 opt = find_argp_option (options, *letter);
2355 if (opt && opt->arg)
2356 {
2357 if (in < argv + argc)
2358 *out++ = *in++;
2359 else
2360 USAGE_ERROR ((0, 0, _("Old option '%c' requires an argument."),
2361 *letter));
2362 }
2363 }
2364
2365 /* Copy all remaining options. */
2366
2367 while (in < argv + argc)
2368 *out++ = *in++;
2369 *out = 0;
2370
2371 /* Replace the old option list by the new one. */
2372
2373 argc = new_argc;
2374 argv = new_argv;
2375 }
2376
2377 /* Parse all options and non-options as they appear. */
2378
2379 prepend_default_options (getenv ("TAR_OPTIONS"), &argc, &argv);
2380
2381 if (argp_parse (&argp, argc, argv, ARGP_IN_ORDER, &idx, &args))
2382 exit (TAREXIT_FAILURE);
2383
2384
2385 /* Special handling for 'o' option:
2386
2387 GNU tar used to say "output old format".
2388 UNIX98 tar says don't chown files after extracting (we use
2389 "--no-same-owner" for this).
2390
2391 The old GNU tar semantics is retained when used with --create
2392 option, otherwise UNIX98 semantics is assumed */
2393
2394 if (args.o_option)
2395 {
2396 if (subcommand_option == CREATE_SUBCOMMAND)
2397 {
2398 /* GNU Tar <= 1.13 compatibility */
2399 set_archive_format ("v7");
2400 }
2401 else
2402 {
2403 /* UNIX98 compatibility */
2404 same_owner_option = -1;
2405 }
2406 }
2407
2408 /* Handle operands after any "--" argument. */
2409 for (; idx < argc; idx++)
2410 {
2411 name_add_name (argv[idx], MAKE_INCL_OPTIONS (&args));
2412 args.input_files = true;
2413 }
2414
2415 /* Warn about implicit use of the wildcards in command line arguments.
2416 See TODO */
2417 warn_regex_usage = args.wildcards == default_wildcards;
2418
2419 /* Derive option values and check option consistency. */
2420
2421 if (archive_format == DEFAULT_FORMAT)
2422 {
2423 if (args.pax_option)
2424 archive_format = POSIX_FORMAT;
2425 else
2426 archive_format = DEFAULT_ARCHIVE_FORMAT;
2427 }
2428
2429 if ((volume_label_option && subcommand_option == CREATE_SUBCOMMAND)
2430 || incremental_option
2431 || multi_volume_option
2432 || sparse_option)
2433 assert_format (FORMAT_MASK (OLDGNU_FORMAT)
2434 | FORMAT_MASK (GNU_FORMAT)
2435 | FORMAT_MASK (POSIX_FORMAT));
2436
2437 if (occurrence_option)
2438 {
2439 if (!args.input_files)
2440 USAGE_ERROR ((0, 0,
2441 _("--occurrence is meaningless without a file list")));
2442 if (subcommand_option != DELETE_SUBCOMMAND
2443 && subcommand_option != DIFF_SUBCOMMAND
2444 && subcommand_option != EXTRACT_SUBCOMMAND
2445 && subcommand_option != LIST_SUBCOMMAND)
2446 USAGE_ERROR ((0, 0,
2447 _("--occurrence cannot be used in the requested operation mode")));
2448 }
2449
2450 if (archive_names == 0)
2451 {
2452 /* If no archive file name given, try TAPE from the environment, or
2453 else, DEFAULT_ARCHIVE from the configuration process. */
2454
2455 archive_names = 1;
2456 archive_name_array[0] = getenv ("TAPE");
2457 if (! archive_name_array[0])
2458 archive_name_array[0] = DEFAULT_ARCHIVE;
2459 }
2460
2461 /* Allow multiple archives only with '-M'. */
2462
2463 if (archive_names > 1 && !multi_volume_option)
2464 USAGE_ERROR ((0, 0,
2465 _("Multiple archive files require '-M' option")));
2466
2467 if (listed_incremental_option
2468 && NEWER_OPTION_INITIALIZED (newer_mtime_option))
2469 USAGE_ERROR ((0, 0,
2470 _("Cannot combine --listed-incremental with --newer")));
2471 if (incremental_level != -1 && !listed_incremental_option)
2472 WARN ((0, 0,
2473 _("--level is meaningless without --listed-incremental")));
2474
2475 if (volume_label_option)
2476 {
2477 if (archive_format == GNU_FORMAT || archive_format == OLDGNU_FORMAT)
2478 {
2479 size_t volume_label_max_len =
2480 (sizeof current_header->header.name
2481 - 1 /* for trailing '\0' */
2482 - (multi_volume_option
2483 ? (sizeof " Volume "
2484 - 1 /* for null at end of " Volume " */
2485 + INT_STRLEN_BOUND (int) /* for volume number */
2486 - 1 /* for sign, as 0 <= volno */)
2487 : 0));
2488 if (volume_label_max_len < strlen (volume_label_option))
2489 USAGE_ERROR ((0, 0,
2490 ngettext ("%s: Volume label is too long (limit is %lu byte)",
2491 "%s: Volume label is too long (limit is %lu bytes)",
2492 volume_label_max_len),
2493 quotearg_colon (volume_label_option),
2494 (unsigned long) volume_label_max_len));
2495 }
2496 /* else FIXME
2497 Label length in PAX format is limited by the volume size. */
2498 }
2499
2500 if (verify_option)
2501 {
2502 if (multi_volume_option)
2503 USAGE_ERROR ((0, 0, _("Cannot verify multi-volume archives")));
2504 if (use_compress_program_option)
2505 USAGE_ERROR ((0, 0, _("Cannot verify compressed archives")));
2506 }
2507
2508 if (use_compress_program_option)
2509 {
2510 if (multi_volume_option)
2511 USAGE_ERROR ((0, 0, _("Cannot use multi-volume compressed archives")));
2512 if (subcommand_option == UPDATE_SUBCOMMAND
2513 || subcommand_option == APPEND_SUBCOMMAND
2514 || subcommand_option == DELETE_SUBCOMMAND)
2515 USAGE_ERROR ((0, 0, _("Cannot update compressed archives")));
2516 if (subcommand_option == CAT_SUBCOMMAND)
2517 USAGE_ERROR ((0, 0, _("Cannot concatenate compressed archives")));
2518 }
2519
2520 /* It is no harm to use --pax-option on non-pax archives in archive
2521 reading mode. It may even be useful, since it allows to override
2522 file attributes from tar headers. Therefore I allow such usage.
2523 --gray */
2524 if (args.pax_option
2525 && archive_format != POSIX_FORMAT
2526 && (subcommand_option != EXTRACT_SUBCOMMAND
2527 || subcommand_option != DIFF_SUBCOMMAND
2528 || subcommand_option != LIST_SUBCOMMAND))
2529 USAGE_ERROR ((0, 0, _("--pax-option can be used only on POSIX archives")));
2530
2531 /* If ready to unlink hierarchies, so we are for simpler files. */
2532 if (recursive_unlink_option)
2533 old_files_option = UNLINK_FIRST_OLD_FILES;
2534
2535 /* Flags for accessing files to be read from or copied into. POSIX says
2536 O_NONBLOCK has unspecified effect on most types of files, but in
2537 practice it never harms and sometimes helps. */
2538 {
2539 int base_open_flags =
2540 (O_BINARY | O_CLOEXEC | O_NOCTTY | O_NONBLOCK
2541 | (dereference_option ? 0 : O_NOFOLLOW)
2542 | (atime_preserve_option == system_atime_preserve ? O_NOATIME : 0));
2543 open_read_flags = O_RDONLY | base_open_flags;
2544 open_searchdir_flags = O_SEARCH | O_DIRECTORY | base_open_flags;
2545 }
2546 fstatat_flags = dereference_option ? 0 : AT_SYMLINK_NOFOLLOW;
2547
2548 if (subcommand_option == TEST_LABEL_SUBCOMMAND)
2549 {
2550 /* --test-label is silent if the user has specified the label name to
2551 compare against. */
2552 if (!args.input_files)
2553 verbose_option++;
2554 }
2555 else if (utc_option)
2556 verbose_option = 2;
2557
2558 if (tape_length_option && tape_length_option < record_size)
2559 USAGE_ERROR ((0, 0, _("Volume length cannot be less than record size")));
2560
2561 if (same_order_option && listed_incremental_option)
2562 USAGE_ERROR ((0, 0, _("--preserve-order is not compatible with "
2563 "--listed-incremental")));
2564
2565 /* Forbid using -c with no input files whatsoever. Check that '-f -',
2566 explicit or implied, is used correctly. */
2567
2568 switch (subcommand_option)
2569 {
2570 case CREATE_SUBCOMMAND:
2571 if (!args.input_files && !files_from_option)
2572 USAGE_ERROR ((0, 0,
2573 _("Cowardly refusing to create an empty archive")));
2574 if (args.compress_autodetect && archive_names
2575 && strcmp (archive_name_array[0], "-"))
2576 set_compression_program_by_suffix (archive_name_array[0],
2577 use_compress_program_option);
2578 break;
2579
2580 case EXTRACT_SUBCOMMAND:
2581 case LIST_SUBCOMMAND:
2582 case DIFF_SUBCOMMAND:
2583 case TEST_LABEL_SUBCOMMAND:
2584 for (archive_name_cursor = archive_name_array;
2585 archive_name_cursor < archive_name_array + archive_names;
2586 archive_name_cursor++)
2587 if (!strcmp (*archive_name_cursor, "-"))
2588 request_stdin ("-f");
2589 break;
2590
2591 case CAT_SUBCOMMAND:
2592 case UPDATE_SUBCOMMAND:
2593 case APPEND_SUBCOMMAND:
2594 for (archive_name_cursor = archive_name_array;
2595 archive_name_cursor < archive_name_array + archive_names;
2596 archive_name_cursor++)
2597 if (!strcmp (*archive_name_cursor, "-"))
2598 USAGE_ERROR ((0, 0,
2599 _("Options '-Aru' are incompatible with '-f -'")));
2600
2601 default:
2602 break;
2603 }
2604
2605 /* Initialize stdlis */
2606 if (index_file_name)
2607 {
2608 stdlis = fopen (index_file_name, "w");
2609 if (! stdlis)
2610 open_fatal (index_file_name);
2611 }
2612 else
2613 stdlis = to_stdout_option ? stderr : stdout;
2614
2615 archive_name_cursor = archive_name_array;
2616
2617 /* Prepare for generating backup names. */
2618
2619 if (args.backup_suffix_string)
2620 simple_backup_suffix = xstrdup (args.backup_suffix_string);
2621
2622 if (backup_option)
2623 {
2624 backup_type = xget_version ("--backup", args.version_control_string);
2625 /* No backup is needed either if explicitely disabled or if
2626 the extracted files are not being written to disk. */
2627 if (backup_type == no_backups || EXTRACT_OVER_PIPE)
2628 backup_option = false;
2629 }
2630
2631 checkpoint_finish_compile ();
2632
2633 report_textual_dates (&args);
2634 }
2635
2636 \f
2637 /* Tar proper. */
2638
2639 /* Main routine for tar. */
2640 int
2641 main (int argc, char **argv)
2642 {
2643 set_start_time ();
2644 set_program_name (argv[0]);
2645
2646 setlocale (LC_ALL, "");
2647 bindtextdomain (PACKAGE, LOCALEDIR);
2648 textdomain (PACKAGE);
2649
2650 exit_failure = TAREXIT_FAILURE;
2651 exit_status = TAREXIT_SUCCESS;
2652 filename_terminator = '\n';
2653 set_quoting_style (0, DEFAULT_QUOTING_STYLE);
2654
2655 /* Make sure we have first three descriptors available */
2656 stdopen ();
2657
2658 /* Pre-allocate a few structures. */
2659
2660 allocated_archive_names = 10;
2661 archive_name_array =
2662 xmalloc (sizeof (const char *) * allocated_archive_names);
2663 archive_names = 0;
2664
2665 obstack_init (&argv_stk);
2666
2667 /* System V fork+wait does not work if SIGCHLD is ignored. */
2668 signal (SIGCHLD, SIG_DFL);
2669
2670 /* Try to disable the ability to unlink a directory. */
2671 priv_set_remove_linkdir ();
2672
2673 /* Decode options. */
2674
2675 decode_options (argc, argv);
2676
2677 name_init ();
2678
2679 /* Main command execution. */
2680
2681 if (volno_file_option)
2682 init_volume_number ();
2683
2684 switch (subcommand_option)
2685 {
2686 case UNKNOWN_SUBCOMMAND:
2687 USAGE_ERROR ((0, 0,
2688 _("You must specify one of the '-Acdtrux' or '--test-label' options")));
2689
2690 case CAT_SUBCOMMAND:
2691 case UPDATE_SUBCOMMAND:
2692 case APPEND_SUBCOMMAND:
2693 update_archive ();
2694 break;
2695
2696 case DELETE_SUBCOMMAND:
2697 delete_archive_members ();
2698 break;
2699
2700 case CREATE_SUBCOMMAND:
2701 create_archive ();
2702 break;
2703
2704 case EXTRACT_SUBCOMMAND:
2705 extr_init ();
2706 read_and (extract_archive);
2707
2708 /* FIXME: should extract_finish () even if an ordinary signal is
2709 received. */
2710 extract_finish ();
2711
2712 break;
2713
2714 case LIST_SUBCOMMAND:
2715 read_and (list_archive);
2716 break;
2717
2718 case DIFF_SUBCOMMAND:
2719 diff_init ();
2720 read_and (diff_archive);
2721 break;
2722
2723 case TEST_LABEL_SUBCOMMAND:
2724 test_archive_label ();
2725 }
2726
2727 if (totals_option)
2728 print_total_stats ();
2729
2730 if (check_links_option)
2731 check_links ();
2732
2733 if (volno_file_option)
2734 closeout_volume_number ();
2735
2736 /* Dispose of allocated memory, and return. */
2737
2738 free (archive_name_array);
2739 name_term ();
2740
2741 if (exit_status == TAREXIT_FAILURE)
2742 error (0, 0, _("Exiting with failure status due to previous errors"));
2743
2744 if (stdlis == stdout)
2745 close_stdout ();
2746 else if (ferror (stderr) || fclose (stderr) != 0)
2747 set_exit_status (TAREXIT_FAILURE);
2748
2749 return exit_status;
2750 }
2751
2752 void
2753 tar_stat_init (struct tar_stat_info *st)
2754 {
2755 memset (st, 0, sizeof (*st));
2756 }
2757
2758 /* Close the stream or file descriptor associated with ST, and remove
2759 all traces of it from ST. Return true if successful, false (with a
2760 diagnostic) otherwise. */
2761 bool
2762 tar_stat_close (struct tar_stat_info *st)
2763 {
2764 int status = (st->dirstream ? closedir (st->dirstream)
2765 : 0 < st->fd ? close (st->fd)
2766 : 0);
2767 st->dirstream = 0;
2768 st->fd = 0;
2769
2770 if (status == 0)
2771 return true;
2772 else
2773 {
2774 close_diag (st->orig_file_name);
2775 return false;
2776 }
2777 }
2778
2779 void
2780 tar_stat_destroy (struct tar_stat_info *st)
2781 {
2782 tar_stat_close (st);
2783 free (st->orig_file_name);
2784 free (st->file_name);
2785 free (st->link_name);
2786 free (st->uname);
2787 free (st->gname);
2788 free (st->sparse_map);
2789 free (st->dumpdir);
2790 xheader_destroy (&st->xhdr);
2791 memset (st, 0, sizeof (*st));
2792 }
2793
2794 /* Format mask for all available formats that support nanosecond
2795 timestamp resolution. */
2796 #define NS_PRECISION_FORMAT_MASK FORMAT_MASK (POSIX_FORMAT)
2797
2798 /* Same as timespec_cmp, but ignore nanoseconds if current archive
2799 format does not provide sufficient resolution. */
2800 int
2801 tar_timespec_cmp (struct timespec a, struct timespec b)
2802 {
2803 if (!(FORMAT_MASK (current_format) & NS_PRECISION_FORMAT_MASK))
2804 a.tv_nsec = b.tv_nsec = 0;
2805 return timespec_cmp (a, b);
2806 }
2807
2808 /* Set tar exit status to VAL, unless it is already indicating
2809 a more serious condition. This relies on the fact that the
2810 values of TAREXIT_ constants are ranged by severity. */
2811 void
2812 set_exit_status (int val)
2813 {
2814 if (val > exit_status)
2815 exit_status = val;
2816 }
This page took 0.159311 seconds and 5 git commands to generate.