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