|
|
b77676 |
From c4a4cafaa330793d776b001c272bf19869aac39c Mon Sep 17 00:00:00 2001
|
|
|
b77676 |
From: Sergey Poznyakoff <gray@gnu.org.ua>
|
|
|
b77676 |
Date: Mon, 23 Sep 2013 19:35:29 +0300
|
|
|
b77676 |
Subject: [PATCH] Changes for compatibility with Slackware installation
|
|
|
b77676 |
scripts.
|
|
|
b77676 |
|
|
|
b77676 |
* src/buffer.c (short_read): the "Record size" message
|
|
|
b77676 |
is controlled by the WARN_RECORD_SIZE warning_option bit.
|
|
|
b77676 |
* src/common.h (keep_directory_symlink_option): New global.
|
|
|
b77676 |
(WARN_RECORD_SIZE): New constant.
|
|
|
b77676 |
(WARN_VERBOSE_WARNINGS): Add WARN_RECORD_SIZE.
|
|
|
b77676 |
* src/extract.c (extract_dir): If keep_directory_symlink_option is
|
|
|
b77676 |
set, follow symlinks to directories.
|
|
|
b77676 |
* src/suffix.c (compression_suffixes): Add support for txz
|
|
|
b77676 |
suffix.
|
|
|
b77676 |
* src/tar.c (KEEP_DIRECTORY_SYMLINK_OPTION): New constant.
|
|
|
b77676 |
(options): New option --keep-directory-symlink.
|
|
|
b77676 |
(parse_opt): Handle this option.
|
|
|
b77676 |
* src/warning.c: Implement "record-size" warning control.
|
|
|
b77676 |
|
|
|
b77676 |
* NEWS: Update.
|
|
|
b77676 |
* doc/tar.texi: Document new features.
|
|
|
b77676 |
---
|
|
|
b77676 |
NEWS | 12 ++++++++++++
|
|
|
b77676 |
doc/tar.texi | 15 +++++++++++++++
|
|
|
b77676 |
src/common.h | 2 ++
|
|
|
b77676 |
src/extract.c | 19 +++++++++++++++++++
|
|
|
b77676 |
src/tar.c | 8 ++++++++
|
|
|
b77676 |
5 files changed, 56 insertions(+)
|
|
|
b77676 |
|
|
|
b77676 |
diff --git a/NEWS b/NEWS
|
|
|
b77676 |
index 8f3c416..36a27da 100644
|
|
|
b77676 |
--- a/NEWS
|
|
|
b77676 |
+++ b/NEWS
|
|
|
b77676 |
@@ -6,6 +6,18 @@ Please send GNU tar bug reports to <bug-tar@gnu.org>
|
|
|
b77676 |
When creating a PAX-format archive, tar no longer arbitrarily restricts
|
|
|
b77676 |
the size of the representation of a sparse file to be less than 8 GiB.
|
|
|
b77676 |
|
|
|
b77676 |
+* New command line option --keep-directory-symlink
|
|
|
b77676 |
+
|
|
|
b77676 |
+By default, if when trying to extract a directory from the archive,
|
|
|
b77676 |
+tar discovers that the corresponding file name already exists and is a
|
|
|
b77676 |
+symbolic link, it first unlinks the entry, and then extracts the directory.
|
|
|
b77676 |
+
|
|
|
b77676 |
+This option disables this behavior and instructs tar to follow
|
|
|
b77676 |
+symlinks to directories when extracting from the archive.
|
|
|
b77676 |
+
|
|
|
b77676 |
+It is mainly intended to provide compatibility with the Slackware
|
|
|
b77676 |
+installation scripts.
|
|
|
b77676 |
+
|
|
|
b77676 |
|
|
|
b77676 |
version 1.26 - Sergey Poznyakoff, 2011-03-12
|
|
|
b77676 |
|
|
|
b77676 |
diff --git a/doc/tar.texi b/doc/tar.texi
|
|
|
b77676 |
index 6bd59c7..fb03b85 100644
|
|
|
b77676 |
--- a/doc/tar.texi
|
|
|
b77676 |
+++ b/doc/tar.texi
|
|
|
b77676 |
@@ -2923,6 +2923,21 @@ Specifies that @command{tar} should ask the user for confirmation before
|
|
|
b77676 |
performing potentially destructive options, such as overwriting files.
|
|
|
b77676 |
@xref{interactive}.
|
|
|
b77676 |
|
|
|
b77676 |
+@opsummary{--keep-directory-symlink}
|
|
|
b77676 |
+@item --keep-directory-symlink
|
|
|
b77676 |
+
|
|
|
b77676 |
+This option changes the behavior of tar when it encounters a symlink
|
|
|
b77676 |
+with the same name as the directory that it is about to extract. By
|
|
|
b77676 |
+default, in this case tar would first remove the symlink and then
|
|
|
b77676 |
+proceed extracting the directory.
|
|
|
b77676 |
+
|
|
|
b77676 |
+The @option{--keep-directory-symlink} option disables this behavior
|
|
|
b77676 |
+and instructs tar to follow symlinks to directories when extracting
|
|
|
b77676 |
+from the archive.
|
|
|
b77676 |
+
|
|
|
b77676 |
+It is mainly intended to provide compatibility with the Slackware
|
|
|
b77676 |
+installation scripts.
|
|
|
b77676 |
+
|
|
|
b77676 |
@opsummary{keep-newer-files}
|
|
|
b77676 |
@item --keep-newer-files
|
|
|
b77676 |
|
|
|
b77676 |
diff --git a/src/common.h b/src/common.h
|
|
|
b77676 |
index 16ba401..274da01 100644
|
|
|
b77676 |
--- a/src/common.h
|
|
|
b77676 |
+++ b/src/common.h
|
|
|
b77676 |
@@ -192,6 +192,8 @@ enum old_files
|
|
|
b77676 |
};
|
|
|
b77676 |
GLOBAL enum old_files old_files_option;
|
|
|
b77676 |
|
|
|
b77676 |
+GLOBAL bool keep_directory_symlink_option;
|
|
|
b77676 |
+
|
|
|
b77676 |
/* Specified file name for incremental list. */
|
|
|
b77676 |
GLOBAL const char *listed_incremental_option;
|
|
|
b77676 |
/* Incremental dump level */
|
|
|
b77676 |
diff --git a/src/extract.c b/src/extract.c
|
|
|
b77676 |
index 3afb95d..b622a2a 100644
|
|
|
b77676 |
--- a/src/extract.c
|
|
|
b77676 |
+++ b/src/extract.c
|
|
|
b77676 |
@@ -854,7 +854,21 @@ apply_nonancestor_delayed_set_stat (char const *file_name, bool after_links)
|
|
|
b77676 |
}
|
|
|
b77676 |
|
|
|
b77676 |
|
|
|
b77676 |
+static bool
|
|
|
b77676 |
+is_directory_link (const char *file_name)
|
|
|
b77676 |
+{
|
|
|
b77676 |
+ struct stat st;
|
|
|
b77676 |
+ int e = errno;
|
|
|
b77676 |
+ int res;
|
|
|
b77676 |
|
|
|
b77676 |
+ res = (fstatat (chdir_fd, file_name, &st, AT_SYMLINK_NOFOLLOW) == 0 &&
|
|
|
b77676 |
+ S_ISLNK (st.st_mode) &&
|
|
|
b77676 |
+ fstatat (chdir_fd, file_name, &st, 0) == 0 &&
|
|
|
b77676 |
+ S_ISDIR (st.st_mode));
|
|
|
b77676 |
+ errno = e;
|
|
|
b77676 |
+ return res;
|
|
|
b77676 |
+}
|
|
|
b77676 |
+
|
|
|
b77676 |
/* Extractor functions for various member types */
|
|
|
b77676 |
|
|
|
b77676 |
static int
|
|
|
b77676 |
@@ -910,10 +924,15 @@ extract_dir (char *file_name, int typeflag)
|
|
|
b77676 |
|
|
|
b77676 |
if (errno == EEXIST
|
|
|
b77676 |
&& (interdir_made
|
|
|
b77676 |
+ || keep_directory_symlink_option
|
|
|
b77676 |
|| old_files_option == DEFAULT_OLD_FILES
|
|
|
b77676 |
|| old_files_option == OVERWRITE_OLD_FILES))
|
|
|
b77676 |
{
|
|
|
b77676 |
struct stat st;
|
|
|
b77676 |
+
|
|
|
b77676 |
+ if (keep_directory_symlink_option && is_directory_link (file_name))
|
|
|
b77676 |
+ return 0;
|
|
|
b77676 |
+
|
|
|
b77676 |
if (deref_stat (file_name, &st) == 0)
|
|
|
b77676 |
{
|
|
|
b77676 |
current_mode = st.st_mode;
|
|
|
b77676 |
diff --git a/src/tar.c b/src/tar.c
|
|
|
b77676 |
index 18277e4..d62ca0e 100644
|
|
|
b77676 |
--- a/src/tar.c
|
|
|
b77676 |
+++ b/src/tar.c
|
|
|
b77676 |
@@ -290,6 +290,7 @@ enum
|
|
|
b77676 |
IGNORE_COMMAND_ERROR_OPTION,
|
|
|
b77676 |
IGNORE_FAILED_READ_OPTION,
|
|
|
b77676 |
INDEX_FILE_OPTION,
|
|
|
b77676 |
+ KEEP_DIRECTORY_SYMLINK_OPTION,
|
|
|
b77676 |
KEEP_NEWER_FILES_OPTION,
|
|
|
b77676 |
LEVEL_OPTION,
|
|
|
b77676 |
LZIP_OPTION,
|
|
|
b77676 |
@@ -488,6 +489,9 @@ static struct argp_option options[] = {
|
|
|
b77676 |
{"overwrite-dir", OVERWRITE_DIR_OPTION, 0, 0,
|
|
|
b77676 |
N_("overwrite metadata of existing directories when extracting (default)"),
|
|
|
b77676 |
GRID+1 },
|
|
|
b77676 |
+ {"keep-directory-symlink", KEEP_DIRECTORY_SYMLINK_OPTION, 0, 0,
|
|
|
b77676 |
+ N_("preserve existing symlinks to directories when extracting"),
|
|
|
b77676 |
+ GRID+1 },
|
|
|
b77676 |
#undef GRID
|
|
|
b77676 |
|
|
|
b77676 |
#define GRID 40
|
|
|
b77676 |
@@ -1878,6 +1882,10 @@ parse_opt (int key, char *arg, struct argp_state *state)
|
|
|
b77676 |
ignore_failed_read_option = true;
|
|
|
b77676 |
break;
|
|
|
b77676 |
|
|
|
b77676 |
+ case KEEP_DIRECTORY_SYMLINK_OPTION:
|
|
|
b77676 |
+ keep_directory_symlink_option = true;
|
|
|
b77676 |
+ break;
|
|
|
b77676 |
+
|
|
|
b77676 |
case KEEP_NEWER_FILES_OPTION:
|
|
|
b77676 |
old_files_option = KEEP_NEWER_FILES;
|
|
|
b77676 |
break;
|
|
|
b77676 |
--
|
|
|
b77676 |
2.9.3
|
|
|
b77676 |
|