tar: update to latest upstream version

This version includes USE=minimal support which strips down the install.

BUG=chromium-os:22939
TEST=`cbuildbot x86-generic-full` works
TEST=`cbuildbot chromiumos-sdk` works

Change-Id: I65f9bec4491f1ed82707bebba753276594f66e29
Reviewed-on: https://gerrit.chromium.org/gerrit/37380
Reviewed-by: David James <davidjames@chromium.org>
Commit-Ready: Mike Frysinger <vapier@chromium.org>
Tested-by: Mike Frysinger <vapier@chromium.org>
This commit is contained in:
Mike Frysinger 2012-11-05 15:49:21 -05:00 committed by Gerrit
parent fa12b91bda
commit 1fe720d2bd
12 changed files with 1030 additions and 724 deletions

View File

@ -1 +1 @@
DIST tar-1.23.tar.bz2 2189324 RMD160 e79062b7f69d80b734445306f69fb8b96801e909 SHA1 6f3b1443a019da02e4ec20a1446d4aa54b488071 SHA256 c9328372db62fbb1d94c9e4e3cefc961111af46de47085b635359c00a0eebe36
DIST tar-1.26.tar.bz2 2339773 SHA256 5a5369f464502a598e938029c310d4b3abd51e6bb8dfd045663e61c8ea9f6d41 SHA512 3bc12441bebfc388017ad0632fb3e777ceaf62be82fb19ce771df8bbb765eb094dad336110189f49f5eaaebd4d6ced586098e1e3c8b9f7f775dc483d5513f209 WHIRLPOOL bfdc579f97a260d6b6776211f470bfc1a99b81d89a8067b2ebfab3101ab1a4f2b4f7c444edffc05bc7585993cae601c499ec074bb606c7ef289deac5429cfb2b

View File

@ -1,124 +0,0 @@
http://bugs.gentoo.org/252680
http://lists.gnu.org/archive/html/bug-tar/2008-12/msg00028.html
revert this change:
2008-11-25 Sergey Poznyakoff <gray@gnu.org.ua>
Do not try to drain the input pipe before closing the
archive.
* src/buffer.c (close_archive): Remove call to
sys_drain_input_pipe. Pass hit_eof as the second
argument to sys_wait_for_child.
* src/common.h (sys_drain_input_pipe): Remove
(sys_wait_for_child): Declare second argument.
* src/system.c (sys_drain_input_pipe): Remove.
(sys_wait_for_child): Take two arguments. The second one helps to
decide whether to tolerate child termination on SIGPIPE.
diff --git a/src/buffer.c b/src/buffer.c
index 5f5457a..02a3e4c 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -848,6 +848,8 @@ close_archive (void)
flush_archive ();
}
+ sys_drain_input_pipe ();
+
compute_duration ();
if (verify_option)
verify_volume ();
@@ -855,7 +857,7 @@ close_archive (void)
if (rmtclose (archive) != 0)
close_error (*archive_name_cursor);
- sys_wait_for_child (child_pid, hit_eof);
+ sys_wait_for_child (child_pid);
tar_stat_destroy (&current_stat_info);
if (save_name)
diff --git a/src/common.h b/src/common.h
index 9897b46..cc3483e 100644
--- a/src/common.h
+++ b/src/common.h
@@ -699,7 +699,8 @@ char *xheader_format_name (struct tar_stat_info *st, const char *fmt,
void sys_detect_dev_null_output (void);
void sys_save_archive_dev_ino (void);
-void sys_wait_for_child (pid_t, bool);
+void sys_drain_input_pipe (void);
+void sys_wait_for_child (pid_t);
void sys_spawn_shell (void);
bool sys_compare_uid (struct stat *a, struct stat *b);
bool sys_compare_gid (struct stat *a, struct stat *b);
diff --git a/src/system.c b/src/system.c
index c90a40d..e57e6da 100644
--- a/src/system.c
+++ b/src/system.c
@@ -1,7 +1,6 @@
/* System-dependent calls for tar.
- Copyright (C) 2003, 2004, 2005, 2006, 2007,
- 2008 Free Software Foundation, Inc.
+ Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
@@ -52,7 +51,12 @@ sys_detect_dev_null_output (void)
}
void
-sys_wait_for_child (pid_t child_pid, bool eof)
+sys_drain_input_pipe (void)
+{
+}
+
+void
+sys_wait_for_child (pid_t child_pid)
{
}
@@ -156,8 +160,26 @@ sys_detect_dev_null_output (void)
&& archive_stat.st_ino == dev_null_stat.st_ino));
}
+/* Manage to fully drain a pipe we might be reading, so to not break it on
+ the producer after the EOF block. FIXME: one of these days, GNU tar
+ might become clever enough to just stop working, once there is no more
+ work to do, we might have to revise this area in such time. */
+
+void
+sys_drain_input_pipe (void)
+{
+ size_t r;
+
+ if (access_mode == ACCESS_READ
+ && ! _isrmt (archive)
+ && (S_ISFIFO (archive_stat.st_mode) || S_ISSOCK (archive_stat.st_mode)))
+ while ((r = rmtread (archive, record_start->buffer, record_size)) != 0
+ && r != SAFE_READ_ERROR)
+ continue;
+}
+
void
-sys_wait_for_child (pid_t child_pid, bool eof)
+sys_wait_for_child (pid_t child_pid)
{
if (child_pid)
{
@@ -171,11 +193,8 @@ sys_wait_for_child (pid_t child_pid, bool eof)
}
if (WIFSIGNALED (wait_status))
- {
- int sig = WTERMSIG (wait_status);
- if (!(!eof && sig == SIGPIPE))
- ERROR ((0, 0, _("Child died with signal %d"), sig));
- }
+ ERROR ((0, 0, _("Child died with signal %d"),
+ WTERMSIG (wait_status)));
else if (WEXITSTATUS (wait_status) != 0)
ERROR ((0, 0, _("Child returned status %d"),
WEXITSTATUS (wait_status)));

View File

@ -1,136 +0,0 @@
https://bugs.gentoo.org/show_bug.cgi?id=253122
http://git.savannah.gnu.org/cgit/tar.git/commit/?id=7b68ef3d918603f3afb03e939ba72f5cad10edf4
From 7b68ef3d918603f3afb03e939ba72f5cad10edf4 Mon Sep 17 00:00:00 2001
From: Sergey Poznyakoff <gray@gnu.org.ua>
Date: Mon, 29 Dec 2008 09:27:00 +0000
Subject: Fix testsuite and bootstrap. Implement -I.
* bootstrap.conf: Include size_max.
* gnulib.modules: Remove memset, rmdir. Replace strdup with
strdup-posix. Patch by Eric Blake.
* src/tar.c: Implement -I as a shorthand for --use-compress-program.
* doc/tar.texi: Document -I.
* tests/pipe.at, tests/shortrec.at: Account for eventual 'Record
size' output.
* tests/testsuite.at (AT_TAR_CHECK_HOOK): New define
(AT_TAR_WITH_HOOK, TAR_IGNREC_HOOK): New macros.
---
diff --git a/tests/pipe.at b/tests/pipe.at
index efca65b..be99212 100644
--- a/tests/pipe.at
+++ b/tests/pipe.at
@@ -1,7 +1,7 @@
# Process this file with autom4te to create testsuite. -*- Autotest -*-
# Test suite for GNU tar.
-# Copyright (C) 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+# Copyright (C) 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -30,7 +30,8 @@ AT_SETUP([decompressing from stdin])
AT_KEYWORDS([pipe])
-AT_TAR_CHECK([
+AT_TAR_WITH_HOOK([TAR_IGNREC_HOOK],
+[AT_TAR_CHECK([
AT_SORT_PREREQ
mkdir directory
@@ -49,6 +50,7 @@ directory/file1
directory/file2
separator
separator
-])
+],
+[stderr])])
AT_CLEANUP
diff --git a/tests/shortrec.at b/tests/shortrec.at
index 3e009fd..179f365 100644
--- a/tests/shortrec.at
+++ b/tests/shortrec.at
@@ -1,7 +1,7 @@
# Process this file with autom4te to create testsuite. -*- Autotest -*-
# Test suite for GNU tar.
-# Copyright (C) 2005, 2007 Free Software Foundation, Inc.
+# Copyright (C) 2005, 2007, 2008 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -23,17 +23,22 @@
# used to create the archive.
AT_SETUP([short records])
-AT_KEYWORDS([shortrec.at])
+AT_KEYWORDS([shortrec])
-AT_TAR_CHECK([
+AT_TAR_WITH_HOOK([TAR_IGNREC_HOOK],
+[AT_TAR_CHECK([
mkdir directory
(cd directory && touch a b c d e f g h i j k l m n o p q r)
-tar -c -b 1 -f - directory | tar -t -f - >/dev/null
+tar -c -b 1 -f - directory | tar -t -f -
tar -c -b 1 -f archive directory
-tar -t -f archive >/dev/null
-tar -t -f - < archive >/dev/null
+tar -t -f archive
+tar -t -f - < archive
rm -r directory
+],
+[0],
+[ignore],
+[stderr])
])
AT_CLEANUP
diff --git a/tests/testsuite.at b/tests/testsuite.at
index 2fa5392..a12477d 100644
--- a/tests/testsuite.at
+++ b/tests/testsuite.at
@@ -1,7 +1,7 @@
# Process this file with autom4te to create testsuite. -*- Autotest -*-
# Test suite for GNU tar.
-# Copyright (C) 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+# Copyright (C) 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -21,6 +21,7 @@
# We need a recent Autotest.
m4_version_prereq([2.52g])
+m4_define([AT_TAR_CHECK_HOOK])
m4_define([AT_TAR_CHECK],[
AT_XFAIL_IF(test -f $[]XFAILFILE)
m4_foreach([FMT],
@@ -33,9 +34,20 @@ export TEST_TAR_FORMAT
TAR_OPTIONS="-H FMT"
export TAR_OPTIONS
rm -rf *
-$1)],$2,$3,$4,$5,$6)])
+$1)],$2,$3,$4,$5,$6)
+ AT_TAR_CHECK_HOOK])
])
+m4_define([AT_TAR_WITH_HOOK],[
+ m4_pushdef([AT_TAR_CHECK_HOOK],[$1])
+ $2
+
+ m4_popdef([AT_TAR_CHECK_HOOK])])
+
+m4_define([TAR_IGNREC_HOOK],[
+ AT_CHECK([grep -v '^.*tar: Record size = ' stderr; exit 0])
+])
+
m4_define([RE_CHECK],[
AT_DATA([$1.re],[$2])
awk '{print NR " " $[]0}' $1 > $[]$.1
--
cgit v0.8.2

View File

@ -1,32 +0,0 @@
diff -uNr tar-1.22.ORIG//src/create.c tar-1.22/src/create.c
--- tar-1.22.ORIG//src/create.c 2010-04-25 19:50:28.147606290 +0100
+++ tar-1.22/src/create.c 2010-04-25 19:50:44.849606051 +0100
@@ -577,7 +577,10 @@
GNAME_TO_CHARS (tmpname, header->header.gname);
free (tmpname);
- strcpy (header->header.magic, OLDGNU_MAGIC);
+ /* OLDGNU_MAGIC is string with 7 chars + NULL */
+ strncpy (header->header.magic, OLDGNU_MAGIC, sizeof(header->header.magic));
+ strncpy (header->header.version, OLDGNU_MAGIC+sizeof(header->header.magic),
+ sizeof(header->header.version));
header->header.typeflag = type;
finish_header (st, header, -1);
@@ -907,9 +910,13 @@
break;
case OLDGNU_FORMAT:
- case GNU_FORMAT: /*FIXME?*/
- /* Overwrite header->header.magic and header.version in one blow. */
- strcpy (header->header.magic, OLDGNU_MAGIC);
+ case GNU_FORMAT:
+ /* OLDGNU_MAGIC is string with 7 chars + NULL */
+ strncpy (header->header.magic, OLDGNU_MAGIC,
+ sizeof(header->header.magic));
+ strncpy (header->header.version,
+ OLDGNU_MAGIC+sizeof(header->header.magic),
+ sizeof(header->header.version));
break;
case POSIX_FORMAT:

View File

@ -1,125 +0,0 @@
http://bugs.gentoo.org/252680
http://bugs.gentoo.org/309001
http://lists.gnu.org/archive/html/bug-tar/2008-12/msg00028.html
revert this change:
2008-11-25 Sergey Poznyakoff <gray@gnu.org.ua>
Do not try to drain the input pipe before closing the
archive.
* src/buffer.c (close_archive): Remove call to
sys_drain_input_pipe. Pass hit_eof as the second
argument to sys_wait_for_child.
* src/common.h (sys_drain_input_pipe): Remove
(sys_wait_for_child): Declare second argument.
* src/system.c (sys_drain_input_pipe): Remove.
(sys_wait_for_child): Take two arguments. The second one helps to
decide whether to tolerate child termination on SIGPIPE.
diff --git a/src/buffer.c b/src/buffer.c
index 5f5457a..02a3e4c 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -848,6 +848,8 @@ close_archive (void)
flush_archive ();
}
+ sys_drain_input_pipe ();
+
compute_duration ();
if (verify_option)
verify_volume ();
@@ -855,7 +857,7 @@ close_archive (void)
if (rmtclose (archive) != 0)
close_error (*archive_name_cursor);
- sys_wait_for_child (child_pid, hit_eof);
+ sys_wait_for_child (child_pid);
tar_stat_destroy (&current_stat_info);
if (save_name)
diff --git a/src/common.h b/src/common.h
index 9897b46..cc3483e 100644
--- a/src/common.h
+++ b/src/common.h
@@ -699,7 +699,8 @@ char *xheader_format_name (struct tar_stat_info *st, const char *fmt,
void sys_detect_dev_null_output (void);
void sys_save_archive_dev_ino (void);
-void sys_wait_for_child (pid_t, bool);
+void sys_drain_input_pipe (void);
+void sys_wait_for_child (pid_t);
void sys_spawn_shell (void);
bool sys_compare_uid (struct stat *a, struct stat *b);
bool sys_compare_gid (struct stat *a, struct stat *b);
diff --git a/src/system.c b/src/system.c
index c90a40d..e57e6da 100644
--- a/src/system.c
+++ b/src/system.c
@@ -1,7 +1,6 @@
/* System-dependent calls for tar.
- Copyright (C) 2003, 2004, 2005, 2006, 2007,
- 2008 Free Software Foundation, Inc.
+ Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
@@ -52,7 +51,12 @@ sys_detect_dev_null_output (void)
}
void
-sys_wait_for_child (pid_t child_pid, bool eof)
+sys_drain_input_pipe (void)
+{
+}
+
+void
+sys_wait_for_child (pid_t child_pid)
{
}
@@ -156,8 +160,26 @@ sys_detect_dev_null_output (void)
&& archive_stat.st_ino == dev_null_stat.st_ino));
}
+/* Manage to fully drain a pipe we might be reading, so to not break it on
+ the producer after the EOF block. FIXME: one of these days, GNU tar
+ might become clever enough to just stop working, once there is no more
+ work to do, we might have to revise this area in such time. */
+
+void
+sys_drain_input_pipe (void)
+{
+ size_t r;
+
+ if (access_mode == ACCESS_READ
+ && ! _isrmt (archive)
+ && (S_ISFIFO (archive_stat.st_mode) || S_ISSOCK (archive_stat.st_mode)))
+ while ((r = rmtread (archive, record_start->buffer, record_size)) != 0
+ && r != SAFE_READ_ERROR)
+ continue;
+}
+
void
-sys_wait_for_child (pid_t child_pid, bool eof)
+sys_wait_for_child (pid_t child_pid)
{
if (child_pid)
{
@@ -171,11 +193,8 @@ sys_wait_for_child (pid_t child_pid, bool eof)
}
if (WIFSIGNALED (wait_status))
- {
- int sig = WTERMSIG (wait_status);
- if (!(!eof && sig == SIGPIPE))
- FATAL_ERROR ((0, 0, _("Child died with signal %d"), sig));
- }
+ FATAL_ERROR ((0, 0, _("Child died with signal %d"),
+ WTERMSIG (wait_status)));
else if (WEXITSTATUS (wait_status) != 0)
ERROR ((0, 0, _("Child returned status %d"),
WEXITSTATUS (wait_status)));

View File

@ -1,32 +0,0 @@
diff -uNr tar-1.23.ORIG//src/create.c tar-1.23/src/create.c
--- tar-1.23.ORIG//src/create.c 2010-04-25 17:36:03.553606076 +0100
+++ tar-1.23/src/create.c 2010-04-25 17:36:16.294605862 +0100
@@ -575,7 +575,10 @@
GNAME_TO_CHARS (tmpname, header->header.gname);
free (tmpname);
- strcpy (header->header.magic, OLDGNU_MAGIC);
+ /* OLDGNU_MAGIC is string with 7 chars + NULL */
+ strncpy (header->header.magic, OLDGNU_MAGIC, sizeof(header->header.magic));
+ strncpy (header->header.version, OLDGNU_MAGIC+sizeof(header->header.magic),
+ sizeof(header->header.version));
header->header.typeflag = type;
finish_header (st, header, -1);
@@ -910,9 +913,13 @@
break;
case OLDGNU_FORMAT:
- case GNU_FORMAT: /*FIXME?*/
- /* Overwrite header->header.magic and header.version in one blow. */
- strcpy (header->header.magic, OLDGNU_MAGIC);
+ case GNU_FORMAT:
+ /* OLDGNU_MAGIC is string with 7 chars + NULL */
+ strncpy (header->header.magic, OLDGNU_MAGIC,
+ sizeof(header->header.magic));
+ strncpy (header->header.version,
+ OLDGNU_MAGIC+sizeof(header->header.magic),
+ sizeof(header->header.version));
break;
case POSIX_FORMAT:

View File

@ -1,177 +0,0 @@
http://bugs.gentoo.org/327641
From b60e56fdb6fd8d82a1f92a4fa7781d9a3184dce1 Mon Sep 17 00:00:00 2001
From: Sergey Poznyakoff <gray@gnu.org.ua>
Date: Sat, 27 Mar 2010 22:02:28 +0200
Subject: [PATCH] Fix dead loop on extracting existing symlinks with the -k option.
* src/extract.c (create_placeholder_file)
(extract_link, extract_symlink)
(extract_node, extract_fifo): Handle all possible
return values from maybe_recoverable. This complements
8f390db92fc. Reported by Ico Doornekamp <bug-tar@zevv.nl>.
---
src/extract.c | 101 +++++++++++++++++++++++++++++++++++++-------------------
2 files changed, 70 insertions(+), 35 deletions(-)
diff --git a/src/extract.c b/src/extract.c
index 32a883f..531654a 100644
--- a/src/extract.c
+++ b/src/extract.c
@@ -888,12 +888,22 @@ create_placeholder_file (char *file_name, bool is_symlink, int *interdir_made)
struct stat st;
while ((fd = open (file_name, O_WRONLY | O_CREAT | O_EXCL, 0)) < 0)
- if (! maybe_recoverable (file_name, interdir_made))
- break;
+ {
+ switch (maybe_recoverable (file_name, interdir_made))
+ {
+ case RECOVER_OK:
+ continue;
+
+ case RECOVER_SKIP:
+ return 0;
+
+ case RECOVER_NO:
+ open_error (file_name);
+ return -1;
+ }
+ }
- if (fd < 0)
- open_error (file_name);
- else if (fstat (fd, &st) != 0)
+ if (fstat (fd, &st) != 0)
{
stat_error (file_name);
close (fd);
@@ -956,7 +966,8 @@ extract_link (char *file_name, int typeflag)
{
int interdir_made = 0;
char const *link_name;
-
+ int rc;
+
link_name = current_stat_info.link_name;
if (! absolute_names_option && contains_dot_dot (link_name))
@@ -996,8 +1007,10 @@ extract_link (char *file_name, int typeflag)
errno = e;
}
- while (maybe_recoverable (file_name, &interdir_made));
+ while ((rc = maybe_recoverable (file_name, &interdir_made)) == RECOVER_OK);
+ if (rc == RECOVER_SKIP)
+ return 0;
if (!(incremental_option && errno == EEXIST))
{
link_error (link_name, file_name);
@@ -1010,7 +1023,6 @@ static int
extract_symlink (char *file_name, int typeflag)
{
#ifdef HAVE_SYMLINK
- int status;
int interdir_made = 0;
if (! absolute_names_option
@@ -1018,15 +1030,22 @@ extract_symlink (char *file_name, int typeflag)
|| contains_dot_dot (current_stat_info.link_name)))
return create_placeholder_file (file_name, true, &interdir_made);
- while ((status = symlink (current_stat_info.link_name, file_name)))
- if (!maybe_recoverable (file_name, &interdir_made))
- break;
-
- if (status == 0)
- set_stat (file_name, &current_stat_info, NULL, 0, 0, SYMTYPE);
- else
- symlink_error (current_stat_info.link_name, file_name);
- return status;
+ while (symlink (current_stat_info.link_name, file_name))
+ switch (maybe_recoverable (file_name, &interdir_made))
+ {
+ case RECOVER_OK:
+ continue;
+
+ case RECOVER_SKIP:
+ return 0;
+
+ case RECOVER_NO:
+ symlink_error (current_stat_info.link_name, file_name);
+ return -1;
+ }
+
+ set_stat (file_name, &current_stat_info, NULL, 0, 0, SYMTYPE);
+ return 0;
#else
static int warned_once;
@@ -1052,16 +1071,23 @@ extract_node (char *file_name, int typeflag)
mode_t invert_permissions =
0 < same_owner_option ? mode & (S_IRWXG | S_IRWXO) : 0;
- do
- status = mknod (file_name, mode ^ invert_permissions,
- current_stat_info.stat.st_rdev);
- while (status && maybe_recoverable (file_name, &interdir_made));
+ while (mknod (file_name, mode ^ invert_permissions,
+ current_stat_info.stat.st_rdev))
+ switch (maybe_recoverable (file_name, &interdir_made))
+ {
+ case RECOVER_OK:
+ continue;
+
+ case RECOVER_SKIP:
+ return 0;
+
+ case RECOVER_NO:
+ mknod_error (file_name);
+ return -1;
+ }
- if (status != 0)
- mknod_error (file_name);
- else
- set_stat (file_name, &current_stat_info, NULL, invert_permissions,
- ARCHIVED_PERMSTATUS, typeflag);
+ set_stat (file_name, &current_stat_info, NULL, invert_permissions,
+ ARCHIVED_PERMSTATUS, typeflag);
return status;
}
#endif
@@ -1077,15 +1103,22 @@ extract_fifo (char *file_name, int typeflag)
0 < same_owner_option ? mode & (S_IRWXG | S_IRWXO) : 0;
while ((status = mkfifo (file_name, mode)) != 0)
- if (!maybe_recoverable (file_name, &interdir_made))
- break;
+ switch (maybe_recoverable (file_name, &interdir_made))
+ {
+ case RECOVER_OK:
+ continue;
+
+ case RECOVER_SKIP:
+ return 0;
+
+ case RECOVER_NO:
+ mkfifo_error (file_name);
+ return -1;
+ }
- if (status == 0)
- set_stat (file_name, &current_stat_info, NULL, invert_permissions,
- ARCHIVED_PERMSTATUS, typeflag);
- else
- mkfifo_error (file_name);
- return status;
+ set_stat (file_name, &current_stat_info, NULL, invert_permissions,
+ ARCHIVED_PERMSTATUS, typeflag);
+ return 0;
}
#endif
--
1.7.1.1

View File

@ -1,27 +0,0 @@
http://bugs.gentoo.org/326785
From 67b4f3519d838c6f16f5b6b63c0b9b8669fb3dd9 Mon Sep 17 00:00:00 2001
From: Sergey Poznyakoff <gray@gnu.org.ua>
Date: Fri, 12 Mar 2010 09:48:46 +0200
Subject: [PATCH] Bugfixes.
* tests/remfiles01.at: Skip if run with root privileges.
---
tests/remfiles01.at | 1 +
2 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/tests/remfiles01.at b/tests/remfiles01.at
index 940fd95..73752b4 100644
--- a/tests/remfiles01.at
+++ b/tests/remfiles01.at
@@ -30,6 +30,7 @@ AT_KEYWORDS([create remove-files remfiles01 gzip])
unset TAR_OPTIONS
AT_CHECK([
+AT_UNPRIVILEGED_PREREQ
AT_GZIP_PREREQ
AT_SORT_PREREQ
--
1.7.1.1

View File

@ -0,0 +1,22 @@
hack until gzip pulls a newer gnulib version
From 66712c23388e93e5c518ebc8515140fa0c807348 Mon Sep 17 00:00:00 2001
From: Eric Blake <eblake@redhat.com>
Date: Thu, 29 Mar 2012 13:30:41 -0600
Subject: [PATCH] stdio: don't assume gets any more
Gnulib intentionally does not have a gets module, and now that C11
and glibc have dropped it, we should be more proactive about warning
any user on a platform that still has a declaration of this dangerous
interface.
--- a/gnu/stdio.in.h
+++ b/gnu/stdio.in.h
@@ -125,7 +125,6 @@
so any use of gets warrants an unconditional warning. Assume it is
always declared, since it is required by C89. */
#undef gets
-_GL_WARN_ON_USE (gets, "gets is a security hole - use fgets instead");
#if @GNULIB_FOPEN@
# if @REPLACE_FOPEN@

View File

@ -0,0 +1,931 @@
https://bugs.gentoo.org/382067
add optional xattr support
--- a/configure.ac
+++ b/configure.ac
@@ -223,6 +223,20 @@ AC_CHECK_TYPE(iconv_t,:,
#endif
])
+AC_ARG_ENABLE(xattr,
+ AC_HELP_STRING([--enable-xattr],
+ [enable Extended Attribute support (disabled by default)]),
+ [xattr_enabled=$enableval],
+ [xattr_enabled=no])
+
+if test "x$xattr_enabled" = xyes; then
+ AC_CHECK_HEADERS(attr/xattr.h)
+ AC_CHECK_FUNCS(getxattr fgetxattr lgetxattr \
+ setxattr fsetxattr lsetxattr \
+ listxattr flistxattr llistxattr,
+ AC_DEFINE(HAVE_XATTRS,1,[Define if we have a working extended attributes]),)
+fi
+
# Gettext.
AM_GNU_GETTEXT([external], [need-formatstring-macros])
AM_GNU_GETTEXT_VERSION([0.16])
--- a/doc/tar.texi
+++ b/doc/tar.texi
@@ -3002,6 +3002,10 @@ mechanism.
Treat all input file or member names literally, do not interpret
escape sequences. @xref{input name quoting}.
+@opsummary{no-xattrs}
+@item --no-xattrs
+Causes @command{tar} not to store and not to extract xattrs. @xref{Attributes}.
+
@opsummary{no-wildcards}
@item --no-wildcards
Do not use wildcards.
@@ -3447,6 +3451,10 @@ Enable or disable warning messages identified by @var{keyword}. The
messages are suppressed if @var{keyword} is prefixed with @samp{no-}.
@xref{warnings}.
+@opsummary{xattrs}
+@item --xattrs
+Causes @command{tar} to store xattrs. @xref{Attributes}.
+
@opsummary{wildcards}
@item --wildcards
Use wildcards when matching member names with patterns.
@@ -8659,6 +8667,8 @@ implementation able to read @samp{ustar} archives will be able to read
most @samp{posix} archives as well, with the only exception that any
additional information (such as long file names etc.) will in such
case be extracted as plain text files along with the files it refers to.
+This is the only format that can store ACLs, SELinux context and extended
+attributes.
This archive format will be the default format for future versions
of @GNUTAR{}.
@@ -9293,6 +9303,20 @@ Same as both @option{--same-permissions} and @option{--same-order}.
This option is deprecated, and will be removed in @GNUTAR{} version 1.23.
+@opindex xattrs
+@item --xattrs
+This option causes @command{tar} to store the current extended attributes in
+the archive.
+
+The @option{--xattrs} option has no equivalent short option name.
+
+@opindex no-xattrs
+@item --no-xattrs
+This option causes @command{tar} not to store the current extended attributes in
+the archive and not to extract any extended attributes in an archive.
+
+The @option{--no-xattrs} option has no equivalent short option name.
+
@end table
@node Portability
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -20,7 +20,7 @@
bin_PROGRAMS = tar
-noinst_HEADERS = arith.h common.h tar.h
+noinst_HEADERS = arith.h common.h tar.h xattrs.h
tar_SOURCES = \
buffer.c\
checkpoint.c\
@@ -42,10 +42,11 @@ tar_SOURCES = \
unlink.c\
update.c\
utf8.c\
- warning.c
+ warning.c\
+ xattrs.c
INCLUDES = -I$(top_srcdir)/gnu -I../ -I../gnu -I$(top_srcdir)/lib -I../lib
LDADD = ../lib/libtar.a ../gnu/libgnu.a $(LIBINTL) $(LIBICONV)
-tar_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) $(LIB_EACCESS)
+tar_LDADD = $(LIBS) $(LDADD) $(LIB_CLOCK_GETTIME) $(LIB_EACCESS)
--- a/src/common.h
+++ b/src/common.h
@@ -253,6 +253,9 @@ GLOBAL int same_owner_option;
/* If positive, preserve permissions when extracting. */
GLOBAL int same_permissions_option;
+/* If positive, save the user and root xattrs. */
+GLOBAL int xattrs_option;
+
/* When set, strip the given number of file name components from the file name
before extracting */
GLOBAL size_t strip_name_components;
@@ -707,6 +710,9 @@ extern char *output_start;
void update_archive (void);
+/* Module attrs.c. */
+#include "xattrs.h"
+
/* Module xheader.c. */
void xheader_decode (struct tar_stat_info *stat);
@@ -727,6 +733,12 @@ bool xheader_string_end (struct xheader *xhdr, char const *keyword);
bool xheader_keyword_deleted_p (const char *kw);
char *xheader_format_name (struct tar_stat_info *st, const char *fmt,
size_t n);
+void xheader_xattr_init (struct tar_stat_info *st);
+void xheader_xattr_free (struct xattr_array *vals, size_t sz);
+void xheader_xattr_copy (const struct tar_stat_info *st,
+ struct xattr_array **vals, size_t *sz);
+void xheader_xattr_add (struct tar_stat_info *st,
+ const char *key, const char *val, size_t len);
/* Module system.c */
--- a/src/create.c
+++ b/src/create.c
@@ -936,6 +936,21 @@ start_header (struct tar_stat_info *st)
GNAME_TO_CHARS (st->gname, header->header.gname);
}
+ if (archive_format == POSIX_FORMAT)
+ {
+ if (xattrs_option > 0)
+ {
+ size_t scan_xattr = 0;
+ struct xattr_array *xattr_map = st->xattr_map;
+
+ while (scan_xattr < st->xattr_map_size)
+ {
+ xheader_store (xattr_map[scan_xattr].xkey, st, &scan_xattr);
+ ++scan_xattr;
+ }
+ }
+ }
+
return header;
}
@@ -1711,6 +1726,11 @@ dump_file0 (struct tar_stat_info *st, char const *name, char const *p)
bool ok;
struct stat final_stat;
+ if (fd == 0)
+ xattrs_xattrs_get (st, p, -1);
+ else
+ xattrs_xattrs_get (st, p, fd);
+
if (is_dir)
{
const char *tag_file_name;
@@ -1829,6 +1849,8 @@ dump_file0 (struct tar_stat_info *st, char const *name, char const *p)
if (NAME_FIELD_SIZE - (archive_format == OLDGNU_FORMAT) < size)
write_long_link (st);
+ xattrs_xattrs_get (st, p, -1);
+
block_ordinal = current_block_ordinal ();
st->stat.st_size = 0; /* force 0 size on symlink */
header = start_header (st);
@@ -1847,11 +1869,20 @@ dump_file0 (struct tar_stat_info *st, char const *name, char const *p)
}
#endif
else if (S_ISCHR (st->stat.st_mode))
- type = CHRTYPE;
+ {
+ type = CHRTYPE;
+ xattrs_xattrs_get (st, p, -1);
+ }
else if (S_ISBLK (st->stat.st_mode))
- type = BLKTYPE;
+ {
+ type = BLKTYPE;
+ xattrs_xattrs_get (st, p, -1);
+ }
else if (S_ISFIFO (st->stat.st_mode))
- type = FIFOTYPE;
+ {
+ type = FIFOTYPE;
+ xattrs_xattrs_get (st, p, -1);
+ }
else if (S_ISSOCK (st->stat.st_mode))
{
WARNOPT (WARN_FILE_IGNORED,
--- a/src/extract.c
+++ b/src/extract.c
@@ -97,6 +97,9 @@ struct delayed_set_stat
/* Directory that the name is relative to. */
int change_dir;
+ /* extended attributes*/
+ size_t xattr_map_size; /* Size of the xattr map */
+ struct xattr_array *xattr_map;
/* Length and contents of name. */
size_t file_name_len;
char file_name[1];
@@ -134,6 +137,9 @@ struct delayed_link
hard-linked together. */
struct string_list *sources;
+ size_t xattr_map_size; /* Size of the xattr map */
+ struct xattr_array *xattr_map;
+
/* The desired target of the desired link. */
char target[1];
};
@@ -335,6 +341,8 @@ set_stat (char const *file_name,
utime_error (file_name);
}
+ xattrs_xattrs_set (st, file_name, typeflag);
+
if (0 < same_owner_option && ! interdir)
{
/* Some systems allow non-root users to give files away. Once this
@@ -431,6 +439,13 @@ delay_set_stat (char const *file_name, struct tar_stat_info const *st,
data->atflag = atflag;
data->after_links = 0;
data->change_dir = chdir_current;
+ if (st)
+ xheader_xattr_copy (st, &data->xattr_map, &data->xattr_map_size);
+ else
+ {
+ data->xattr_map = NULL;
+ data->xattr_map_size = 0;
+ }
strcpy (data->file_name, file_name);
delayed_set_stat_head = data;
if (must_be_dot_or_slash (file_name))
@@ -673,6 +688,31 @@ maybe_recoverable (char *file_name, bool regular, bool *interdir_made)
return RECOVER_NO;
}
+/* Restore stat extended attributes (xattr) for FILE_NAME, using information
+ given in *ST. Restore before extraction because they may affect layout.
+ If not restoring permissions, invert the
+ INVERT_PERMISSIONS bits from the file's current permissions.
+ TYPEFLAG specifies the type of the file.
+ FILE_CREATED indicates set_xattr has created the file */
+static int
+set_xattr (char const *file_name, struct tar_stat_info const *st,
+ mode_t invert_permissions, char typeflag, int *file_created)
+{
+ int status = 0;
+ bool interdir_made = false;
+
+ if ((xattrs_option >= 0) && st->xattr_map_size) {
+ mode_t mode = current_stat_info.stat.st_mode & MODE_RWX & ~ current_umask;
+
+ do
+ status = mknod (file_name, mode ^ invert_permissions, 0);
+ while (status && maybe_recoverable ((char *)file_name, false, &interdir_made));
+ xattrs_xattrs_set (st, file_name, typeflag);
+ *file_created = 1;
+ }
+ return(status);
+}
+
/* Fix the statuses of all directories whose statuses need fixing, and
which are not ancestors of FILE_NAME. If AFTER_LINKS is
nonzero, do this for all such directories; otherwise, stop at the
@@ -733,12 +773,15 @@ apply_nonancestor_delayed_set_stat (char const *file_name, bool after_links)
sb.stat.st_gid = data->gid;
sb.atime = data->atime;
sb.mtime = data->mtime;
+ sb.xattr_map = data->xattr_map;
+ sb.xattr_map_size = data->xattr_map_size;
set_stat (data->file_name, &sb,
-1, current_mode, current_mode_mask,
DIRTYPE, data->interdir, data->atflag);
}
delayed_set_stat_head = data->next;
+ xheader_xattr_free (data->xattr_map, data->xattr_map_size);
free (data);
}
}
@@ -854,6 +897,7 @@ extract_dir (char *file_name, int typeflag)
static int
open_output_file (char const *file_name, int typeflag, mode_t mode,
+ int file_created,
mode_t *current_mode, mode_t *current_mode_mask)
{
int fd;
@@ -864,6 +908,10 @@ open_output_file (char const *file_name, int typeflag, mode_t mode,
? O_TRUNC | (dereference_option ? 0 : O_NOFOLLOW)
: O_EXCL));
+ /* File might be created in set_xattr. So clear O_EXCL to avoid open() failure */
+ if (file_created)
+ openflag = openflag & ~O_EXCL;
+
if (typeflag == CONTTYPE)
{
static int conttype_diagnosed;
@@ -934,6 +982,7 @@ extract_file (char *file_name, int typeflag)
bool interdir_made = false;
mode_t mode = (current_stat_info.stat.st_mode & MODE_RWX
& ~ (0 < same_owner_option ? S_IRWXG | S_IRWXO : 0));
+ mode_t invert_permissions = 0 < same_owner_option ? mode & (S_IRWXG | S_IRWXO) : 0;
mode_t current_mode = 0;
mode_t current_mode_mask = 0;
@@ -950,7 +999,17 @@ extract_file (char *file_name, int typeflag)
}
else
{
+ int file_created = 0;
+ if (set_xattr (file_name, &current_stat_info, invert_permissions,
+ typeflag, &file_created))
+ {
+ skip_member ();
+ open_error (file_name);
+ return 1;
+ }
+
while ((fd = open_output_file (file_name, typeflag, mode,
+ file_created,
&current_mode, &current_mode_mask))
< 0)
{
@@ -1091,6 +1150,7 @@ create_placeholder_file (char *file_name, bool is_symlink, bool *interdir_made)
+ strlen (file_name) + 1);
p->sources->next = 0;
strcpy (p->sources->string, file_name);
+ xheader_xattr_copy (&current_stat_info, &p->xattr_map, &p->xattr_map_size);
strcpy (p->target, current_stat_info.link_name);
h = delayed_set_stat_head;
@@ -1525,6 +1585,8 @@ apply_delayed_links (void)
st1.stat.st_gid = ds->gid;
st1.atime = ds->atime;
st1.mtime = ds->mtime;
+ st1.xattr_map = ds->xattr_map;
+ st1.xattr_map_size = ds->xattr_map_size;
set_stat (source, &st1, -1, 0, 0, SYMTYPE,
false, AT_SYMLINK_NOFOLLOW);
valid_source = source;
@@ -1539,6 +1601,8 @@ apply_delayed_links (void)
sources = next;
}
+ xheader_xattr_free (ds->xattr_map, ds->xattr_map_size);
+
{
struct delayed_link *next = ds->next;
free (ds);
--- a/src/list.c
+++ b/src/list.c
@@ -604,6 +604,8 @@ decode_header (union block *header, struct tar_stat_info *stat_info,
assign_string (&stat_info->gname,
header->header.gname[0] ? header->header.gname : NULL);
+ xheader_xattr_init (stat_info);
+
if (format == OLDGNU_FORMAT && incremental_option)
{
stat_info->atime.tv_sec = TIME_FROM_HEADER (header->oldgnu_header.atime);
--- a/src/tar.c
+++ b/src/tar.c
@@ -304,6 +304,7 @@ enum
NO_UNQUOTE_OPTION,
NO_WILDCARDS_MATCH_SLASH_OPTION,
NO_WILDCARDS_OPTION,
+ NO_XATTR_OPTION,
NULL_OPTION,
NUMERIC_OWNER_OPTION,
OCCURRENCE_OPTION,
@@ -340,7 +341,8 @@ enum
VOLNO_FILE_OPTION,
WARNING_OPTION,
WILDCARDS_MATCH_SLASH_OPTION,
- WILDCARDS_OPTION
+ WILDCARDS_OPTION,
+ XATTR_OPTION
};
const char *argp_program_version = "tar (" PACKAGE_NAME ") " VERSION;
@@ -516,6 +518,10 @@ static struct argp_option options[] = {
{"preserve-order", 's', 0, 0,
N_("sort names to extract to match archive"), GRID+1 },
{"same-order", 0, 0, OPTION_ALIAS, NULL, GRID+1 },
+ {"xattrs", XATTR_OPTION, 0, 0,
+ N_("Save the user/root xattrs to the archive"), GRID+1 },
+ {"no-xattrs", NO_XATTR_OPTION, 0, 0,
+ N_("Don't extract the user/root xattrs from the archive"), GRID+1 },
{"preserve", PRESERVE_OPTION, 0, 0,
N_("same as both -p and -s"), GRID+1 },
{"delay-directory-restore", DELAY_DIRECTORY_RESTORE_OPTION, 0, 0,
@@ -2079,6 +2085,15 @@ parse_opt (int key, char *arg, struct argp_state *state)
same_permissions_option = -1;
break;
+ case XATTR_OPTION:
+ set_archive_format ("posix");
+ xattrs_option = 1;
+ break;
+
+ case NO_XATTR_OPTION:
+ xattrs_option = -1;
+ break;
+
case RECURSION_OPTION:
recursion_option = FNM_LEADING_DIR;
break;
@@ -2461,6 +2476,15 @@ decode_options (int argc, char **argv)
|| subcommand_option != LIST_SUBCOMMAND))
USAGE_ERROR ((0, 0, _("--pax-option can be used only on POSIX archives")));
+ /* star create's non-POSIX typed archives with xattr support, so allow the
+ extra headers */
+ if ((xattrs_option > 0)
+ && archive_format != POSIX_FORMAT
+ && (subcommand_option != EXTRACT_SUBCOMMAND
+ || subcommand_option != DIFF_SUBCOMMAND
+ || subcommand_option != LIST_SUBCOMMAND))
+ USAGE_ERROR ((0, 0, _("--xattrs can be used only on POSIX archives")));
+
/* If ready to unlink hierarchies, so we are for simpler files. */
if (recursive_unlink_option)
old_files_option = UNLINK_FIRST_OLD_FILES;
@@ -2713,6 +2737,7 @@ void
tar_stat_destroy (struct tar_stat_info *st)
{
tar_stat_close (st);
+ xheader_xattr_free (st->xattr_map, st->xattr_map_size);
free (st->orig_file_name);
free (st->file_name);
free (st->link_name);
--- a/src/tar.h
+++ b/src/tar.h
@@ -276,6 +276,14 @@ struct xheader
uintmax_t string_length;
};
+/* Information about xattrs for a file. */
+struct xattr_array
+ {
+ char *xkey;
+ char *xval_ptr;
+ size_t xval_len;
+ };
+
struct tar_stat_info
{
char *orig_file_name; /* name of file read from the archive header */
@@ -287,6 +295,7 @@ struct tar_stat_info
char *uname; /* user name of owner */
char *gname; /* group name of owner */
+
struct stat stat; /* regular filesystem stat */
/* STAT doesn't always have access, data modification, and status
@@ -309,6 +318,9 @@ struct tar_stat_info
size_t sparse_map_size; /* Size of the sparse map */
struct sp_array *sparse_map;
+ size_t xattr_map_size; /* Size of the xattr map */
+ struct xattr_array *xattr_map;
+
/* Extended headers */
struct xheader xhdr;
--- /dev/null
+++ b/src/xattrs.c
@@ -0,0 +1,181 @@
+/* Create a tar archive.
+
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+ Written by James Antill, on 2006-07-27.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by the
+ Free Software Foundation; either version 2, or (at your option) any later
+ version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <system.h>
+
+#include <quotearg.h>
+
+#include "common.h"
+
+
+#ifndef HAVE_ATTR_XATTR_H
+# undef HAVE_XATTRS
+#endif
+
+#ifdef HAVE_ATTR_XATTR_H
+# include <attr/xattr.h>
+#endif
+
+
+void xattrs_xattrs_get (struct tar_stat_info *st, char const *file_name, int fd)
+{
+ if (xattrs_option > 0)
+ { /* get all xattrs ... this include security.* and system.* if
+ available. We filter them here, but we have to filter them
+ in xattrs_xattrs_set() anyway.
+ */
+ static ssize_t xsz = 1024;
+ static char *xatrs = NULL;
+ ssize_t xret = -1;
+
+#ifndef HAVE_XATTRS
+ static int done = 0;
+ if ((xattrs_option > 0) && !done)
+ WARN ((0, 0, _("Xattr support requested, but not available")));
+ done = 1;
+#else
+
+ if (!xatrs) xatrs = xmalloc (xsz);
+
+ while (((fd == -1) ?
+ ((xret = llistxattr (file_name, xatrs, xsz)) == -1) :
+ ((xret = flistxattr (fd, xatrs, xsz)) == -1)) &&
+ (errno == ERANGE))
+ {
+ xsz <<= 1;
+ xatrs = xrealloc (xatrs, xsz);
+ }
+
+ if (xret == -1)
+ call_arg_warn ((fd == -1) ? "llistxattrs" : "flistxattrs", file_name);
+ else
+ {
+ const char *attr = xatrs;
+ static ssize_t asz = 1024;
+ static char *val = NULL;
+
+ if (!val) val = xmalloc (asz);
+
+ while (xret > 0)
+ {
+ size_t len = strlen (attr);
+ ssize_t aret = 0;
+
+ /* Archive all xattrs during creation, decide at extraction time
+ * which ones are of interest/use for the target filesystem. */
+ while (((fd == -1) ?
+ ((aret = lgetxattr (file_name, attr, val, asz)) == -1) :
+ ((aret = fgetxattr (fd, attr, val, asz)) == -1)) &&
+ (errno == ERANGE))
+ {
+ asz <<= 1;
+ val = xrealloc (val, asz);
+ }
+
+ if (aret != -1)
+ xheader_xattr_add (st, attr, val, aret);
+ else if (errno != ENOATTR)
+ call_arg_warn ((fd==-1) ? "lgetxattr" : "fgetxattr", file_name);
+
+ attr += len + 1;
+ xret -= len + 1;
+ }
+ }
+#endif
+ }
+}
+
+static void xattrs__fd_set (struct tar_stat_info const *st,
+ char const *file_name, char typeflag,
+ const char *attr,
+ const char *ptr, size_t len)
+{
+#ifdef HAVE_XATTRS
+ if (ptr)
+ {
+ const char *sysname = "setxattr";
+ int ret = -1;
+
+ if (typeflag != SYMTYPE)
+ ret = setxattr (file_name, attr, ptr, len, 0);
+ else
+ {
+ sysname = "lsetxattr";
+ ret = lsetxattr (file_name, attr, ptr, len, 0);
+ }
+
+ /* do not print warnings when SELinux is disabled */
+ if ((ret == -1) && (errno != EPERM) && (errno != ENOTSUP))
+ call_arg_error (sysname, file_name);
+ }
+#endif
+}
+
+static char *skip_to_ext_fields (char *ptr)
+{
+ ptr += strcspn (ptr, ":,\n"); /* skip tag name. Ie. user/group/default/mask */
+
+ if (*ptr != ':')
+ return (ptr); /* error? no user/group field */
+ ++ptr;
+
+ ptr += strcspn (ptr, ":,\n"); /* skip user/group name */
+
+ if (*ptr != ':')
+ return (ptr); /* error? no perms field */
+ ++ptr;
+
+ ptr += strcspn (ptr, ":,\n"); /* skip perms */
+
+ if (*ptr != ':')
+ return (ptr); /* no extra fields */
+
+ return (ptr);
+}
+
+void xattrs_xattrs_set (struct tar_stat_info const *st,
+ char const *file_name, char typeflag)
+{
+ if ((xattrs_option >= 0) && st->xattr_map_size)
+ {
+ size_t scan = 0;
+
+#ifndef HAVE_XATTRS
+ static int done = 0;
+ if (!done)
+ WARN ((0, 0, _("Xattr support requested, but not available")));
+ done = 1;
+#else
+ while (scan < st->xattr_map_size)
+ {
+ char *keyword = st->xattr_map[scan].xkey;
+
+ /* assert (!memcpy (keyword, "SCHILY.xattr.", strlen("SCHILY.xattr."))); */
+ keyword += strlen ("SCHILY.xattr.");
+
+ xattrs__fd_set (st, file_name, typeflag, keyword,
+ st->xattr_map[scan].xval_ptr,
+ st->xattr_map[scan].xval_len);
+
+ ++scan;
+ }
+#endif
+ }
+}
--- /dev/null
+++ b/src/xattrs.h
@@ -0,0 +1,6 @@
+
+extern void xattrs_xattrs_get (struct tar_stat_info *st,
+ char const *file_name, int fd);
+
+extern void xattrs_xattrs_set (struct tar_stat_info const *st,
+ char const *file_name, char typeflag);
--- a/src/xheader.c
+++ b/src/xheader.c
@@ -460,6 +460,74 @@ xheader_write_global (struct xheader *xhdr)
}
}
+void xheader_xattr_init (struct tar_stat_info *st)
+{
+ st->xattr_map = NULL;
+ st->xattr_map_size = 0;
+}
+
+void xheader_xattr_free (struct xattr_array *xattr_map, size_t xattr_map_size)
+{
+ size_t scan = 0;
+
+ while (scan < xattr_map_size)
+ {
+ free (xattr_map[scan].xkey);
+ free (xattr_map[scan].xval_ptr);
+
+ ++scan;
+ }
+ free (xattr_map);
+}
+
+static void xheader_xattr__add (struct xattr_array **xattr_map,
+ size_t *xattr_map_size,
+ const char *key, const char *val, size_t len)
+{
+ size_t pos = (*xattr_map_size)++;
+
+ *xattr_map = xrealloc (*xattr_map,
+ *xattr_map_size * sizeof (struct xattr_array));
+ (*xattr_map)[pos].xkey = xstrdup (key);
+ (*xattr_map)[pos].xval_ptr = xmemdup (val, len + 1);
+ (*xattr_map)[pos].xval_len = len;
+}
+
+void xheader_xattr_add (struct tar_stat_info *st,
+ const char *key, const char *val, size_t len)
+{
+ size_t klen = strlen (key);
+ char *xkey = xmalloc (strlen("SCHILY.xattr.") + klen + 1);
+ char *tmp = xkey;
+
+ tmp = stpcpy (tmp, "SCHILY.xattr.");
+ tmp = stpcpy (tmp, key);
+
+ xheader_xattr__add (&st->xattr_map, &st->xattr_map_size, xkey, val, len);
+
+ free (xkey);
+}
+
+void xheader_xattr_copy (const struct tar_stat_info *st,
+ struct xattr_array **xattr_map, size_t *xattr_map_size)
+{
+ size_t scan = 0;
+
+ *xattr_map = NULL;
+ *xattr_map_size = 0;
+
+ while (scan < st->xattr_map_size)
+ {
+ char *key = st->xattr_map[scan].xkey;
+ char *val = st->xattr_map[scan].xval_ptr;
+ size_t len = st->xattr_map[scan].xval_len;
+
+ xheader_xattr__add (xattr_map, xattr_map_size, key, val, len);
+
+ ++scan;
+ }
+}
+
/* General Interface */
@@ -473,6 +541,7 @@ struct xhdr_tab
struct xheader *, void const *data);
void (*decoder) (struct tar_stat_info *, char const *, char const *, size_t);
int flags;
+ bool prefix;
};
/* This declaration must be extern, because ISO C99 section 6.9.2
@@ -489,8 +558,17 @@ locate_handler (char const *keyword)
struct xhdr_tab const *p;
for (p = xhdr_tab; p->keyword; p++)
- if (strcmp (p->keyword, keyword) == 0)
- return p;
+ if (p->prefix)
+ {
+ if (strncmp (p->keyword, keyword, strlen(p->keyword)) == 0)
+ return p;
+ }
+ else
+ {
+ if (strcmp (p->keyword, keyword) == 0)
+ return p;
+ }
+
return NULL;
}
@@ -500,7 +578,7 @@ xheader_protected_pattern_p (const char *pattern)
struct xhdr_tab const *p;
for (p = xhdr_tab; p->keyword; p++)
- if ((p->flags & XHDR_PROTECTED) && fnmatch (pattern, p->keyword, 0) == 0)
+ if (!p->prefix && (p->flags & XHDR_PROTECTED) && fnmatch (pattern, p->keyword, 0) == 0)
return true;
return false;
}
@@ -511,7 +589,7 @@ xheader_protected_keyword_p (const char *keyword)
struct xhdr_tab const *p;
for (p = xhdr_tab; p->keyword; p++)
- if ((p->flags & XHDR_PROTECTED) && strcmp (p->keyword, keyword) == 0)
+ if (!p->prefix && (p->flags & XHDR_PROTECTED) && strcmp (p->keyword, keyword) == 0)
return true;
return false;
}
@@ -1470,6 +1548,27 @@ volume_filename_decoder (struct tar_stat_info *st,
}
static void
+xattr_coder (struct tar_stat_info const *st , char const *keyword,
+ struct xheader *xhdr, void const *data)
+{
+ struct xattr_array *xattr_map = st->xattr_map;
+ const size_t *off = data;
+ xheader_print_n (xhdr, keyword,
+ xattr_map[*off].xval_ptr, xattr_map[*off].xval_len);
+}
+
+static void
+xattr_decoder (struct tar_stat_info *st,
+ char const *keyword, char const *arg, size_t size)
+{
+ char *xstr = NULL;
+
+ xstr = xmemdup (arg, size + 1);
+ xheader_xattr_add (st, keyword + strlen("SCHILY.xattr."), xstr, size);
+ free (xstr);
+}
+
+static void
sparse_major_coder (struct tar_stat_info const *st, char const *keyword,
struct xheader *xhdr, void const *data)
{
@@ -1506,53 +1605,53 @@ sparse_minor_decoder (struct tar_stat_info *st,
}
struct xhdr_tab const xhdr_tab[] = {
- { "atime", atime_coder, atime_decoder, 0 },
- { "comment", dummy_coder, dummy_decoder, 0 },
- { "charset", dummy_coder, dummy_decoder, 0 },
- { "ctime", ctime_coder, ctime_decoder, 0 },
- { "gid", gid_coder, gid_decoder, 0 },
- { "gname", gname_coder, gname_decoder, 0 },
- { "linkpath", linkpath_coder, linkpath_decoder, 0 },
- { "mtime", mtime_coder, mtime_decoder, 0 },
- { "path", path_coder, path_decoder, 0 },
- { "size", size_coder, size_decoder, 0 },
- { "uid", uid_coder, uid_decoder, 0 },
- { "uname", uname_coder, uname_decoder, 0 },
+ { "atime", atime_coder, atime_decoder, 0, false },
+ { "comment", dummy_coder, dummy_decoder, 0, false },
+ { "charset", dummy_coder, dummy_decoder, 0, false },
+ { "ctime", ctime_coder, ctime_decoder, 0, false },
+ { "gid", gid_coder, gid_decoder, 0, false },
+ { "gname", gname_coder, gname_decoder, 0, false },
+ { "linkpath", linkpath_coder, linkpath_decoder, 0, false },
+ { "mtime", mtime_coder, mtime_decoder, 0, false },
+ { "path", path_coder, path_decoder, 0, false },
+ { "size", size_coder, size_decoder, 0, false },
+ { "uid", uid_coder, uid_decoder, 0, false },
+ { "uname", uname_coder, uname_decoder, 0, false },
/* Sparse file handling */
{ "GNU.sparse.name", path_coder, path_decoder,
- XHDR_PROTECTED },
+ XHDR_PROTECTED, false },
{ "GNU.sparse.major", sparse_major_coder, sparse_major_decoder,
- XHDR_PROTECTED },
+ XHDR_PROTECTED, false },
{ "GNU.sparse.minor", sparse_minor_coder, sparse_minor_decoder,
- XHDR_PROTECTED },
+ XHDR_PROTECTED, false },
{ "GNU.sparse.realsize", sparse_size_coder, sparse_size_decoder,
- XHDR_PROTECTED },
+ XHDR_PROTECTED, false },
{ "GNU.sparse.numblocks", sparse_numblocks_coder, sparse_numblocks_decoder,
- XHDR_PROTECTED },
+ XHDR_PROTECTED, false },
/* tar 1.14 - 1.15.90 keywords. */
{ "GNU.sparse.size", sparse_size_coder, sparse_size_decoder,
- XHDR_PROTECTED },
+ XHDR_PROTECTED, false },
/* tar 1.14 - 1.15.1 keywords. Multiple instances of these appeared in 'x'
headers, and each of them was meaningful. It confilcted with POSIX specs,
which requires that "when extended header records conflict, the last one
given in the header shall take precedence." */
{ "GNU.sparse.offset", sparse_offset_coder, sparse_offset_decoder,
- XHDR_PROTECTED },
+ XHDR_PROTECTED, false },
{ "GNU.sparse.numbytes", sparse_numbytes_coder, sparse_numbytes_decoder,
- XHDR_PROTECTED },
+ XHDR_PROTECTED, false },
/* tar 1.15.90 keyword, introduced to remove the above-mentioned conflict. */
{ "GNU.sparse.map", NULL /* Unused, see pax_dump_header() */,
- sparse_map_decoder, 0 },
+ sparse_map_decoder, 0, false },
{ "GNU.dumpdir", dumpdir_coder, dumpdir_decoder,
- XHDR_PROTECTED },
+ XHDR_PROTECTED, false },
/* Keeps the tape/volume label. May be present only in the global headers.
Equivalent to GNUTYPE_VOLHDR. */
{ "GNU.volume.label", volume_label_coder, volume_label_decoder,
- XHDR_PROTECTED | XHDR_GLOBAL },
+ XHDR_PROTECTED | XHDR_GLOBAL, false },
/* These may be present in a first global header of the archive.
They provide the same functionality as GNUTYPE_MULTIVOL header.
@@ -1561,11 +1660,14 @@ struct xhdr_tab const xhdr_tab[] = {
GNU.volume.offset keeps the offset of the start of this volume,
otherwise kept in oldgnu_header.offset. */
{ "GNU.volume.filename", volume_label_coder, volume_filename_decoder,
- XHDR_PROTECTED | XHDR_GLOBAL },
+ XHDR_PROTECTED | XHDR_GLOBAL, false },
{ "GNU.volume.size", volume_size_coder, volume_size_decoder,
- XHDR_PROTECTED | XHDR_GLOBAL },
+ XHDR_PROTECTED | XHDR_GLOBAL, false },
{ "GNU.volume.offset", volume_offset_coder, volume_offset_decoder,
- XHDR_PROTECTED | XHDR_GLOBAL },
+ XHDR_PROTECTED | XHDR_GLOBAL, false },
+
+ /* xattrs use the star format. note we only save some variants... */
+ { "SCHILY.xattr", xattr_coder, xattr_decoder, 0, true },
- { NULL, NULL, NULL, 0 }
+ { NULL, NULL, NULL, 0, false }
};

View File

@ -1,70 +0,0 @@
# Copyright 1999-2010 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Header: /var/cvsroot/gentoo-x86/app-arch/tar/tar-1.23-r4.ebuild,v 1.1 2010/07/19 21:52:44 vapier Exp $
EAPI="2"
inherit flag-o-matic eutils
DESCRIPTION="Use this to make tarballs :)"
HOMEPAGE="http://www.gnu.org/software/tar/"
SRC_URI="http://ftp.gnu.org/gnu/tar/${P}.tar.bz2
ftp://alpha.gnu.org/gnu/tar/${P}.tar.bz2
mirror://gnu/tar/${P}.tar.bz2"
LICENSE="GPL-3"
SLOT="0"
KEYWORDS="alpha amd64 arm hppa ia64 m68k mips ppc ppc64 s390 sh sparc x86 ~x86-fbsd"
IUSE="nls static userland_GNU"
RDEPEND=""
DEPEND="${RDEPEND}
nls? ( >=sys-devel/gettext-0.10.35 )"
src_prepare() {
epatch "${FILESDIR}"/${P}-revert-pipe.patch #309001
epatch "${FILESDIR}"/${P}-strncpy.patch #317139
epatch "${FILESDIR}"/${P}-symlink-k-hang.patch #327641
epatch "${FILESDIR}"/${P}-tests.patch #326785
if ! use userland_GNU ; then
sed -i \
-e 's:/backup\.sh:/gbackup.sh:' \
scripts/{backup,dump-remind,restore}.in \
|| die "sed non-GNU"
fi
}
src_configure() {
local myconf
use static && append-ldflags -static
use userland_GNU || myconf="--program-prefix=g"
# Work around bug in sandbox #67051
gl_cv_func_chown_follows_symlink=yes \
econf \
--enable-backup-scripts \
--bindir=/bin \
--libexecdir=/usr/sbin \
$(use_enable nls) \
${myconf}
}
src_install() {
local p=""
use userland_GNU || p=g
emake DESTDIR="${D}" install || die "make install failed"
if [[ -z ${p} ]] ; then
# a nasty yet required piece of baggage
exeinto /etc
doexe "${FILESDIR}"/rmt || die
fi
dodoc AUTHORS ChangeLog* NEWS README* THANKS
newman "${FILESDIR}"/tar.1 ${p}tar.1
mv "${D}"/usr/sbin/${p}backup{,-tar}
mv "${D}"/usr/sbin/${p}restore{,-tar}
rm -f "${D}"/usr/$(get_libdir)/charset.alias
}

View File

@ -0,0 +1,76 @@
# Copyright 1999-2012 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Header: /var/cvsroot/gentoo-x86/app-arch/tar/tar-1.26-r1.ebuild,v 1.7 2012/11/06 03:19:17 vapier Exp $
EAPI="3"
inherit flag-o-matic eutils autotools
DESCRIPTION="Use this to make tarballs :)"
HOMEPAGE="http://www.gnu.org/software/tar/"
SRC_URI="mirror://gnu/tar/${P}.tar.bz2
mirror://gnu-alpha/tar/${P}.tar.bz2"
LICENSE="GPL-3"
SLOT="0"
KEYWORDS="alpha amd64 arm hppa ia64 m68k mips ppc ppc64 s390 sh sparc x86 ~ppc-aix ~x86-fbsd ~x64-freebsd ~x86-freebsd ~hppa-hpux ~ia64-hpux ~x86-interix ~amd64-linux ~ia64-linux ~x86-linux ~ppc-macos ~x64-macos ~x86-macos ~m68k-mint ~sparc-solaris ~sparc64-solaris ~x64-solaris ~x86-solaris"
IUSE="minimal nls static userland_GNU xattr"
RDEPEND="xattr? ( sys-apps/attr )"
DEPEND="${RDEPEND}
nls? ( >=sys-devel/gettext-0.10.35 )"
src_prepare() {
epatch "${FILESDIR}"/${P}-xattr.patch #382067
epatch "${FILESDIR}"/${P}-no-gets.patch
eautoreconf
if ! use userland_GNU ; then
sed -i \
-e 's:/backup\.sh:/gbackup.sh:' \
scripts/{backup,dump-remind,restore}.in \
|| die "sed non-GNU"
fi
}
src_configure() {
use static && append-ldflags -static
FORCE_UNSAFE_CONFIGURE=1 \
econf \
--enable-backup-scripts \
--bindir="${EPREFIX}"/bin \
--libexecdir="${EPREFIX}"/usr/sbin \
$(usex userland_GNU "" "--program-prefix=g") \
$(use_enable nls) \
$(use_enable xattr)
}
src_install() {
emake DESTDIR="${D}" install || die
local p=$(usex userland_GNU "" "g")
if [[ -z ${p} ]] ; then
# a nasty yet required piece of baggage
exeinto /etc
doexe "${FILESDIR}"/rmt || die
fi
# autoconf looks for gtar before tar (in configure scripts), hence
# in Prefix it is important that it is there, otherwise, a gtar from
# the host system (FreeBSD, Solaris, Darwin) will be found instead
# of the Prefix provided (GNU) tar
if use prefix ; then
dosym tar /bin/gtar
fi
dodoc AUTHORS ChangeLog* NEWS README* THANKS
newman "${FILESDIR}"/tar.1 ${p}tar.1
mv "${ED}"/usr/sbin/${p}backup{,-tar}
mv "${ED}"/usr/sbin/${p}restore{,-tar}
if use minimal ; then
find "${ED}"/etc "${ED}"/*bin/ "${ED}"/usr/*bin/ \
-type f -a '!' '(' -name tar -o -name ${p}tar ')' \
-delete
fi
}