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