On 04/05/2017 11:58 AM, Daniel Peebles wrote:
the write_gnu_long_link function doesn't seem to pay any attention to my --numeric-owner flags and just blindly inserts the name of the 0 user/group into the LONGLINK struct. Is there a reason for that?
It's just an oversight. Thanks for reporting it. I installed the attached.
From c0f375e271acba56483ac1f066da2c26cb399809 Mon Sep 17 00:00:00 2001 From: Paul Eggert <eggert@cs.ucla.edu> Date: Thu, 6 Apr 2017 18:16:51 -0700 Subject: [PATCH] --numeric-owner now affects private headers too Problem reported by Daniel Peebles in: http://lists.gnu.org/archive/html/bug-tar/2017-04/msg00004.html * NEWS: Document this. * src/create.c (write_gnu_long_link): If --numeric-owner, leave the user and group empty in a private header. Cache the names for 0. --- NEWS | 21 ++++++++++++--------- src/create.c | 28 ++++++++++++++++------------ 2 files changed, 28 insertions(+), 21 deletions(-) diff --git a/NEWS b/NEWS index 40310a6..ad2b876 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,4 @@ -GNU tar NEWS - User visible changes. 2016-10-29 +GNU tar NEWS - User visible changes. 2017-04-06 Please send GNU tar bug reports to <bug-tar@gnu.org> @@ -20,7 +20,7 @@ invoked as tar -cf a.tar . --exclude '*.o' tar will create the archive, but will exit with status 2, having -issued the following error message +issued the following error message tar: The following options were used after any non-optional arguments in archive create or update mode. These options are @@ -28,7 +28,10 @@ issued the following error message rearrange them properly. tar: --exclude '*.o' has no effect tar: Exiting with failure status due to previous errors - + +* --numeric-owner now affects private headers too. +This helps the output of 'tar' to be more deterministic. + version 1.29 - Sergey Poznyakoff, 2016-05-16 @@ -52,7 +55,7 @@ the command line. Its effect is reverted by the * --null option reads file names verbatim -The --null option implies --verbatim-files-from. I.e. each line +The --null option implies --verbatim-files-from. I.e. each line read from null-delimited file lists is treated as a file name. This restores the documented behavior, which was broken in version @@ -83,7 +86,7 @@ use the time specified if the file mtime is newer than the given time. The --clamp-mtime option can only be used together with --mtime. Typical use case is to make builds reproducible: to loose less -information, it's better to keep the original date of an archive, +information, it's better to keep the original date of an archive, except for files modified during the build process. In that case, using reference (and thus reproducible) timestamps for the latter is good enough. @@ -131,7 +134,7 @@ sign and the specifier letter. deleted, correspondingly. %{FMT}t - Current local time using FMT as strftime(3) format. If {FMT} is omitted, use %c. - %{N}* - Pad output with spaces to the Nth column, or to the + %{N}* - Pad output with spaces to the Nth column, or to the current screen width, if {N} is not given. %c - A shortcut for "%{%Y-%m-%d %H:%M:%S}t: %ds, %{read,wrote}T%*\r" @@ -170,7 +173,7 @@ speed up archivation. --exclude-vcs-ignores Read exclude tags from VCS ignore files, where such files exist. Supported VCS's are: CVS, Git, Bazaar, Mercurial. - + * Tar refuses to read input from and write output to a tty device. @@ -179,7 +182,7 @@ speed up archivation. This release includes official tar(1) and rmt(8) manpages. Distribution maintainers are kindly asked to use these instead of the home-made pages they have been providing so far. - + version 1.27.1 - Sergey Poznyakoff, 2013-11-17 @@ -272,7 +275,7 @@ 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. +symlinks to directories when extracting from the archive. It is mainly intended to provide compatibility with the Slackware installation scripts. diff --git a/src/create.c b/src/create.c index 18e98d2..4fbdf66 100644 --- a/src/create.c +++ b/src/create.c @@ -202,8 +202,8 @@ to_base256 (int negative, uintmax_t value, char *where, size_t size) #define MODE_TO_CHARS(val, where) mode_to_chars (val, where, sizeof (where)) #define UID_TO_CHARS(val, where) uid_to_chars (val, where, sizeof (where)) -#define UNAME_TO_CHARS(name,buf) string_to_chars (name, buf, sizeof(buf)) -#define GNAME_TO_CHARS(name,buf) string_to_chars (name, buf, sizeof(buf)) +#define UNAME_TO_CHARS(name, buf) string_to_chars (name, buf, sizeof (buf)) +#define GNAME_TO_CHARS(name, buf) string_to_chars (name, buf, sizeof (buf)) static bool to_chars (int negative, uintmax_t value, size_t valsize, @@ -542,15 +542,19 @@ write_gnu_long_link (struct tar_stat_info *st, const char *p, char type) size_t size = strlen (p) + 1; size_t bufsize; union block *header; - char *tmpname; header = start_private_header ("././@LongLink", size, 0); - uid_to_uname (0, &tmpname); - UNAME_TO_CHARS (tmpname, header->header.uname); - free (tmpname); - gid_to_gname (0, &tmpname); - GNAME_TO_CHARS (tmpname, header->header.gname); - free (tmpname); + if (! numeric_owner_option) + { + static char *uname, *gname; + if (!uname) + { + uid_to_uname (0, &uname); + gid_to_gname (0, &gname); + } + UNAME_TO_CHARS (uname, header->header.uname); + GNAME_TO_CHARS (gname, header->header.gname); + } strcpy (header->buffer + offsetof (struct posix_header, magic), OLDGNU_MAGIC); @@ -743,7 +747,7 @@ start_header (struct tar_stat_info *st) union block *header; char const *uname = NULL; char const *gname = NULL; - + header = write_header_name (st); if (!header) return NULL; @@ -830,11 +834,11 @@ start_header (struct tar_stat_info *st) case USE_FILE_MTIME: mtime = st->mtime; break; - + case FORCE_MTIME: mtime = mtime_option; break; - + case CLAMP_MTIME: mtime = timespec_cmp (st->mtime, mtime_option) > 0 ? mtime_option : st->mtime; -- 2.9.3