diff options
author | Mike Frysinger <vapier@gentoo.org> | 2012-02-05 04:29:53 +0000 |
---|---|---|
committer | Mike Frysinger <vapier@gentoo.org> | 2012-02-05 04:29:53 +0000 |
commit | 3d2f716be117029c96044726dcbeb970c1fa4c38 (patch) | |
tree | eb6f872f3eac8ca7b5f5555a0db0c98fb76561ac | |
parent | New package, ebuild written by me (diff) | |
download | historical-3d2f716be117029c96044726dcbeb970c1fa4c38.tar.gz historical-3d2f716be117029c96044726dcbeb970c1fa4c38.tar.bz2 historical-3d2f716be117029c96044726dcbeb970c1fa4c38.zip |
Add xattr support #382067 by Anthony Basile.
Package-Manager: portage-2.2.0_alpha84/cvs/Linux x86_64
-rw-r--r-- | app-arch/tar/ChangeLog | 8 | ||||
-rw-r--r-- | app-arch/tar/Manifest | 30 | ||||
-rw-r--r-- | app-arch/tar/files/tar-1.26-xattr.patch | 931 | ||||
-rw-r--r-- | app-arch/tar/tar-1.26-r1.ebuild | 70 |
4 files changed, 1024 insertions, 15 deletions
diff --git a/app-arch/tar/ChangeLog b/app-arch/tar/ChangeLog index a111e5e35c6c..c99a36d574e4 100644 --- a/app-arch/tar/ChangeLog +++ b/app-arch/tar/ChangeLog @@ -1,6 +1,12 @@ # ChangeLog for app-arch/tar # Copyright 1999-2012 Gentoo Foundation; Distributed under the GPL v2 -# $Header: /var/cvsroot/gentoo-x86/app-arch/tar/ChangeLog,v 1.163 2012/01/07 00:00:26 vapier Exp $ +# $Header: /var/cvsroot/gentoo-x86/app-arch/tar/ChangeLog,v 1.164 2012/02/05 04:29:53 vapier Exp $ + +*tar-1.26-r1 (05 Feb 2012) + + 05 Feb 2012; Mike Frysinger <vapier@gentoo.org> +tar-1.26-r1.ebuild, + +files/tar-1.26-xattr.patch: + Add xattr support #382067 by Anthony Basile. 07 Jan 2012; Mike Frysinger <vapier@gentoo.org> files/tar.1: Fix duplicate --one-file-system listing reported by Mikachu. diff --git a/app-arch/tar/Manifest b/app-arch/tar/Manifest index de6f1031e881..b5d5fbe66883 100644 --- a/app-arch/tar/Manifest +++ b/app-arch/tar/Manifest @@ -9,6 +9,7 @@ AUX tar-1.23-tests.patch 662 RMD160 ef87a9f5c25240abddde45be4fb0a932c1fd2ec7 SHA AUX tar-1.25-incremental-fix.patch 4387 RMD160 b4ca004367e6a5ebd289a8237bb9efaeb5061c90 SHA1 2e54ce1a23a707110a2e440328f0d81743e49b32 SHA256 da801c2550a837b95ccabacd269cc9360c1c4f9d7f27fd80537c608576a112e5 AUX tar-1.25-verify-check.patch 2083 RMD160 ef237dfe85a0f95c81d9715c791069574ef5342c SHA1 54dcaa661de4b601f6e5cb025720d3dccdbf5cd9 SHA256 4604f596b097d75c063b74c27c75c9cd5528941e2b8f904bb0743767e592c09d AUX tar-1.25-verify-fix.patch 1400 RMD160 e20ae093a3449bcf22a8d9591eddfa8027f7f4f0 SHA1 d39aae9a0a9e58581568e2292a41dc10c8e824a5 SHA256 eb5d28b4c10938e287476cbf6bf56a32d13043c9f6ff6ea96f91bcef46a36515 +AUX tar-1.26-xattr.patch 29828 RMD160 e753e032645f3fcd694030bbfb1c43c548c53a6f SHA1 42bee36afb989c493a665fd3902747e828c89b94 SHA256 ce2b67c9fca5e610e117e11485f11bea5d4c6b053392c97825da7f7e65e9d043 AUX tar.1 16744 RMD160 1d4e8430d6e76aa22f747e1e7b5fa893d092faea SHA1 3823ab407b38ae1fe6f867e01e1eb21977199b08 SHA256 47100e0f1dcaeee56b99083d8bb6fb398be701030f0a72439a1b4de31ac701d3 DIST tar-1.23.tar.bz2 2189324 RMD160 e79062b7f69d80b734445306f69fb8b96801e909 SHA1 6f3b1443a019da02e4ec20a1446d4aa54b488071 SHA256 c9328372db62fbb1d94c9e4e3cefc961111af46de47085b635359c00a0eebe36 DIST tar-1.25.tar.bz2 2327460 RMD160 4798d95b8816f5b7a90af8f0596a2e6b70cacb5e SHA1 0f0c090e51d127cbeffbb9aeeb90db1181d82aed SHA256 f3f6ce41b8e0f327abd05c95990f113ddafbae131e10f79a99728ed46458494b @@ -17,23 +18,24 @@ EBUILD tar-1.23-r2.ebuild 1757 RMD160 fe262e531e6edca865a1c49eb47bfca9f10b1edf S EBUILD tar-1.23-r4.ebuild 1824 RMD160 6721228dfd20f85bd93278148f0f7fa7d57db84f SHA1 8fa3f45e1c85c3a06ab6062940a37f3c67ce50c0 SHA256 25bde52ba653a03f48aa26dd0d86e5879e381260b7fae24f6095de5ef55b1de0 EBUILD tar-1.25-r1.ebuild 2250 RMD160 e52a2483470147740259dd2d8efab64dd8b844fb SHA1 1df965311d85d14655435d4aafb392a0144fd970 SHA256 30d491208882b35e3b852e14ca36d6e0f4322805fbc6cccc7a19bdcd558fdcd1 EBUILD tar-1.25.ebuild 2094 RMD160 dc0007c343c76e5acc722ddf82d4ea61e9728d9d SHA1 e92cec9a7523c59c8d6db22388dcf7040cfc3197 SHA256 4a8cb3060e514f43d1883bcceee92b8b910851825bef40b1706f7ac4cc72dbdc +EBUILD tar-1.26-r1.ebuild 2114 RMD160 faffbae5e53447da8494f60e5441e918f1d0c2d1 SHA1 69b56b0590a8a01a41d703c5c663d323d1df8348 SHA256 93856aba875a281e872eb7fd2f8947501196e7e22850d5237ecc0a0094463e8c EBUILD tar-1.26.ebuild 2092 RMD160 8d7c7c11dfb0c44076e648979ffb90eb0fb7fe17 SHA1 656a9ca933cf5a1a2ca8fc55c18b6f9e6c59916a SHA256 fe0f4aadd357440e0e3f23912186091c2b7c20b424745fef68871e695ff45a13 -MISC ChangeLog 24714 RMD160 a787d959e0595b3bd592d1fa72e3d59958c875ab SHA1 56e3af339936c04986caae67585f08bf85d00773 SHA256 a8eb0cf8a7c57b0be5c79caf700235864dc5b871f91c14ba6e93172e57ad80d4 +MISC ChangeLog 24892 RMD160 611c24c2fe113929a48c38ff5f8f5736c33557e6 SHA1 09db6548bce392af12b2ecc6d4e5bbd0a4c7af1c SHA256 ced78f4a2d3d03fca3b4518312eb2e714a76a54fb18967f22b66eb4854c54b03 MISC metadata.xml 164 RMD160 f43cbec30b7074319087c9acffdb9354b17b0db3 SHA1 9c213f5803676c56439df3716be07d6692588856 SHA256 f5f2891f2a4791cd31350bb2bb572131ad7235cd0eeb124c9912c187ac10ce92 -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.18 (GNU/Linux) -iQIcBAEBAgAGBQJPB4tEAAoJELEHsLL7fEFW36cP/0oIaWDF8zdXAR/7+7vJfLHJ -s7eVnjsUNBe5OggFqsS0tIZn8ENqfElI1flnT2hNAc+8BluQRoR8fvxJYc3olcCn -BQPxN/KHxU5CaYlmAAzV+tVHHIIjY2gjQLurERIEZuAIE1cADiU6iwcPbKx/IjXR -3hjjv/DmVNxCAUMgiy34OXiDfgqWNOCtrJkTydIPKjiHctiisbua1BJYHLN4Fiq9 -kprEXfL136SaZlEuGD2C6FJEZ09rgSpXTbsg3vkvEZS/DZgOktLlnO+3b/EmGTPt -hM7hXL/1G/NiRzUuP+hDt3CweNYRlUWqUmWsNq+Hi/aw80yC2r0/rjaOebDLggvJ -U6s1PGyK4QWMLp9BcS5wDfNnODrUBbMLhVHUoED8qHygCtZm1CeecCjgoCFfXClV -q/gwbLwflqIpk/Bt2/cCMhX/+rsWRlfzPqW0Bm12zykgDwYRs+Vad4QStkbW5l0v -fgUFr5uUxDwP6xF6jQMuRk44rUyYSI1Mi8p4mMyewTqWL2cqpV5xRlfwjb8ufxDD -WbCHTkw1aTx08JSWvEhp+fej81XteQMtutMTkmIK3AA7icMyPIL4+zqZEcXxXqx/ -Av9rsr/CHCwl2wLTZZgi9CzL5SDzHr6Ra5AOa1LfTG8XLai5VSGxw315Nh+H8w0c -OvErlWKeHObRd9h4z4Ft -=zOFv +iQIcBAEBAgAGBQJPLgXZAAoJELEHsLL7fEFW7jgQAI/hfuTP5Vcy+LUhGQvLjQ0U +hBvfurYUyvxS2eU6/xuJ/ck829OK/n1H7TkGpKVwJH+aum4uETUanVDmP06Q8opc +rjafriVU2uaY6hgDwenBGaid1HKMmh0OSUv1bSDIk4Stxm0f1BIvMnUln0gVlEY5 +N52k1PTkUobpCYLQ4CuHlCc39ctun5POoabT9CICGouIj3ZW9m2zGtdYaPz3dnC9 +uqu/Q61buDRRwmrG3RLi0bGSx6TDQjUAMLTAvuwNZB3ebqcsQpCDPEVmN5ZxjmUC +rJgUs8sYcfNL6H7r6vSKeCRqJu7JqS+ySPs5tidrV/HUcH3g+fPK8feb+U9/Fq19 +Lw6rNnUyzZKGqC5Ewj/XjGuK8KDOE6iAk4pdLzxR4L5wQ7PdcgBWjIWRKLJAJWmW +gXIjpMGxAgW8ePYW6gSv4UXf02jKWeHhUI4CihTpYYcHtyn8P7FTOw1cHlVGidTE +qiAuxj4EaDOpOJycgduxIVTyHm5MYjQjCEQQwaHjFSFKcGEV2nV4DTC9l9fccgjm +ZaY16Iaf3aaUFETPepmAlYpMdb2AqE+rDHqzciqJAheQNfjo3bBD1I7Vl0EM0zv3 +ocUb8RI9edlnRDfLPfb9+0/+OBMsFgdYNZmvGjOEEuAbjXOKmbt9Up79e62tAEi4 +ikjwOKs/7VaPRClF4vBI +=5/Fq -----END PGP SIGNATURE----- diff --git a/app-arch/tar/files/tar-1.26-xattr.patch b/app-arch/tar/files/tar-1.26-xattr.patch new file mode 100644 index 000000000000..7986828ef519 --- /dev/null +++ b/app-arch/tar/files/tar-1.26-xattr.patch @@ -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, ¤t_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, + ¤t_mode, ¤t_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 (¤t_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 } + }; diff --git a/app-arch/tar/tar-1.26-r1.ebuild b/app-arch/tar/tar-1.26-r1.ebuild new file mode 100644 index 000000000000..b47094f8911e --- /dev/null +++ b/app-arch/tar/tar-1.26-r1.ebuild @@ -0,0 +1,70 @@ +# 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.1 2012/02/05 04:29:53 vapier Exp $ + +EAPI="3" + +inherit flag-o-matic autotools + +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 ~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="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 + 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} +} |