summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2008-10-16 11:07:19 +0000
committerSergey Poznyakoff <gray@gnu.org.ua>2008-10-16 11:07:19 +0000
commit57bfbbde90dfcc18ee6b1e27c01ba915ecc56312 (patch)
treeba70375978435fa2ae5c1c4f2f3fb9613abc91e8
parent7b69ee5a240bf25a7b65e7724248f2dd3f7e4836 (diff)
downloadtar-57bfbbde90dfcc18ee6b1e27c01ba915ecc56312.tar.gz
* 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.
-rw-r--r--ChangeLog17
-rw-r--r--NEWS12
-rw-r--r--THANKS1
-rw-r--r--doc/tar.texi64
-rw-r--r--lib/.cvsignore6
-rw-r--r--src/buffer.c28
-rw-r--r--src/common.h3
-rw-r--r--src/create.c3
-rw-r--r--src/names.c4
-rw-r--r--src/tar.c21
10 files changed, 134 insertions, 25 deletions
diff --git a/ChangeLog b/ChangeLog
index e74930b1..4e74e8c0 100644
--- a/ChangeLog
+++ b/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.
diff --git a/NEWS b/NEWS
index 5767601b..a55eb340 100644
--- a/NEWS
+++ b/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
diff --git a/THANKS b/THANKS
index 0c2495cd..986b1af7 100644
--- a/THANKS
+++ b/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
diff --git a/doc/tar.texi b/doc/tar.texi
index f86f077a..43970adf 100644
--- a/doc/tar.texi
+++ b/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/}
diff --git a/lib/.cvsignore b/lib/.cvsignore
index eb463340..91735071 100644
--- a/lib/.cvsignore
+++ b/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
diff --git a/src/buffer.c b/src/buffer.c
index c544ee00..79bb7d6f 100644
--- a/src/buffer.c
+++ b/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++;
}
diff --git a/src/common.h b/src/common.h
index 91ae10cf..947546a1 100644
--- a/src/common.h
+++ b/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 */
diff --git a/src/create.c b/src/create.c
index fc26f1ef..7b20c02b 100644
--- a/src/create.c
+++ b/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);
diff --git a/src/names.c b/src/names.c
index 0c3aebfc..05f89b15 100644
--- a/src/names.c
+++ b/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)
diff --git a/src/tar.c b/src/tar.c
index c2ead135..1b9ffce1 100644
--- a/src/tar.c
+++ b/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. */