* 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.
This commit is contained in:
Sergey Poznyakoff
2008-10-16 11:07:19 +00:00
parent 7b69ee5a24
commit 57bfbbde90
10 changed files with 134 additions and 25 deletions

View File

@@ -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.

12
NEWS
View File

@@ -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
THANKS
View File

@@ -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

View File

@@ -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/}

View File

@@ -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

View File

@@ -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++;
}

View File

@@ -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 */

View File

@@ -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);

View File

@@ -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)

View File

@@ -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. */