Changes for compatibility with Slackware installation scripts.

* src/buffer.c (short_read): the "Record size" message
is controlled by the WARN_RECORD_SIZE warning_option bit.
* src/common.h (keep_directory_symlink_option): New global.
(WARN_RECORD_SIZE): New constant.
(WARN_VERBOSE_WARNINGS): Add WARN_RECORD_SIZE.
* src/extract.c (extract_dir): If keep_directory_symlink_option is
set, follow symlinks to directories.
* src/suffix.c (compression_suffixes): Add support for txz
suffix.
* src/tar.c (KEEP_DIRECTORY_SYMLINK_OPTION): New constant.
(options): New option --keep-directory-symlink.
(parse_opt): Handle this option.
* src/warning.c: Implement "record-size" warning control.

* NEWS: Update.
* doc/tar.texi: Document new features.
This commit is contained in:
Sergey Poznyakoff
2013-09-23 19:35:29 +03:00
parent 570a2c5f3d
commit 2c06a80918
8 changed files with 90 additions and 20 deletions

19
NEWS
View File

@@ -1,4 +1,4 @@
GNU tar NEWS - User visible changes. 2013-02-10
GNU tar NEWS - User visible changes. 2013-09-23
Please send GNU tar bug reports to <bug-tar@gnu.org>
@@ -70,6 +70,23 @@ prevent from being expanded too early, for example:
* New configure option --enable-gcc-warnings, intended for debugging.
* New warning control option --warning=[no-]record-size
On extraction, this option controls whether to display actual record
size, if it differs from the default.
* New command line option --keep-directory-symlink
By default, if when trying to extract a directory from the archive,
tar discovers that the corresponding file name already exists and is a
symbolic link, it first unlinks the entry, and then extracts the directory.
This option disables this behavior and instructs tar to follow
symlinks to directories when extracting from the archive.
It is mainly intended to provide compatibility with the Slackware
installation scripts.
version 1.26 - Sergey Poznyakoff, 2011-03-12

View File

@@ -2804,6 +2804,21 @@ Specifies that @command{tar} should ask the user for confirmation before
performing potentially destructive options, such as overwriting files.
@xref{interactive}.
@opsummary{--keep-directory-symlink}
@item --keep-directory-symlink
This option changes the behavior of tar when it encounters a symlink
with the same name as the directory that it is about to extract. By
default, in this case tar would first remove the symlink and then
proceed extracting the directory.
The @option{--keep-directory-symlink} option disables this behavior
and instructs tar to follow symlinks to directories when extracting
from the archive.
It is mainly intended to provide compatibility with the Slackware
installation scripts.
@opsummary{keep-newer-files}
@item --keep-newer-files
@@ -4221,6 +4236,10 @@ tar (child): trying gzip
This means that @command{tar} first tried to decompress
@file{archive.Z} using @command{compress}, and, when that
failed, switched to @command{gzip}.
@kwindex record-size
@cindex @samp{Record size = %lu blocks}, warning message
@item record-size
@samp{Record size = %lu blocks}
@end table
@subheading Keywords controlling incremental extraction:
@@ -10706,15 +10725,16 @@ When reading an archive, @command{tar} can usually figure out the
record size on itself. When this is the case, and a non-standard
record size was used when the archive was created, @command{tar} will
print a message about a non-standard blocking factor, and then operate
normally. On some tape devices, however, @command{tar} cannot figure
out the record size itself. On most of those, you can specify a
blocking factor (with @option{--blocking-factor}) larger than the
actual blocking factor, and then use the @option{--read-full-records}
(@option{-B}) option. (If you specify a blocking factor with
@option{--blocking-factor} and don't use the
@option{--read-full-records} option, then @command{tar} will not
attempt to figure out the recording size itself.) On some devices,
you must always specify the record size exactly with
normally@footnote{If this message is not needed, you can turn it off
using the @option{--warning=no-record-size} option.}. On some tape
devices, however, @command{tar} cannot figure out the record size
itself. On most of those, you can specify a blocking factor (with
@option{--blocking-factor}) larger than the actual blocking factor,
and then use the @option{--read-full-records} (@option{-B}) option.
(If you specify a blocking factor with @option{--blocking-factor} and
don't use the @option{--read-full-records} option, then @command{tar}
will not attempt to figure out the recording size itself.) On some
devices, you must always specify the record size exactly with
@option{--blocking-factor} when reading, because @command{tar} cannot
figure it out. In any case, use @option{--list} (@option{-t}) before
doing any extractions to see whether @command{tar} is reading the archive

View File

@@ -884,16 +884,16 @@ short_read (size_t status)
left = record_size - status;
if (left && left % BLOCKSIZE == 0
&& verbose_option
&& (warning_option & WARN_RECORD_SIZE)
&& record_start_block == 0 && status != 0
&& archive_is_dev ())
{
unsigned long rsize = status / BLOCKSIZE;
WARN ((0, 0,
ngettext ("Record size = %lu block",
"Record size = %lu blocks",
rsize),
rsize));
ngettext ("Record size = %lu block",
"Record size = %lu blocks",
rsize),
rsize));
}
while (left % BLOCKSIZE != 0

View File

@@ -190,6 +190,8 @@ enum old_files
};
GLOBAL enum old_files old_files_option;
GLOBAL bool keep_directory_symlink_option;
/* Specified file name for incremental list. */
GLOBAL const char *listed_incremental_option;
/* Incremental dump level */
@@ -872,11 +874,12 @@ void checkpoint_run (bool do_write);
#define WARN_DECOMPRESS_PROGRAM 0x00080000
#define WARN_EXISTING_FILE 0x00100000
#define WARN_XATTR_WRITE 0x00200000
#define WARN_RECORD_SIZE 0x00400000
/* The warnings composing WARN_VERBOSE_WARNINGS are enabled by default
in verbose mode */
/* These warnings are enabled by default in verbose mode: */
#define WARN_VERBOSE_WARNINGS (WARN_RENAME_DIRECTORY|WARN_NEW_DIRECTORY|\
WARN_DECOMPRESS_PROGRAM|WARN_EXISTING_FILE)
WARN_DECOMPRESS_PROGRAM|WARN_EXISTING_FILE|\
WARN_RECORD_SIZE)
#define WARN_ALL (~WARN_VERBOSE_WARNINGS)
void set_warning_option (const char *arg);

View File

@@ -855,7 +855,21 @@ apply_nonancestor_delayed_set_stat (char const *file_name, bool after_links)
}
static bool
is_directory_link (const char *file_name)
{
struct stat st;
int e = errno;
int res;
res = (fstatat (chdir_fd, file_name, &st, AT_SYMLINK_NOFOLLOW) == 0 &&
S_ISLNK (st.st_mode) &&
fstatat (chdir_fd, file_name, &st, 0) == 0 &&
S_ISDIR (st.st_mode));
errno = e;
return res;
}
/* Extractor functions for various member types */
static int
@@ -911,10 +925,15 @@ extract_dir (char *file_name, int typeflag)
if (errno == EEXIST
&& (interdir_made
|| keep_directory_symlink_option
|| old_files_option == DEFAULT_OLD_FILES
|| old_files_option == OVERWRITE_OLD_FILES))
{
struct stat st;
if (keep_directory_symlink_option && is_directory_link (file_name))
return 0;
if (deref_stat (file_name, &st) == 0)
{
current_mode = st.st_mode;

View File

@@ -43,6 +43,7 @@ static struct compression_suffix compression_suffixes[] = {
{ S(tlz, LZMA) },
{ S(lzo, LZOP) },
{ S(xz, XZ) },
{ S(txz, XZ) }, /* Slackware */
#undef S
#undef __CAT2__
};

View File

@@ -286,6 +286,7 @@ enum
IGNORE_COMMAND_ERROR_OPTION,
IGNORE_FAILED_READ_OPTION,
INDEX_FILE_OPTION,
KEEP_DIRECTORY_SYMLINK_OPTION,
KEEP_NEWER_FILES_OPTION,
LEVEL_OPTION,
LZIP_OPTION,
@@ -485,6 +486,9 @@ static struct argp_option options[] = {
{"overwrite-dir", OVERWRITE_DIR_OPTION, 0, 0,
N_("overwrite metadata of existing directories when extracting (default)"),
GRID+1 },
{"keep-directory-symlink", KEEP_DIRECTORY_SYMLINK_OPTION, 0, 0,
N_("preserve existing symlinks to directories when extracting"),
GRID+1 },
#undef GRID
#define GRID 40
@@ -1767,6 +1771,10 @@ parse_opt (int key, char *arg, struct argp_state *state)
ignore_failed_read_option = true;
break;
case KEEP_DIRECTORY_SYMLINK_OPTION:
keep_directory_symlink_option = true;
break;
case KEEP_NEWER_FILES_OPTION:
old_files_option = KEEP_NEWER_FILES;
break;

View File

@@ -46,6 +46,7 @@ static char const *const warning_args[] = {
"decompress-program",
"existing-file",
"xattr-write",
"record-size",
NULL
};
@@ -72,7 +73,8 @@ static int warning_types[] = {
WARN_XDEV,
WARN_DECOMPRESS_PROGRAM,
WARN_EXISTING_FILE,
WARN_XATTR_WRITE
WARN_XATTR_WRITE,
WARN_RECORD_SIZE
};
ARGMATCH_VERIFY (warning_args, warning_types);