1 /* A tar (tape archiver) program.
2 Copyright (C) 1988, 92,93,94,95,96,97, 1999 Free Software Foundation, Inc.
3 Written by John Gilmore, starting 1985-08-25.
5 This program is free software; you can redistribute it and/or modify it
6 under the terms of the GNU General Public License as published by the
7 Free Software Foundation; either version 2, or (at your option) any later
10 This program is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
13 Public License for more details.
15 You should have received a copy of the GNU General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
23 /* The following causes "common.h" to produce definitions of all the global
24 variables, rather than just "extern" declarations of them. GNU tar does
25 depend on the system loader to preset all GLOBAL variables to neutral (or
26 zero) values, explicit initialisation is usually not done. */
34 /* Local declarations. */
36 #ifndef DEFAULT_ARCHIVE
37 # define DEFAULT_ARCHIVE "tar.out"
40 #ifndef DEFAULT_BLOCKING
41 # define DEFAULT_BLOCKING 20
44 static void usage
PARAMS ((int));
48 /*----------------------------------------------.
49 | Doesn't return if stdin already requested. |
50 `----------------------------------------------*/
52 /* Name of option using stdin. */
53 static const char *stdin_used_by
= NULL
;
56 request_stdin (const char *option
)
59 USAGE_ERROR ((0, 0, _("Options `-%s' and `-%s' both want standard input"),
60 stdin_used_by
, option
));
62 stdin_used_by
= option
;
65 /*--------------------------------------------------------.
66 | Returns true if and only if the user typed 'y' or 'Y'. |
67 `--------------------------------------------------------*/
70 confirm (const char *message_action
, const char *message_name
)
72 static FILE *confirm_file
= NULL
;
76 if (archive
== 0 || stdin_used_by
)
77 confirm_file
= fopen (TTY_NAME
, "r");
85 FATAL_ERROR ((0, 0, _("Cannot read confirmation from user")));
88 fprintf (stdlis
, "%s %s?", message_action
, message_name
);
92 int reply
= getc (confirm_file
);
95 for (character
= reply
;
96 character
!= '\n' && character
!= EOF
;
97 character
= getc (confirm_file
))
99 return reply
== 'y' || reply
== 'Y';
105 /* For long options that unconditionally set a single flag, we have getopt
106 do it. For the others, we share the code for the equivalent short
107 named option, the name of which is stored in the otherwise-unused `val'
108 field of the `struct option'; for long options that have no equivalent
109 short option, we use non-characters as pseudo short options,
110 starting at CHAR_MAX + 1 and going upwards. */
114 BACKUP_OPTION
= CHAR_MAX
+ 1,
128 USE_COMPRESS_PROGRAM_OPTION
,
131 /* Some cleanup is being made in GNU tar long options. Using old names is
132 allowed for a while, but will also send a warning to stderr. Take old
133 names out in 1.14, or in summer 1997, whichever happens last. */
135 OBSOLETE_ABSOLUTE_NAMES
,
136 OBSOLETE_BLOCK_COMPRESS
,
137 OBSOLETE_BLOCKING_FACTOR
,
138 OBSOLETE_BLOCK_NUMBER
,
139 OBSOLETE_READ_FULL_RECORDS
,
141 OBSOLETE_VERSION_CONTROL
144 /* If nonzero, display usage information and exit. */
145 static int show_help
= 0;
147 /* If nonzero, print the version on standard output and exit. */
148 static int show_version
= 0;
150 struct option long_options
[] =
152 {"absolute-names", no_argument
, NULL
, 'P'},
153 {"absolute-paths", no_argument
, NULL
, OBSOLETE_ABSOLUTE_NAMES
},
154 {"after-date", required_argument
, NULL
, 'N'},
155 {"append", no_argument
, NULL
, 'r'},
156 {"atime-preserve", no_argument
, &atime_preserve_option
, 1},
157 {"backup", optional_argument
, NULL
, BACKUP_OPTION
},
158 {"block-compress", no_argument
, NULL
, OBSOLETE_BLOCK_COMPRESS
},
159 {"block-number", no_argument
, NULL
, 'R'},
160 {"block-size", required_argument
, NULL
, OBSOLETE_BLOCKING_FACTOR
},
161 {"blocking-factor", required_argument
, NULL
, 'b'},
162 {"catenate", no_argument
, NULL
, 'A'},
163 {"checkpoint", no_argument
, &checkpoint_option
, 1},
164 {"compare", no_argument
, NULL
, 'd'},
165 {"compress", no_argument
, NULL
, 'Z'},
166 {"concatenate", no_argument
, NULL
, 'A'},
167 {"confirmation", no_argument
, NULL
, 'w'},
168 /* FIXME: --selective as a synonym for --confirmation? */
169 {"create", no_argument
, NULL
, 'c'},
170 {"delete", no_argument
, NULL
, DELETE_OPTION
},
171 {"dereference", no_argument
, NULL
, 'h'},
172 {"diff", no_argument
, NULL
, 'd'},
173 {"directory", required_argument
, NULL
, 'C'},
174 {"exclude", required_argument
, NULL
, EXCLUDE_OPTION
},
175 {"exclude-from", required_argument
, NULL
, 'X'},
176 {"extract", no_argument
, NULL
, 'x'},
177 {"file", required_argument
, NULL
, 'f'},
178 {"files-from", required_argument
, NULL
, 'T'},
179 {"force-local", no_argument
, &force_local_option
, 1},
180 {"get", no_argument
, NULL
, 'x'},
181 {"group", required_argument
, NULL
, GROUP_OPTION
},
182 {"gunzip", no_argument
, NULL
, 'z'},
183 {"gzip", no_argument
, NULL
, 'z'},
184 {"help", no_argument
, &show_help
, 1},
185 {"ignore-failed-read", no_argument
, &ignore_failed_read_option
, 1},
186 {"ignore-zeros", no_argument
, NULL
, 'i'},
187 /* FIXME: --ignore-end as a new name for --ignore-zeros? */
188 {"incremental", no_argument
, NULL
, 'G'},
189 {"info-script", required_argument
, NULL
, 'F'},
190 {"interactive", no_argument
, NULL
, 'w'},
191 {"keep-old-files", no_argument
, NULL
, 'k'},
192 {"label", required_argument
, NULL
, 'V'},
193 {"list", no_argument
, NULL
, 't'},
194 {"listed-incremental", required_argument
, NULL
, 'g'},
195 {"mode", required_argument
, NULL
, MODE_OPTION
},
196 {"modification-time", no_argument
, NULL
, OBSOLETE_TOUCH
},
197 {"multi-volume", no_argument
, NULL
, 'M'},
198 {"new-volume-script", required_argument
, NULL
, 'F'},
199 {"newer", required_argument
, NULL
, 'N'},
200 {"newer-mtime", required_argument
, NULL
, NEWER_MTIME_OPTION
},
201 {"null", no_argument
, NULL
, NULL_OPTION
},
202 {"no-recursion", no_argument
, NULL
, NO_RECURSE_OPTION
},
203 {"numeric-owner", no_argument
, &numeric_owner_option
, 1},
204 {"old-archive", no_argument
, NULL
, 'o'},
205 {"one-file-system", no_argument
, NULL
, 'l'},
206 {"owner", required_argument
, NULL
, OWNER_OPTION
},
207 {"portability", no_argument
, NULL
, 'o'},
208 {"posix", no_argument
, NULL
, POSIX_OPTION
},
209 {"preserve", no_argument
, NULL
, PRESERVE_OPTION
},
210 {"preserve-order", no_argument
, NULL
, 's'},
211 {"preserve-permissions", no_argument
, NULL
, 'p'},
212 {"recursive-unlink", no_argument
, &recursive_unlink_option
, 1},
213 {"read-full-blocks", no_argument
, NULL
, OBSOLETE_READ_FULL_RECORDS
},
214 {"read-full-records", no_argument
, NULL
, 'B'},
215 /* FIXME: --partial-blocks might be a synonym for --read-full-records? */
216 {"record-number", no_argument
, NULL
, OBSOLETE_BLOCK_NUMBER
},
217 {"record-size", required_argument
, NULL
, RECORD_SIZE_OPTION
},
218 {"remove-files", no_argument
, &remove_files_option
, 1},
219 {"rsh-command", required_argument
, NULL
, RSH_COMMAND_OPTION
},
220 {"same-order", no_argument
, NULL
, 's'},
221 {"same-owner", no_argument
, &same_owner_option
, 1},
222 {"same-permissions", no_argument
, NULL
, 'p'},
223 {"show-omitted-dirs", no_argument
, &show_omitted_dirs_option
, 1},
224 {"sparse", no_argument
, NULL
, 'S'},
225 {"starting-file", required_argument
, NULL
, 'K'},
226 {"suffix", required_argument
, NULL
, SUFFIX_OPTION
},
227 {"tape-length", required_argument
, NULL
, 'L'},
228 {"to-stdout", no_argument
, NULL
, 'O'},
229 {"totals", no_argument
, &totals_option
, 1},
230 {"touch", no_argument
, NULL
, 'm'},
231 {"uncompress", no_argument
, NULL
, 'Z'},
232 {"ungzip", no_argument
, NULL
, 'z'},
233 {"unlink-first", no_argument
, NULL
, 'U'},
234 {"update", no_argument
, NULL
, 'u'},
235 {"use-compress-program", required_argument
, NULL
, USE_COMPRESS_PROGRAM_OPTION
},
236 {"verbose", no_argument
, NULL
, 'v'},
237 {"verify", no_argument
, NULL
, 'W'},
238 {"version", no_argument
, &show_version
, 1},
239 {"version-control", required_argument
, NULL
, OBSOLETE_VERSION_CONTROL
},
240 {"volno-file", required_argument
, NULL
, VOLNO_FILE_OPTION
},
245 /*---------------------------------------------.
246 | Print a usage message and exit with STATUS. |
247 `---------------------------------------------*/
252 if (status
!= TAREXIT_SUCCESS
)
253 fprintf (stderr
, _("Try `%s --help' for more information.\n"),
258 GNU `tar' saves many files together into a single tape or disk archive, and\n\
259 can restore individual files from the archive.\n"),
261 printf (_("\nUsage: %s [OPTION]... [FILE]...\n"), program_name
);
264 If a long option shows an argument as mandatory, then it is mandatory\n\
265 for the equivalent short option also. Similarly for optional arguments.\n"),
269 Main operation mode:\n\
270 -t, --list list the contents of an archive\n\
271 -x, --extract, --get extract files from an archive\n\
272 -c, --create create a new archive\n\
273 -d, --diff, --compare find differences between archive and file system\n\
274 -r, --append append files to the end of an archive\n\
275 -u, --update only append files newer than copy in archive\n\
276 -A, --catenate append tar files to an archive\n\
277 --concatenate same as -A\n\
278 --delete delete from the archive (not on mag tapes!)\n"),
282 Operation modifiers:\n\
283 -W, --verify attempt to verify the archive after writing it\n\
284 --remove-files remove files after adding them to the archive\n\
285 -k, --keep-old-files don't overwrite existing files when extracting\n\
286 -U, --unlink-first remove each file prior to extracting over it\n\
287 --recursive-unlink empty hierarchies prior to extracting directory\n\
288 -S, --sparse handle sparse files efficiently\n\
289 -O, --to-stdout extract files to standard output\n\
290 -G, --incremental handle old GNU-format incremental backup\n\
291 -g, --listed-incremental handle new GNU-format incremental backup\n\
292 --ignore-failed-read do not exit with nonzero on unreadable files\n"),
296 Handling of file attributes:\n\
297 --owner=NAME force NAME as owner for added files\n\
298 --group=NAME force NAME as group for added files\n\
299 --mode=CHANGES force (symbolic) mode CHANGES for added files\n\
300 --atime-preserve don't change access times on dumped files\n\
301 -m, --modification-time don't extract file modified time\n\
302 --same-owner try extracting files with the same ownership\n\
303 --numeric-owner always use numbers for user/group names\n\
304 -p, --same-permissions extract all protection information\n\
305 --preserve-permissions same as -p\n\
306 -s, --same-order sort names to extract to match archive\n\
307 --preserve-order same as -s\n\
308 --preserve same as both -p and -s\n"),
312 Device selection and switching:\n\
313 -f, --file=ARCHIVE use archive file or device ARCHIVE\n\
314 --force-local archive file is local even if has a colon\n\
315 --rsh-command=COMMAND use remote COMMAND instead of rsh\n\
316 -[0-7][lmh] specify drive and density\n\
317 -M, --multi-volume create/list/extract multi-volume archive\n\
318 -L, --tape-length=NUM change tape after writing NUM x 1024 bytes\n\
319 -F, --info-script=FILE run script at end of each tape (implies -M)\n\
320 --new-volume-script=FILE same as -F FILE\n\
321 --volno-file=FILE use/update the volume number in FILE\n"),
326 -b, --blocking-factor=BLOCKS BLOCKS x 512 bytes per record\n\
327 --record-size=SIZE SIZE bytes per record, multiple of 512\n\
328 -i, --ignore-zeros ignore zeroed blocks in archive (means EOF)\n\
329 -B, --read-full-records reblock as we read (for 4.2BSD pipes)\n"),
333 Archive format selection:\n\
334 -V, --label=NAME create archive with volume name NAME\n\
335 PATTERN at list/extract time, a globbing PATTERN\n\
336 -o, --old-archive, --portability write a V7 format archive\n\
337 --posix write a POSIX conformant archive\n\
338 -z, --gzip, --ungzip filter the archive through gzip\n\
339 -Z, --compress, --uncompress filter the archive through compress\n\
340 --use-compress-program=PROG filter through PROG (must accept -d)\n"),
344 Local file selection:\n\
345 -C, --directory=DIR change to directory DIR\n\
346 -T, --files-from=NAME get names to extract or create from file NAME\n\
347 --null -T reads null-terminated names, disable -C\n\
348 --exclude=PATTERN exclude files, given as a globbing PATTERN\n\
349 -X, --exclude-from=FILE exclude globbing patterns listed in FILE\n\
350 -P, --absolute-names don't strip leading `/'s from file names\n\
351 -h, --dereference dump instead the files symlinks point to\n\
352 --no-recursion avoid descending automatically in directories\n\
353 -l, --one-file-system stay in local file system when creating archive\n\
354 -K, --starting-file=NAME begin at file NAME in the archive\n"),
358 -N, --newer=DATE only store files newer than DATE\n\
359 --newer-mtime compare date and time when data changed only\n\
360 --after-date=DATE same as -N\n"),
364 --backup[=CONTROL] backup before removal, choose version control\n\
365 --suffix=SUFFIX backup before removel, override usual suffix\n"),
369 Informative output:\n\
370 --help print this help, then exit\n\
371 --version print tar program version number, then exit\n\
372 -v, --verbose verbosely list files processed\n\
373 --checkpoint print directory names while reading the archive\n\
374 --totals print total bytes written while creating archive\n\
375 -R, --block-number show block number within archive with each message\n\
376 -w, --interactive ask for confirmation for every action\n\
377 --confirmation same as -w\n"),
381 The backup suffix is `~', unless set with --suffix or SIMPLE_BACKUP_SUFFIX.\n\
382 The version control may be set with --backup or VERSION_CONTROL, values are:\n\
384 t, numbered make numbered backups\n\
385 nil, existing numbered if numbered backups exist, simple otherwise\n\
386 never, simple always make simple backups\n"),
390 GNU tar cannot read nor produce `--posix' archives. If POSIXLY_CORRECT\n\
391 is set in the environment, GNU extensions are disallowed with `--posix'.\n\
392 Support for POSIX is only partially implemented, don't count on it yet.\n\
393 ARCHIVE may be FILE, HOST:FILE or USER@HOST:FILE; and FILE may be a file\n\
394 or a device. *This* `tar' defaults to `-f%s -b%d'.\n"),
395 DEFAULT_ARCHIVE
, DEFAULT_BLOCKING
);
398 Report bugs to <tar-bugs@gnu.org>.\n"),
404 /*----------------------------.
405 | Parse the options for tar. |
406 `----------------------------*/
408 /* Available option letters are DEHIJQY and aejnqy. Some are reserved:
410 y per-file gzip compression
411 Y per-block gzip compression */
413 #define OPTION_STRING \
414 "-01234567ABC:F:GK:L:MN:OPRST:UV:WX:Zb:cdf:g:hiklmoprstuvwxz"
417 set_subcommand_option (enum subcommand subcommand
)
419 if (subcommand_option
!= UNKNOWN_SUBCOMMAND
420 && subcommand_option
!= subcommand
)
422 _("You may not specify more than one `-Acdtrux' option")));
424 subcommand_option
= subcommand
;
428 set_use_compress_program_option (const char *string
)
430 if (use_compress_program_option
&& strcmp (use_compress_program_option
, string
) != 0)
431 USAGE_ERROR ((0, 0, _("Conflicting compression options")));
433 use_compress_program_option
= string
;
437 decode_options (int argc
, char *const *argv
)
439 int optchar
; /* option letter */
440 int input_files
; /* number of input files */
441 const char *backup_suffix_string
;
442 const char *version_control_string
= NULL
;
444 /* Set some default option values. */
446 subcommand_option
= UNKNOWN_SUBCOMMAND
;
447 archive_format
= DEFAULT_FORMAT
;
448 blocking_factor
= DEFAULT_BLOCKING
;
449 record_size
= DEFAULT_BLOCKING
* BLOCKSIZE
;
454 backup_suffix_string
= getenv ("SIMPLE_BACKUP_SUFFIX");
456 /* Convert old-style tar call by exploding option element and rearranging
457 options accordingly. */
459 if (argc
> 1 && argv
[1][0] != '-')
461 int new_argc
; /* argc value for rearranged arguments */
462 char **new_argv
; /* argv value for rearranged arguments */
463 char *const *in
; /* cursor into original argv */
464 char **out
; /* cursor into rearranged argv */
465 const char *letter
; /* cursor into old option letters */
466 char buffer
[3]; /* constructed option buffer */
467 const char *cursor
; /* cursor in OPTION_STRING */
469 /* Initialize a constructed option. */
474 /* Allocate a new argument array, and copy program name in it. */
476 new_argc
= argc
- 1 + strlen (argv
[1]);
477 new_argv
= (char **) xmalloc (new_argc
* sizeof (char *));
482 /* Copy each old letter option as a separate option, and have the
483 corresponding argument moved next to it. */
485 for (letter
= *in
++; *letter
; letter
++)
488 *out
++ = xstrdup (buffer
);
489 cursor
= strchr (OPTION_STRING
, *letter
);
490 if (cursor
&& cursor
[1] == ':')
492 if (in
< argv
+ argc
)
495 USAGE_ERROR ((0, 0, _("Old option `%c' requires an argument."),
500 /* Copy all remaining options. */
502 while (in
< argv
+ argc
)
505 /* Replace the old option list by the new one. */
511 /* Parse all options and non-options as they appear. */
515 while (optchar
= getopt_long (argc
, argv
, OPTION_STRING
, long_options
, NULL
),
520 usage (TAREXIT_FAILURE
);
526 /* File name or non-parsed option, because of RETURN_IN_ORDER
527 ordering triggerred by the leading dash in OPTION_STRING. */
534 set_subcommand_option (CAT_SUBCOMMAND
);
537 case OBSOLETE_BLOCK_COMPRESS
:
538 WARN ((0, 0, _("Obsolete option, now implied by --blocking-factor")));
541 case OBSOLETE_BLOCKING_FACTOR
:
542 WARN ((0, 0, _("Obsolete option name replaced by --blocking-factor")));
548 if (! (xstrtol (optarg
, (char **) 0, 10, &l
, "") == LONGINT_OK
549 && l
== (blocking_factor
= l
)
550 && 0 < blocking_factor
551 && l
== (record_size
= l
* (size_t) BLOCKSIZE
) / BLOCKSIZE
))
552 USAGE_ERROR ((0, 0, _("Invalid blocking factor")));
556 case OBSOLETE_READ_FULL_RECORDS
:
558 _("Obsolete option name replaced by --read-full-records")));
562 /* Try to reblock input records. For reading 4.2BSD pipes. */
564 /* It would surely make sense to exchange -B and -R, but it seems
565 that -B has been used for a long while in Sun tar ans most
566 BSD-derived systems. This is a consequence of the block/record
567 terminology confusion. */
569 read_full_records_option
= 1;
573 set_subcommand_option (CREATE_SUBCOMMAND
);
582 set_subcommand_option (DIFF_SUBCOMMAND
);
586 if (archive_names
== allocated_archive_names
)
588 allocated_archive_names
*= 2;
589 archive_name_array
= (const char **)
590 xrealloc (archive_name_array
,
591 sizeof (const char *) * allocated_archive_names
);
593 archive_name_array
[archive_names
++] = optarg
;
597 /* Since -F is only useful with -M, make it implied. Run this
598 script at the end of each tape. */
600 info_script_option
= optarg
;
601 multi_volume_option
= 1;
605 listed_incremental_option
= optarg
;
609 /* We are making an incremental dump (FIXME: are we?); save
610 directories at the beginning of the archive, and include in each
611 directory its contents. */
613 incremental_option
= 1;
617 /* Follow symbolic links. */
619 dereference_option
= 1;
623 /* Ignore zero blocks (eofs). This can't be the default,
624 because Unix tar writes two blocks of zeros, then pads out
625 the record with garbage. */
627 ignore_zeros_option
= 1;
631 /* Don't overwrite existing files. */
633 keep_old_files_option
= 1;
637 starting_file_option
= 1;
642 /* When dumping directories, don't dump files/subdirectories
643 that are on other filesystems. */
645 one_file_system_option
= 1;
651 if (xstrtoul (optarg
, (char **) 0, 10, &u
, "") != LONG_MAX
)
652 USAGE_ERROR ((0, 0, _("Invalid tape length")));
653 clear_tarlong (tape_length_option
);
654 add_to_tarlong (tape_length_option
, u
);
655 mult_tarlong (tape_length_option
, 1024);
656 multi_volume_option
= 1;
661 WARN ((0, 0, _("Obsolete option name replaced by --touch")));
669 /* Make multivolume archive: when we can't write any more into
670 the archive, re-open it, and continue writing. */
672 multi_volume_option
= 1;
677 after_date_option
= 1;
680 case NEWER_MTIME_OPTION
:
681 if (newer_mtime_option
)
682 USAGE_ERROR ((0, 0, _("More than one threshold date")));
684 newer_mtime_option
= get_date (optarg
, (voidstar
) 0);
685 if (newer_mtime_option
== (time_t) -1)
686 USAGE_ERROR ((0, 0, _("Invalid date format `%s'"), optarg
));
689 #endif /* not MSDOS */
692 if (archive_format
== DEFAULT_FORMAT
)
693 archive_format
= V7_FORMAT
;
694 else if (archive_format
!= V7_FORMAT
)
695 USAGE_ERROR ((0, 0, _("Conflicting archive format options")));
699 to_stdout_option
= 1;
703 same_permissions_option
= 1;
706 case OBSOLETE_ABSOLUTE_NAMES
:
707 WARN ((0, 0, _("Obsolete option name replaced by --absolute-names")));
711 absolute_names_option
= 1;
715 set_subcommand_option (APPEND_SUBCOMMAND
);
718 case OBSOLETE_BLOCK_NUMBER
:
719 WARN ((0, 0, _("Obsolete option name replaced by --block-number")));
723 /* Print block numbers for debugging bad tar archives. */
725 /* It would surely make sense to exchange -B and -R, but it seems
726 that -B has been used for a long while in Sun tar ans most
727 BSD-derived systems. This is a consequence of the block/record
728 terminology confusion. */
730 block_number_option
= 1;
734 /* Names to extr are sorted. */
736 same_order_option
= 1;
744 set_subcommand_option (LIST_SUBCOMMAND
);
749 files_from_option
= optarg
;
753 set_subcommand_option (UPDATE_SUBCOMMAND
);
757 unlink_first_option
= 1;
765 volume_label_option
= optarg
;
769 interactive_option
= 1;
777 set_subcommand_option (EXTRACT_SUBCOMMAND
);
782 add_exclude_file (optarg
);
786 set_use_compress_program_option ("gzip");
790 set_use_compress_program_option ("compress");
793 case OBSOLETE_VERSION_CONTROL
:
794 WARN ((0, 0, _("Obsolete option name replaced by --backup")));
800 version_control_string
= optarg
;
804 set_subcommand_option (DELETE_SUBCOMMAND
);
809 add_exclude (optarg
);
813 if (! (strlen (optarg
) < GNAME_FIELD_SIZE
814 && gname_to_gid (optarg
, &group_option
)))
817 if (xstrtoumax (optarg
, (char **) 0, 10, &g
, "") == LONGINT_OK
821 ERROR ((TAREXIT_FAILURE
, 0, _("Invalid group given on option")));
827 = mode_compile (optarg
,
828 MODE_MASK_EQUALS
| MODE_MASK_PLUS
| MODE_MASK_MINUS
);
829 if (mode_option
== MODE_INVALID
)
830 ERROR ((TAREXIT_FAILURE
, 0, _("Invalid mode given on option")));
831 if (mode_option
== MODE_MEMORY_EXHAUSTED
)
832 ERROR ((TAREXIT_FAILURE
, 0, _("Memory exhausted")));
835 case NO_RECURSE_OPTION
:
836 no_recurse_option
= 1;
840 filename_terminator
= '\0';
844 if (! (strlen (optarg
) < UNAME_FIELD_SIZE
845 && uname_to_uid (optarg
, &owner_option
)))
848 if (xstrtoumax (optarg
, (char **) 0, 10, &u
, "") == LONGINT_OK
852 ERROR ((TAREXIT_FAILURE
, 0, _("Invalid owner given on option")));
857 #if OLDGNU_COMPATIBILITY
858 if (archive_format
== DEFAULT_FORMAT
)
859 archive_format
= GNU_FORMAT
;
860 else if (archive_format
!= GNU_FORMAT
)
861 USAGE_ERROR ((0, 0, _("Conflicting archive format options")));
863 if (archive_format
== DEFAULT_FORMAT
)
864 archive_format
= POSIX_FORMAT
;
865 else if (archive_format
!= POSIX_FORMAT
)
866 USAGE_ERROR ((0, 0, _("Conflicting archive format options")));
870 case PRESERVE_OPTION
:
871 same_permissions_option
= 1;
872 same_order_option
= 1;
875 case RECORD_SIZE_OPTION
:
878 if (! (xstrtoumax (optarg
, (char **) 0, 10, &u
, "") == LONG_MAX
880 USAGE_ERROR ((0, 0, _("Invalid record size")));
882 if (record_size
% BLOCKSIZE
!= 0)
883 USAGE_ERROR ((0, 0, _("Record size must be a multiple of %d."),
885 blocking_factor
= record_size
/ BLOCKSIZE
;
889 case RSH_COMMAND_OPTION
:
890 rsh_command_option
= optarg
;
895 backup_suffix_string
= optarg
;
898 case VOLNO_FILE_OPTION
:
899 volno_file_option
= optarg
;
902 case USE_COMPRESS_PROGRAM_OPTION
:
903 set_use_compress_program_option (optarg
);
917 int device
= optchar
- '0';
919 static char buf
[sizeof DEVICE_PREFIX
+ 10];
922 density
= getopt_long (argc
, argv
, "lmh", NULL
, NULL
);
923 strcpy (buf
, DEVICE_PREFIX
);
924 cursor
= buf
+ strlen (buf
);
926 #ifdef DENSITY_LETTER
928 sprintf (cursor
, "%d%c", device
, density
);
930 #else /* not DENSITY_LETTER */
957 usage (TAREXIT_FAILURE
);
959 sprintf (cursor
, "%d", device
);
961 #endif /* not DENSITY_LETTER */
963 if (archive_names
== allocated_archive_names
)
965 allocated_archive_names
*= 2;
966 archive_name_array
= (const char **)
967 xrealloc (archive_name_array
,
968 sizeof (const char *) * allocated_archive_names
);
970 archive_name_array
[archive_names
++] = buf
;
972 /* FIXME: How comes this works for many archives when buf is
977 #else /* not DEVICE_PREFIX */
980 _("Options `-[0-7][lmh]' not supported by *this* tar")));
982 #endif /* not DEVICE_PREFIX */
985 /* Process trivial options. */
989 printf ("tar (GNU %s) %s\n", PACKAGE
, VERSION
);
992 Copyright (C) 1988, 92,93,94,95,96,97,98, 1999 Free Software Foundation, Inc.\n"),
995 This is free software; see the source for copying conditions. There is NO\n\
996 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"),
1000 Written by John Gilmore and Jay Fenlason.\n"),
1002 exit (TAREXIT_SUCCESS
);
1006 usage (TAREXIT_SUCCESS
);
1008 /* Derive option values and check option consistency. */
1010 if (archive_format
== DEFAULT_FORMAT
)
1012 #if OLDGNU_COMPATIBILITY
1013 archive_format
= OLDGNU_FORMAT
;
1015 archive_format
= GNU_FORMAT
;
1019 if (archive_format
== GNU_FORMAT
&& getenv ("POSIXLY_CORRECT"))
1020 archive_format
= POSIX_FORMAT
;
1022 if ((volume_label_option
!= NULL
1023 || incremental_option
|| multi_volume_option
|| sparse_option
)
1024 && archive_format
!= OLDGNU_FORMAT
&& archive_format
!= GNU_FORMAT
)
1026 _("GNU features wanted on incompatible archive format")));
1028 if (archive_names
== 0)
1030 /* If no archive file name given, try TAPE from the environment, or
1031 else, DEFAULT_ARCHIVE from the configuration process. */
1034 archive_name_array
[0] = getenv ("TAPE");
1035 if (archive_name_array
[0] == NULL
)
1036 archive_name_array
[0] = DEFAULT_ARCHIVE
;
1039 /* Allow multiple archives only with `-M'. */
1041 if (archive_names
> 1 && !multi_volume_option
)
1043 _("Multiple archive files requires `-M' option")));
1045 /* If ready to unlink hierarchies, so we are for simpler files. */
1046 if (recursive_unlink_option
)
1047 unlink_first_option
= 1;
1049 /* Forbid using -c with no input files whatsoever. Check that `-f -',
1050 explicit or implied, is used correctly. */
1052 switch (subcommand_option
)
1054 case CREATE_SUBCOMMAND
:
1055 if (input_files
== 0 && !files_from_option
)
1057 _("Cowardly refusing to create an empty archive")));
1060 case EXTRACT_SUBCOMMAND
:
1061 case LIST_SUBCOMMAND
:
1062 case DIFF_SUBCOMMAND
:
1063 for (archive_name_cursor
= archive_name_array
;
1064 archive_name_cursor
< archive_name_array
+ archive_names
;
1065 archive_name_cursor
++)
1066 if (!strcmp (*archive_name_cursor
, "-"))
1067 request_stdin ("-f");
1070 case CAT_SUBCOMMAND
:
1071 case UPDATE_SUBCOMMAND
:
1072 case APPEND_SUBCOMMAND
:
1073 for (archive_name_cursor
= archive_name_array
;
1074 archive_name_cursor
< archive_name_array
+ archive_names
;
1075 archive_name_cursor
++)
1076 if (!strcmp (*archive_name_cursor
, "-"))
1078 _("Options `-Aru' are incompatible with `-f -'")));
1084 archive_name_cursor
= archive_name_array
;
1086 /* Prepare for generating backup names. */
1088 if (backup_suffix_string
)
1089 simple_backup_suffix
= xstrdup (backup_suffix_string
);
1092 backup_type
= xget_version ("--backup", version_control_string
);
1097 /*-----------------------.
1098 | Main routine for tar. |
1099 `-----------------------*/
1102 main (int argc
, char *const *argv
)
1104 program_name
= argv
[0];
1105 setlocale (LC_ALL
, "");
1106 bindtextdomain (PACKAGE
, LOCALEDIR
);
1107 textdomain (PACKAGE
);
1109 exit_status
= TAREXIT_SUCCESS
;
1110 filename_terminator
= '\n';
1112 /* Pre-allocate a few structures. */
1114 allocated_archive_names
= 10;
1115 archive_name_array
= (const char **)
1116 xmalloc (sizeof (const char *) * allocated_archive_names
);
1121 /* Decode options. */
1123 decode_options (argc
, argv
);
1124 name_init (argc
, argv
);
1126 /* Main command execution. */
1128 if (volno_file_option
)
1129 init_volume_number ();
1131 switch (subcommand_option
)
1133 case UNKNOWN_SUBCOMMAND
:
1135 _("You must specify one of the `-Acdtrux' options")));
1137 case CAT_SUBCOMMAND
:
1138 case UPDATE_SUBCOMMAND
:
1139 case APPEND_SUBCOMMAND
:
1143 case DELETE_SUBCOMMAND
:
1144 delete_archive_members ();
1147 case CREATE_SUBCOMMAND
:
1149 init_total_written ();
1155 print_total_written ();
1158 case EXTRACT_SUBCOMMAND
:
1160 read_and (extract_archive
);
1163 case LIST_SUBCOMMAND
:
1164 read_and (list_archive
);
1167 case DIFF_SUBCOMMAND
:
1169 read_and (diff_archive
);
1173 if (volno_file_option
)
1174 closeout_volume_number ();
1176 /* Dispose of allocated memory, and return. */
1178 free (archive_name_array
);
1181 if (exit_status
== TAREXIT_FAILURE
)
1182 error (0, 0, _("Error exit delayed from previous errors"));