- support for "lustre.*" extended attributes (#561855)

This commit is contained in:
Kamil Dudka 2010-02-20 13:02:03 +00:00
parent b0701b539d
commit d2ac7340c6
2 changed files with 223 additions and 138 deletions

View File

@ -24,7 +24,7 @@ index 762f8e4..c442489 100644
AC_CHECK_DECLS([getgrgid],,, [#include <grp.h>]) AC_CHECK_DECLS([getgrgid],,, [#include <grp.h>])
AC_CHECK_DECLS([getpwuid],,, [#include <pwd.h>]) AC_CHECK_DECLS([getpwuid],,, [#include <pwd.h>])
AC_CHECK_DECLS([time],,, [#include <time.h>]) AC_CHECK_DECLS([time],,, [#include <time.h>])
@@ -203,6 +209,7 @@ AC_DEFINE_UNQUOTED(DEFAULT_QUOTING_STYLE @@ -203,6 +209,7 @@ AC_DEFINE_UNQUOTED(DEFAULT_QUOTING_STYLE, $DEFAULT_QUOTING_STYLE,
# Iconv # Iconv
AM_ICONV AM_ICONV
AC_CHECK_HEADERS(iconv.h) AC_CHECK_HEADERS(iconv.h)
@ -50,10 +50,11 @@ index 762f8e4..c442489 100644
# Gettext. # Gettext.
AM_GNU_GETTEXT([external], [need-formatstring-macros]) AM_GNU_GETTEXT([external], [need-formatstring-macros])
AM_GNU_GETTEXT_VERSION([0.16]) AM_GNU_GETTEXT_VERSION([0.16])
diff -urNp tar-1.22-orig/doc/tar.texi tar-1.22/doc/tar.texi diff --git a/doc/tar.texi b/doc/tar.texi
--- tar-1.22-orig/doc/tar.texi 2009-03-05 08:04:13.000000000 +0100 index 7d8952b..e9c5693 100644
+++ tar-1.22/doc/tar.texi 2009-11-23 14:48:00.000000000 +0100 --- a/doc/tar.texi
@@ -2345,6 +2345,10 @@ Normally when creating an archive, @comm +++ b/doc/tar.texi
@@ -2345,6 +2345,10 @@ Normally when creating an archive, @command{tar} strips an initial
@samp{/} from member names. This option disables that behavior. @samp{/} from member names. This option disables that behavior.
@xref{absolute}. @xref{absolute}.
@ -64,7 +65,7 @@ diff -urNp tar-1.22-orig/doc/tar.texi tar-1.22/doc/tar.texi
@opsummary{after-date} @opsummary{after-date}
@item --after-date @item --after-date
@@ -2844,6 +2848,10 @@ contents have changed (as opposed to jus @@ -2844,6 +2848,10 @@ contents have changed (as opposed to just @option{--newer}, which will
also back up files for which any status information has also back up files for which any status information has
changed). @xref{after}. changed). @xref{after}.
@ -75,7 +76,7 @@ diff -urNp tar-1.22-orig/doc/tar.texi tar-1.22/doc/tar.texi
@opsummary{no-anchored} @opsummary{no-anchored}
@item --no-anchored @item --no-anchored
An exclude pattern can match any subsequence of the name's components. An exclude pattern can match any subsequence of the name's components.
@@ -2919,11 +2927,21 @@ When extracting an archive, subtract the @@ -2919,11 +2927,21 @@ When extracting an archive, subtract the user's umask from files from
the permissions specified in the archive. This is the default behavior the permissions specified in the archive. This is the default behavior
for ordinary users. for ordinary users.
@ -97,7 +98,7 @@ diff -urNp tar-1.22-orig/doc/tar.texi tar-1.22/doc/tar.texi
@opsummary{no-wildcards} @opsummary{no-wildcards}
@item --no-wildcards @item --no-wildcards
Do not use wildcards. Do not use wildcards.
@@ -3151,6 +3169,11 @@ locations. Usually @command{tar} determ @@ -3151,6 +3169,11 @@ locations. Usually @command{tar} determines automatically whether
the archive can be seeked or not. This option is intended for use the archive can be seeked or not. This option is intended for use
in cases when such recognition fails. in cases when such recognition fails.
@ -109,7 +110,7 @@ diff -urNp tar-1.22-orig/doc/tar.texi tar-1.22/doc/tar.texi
@opsummary{show-defaults} @opsummary{show-defaults}
@item --show-defaults @item --show-defaults
@@ -3349,6 +3372,11 @@ Used in conjunction with @option{--multi @@ -3349,6 +3372,11 @@ Used in conjunction with @option{--multi-volume}. @command{tar} will
keep track of which volume of a multi-volume archive it is working in keep track of which volume of a multi-volume archive it is working in
@var{file}. @xref{volno-file}. @var{file}. @xref{volno-file}.
@ -121,7 +122,7 @@ diff -urNp tar-1.22-orig/doc/tar.texi tar-1.22/doc/tar.texi
@opsummary{wildcards} @opsummary{wildcards}
@item --wildcards @item --wildcards
Use wildcards when matching member names with patterns. Use wildcards when matching member names with patterns.
@@ -8350,6 +8378,8 @@ implementation able to read @samp{ustar} @@ -8350,6 +8378,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 most @samp{posix} archives as well, with the only exception that any
additional information (such as long file names etc.) will in such 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. case be extracted as plain text files along with the files it refers to.
@ -130,7 +131,7 @@ diff -urNp tar-1.22-orig/doc/tar.texi tar-1.22/doc/tar.texi
This archive format will be the default format for future versions This archive format will be the default format for future versions
of @GNUTAR{}. of @GNUTAR{}.
@@ -8902,6 +8932,51 @@ Same as both @option{--same-permissions} @@ -8902,6 +8932,51 @@ Same as both @option{--same-permissions} and @option{--same-order}.
This option is deprecated, and will be removed in @GNUTAR{} version 1.23. This option is deprecated, and will be removed in @GNUTAR{} version 1.23.
@ -182,9 +183,37 @@ diff -urNp tar-1.22-orig/doc/tar.texi tar-1.22/doc/tar.texi
@end table @end table
@node Portability @node Portability
diff -urNp tar-1.22-orig/src/common.h tar-1.22/src/common.h diff --git a/src/Makefile.am b/src/Makefile.am
--- tar-1.22-orig/src/common.h 2008-11-30 13:30:29.000000000 +0100 index c22a568..8755333 100644
+++ tar-1.22/src/common.h 2009-11-23 14:48:00.000000000 +0100 --- 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\
@@ -39,10 +39,11 @@ tar_SOURCES = \
tar.c\
transform.c\
update.c\
- utf8.c
+ utf8.c\
+ xattrs.c
INCLUDES = -I$(top_srcdir)/lib -I../ -I../lib
LDADD = ../lib/libtar.a $(LIBINTL) $(LIBICONV)
-tar_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME)
+tar_LDADD = $(LIBS) $(LDADD) $(LIB_CLOCK_GETTIME)
diff --git a/src/common.h b/src/common.h
index 9897b46..5318279 100644
--- a/src/common.h
+++ b/src/common.h
@@ -248,6 +248,15 @@ GLOBAL int same_owner_option; @@ -248,6 +248,15 @@ GLOBAL int same_owner_option;
/* If positive, preserve permissions when extracting. */ /* If positive, preserve permissions when extracting. */
GLOBAL int same_permissions_option; GLOBAL int same_permissions_option;
@ -211,7 +240,7 @@ diff -urNp tar-1.22-orig/src/common.h tar-1.22/src/common.h
/* Module xheader.c. */ /* Module xheader.c. */
void xheader_init (struct xheader *xhdr); void xheader_init (struct xheader *xhdr);
@@ -694,6 +706,12 @@ bool xheader_string_end (struct xheader @@ -694,6 +706,12 @@ bool xheader_string_end (struct xheader *xhdr, char const *keyword);
bool xheader_keyword_deleted_p (const char *kw); bool xheader_keyword_deleted_p (const char *kw);
char *xheader_format_name (struct tar_stat_info *st, const char *fmt, char *xheader_format_name (struct tar_stat_info *st, const char *fmt,
size_t n); size_t n);
@ -224,9 +253,10 @@ diff -urNp tar-1.22-orig/src/common.h tar-1.22/src/common.h
/* Module system.c */ /* Module system.c */
diff -urNp tar-1.22-orig/src/create.c tar-1.22/src/create.c diff --git a/src/create.c b/src/create.c
--- tar-1.22-orig/src/create.c 2008-10-30 11:58:04.000000000 +0100 index a925160..29a6fd8 100644
+++ tar-1.22/src/create.c 2009-11-23 14:48:33.000000000 +0100 --- a/src/create.c
+++ b/src/create.c
@@ -24,6 +24,7 @@ @@ -24,6 +24,7 @@
#include <quotearg.h> #include <quotearg.h>
@ -254,7 +284,7 @@ diff -urNp tar-1.22-orig/src/create.c tar-1.22/src/create.c
+ { + {
+ size_t scan_xattr = 0; + size_t scan_xattr = 0;
+ struct xattr_array *xattr_map = st->xattr_map; + struct xattr_array *xattr_map = st->xattr_map;
+ +
+ while (scan_xattr < st->xattr_map_size) + while (scan_xattr < st->xattr_map_size)
+ { + {
+ xheader_store (xattr_map[scan_xattr].xkey, st, &scan_xattr); + xheader_store (xattr_map[scan_xattr].xkey, st, &scan_xattr);
@ -266,7 +296,7 @@ diff -urNp tar-1.22-orig/src/create.c tar-1.22/src/create.c
return header; return header;
} }
@@ -1578,6 +1603,10 @@ dump_file0 (struct tar_stat_info *st, co @@ -1578,6 +1603,10 @@ dump_file0 (struct tar_stat_info *st, const char *p,
} }
} }
@ -277,7 +307,7 @@ diff -urNp tar-1.22-orig/src/create.c tar-1.22/src/create.c
if (is_dir) if (is_dir)
{ {
const char *tag_file_name; const char *tag_file_name;
@@ -1709,6 +1738,9 @@ dump_file0 (struct tar_stat_info *st, co @@ -1709,6 +1738,9 @@ dump_file0 (struct tar_stat_info *st, const char *p,
if (NAME_FIELD_SIZE - (archive_format == OLDGNU_FORMAT) < size) if (NAME_FIELD_SIZE - (archive_format == OLDGNU_FORMAT) < size)
write_long_link (st); write_long_link (st);
@ -287,9 +317,10 @@ diff -urNp tar-1.22-orig/src/create.c tar-1.22/src/create.c
block_ordinal = current_block_ordinal (); block_ordinal = current_block_ordinal ();
st->stat.st_size = 0; /* force 0 size on symlink */ st->stat.st_size = 0; /* force 0 size on symlink */
header = start_header (st); header = start_header (st);
diff -urNp tar-1.22-orig/src/extract.c tar-1.22/src/extract.c diff --git a/src/extract.c b/src/extract.c
--- tar-1.22-orig/src/extract.c 2008-10-30 15:10:28.000000000 +0100 index 6d70398..ac33df2 100644
+++ tar-1.22/src/extract.c 2009-11-23 14:48:33.000000000 +0100 --- a/src/extract.c
+++ b/src/extract.c
@@ -69,6 +69,13 @@ struct delayed_set_stat @@ -69,6 +69,13 @@ struct delayed_set_stat
mode_t invert_permissions; mode_t invert_permissions;
enum permstatus permstatus; enum permstatus permstatus;
@ -310,16 +341,16 @@ diff -urNp tar-1.22-orig/src/extract.c tar-1.22/src/extract.c
+ /* SELinux context */ + /* SELinux context */
+ char *cntx_name; + char *cntx_name;
+ +
+ /* ACLs */ + /* ACLs */
+ char *acls_a_ptr; + char *acls_a_ptr;
+ size_t acls_a_len; + size_t acls_a_len;
+ char *acls_d_ptr; + char *acls_d_ptr;
+ size_t acls_d_len; + size_t acls_d_len;
+ +
+ size_t xattr_map_size; /* Size of the xattr map */ + size_t xattr_map_size; /* Size of the xattr map */
+ struct xattr_array *xattr_map; + struct xattr_array *xattr_map;
+ +
/* The desired target of the desired link. */ /* The desired target of the desired link. */
char target[1]; char target[1];
}; };
@ -334,7 +365,7 @@ diff -urNp tar-1.22-orig/src/extract.c tar-1.22/src/extract.c
if (0 < same_owner_option && permstatus != INTERDIR_PERMSTATUS) if (0 < same_owner_option && permstatus != INTERDIR_PERMSTATUS)
{ {
/* When lchown exists, it should be used to change the attributes of /* When lchown exists, it should be used to change the attributes of
@@ -352,6 +375,29 @@ delay_set_stat (char const *file_name, s @@ -352,6 +375,29 @@ delay_set_stat (char const *file_name, struct tar_stat_info const *st,
data->invert_permissions = invert_permissions; data->invert_permissions = invert_permissions;
data->permstatus = permstatus; data->permstatus = permstatus;
data->after_links = 0; data->after_links = 0;
@ -364,7 +395,39 @@ diff -urNp tar-1.22-orig/src/extract.c tar-1.22/src/extract.c
strcpy (data->file_name, file_name); strcpy (data->file_name, file_name);
delayed_set_stat_head = data; delayed_set_stat_head = data;
} }
@@ -599,11 +645,22 @@ apply_nonancestor_delayed_set_stat (char @@ -546,6 +592,31 @@ maybe_recoverable (char *file_name, int *interdir_made)
}
}
+/* 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;
+ int interdir_made = 0;
+
+ 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, &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
@@ -599,11 +670,22 @@ apply_nonancestor_delayed_set_stat (char const *file_name, bool after_links)
sb.stat.st_gid = data->gid; sb.stat.st_gid = data->gid;
sb.atime = data->atime; sb.atime = data->atime;
sb.mtime = data->mtime; sb.mtime = data->mtime;
@ -387,7 +450,47 @@ diff -urNp tar-1.22-orig/src/extract.c tar-1.22/src/extract.c
free (data); free (data);
} }
} }
@@ -882,6 +939,13 @@ create_placeholder_file (char *file_name @@ -696,7 +778,7 @@ extract_dir (char *file_name, int typeflag)
static int
-open_output_file (char *file_name, int typeflag, mode_t mode)
+open_output_file (char *file_name, int typeflag, mode_t mode, int file_created)
{
int fd;
int openflag = (O_WRONLY | O_BINARY | O_CREAT
@@ -704,6 +786,10 @@ open_output_file (char *file_name, int typeflag, mode_t mode)
? O_TRUNC
: 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 O_CTG
/* Contiguous files (on the Masscomp) have to specify the size in
the open call that creates them. */
@@ -760,8 +846,18 @@ 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;
+ }
+
do
- fd = open_output_file (file_name, typeflag, mode ^ invert_permissions);
+ fd = open_output_file (file_name, typeflag, mode ^ invert_permissions,
+ file_created);
while (fd < 0 && maybe_recoverable (file_name, &interdir_made));
if (fd < 0)
@@ -882,6 +978,13 @@ create_placeholder_file (char *file_name, bool is_symlink, int *interdir_made)
+ strlen (file_name) + 1); + strlen (file_name) + 1);
p->sources->next = 0; p->sources->next = 0;
strcpy (p->sources->string, file_name); strcpy (p->sources->string, file_name);
@ -401,7 +504,7 @@ diff -urNp tar-1.22-orig/src/extract.c tar-1.22/src/extract.c
strcpy (p->target, current_stat_info.link_name); strcpy (p->target, current_stat_info.link_name);
h = delayed_set_stat_head; h = delayed_set_stat_head;
@@ -1288,6 +1352,13 @@ apply_delayed_links (void) @@ -1288,6 +1391,13 @@ apply_delayed_links (void)
struct tar_stat_info st1; struct tar_stat_info st1;
st1.stat.st_uid = ds->uid; st1.stat.st_uid = ds->uid;
st1.stat.st_gid = ds->gid; st1.stat.st_gid = ds->gid;
@ -415,7 +518,7 @@ diff -urNp tar-1.22-orig/src/extract.c tar-1.22/src/extract.c
set_stat (source, &st1, NULL, 0, 0, SYMTYPE); set_stat (source, &st1, NULL, 0, 0, SYMTYPE);
valid_source = source; valid_source = source;
} }
@@ -1301,6 +1372,9 @@ apply_delayed_links (void) @@ -1301,6 +1411,9 @@ apply_delayed_links (void)
sources = next; sources = next;
} }
@ -425,10 +528,11 @@ diff -urNp tar-1.22-orig/src/extract.c tar-1.22/src/extract.c
{ {
struct delayed_link *next = ds->next; struct delayed_link *next = ds->next;
free (ds); free (ds);
diff -urNp tar-1.22-orig/src/list.c tar-1.22/src/list.c diff --git a/src/list.c b/src/list.c
--- tar-1.22-orig/src/list.c 2009-11-23 14:47:03.000000000 +0100 index c060701..abb94bf 100644
+++ tar-1.22/src/list.c 2009-11-23 14:48:00.000000000 +0100 --- a/src/list.c
@@ -568,6 +568,13 @@ decode_header (union block *header, stru +++ b/src/list.c
@@ -568,6 +568,13 @@ decode_header (union block *header, struct tar_stat_info *stat_info,
assign_string (&stat_info->gname, assign_string (&stat_info->gname,
header->header.gname[0] ? header->header.gname : NULL); header->header.gname[0] ? header->header.gname : NULL);
@ -438,39 +542,14 @@ diff -urNp tar-1.22-orig/src/list.c tar-1.22/src/list.c
+ stat_info->acls_d_len = 0; + stat_info->acls_d_len = 0;
+ stat_info->cntx_name = NULL; + stat_info->cntx_name = NULL;
+ xheader_xattr_init(stat_info); + xheader_xattr_init(stat_info);
+ +
if (format == OLDGNU_FORMAT && incremental_option) if (format == OLDGNU_FORMAT && incremental_option)
{ {
stat_info->atime.tv_sec = TIME_FROM_HEADER (header->oldgnu_header.atime); stat_info->atime.tv_sec = TIME_FROM_HEADER (header->oldgnu_header.atime);
diff -urNp tar-1.22-orig/src/Makefile.am tar-1.22/src/Makefile.am diff --git a/src/tar.c b/src/tar.c
--- tar-1.22-orig/src/Makefile.am 2007-10-29 18:53:06.000000000 +0100 index dbffc2a..510350b 100644
+++ tar-1.22/src/Makefile.am 2009-11-23 14:48:00.000000000 +0100 --- a/src/tar.c
@@ -20,7 +20,7 @@ +++ b/src/tar.c
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\
@@ -39,10 +39,11 @@ tar_SOURCES = \
tar.c\
transform.c\
update.c\
- utf8.c
+ utf8.c\
+ xattrs.c
INCLUDES = -I$(top_srcdir)/lib -I../ -I../lib
LDADD = ../lib/libtar.a $(LIBINTL) $(LIBICONV)
-tar_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME)
+tar_LDADD = $(LIBS) $(LDADD) $(LIB_CLOCK_GETTIME)
diff -urNp tar-1.22-orig/src/tar.c tar-1.22/src/tar.c
--- tar-1.22-orig/src/tar.c 2009-03-05 08:04:13.000000000 +0100
+++ tar-1.22/src/tar.c 2009-11-23 14:48:00.000000000 +0100
@@ -246,7 +246,8 @@ tar_set_quoting_style (char *arg) @@ -246,7 +246,8 @@ tar_set_quoting_style (char *arg)
enum enum
@ -523,9 +602,9 @@ diff -urNp tar-1.22-orig/src/tar.c tar-1.22/src/tar.c
{NULL, 0, NULL, 0, {NULL, 0, NULL, 0,
N_("Handling of file attributes:"), GRID }, N_("Handling of file attributes:"), GRID },
+ {"acls", ACLS_OPTION, 0, 0, + {"acls", ACLS_OPTION, 0, 0,
+ N_("Save the ACLs to the archive"), GRID+1 }, + N_("Save the ACLs to the archive"), GRID+1 },
+ {"no-acls", NO_ACLS_OPTION, 0, 0, + {"no-acls", NO_ACLS_OPTION, 0, 0,
+ N_("Don't extract the ACLs from the archive"), GRID+1 }, + N_("Don't extract the ACLs from the archive"), GRID+1 },
{"owner", OWNER_OPTION, N_("NAME"), 0, {"owner", OWNER_OPTION, N_("NAME"), 0,
N_("force NAME as owner for added files"), GRID+1 }, N_("force NAME as owner for added files"), GRID+1 },
@ -534,18 +613,18 @@ diff -urNp tar-1.22-orig/src/tar.c tar-1.22/src/tar.c
{"preserve-order", 's', 0, 0, {"preserve-order", 's', 0, 0,
N_("sort names to extract to match archive"), GRID+1 }, N_("sort names to extract to match archive"), GRID+1 },
{"same-order", 0, 0, OPTION_ALIAS, NULL, GRID+1 }, {"same-order", 0, 0, OPTION_ALIAS, NULL, GRID+1 },
+ {"selinux", SELINUX_CONTEXT_OPTION, 0, 0, + {"selinux", SELINUX_CONTEXT_OPTION, 0, 0,
+ N_("Save the SELinux context to the archive"), GRID+1 }, + N_("Save the SELinux context to the archive"), GRID+1 },
+ {"no-selinux", NO_SELINUX_CONTEXT_OPTION, 0, 0, + {"no-selinux", NO_SELINUX_CONTEXT_OPTION, 0, 0,
+ N_("Don't extract the SELinux context from the archive"), GRID+1 }, + N_("Don't extract the SELinux context from the archive"), GRID+1 },
+ {"xattrs", XATTR_OPTION, 0, 0, + {"xattrs", XATTR_OPTION, 0, 0,
+ N_("Save the user/root xattrs to the archive"), GRID+1 }, + N_("Save the user/root xattrs to the archive"), GRID+1 },
+ {"no-xattrs", NO_XATTR_OPTION, 0, 0, + {"no-xattrs", NO_XATTR_OPTION, 0, 0,
+ N_("Don't extract the user/root xattrs from the archive"), GRID+1 }, + N_("Don't extract the user/root xattrs from the archive"), GRID+1 },
{"preserve", PRESERVE_OPTION, 0, 0, {"preserve", PRESERVE_OPTION, 0, 0,
N_("same as both -p and -s"), GRID+1 }, N_("same as both -p and -s"), GRID+1 },
{"delay-directory-restore", DELAY_DIRECTORY_RESTORE_OPTION, 0, 0, {"delay-directory-restore", DELAY_DIRECTORY_RESTORE_OPTION, 0, 0,
@@ -1932,6 +1950,37 @@ parse_opt (int key, char *arg, struct ar @@ -1932,6 +1950,37 @@ parse_opt (int key, char *arg, struct argp_state *state)
same_permissions_option = -1; same_permissions_option = -1;
break; break;
@ -629,9 +708,10 @@ diff -urNp tar-1.22-orig/src/tar.c tar-1.22/src/tar.c
free (st->sparse_map); free (st->sparse_map);
free (st->dumpdir); free (st->dumpdir);
xheader_destroy (&st->xhdr); xheader_destroy (&st->xhdr);
diff -urNp tar-1.22-orig/src/tar.h tar-1.22/src/tar.h diff --git a/src/tar.h b/src/tar.h
--- tar-1.22-orig/src/tar.h 2007-06-27 15:30:32.000000000 +0200 index 7f72f3e..49ee1ee 100644
+++ tar-1.22/src/tar.h 2009-11-23 14:48:00.000000000 +0100 --- a/src/tar.h
+++ b/src/tar.h
@@ -276,6 +276,14 @@ struct xheader @@ -276,6 +276,14 @@ struct xheader
uintmax_t string_length; uintmax_t string_length;
}; };
@ -656,7 +736,7 @@ diff -urNp tar-1.22-orig/src/tar.h tar-1.22/src/tar.h
+ +
+ char *acls_a_ptr; /* Access ACLs for the current archive entry. */ + char *acls_a_ptr; /* Access ACLs for the current archive entry. */
+ size_t acls_a_len; /* Access ACLs for the current archive entry. */ + size_t acls_a_len; /* Access ACLs for the current archive entry. */
+ +
+ char *acls_d_ptr; /* Default ACLs for the current archive entry. */ + char *acls_d_ptr; /* Default ACLs for the current archive entry. */
+ size_t acls_d_len; /* Default ACLs for the current archive entry. */ + size_t acls_d_len; /* Default ACLs for the current archive entry. */
+ +
@ -673,10 +753,12 @@ diff -urNp tar-1.22-orig/src/tar.h tar-1.22/src/tar.h
/* Extended headers */ /* Extended headers */
struct xheader xhdr; struct xheader xhdr;
diff -urNp tar-1.22-orig/src/xattrs.c tar-1.22/src/xattrs.c diff --git a/src/xattrs.c b/src/xattrs.c
--- tar-1.22-orig/src/xattrs.c 1970-01-01 01:00:00.000000000 +0100 new file mode 100644
+++ tar-1.22/src/xattrs.c 2009-11-23 14:48:33.000000000 +0100 index 0000000..fea18c3
@@ -0,0 +1,491 @@ --- /dev/null
+++ b/src/xattrs.c
@@ -0,0 +1,488 @@
+/* Create a tar archive. +/* Create a tar archive.
+ +
+ Copyright (C) 2006 Free Software Foundation, Inc. + Copyright (C) 2006 Free Software Foundation, Inc.
@ -738,16 +820,16 @@ diff -urNp tar-1.22-orig/src/xattrs.c tar-1.22/src/xattrs.c
+ static ssize_t asz = 1024; + static ssize_t asz = 1024;
+ ssize_t ret = 0; + ssize_t ret = 0;
+ static char *val = NULL; + static char *val = NULL;
+ +
+ if (!val) val = xmalloc (asz); + if (!val) val = xmalloc (asz);
+ +
+ while (((ret = fgetxattr (fd, attr, val, asz)) == -1) && + while (((ret = fgetxattr (fd, attr, val, asz)) == -1) &&
+ (errno == ERANGE)) + (errno == ERANGE))
+ { + {
+ asz <<= 1; + asz <<= 1;
+ val = xrealloc (val, asz); + val = xrealloc (val, asz);
+ } + }
+ +
+ if (ret != -1) + if (ret != -1)
+ { + {
+ *ret_ptr = xmemdup (val, ret + 1); + *ret_ptr = xmemdup (val, ret + 1);
@ -783,20 +865,20 @@ diff -urNp tar-1.22-orig/src/xattrs.c tar-1.22/src/xattrs.c
+ call_arg_warn ("acl_get_file", file_name); + call_arg_warn ("acl_get_file", file_name);
+ return; + return;
+ } + }
+ +
+ +
+ val = acl_to_text(acl, &len); + val = acl_to_text(acl, &len);
+ acl_free (acl); + acl_free (acl);
+ +
+ if (val == NULL) + if (val == NULL)
+ { + {
+ call_arg_warn ("acl_to_text", file_name); + call_arg_warn ("acl_to_text", file_name);
+ return; + return;
+ } + }
+ +
+ *ret_ptr = xstrdup (val); + *ret_ptr = xstrdup (val);
+ *ret_len = len; + *ret_len = len;
+ +
+ acl_free (val); + acl_free (val);
+#endif +#endif
+} +}
@ -809,26 +891,26 @@ diff -urNp tar-1.22-orig/src/xattrs.c tar-1.22/src/xattrs.c
+ char *val = NULL; + char *val = NULL;
+ ssize_t len; + ssize_t len;
+ acl_t acl; + acl_t acl;
+ +
+ if ((acl = acl_get_file (file_name, ACL_TYPE_DEFAULT)) == (acl_t)NULL) + if ((acl = acl_get_file (file_name, ACL_TYPE_DEFAULT)) == (acl_t)NULL)
+ { + {
+ if (errno != ENOTSUP) + if (errno != ENOTSUP)
+ call_arg_warn ("acl_get_file", file_name); + call_arg_warn ("acl_get_file", file_name);
+ return; + return;
+ } + }
+ +
+ val = acl_to_text(acl, &len); + val = acl_to_text(acl, &len);
+ acl_free (acl); + acl_free (acl);
+ +
+ if (val == NULL) + if (val == NULL)
+ { + {
+ call_arg_warn ("acl_to_text", file_name); + call_arg_warn ("acl_to_text", file_name);
+ return; + return;
+ } + }
+ +
+ *ret_ptr = xstrdup (val); + *ret_ptr = xstrdup (val);
+ *ret_len = len; + *ret_len = len;
+ +
+ acl_free (val); + acl_free (val);
+#endif +#endif
+} +}
@ -892,8 +974,8 @@ diff -urNp tar-1.22-orig/src/xattrs.c tar-1.22/src/xattrs.c
+#else +#else
+ +
+ if (!xatrs) xatrs = xmalloc (xsz); + if (!xatrs) xatrs = xmalloc (xsz);
+ +
+ while (((fd == -1) ? + while (((fd == -1) ?
+ ((xret = llistxattr (file_name, xatrs, xsz)) == -1) : + ((xret = llistxattr (file_name, xatrs, xsz)) == -1) :
+ ((xret = flistxattr (fd, xatrs, xsz)) == -1)) && + ((xret = flistxattr (fd, xatrs, xsz)) == -1)) &&
+ (errno == ERANGE)) + (errno == ERANGE))
@ -909,18 +991,16 @@ diff -urNp tar-1.22-orig/src/xattrs.c tar-1.22/src/xattrs.c
+ const char *attr = xatrs; + const char *attr = xatrs;
+ static ssize_t asz = 1024; + static ssize_t asz = 1024;
+ static char *val = NULL; + static char *val = NULL;
+ +
+ if (!val) val = xmalloc (asz); + if (!val) val = xmalloc (asz);
+ +
+ while (xret > 0) + while (xret > 0)
+ { + {
+ size_t len = strlen (attr); + size_t len = strlen (attr);
+ ssize_t aret = 0; + ssize_t aret = 0;
+ +
+ if (strncmp (attr, "user.", strlen("user.")) && + /* Archive all xattrs during creation, decide at extraction time
+ strncmp (attr, "trusted.", strlen("trusted."))) + * which ones are of interest/use for the target filesystem. */
+ goto next_attr; /* only store normal xattrs */
+
+ while (((fd == -1) ? + while (((fd == -1) ?
+ ((aret = lgetxattr (file_name, attr, val, asz)) == -1) : + ((aret = lgetxattr (file_name, attr, val, asz)) == -1) :
+ ((aret = fgetxattr (fd, attr, val, asz)) == -1)) && + ((aret = fgetxattr (fd, attr, val, asz)) == -1)) &&
@ -929,13 +1009,12 @@ diff -urNp tar-1.22-orig/src/xattrs.c tar-1.22/src/xattrs.c
+ asz <<= 1; + asz <<= 1;
+ val = xrealloc (val, asz); + val = xrealloc (val, asz);
+ } + }
+ +
+ if (aret != -1) + if (aret != -1)
+ xheader_xattr_add (st, attr, val, aret); + xheader_xattr_add (st, attr, val, aret);
+ else if (errno != ENOATTR) + else if (errno != ENOATTR)
+ call_arg_warn ((fd==-1) ? "lgetxattr" : "fgetxattr", file_name); + call_arg_warn ((fd==-1) ? "lgetxattr" : "fgetxattr", file_name);
+ +
+ next_attr:
+ attr += len + 1; + attr += len + 1;
+ xret -= len + 1; + xret -= len + 1;
+ } + }
@ -991,7 +1070,7 @@ diff -urNp tar-1.22-orig/src/xattrs.c tar-1.22/src/xattrs.c
+ if (perms & 0004) val[28] = 'r'; + if (perms & 0004) val[28] = 'r';
+ if (perms & 0002) val[29] = 'w'; + if (perms & 0002) val[29] = 'w';
+ if (perms & 0001) val[30] = 'x'; + if (perms & 0001) val[30] = 'x';
+ +
+ return (acl_from_text (val)); + return (acl_from_text (val));
+} +}
+#endif +#endif
@ -1003,13 +1082,13 @@ diff -urNp tar-1.22-orig/src/xattrs.c tar-1.22/src/xattrs.c
+ if (*ptr != ':') + if (*ptr != ':')
+ return (ptr); /* error? no user/group field */ + return (ptr); /* error? no user/group field */
+ ++ptr; + ++ptr;
+ +
+ ptr += strcspn(ptr, ":,\n"); /* skip user/group name */ + ptr += strcspn(ptr, ":,\n"); /* skip user/group name */
+ +
+ if (*ptr != ':') + if (*ptr != ':')
+ return (ptr); /* error? no perms field */ + return (ptr); /* error? no perms field */
+ ++ptr; + ++ptr;
+ +
+ ptr += strcspn(ptr, ":,\n"); /* skip perms */ + ptr += strcspn(ptr, ":,\n"); /* skip perms */
+ +
+ if (*ptr != ':') + if (*ptr != ':')
@ -1038,13 +1117,13 @@ diff -urNp tar-1.22-orig/src/xattrs.c tar-1.22/src/xattrs.c
+ +
+ if (*src == ':') /* We have extra fields, skip them all */ + if (*src == ':') /* We have extra fields, skip them all */
+ src += strcspn(src, "\n,"); + src += strcspn(src, "\n,");
+ +
+ if ((*src == '\n') || (*src == ',')) + if ((*src == '\n') || (*src == ','))
+ *dst++ = *src++; /* also done when dst == src, but that's ok */ + *dst++ = *src++; /* also done when dst == src, but that's ok */
+ } + }
+ if (src != dst) + if (src != dst)
+ *dst = 0; + *dst = 0;
+ +
+ return ptr; + return ptr;
+} +}
+ +
@ -1059,7 +1138,7 @@ diff -urNp tar-1.22-orig/src/xattrs.c tar-1.22/src/xattrs.c
+ { + {
+ /* assert (strlen (ptr) == len); */ + /* assert (strlen (ptr) == len); */
+ ptr = fixup_extra_acl_fields(ptr); + ptr = fixup_extra_acl_fields(ptr);
+ +
+ acl = acl_from_text (ptr); + acl = acl_from_text (ptr);
+ acls_option = 1; + acls_option = 1;
+ } + }
@ -1068,13 +1147,13 @@ diff -urNp tar-1.22-orig/src/xattrs.c tar-1.22/src/xattrs.c
+ else + else
+ return; /* don't call acl functions unless we first hit an ACL, or + return; /* don't call acl functions unless we first hit an ACL, or
+ --acls was passed explicitly */ + --acls was passed explicitly */
+ +
+ if (acl == (acl_t)NULL) + if (acl == (acl_t)NULL)
+ { + {
+ call_arg_warn ("acl_from_text", file_name); + call_arg_warn ("acl_from_text", file_name);
+ return; + return;
+ } + }
+ +
+ if (acl_set_file (file_name, type, acl) == -1) + if (acl_set_file (file_name, type, acl) == -1)
+ { + {
+ if (errno != ENOTSUP) + if (errno != ENOTSUP)
@ -1155,22 +1234,24 @@ diff -urNp tar-1.22-orig/src/xattrs.c tar-1.22/src/xattrs.c
+ keyword += strlen("SCHILY.xattr."); + keyword += strlen("SCHILY.xattr.");
+ +
+ if (strncmp (keyword, "user.", strlen("user.")) && + if (strncmp (keyword, "user.", strlen("user.")) &&
+ strncmp (keyword, "lustre.", strlen("lustre.")) &&
+ strncmp (keyword, "trusted.", strlen("trusted."))) + strncmp (keyword, "trusted.", strlen("trusted.")))
+ continue; /* don't try and set anything but normal xattrs */ + continue; /* don't try and set anything but normal xattrs */
+ +
+ /* should we ignore trusted.* EPERM errors when not root ? */
+ xattrs__fd_set (st, file_name, typeflag, keyword, + xattrs__fd_set (st, file_name, typeflag, keyword,
+ st->xattr_map[scan].xval_ptr, + st->xattr_map[scan].xval_ptr,
+ st->xattr_map[scan].xval_len); + st->xattr_map[scan].xval_len);
+ +
+ ++scan; + ++scan;
+ } + }
+#endif +#endif
+ } + }
+} +}
diff -urNp tar-1.22-orig/src/xattrs.h tar-1.22/src/xattrs.h diff --git a/src/xattrs.h b/src/xattrs.h
--- tar-1.22-orig/src/xattrs.h 1970-01-01 01:00:00.000000000 +0100 new file mode 100644
+++ tar-1.22/src/xattrs.h 2009-11-23 14:48:00.000000000 +0100 index 0000000..ebbd5c6
--- /dev/null
+++ b/src/xattrs.h
@@ -0,0 +1,14 @@ @@ -0,0 +1,14 @@
+ +
+extern void xattrs_acls_get(struct tar_stat_info *st, +extern void xattrs_acls_get(struct tar_stat_info *st,
@ -1186,10 +1267,11 @@ diff -urNp tar-1.22-orig/src/xattrs.h tar-1.22/src/xattrs.h
+ char const *file_name, char typeflag); + char const *file_name, char typeflag);
+extern void xattrs_xattrs_set(struct tar_stat_info const *st, +extern void xattrs_xattrs_set(struct tar_stat_info const *st,
+ char const *file_name, char typeflag); + char const *file_name, char typeflag);
diff -urNp tar-1.22-orig/src/xheader.c tar-1.22/src/xheader.c diff --git a/src/xheader.c b/src/xheader.c
--- tar-1.22-orig/src/xheader.c 2008-11-30 13:30:54.000000000 +0100 index 919ecd3..8e18421 100644
+++ tar-1.22/src/xheader.c 2009-11-23 14:48:00.000000000 +0100 --- a/src/xheader.c
@@ -417,6 +417,74 @@ xheader_write_global (struct xheader *xh +++ b/src/xheader.c
@@ -417,6 +417,74 @@ xheader_write_global (struct xheader *xhdr)
free (name); free (name);
} }
@ -1218,7 +1300,7 @@ diff -urNp tar-1.22-orig/src/xheader.c tar-1.22/src/xheader.c
+ const char *key, const char *val, size_t len) + const char *key, const char *val, size_t len)
+{ +{
+ size_t pos = (*xattr_map_size)++; + size_t pos = (*xattr_map_size)++;
+ +
+ *xattr_map = xrealloc (*xattr_map, + *xattr_map = xrealloc (*xattr_map,
+ *xattr_map_size * sizeof(struct xattr_array)); + *xattr_map_size * sizeof(struct xattr_array));
+ (*xattr_map)[pos].xkey = xstrdup (key); + (*xattr_map)[pos].xkey = xstrdup (key);
@ -1235,7 +1317,7 @@ diff -urNp tar-1.22-orig/src/xheader.c tar-1.22/src/xheader.c
+ +
+ tmp = stpcpy (tmp, "SCHILY.xattr."); + tmp = stpcpy (tmp, "SCHILY.xattr.");
+ tmp = stpcpy (tmp, key); + tmp = stpcpy (tmp, key);
+ +
+ xheader_xattr__add (&st->xattr_map, &st->xattr_map_size, xkey, val, len); + xheader_xattr__add (&st->xattr_map, &st->xattr_map_size, xkey, val, len);
+ +
+ free (xkey); + free (xkey);
@ -1248,13 +1330,13 @@ diff -urNp tar-1.22-orig/src/xheader.c tar-1.22/src/xheader.c
+ +
+ *xattr_map = NULL; + *xattr_map = NULL;
+ *xattr_map_size = 0; + *xattr_map_size = 0;
+ +
+ while (scan < st->xattr_map_size) + while (scan < st->xattr_map_size)
+ { + {
+ char *key = st->xattr_map[scan].xkey; + char *key = st->xattr_map[scan].xkey;
+ char *val = st->xattr_map[scan].xval_ptr; + char *val = st->xattr_map[scan].xval_ptr;
+ size_t len = st->xattr_map[scan].xval_len; + size_t len = st->xattr_map[scan].xval_len;
+ +
+ xheader_xattr__add(xattr_map, xattr_map_size, key, val, len); + xheader_xattr__add(xattr_map, xattr_map_size, key, val, len);
+ +
+ ++scan; + ++scan;
@ -1288,11 +1370,11 @@ diff -urNp tar-1.22-orig/src/xheader.c tar-1.22/src/xheader.c
+ if (strcmp (p->keyword, keyword) == 0) + if (strcmp (p->keyword, keyword) == 0)
+ return p; + return p;
+ } + }
+ +
return NULL; return NULL;
} }
@@ -454,7 +532,7 @@ xheader_protected_pattern_p (const char @@ -454,7 +532,7 @@ xheader_protected_pattern_p (const char *pattern)
struct xhdr_tab const *p; struct xhdr_tab const *p;
for (p = xhdr_tab; p->keyword; p++) for (p = xhdr_tab; p->keyword; p++)
@ -1301,7 +1383,7 @@ diff -urNp tar-1.22-orig/src/xheader.c tar-1.22/src/xheader.c
return true; return true;
return false; return false;
} }
@@ -465,7 +543,7 @@ xheader_protected_keyword_p (const char @@ -465,7 +543,7 @@ xheader_protected_keyword_p (const char *keyword)
struct xhdr_tab const *p; struct xhdr_tab const *p;
for (p = xhdr_tab; p->keyword; p++) for (p = xhdr_tab; p->keyword; p++)
@ -1310,7 +1392,7 @@ diff -urNp tar-1.22-orig/src/xheader.c tar-1.22/src/xheader.c
return true; return true;
return false; return false;
} }
@@ -1417,6 +1495,71 @@ volume_filename_decoder (struct tar_stat @@ -1417,6 +1495,71 @@ volume_filename_decoder (struct tar_stat_info *st,
} }
static void static void
@ -1382,7 +1464,7 @@ diff -urNp tar-1.22-orig/src/xheader.c tar-1.22/src/xheader.c
sparse_major_coder (struct tar_stat_info const *st, char const *keyword, sparse_major_coder (struct tar_stat_info const *st, char const *keyword,
struct xheader *xhdr, void const *data) struct xheader *xhdr, void const *data)
{ {
@@ -1453,18 +1596,18 @@ sparse_minor_decoder (struct tar_stat_in @@ -1453,18 +1596,18 @@ sparse_minor_decoder (struct tar_stat_info *st,
} }
struct xhdr_tab const xhdr_tab[] = { struct xhdr_tab const xhdr_tab[] = {
@ -1445,14 +1527,13 @@ diff -urNp tar-1.22-orig/src/xheader.c tar-1.22/src/xheader.c
/* These may be present in a first global header of the archive. /* These may be present in a first global header of the archive.
They provide the same functionality as GNUTYPE_MULTIVOL header. They provide the same functionality as GNUTYPE_MULTIVOL header.
@@ -1506,9 +1649,38 @@ struct xhdr_tab const xhdr_tab[] = { @@ -1506,9 +1649,39 @@ struct xhdr_tab const xhdr_tab[] = {
GNU.volume.offset keeps the offset of the start of this volume, GNU.volume.offset keeps the offset of the start of this volume,
otherwise kept in oldgnu_header.offset. */ otherwise kept in oldgnu_header.offset. */
{ "GNU.volume.filename", volume_label_coder, volume_filename_decoder, { "GNU.volume.filename", volume_label_coder, volume_filename_decoder,
- true }, - true },
- { "GNU.volume.size", volume_size_coder, volume_size_decoder, true }, - { "GNU.volume.size", volume_size_coder, volume_size_decoder, true },
- { "GNU.volume.offset", volume_offset_coder, volume_offset_decoder, true }, - { "GNU.volume.offset", volume_offset_coder, volume_offset_decoder, true },
-
+ true, false }, + true, false },
+ { "GNU.volume.size", volume_size_coder, volume_size_decoder, true, false }, + { "GNU.volume.size", volume_size_coder, volume_size_decoder, true, false },
+ { "GNU.volume.offset", volume_offset_coder, volume_offset_decoder, + { "GNU.volume.offset", volume_offset_coder, volume_offset_decoder,
@ -1479,12 +1560,13 @@ diff -urNp tar-1.22-orig/src/xheader.c tar-1.22/src/xheader.c
+ { "SCHILY.xattr.system.posix_acl_default", + { "SCHILY.xattr.system.posix_acl_default",
+ xattr_acls_d_coder, xattr_acls_d_decoder, false, false }, + xattr_acls_d_coder, xattr_acls_d_decoder, false, false },
+ +
+ /* xattr's, use the star format note we only save the user/trusted varients... */ + /* xattrs use the star format. note we only save some variants... */
+ { "SCHILY.xattr.user", xattr_coder, xattr_decoder, false, true }, + { "SCHILY.xattr.user", xattr_coder, xattr_decoder, false, true },
+ { "SCHILY.xattr.trusted", xattr_coder, xattr_decoder, false, true }, + { "SCHILY.xattr.trusted", xattr_coder, xattr_decoder, false, true },
+ { "SCHILY.xattr.lustre", xattr_coder, xattr_decoder, false, true },
+ +
+ /* ignore everything else in the xattr namespaces... */ + /* ignore everything else in the xattr namespaces... */
+ { "SCHILY.xattr", dummy_coder, dummy_decoder, false, true }, + { "SCHILY.xattr", dummy_coder, dummy_decoder, false, true },
+
{ NULL, NULL, NULL, false } { NULL, NULL, NULL, false }
}; };

View File

@ -5,7 +5,7 @@ Summary: A GNU file archiving program
Name: tar Name: tar
Epoch: 2 Epoch: 2
Version: 1.22 Version: 1.22
Release: 15%{?dist} Release: 16%{?dist}
License: GPLv3+ License: GPLv3+
Group: Applications/Archiving Group: Applications/Archiving
URL: http://www.gnu.org/software/tar/ URL: http://www.gnu.org/software/tar/
@ -132,6 +132,9 @@ fi
%{_infodir}/tar.info* %{_infodir}/tar.info*
%changelog %changelog
* Sat Feb 20 2010 Kamil Dudka <kdudka@redhat.com> 2:1.22-16
- support for "lustre.*" extended attributes (#561855)
* Thu Feb 04 2010 Ondrej Vasik <ovasik@redhat.com> 2:1.22-15 * Thu Feb 04 2010 Ondrej Vasik <ovasik@redhat.com> 2:1.22-15
- fix segfault with corrupted metadata in code_ns_fraction - fix segfault with corrupted metadata in code_ns_fraction
(#531441) (#531441)