]> Dogcows Code - chaz/tar/blob - src/tar.c
(options): Minor rewording
[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 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 2, 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 <getline.h>
26 #include <argp.h>
27 #include <argp-namefrob.h>
28
29 #include <signal.h>
30 #if ! defined SIGCHLD && defined SIGCLD
31 # define SIGCHLD SIGCLD
32 #endif
33
34 /* The following causes "common.h" to produce definitions of all the global
35 variables, rather than just "extern" declarations of them. GNU tar does
36 depend on the system loader to preset all GLOBAL variables to neutral (or
37 zero) values; explicit initialization is usually not done. */
38 #define GLOBAL
39 #include "common.h"
40
41 #include <argmatch.h>
42 #include <closeout.h>
43 #include <exitfail.h>
44 #include <getdate.h>
45 #include <localedir.h>
46 #include <rmt.h>
47 #include <prepargs.h>
48 #include <quotearg.h>
49 #include <version-etc.h>
50 #include <xstrtol.h>
51 #include <stdopen.h>
52
53 /* Local declarations. */
54
55 #ifndef DEFAULT_ARCHIVE_FORMAT
56 # define DEFAULT_ARCHIVE_FORMAT GNU_FORMAT
57 #endif
58
59 #ifndef DEFAULT_ARCHIVE
60 # define DEFAULT_ARCHIVE "tar.out"
61 #endif
62
63 #ifndef DEFAULT_BLOCKING
64 # define DEFAULT_BLOCKING 20
65 #endif
66
67 \f
68 /* Miscellaneous. */
69
70 /* Name of option using stdin. */
71 static const char *stdin_used_by;
72
73 /* Doesn't return if stdin already requested. */
74 void
75 request_stdin (const char *option)
76 {
77 if (stdin_used_by)
78 USAGE_ERROR ((0, 0, _("Options `-%s' and `-%s' both want standard input"),
79 stdin_used_by, option));
80
81 stdin_used_by = option;
82 }
83
84 extern int rpmatch (char const *response);
85
86 /* Returns true if and only if the user typed an affirmative response. */
87 int
88 confirm (const char *message_action, const char *message_name)
89 {
90 static FILE *confirm_file;
91 static int confirm_file_EOF;
92 bool status = false;
93
94 if (!confirm_file)
95 {
96 if (archive == 0 || stdin_used_by)
97 {
98 confirm_file = fopen (TTY_NAME, "r");
99 if (! confirm_file)
100 open_fatal (TTY_NAME);
101 }
102 else
103 {
104 request_stdin ("-w");
105 confirm_file = stdin;
106 }
107 }
108
109 fprintf (stdlis, "%s %s?", message_action, quote (message_name));
110 fflush (stdlis);
111
112 if (!confirm_file_EOF)
113 {
114 char *response = NULL;
115 size_t response_size = 0;
116 if (getline (&response, &response_size, confirm_file) < 0)
117 confirm_file_EOF = 1;
118 else
119 status = rpmatch (response) > 0;
120 free (response);
121 }
122
123 if (confirm_file_EOF)
124 {
125 fputc ('\n', stdlis);
126 fflush (stdlis);
127 }
128
129 return status;
130 }
131
132 static struct fmttab {
133 char const *name;
134 enum archive_format fmt;
135 } const fmttab[] = {
136 { "v7", V7_FORMAT },
137 { "oldgnu", OLDGNU_FORMAT },
138 { "ustar", USTAR_FORMAT },
139 { "posix", POSIX_FORMAT },
140 #if 0 /* not fully supported yet */
141 { "star", STAR_FORMAT },
142 #endif
143 { "gnu", GNU_FORMAT },
144 { "pax", POSIX_FORMAT }, /* An alias for posix */
145 { NULL, 0 }
146 };
147
148 static void
149 set_archive_format (char const *name)
150 {
151 struct fmttab const *p;
152
153 for (p = fmttab; strcmp (p->name, name) != 0; )
154 if (! (++p)->name)
155 USAGE_ERROR ((0, 0, _("%s: Invalid archive format"),
156 quotearg_colon (name)));
157
158 archive_format = p->fmt;
159 }
160
161 const char *
162 archive_format_string (enum archive_format fmt)
163 {
164 struct fmttab const *p;
165
166 for (p = fmttab; p->name; p++)
167 if (p->fmt == fmt)
168 return p->name;
169 return "unknown?";
170 }
171
172 #define FORMAT_MASK(n) (1<<(n))
173
174 static void
175 assert_format(unsigned fmt_mask)
176 {
177 if ((FORMAT_MASK (archive_format) & fmt_mask) == 0)
178 USAGE_ERROR ((0, 0,
179 _("GNU features wanted on incompatible archive format")));
180 }
181
182 const char *
183 subcommand_string (enum subcommand c)
184 {
185 switch (c)
186 {
187 case UNKNOWN_SUBCOMMAND:
188 return "unknown?";
189
190 case APPEND_SUBCOMMAND:
191 return "-r";
192
193 case CAT_SUBCOMMAND:
194 return "-A";
195
196 case CREATE_SUBCOMMAND:
197 return "-c";
198
199 case DELETE_SUBCOMMAND:
200 return "-D";
201
202 case DIFF_SUBCOMMAND:
203 return "-d";
204
205 case EXTRACT_SUBCOMMAND:
206 return "-x";
207
208 case LIST_SUBCOMMAND:
209 return "-t";
210
211 case UPDATE_SUBCOMMAND:
212 return "-u";
213
214 default:
215 abort ();
216 }
217 }
218
219 void
220 tar_list_quoting_styles (FILE *fp, char *prefix)
221 {
222 int i;
223
224 for (i = 0; quoting_style_args[i]; i++)
225 fprintf (fp, "%s%s\n", prefix, quoting_style_args[i]);
226 }
227
228 void
229 tar_set_quoting_style (char *arg)
230 {
231 int i;
232
233 for (i = 0; quoting_style_args[i]; i++)
234 if (strcmp (arg, quoting_style_args[i]) == 0)
235 {
236 set_quoting_style (NULL, i);
237 return;
238 }
239 FATAL_ERROR ((0, 0,
240 _("Unknown quoting style `%s'. Try `%s --quoting-style=help' to get a list."), arg, program_invocation_short_name));
241 }
242
243 \f
244 /* Options. */
245
246 enum
247 {
248 ANCHORED_OPTION = CHAR_MAX + 1,
249 ATIME_PRESERVE_OPTION,
250 BACKUP_OPTION,
251 CHECKPOINT_OPTION,
252 DELAY_DIRECTORY_RESTORE_OPTION,
253 DELETE_OPTION,
254 EXCLUDE_CACHES_OPTION,
255 EXCLUDE_OPTION,
256 FORCE_LOCAL_OPTION,
257 GROUP_OPTION,
258 HANG_OPTION,
259 IGNORE_CASE_OPTION,
260 IGNORE_COMMAND_ERROR_OPTION,
261 IGNORE_FAILED_READ_OPTION,
262 INDEX_FILE_OPTION,
263 KEEP_NEWER_FILES_OPTION,
264 MODE_OPTION,
265 NEWER_MTIME_OPTION,
266 NO_ANCHORED_OPTION,
267 NO_DELAY_DIRECTORY_RESTORE_OPTION,
268 NO_IGNORE_CASE_OPTION,
269 NO_IGNORE_COMMAND_ERROR_OPTION,
270 NO_OVERWRITE_DIR_OPTION,
271 NO_QUOTE_CHARS_OPTION,
272 NO_RECURSION_OPTION,
273 NO_SAME_OWNER_OPTION,
274 NO_SAME_PERMISSIONS_OPTION,
275 NO_UNQUOTE_OPTION,
276 NO_WILDCARDS_MATCH_SLASH_OPTION,
277 NO_WILDCARDS_OPTION,
278 NULL_OPTION,
279 NUMERIC_OWNER_OPTION,
280 OCCURRENCE_OPTION,
281 OLD_ARCHIVE_OPTION,
282 ONE_FILE_SYSTEM_OPTION,
283 OVERWRITE_OPTION,
284 OWNER_OPTION,
285 PAX_OPTION,
286 POSIX_OPTION,
287 PRESERVE_OPTION,
288 QUOTE_CHARS_OPTION,
289 QUOTING_STYLE_OPTION,
290 RECORD_SIZE_OPTION,
291 RECURSION_OPTION,
292 RECURSIVE_UNLINK_OPTION,
293 REMOVE_FILES_OPTION,
294 RESTRICT_OPTION,
295 RMT_COMMAND_OPTION,
296 RSH_COMMAND_OPTION,
297 SAME_OWNER_OPTION,
298 SHOW_DEFAULTS_OPTION,
299 SHOW_OMITTED_DIRS_OPTION,
300 SHOW_TRANSFORMED_NAMES_OPTION,
301 STRIP_COMPONENTS_OPTION,
302 SUFFIX_OPTION,
303 TEST_LABEL_OPTION,
304 TOTALS_OPTION,
305 TO_COMMAND_OPTION,
306 TRANSFORM_OPTION,
307 UNQUOTE_OPTION,
308 USAGE_OPTION,
309 USE_COMPRESS_PROGRAM_OPTION,
310 UTC_OPTION,
311 VERSION_OPTION,
312 VOLNO_FILE_OPTION,
313 WILDCARDS_MATCH_SLASH_OPTION,
314 WILDCARDS_OPTION
315 };
316
317 const char *argp_program_version = "tar (" PACKAGE_NAME ") " VERSION;
318 const char *argp_program_bug_address = "<" PACKAGE_BUGREPORT ">";
319 static char doc[] = N_("GNU `tar' saves many files together into a single tape or disk archive, and can restore individual files from the archive.\n\
320 \n\
321 Examples:\n\
322 tar -cf archive.tar foo bar # Create archive.tar from files foo and bar.\n\
323 tar -tvf archive.tar # List all files in archive.tar verbosely.\n\
324 tar -xf archive.tar # Extract all files from archive.tar.\n\
325 \vThe backup suffix is `~', unless set with --suffix or SIMPLE_BACKUP_SUFFIX.\n\
326 The version control may be set with --backup or VERSION_CONTROL, values are:\n\n\
327 none, off never make backups\n\
328 t, numbered make numbered backups\n\
329 nil, existing numbered if numbered backups exist, simple otherwise\n\
330 never, simple always make simple backups\n");
331
332
333 /* NOTE:
334
335 Available option letters are DEIJQY and aeqy. Consider the following
336 assignments:
337
338 [For Solaris tar compatibility =/= Is it important at all?]
339 e exit immediately with a nonzero exit status if unexpected errors occur
340 E use extended headers (--format=posix)
341
342 [q alias for --occurrence=1 =/= this would better be used for quiet?]
343 [I same as T =/= will harm star compatibility]
344
345 y per-file gzip compression
346 Y per-block gzip compression */
347
348 static struct argp_option options[] = {
349 #define GRID 10
350 {NULL, 0, NULL, 0,
351 N_("Main operation mode:"), GRID },
352
353 {"list", 't', 0, 0,
354 N_("list the contents of an archive"), GRID+1 },
355 {"extract", 'x', 0, 0,
356 N_("extract files from an archive"), GRID+1 },
357 {"get", 0, 0, OPTION_ALIAS, NULL, GRID+1 },
358 {"create", 'c', 0, 0,
359 N_("create a new archive"), GRID+1 },
360 {"diff", 'd', 0, 0,
361 N_("find differences between archive and file system"), GRID+1 },
362 {"compare", 0, 0, OPTION_ALIAS, NULL, GRID+1 },
363 {"append", 'r', 0, 0,
364 N_("append files to the end of an archive"), GRID+1 },
365 {"update", 'u', 0, 0,
366 N_("only append files newer than copy in archive"), GRID+1 },
367 {"catenate", 'A', 0, 0,
368 N_("append tar files to an archive"), GRID+1 },
369 {"concatenate", 0, 0, OPTION_ALIAS, NULL, GRID+1 },
370 {"delete", DELETE_OPTION, 0, 0,
371 N_("delete from the archive (not on mag tapes!)"), GRID+1 },
372 {"test-label", TEST_LABEL_OPTION, NULL, 0,
373 N_("test the archive volume label and exit"), GRID+1 },
374 #undef GRID
375
376 #define GRID 20
377 {NULL, 0, NULL, 0,
378 N_("Operation modifiers:"), GRID },
379
380 {"sparse", 'S', 0, 0,
381 N_("handle sparse files efficiently"), GRID+1 },
382 {"incremental", 'G', 0, 0,
383 N_("handle old GNU-format incremental backup"), GRID+1 },
384 {"listed-incremental", 'g', N_("FILE"), 0,
385 N_("handle new GNU-format incremental backup"), GRID+1 },
386 {"ignore-failed-read", IGNORE_FAILED_READ_OPTION, 0, 0,
387 N_("do not exit with nonzero on unreadable files"), GRID+1 },
388 {"occurrence", OCCURRENCE_OPTION, N_("NUMBER"), OPTION_ARG_OPTIONAL,
389 N_("process only the NUMBERth occurrence of each file in the archive;"
390 " this option is valid only in conjunction with one of the subcommands"
391 " --delete, --diff, --extract or --list and when a list of files"
392 " is given either on the command line or via the -T option;"
393 " NUMBER defaults to 1"), GRID+1 },
394 {"seek", 'n', NULL, 0,
395 N_("archive is seekable"), GRID+1 },
396 #undef GRID
397
398 #define GRID 30
399 {NULL, 0, NULL, 0,
400 N_("Overwrite control:\n"), GRID+1 },
401
402 {"verify", 'W', 0, 0,
403 N_("attempt to verify the archive after writing it"), GRID+1 },
404 {"remove-files", REMOVE_FILES_OPTION, 0, 0,
405 N_("remove files after adding them to the archive"), GRID+1 },
406 {"keep-old-files", 'k', 0, 0,
407 N_("don't replace existing files when extracting"), GRID+1 },
408 {"keep-newer-files", KEEP_NEWER_FILES_OPTION, 0, 0,
409 N_("don't replace existing files that are newer than their archive copies"), GRID+1 },
410 {"overwrite", OVERWRITE_OPTION, 0, 0,
411 N_("overwrite existing files when extracting"), GRID+1 },
412 {"unlink-first", 'U', 0, 0,
413 N_("remove each file prior to extracting over it"), GRID+1 },
414 {"recursive-unlink", RECURSIVE_UNLINK_OPTION, 0, 0,
415 N_("empty hierarchies prior to extracting directory"), GRID+1 },
416 {"no-overwrite-dir", NO_OVERWRITE_DIR_OPTION, 0, 0,
417 N_("preserve metadata of existing directories"), GRID+1 },
418 #undef GRID
419
420 #define GRID 40
421 {NULL, 0, NULL, 0,
422 N_("Select output stream:"), GRID },
423
424 {"to-stdout", 'O', 0, 0,
425 N_("extract files to standard output"), GRID+1 },
426 {"to-command", TO_COMMAND_OPTION, N_("COMMAND"), 0,
427 N_("pipe extracted files to another program"), GRID+1 },
428 {"ignore-command-error", IGNORE_COMMAND_ERROR_OPTION, 0, 0,
429 N_("ignore exit codes of children"), GRID+1 },
430 {"no-ignore-command-error", NO_IGNORE_COMMAND_ERROR_OPTION, 0, 0,
431 N_("treat non-zero exit codes of children as error"), GRID+1 },
432 #undef GRID
433
434 #define GRID 50
435 {NULL, 0, NULL, 0,
436 N_("Handling of file attributes:"), GRID },
437
438 {"owner", OWNER_OPTION, N_("NAME"), 0,
439 N_("force NAME as owner for added files"), GRID+1 },
440 {"group", GROUP_OPTION, N_("NAME"), 0,
441 N_("force NAME as group for added files"), GRID+1 },
442 {"mode", MODE_OPTION, N_("CHANGES"), 0,
443 N_("force (symbolic) mode CHANGES for added files"), GRID+1 },
444 {"atime-preserve", ATIME_PRESERVE_OPTION,
445 N_("METHOD"), OPTION_ARG_OPTIONAL,
446 N_("preserve access times on dumped files, either by restoring the times"
447 " after reading (METHOD='replace'; default) or by not setting the times"
448 " in the first place (METHOD='system')"), GRID+1 },
449 {"touch", 'm', 0, 0,
450 N_("don't extract file modified time"), GRID+1 },
451 {"same-owner", SAME_OWNER_OPTION, 0, 0,
452 N_("try extracting files with the same ownership"), GRID+1 },
453 {"no-same-owner", NO_SAME_OWNER_OPTION, 0, 0,
454 N_("extract files as yourself"), GRID+1 },
455 {"numeric-owner", NUMERIC_OWNER_OPTION, 0, 0,
456 N_("always use numbers for user/group names"), GRID+1 },
457 {"preserve-permissions", 'p', 0, 0,
458 N_("extract information about file permissions (default for superuser)"),
459 GRID+1 },
460 {"same-permissions", 0, 0, OPTION_ALIAS, NULL, GRID+1 },
461 {"no-same-permissions", NO_SAME_PERMISSIONS_OPTION, 0, 0,
462 N_("apply the user's umask when extracting permissions from the archive (default for ordinary users)"), GRID+1 },
463 {"preserve-order", 's', 0, 0,
464 N_("sort names to extract to match archive"), GRID+1 },
465 {"same-order", 0, 0, OPTION_ALIAS, NULL, GRID+1 },
466 {"preserve", PRESERVE_OPTION, 0, 0,
467 N_("same as both -p and -s"), GRID+1 },
468 {"delay-directory-restore", DELAY_DIRECTORY_RESTORE_OPTION, 0, 0,
469 N_("delay setting modification times and permissions of extracted"
470 " directories until the end of extraction"), GRID+1 },
471 {"no-delay-directory-restore", NO_DELAY_DIRECTORY_RESTORE_OPTION, 0, 0,
472 N_("cancel the effect of --delay-directory-restore option"), GRID+1 },
473 #undef GRID
474
475 #define GRID 60
476 {NULL, 0, NULL, 0,
477 N_("Device selection and switching:\n"), GRID+1 },
478
479 {"file", 'f', N_("ARCHIVE"), 0,
480 N_("use archive file or device ARCHIVE"), GRID+1 },
481 {"force-local", FORCE_LOCAL_OPTION, 0, 0,
482 N_("archive file is local even if it has a colon"), GRID+1 },
483 {"rmt-command", RMT_COMMAND_OPTION, N_("COMMAND"), 0,
484 N_("use given rmt COMMAND instead of rmt"), GRID+1 },
485 {"rsh-command", RSH_COMMAND_OPTION, N_("COMMAND"), 0,
486 N_("use remote COMMAND instead of rsh"), GRID+1 },
487 #ifdef DEVICE_PREFIX
488 {"-[0-7][lmh]", 0, NULL, OPTION_DOC, /* It is OK, since `name' will never be
489 translated */
490 N_("specify drive and density"), GRID+1 },
491 #endif
492 {NULL, '0', NULL, OPTION_HIDDEN, NULL, GRID+1 },
493 {NULL, '1', NULL, OPTION_HIDDEN, NULL, GRID+1 },
494 {NULL, '2', NULL, OPTION_HIDDEN, NULL, GRID+1 },
495 {NULL, '3', NULL, OPTION_HIDDEN, NULL, GRID+1 },
496 {NULL, '4', NULL, OPTION_HIDDEN, NULL, GRID+1 },
497 {NULL, '5', NULL, OPTION_HIDDEN, NULL, GRID+1 },
498 {NULL, '6', NULL, OPTION_HIDDEN, NULL, GRID+1 },
499 {NULL, '7', NULL, OPTION_HIDDEN, NULL, GRID+1 },
500 {NULL, '8', NULL, OPTION_HIDDEN, NULL, GRID+1 },
501 {NULL, '9', NULL, OPTION_HIDDEN, NULL, GRID+1 },
502
503 {"multi-volume", 'M', 0, 0,
504 N_("create/list/extract multi-volume archive"), GRID+1 },
505 {"tape-length", 'L', N_("NUMBER"), 0,
506 N_("change tape after writing NUMBER x 1024 bytes"), GRID+1 },
507 {"info-script", 'F', N_("NAME"), 0,
508 N_("run script at end of each tape (implies -M)"), GRID+1 },
509 {"new-volume-script", 0, 0, OPTION_ALIAS, NULL, GRID+1 },
510 {"volno-file", VOLNO_FILE_OPTION, N_("FILE"), 0,
511 N_("use/update the volume number in FILE"), GRID+1 },
512 #undef GRID
513
514 #define GRID 70
515 {NULL, 0, NULL, 0,
516 N_("Device blocking:"), GRID+1 },
517
518 {"blocking-factor", 'b', N_("BLOCKS"), 0,
519 N_("BLOCKS x 512 bytes per record"), GRID+1 },
520 {"record-size", RECORD_SIZE_OPTION, N_("NUMBER"), 0,
521 N_("NUMBER of bytes per record, multiple of 512"), GRID+1 },
522 {"ignore-zeros", 'i', 0, 0,
523 N_("ignore zeroed blocks in archive (means EOF)"), GRID+1 },
524 {"read-full-records", 'B', 0, 0,
525 N_("reblock as we read (for 4.2BSD pipes)"), GRID+1 },
526 #undef GRID
527
528 #define GRID 80
529 {NULL, 0, NULL, 0,
530 N_("Archive format selection:"), GRID },
531
532 {"format", 'H', N_("FORMAT"), 0,
533 N_("create archive of the given format"), GRID+1 },
534
535 {NULL, 0, NULL, 0, N_("FORMAT is one of the following:"), GRID+2 },
536 {" v7", 0, NULL, OPTION_DOC|OPTION_NO_TRANS, N_("old V7 tar format"),
537 GRID+3 },
538 {" oldgnu", 0, NULL, OPTION_DOC|OPTION_NO_TRANS,
539 N_("GNU format as per tar <= 1.12"), GRID+3 },
540 {" gnu", 0, NULL, OPTION_DOC|OPTION_NO_TRANS,
541 N_("GNU tar 1.13.x format"), GRID+3 },
542 {" ustar", 0, NULL, OPTION_DOC|OPTION_NO_TRANS,
543 N_("POSIX 1003.1-1988 (ustar) format"), GRID+3 },
544 {" pax", 0, NULL, OPTION_DOC|OPTION_NO_TRANS,
545 N_("POSIX 1003.1-2001 (pax) format"), GRID+3 },
546 {" posix", 0, NULL, OPTION_DOC|OPTION_NO_TRANS, N_("same as pax"), GRID+3 },
547
548 {"old-archive", OLD_ARCHIVE_OPTION, 0, 0, /* FIXME */
549 N_("same as --format=v7"), GRID+8 },
550 {"portability", 0, 0, OPTION_ALIAS, NULL, GRID+8 },
551 {"posix", POSIX_OPTION, 0, 0,
552 N_("same as --format=posix"), GRID+8 },
553 {"pax-option", PAX_OPTION, N_("keyword[[:]=value][,keyword[[:]=value]]..."), 0,
554 N_("control pax keywords"), GRID+8 },
555 {"label", 'V', N_("TEXT"), 0,
556 N_("create archive with volume name TEXT; at list/extract time, use TEXT as a globbing pattern for volume name"), GRID+8 },
557 {"bzip2", 'j', 0, 0,
558 N_("filter the archive through bzip2"), GRID+8 },
559 {"gzip", 'z', 0, 0,
560 N_("filter the archive through gzip"), GRID+8 },
561 {"gunzip", 0, 0, OPTION_ALIAS, NULL, GRID+8 },
562 {"ungzip", 0, 0, OPTION_ALIAS, NULL, GRID+8 },
563 {"compress", 'Z', 0, 0,
564 N_("filter the archive through compress"), GRID+8 },
565 {"uncompress", 0, 0, OPTION_ALIAS, NULL, GRID+8 },
566 {"use-compress-program", USE_COMPRESS_PROGRAM_OPTION, N_("PROG"), 0,
567 N_("filter through PROG (must accept -d)"), GRID+8 },
568 #undef GRID
569
570 #define GRID 90
571 {NULL, 0, NULL, 0,
572 N_("Local file selection:"), GRID },
573
574 {"add-file", ARGP_KEY_ARG, N_("FILE"), 0,
575 N_("add given FILE to the archive (useful if its name starts with a dash)"), GRID+1 },
576 {"directory", 'C', N_("DIR"), 0,
577 N_("change to directory DIR"), GRID+1 },
578 {"files-from", 'T', N_("FILE"), 0,
579 N_("get names to extract or create from FILE"), GRID+1 },
580 {"null", NULL_OPTION, 0, 0,
581 N_("-T reads null-terminated names, disable -C"), GRID+1 },
582 {"unquote", UNQUOTE_OPTION, 0, 0,
583 N_("unquote filenames read with -T (default)"), GRID+1 },
584 {"no-unquote", NO_UNQUOTE_OPTION, 0, 0,
585 N_("do not unquote filenames read with -T"), GRID+1 },
586 {"exclude", EXCLUDE_OPTION, N_("PATTERN"), 0,
587 N_("exclude files, given as a PATTERN"), GRID+1 },
588 {"exclude-from", 'X', N_("FILE"), 0,
589 N_("exclude patterns listed in FILE"), GRID+1 },
590 {"exclude-caches", EXCLUDE_CACHES_OPTION, 0, 0,
591 N_("exclude directories containing a cache tag"), GRID+1 },
592 {"no-recursion", NO_RECURSION_OPTION, 0, 0,
593 N_("avoid descending automatically in directories"), GRID+1 },
594 {"one-file-system", ONE_FILE_SYSTEM_OPTION, 0, 0,
595 N_("stay in local file system when creating archive"), GRID+1 },
596 {"recursion", RECURSION_OPTION, 0, 0,
597 N_("recurse into directories (default)"), GRID+1 },
598 {"absolute-names", 'P', 0, 0,
599 N_("don't strip leading `/'s from file names"), GRID+1 },
600 {"dereference", 'h', 0, 0,
601 N_("follow symlinks; archive and dump the files they point to"), GRID+1 },
602 {"starting-file", 'K', N_("MEMBER-NAME"), 0,
603 N_("begin at member MEMBER-NAME in the archive"), GRID+1 },
604 {"newer", 'N', N_("DATE-OR-FILE"), 0,
605 N_("only store files newer than DATE-OR-FILE"), GRID+1 },
606 {"newer-mtime", NEWER_MTIME_OPTION, N_("DATE"), 0,
607 N_("compare date and time when data changed only"), GRID+1 },
608 {"after-date", 'N', N_("DATE"), 0,
609 N_("same as -N"), GRID+1 },
610 {"backup", BACKUP_OPTION, N_("CONTROL"), OPTION_ARG_OPTIONAL,
611 N_("backup before removal, choose version CONTROL"), GRID+1 },
612 {"suffix", SUFFIX_OPTION, N_("STRING"), 0,
613 N_("backup before removal, override usual suffix ('~' unless overridden by environment variable SIMPLE_BACKUP_SUFFIX)"), GRID+1 },
614 #undef GRID
615
616 #define GRID 92
617 {NULL, 0, NULL, 0,
618 N_("File name transformations:"), GRID },
619 {"strip-components", STRIP_COMPONENTS_OPTION, N_("NUMBER"), 0,
620 N_("strip NUMBER leading components from file names on extraction"),
621 GRID+1 },
622 {"transform", TRANSFORM_OPTION, N_("EXPRESSION"), 0,
623 N_("Use sed replace EXPRESSION to transform file names"), GRID+1 },
624 #undef GRID
625
626 #define GRID 95
627 {NULL, 0, NULL, 0,
628 N_("File name matching options (affect both exclude and include patterns):"),
629 GRID },
630 {"ignore-case", IGNORE_CASE_OPTION, 0, 0,
631 N_("ignore case"), GRID+1 },
632 {"anchored", ANCHORED_OPTION, 0, 0,
633 N_("patterns match file name start"), GRID+1 },
634 {"no-anchored", NO_ANCHORED_OPTION, 0, 0,
635 N_("patterns match after any `/' (default for exclusion)"), GRID+1 },
636 {"no-ignore-case", NO_IGNORE_CASE_OPTION, 0, 0,
637 N_("case sensitive matching (default)"), GRID+1 },
638 {"wildcards", WILDCARDS_OPTION, 0, 0,
639 N_("use wildcards (default for exclusion)"), GRID+1 },
640 {"no-wildcards", NO_WILDCARDS_OPTION, 0, 0,
641 N_("verbatim string matching"), GRID+1 },
642 {"no-wildcards-match-slash", NO_WILDCARDS_MATCH_SLASH_OPTION, 0, 0,
643 N_("wildcards do not match `/'"), GRID+1 },
644 {"wildcards-match-slash", WILDCARDS_MATCH_SLASH_OPTION, 0, 0,
645 N_("wildcards match `/' (default for exclusion)"), GRID+1 },
646 #undef GRID
647
648 #define GRID 100
649 {NULL, 0, NULL, 0,
650 N_("Informative output:"), GRID },
651
652 {"verbose", 'v', 0, 0,
653 N_("verbosely list files processed"), GRID+1 },
654 {"checkpoint", CHECKPOINT_OPTION, 0, 0,
655 N_("display progress messages every 10th record"), GRID+1 },
656 {"check-links", 'l', 0, 0,
657 N_("print a message if not all links are dumped"), GRID+1 },
658 {"totals", TOTALS_OPTION, 0, 0,
659 N_("print total bytes written while creating archive"), GRID+1 },
660 {"utc", UTC_OPTION, 0, 0,
661 N_("print file modification dates in UTC"), GRID+1 },
662 {"index-file", INDEX_FILE_OPTION, N_("FILE"), 0,
663 N_("send verbose output to FILE"), GRID+1 },
664 {"block-number", 'R', 0, 0,
665 N_("show block number within archive with each message"), GRID+1 },
666 {"interactive", 'w', 0, 0,
667 N_("ask for confirmation for every action"), GRID+1 },
668 {"confirmation", 0, 0, OPTION_ALIAS, NULL, GRID+1 },
669 {"show-defaults", SHOW_DEFAULTS_OPTION, 0, 0,
670 N_("show tar defaults"), GRID+1 },
671 {"show-omitted-dirs", SHOW_OMITTED_DIRS_OPTION, 0, 0,
672 N_("when listing or extracting, list each directory that does not match search criteria"), GRID+1 },
673 {"show-transformed-names", SHOW_TRANSFORMED_NAMES_OPTION, 0, 0,
674 N_("show file or archive names after transformation"),
675 GRID+1 },
676 {"show-stored-names", 0, 0, OPTION_ALIAS, NULL, GRID+1 },
677 {"quoting-style", QUOTING_STYLE_OPTION, N_("STYLE"), 0,
678 N_("set name quoting style; see below for valid STYLE values"), GRID+1 },
679 {"quote-chars", QUOTE_CHARS_OPTION, N_("STRING"), 0,
680 N_("additionally quote characters from STRING"), GRID+1 },
681 {"no-quote-chars", NO_QUOTE_CHARS_OPTION, N_("STRING"), 0,
682 N_("disable quoting for characters from STRING"), GRID+1 },
683 #undef GRID
684
685 #define GRID 110
686 {NULL, 0, NULL, 0,
687 N_("Compatibility options:"), GRID },
688
689 {NULL, 'o', 0, 0,
690 N_("when creating, same as --old-archive; when extracting, same as --no-same-owner"), GRID+1 },
691 #undef GRID
692
693 #define GRID 120
694 {NULL, 0, NULL, 0,
695 N_("Other options:"), GRID },
696
697 {"restrict", RESTRICT_OPTION, 0, 0,
698 N_("disable use of some potentially harmful options"), -1 },
699
700 {"help", '?', 0, 0, N_("give this help list"), -1},
701 {"usage", USAGE_OPTION, 0, 0, N_("give a short usage message"), -1},
702 {"version", VERSION_OPTION, 0, 0, N_("print program version"), -1},
703 /* FIXME -V (--label) conflicts with the default short option for
704 --version */
705 {"HANG", HANG_OPTION, "SECS", OPTION_ARG_OPTIONAL | OPTION_HIDDEN,
706 N_("hang for SECS seconds (default 3600)"), 0},
707 #undef GRID
708
709 {0, 0, 0, 0, 0, 0}
710 };
711
712 static char const *const atime_preserve_args[] =
713 {
714 "replace", "system", NULL
715 };
716
717 static enum atime_preserve const atime_preserve_types[] =
718 {
719 replace_atime_preserve, system_atime_preserve
720 };
721
722 ARGMATCH_VERIFY (atime_preserve_args, atime_preserve_types);
723
724 /* Wildcard matching settings */
725 enum wildcards
726 {
727 default_wildcards, /* For exclusion == enable_wildcards,
728 for inclusion == disable_wildcards */
729 disable_wildcards,
730 enable_wildcards
731 };
732
733 struct tar_args /* Variables used during option parsing */
734 {
735 char const *textual_date_option; /* Keeps the argument to --newer-mtime
736 option if it represents a textual date */
737 enum wildcards wildcards; /* Wildcard settings (--wildcards/
738 --no-wildcards) */
739 int matching_flags; /* exclude_fnmatch options */
740 int include_anchored; /* Pattern anchoring options used for
741 file inclusion */
742 bool o_option; /* True if -o option was given */
743 bool pax_option; /* True if --pax-option was given */
744 char const *backup_suffix_string; /* --suffix option argument */
745 char const *version_control_string; /* --backup option argument */
746 bool input_files; /* True if some input files where given */
747 };
748
749 #define MAKE_EXCL_OPTIONS(args) \
750 ((((args)->wildcards != disable_wildcards) ? EXCLUDE_WILDCARDS : 0) \
751 | (args)->matching_flags \
752 | recursion_option)
753
754 #define MAKE_INCL_OPTIONS(args) \
755 ((((args)->wildcards == enable_wildcards) ? EXCLUDE_WILDCARDS : 0) \
756 | (args)->include_anchored \
757 | (args)->matching_flags \
758 | recursion_option)
759
760 static void
761 show_default_settings (FILE *stream)
762 {
763 fprintf (stream,
764 "--format=%s -f%s -b%d --quoting-style=%s --rmt-command=%s",
765 archive_format_string (DEFAULT_ARCHIVE_FORMAT),
766 DEFAULT_ARCHIVE, DEFAULT_BLOCKING,
767 quoting_style_args[DEFAULT_QUOTING_STYLE],
768 DEFAULT_RMT_COMMAND);
769 #ifdef REMOTE_SHELL
770 fprintf (stream, " --rsh-command=%s", REMOTE_SHELL);
771 #endif
772 fprintf (stream, "\n");
773 }
774
775 static void
776 set_subcommand_option (enum subcommand subcommand)
777 {
778 if (subcommand_option != UNKNOWN_SUBCOMMAND
779 && subcommand_option != subcommand)
780 USAGE_ERROR ((0, 0,
781 _("You may not specify more than one `-Acdtrux' option")));
782
783 subcommand_option = subcommand;
784 }
785
786 static void
787 set_use_compress_program_option (const char *string)
788 {
789 if (use_compress_program_option
790 && strcmp (use_compress_program_option, string) != 0)
791 USAGE_ERROR ((0, 0, _("Conflicting compression options")));
792
793 use_compress_program_option = string;
794 }
795
796 static volatile int _argp_hang;
797
798 enum read_file_list_state /* Result of reading file name from the list file */
799 {
800 file_list_success, /* OK, name read successfully */
801 file_list_end, /* End of list file */
802 file_list_zero /* Zero separator encountered where it should not */
803 };
804
805 /* Read from FP a sequence of characters up to FILENAME_TERMINATOR and put them
806 into STK.
807 */
808 static enum read_file_list_state
809 read_name_from_file (FILE *fp, struct obstack *stk)
810 {
811 int c;
812 size_t counter = 0;
813
814 for (c = getc (fp); c != EOF && c != filename_terminator; c = getc (fp))
815 {
816 if (c == 0)
817 {
818 /* We have read a zero separator. The file possibly is
819 zero-separated */
820 /* FATAL_ERROR((0, 0, N_("file name contains null character"))); */
821 return file_list_zero;
822 }
823 obstack_1grow (stk, c);
824 counter++;
825 }
826
827 obstack_1grow (stk, 0);
828
829 return (counter == 0 && c == EOF) ? file_list_end : file_list_success;
830 }
831
832 \f
833 static bool files_from_option; /* When set, tar will not refuse to create
834 empty archives */
835 static struct obstack argv_stk; /* Storage for additional command line options
836 read using -T option */
837
838 /* Prevent recursive inclusion of the same file */
839 struct file_id_list
840 {
841 struct file_id_list *next;
842 ino_t ino;
843 dev_t dev;
844 };
845
846 static struct file_id_list *file_id_list;
847
848 static void
849 add_file_id (const char *filename)
850 {
851 struct file_id_list *p;
852 struct stat st;
853
854 if (stat (filename, &st))
855 stat_fatal (filename);
856 for (p = file_id_list; p; p = p->next)
857 if (p->ino == st.st_ino && p->dev == st.st_dev)
858 {
859 FATAL_ERROR ((0, 0, _("%s: file list already read"),
860 quotearg_colon (filename)));
861 }
862 p = xmalloc (sizeof *p);
863 p->next = file_id_list;
864 p->ino = st.st_ino;
865 p->dev = st.st_dev;
866 file_id_list = p;
867 }
868
869 /* Default density numbers for [0-9][lmh] device specifications */
870
871 #ifndef LOW_DENSITY_NUM
872 # define LOW_DENSITY_NUM 0
873 #endif
874
875 #ifndef MID_DENSITY_NUM
876 # define MID_DENSITY_NUM 8
877 #endif
878
879 #ifndef HIGH_DENSITY_NUM
880 # define HIGH_DENSITY_NUM 16
881 #endif
882
883 static void
884 update_argv (const char *filename, struct argp_state *state)
885 {
886 FILE *fp;
887 size_t count = 0, i;
888 char *start, *p;
889 char **new_argv;
890 size_t new_argc;
891 bool is_stdin = false;
892 enum read_file_list_state read_state;
893
894 if (!strcmp (filename, "-"))
895 {
896 is_stdin = true;
897 request_stdin ("-T");
898 fp = stdin;
899 }
900 else
901 {
902 add_file_id (filename);
903 if ((fp = fopen (filename, "r")) == NULL)
904 open_fatal (filename);
905 }
906
907 while ((read_state = read_name_from_file (fp, &argv_stk)) == file_list_success)
908 count++;
909
910 if (read_state == file_list_zero)
911 {
912 size_t size;
913
914 WARN ((0, 0, N_("%s: file name read contains nul character"),
915 quotearg_colon (filename)));
916
917 /* Prepare new stack contents */
918 size = obstack_object_size (&argv_stk);
919 p = obstack_finish (&argv_stk);
920 for (; size > 0; size--, p++)
921 if (*p)
922 obstack_1grow (&argv_stk, *p);
923 else
924 obstack_1grow (&argv_stk, '\n');
925 obstack_1grow (&argv_stk, 0);
926 count = 1;
927
928 /* Read rest of files using new filename terminator */
929 filename_terminator = 0;
930 while (read_name_from_file (fp, &argv_stk) == file_list_success)
931 count++;
932 }
933
934 if (!is_stdin)
935 fclose (fp);
936
937 if (count == 0)
938 return;
939
940 start = obstack_finish (&argv_stk);
941
942 if (filename_terminator == 0)
943 for (p = start; *p; p += strlen (p) + 1)
944 if (p[0] == '-')
945 count++;
946
947 new_argc = state->argc + count;
948 new_argv = xmalloc (sizeof (state->argv[0]) * (new_argc + 1));
949 memcpy (new_argv, state->argv, sizeof (state->argv[0]) * (state->argc + 1));
950 state->argv = new_argv;
951 memmove (&state->argv[state->next + count], &state->argv[state->next],
952 (state->argc - state->next + 1) * sizeof (state->argv[0]));
953
954 state->argc = new_argc;
955
956 for (i = state->next, p = start; *p; p += strlen (p) + 1, i++)
957 {
958 if (filename_terminator == 0 && p[0] == '-')
959 state->argv[i++] = "--add-file";
960 state->argv[i] = p;
961 }
962 }
963
964 \f
965 static error_t
966 parse_opt (int key, char *arg, struct argp_state *state)
967 {
968 struct tar_args *args = state->input;
969
970 switch (key)
971 {
972 case ARGP_KEY_ARG:
973 /* File name or non-parsed option, because of ARGP_IN_ORDER */
974 name_add_name (arg, MAKE_INCL_OPTIONS (args));
975 args->input_files = true;
976 break;
977
978 case 'A':
979 set_subcommand_option (CAT_SUBCOMMAND);
980 break;
981
982 case 'b':
983 {
984 uintmax_t u;
985 if (! (xstrtoumax (arg, 0, 10, &u, "") == LONGINT_OK
986 && u == (blocking_factor = u)
987 && 0 < blocking_factor
988 && u == (record_size = u * BLOCKSIZE) / BLOCKSIZE))
989 USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (arg),
990 _("Invalid blocking factor")));
991 }
992 break;
993
994 case 'B':
995 /* Try to reblock input records. For reading 4.2BSD pipes. */
996
997 /* It would surely make sense to exchange -B and -R, but it seems
998 that -B has been used for a long while in Sun tar and most
999 BSD-derived systems. This is a consequence of the block/record
1000 terminology confusion. */
1001
1002 read_full_records_option = true;
1003 break;
1004
1005 case 'c':
1006 set_subcommand_option (CREATE_SUBCOMMAND);
1007 break;
1008
1009 case 'C':
1010 name_add_dir (arg);
1011 break;
1012
1013 case 'd':
1014 set_subcommand_option (DIFF_SUBCOMMAND);
1015 break;
1016
1017 case 'f':
1018 if (archive_names == allocated_archive_names)
1019 archive_name_array = x2nrealloc (archive_name_array,
1020 &allocated_archive_names,
1021 sizeof (archive_name_array[0]));
1022
1023 archive_name_array[archive_names++] = arg;
1024 break;
1025
1026 case 'F':
1027 /* Since -F is only useful with -M, make it implied. Run this
1028 script at the end of each tape. */
1029
1030 info_script_option = arg;
1031 multi_volume_option = true;
1032 break;
1033
1034 case 'g':
1035 listed_incremental_option = arg;
1036 after_date_option = true;
1037 /* Fall through. */
1038
1039 case 'G':
1040 /* We are making an incremental dump (FIXME: are we?); save
1041 directories at the beginning of the archive, and include in each
1042 directory its contents. */
1043
1044 incremental_option = true;
1045 break;
1046
1047 case 'h':
1048 /* Follow symbolic links. */
1049 dereference_option = true;
1050 break;
1051
1052 case 'i':
1053 /* Ignore zero blocks (eofs). This can't be the default,
1054 because Unix tar writes two blocks of zeros, then pads out
1055 the record with garbage. */
1056
1057 ignore_zeros_option = true;
1058 break;
1059
1060 case 'I':
1061 USAGE_ERROR ((0, 0,
1062 _("Warning: the -I option is not supported;"
1063 " perhaps you meant -j or -T?")));
1064 break;
1065
1066 case 'j':
1067 set_use_compress_program_option ("bzip2");
1068 break;
1069
1070 case 'k':
1071 /* Don't replace existing files. */
1072 old_files_option = KEEP_OLD_FILES;
1073 break;
1074
1075 case 'K':
1076 starting_file_option = true;
1077 addname (arg, 0);
1078 break;
1079
1080 case ONE_FILE_SYSTEM_OPTION:
1081 /* When dumping directories, don't dump files/subdirectories
1082 that are on other filesystems. */
1083 one_file_system_option = true;
1084 break;
1085
1086 case 'l':
1087 check_links_option = 1;
1088 break;
1089
1090 case 'L':
1091 {
1092 uintmax_t u;
1093 if (xstrtoumax (arg, 0, 10, &u, "") != LONGINT_OK)
1094 USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (arg),
1095 _("Invalid tape length")));
1096 tape_length_option = 1024 * (tarlong) u;
1097 multi_volume_option = true;
1098 }
1099 break;
1100
1101 case 'm':
1102 touch_option = true;
1103 break;
1104
1105 case 'M':
1106 /* Make multivolume archive: when we can't write any more into
1107 the archive, re-open it, and continue writing. */
1108
1109 multi_volume_option = true;
1110 break;
1111
1112 case 'n':
1113 seekable_archive = true;
1114 break;
1115
1116 case 'N':
1117 after_date_option = true;
1118 /* Fall through. */
1119
1120 case NEWER_MTIME_OPTION:
1121 if (NEWER_OPTION_INITIALIZED (newer_mtime_option))
1122 USAGE_ERROR ((0, 0, _("More than one threshold date")));
1123
1124 if (FILE_SYSTEM_PREFIX_LEN (arg) != 0
1125 || ISSLASH (*arg)
1126 || *arg == '.')
1127 {
1128 struct stat st;
1129 if (deref_stat (dereference_option, arg, &st) != 0)
1130 {
1131 stat_error (arg);
1132 USAGE_ERROR ((0, 0, _("Date sample file not found")));
1133 }
1134 newer_mtime_option = get_stat_mtime (&st);
1135 }
1136 else
1137 {
1138 if (! get_date (&newer_mtime_option, arg, NULL))
1139 {
1140 WARN ((0, 0, _("Substituting %s for unknown date format %s"),
1141 tartime (newer_mtime_option, false), quote (arg)));
1142 newer_mtime_option.tv_nsec = 0;
1143 }
1144 else
1145 args->textual_date_option = arg;
1146 }
1147
1148 break;
1149
1150 case 'o':
1151 args->o_option = true;
1152 break;
1153
1154 case 'O':
1155 to_stdout_option = true;
1156 break;
1157
1158 case 'p':
1159 same_permissions_option = true;
1160 break;
1161
1162 case 'P':
1163 absolute_names_option = true;
1164 break;
1165
1166 case 'r':
1167 set_subcommand_option (APPEND_SUBCOMMAND);
1168 break;
1169
1170 case 'R':
1171 /* Print block numbers for debugging bad tar archives. */
1172
1173 /* It would surely make sense to exchange -B and -R, but it seems
1174 that -B has been used for a long while in Sun tar ans most
1175 BSD-derived systems. This is a consequence of the block/record
1176 terminology confusion. */
1177
1178 block_number_option = true;
1179 break;
1180
1181 case 's':
1182 /* Names to extr are sorted. */
1183
1184 same_order_option = true;
1185 break;
1186
1187 case 'S':
1188 sparse_option = true;
1189 break;
1190
1191 case 't':
1192 set_subcommand_option (LIST_SUBCOMMAND);
1193 verbose_option++;
1194 break;
1195
1196 case TEST_LABEL_OPTION:
1197 set_subcommand_option (LIST_SUBCOMMAND);
1198 test_label_option = true;
1199 break;
1200
1201 case 'T':
1202 update_argv (arg, state);
1203 /* Indicate we've been given -T option. This is for backward
1204 compatibility only, so that `tar cfT archive /dev/null will
1205 succeed */
1206 files_from_option = true;
1207 break;
1208
1209 case 'u':
1210 set_subcommand_option (UPDATE_SUBCOMMAND);
1211 break;
1212
1213 case 'U':
1214 old_files_option = UNLINK_FIRST_OLD_FILES;
1215 break;
1216
1217 case UTC_OPTION:
1218 utc_option = true;
1219 break;
1220
1221 case 'v':
1222 verbose_option++;
1223 break;
1224
1225 case 'V':
1226 volume_label_option = arg;
1227 break;
1228
1229 case 'w':
1230 interactive_option = true;
1231 break;
1232
1233 case 'W':
1234 verify_option = true;
1235 break;
1236
1237 case 'x':
1238 set_subcommand_option (EXTRACT_SUBCOMMAND);
1239 break;
1240
1241 case 'X':
1242 if (add_exclude_file (add_exclude, excluded, arg,
1243 MAKE_EXCL_OPTIONS (args), '\n')
1244 != 0)
1245 {
1246 int e = errno;
1247 FATAL_ERROR ((0, e, "%s", quotearg_colon (arg)));
1248 }
1249 break;
1250
1251 case 'z':
1252 set_use_compress_program_option ("gzip");
1253 break;
1254
1255 case 'Z':
1256 set_use_compress_program_option ("compress");
1257 break;
1258
1259 case ANCHORED_OPTION:
1260 args->matching_flags |= EXCLUDE_ANCHORED;
1261 break;
1262
1263 case ATIME_PRESERVE_OPTION:
1264 atime_preserve_option =
1265 (arg
1266 ? XARGMATCH ("--atime-preserve", arg,
1267 atime_preserve_args, atime_preserve_types)
1268 : replace_atime_preserve);
1269 if (! O_NOATIME && atime_preserve_option == system_atime_preserve)
1270 FATAL_ERROR ((0, 0,
1271 _("--atime-preserve='system' is not supported"
1272 " on this platform")));
1273 break;
1274
1275 case CHECKPOINT_OPTION:
1276 checkpoint_option = true;
1277 break;
1278
1279 case BACKUP_OPTION:
1280 backup_option = true;
1281 if (arg)
1282 args->version_control_string = arg;
1283 break;
1284
1285 case DELAY_DIRECTORY_RESTORE_OPTION:
1286 delay_directory_restore_option = true;
1287 break;
1288
1289 case NO_DELAY_DIRECTORY_RESTORE_OPTION:
1290 delay_directory_restore_option = false;
1291 break;
1292
1293 case DELETE_OPTION:
1294 set_subcommand_option (DELETE_SUBCOMMAND);
1295 break;
1296
1297 case EXCLUDE_OPTION:
1298 add_exclude (excluded, arg, MAKE_EXCL_OPTIONS (args));
1299 break;
1300
1301 case EXCLUDE_CACHES_OPTION:
1302 exclude_caches_option = true;
1303 break;
1304
1305 case FORCE_LOCAL_OPTION:
1306 force_local_option = true;
1307 break;
1308
1309 case 'H':
1310 set_archive_format (arg);
1311 break;
1312
1313 case INDEX_FILE_OPTION:
1314 index_file_name = arg;
1315 break;
1316
1317 case IGNORE_CASE_OPTION:
1318 args->matching_flags |= FNM_CASEFOLD;
1319 break;
1320
1321 case IGNORE_COMMAND_ERROR_OPTION:
1322 ignore_command_error_option = true;
1323 break;
1324
1325 case IGNORE_FAILED_READ_OPTION:
1326 ignore_failed_read_option = true;
1327 break;
1328
1329 case KEEP_NEWER_FILES_OPTION:
1330 old_files_option = KEEP_NEWER_FILES;
1331 break;
1332
1333 case GROUP_OPTION:
1334 if (! (strlen (arg) < GNAME_FIELD_SIZE
1335 && gname_to_gid (arg, &group_option)))
1336 {
1337 uintmax_t g;
1338 if (xstrtoumax (arg, 0, 10, &g, "") == LONGINT_OK
1339 && g == (gid_t) g)
1340 group_option = g;
1341 else
1342 FATAL_ERROR ((0, 0, "%s: %s", quotearg_colon (arg),
1343 _("%s: Invalid group")));
1344 }
1345 break;
1346
1347 case MODE_OPTION:
1348 mode_option = mode_compile (arg);
1349 if (!mode_option)
1350 FATAL_ERROR ((0, 0, _("Invalid mode given on option")));
1351 initial_umask = umask (0);
1352 umask (initial_umask);
1353 break;
1354
1355 case NO_ANCHORED_OPTION:
1356 args->include_anchored = 0; /* Clear the default for comman line args */
1357 args->matching_flags &= ~ EXCLUDE_ANCHORED;
1358 break;
1359
1360 case NO_IGNORE_CASE_OPTION:
1361 args->matching_flags &= ~ FNM_CASEFOLD;
1362 break;
1363
1364 case NO_IGNORE_COMMAND_ERROR_OPTION:
1365 ignore_command_error_option = false;
1366 break;
1367
1368 case NO_OVERWRITE_DIR_OPTION:
1369 old_files_option = NO_OVERWRITE_DIR_OLD_FILES;
1370 break;
1371
1372 case NO_QUOTE_CHARS_OPTION:
1373 for (;*arg; arg++)
1374 set_char_quoting (NULL, *arg, 0);
1375 break;
1376
1377 case NO_WILDCARDS_OPTION:
1378 args->wildcards = disable_wildcards;
1379 break;
1380
1381 case NO_WILDCARDS_MATCH_SLASH_OPTION:
1382 args->matching_flags |= FNM_FILE_NAME;
1383 break;
1384
1385 case NULL_OPTION:
1386 filename_terminator = '\0';
1387 break;
1388
1389 case NUMERIC_OWNER_OPTION:
1390 numeric_owner_option = true;
1391 break;
1392
1393 case OCCURRENCE_OPTION:
1394 if (!arg)
1395 occurrence_option = 1;
1396 else
1397 {
1398 uintmax_t u;
1399 if (xstrtoumax (arg, 0, 10, &u, "") == LONGINT_OK)
1400 occurrence_option = u;
1401 else
1402 FATAL_ERROR ((0, 0, "%s: %s", quotearg_colon (arg),
1403 _("Invalid number")));
1404 }
1405 break;
1406
1407 case OVERWRITE_OPTION:
1408 old_files_option = OVERWRITE_OLD_FILES;
1409 break;
1410
1411 case OWNER_OPTION:
1412 if (! (strlen (arg) < UNAME_FIELD_SIZE
1413 && uname_to_uid (arg, &owner_option)))
1414 {
1415 uintmax_t u;
1416 if (xstrtoumax (arg, 0, 10, &u, "") == LONGINT_OK
1417 && u == (uid_t) u)
1418 owner_option = u;
1419 else
1420 FATAL_ERROR ((0, 0, "%s: %s", quotearg_colon (arg),
1421 _("Invalid owner")));
1422 }
1423 break;
1424
1425 case QUOTE_CHARS_OPTION:
1426 for (;*arg; arg++)
1427 set_char_quoting (NULL, *arg, 1);
1428 break;
1429
1430 case QUOTING_STYLE_OPTION:
1431 tar_set_quoting_style (arg);
1432 break;
1433
1434 case PAX_OPTION:
1435 args->pax_option = true;
1436 xheader_set_option (arg);
1437 break;
1438
1439 case POSIX_OPTION:
1440 set_archive_format ("posix");
1441 break;
1442
1443 case PRESERVE_OPTION:
1444 /* FIXME: What it is good for? */
1445 same_permissions_option = true;
1446 same_order_option = true;
1447 break;
1448
1449 case RECORD_SIZE_OPTION:
1450 {
1451 uintmax_t u;
1452 if (! (xstrtoumax (arg, 0, 10, &u, "") == LONGINT_OK
1453 && u == (size_t) u))
1454 USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (arg),
1455 _("Invalid record size")));
1456 record_size = u;
1457 if (record_size % BLOCKSIZE != 0)
1458 USAGE_ERROR ((0, 0, _("Record size must be a multiple of %d."),
1459 BLOCKSIZE));
1460 blocking_factor = record_size / BLOCKSIZE;
1461 }
1462 break;
1463
1464 case RECURSIVE_UNLINK_OPTION:
1465 recursive_unlink_option = true;
1466 break;
1467
1468 case REMOVE_FILES_OPTION:
1469 remove_files_option = true;
1470 break;
1471
1472 case RESTRICT_OPTION:
1473 restrict_option = true;
1474 break;
1475
1476 case RMT_COMMAND_OPTION:
1477 rmt_command = arg;
1478 break;
1479
1480 case RSH_COMMAND_OPTION:
1481 rsh_command_option = arg;
1482 break;
1483
1484 case SHOW_DEFAULTS_OPTION:
1485 show_default_settings (stdout);
1486 close_stdout ();
1487 exit (0);
1488
1489 case STRIP_COMPONENTS_OPTION:
1490 {
1491 uintmax_t u;
1492 if (! (xstrtoumax (arg, 0, 10, &u, "") == LONGINT_OK
1493 && u == (size_t) u))
1494 USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (arg),
1495 _("Invalid number of elements")));
1496 strip_name_components = u;
1497 }
1498 break;
1499
1500 case SHOW_OMITTED_DIRS_OPTION:
1501 show_omitted_dirs_option = true;
1502 break;
1503
1504 case SHOW_TRANSFORMED_NAMES_OPTION:
1505 show_transformed_names_option = true;
1506 break;
1507
1508 case SUFFIX_OPTION:
1509 backup_option = true;
1510 args->backup_suffix_string = arg;
1511 break;
1512
1513 case TO_COMMAND_OPTION:
1514 if (to_command_option)
1515 USAGE_ERROR ((0, 0, _("Only one --to-command option allowed")));
1516 to_command_option = arg;
1517 break;
1518
1519 case TOTALS_OPTION:
1520 totals_option = true;
1521 break;
1522
1523 case TRANSFORM_OPTION:
1524 set_transform_expr (arg);
1525 break;
1526
1527 case USE_COMPRESS_PROGRAM_OPTION:
1528 set_use_compress_program_option (arg);
1529 break;
1530
1531 case VOLNO_FILE_OPTION:
1532 volno_file_option = arg;
1533 break;
1534
1535 case WILDCARDS_OPTION:
1536 args->wildcards = enable_wildcards;
1537 break;
1538
1539 case WILDCARDS_MATCH_SLASH_OPTION:
1540 args->matching_flags &= ~ FNM_FILE_NAME;
1541 break;
1542
1543 case NO_RECURSION_OPTION:
1544 recursion_option = 0;
1545 break;
1546
1547 case NO_SAME_OWNER_OPTION:
1548 same_owner_option = -1;
1549 break;
1550
1551 case NO_SAME_PERMISSIONS_OPTION:
1552 same_permissions_option = -1;
1553 break;
1554
1555 case RECURSION_OPTION:
1556 recursion_option = FNM_LEADING_DIR;
1557 break;
1558
1559 case SAME_OWNER_OPTION:
1560 same_owner_option = 1;
1561 break;
1562
1563 case UNQUOTE_OPTION:
1564 unquote_option = true;
1565 break;
1566
1567 case NO_UNQUOTE_OPTION:
1568 unquote_option = false;
1569 break;
1570
1571 case '0':
1572 case '1':
1573 case '2':
1574 case '3':
1575 case '4':
1576 case '5':
1577 case '6':
1578 case '7':
1579
1580 #ifdef DEVICE_PREFIX
1581 {
1582 int device = key - '0';
1583 int density;
1584 static char buf[sizeof DEVICE_PREFIX + 10];
1585 char *cursor;
1586
1587 if (arg[1])
1588 argp_error (state, _("Malformed density argument: %s"), quote (arg));
1589
1590 strcpy (buf, DEVICE_PREFIX);
1591 cursor = buf + strlen (buf);
1592
1593 #ifdef DENSITY_LETTER
1594
1595 sprintf (cursor, "%d%c", device, arg[0]);
1596
1597 #else /* not DENSITY_LETTER */
1598
1599 switch (arg[0])
1600 {
1601 case 'l':
1602 device += LOW_DENSITY_NUM;
1603 break;
1604
1605 case 'm':
1606 device += MID_DENSITY_NUM;
1607 break;
1608
1609 case 'h':
1610 device += HIGH_DENSITY_NUM;
1611 break;
1612
1613 default:
1614 argp_error (state, _("Unknown density: `%c'"), arg[0]);
1615 }
1616 sprintf (cursor, "%d", device);
1617
1618 #endif /* not DENSITY_LETTER */
1619
1620 if (archive_names == allocated_archive_names)
1621 archive_name_array = x2nrealloc (archive_name_array,
1622 &allocated_archive_names,
1623 sizeof (archive_name_array[0]));
1624 archive_name_array[archive_names++] = xstrdup (buf);
1625 }
1626 break;
1627
1628 #else /* not DEVICE_PREFIX */
1629
1630 argp_error (state,
1631 _("Options `-[0-7][lmh]' not supported by *this* tar"));
1632
1633 #endif /* not DEVICE_PREFIX */
1634
1635 case '?':
1636 state->flags |= ARGP_NO_EXIT;
1637 argp_state_help (state, state->out_stream,
1638 ARGP_HELP_STD_HELP & ~ARGP_HELP_BUG_ADDR);
1639 fprintf (state->out_stream, "\n%s\n\n",
1640 _("Valid arguments for --quoting-style options are:"));
1641 tar_list_quoting_styles (state->out_stream, " ");
1642
1643 fprintf (state->out_stream, _("\n*This* tar defaults to:\n"));
1644 show_default_settings (state->out_stream);
1645 fprintf (state->out_stream, "\n");
1646 fprintf (state->out_stream, _("Report bugs to %s.\n"),
1647 argp_program_bug_address);
1648 close_stdout ();
1649 exit (0);
1650
1651 case USAGE_OPTION:
1652 argp_state_help (state, state->out_stream, ARGP_HELP_USAGE);
1653 close_stdout ();
1654 exit (0);
1655
1656 case VERSION_OPTION:
1657 version_etc (state->out_stream, "tar", PACKAGE_NAME, VERSION,
1658 "John Gilmore", "Jay Fenlason", (char *) NULL);
1659 close_stdout ();
1660 exit (0);
1661
1662 case HANG_OPTION:
1663 _argp_hang = atoi (arg ? arg : "3600");
1664 while (_argp_hang-- > 0)
1665 sleep (1);
1666 break;
1667
1668 default:
1669 return ARGP_ERR_UNKNOWN;
1670 }
1671 return 0;
1672 }
1673
1674 static struct argp argp = {
1675 options,
1676 parse_opt,
1677 N_("[FILE]..."),
1678 doc,
1679 NULL,
1680 NULL,
1681 NULL
1682 };
1683
1684 void
1685 usage (int status)
1686 {
1687 argp_help (&argp, stderr, ARGP_HELP_SEE, (char*) program_name);
1688 close_stdout ();
1689 exit (status);
1690 }
1691
1692 /* Parse the options for tar. */
1693
1694 static struct argp_option *
1695 find_argp_option (struct argp_option *options, int letter)
1696 {
1697 for (;
1698 !(options->name == NULL
1699 && options->key == 0
1700 && options->arg == 0
1701 && options->flags == 0
1702 && options->doc == NULL); options++)
1703 if (options->key == letter)
1704 return options;
1705 return NULL;
1706 }
1707
1708 static void
1709 decode_options (int argc, char **argv)
1710 {
1711 int index;
1712 struct tar_args args;
1713
1714 /* Set some default option values. */
1715 args.textual_date_option = NULL;
1716 args.wildcards = default_wildcards;
1717 args.matching_flags = 0;
1718 args.include_anchored = EXCLUDE_ANCHORED;
1719 args.o_option = false;
1720 args.pax_option = false;
1721 args.backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX");
1722 args.version_control_string = 0;
1723 args.input_files = false;
1724
1725 subcommand_option = UNKNOWN_SUBCOMMAND;
1726 archive_format = DEFAULT_FORMAT;
1727 blocking_factor = DEFAULT_BLOCKING;
1728 record_size = DEFAULT_BLOCKING * BLOCKSIZE;
1729 excluded = new_exclude ();
1730 newer_mtime_option.tv_sec = TYPE_MINIMUM (time_t);
1731 newer_mtime_option.tv_nsec = -1;
1732 recursion_option = FNM_LEADING_DIR;
1733 unquote_option = true;
1734
1735 owner_option = -1;
1736 group_option = -1;
1737
1738 /* Convert old-style tar call by exploding option element and rearranging
1739 options accordingly. */
1740
1741 if (argc > 1 && argv[1][0] != '-')
1742 {
1743 int new_argc; /* argc value for rearranged arguments */
1744 char **new_argv; /* argv value for rearranged arguments */
1745 char *const *in; /* cursor into original argv */
1746 char **out; /* cursor into rearranged argv */
1747 const char *letter; /* cursor into old option letters */
1748 char buffer[3]; /* constructed option buffer */
1749
1750 /* Initialize a constructed option. */
1751
1752 buffer[0] = '-';
1753 buffer[2] = '\0';
1754
1755 /* Allocate a new argument array, and copy program name in it. */
1756
1757 new_argc = argc - 1 + strlen (argv[1]);
1758 new_argv = xmalloc ((new_argc + 1) * sizeof (char *));
1759 in = argv;
1760 out = new_argv;
1761 *out++ = *in++;
1762
1763 /* Copy each old letter option as a separate option, and have the
1764 corresponding argument moved next to it. */
1765
1766 for (letter = *in++; *letter; letter++)
1767 {
1768 struct argp_option *opt;
1769
1770 buffer[1] = *letter;
1771 *out++ = xstrdup (buffer);
1772 opt = find_argp_option (options, *letter);
1773 if (opt && opt->arg)
1774 {
1775 if (in < argv + argc)
1776 *out++ = *in++;
1777 else
1778 USAGE_ERROR ((0, 0, _("Old option `%c' requires an argument."),
1779 *letter));
1780 }
1781 }
1782
1783 /* Copy all remaining options. */
1784
1785 while (in < argv + argc)
1786 *out++ = *in++;
1787 *out = 0;
1788
1789 /* Replace the old option list by the new one. */
1790
1791 argc = new_argc;
1792 argv = new_argv;
1793 }
1794
1795 /* Parse all options and non-options as they appear. */
1796
1797 prepend_default_options (getenv ("TAR_OPTIONS"), &argc, &argv);
1798
1799 if (argp_parse (&argp, argc, argv, ARGP_IN_ORDER|ARGP_NO_HELP,
1800 &index, &args))
1801 exit (TAREXIT_FAILURE);
1802
1803
1804 /* Special handling for 'o' option:
1805
1806 GNU tar used to say "output old format".
1807 UNIX98 tar says don't chown files after extracting (we use
1808 "--no-same-owner" for this).
1809
1810 The old GNU tar semantics is retained when used with --create
1811 option, otherwise UNIX98 semantics is assumed */
1812
1813 if (args.o_option)
1814 {
1815 if (subcommand_option == CREATE_SUBCOMMAND)
1816 {
1817 /* GNU Tar <= 1.13 compatibility */
1818 set_archive_format ("v7");
1819 }
1820 else
1821 {
1822 /* UNIX98 compatibility */
1823 same_owner_option = -1;
1824 }
1825 }
1826
1827 /* Handle operands after any "--" argument. */
1828 for (; index < argc; index++)
1829 {
1830 name_add_name (argv[index], MAKE_INCL_OPTIONS (&args));
1831 args.input_files = true;
1832 }
1833
1834 /* Warn about implicit use of the wildcards in command line arguments.
1835 See TODO */
1836 warn_regex_usage = args.wildcards == default_wildcards;
1837
1838 /* Derive option values and check option consistency. */
1839
1840 if (archive_format == DEFAULT_FORMAT)
1841 {
1842 if (args.pax_option)
1843 archive_format = POSIX_FORMAT;
1844 else
1845 archive_format = DEFAULT_ARCHIVE_FORMAT;
1846 }
1847
1848 if ((volume_label_option && subcommand_option == CREATE_SUBCOMMAND)
1849 || incremental_option
1850 || multi_volume_option
1851 || sparse_option)
1852 assert_format (FORMAT_MASK (OLDGNU_FORMAT)
1853 | FORMAT_MASK (GNU_FORMAT)
1854 | FORMAT_MASK (POSIX_FORMAT));
1855
1856 if (multi_volume_option
1857 && archive_format == POSIX_FORMAT
1858 && subcommand_option == CREATE_SUBCOMMAND
1859 && !tape_length_option)
1860 USAGE_ERROR ((0, 0,
1861 _("creating multi-volume archives in posix format requires using --tape-length (-L) option")));
1862
1863 if (occurrence_option)
1864 {
1865 if (!args.input_files)
1866 USAGE_ERROR ((0, 0,
1867 _("--occurrence is meaningless without a file list")));
1868 if (subcommand_option != DELETE_SUBCOMMAND
1869 && subcommand_option != DIFF_SUBCOMMAND
1870 && subcommand_option != EXTRACT_SUBCOMMAND
1871 && subcommand_option != LIST_SUBCOMMAND)
1872 USAGE_ERROR ((0, 0,
1873 _("--occurrence cannot be used in the requested operation mode")));
1874 }
1875
1876 if (seekable_archive && subcommand_option == DELETE_SUBCOMMAND)
1877 {
1878 /* The current code in delete.c is based on the assumption that
1879 skip_member() reads all data from the archive. So, we should
1880 make sure it won't use seeks. On the other hand, the same code
1881 depends on the ability to backspace a record in the archive,
1882 so setting seekable_archive to false is technically incorrect.
1883 However, it is tested only in skip_member(), so it's not a
1884 problem. */
1885 seekable_archive = false;
1886 }
1887
1888 if (archive_names == 0)
1889 {
1890 /* If no archive file name given, try TAPE from the environment, or
1891 else, DEFAULT_ARCHIVE from the configuration process. */
1892
1893 archive_names = 1;
1894 archive_name_array[0] = getenv ("TAPE");
1895 if (! archive_name_array[0])
1896 archive_name_array[0] = DEFAULT_ARCHIVE;
1897 }
1898
1899 /* Allow multiple archives only with `-M'. */
1900
1901 if (archive_names > 1 && !multi_volume_option)
1902 USAGE_ERROR ((0, 0,
1903 _("Multiple archive files require `-M' option")));
1904
1905 if (listed_incremental_option
1906 && NEWER_OPTION_INITIALIZED (newer_mtime_option))
1907 USAGE_ERROR ((0, 0,
1908 _("Cannot combine --listed-incremental with --newer")));
1909
1910 if (volume_label_option)
1911 {
1912 if (archive_format == GNU_FORMAT || archive_format == OLDGNU_FORMAT)
1913 {
1914 size_t volume_label_max_len =
1915 (sizeof current_header->header.name
1916 - 1 /* for trailing '\0' */
1917 - (multi_volume_option
1918 ? (sizeof " Volume "
1919 - 1 /* for null at end of " Volume " */
1920 + INT_STRLEN_BOUND (int) /* for volume number */
1921 - 1 /* for sign, as 0 <= volno */)
1922 : 0));
1923 if (volume_label_max_len < strlen (volume_label_option))
1924 USAGE_ERROR ((0, 0,
1925 ngettext ("%s: Volume label is too long (limit is %lu byte)",
1926 "%s: Volume label is too long (limit is %lu bytes)",
1927 volume_label_max_len),
1928 quotearg_colon (volume_label_option),
1929 (unsigned long) volume_label_max_len));
1930 }
1931 /* else FIXME
1932 Label length in PAX format is limited by the volume size. */
1933 }
1934
1935 if (verify_option)
1936 {
1937 if (multi_volume_option)
1938 USAGE_ERROR ((0, 0, _("Cannot verify multi-volume archives")));
1939 if (use_compress_program_option)
1940 USAGE_ERROR ((0, 0, _("Cannot verify compressed archives")));
1941 }
1942
1943 if (use_compress_program_option)
1944 {
1945 if (multi_volume_option)
1946 USAGE_ERROR ((0, 0, _("Cannot use multi-volume compressed archives")));
1947 if (subcommand_option == UPDATE_SUBCOMMAND
1948 || subcommand_option == APPEND_SUBCOMMAND
1949 || subcommand_option == DELETE_SUBCOMMAND)
1950 USAGE_ERROR ((0, 0, _("Cannot update compressed archives")));
1951 if (subcommand_option == CAT_SUBCOMMAND)
1952 USAGE_ERROR ((0, 0, _("Cannot concatenate compressed archives")));
1953 }
1954
1955 /* It is no harm to use --pax-option on non-pax archives in archive
1956 reading mode. It may even be useful, since it allows to override
1957 file attributes from tar headers. Therefore I allow such usage.
1958 --gray */
1959 if (args.pax_option
1960 && archive_format != POSIX_FORMAT
1961 && (subcommand_option != EXTRACT_SUBCOMMAND
1962 || subcommand_option != DIFF_SUBCOMMAND
1963 || subcommand_option != LIST_SUBCOMMAND))
1964 USAGE_ERROR ((0, 0, _("--pax-option can be used only on POSIX archives")));
1965
1966 /* If ready to unlink hierarchies, so we are for simpler files. */
1967 if (recursive_unlink_option)
1968 old_files_option = UNLINK_FIRST_OLD_FILES;
1969
1970
1971 if (test_label_option)
1972 {
1973 /* --test-label is silent if the user has specified the label name to
1974 compare against. */
1975 if (!args.input_files)
1976 verbose_option++;
1977 }
1978 else if (utc_option)
1979 verbose_option = 2;
1980
1981 /* Forbid using -c with no input files whatsoever. Check that `-f -',
1982 explicit or implied, is used correctly. */
1983
1984 switch (subcommand_option)
1985 {
1986 case CREATE_SUBCOMMAND:
1987 if (!args.input_files && !files_from_option)
1988 USAGE_ERROR ((0, 0,
1989 _("Cowardly refusing to create an empty archive")));
1990 break;
1991
1992 case EXTRACT_SUBCOMMAND:
1993 case LIST_SUBCOMMAND:
1994 case DIFF_SUBCOMMAND:
1995 for (archive_name_cursor = archive_name_array;
1996 archive_name_cursor < archive_name_array + archive_names;
1997 archive_name_cursor++)
1998 if (!strcmp (*archive_name_cursor, "-"))
1999 request_stdin ("-f");
2000 break;
2001
2002 case CAT_SUBCOMMAND:
2003 case UPDATE_SUBCOMMAND:
2004 case APPEND_SUBCOMMAND:
2005 for (archive_name_cursor = archive_name_array;
2006 archive_name_cursor < archive_name_array + archive_names;
2007 archive_name_cursor++)
2008 if (!strcmp (*archive_name_cursor, "-"))
2009 USAGE_ERROR ((0, 0,
2010 _("Options `-Aru' are incompatible with `-f -'")));
2011
2012 default:
2013 break;
2014 }
2015
2016 archive_name_cursor = archive_name_array;
2017
2018 /* Prepare for generating backup names. */
2019
2020 if (args.backup_suffix_string)
2021 simple_backup_suffix = xstrdup (args.backup_suffix_string);
2022
2023 if (backup_option)
2024 {
2025 backup_type = xget_version ("--backup", args.version_control_string);
2026 /* No backup is needed either if explicitely disabled or if
2027 the extracted files are not being written to disk. */
2028 if (backup_type == no_backups || EXTRACT_OVER_PIPE)
2029 backup_option = false;
2030 }
2031
2032 if (verbose_option && args.textual_date_option)
2033 {
2034 char const *treated_as = tartime (newer_mtime_option, true);
2035 if (strcmp (args.textual_date_option, treated_as) != 0)
2036 WARN ((0, 0, _("Treating date `%s' as %s"),
2037 args.textual_date_option, treated_as));
2038 }
2039 }
2040
2041 \f
2042 /* Tar proper. */
2043
2044 /* Main routine for tar. */
2045 int
2046 main (int argc, char **argv)
2047 {
2048 set_start_time ();
2049 program_name = argv[0];
2050
2051 setlocale (LC_ALL, "");
2052 bindtextdomain (PACKAGE, LOCALEDIR);
2053 textdomain (PACKAGE);
2054
2055 exit_failure = TAREXIT_FAILURE;
2056 exit_status = TAREXIT_SUCCESS;
2057 filename_terminator = '\n';
2058 set_quoting_style (0, DEFAULT_QUOTING_STYLE);
2059
2060 /* Make sure we have first three descriptors available */
2061 stdopen ();
2062
2063 /* Pre-allocate a few structures. */
2064
2065 allocated_archive_names = 10;
2066 archive_name_array =
2067 xmalloc (sizeof (const char *) * allocated_archive_names);
2068 archive_names = 0;
2069
2070 obstack_init (&argv_stk);
2071
2072 #ifdef SIGCHLD
2073 /* System V fork+wait does not work if SIGCHLD is ignored. */
2074 signal (SIGCHLD, SIG_DFL);
2075 #endif
2076
2077 /* Decode options. */
2078
2079 decode_options (argc, argv);
2080 name_init ();
2081
2082 /* Main command execution. */
2083
2084 if (volno_file_option)
2085 init_volume_number ();
2086
2087 switch (subcommand_option)
2088 {
2089 case UNKNOWN_SUBCOMMAND:
2090 USAGE_ERROR ((0, 0,
2091 _("You must specify one of the `-Acdtrux' options")));
2092
2093 case CAT_SUBCOMMAND:
2094 case UPDATE_SUBCOMMAND:
2095 case APPEND_SUBCOMMAND:
2096 update_archive ();
2097 break;
2098
2099 case DELETE_SUBCOMMAND:
2100 delete_archive_members ();
2101 break;
2102
2103 case CREATE_SUBCOMMAND:
2104 create_archive ();
2105 if (totals_option)
2106 print_total_written ();
2107 break;
2108
2109 case EXTRACT_SUBCOMMAND:
2110 extr_init ();
2111 read_and (extract_archive);
2112
2113 /* FIXME: should extract_finish () even if an ordinary signal is
2114 received. */
2115 extract_finish ();
2116
2117 break;
2118
2119 case LIST_SUBCOMMAND:
2120 read_and (list_archive);
2121 break;
2122
2123 case DIFF_SUBCOMMAND:
2124 diff_init ();
2125 read_and (diff_archive);
2126 break;
2127 }
2128
2129 if (check_links_option)
2130 check_links ();
2131
2132 if (volno_file_option)
2133 closeout_volume_number ();
2134
2135 /* Dispose of allocated memory, and return. */
2136
2137 free (archive_name_array);
2138 name_term ();
2139
2140 if (stdlis == stdout)
2141 close_stdout ();
2142
2143 if (exit_status == TAREXIT_FAILURE)
2144 error (0, 0, _("Error exit delayed from previous errors"));
2145 if (ferror (stderr) || fclose (stderr) != 0)
2146 exit_status = TAREXIT_FAILURE;
2147 return exit_status;
2148 }
2149
2150 void
2151 tar_stat_init (struct tar_stat_info *st)
2152 {
2153 memset (st, 0, sizeof (*st));
2154 }
2155
2156 void
2157 tar_stat_destroy (struct tar_stat_info *st)
2158 {
2159 free (st->orig_file_name);
2160 free (st->file_name);
2161 free (st->link_name);
2162 free (st->uname);
2163 free (st->gname);
2164 free (st->sparse_map);
2165 free (st->dumpdir);
2166 memset (st, 0, sizeof (*st));
2167 }
2168
2169 /* Format mask for all available formats that support nanosecond
2170 timestamp resolution. */
2171 #define NS_PRECISION_FORMAT_MASK FORMAT_MASK (POSIX_FORMAT)
2172
2173 /* Same as timespec_cmp, but ignore nanoseconds if current archive
2174 format does not provide sufficient resolution. */
2175 int
2176 tar_timespec_cmp (struct timespec a, struct timespec b)
2177 {
2178 if (!(FORMAT_MASK (current_format) & NS_PRECISION_FORMAT_MASK))
2179 a.tv_nsec = b.tv_nsec = 0;
2180 return timespec_cmp (a, b);
2181 }
This page took 0.133135 seconds and 5 git commands to generate.