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