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