Browse Source

* src/common.h (transform_symlinks_option): New global.
* src/create.c (dump_file0): Transform symlink targets only if
explicitly required. Thanks Cyril Strejc for reporting the
problem.
* src/tar.c (parse_opt): New options --transform-symlinks and
--no-transform-symlinks. New alias --xform to the --transform
option.
* doc/tar.texi: Document --transform-symlinks
* NEWS: Update.
* THANKS: Update.

* src/names.c (name_gather): Use xzalloc.
* src/buffer.c (short_read): Move record size detection before
the loop.

Sergey Poznyakoff 16 năm trước cách đây
mục cha
commit
57bfbbde90
10 tập tin đã thay đổi với 134 bổ sung25 xóa
  1. 17 0
      ChangeLog
  2. 11 1
      NEWS
  3. 1 0
      THANKS
  4. 60 4
      doc/tar.texi
  5. 6 0
      lib/.cvsignore
  6. 12 16
      src/buffer.c
  7. 3 0
      src/common.h
  8. 2 1
      src/create.c
  9. 1 3
      src/names.c
  10. 21 0
      src/tar.c

+ 17 - 0
ChangeLog

@@ -1,3 +1,20 @@
+2008-10-16  Sergey Poznyakoff  <gray@gnu.org.ua>
+
+	* src/common.h (transform_symlinks_option): New global.
+	* src/create.c (dump_file0): Transform symlink targets only if
+	explicitly required.  Thanks Cyril Strejc for reporting the
+	problem.
+	* src/tar.c (parse_opt): New options --transform-symlinks and
+	--no-transform-symlinks. New alias --xform to the --transform
+	option.
+	* doc/tar.texi: Document --transform-symlinks
+	* NEWS: Update.
+	* THANKS: Update.
+	
+	* src/names.c (name_gather): Use xzalloc.
+	* src/buffer.c (short_read): Move record size detection before
+	the loop.
+	
 2008-10-07  Sergey Poznyakoff  <gray@gnu.org.ua>
 
 	* src/tar.c (options): Add --lzop option.

+ 11 - 1
NEWS

@@ -1,4 +1,4 @@
-GNU tar NEWS - User visible changes. 2008-09-24
+GNU tar NEWS - User visible changes. 2008-10-16
 Please send GNU tar bug reports to <bug-tar@gnu.org>
 
 
@@ -28,6 +28,16 @@ back to using archive suffix to determine it.
 Using --exclude-vcs handles also files used internally by Bazaar,
 Mercurial and Darcs.
 
+* The --transform-symlink option.
+
+The effect of the --transform option on the symbolic links targets is
+controlled by --transform-symlink and --no-transform-symlink options.
+By default, transformations do not apply to symlink targets,
+which corresponds to the behavior of version 1.19.  To apply
+transformations to symlink targets as well, use --transform-symlink
+option.  The --no-transform-symlink option cancels the effect of any
+prior --transform-symlink.
+
 * Bugfixes
 
 ** The --null option disabled handling of tar options in list files.  This

+ 1 - 0
THANKS

@@ -102,6 +102,7 @@ Clinton Carr		clint@netcom.com
 Conrad Hughes		chughes@maths.tcd.ie
 Constantin Belous	const@cris.net
 Coranth Gryphon		gryphon@bur.visidyne.com
+Cyril Strejc		strejc@unicontrols.cz
 Dale R. Worley		worley@world.std.com
 Dale Wiles		wiles@geordi.calspan.com
 Dan Bloch		dan@transarc.com

+ 60 - 4
doc/tar.texi

@@ -2905,6 +2905,13 @@ characters set by the previous @option{--quote-chars} option
 With this option, @command{tar} will not recurse into directories.
 @xref{recurse}.
 
+@opsummary{no-transform-symlinks}
+@item --no-transform-symlinks
+Cancel the effect of any prior @command{--transform-symlinks} option
+(see below) and return to the default behavior of applying name
+transformation expression only to the names of files (archive
+members), not to target of symbolic links.
+
 @opsummary{no-same-owner}
 @item --no-same-owner
 @itemx -o
@@ -3266,8 +3273,9 @@ rather than the data modification time stored in the archive.
 @xref{Data Modification Times}.
 
 @opsummary{transform}
+@opsummary{xform}
 @item --transform=@var{sed-expr}
-
+@itemx --xform=@var{sed-expr}
 Transform file or member names using @command{sed} replacement expression
 @var{sed-expr}.  For example,
 
@@ -3284,6 +3292,11 @@ To see transformed member names in verbose listings, use
 @option{--show-transformed-names} option
 (@pxref{show-transformed-names}).
 
+@opsummary{transform-symlinks}
+@item --transform-symlinks
+Apply @command{--transform} option to symbolic link targets
+(@pxref{transform}).
+
 @opsummary{uncompress}
 @item --uncompress
 
@@ -7553,7 +7566,7 @@ characters that are quoted by default in the selected quoting style.
 
 @command{Tar} archives contain detailed information about files stored
 in them and full file names are part of that information.  When
-storing file to an archive, its file name is recorded in the archive
+storing file to an archive, its file name is recorded in it,
 along with the actual file contents.  When restoring from an archive,
 a file is created on disk with exactly the same name as that stored
 in the archive.  In the majority of cases this is the desired behavior
@@ -7570,7 +7583,7 @@ directory components, or with otherwise modified names.  In other
 cases it is desirable to store files under differing names in the
 archive.
 
-@GNUTAR{} provides two options for these needs.
+@GNUTAR{} provides several options for these needs.
 
 @table @option
 @opindex strip-components
@@ -7644,7 +7657,9 @@ In case you need to apply more complex modifications to the file name,
 
 @table @option
 @opindex transform
+@opindex xform
 @item --transform=@var{expression}
+@itemx --xform=@var{expression}
 Modify file names using supplied @var{expression}.
 @end table
 
@@ -7683,7 +7698,7 @@ sed, GNU sed}).
 @item @var{number}
 Only replace the @var{number}th match of the @var{regexp}.
 
-Note: the @var{posix} standard does not specify what should happen
+Note: the @acronym{POSIX} standard does not specify what should happen
 when you mix the @samp{g} and @var{number} modifiers.  @GNUTAR{}
 follows the GNU @command{sed} implementation in this regard, so
 the interaction is defined to be: ignore matches before the
@@ -7737,6 +7752,47 @@ $ @kbd{tar --transform 's/.*/\L&/' -x -f arch.tar}
 
 @end enumerate
 
+The @option{--transform} option applies only to member names.  It does
+not apply to symbolic link targets.  In many cases, this is the
+desired behavior.  Consider for example, archiving the @file{/lib}
+directory: 
+
+@smallexample
+$ @kbd{tar -vv -c -f archive /lib}
+tar: Removing leading `/' from member names
+drwxr-xr-x root/root       0 2008-07-08 16:20 /lib/
+-rwxr-xr-x root/root 1250840 2008-05-25 07:44 /lib/libc-2.3.2.so
+lrwxrwxrwx root/root       0 2008-06-24 17:12 /lib/libc.so.6 -> libc-2.3.2.so
+...
+@end smallexample
+
+Now, you can use our example above to extract it into @file{/usr/local}:
+
+@smallexample
+$ @kbd{tar --transform 's,^,/usr/local/,' \
+  --show-transformed -v -x -f archive}
+drwxr-xr-x root/root       0 2008-07-08 16:20 /usr/local/lib/
+-rwxr-xr-x root/root 1250840 2008-05-25 07:44 /usr/local/lib/libc-2.3.2.so
+lrwxrwxrwx root/root       0 2008-06-24 17:12 /usr/local/lib/libc.so.6 ->
+libc-2.3.2.so
+@end smallexample
+
+As you see, it correctly extracts @file{libc.so.6} as a symbolic link
+to @file{libc-2.3.2.so}.
+
+However, sometimes you may need to transform symbolic link targets as
+well.  To do so, @GNUTAR provides an additional option:
+
+@table @option
+@opindex transform-symlinks
+@item --transform-symlinks
+Apply @command{--transform} option to symbolic link targets.
+
+@opindex no-transform-symlinks
+@itemx --no-transform-symlinks
+Cancel the effect of the previous @option{--transform-symlinks} option.
+@end table
+
 Unlike @option{--strip-components}, @option{--transform} can be used
 in any @GNUTAR{} operation mode.  For example, the following command
 adds files to the archive while replacing the leading @file{usr/}

+ 6 - 0
lib/.cvsignore

@@ -25,6 +25,8 @@ at-func.c
 backupfile.c
 backupfile.h
 basename.c
+c-ctype.c
+c-ctype.h
 canonicalize-lgpl.c
 canonicalize.h
 charset.alias
@@ -46,6 +48,7 @@ dirname.c
 dirname.h
 dup-safer.c
 dup2.c
+errno.in.h
 error.c
 error.h
 exclude.c
@@ -130,6 +133,7 @@ obstack.c
 obstack.h
 offtostr.c
 open-safer.c
+open.c
 openat-die.c
 openat-priv.h
 openat-proc.c
@@ -189,6 +193,7 @@ stdbool.in.h
 stdint.h
 stdint.in.h
 stdio-impl.h
+stdio-write.c
 stdio.h
 stdio.in.h
 stdlib.h
@@ -258,6 +263,7 @@ wchar.in.h
 wctype.h
 wctype.in.h
 wcwidth.c
+write.c
 xalloc-die.c
 xalloc.h
 xgetcwd.c

+ 12 - 16
src/buffer.c

@@ -686,6 +686,18 @@ short_read (size_t status)
   more = record_start->buffer + status;
   left = record_size - status;
 
+  if (left && left % BLOCKSIZE == 0
+      && !read_full_records && verbose_option > 1
+      && record_start_block == 0 && status != 0)
+    {
+      unsigned long rsize = status / BLOCKSIZE;
+      WARN ((0, 0,
+             ngettext ("Record size = %lu block",
+                       "Record size = %lu blocks",
+                       rsize),
+             rsize));
+    }
+
   while (left % BLOCKSIZE != 0
          || (left && status && read_full_records))
     {
@@ -707,26 +719,10 @@ short_read (size_t status)
                         rest));
         }
 
-      /* User warned us about this.  Fix up.  */
-
       left -= status;
       more += status;
     }
 
-  /* FIXME: for size=0, multi-volume support.  On the first record, warn
-     about the problem.  */
-
-  if (!read_full_records && verbose_option > 1
-      && record_start_block == 0 && status != 0)
-    {
-      unsigned long rsize = (record_size - left) / BLOCKSIZE;
-      WARN ((0, 0,
-             ngettext ("Record size = %lu block",
-                       "Record size = %lu blocks",
-                       rsize),
-             rsize));
-    }
-
   record_end = record_start + (record_size - left) / BLOCKSIZE;
   records_read++;
 }

+ 3 - 0
src/common.h

@@ -346,6 +346,9 @@ GLOBAL bool unquote_option;
 
 GLOBAL bool test_label_option; /* Test archive volume label and exit */
 
+/* Apply transformations to symlink targets as well. */
+GLOBAL bool transform_symlinks_option;
+
 /* Show file or archive names after transformation.
    In particular, when creating archive in verbose mode, list member names
    as stored in the archive */

+ 2 - 1
src/create.c

@@ -1705,7 +1705,8 @@ dump_file0 (struct tar_stat_info *st, const char *p,
 	}
       buffer[size] = '\0';
       assign_string (&st->link_name, buffer);
-      transform_name (&st->link_name);
+      if (transform_symlinks_option)
+	transform_name (&st->link_name);
       if (NAME_FIELD_SIZE - (archive_format == OLDGNU_FORMAT) < size)
 	write_long_link (st);
 

+ 1 - 3
src/names.c

@@ -388,9 +388,7 @@ name_gather (void)
       if (allocated_size == 0)
 	{
 	  allocated_size = offsetof (struct name, name) + NAME_FIELD_SIZE + 1;
-	  buffer = xmalloc (allocated_size);
-	  /* FIXME: This memset is overkill, and ugly...  */
-	  memset (buffer, 0, allocated_size);
+	  buffer = xzalloc (allocated_size);
 	}
       
       while ((ep = name_next_elt (0)) && ep->type == NELT_CHDIR)

+ 21 - 0
src/tar.c

@@ -287,6 +287,7 @@ enum
   NO_RECURSION_OPTION,
   NO_SAME_OWNER_OPTION,
   NO_SAME_PERMISSIONS_OPTION,
+  NO_TRANSFORM_SYMLINKS_OPTION,
   NO_UNQUOTE_OPTION,
   NO_WILDCARDS_MATCH_SLASH_OPTION,
   NO_WILDCARDS_OPTION,
@@ -321,6 +322,7 @@ enum
   TOTALS_OPTION,
   TO_COMMAND_OPTION,
   TRANSFORM_OPTION,
+  TRANSFORM_SYMLINKS_OPTION,
   UNQUOTE_OPTION,
   USAGE_OPTION,
   USE_COMPRESS_PROGRAM_OPTION,
@@ -686,6 +688,11 @@ static struct argp_option options[] = {
    GRID+1 },
   {"transform", TRANSFORM_OPTION, N_("EXPRESSION"), 0,
    N_("use sed replace EXPRESSION to transform file names"), GRID+1 },
+  {"xform", 0, 0, OPTION_ALIAS, NULL, GRID+1 },
+  {"transform-symlinks", TRANSFORM_SYMLINKS_OPTION, NULL, 0,
+   N_("apply transformations to symlink targets"), GRID+1 },
+  {"no-transform-symlinks", NO_TRANSFORM_SYMLINKS_OPTION, NULL, 0,
+   N_("cancel effect of the previous --transform-symlinks option"), GRID+1 },
 #undef GRID
 
 #define GRID 120
@@ -1819,6 +1826,8 @@ parse_opt (int key, char *arg, struct argp_state *state)
       /* FIXME: What it is good for? */
       same_permissions_option = true;
       same_order_option = true;
+      WARN ((0, 0, _("The --preserve option is deprecated, "
+		     "use --preserve-permissions --preserve-order instead")));
       break;
 
     case RECORD_SIZE_OPTION:
@@ -1902,6 +1911,14 @@ parse_opt (int key, char *arg, struct argp_state *state)
       set_transform_expr (arg);
       break;
 
+    case TRANSFORM_SYMLINKS_OPTION:
+      transform_symlinks_option = true;
+      break;
+
+    case NO_TRANSFORM_SYMLINKS_OPTION:
+      transform_symlinks_option = false;
+      break;
+      
     case USE_COMPRESS_PROGRAM_OPTION:
       set_use_compress_program_option (arg);
       break;
@@ -2345,6 +2362,10 @@ decode_options (int argc, char **argv)
 
   if (tape_length_option && tape_length_option < record_size)
     USAGE_ERROR ((0, 0, _("Volume length cannot be less than record size")));
+
+  if (same_order_option && listed_incremental_option)
+    USAGE_ERROR ((0, 0, _("--preserve-order is not compatible with "
+			  "--listed-incremental")));
   
   /* Forbid using -c with no input files whatsoever.  Check that `-f -',
      explicit or implied, is used correctly.  */