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