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