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