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