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