]> Dogcows Code - chaz/tar/commitdiff
Changes for compatibility with Slackware installation scripts.
authorSergey Poznyakoff <gray@gnu.org.ua>
Mon, 23 Sep 2013 16:35:29 +0000 (19:35 +0300)
committerSergey Poznyakoff <gray@gnu.org.ua>
Mon, 23 Sep 2013 16:35:29 +0000 (19:35 +0300)
* 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.

NEWS
doc/tar.texi
src/buffer.c
src/common.h
src/extract.c
src/suffix.c
src/tar.c
src/warning.c

diff --git a/NEWS b/NEWS
index 31087984f482d916c1299b312f80133ef47aa250..90a9022d50010e4f6c66828a50a8ecedc71ef0f8 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -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>
 
 \f
@@ -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.
+
 \f
 version 1.26 - Sergey Poznyakoff, 2011-03-12
 
index ddfa055e47e570a1c00956e3d9b3f71a62274351..9fde5a0761f41b7b6aff3e76bb840a8926e8fdaa 100644 (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
index 97084ab5caa0d76a43abd053e5a11d9368996226..4b44eaf13b9844b39e7bc6b8c80adbb93c19e882 100644 (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
index 723ad9028748506468e4dd57c8036e89509a155b..e65e647706b5b77caf7fc4e8a0d69aa9302e8c2c 100644 (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);
index 3d8ba10dbf539f50e3407eb0b56e8dd47213b997..9b6b7f97487e39d6a297e99c797f9ae37e882cc3 100644 (file)
@@ -855,7 +855,21 @@ apply_nonancestor_delayed_set_stat (char const *file_name, bool after_links)
 }
 
 \f
-
+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;
+}
+\f
 /* 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;
index d11e9ee20ff00bf24ca1f37daf41bafe7fff6261..cf8056cf9518a3f436dfdee2b73030b5de80b37f 100644 (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__
 };
index 6dc2ec560837508be616aee493103f272cfe9119..6c327f707def2bf3f7109e80bc676f2b10a2f68a 100644 (file)
--- a/src/tar.c
+++ b/src/tar.c
@@ -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;
index 81805e106df9ba726437231ac27d2c17267f0c01..d58a575d5813fe2e7f83fc907cb4d71a47ea24e4 100644 (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);
This page took 0.045693 seconds and 4 git commands to generate.