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