+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.
-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>
\f
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
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
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
@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,
@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
@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
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
@table @option
@opindex transform
+@opindex xform
@item --transform=@var{expression}
+@itemx --xform=@var{expression}
Modify file names using supplied @var{expression}.
@end table
@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
@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/}
backupfile.c
backupfile.h
basename.c
+c-ctype.c
+c-ctype.h
canonicalize-lgpl.c
canonicalize.h
charset.alias
dirname.h
dup-safer.c
dup2.c
+errno.in.h
error.c
error.h
exclude.c
obstack.h
offtostr.c
open-safer.c
+open.c
openat-die.c
openat-priv.h
openat-proc.c
stdint.h
stdint.in.h
stdio-impl.h
+stdio-write.c
stdio.h
stdio.in.h
stdlib.h
wctype.h
wctype.in.h
wcwidth.c
+write.c
xalloc-die.c
xalloc.h
xgetcwd.c
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))
{
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++;
}
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 */
}
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);
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)
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,
TOTALS_OPTION,
TO_COMMAND_OPTION,
TRANSFORM_OPTION,
+ TRANSFORM_SYMLINKS_OPTION,
UNQUOTE_OPTION,
USAGE_OPTION,
USE_COMPRESS_PROGRAM_OPTION,
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
/* 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:
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;
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. */