X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=src%2Ftar.c;h=7d87f80159909f0a34b7c3ff493a0496dee6d5cb;hb=3847d0f51f8605678551a6026c484065e30880a6;hp=998a21ae0cae67acb4efd119fd0eb0ffda1152f4;hpb=825b72c52bb82523627f880b49d4d9105c4d7b2e;p=chaz%2Ftar diff --git a/src/tar.c b/src/tar.c index 998a21a..7d87f80 100644 --- a/src/tar.c +++ b/src/tar.c @@ -1,5 +1,8 @@ /* A tar (tape archiver) program. - Copyright 1988, 92,93,94,95,96,97, 1999 Free Software Foundation, Inc. + + Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1999, 2000, 2001 + Free Software Foundation, Inc. + Written by John Gilmore, starting 1985-08-25. This program is free software; you can redistribute it and/or modify it @@ -18,6 +21,7 @@ #include "system.h" +#include #include #include @@ -25,11 +29,6 @@ # define SIGCHLD SIGCLD #endif -#include -#ifndef time -time_t time (); -#endif - /* The following causes "common.h" to produce definitions of all the global variables, rather than just "extern" declarations of them. GNU tar does depend on the system loader to preset all GLOBAL variables to neutral (or @@ -37,7 +36,11 @@ time_t time (); #define GLOBAL #include "common.h" -#include "xstrtol.h" +#include +#include +#include +#include +#include time_t get_date (); @@ -51,17 +54,14 @@ time_t get_date (); # define DEFAULT_BLOCKING 20 #endif -static void usage PARAMS ((int)); +static void usage PARAMS ((int)) __attribute__ ((noreturn)); /* Miscellaneous. */ -/*----------------------------------------------. -| Doesn't return if stdin already requested. | -`----------------------------------------------*/ - /* Name of option using stdin. */ static const char *stdin_used_by; +/* Doesn't return if stdin already requested. */ void request_stdin (const char *option) { @@ -72,10 +72,7 @@ request_stdin (const char *option) stdin_used_by = option; } -/*--------------------------------------------------------. -| Returns true if and only if the user typed 'y' or 'Y'. | -`--------------------------------------------------------*/ - +/* Returns true if and only if the user typed 'y' or 'Y'. */ int confirm (const char *message_action, const char *message_name) { @@ -85,18 +82,19 @@ confirm (const char *message_action, const char *message_name) if (!confirm_file) { if (archive == 0 || stdin_used_by) - confirm_file = fopen (TTY_NAME, "r"); + { + confirm_file = fopen (TTY_NAME, "r"); + if (! confirm_file) + open_fatal (TTY_NAME); + } else { request_stdin ("-w"); confirm_file = stdin; } - - if (!confirm_file) - FATAL_ERROR ((0, 0, _("Cannot read confirmation from user"))); } - fprintf (stdlis, "%s %s?", message_action, message_name); + fprintf (stdlis, "%s %s?", message_action, quote (message_name)); fflush (stdlis); { @@ -128,14 +126,21 @@ confirm (const char *message_action, const char *message_name) enum { - BACKUP_OPTION = CHAR_MAX + 1, + ANCHORED_OPTION = CHAR_MAX + 1, + BACKUP_OPTION, DELETE_OPTION, EXCLUDE_OPTION, GROUP_OPTION, + IGNORE_CASE_OPTION, MODE_OPTION, NEWER_MTIME_OPTION, - NO_RECURSE_OPTION, + NO_ANCHORED_OPTION, + NO_IGNORE_CASE_OPTION, + NO_WILDCARDS_OPTION, + NO_WILDCARDS_MATCH_SLASH_OPTION, NULL_OPTION, + OVERWRITE_OPTION, + OVERWRITE_DIR_OPTION, OWNER_OPTION, POSIX_OPTION, PRESERVE_OPTION, @@ -144,6 +149,8 @@ enum SUFFIX_OPTION, USE_COMPRESS_PROGRAM_OPTION, VOLNO_FILE_OPTION, + WILDCARDS_OPTION, + WILDCARDS_MATCH_SLASH_OPTION, /* Some cleanup is being made in GNU tar long options. Using old names is allowed for a while, but will also send a warning to stderr. Take old @@ -164,11 +171,12 @@ static int show_help; /* If nonzero, print the version on standard output and exit. */ static int show_version; -struct option long_options[] = +static struct option long_options[] = { {"absolute-names", no_argument, 0, 'P'}, {"absolute-paths", no_argument, 0, OBSOLETE_ABSOLUTE_NAMES}, {"after-date", required_argument, 0, 'N'}, + {"anchored", no_argument, 0, ANCHORED_OPTION}, {"append", no_argument, 0, 'r'}, {"atime-preserve", no_argument, &atime_preserve_option, 1}, {"backup", optional_argument, 0, BACKUP_OPTION}, @@ -176,7 +184,7 @@ struct option long_options[] = {"block-number", no_argument, 0, 'R'}, {"block-size", required_argument, 0, OBSOLETE_BLOCKING_FACTOR}, {"blocking-factor", required_argument, 0, 'b'}, - {"bzip2", no_argument, 0, 'I'}, + {"bzip2", no_argument, 0, 'j'}, {"catenate", no_argument, 0, 'A'}, {"checkpoint", no_argument, &checkpoint_option, 1}, {"compare", no_argument, 0, 'd'}, @@ -200,6 +208,7 @@ struct option long_options[] = {"gunzip", no_argument, 0, 'z'}, {"gzip", no_argument, 0, 'z'}, {"help", no_argument, &show_help, 1}, + {"ignore-case", no_argument, 0, IGNORE_CASE_OPTION}, {"ignore-failed-read", no_argument, &ignore_failed_read_option, 1}, {"ignore-zeros", no_argument, 0, 'i'}, /* FIXME: --ignore-end as a new name for --ignore-zeros? */ @@ -217,18 +226,25 @@ struct option long_options[] = {"newer", required_argument, 0, 'N'}, {"newer-mtime", required_argument, 0, NEWER_MTIME_OPTION}, {"null", no_argument, 0, NULL_OPTION}, - {"no-recursion", no_argument, 0, NO_RECURSE_OPTION}, + {"no-anchored", no_argument, 0, NO_ANCHORED_OPTION}, + {"no-ignore-case", no_argument, 0, NO_IGNORE_CASE_OPTION}, + {"no-wildcards", no_argument, 0, NO_WILDCARDS_OPTION}, + {"no-wildcards-match-slash", no_argument, 0, NO_WILDCARDS_MATCH_SLASH_OPTION}, + {"no-recursion", no_argument, &recursion_option, 0}, {"no-same-owner", no_argument, &same_owner_option, -1}, {"no-same-permissions", no_argument, &same_permissions_option, -1}, {"numeric-owner", no_argument, &numeric_owner_option, 1}, {"old-archive", no_argument, 0, 'o'}, {"one-file-system", no_argument, 0, 'l'}, + {"overwrite", no_argument, 0, OVERWRITE_OPTION}, + {"overwrite-dir", no_argument, 0, OVERWRITE_DIR_OPTION}, {"owner", required_argument, 0, OWNER_OPTION}, {"portability", no_argument, 0, 'o'}, {"posix", no_argument, 0, POSIX_OPTION}, {"preserve", no_argument, 0, PRESERVE_OPTION}, {"preserve-order", no_argument, 0, 's'}, {"preserve-permissions", no_argument, 0, 'p'}, + {"recursion", no_argument, &recursion_option, FNM_LEADING_DIR}, {"recursive-unlink", no_argument, &recursive_unlink_option, 1}, {"read-full-blocks", no_argument, 0, OBSOLETE_READ_FULL_RECORDS}, {"read-full-records", no_argument, 0, 'B'}, @@ -258,14 +274,13 @@ struct option long_options[] = {"version", no_argument, &show_version, 1}, {"version-control", required_argument, 0, OBSOLETE_VERSION_CONTROL}, {"volno-file", required_argument, 0, VOLNO_FILE_OPTION}, + {"wildcards", no_argument, 0, WILDCARDS_OPTION}, + {"wildcards-match-slash", no_argument, 0, WILDCARDS_MATCH_SLASH_OPTION}, {0, 0, 0, 0} }; -/*---------------------------------------------. -| Print a usage message and exit with STATUS. | -`---------------------------------------------*/ - +/* Print a usage message and exit with STATUS. */ static void usage (int status) { @@ -278,7 +293,13 @@ usage (int status) GNU `tar' saves many files together into a single tape or disk archive, and\n\ can restore individual files from the archive.\n"), stdout); - printf (_("\nUsage: %s [OPTION]... [FILE]...\n"), program_name); + printf (_("\nUsage: %s [OPTION]... [FILE]...\n\ +\n\ +Examples:\n\ + %s -cf archive.tar foo bar # Create archive.tar from files foo and bar.\n\ + %s -tvf archive.tar # List all files in archive.tar verbosely.\n\ + %s -xf archive.tar # Extract all files from archive.tar.\n"), + program_name, program_name, program_name, program_name); fputs (_("\ \n\ If a long option shows an argument as mandatory, then it is mandatory\n\ @@ -302,7 +323,9 @@ Main operation mode:\n\ Operation modifiers:\n\ -W, --verify attempt to verify the archive after writing it\n\ --remove-files remove files after adding them to the archive\n\ - -k, --keep-old-files don't overwrite existing files when extracting\n\ + -k, --keep-old-files don't replace existing files when extracting\n\ + --overwrite overwrite existing files when extracting\n\ + --overwrite-dir overwrite directory metadata when extracting\n\ -U, --unlink-first remove each file prior to extracting over it\n\ --recursive-unlink empty hierarchies prior to extracting directory\n\ -S, --sparse handle sparse files efficiently\n\ @@ -358,7 +381,7 @@ Archive format selection:\n\ PATTERN at list/extract time, a globbing PATTERN\n\ -o, --old-archive, --portability write a V7 format archive\n\ --posix write a POSIX format archive\n\ - -I, --bzip2 filter the archive through bzip2\n\ + -j, --bzip2 filter the archive through bzip2\n\ -z, --gzip, --ungzip filter the archive through gzip\n\ -Z, --compress, --uncompress filter the archive through compress\n\ --use-compress-program=PROG filter through PROG (must accept -d)\n"), @@ -369,8 +392,16 @@ Local file selection:\n\ -C, --directory=DIR change to directory DIR\n\ -T, --files-from=NAME get names to extract or create from file NAME\n\ --null -T reads null-terminated names, disable -C\n\ - --exclude=PATTERN exclude files, given as a globbing PATTERN\n\ - -X, --exclude-from=FILE exclude globbing patterns listed in FILE\n\ + --exclude=PATTERN exclude files, given as a PATTERN\n\ + -X, --exclude-from=FILE exclude patterns listed in FILE\n\ + --anchored exclude patterns match file name start (default)\n\ + --no-anchored exclude patterns match after any /\n\ + --ignore-case exclusion ignores case\n\ + --no-ignore-case exclusion is case sensitive (default)\n\ + --wildcards exclude patterns use wildcards (default)\n\ + --no-wildcards exclude patterns are plain strings\n\ + --wildcards-match-slash exclude pattern wildcards match '/' (default)\n\ + --no-wildcards-match-slash exclude pattern wildcards do not match '/'\n\ -P, --absolute-names don't strip leading `/'s from file names\n\ -h, --dereference dump instead the files symlinks point to\n\ --no-recursion avoid descending automatically in directories\n\ @@ -380,7 +411,7 @@ Local file selection:\n\ #if !MSDOS fputs (_("\ -N, --newer=DATE only store files newer than DATE\n\ - --newer-mtime compare date and time when data changed only\n\ + --newer-mtime=DATE compare date and time when data changed only\n\ --after-date=DATE same as -N\n"), stdout); #endif @@ -414,28 +445,29 @@ The version control may be set with --backup or VERSION_CONTROL, values are:\n\ GNU tar cannot read nor produce `--posix' archives. If POSIXLY_CORRECT\n\ is set in the environment, GNU extensions are disallowed with `--posix'.\n\ Support for POSIX is only partially implemented, don't count on it yet.\n\ -ARCHIVE may be FILE, HOST:FILE or USER@HOST:FILE; and FILE may be a file\n\ -or a device. *This* `tar' defaults to `-f%s -b%d'.\n"), +ARCHIVE may be FILE, HOST:FILE or USER@HOST:FILE; DATE may be a textual date\n\ +or a file name starting with `/' or `.', in which case the file's date is used.\n\ +*This* `tar' defaults to `-f%s -b%d'.\n"), DEFAULT_ARCHIVE, DEFAULT_BLOCKING); - fputs (_("\ -\n\ -Report bugs to .\n"), - stdout); + fputs (_("\nReport bugs to .\n"), stdout); } exit (status); } -/*----------------------------. -| Parse the options for tar. | -`----------------------------*/ +/* Parse the options for tar. */ -/* Available option letters are DEHJQY and aejnqy. Some are reserved: +/* Available option letters are DEHIJQY and aenqy. Some are reserved: + e exit immediately with a nonzero exit status if unexpected errors occur + E use extended headers (draft POSIX headers, that is) + I same as T (for compatibility with Solaris tar) + n the archive is quickly seekable, so don't worry about random seeks + q stop after extracting the first occurrence of the named file y per-file gzip compression Y per-block gzip compression */ #define OPTION_STRING \ - "-01234567ABC:F:GIK:L:MN:OPRST:UV:WX:Zb:cdf:g:hiklmoprstuvwxz" + "-01234567ABC:F:GIK:L:MN:OPRST:UV:WX:Zb:cdf:g:hijklmoprstuvwxyz" static void set_subcommand_option (enum subcommand subcommand) @@ -457,25 +489,14 @@ set_use_compress_program_option (const char *string) use_compress_program_option = string; } -/* Ignore DUMMY (which will always be null in practice), and add - PATTERN to the proper set of patterns to be excluded -- either - patterns with slashes, or patterns without. */ -static void -add_filtered_exclude (struct exclude *dummy, char const *pattern) -{ - add_exclude ((strchr (pattern, '/') - ? excluded_with_slash - : excluded_without_slash), - pattern); -} - static void -decode_options (int argc, char *const *argv) +decode_options (int argc, char **argv) { int optchar; /* option letter */ int input_files; /* number of input files */ const char *backup_suffix_string; const char *version_control_string = 0; + int exclude_options = EXCLUDE_WILDCARDS; /* Set some default option values. */ @@ -483,9 +504,9 @@ decode_options (int argc, char *const *argv) archive_format = DEFAULT_FORMAT; blocking_factor = DEFAULT_BLOCKING; record_size = DEFAULT_BLOCKING * BLOCKSIZE; - excluded_with_slash = new_exclude (); - excluded_without_slash = new_exclude (); + excluded = new_exclude (); newer_mtime_option = TYPE_MINIMUM (time_t); + recursion_option = FNM_LEADING_DIR; owner_option = -1; group_option = -1; @@ -551,6 +572,8 @@ decode_options (int argc, char *const *argv) input_files = 0; + prepend_default_options (getenv ("TAR_OPTIONS"), &argc, &argv); + while (optchar = getopt_long (argc, argv, OPTION_STRING, long_options, 0), optchar != -1) switch (optchar) @@ -588,7 +611,8 @@ decode_options (int argc, char *const *argv) && u == (blocking_factor = u) && 0 < blocking_factor && u == (record_size = u * BLOCKSIZE) / BLOCKSIZE)) - USAGE_ERROR ((0, 0, _("Invalid blocking factor"))); + USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (optarg), + _("Invalid blocking factor"))); } break; @@ -668,13 +692,18 @@ decode_options (int argc, char *const *argv) break; case 'I': + USAGE_ERROR ((0, 0, + _("Warning: the -I option is not supported;" + " perhaps you meant -j or -T?"))); + break; + + case 'j': set_use_compress_program_option ("bzip2"); break; case 'k': - /* Don't overwrite existing files. */ - - keep_old_files_option = 1; + /* Don't replace existing files. */ + old_files_option = KEEP_OLD_FILES; break; case 'K': @@ -693,7 +722,8 @@ decode_options (int argc, char *const *argv) { uintmax_t u; if (xstrtoumax (optarg, 0, 10, &u, "") != LONGINT_OK) - USAGE_ERROR ((0, 0, _("Invalid tape length"))); + USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (optarg), + _("Invalid tape length"))); tape_length_option = 1024 * (tarlong) u; multi_volume_option = 1; } @@ -720,12 +750,28 @@ decode_options (int argc, char *const *argv) /* Fall through. */ case NEWER_MTIME_OPTION: - if (newer_mtime_option != TYPE_MINIMUM (time_t)) + if (newer_mtime_option != TYPE_MINIMUM (time_t)) USAGE_ERROR ((0, 0, _("More than one threshold date"))); - newer_mtime_option = get_date (optarg, 0); - if (newer_mtime_option == (time_t) -1) - USAGE_ERROR ((0, 0, _("Invalid date format `%s'"), optarg)); + if (FILESYSTEM_PREFIX_LEN (optarg) != 0 + || ISSLASH (*optarg) + || *optarg == '.') + { + struct stat st; + if (deref_stat (dereference_option, optarg, &st) != 0) + { + stat_error (optarg); + USAGE_ERROR ((0, 0, _("Date file not found"))); + } + newer_mtime_option = st.st_mtime; + } + else + { + newer_mtime_option = get_date (optarg, 0); + if (newer_mtime_option == (time_t) -1) + WARN ((0, 0, _("Substituting %s for unknown date format %s"), + tartime (newer_mtime_option), quote (optarg))); + } break; #endif /* not MSDOS */ @@ -796,7 +842,7 @@ decode_options (int argc, char *const *argv) break; case 'U': - unlink_first_option = 1; + old_files_option = UNLINK_FIRST_OLD_FILES; break; case 'v': @@ -820,8 +866,19 @@ decode_options (int argc, char *const *argv) break; case 'X': - if (add_exclude_file (add_filtered_exclude, 0, optarg, '\n') != 0) - FATAL_ERROR ((0, errno, "%s", optarg)); + if (add_exclude_file (add_exclude, excluded, optarg, + exclude_options | recursion_option, '\n') + != 0) + { + int e = errno; + FATAL_ERROR ((0, e, "%s", quotearg_colon (optarg))); + } + break; + + case 'y': + USAGE_ERROR ((0, 0, + _("Warning: the -y option is not supported;" + " perhaps you meant -j?"))); break; case 'z': @@ -836,6 +893,10 @@ decode_options (int argc, char *const *argv) WARN ((0, 0, _("Obsolete option name replaced by --backup"))); /* Fall through. */ + case ANCHORED_OPTION: + exclude_options |= EXCLUDE_ANCHORED; + break; + case BACKUP_OPTION: backup_option = 1; if (optarg) @@ -847,7 +908,11 @@ decode_options (int argc, char *const *argv) break; case EXCLUDE_OPTION: - add_filtered_exclude (0, optarg); + add_exclude (excluded, optarg, exclude_options | recursion_option); + break; + + case IGNORE_CASE_OPTION: + exclude_options |= FNM_CASEFOLD; break; case GROUP_OPTION: @@ -859,7 +924,8 @@ decode_options (int argc, char *const *argv) && g == (gid_t) g) group_option = g; else - FATAL_ERROR ((0, 0, _("Invalid group given on option"))); + FATAL_ERROR ((0, 0, "%s: %s", quotearg_colon (optarg), + _("%s: Invalid group"))); } break; @@ -870,17 +936,37 @@ decode_options (int argc, char *const *argv) if (mode_option == MODE_INVALID) FATAL_ERROR ((0, 0, _("Invalid mode given on option"))); if (mode_option == MODE_MEMORY_EXHAUSTED) - FATAL_ERROR ((0, 0, _("Memory exhausted"))); + xalloc_die (); + break; + + case NO_ANCHORED_OPTION: + exclude_options &= ~ EXCLUDE_ANCHORED; + break; + + case NO_IGNORE_CASE_OPTION: + exclude_options &= ~ FNM_CASEFOLD; break; - case NO_RECURSE_OPTION: - no_recurse_option = 1; + case NO_WILDCARDS_OPTION: + exclude_options &= ~ EXCLUDE_WILDCARDS; + break; + + case NO_WILDCARDS_MATCH_SLASH_OPTION: + exclude_options |= FNM_FILE_NAME; break; case NULL_OPTION: filename_terminator = '\0'; break; + case OVERWRITE_OPTION: + old_files_option = OVERWRITE_OLD_FILES; + break; + + case OVERWRITE_DIR_OPTION: + old_files_option = OVERWRITE_OLD_DIRS; + break; + case OWNER_OPTION: if (! (strlen (optarg) < UNAME_FIELD_SIZE && uname_to_uid (optarg, &owner_option))) @@ -890,7 +976,8 @@ decode_options (int argc, char *const *argv) && u == (uid_t) u) owner_option = u; else - FATAL_ERROR ((0, 0, _("Invalid owner given on option"))); + FATAL_ERROR ((0, 0, "%s: %s", quotearg_colon (optarg), + _("Invalid owner"))); } break; @@ -918,7 +1005,8 @@ decode_options (int argc, char *const *argv) uintmax_t u; if (! (xstrtoumax (optarg, 0, 10, &u, "") == LONGINT_OK && u == (size_t) u)) - USAGE_ERROR ((0, 0, _("Invalid record size"))); + USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (optarg), + _("Invalid record size"))); record_size = u; if (record_size % BLOCKSIZE != 0) USAGE_ERROR ((0, 0, _("Record size must be a multiple of %d."), @@ -936,12 +1024,20 @@ decode_options (int argc, char *const *argv) backup_suffix_string = optarg; break; + case USE_COMPRESS_PROGRAM_OPTION: + set_use_compress_program_option (optarg); + break; + case VOLNO_FILE_OPTION: volno_file_option = optarg; break; - case USE_COMPRESS_PROGRAM_OPTION: - set_use_compress_program_option (optarg); + case WILDCARDS_OPTION: + exclude_options |= EXCLUDE_WILDCARDS; + break; + + case WILDCARDS_MATCH_SLASH_OPTION: + exclude_options &= ~ FNM_FILE_NAME; break; case '0': @@ -1035,18 +1131,14 @@ decode_options (int argc, char *const *argv) if (show_version) { printf ("tar (GNU %s) %s\n", PACKAGE, VERSION); - fputs (_("\ -\n\ -Copyright 1988, 92,93,94,95,96,97,98, 1999 Free Software Foundation, Inc.\n"), - stdout); - fputs (_("\ -This is free software; see the source for copying conditions. There is NO\n\ -warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"), - stdout); - fputs (_("\ -\n\ -Written by John Gilmore and Jay Fenlason.\n"), - stdout); + print_copyright ("2001 Free Software Foundation, Inc."); + puts (_("\ +This program comes with NO WARRANTY, to the extent permitted by law.\n\ +You may redistribute it under the terms of the GNU General Public License;\n\ +see the file named COPYING for details.")); + + puts (_("Written by John Gilmore and Jay Fenlason.")); + exit (TAREXIT_SUCCESS); } @@ -1095,9 +1187,27 @@ Written by John Gilmore and Jay Fenlason.\n"), USAGE_ERROR ((0, 0, _("Cannot combine --listed-incremental with --newer"))); + if (volume_label_option) + { + size_t volume_label_max_len = + (sizeof current_header->header.name + - 1 /* for trailing '\0' */ + - (multi_volume_option + ? (sizeof " Volume " + - 1 /* for null at end of " Volume " */ + + INT_STRLEN_BOUND (int) /* for volume number */ + - 1 /* for sign, as 0 <= volno */) + : 0)); + if (volume_label_max_len < strlen (volume_label_option)) + USAGE_ERROR ((0, 0, + _("%s: Volume label is too long (limit is %lu bytes)"), + quotearg_colon (volume_label_option), + (unsigned long) volume_label_max_len)); + } + /* If ready to unlink hierarchies, so we are for simpler files. */ if (recursive_unlink_option) - unlink_first_option = 1; + old_files_option = UNLINK_FIRST_OLD_FILES; /* Forbid using -c with no input files whatsoever. Check that `-f -', explicit or implied, is used correctly. */ @@ -1147,12 +1257,9 @@ Written by John Gilmore and Jay Fenlason.\n"), /* Tar proper. */ -/*-----------------------. -| Main routine for tar. | -`-----------------------*/ - +/* Main routine for tar. */ int -main (int argc, char *const *argv) +main (int argc, char **argv) { #if HAVE_CLOCK_GETTIME if (clock_gettime (CLOCK_REALTIME, &start_timespec) != 0) @@ -1165,6 +1272,7 @@ main (int argc, char *const *argv) exit_status = TAREXIT_SUCCESS; filename_terminator = '\n'; + set_quoting_style (0, escape_quoting_style); /* Pre-allocate a few structures. */ @@ -1217,6 +1325,7 @@ main (int argc, char *const *argv) case EXTRACT_SUBCOMMAND: extr_init (); read_and (extract_archive); + extract_finish (); break; case LIST_SUBCOMMAND: