1 diff -urNp tar-1.24-orig/configure.ac tar-1.24/configure.ac
2 --- tar-1.24-orig/configure.ac 2010-10-24 23:35:35.000000000 +0200
3 +++ tar-1.24/configure.ac 2010-10-25 10:24:52.548214037 +0200
4 @@ -44,7 +44,7 @@ AC_CHECK_HEADERS_ONCE(fcntl.h linux/fd.h
5 sys/param.h sys/device.h sys/gentape.h \
6 sys/inet.h sys/io/trioctl.h \
7 sys/mtio.h sys/time.h sys/tprintf.h sys/tape.h \
9 + unistd.h locale.h attr/xattr.h sys/acl.h)
11 AC_CHECK_HEADERS([sys/buf.h], [], [],
13 @@ -91,6 +91,12 @@ gl_INIT
16 AC_CHECK_FUNCS_ONCE([fchmod fchown fsync lstat mkfifo readlink symlink])
17 +AC_CHECK_FUNCS(getxattr fgetxattr lgetxattr \
18 + setxattr fsetxattr lsetxattr \
19 + listxattr flistxattr llistxattr,
20 + AC_DEFINE(HAVE_XATTRS,,[Define if we have a working extended attributes]),)
21 +AC_CHECK_LIB(acl, acl_get_fd)
23 AC_CHECK_DECLS([getgrgid],,, [#include <grp.h>])
24 AC_CHECK_DECLS([getpwuid],,, [#include <pwd.h>])
25 AC_CHECK_DECLS([time],,, [#include <time.h>])
26 @@ -214,6 +220,7 @@ AC_DEFINE_UNQUOTED(DEFAULT_QUOTING_STYLE
29 AC_CHECK_HEADERS(iconv.h)
30 +AC_CHECK_HEADERS(attr/xattr.h)
31 AC_CHECK_TYPE(iconv_t,:,
32 AC_DEFINE(iconv_t, int,
33 [Conversion descriptor type]),
34 @@ -223,6 +230,17 @@ AC_CHECK_TYPE(iconv_t,:,
38 +AC_ARG_ENABLE(selinux,
39 + AC_HELP_STRING([--enable-selinux],
40 + [enable SELinux support (disabled by default)]),
41 + [selinux_enabled=$enableval],
42 + [selinux_enabled=no])
44 +if test "x$selinux_enabled" = xyes; then
45 + AC_CHECK_LIB(selinux, getfilecon)
46 + AC_CHECK_HEADERS(selinux/selinux.h)
50 AM_GNU_GETTEXT([external], [need-formatstring-macros])
51 AM_GNU_GETTEXT_VERSION([0.16])
52 diff -urNp tar-1.24-orig/doc/tar.texi tar-1.24/doc/tar.texi
53 --- tar-1.24-orig/doc/tar.texi 2010-10-24 20:07:54.000000000 +0200
54 +++ tar-1.24/doc/tar.texi 2010-10-25 10:24:52.554213688 +0200
55 @@ -2370,6 +2370,10 @@ Normally when creating an archive, @comm
56 @samp{/} from member names. This option disables that behavior.
61 +Causes @command{tar} to store ACL's. @xref{Attributes}.
63 @opsummary{after-date}
66 @@ -2915,6 +2919,10 @@ contents have changed (as opposed to jus
67 also back up files for which any status information has
68 changed). @xref{after}.
72 +Causes @command{tar} not to store and not to extract ACL's. @xref{Attributes}.
74 @opsummary{no-anchored}
76 An exclude pattern can match any subsequence of the name's components.
77 @@ -2998,11 +3006,21 @@ locations. Usually @command{tar} determ
78 the archive can be seeked or not. Use this option to disable this
81 +@opsummary{no-selinux}
83 +Causes @command{tar} not to store and not to extract SELinux security context.
86 @opsummary{no-unquote}
88 Treat all input file or member names literally, do not interpret
89 escape sequences. @xref{input name quoting}.
91 +@opsummary{no-xattrs}
93 +Causes @command{tar} not to store and not to extract xattrs. This option also
94 +enables @option{--no-selinux} and @option{--no-acls}. @xref{Attributes}.
96 @opsummary{no-wildcards}
99 @@ -3235,6 +3253,11 @@ in cases when such recognition fails. I
100 archive is open for reading (e.g. with @option{--list} or
101 @option{--extract} options).
105 +Causes @command{tar} to store SElinux security context. @xref{Attributes}.
108 @opsummary{show-defaults}
109 @item --show-defaults
111 @@ -3448,6 +3471,11 @@ Enable or disable warning messages ident
112 messages are suppressed if @var{keyword} is prefixed with @samp{no-}.
117 +Causes @command{tar} to store xattrs. This option also enables
118 +@option{--selinux} and @option{--acls}. @xref{Attributes}.
120 @opsummary{wildcards}
122 Use wildcards when matching member names with patterns.
123 @@ -8643,6 +8671,8 @@ implementation able to read @samp{ustar}
124 most @samp{posix} archives as well, with the only exception that any
125 additional information (such as long file names etc.) will in such
126 case be extracted as plain text files along with the files it refers to.
127 +This is the only format that can store ACLs, SELinux context and extended
130 This archive format will be the default format for future versions
132 @@ -9259,6 +9289,51 @@ Same as both @option{--same-permissions}
134 This option is deprecated, and will be removed in @GNUTAR{} version 1.23.
138 +This option causes @command{tar} to store the current ACL in the archive.
140 +The @option{--acls} option has no equivalent short option name.
144 +This option causes @command{tar} to store the current SELinux security context
145 +information in the archive.
147 +The @option{--selinux} option has no equivalent short option name.
151 +This option causes @command{tar} to store the current extended attributes in
152 +the archive. This option also enables @option{--acls} and @option{--selinux} if
153 +they haven't been set already.
155 +The @option{--xattrs} option has no equivalent short option name.
159 +This option causes @command{tar} not to store the current ACL in the archive
160 +and not to extract any ACL information in an archive.
162 +The @option{--no-acls} option has no equivalent short option name.
166 +This option causes @command{tar} not to store the current SELinux security
167 +context information in the archive and not to extract any SELinux information in
170 +The @option{--no-selinux} option has no equivalent short option name.
174 +This option causes @command{tar} not to store the current extended attributes in
175 +the archive and not to extract any extended attributes in an archive. This
176 +option also enables @option{--no-acls} and @option{--no-selinux} if
177 +they haven't been set already.
179 +The @option{--no-xattrs} option has no equivalent short option name.
184 diff -urNp tar-1.24-orig/src/common.h tar-1.24/src/common.h
185 --- tar-1.24-orig/src/common.h 2010-10-24 20:07:54.000000000 +0200
186 +++ tar-1.24/src/common.h 2010-10-25 10:24:52.558475456 +0200
187 @@ -253,6 +253,15 @@ GLOBAL int same_owner_option;
188 /* If positive, preserve permissions when extracting. */
189 GLOBAL int same_permissions_option;
191 +/* If positive, save the SELinux context. */
192 +GLOBAL int selinux_context_option;
194 +/* If positive, save the ACLs. */
195 +GLOBAL int acls_option;
197 +/* If positive, save the user and root xattrs. */
198 +GLOBAL int xattrs_option;
200 /* When set, strip the given number of file name components from the file name
202 GLOBAL size_t strip_name_components;
203 @@ -706,6 +715,9 @@ extern char *output_start;
205 void update_archive (void);
207 +/* Module attrs.c. */
210 /* Module xheader.c. */
212 void xheader_decode (struct tar_stat_info *stat);
213 @@ -726,6 +738,12 @@ bool xheader_string_end (struct xheader
214 bool xheader_keyword_deleted_p (const char *kw);
215 char *xheader_format_name (struct tar_stat_info *st, const char *fmt,
217 +void xheader_xattr_init(struct tar_stat_info *st);
218 +void xheader_xattr_free(struct xattr_array *vals, size_t sz);
219 +void xheader_xattr_copy(const struct tar_stat_info *st,
220 + struct xattr_array **vals, size_t *sz);
221 +void xheader_xattr_add(struct tar_stat_info *st,
222 + const char *key, const char *val, size_t len);
224 /* Module system.c */
226 diff -urNp tar-1.24-orig/src/create.c tar-1.24/src/create.c
227 --- tar-1.24-orig/src/create.c 2010-10-24 20:07:54.000000000 +0200
228 +++ tar-1.24/src/create.c 2010-10-25 10:24:52.560213618 +0200
230 #include <quotearg.h>
236 /* Error number to use when an impostor is discovered.
237 @@ -934,6 +935,30 @@ start_header (struct tar_stat_info *st)
238 GNAME_TO_CHARS (st->gname, header->header.gname);
241 + if (archive_format == POSIX_FORMAT)
243 + if (acls_option > 0)
245 + if (st->acls_a_ptr)
246 + xheader_store ("SCHILY.acl.access", st, NULL);
247 + if (st->acls_d_ptr)
248 + xheader_store ("SCHILY.acl.default", st, NULL);
250 + if ((selinux_context_option > 0) && st->cntx_name)
251 + xheader_store ("RHT.security.selinux", st, NULL);
252 + if (xattrs_option > 0)
254 + size_t scan_xattr = 0;
255 + struct xattr_array *xattr_map = st->xattr_map;
257 + while (scan_xattr < st->xattr_map_size)
259 + xheader_store (xattr_map[scan_xattr].xkey, st, &scan_xattr);
268 @@ -1709,6 +1734,10 @@ dump_file0 (struct tar_stat_info *st, ch
270 struct stat final_stat;
272 + xattrs_acls_get(st, p, fd, !is_dir);
273 + xattrs_selinux_get(st, p, fd);
274 + xattrs_xattrs_get(st, p, fd);
278 const char *tag_file_name;
279 @@ -1826,6 +1855,9 @@ dump_file0 (struct tar_stat_info *st, ch
280 if (NAME_FIELD_SIZE - (archive_format == OLDGNU_FORMAT) < size)
281 write_long_link (st);
283 + xattrs_selinux_get(st, p, -1);
284 + xattrs_xattrs_get(st, p, -1);
286 block_ordinal = current_block_ordinal ();
287 st->stat.st_size = 0; /* force 0 size on symlink */
288 header = start_header (st);
289 @@ -1844,11 +1876,23 @@ dump_file0 (struct tar_stat_info *st, ch
292 else if (S_ISCHR (st->stat.st_mode))
296 + xattrs_selinux_get(st, p, -1);
297 + xattrs_xattrs_get(st, p, -1);
299 else if (S_ISBLK (st->stat.st_mode))
303 + xattrs_selinux_get(st, p, -1);
304 + xattrs_xattrs_get(st, p, -1);
306 else if (S_ISFIFO (st->stat.st_mode))
310 + xattrs_selinux_get(st, p, -1);
311 + xattrs_xattrs_get(st, p, -1);
313 else if (S_ISSOCK (st->stat.st_mode))
315 WARNOPT (WARN_FILE_IGNORED,
316 diff -urNp tar-1.24-orig/src/extract.c tar-1.24/src/extract.c
317 --- tar-1.24-orig/src/extract.c 2010-10-24 20:07:54.000000000 +0200
318 +++ tar-1.24/src/extract.c 2010-10-25 10:35:10.903214037 +0200
319 @@ -97,6 +97,14 @@ struct delayed_set_stat
320 /* Directory that the name is relative to. */
323 + /* extended attributes*/
329 + size_t xattr_map_size; /* Size of the xattr map */
330 + struct xattr_array *xattr_map;
331 /* Length and contents of name. */
332 size_t file_name_len;
334 @@ -134,6 +142,18 @@ struct delayed_link
335 hard-linked together. */
336 struct string_list *sources;
338 + /* SELinux context */
347 + size_t xattr_map_size; /* Size of the xattr map */
348 + struct xattr_array *xattr_map;
350 /* The desired target of the desired link. */
353 @@ -335,6 +355,10 @@ set_stat (char const *file_name,
354 utime_error (file_name);
357 + xattrs_acls_set(st, file_name, typeflag);
358 + xattrs_selinux_set(st, file_name, typeflag);
359 + xattrs_xattrs_set(st, file_name, typeflag);
361 if (0 < same_owner_option && ! interdir)
363 /* Some systems allow non-root users to give files away. Once this
364 @@ -431,6 +455,36 @@ delay_set_stat (char const *file_name, s
365 data->atflag = atflag;
366 data->after_links = 0;
367 data->change_dir = chdir_current;
368 + data->cntx_name = NULL;
370 + assign_string (&data->cntx_name, st->cntx_name);
371 + if (st && st->acls_a_ptr)
373 + data->acls_a_ptr = xmemdup(st->acls_a_ptr, st->acls_a_len + 1);
374 + data->acls_a_len = st->acls_a_len;
378 + data->acls_a_ptr = NULL;
379 + data->acls_a_len = 0;
381 + if (st && st->acls_d_ptr)
383 + data->acls_d_ptr = xmemdup(st->acls_d_ptr, st->acls_d_len + 1);
384 + data->acls_d_len = st->acls_d_len;
388 + data->acls_d_ptr = NULL;
389 + data->acls_d_len = 0;
392 + xheader_xattr_copy (st, &data->xattr_map, &data->xattr_map_size);
395 + data->xattr_map = NULL;
396 + data->xattr_map_size = 0;
398 strcpy (data->file_name, file_name);
399 delayed_set_stat_head = data;
400 if (must_be_dot_or_slash (file_name))
401 @@ -661,6 +708,31 @@ maybe_recoverable (char *file_name, bool
405 +/* Restore stat extended attributes (xattr) for FILE_NAME, using information
406 + given in *ST. Restore before extraction because they may affect layout.
407 + If not restoring permissions, invert the
408 + INVERT_PERMISSIONS bits from the file's current permissions.
409 + TYPEFLAG specifies the type of the file.
410 + FILE_CREATED indicates set_xattr has created the file */
412 +set_xattr (char const *file_name, struct tar_stat_info const *st,
413 + mode_t invert_permissions, char typeflag, int *file_created)
416 + bool interdir_made = false;
418 + if ((xattrs_option >= 0) && st->xattr_map_size) {
419 + mode_t mode = current_stat_info.stat.st_mode & MODE_RWX & ~ current_umask;
422 + status = mknod (file_name, mode ^ invert_permissions, 0);
423 + while (status && maybe_recoverable ((char *)file_name, false, &interdir_made));
424 + xattrs_xattrs_set(st, file_name, typeflag);
430 /* Fix the statuses of all directories whose statuses need fixing, and
431 which are not ancestors of FILE_NAME. If AFTER_LINKS is
432 nonzero, do this for all such directories; otherwise, stop at the
433 @@ -721,12 +793,23 @@ apply_nonancestor_delayed_set_stat (char
434 sb.stat.st_gid = data->gid;
435 sb.atime = data->atime;
436 sb.mtime = data->mtime;
437 + sb.cntx_name = data->cntx_name;
438 + sb.acls_a_ptr = data->acls_a_ptr;
439 + sb.acls_a_len = data->acls_a_len;
440 + sb.acls_d_ptr = data->acls_d_ptr;
441 + sb.acls_d_len = data->acls_d_len;
442 + sb.xattr_map = data->xattr_map;
443 + sb.xattr_map_size = data->xattr_map_size;
444 set_stat (data->file_name, &sb,
445 -1, current_mode, current_mode_mask,
446 DIRTYPE, data->interdir, data->atflag);
449 delayed_set_stat_head = data->next;
450 + xheader_xattr_free (data->xattr_map, data->xattr_map_size);
451 + free (data->cntx_name);
452 + free (data->acls_a_ptr);
453 + free (data->acls_d_ptr);
457 @@ -842,6 +925,7 @@ extract_dir (char *file_name, int typefl
460 open_output_file (char const *file_name, int typeflag, mode_t mode,
462 mode_t *current_mode, mode_t *current_mode_mask)
465 @@ -852,6 +936,10 @@ open_output_file (char const *file_name,
466 ? O_TRUNC | (dereference_option ? 0 : O_NOFOLLOW)
469 + /* File might be created in set_xattr. So clear O_EXCL to avoid open() failure */
471 + openflag = openflag & ~O_EXCL;
473 if (typeflag == CONTTYPE)
475 static int conttype_diagnosed;
476 @@ -908,6 +996,7 @@ extract_file (char *file_name, int typef
477 bool interdir_made = false;
478 mode_t mode = (current_stat_info.stat.st_mode & MODE_RWX
479 & ~ (0 < same_owner_option ? S_IRWXG | S_IRWXO : 0));
480 + mode_t invert_permissions = 0 < same_owner_option ? mode & (S_IRWXG | S_IRWXO) : 0;
481 mode_t current_mode = 0;
482 mode_t current_mode_mask = 0;
484 @@ -924,7 +1013,17 @@ extract_file (char *file_name, int typef
488 + int file_created = 0;
489 + if (set_xattr (file_name, ¤t_stat_info, invert_permissions,
490 + typeflag, &file_created))
493 + open_error (file_name);
497 while ((fd = open_output_file (file_name, typeflag, mode,
499 ¤t_mode, ¤t_mode_mask))
502 @@ -1065,6 +1164,13 @@ create_placeholder_file (char *file_name
503 + strlen (file_name) + 1);
504 p->sources->next = 0;
505 strcpy (p->sources->string, file_name);
506 + p->cntx_name = NULL;
507 + assign_string (&p->cntx_name, current_stat_info.cntx_name);
508 + p->acls_a_ptr = NULL;
510 + p->acls_d_ptr = NULL;
512 + xheader_xattr_copy (¤t_stat_info, &p->xattr_map, &p->xattr_map_size);
513 strcpy (p->target, current_stat_info.link_name);
515 h = delayed_set_stat_head;
516 @@ -1499,6 +1605,13 @@ apply_delayed_links (void)
517 st1.stat.st_gid = ds->gid;
518 st1.atime = ds->atime;
519 st1.mtime = ds->mtime;
520 + st1.cntx_name = ds->cntx_name;
521 + st1.acls_a_ptr = ds->acls_a_ptr;
522 + st1.acls_a_len = ds->acls_a_len;
523 + st1.acls_d_ptr = ds->acls_d_ptr;
524 + st1.acls_d_len = ds->acls_d_len;
525 + st1.xattr_map = ds->xattr_map;
526 + st1.xattr_map_size = ds->xattr_map_size;
527 set_stat (source, &st1, -1, 0, 0, SYMTYPE,
528 false, AT_SYMLINK_NOFOLLOW);
529 valid_source = source;
530 @@ -1513,6 +1626,9 @@ apply_delayed_links (void)
534 + xheader_xattr_free (ds->xattr_map, ds->xattr_map_size);
535 + free (ds->cntx_name);
538 struct delayed_link *next = ds->next;
540 diff -urNp tar-1.24-orig/src/list.c tar-1.24/src/list.c
541 --- tar-1.24-orig/src/list.c 2010-10-25 09:15:14.216463863 +0200
542 +++ tar-1.24/src/list.c 2010-10-25 10:24:52.563213968 +0200
543 @@ -597,6 +597,13 @@ decode_header (union block *header, stru
544 assign_string (&stat_info->gname,
545 header->header.gname[0] ? header->header.gname : NULL);
547 + stat_info->acls_a_ptr = NULL;
548 + stat_info->acls_a_len = 0;
549 + stat_info->acls_d_ptr = NULL;
550 + stat_info->acls_d_len = 0;
551 + stat_info->cntx_name = NULL;
552 + xheader_xattr_init(stat_info);
554 if (format == OLDGNU_FORMAT && incremental_option)
556 stat_info->atime.tv_sec = TIME_FROM_HEADER (header->oldgnu_header.atime);
557 diff -urNp tar-1.24-orig/src/Makefile.am tar-1.24/src/Makefile.am
558 --- tar-1.24-orig/src/Makefile.am 2010-10-24 20:07:54.000000000 +0200
559 +++ tar-1.24/src/Makefile.am 2010-10-25 10:24:52.564214456 +0200
564 -noinst_HEADERS = arith.h common.h tar.h
565 +noinst_HEADERS = arith.h common.h tar.h xattrs.h
569 @@ -42,10 +42,11 @@ tar_SOURCES = \
577 INCLUDES = -I$(top_srcdir)/gnu -I../ -I../gnu -I$(top_srcdir)/lib -I../lib
579 LDADD = ../lib/libtar.a ../gnu/libgnu.a $(LIBINTL) $(LIBICONV)
581 -tar_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) $(LIB_EACCESS)
582 +tar_LDADD = $(LIBS) $(LDADD) $(LIB_CLOCK_GETTIME) $(LIB_EACCESS)
583 diff -urNp tar-1.24-orig/src/tar.c tar-1.24/src/tar.c
584 --- tar-1.24-orig/src/tar.c 2010-10-24 20:07:55.000000000 +0200
585 +++ tar-1.24/src/tar.c 2010-10-25 10:24:52.565223676 +0200
586 @@ -255,7 +255,8 @@ tar_set_quoting_style (char *arg)
590 - ANCHORED_OPTION = CHAR_MAX + 1,
591 + ACLS_OPTION = CHAR_MAX + 1,
593 ATIME_PRESERVE_OPTION,
596 @@ -288,6 +289,7 @@ enum
602 NO_AUTO_COMPRESS_OPTION,
603 NO_CHECK_DEVICE_OPTION,
604 @@ -301,9 +303,11 @@ enum
605 NO_SAME_OWNER_OPTION,
606 NO_SAME_PERMISSIONS_OPTION,
608 + NO_SELINUX_CONTEXT_OPTION,
610 NO_WILDCARDS_MATCH_SLASH_OPTION,
614 NUMERIC_OWNER_OPTION,
616 @@ -325,6 +329,7 @@ enum
620 + SELINUX_CONTEXT_OPTION,
621 SHOW_DEFAULTS_OPTION,
622 SHOW_OMITTED_DIRS_OPTION,
623 SHOW_TRANSFORMED_NAMES_OPTION,
624 @@ -340,7 +345,8 @@ enum
627 WILDCARDS_MATCH_SLASH_OPTION,
633 const char *argp_program_version = "tar (" PACKAGE_NAME ") " VERSION;
634 @@ -486,6 +492,10 @@ static struct argp_option options[] = {
636 N_("Handling of file attributes:"), GRID },
638 + {"acls", ACLS_OPTION, 0, 0,
639 + N_("Save the ACLs to the archive"), GRID+1 },
640 + {"no-acls", NO_ACLS_OPTION, 0, 0,
641 + N_("Don't extract the ACLs from the archive"), GRID+1 },
642 {"owner", OWNER_OPTION, N_("NAME"), 0,
643 N_("force NAME as owner for added files"), GRID+1 },
644 {"group", GROUP_OPTION, N_("NAME"), 0,
645 @@ -516,6 +526,14 @@ static struct argp_option options[] = {
646 {"preserve-order", 's', 0, 0,
647 N_("sort names to extract to match archive"), GRID+1 },
648 {"same-order", 0, 0, OPTION_ALIAS, NULL, GRID+1 },
649 + {"selinux", SELINUX_CONTEXT_OPTION, 0, 0,
650 + N_("Save the SELinux context to the archive"), GRID+1 },
651 + {"no-selinux", NO_SELINUX_CONTEXT_OPTION, 0, 0,
652 + N_("Don't extract the SELinux context from the archive"), GRID+1 },
653 + {"xattrs", XATTR_OPTION, 0, 0,
654 + N_("Save the user/root xattrs to the archive"), GRID+1 },
655 + {"no-xattrs", NO_XATTR_OPTION, 0, 0,
656 + N_("Don't extract the user/root xattrs from the archive"), GRID+1 },
657 {"preserve", PRESERVE_OPTION, 0, 0,
658 N_("same as both -p and -s"), GRID+1 },
659 {"delay-directory-restore", DELAY_DIRECTORY_RESTORE_OPTION, 0, 0,
660 @@ -2079,6 +2097,37 @@ parse_opt (int key, char *arg, struct ar
661 same_permissions_option = -1;
665 + set_archive_format ("posix");
669 + case NO_ACLS_OPTION:
673 + case SELINUX_CONTEXT_OPTION:
674 + set_archive_format ("posix");
675 + selinux_context_option = 1;
678 + case NO_SELINUX_CONTEXT_OPTION:
679 + selinux_context_option = -1;
683 + set_archive_format ("posix");
684 + if (!acls_option) acls_option = 1;
685 + if (!selinux_context_option) selinux_context_option = 1;
689 + case NO_XATTR_OPTION:
690 + if (!acls_option) acls_option = -1;
691 + if (!selinux_context_option) selinux_context_option = -1;
692 + xattrs_option = -1;
695 case RECURSION_OPTION:
696 recursion_option = FNM_LEADING_DIR;
698 @@ -2461,6 +2510,29 @@ decode_options (int argc, char **argv)
699 || subcommand_option != LIST_SUBCOMMAND))
700 USAGE_ERROR ((0, 0, _("--pax-option can be used only on POSIX archives")));
702 + /* star create's non-POSIX typed archives with xattr support, so allow the
704 + if ((acls_option > 0)
705 + && archive_format != POSIX_FORMAT
706 + && (subcommand_option != EXTRACT_SUBCOMMAND
707 + || subcommand_option != DIFF_SUBCOMMAND
708 + || subcommand_option != LIST_SUBCOMMAND))
709 + USAGE_ERROR ((0, 0, _("--acls can be used only on POSIX archives")));
711 + if ((selinux_context_option > 0)
712 + && archive_format != POSIX_FORMAT
713 + && (subcommand_option != EXTRACT_SUBCOMMAND
714 + || subcommand_option != DIFF_SUBCOMMAND
715 + || subcommand_option != LIST_SUBCOMMAND))
716 + USAGE_ERROR ((0, 0, _("--selinux can be used only on POSIX archives")));
718 + if ((xattrs_option > 0)
719 + && archive_format != POSIX_FORMAT
720 + && (subcommand_option != EXTRACT_SUBCOMMAND
721 + || subcommand_option != DIFF_SUBCOMMAND
722 + || subcommand_option != LIST_SUBCOMMAND))
723 + USAGE_ERROR ((0, 0, _("--xattrs can be used only on POSIX archives")));
725 /* If ready to unlink hierarchies, so we are for simpler files. */
726 if (recursive_unlink_option)
727 old_files_option = UNLINK_FIRST_OLD_FILES;
728 @@ -2713,11 +2785,15 @@ void
729 tar_stat_destroy (struct tar_stat_info *st)
732 + xheader_xattr_free (st->xattr_map, st->xattr_map_size);
733 free (st->orig_file_name);
734 free (st->file_name);
735 free (st->link_name);
738 + free (st->cntx_name);
739 + free (st->acls_a_ptr);
740 + free (st->acls_d_ptr);
741 free (st->sparse_map);
743 xheader_destroy (&st->xhdr);
744 diff -urNp tar-1.24-orig/src/tar.h tar-1.24/src/tar.h
745 --- tar-1.24-orig/src/tar.h 2010-10-24 20:07:46.000000000 +0200
746 +++ tar-1.24/src/tar.h 2010-10-25 10:24:52.567223606 +0200
747 @@ -276,6 +276,14 @@ struct xheader
748 uintmax_t string_length;
751 +/* Information about xattrs for a file. */
761 char *orig_file_name; /* name of file read from the archive header */
762 @@ -287,6 +295,15 @@ struct tar_stat_info
764 char *uname; /* user name of owner */
765 char *gname; /* group name of owner */
767 + char *cntx_name; /* SELinux context for the current archive entry. */
769 + char *acls_a_ptr; /* Access ACLs for the current archive entry. */
770 + size_t acls_a_len; /* Access ACLs for the current archive entry. */
772 + char *acls_d_ptr; /* Default ACLs for the current archive entry. */
773 + size_t acls_d_len; /* Default ACLs for the current archive entry. */
775 struct stat stat; /* regular filesystem stat */
777 /* STAT doesn't always have access, data modification, and status
778 @@ -309,6 +326,9 @@ struct tar_stat_info
779 size_t sparse_map_size; /* Size of the sparse map */
780 struct sp_array *sparse_map;
782 + size_t xattr_map_size; /* Size of the xattr map */
783 + struct xattr_array *xattr_map;
785 /* Extended headers */
788 diff -urNp tar-1.24-orig/src/xattrs.c tar-1.24/src/xattrs.c
789 --- tar-1.24-orig/src/xattrs.c 1970-01-01 01:00:00.000000000 +0100
790 +++ tar-1.24/src/xattrs.c 2010-10-25 10:24:52.568214736 +0200
792 +/* Create a tar archive.
794 + Copyright (C) 2006 Free Software Foundation, Inc.
796 + Written by James Antill, on 2006-07-27.
798 + This program is free software; you can redistribute it and/or modify it
799 + under the terms of the GNU General Public License as published by the
800 + Free Software Foundation; either version 2, or (at your option) any later
803 + This program is distributed in the hope that it will be useful, but
804 + WITHOUT ANY WARRANTY; without even the implied warranty of
805 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
806 + Public License for more details.
808 + You should have received a copy of the GNU General Public License along
809 + with this program; if not, write to the Free Software Foundation, Inc.,
810 + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
814 +#include <quotearg.h>
819 +#ifndef HAVE_SELINUX_SELINUX_H
820 +# undef HAVE_LIBSELINUX
823 +#ifndef HAVE_ATTR_XATTR_H
827 +#ifndef HAVE_SYS_ACL_H
831 +#ifdef HAVE_SELINUX_SELINUX_H
832 +# include <selinux/selinux.h>
835 +#ifdef HAVE_ATTR_XATTR_H
836 +# include <attr/xattr.h>
839 +#ifdef HAVE_SYS_ACL_H
840 +# include <sys/acl.h>
844 +#if 0 /* unused by xattr's atm. */
845 +static void xattrs__fd_get(struct tar_stat_info *st,
846 + char const *file_name, int fd, const char *attr,
847 + char **ret_ptr, size_t *ret_len)
850 + static ssize_t asz = 1024;
852 + static char *val = NULL;
854 + if (!val) val = xmalloc (asz);
856 + while (((ret = fgetxattr (fd, attr, val, asz)) == -1) &&
860 + val = xrealloc (val, asz);
865 + *ret_ptr = xmemdup (val, ret + 1);
868 + else if (errno != ENOATTR)
869 + call_arg_warn ("fgetxattr", file_name);
874 +static void xattrs__acls_get_a(struct tar_stat_info *st,
875 + char const *file_name, int fd,
876 + char **ret_ptr, size_t *ret_len)
877 +{ /* "system.posix_acl_access" */
885 + if ((acl = acl_get_fd (fd)) == (acl_t)NULL)
887 + if (errno != ENOTSUP)
888 + call_arg_warn ("acl_get_fd", file_name);
892 + else if ((acl = acl_get_file (file_name, ACL_TYPE_ACCESS)) == (acl_t)NULL)
894 + if (errno != ENOTSUP)
895 + call_arg_warn ("acl_get_file", file_name);
900 + val = acl_to_text(acl, &len);
905 + call_arg_warn ("acl_to_text", file_name);
909 + *ret_ptr = xstrdup (val);
916 +static void xattrs__acls_get_d(struct tar_stat_info *st,
917 + char const *file_name,
918 + char **ret_ptr, size_t *ret_len)
919 +{ /* "system.posix_acl_default" */
925 + if ((acl = acl_get_file (file_name, ACL_TYPE_DEFAULT)) == (acl_t)NULL)
927 + if (errno != ENOTSUP)
928 + call_arg_warn ("acl_get_file", file_name);
932 + val = acl_to_text(acl, &len);
937 + call_arg_warn ("acl_to_text", file_name);
941 + *ret_ptr = xstrdup (val);
948 +void xattrs_acls_get(struct tar_stat_info *st, char const *file_name, int fd,
951 + if (acls_option > 0)
954 + static int done = 0;
956 + WARN ((0, 0, _("ACL support requested, but not available")));
959 + xattrs__acls_get_a (st, file_name, fd,
960 + &st->acls_a_ptr, &st->acls_a_len);
962 + xattrs__acls_get_d (st, file_name,
963 + &st->acls_d_ptr, &st->acls_d_len);
967 +void xattrs_selinux_get(struct tar_stat_info *st, char const *file_name, int fd)
969 + if (selinux_context_option > 0)
971 +#ifndef HAVE_LIBSELINUX
972 + static int done = 0;
974 + WARN ((0, 0, _("SELinux support requested, but not available")));
979 + if ((lgetfilecon (file_name, &st->cntx_name) == -1) && (errno != ENOTSUP) && (errno != ENODATA))
980 + call_arg_warn ("lgetfilecon", file_name);
982 + else if ((fgetfilecon (fd, &st->cntx_name) == -1) && (errno != ENOTSUP) && (errno != ENODATA))
983 + call_arg_warn ("fgetfilecon", file_name);
988 +void xattrs_xattrs_get(struct tar_stat_info *st, char const *file_name, int fd)
990 + if (xattrs_option > 0)
991 + { /* get all xattrs ... this include security.* and system.* if
992 + available. We filter them here, but we have to filter them
993 + in xattrs_xattrs_set() anyway.
995 + static ssize_t xsz = 1024;
996 + static char *xatrs = NULL;
1000 + static int done = 0;
1001 + if ((xattrs_option > 0) && !done)
1002 + WARN ((0, 0, _("Xattr support requested, but not available")));
1006 + if (!xatrs) xatrs = xmalloc (xsz);
1008 + while (((fd == -1) ?
1009 + ((xret = llistxattr (file_name, xatrs, xsz)) == -1) :
1010 + ((xret = flistxattr (fd, xatrs, xsz)) == -1)) &&
1011 + (errno == ERANGE))
1014 + xatrs = xrealloc (xatrs, xsz);
1018 + call_arg_warn ((fd == -1) ? "llistxattrs" : "flistxattrs", file_name);
1021 + const char *attr = xatrs;
1022 + static ssize_t asz = 1024;
1023 + static char *val = NULL;
1025 + if (!val) val = xmalloc (asz);
1029 + size_t len = strlen (attr);
1032 + /* Archive all xattrs during creation, decide at extraction time
1033 + * which ones are of interest/use for the target filesystem. */
1034 + while (((fd == -1) ?
1035 + ((aret = lgetxattr (file_name, attr, val, asz)) == -1) :
1036 + ((aret = fgetxattr (fd, attr, val, asz)) == -1)) &&
1037 + (errno == ERANGE))
1040 + val = xrealloc (val, asz);
1044 + xheader_xattr_add (st, attr, val, aret);
1045 + else if (errno != ENOATTR)
1046 + call_arg_warn ((fd==-1) ? "lgetxattr" : "fgetxattr", file_name);
1056 +static void xattrs__fd_set(struct tar_stat_info const *st,
1057 + char const *file_name, char typeflag,
1059 + const char *ptr, size_t len)
1064 + const char *sysname = "setxattr";
1067 + if (typeflag != SYMTYPE)
1068 + ret = setxattr (file_name, attr, ptr, len, 0);
1071 + sysname = "lsetxattr";
1072 + ret = lsetxattr (file_name, attr, ptr, len, 0);
1075 + /* do not print warnings when SELinux is disabled */
1076 + if ((ret == -1) && (errno != EPERM) && (errno != ENOTSUP))
1077 + call_arg_error(sysname, file_name);
1082 +/* convert unix permissions into an ACL ... needed due to "default" ACLs */
1084 +static acl_t perms2acl(int perms)
1086 + char val[] = "user::---,group::---,other::---";
1087 + /* 0123456789 123456789 123456789 123456789 */
1090 + if (perms & 0400) val[ 6] = 'r';
1091 + if (perms & 0200) val[ 7] = 'w';
1092 + if (perms & 0100) val[ 8] = 'x';
1095 + if (perms & 0040) val[17] = 'r';
1096 + if (perms & 0020) val[18] = 'w';
1097 + if (perms & 0010) val[19] = 'x';
1100 + if (perms & 0004) val[28] = 'r';
1101 + if (perms & 0002) val[29] = 'w';
1102 + if (perms & 0001) val[30] = 'x';
1104 + return (acl_from_text (val));
1108 +static char *skip_to_ext_fields(char *ptr)
1110 + ptr += strcspn(ptr, ":,\n"); /* skip tag name. Ie. user/group/default/mask */
1113 + return (ptr); /* error? no user/group field */
1116 + ptr += strcspn(ptr, ":,\n"); /* skip user/group name */
1119 + return (ptr); /* error? no perms field */
1122 + ptr += strcspn(ptr, ":,\n"); /* skip perms */
1125 + return (ptr); /* no extra fields */
1130 +/* The POSIX draft allows extra fields after the three main ones. Star
1131 + uses this to add a fourth field for user/group which is the numeric ID.
1132 + We just skip all extra fields atm. */
1133 +static const char *fixup_extra_acl_fields(const char *ptr)
1135 + char *src = (char *)ptr;
1136 + char *dst = (char *)ptr;
1140 + const char *old = src;
1143 + src = skip_to_ext_fields(src);
1145 + if (old != dst) memmove(dst, old, len);
1148 + if (*src == ':') /* We have extra fields, skip them all */
1149 + src += strcspn(src, "\n,");
1151 + if ((*src == '\n') || (*src == ','))
1152 + *dst++ = *src++; /* also done when dst == src, but that's ok */
1160 +static void xattrs__acls_set(struct tar_stat_info const *st,
1161 + char const *file_name, int type,
1162 + const char *ptr, size_t len)
1163 +{ /* "system.posix_acl_access" */
1169 + /* assert (strlen (ptr) == len); */
1170 + ptr = fixup_extra_acl_fields(ptr);
1172 + acl = acl_from_text (ptr);
1175 + else if (acls_option > 0)
1176 + acl = perms2acl (st->stat.st_mode);
1178 + return; /* don't call acl functions unless we first hit an ACL, or
1179 + --acls was passed explicitly */
1181 + if (acl == (acl_t)NULL)
1183 + call_arg_warn ("acl_from_text", file_name);
1187 + if (acl_set_file (file_name, type, acl) == -1)
1189 + if (errno != ENOTSUP)
1190 + call_arg_warn ("acl_set_file", file_name);
1196 +void xattrs_acls_set(struct tar_stat_info const *st,
1197 + char const *file_name, char typeflag)
1199 + if ((acls_option >= 0) && (typeflag != SYMTYPE))
1201 +#ifndef HAVE_LIBACL
1202 + static int done = 0;
1204 + WARN ((0, 0, _("ACL support requested, but not available")));
1207 + xattrs__acls_set (st, file_name, ACL_TYPE_ACCESS,
1208 + st->acls_a_ptr, st->acls_a_len);
1209 + if ((typeflag == DIRTYPE) || (typeflag == GNUTYPE_DUMPDIR))
1210 + xattrs__acls_set (st, file_name, ACL_TYPE_DEFAULT,
1211 + st->acls_d_ptr, st->acls_d_len);
1216 +void xattrs_selinux_set(struct tar_stat_info const *st,
1217 + char const *file_name, char typeflag)
1219 + if ((selinux_context_option >= 0) && st->cntx_name)
1221 + const char *sysname = "setfilecon";
1224 +#ifndef HAVE_LIBSELINUX
1225 + static int done = 0;
1227 + WARN ((0, 0, _("SELinux support requested, but not available")));
1230 + if (typeflag != SYMTYPE)
1231 + ret = setfilecon (file_name, st->cntx_name);
1234 + sysname = "lsetfilecon";
1235 + ret = lsetfilecon (file_name, st->cntx_name);
1238 + if ((ret == -1) && (errno == EPERM))
1239 + call_arg_warn(sysname, file_name);
1240 + else if ((ret == -1) && (errno != EOPNOTSUPP))
1241 + call_arg_error(sysname, file_name);
1246 +void xattrs_xattrs_set(struct tar_stat_info const *st,
1247 + char const *file_name, char typeflag)
1249 + if ((xattrs_option >= 0) && st->xattr_map_size)
1253 +#ifndef HAVE_XATTRS
1254 + static int done = 0;
1256 + WARN ((0, 0, _("Xattr support requested, but not available")));
1259 + while (scan < st->xattr_map_size)
1261 + char *keyword = st->xattr_map[scan].xkey;
1263 + /* assert (!memcpy (keyword, "SCHILY.xattr.", strlen("SCHILY.xattr."))); */
1264 + keyword += strlen("SCHILY.xattr.");
1266 + if (strncmp (keyword, "user.", strlen("user.")) &&
1267 + strncmp (keyword, "lustre.", strlen("lustre.")) &&
1268 + strncmp (keyword, "trusted.", strlen("trusted.")) &&
1269 + strncmp (keyword, "security.NTACL", strlen("security.NTACL")))
1270 + continue; /* don't try and set anything but normal xattrs */
1272 + xattrs__fd_set (st, file_name, typeflag, keyword,
1273 + st->xattr_map[scan].xval_ptr,
1274 + st->xattr_map[scan].xval_len);
1281 diff -urNp tar-1.24-orig/src/xattrs.h tar-1.24/src/xattrs.h
1282 --- tar-1.24-orig/src/xattrs.h 1970-01-01 01:00:00.000000000 +0100
1283 +++ tar-1.24/src/xattrs.h 2010-10-25 10:24:52.569214526 +0200
1286 +extern void xattrs_acls_get(struct tar_stat_info *st,
1287 + char const *file_name, int fd, int xisfile);
1288 +extern void xattrs_selinux_get(struct tar_stat_info *st,
1289 + char const *file_name, int fd);
1290 +extern void xattrs_xattrs_get(struct tar_stat_info *st,
1291 + char const *file_name, int fd);
1293 +extern void xattrs_acls_set(struct tar_stat_info const *st,
1294 + char const *file_name, char typeflag);
1295 +extern void xattrs_selinux_set(struct tar_stat_info const *st,
1296 + char const *file_name, char typeflag);
1297 +extern void xattrs_xattrs_set(struct tar_stat_info const *st,
1298 + char const *file_name, char typeflag);
1299 diff -urNp tar-1.24-orig/src/xheader.c tar-1.24/src/xheader.c
1300 --- tar-1.24-orig/src/xheader.c 2010-10-24 20:07:46.000000000 +0200
1301 +++ tar-1.24/src/xheader.c 2010-10-25 10:24:52.570223396 +0200
1302 @@ -460,6 +460,74 @@ xheader_write_global (struct xheader *xh
1306 +void xheader_xattr_init(struct tar_stat_info *st)
1308 + st->xattr_map = NULL;
1309 + st->xattr_map_size = 0;
1312 +void xheader_xattr_free(struct xattr_array *xattr_map, size_t xattr_map_size)
1316 + while (scan < xattr_map_size)
1318 + free (xattr_map[scan].xkey);
1319 + free (xattr_map[scan].xval_ptr);
1326 +static void xheader_xattr__add(struct xattr_array **xattr_map,
1327 + size_t *xattr_map_size,
1328 + const char *key, const char *val, size_t len)
1330 + size_t pos = (*xattr_map_size)++;
1332 + *xattr_map = xrealloc (*xattr_map,
1333 + *xattr_map_size * sizeof(struct xattr_array));
1334 + (*xattr_map)[pos].xkey = xstrdup (key);
1335 + (*xattr_map)[pos].xval_ptr = xmemdup (val, len + 1);
1336 + (*xattr_map)[pos].xval_len = len;
1339 +void xheader_xattr_add(struct tar_stat_info *st,
1340 + const char *key, const char *val, size_t len)
1342 + size_t klen = strlen (key);
1343 + char *xkey = xmalloc (strlen("SCHILY.xattr.") + klen + 1);
1346 + tmp = stpcpy (tmp, "SCHILY.xattr.");
1347 + tmp = stpcpy (tmp, key);
1349 + xheader_xattr__add (&st->xattr_map, &st->xattr_map_size, xkey, val, len);
1354 +void xheader_xattr_copy(const struct tar_stat_info *st,
1355 + struct xattr_array **xattr_map, size_t *xattr_map_size)
1359 + *xattr_map = NULL;
1360 + *xattr_map_size = 0;
1362 + while (scan < st->xattr_map_size)
1364 + char *key = st->xattr_map[scan].xkey;
1365 + char *val = st->xattr_map[scan].xval_ptr;
1366 + size_t len = st->xattr_map[scan].xval_len;
1368 + xheader_xattr__add(xattr_map, xattr_map_size, key, val, len);
1375 /* General Interface */
1377 @@ -473,6 +541,7 @@ struct xhdr_tab
1378 struct xheader *, void const *data);
1379 void (*decoder) (struct tar_stat_info *, char const *, char const *, size_t);
1384 /* This declaration must be extern, because ISO C99 section 6.9.2
1385 @@ -489,8 +558,17 @@ locate_handler (char const *keyword)
1386 struct xhdr_tab const *p;
1388 for (p = xhdr_tab; p->keyword; p++)
1389 - if (strcmp (p->keyword, keyword) == 0)
1393 + if (strncmp (p->keyword, keyword, strlen(p->keyword)) == 0)
1398 + if (strcmp (p->keyword, keyword) == 0)
1405 @@ -500,7 +578,7 @@ xheader_protected_pattern_p (const char
1406 struct xhdr_tab const *p;
1408 for (p = xhdr_tab; p->keyword; p++)
1409 - if ((p->flags & XHDR_PROTECTED) && fnmatch (pattern, p->keyword, 0) == 0)
1410 + if (!p->prefix && (p->flags & XHDR_PROTECTED) && fnmatch (pattern, p->keyword, 0) == 0)
1414 @@ -511,7 +589,7 @@ xheader_protected_keyword_p (const char
1415 struct xhdr_tab const *p;
1417 for (p = xhdr_tab; p->keyword; p++)
1418 - if ((p->flags & XHDR_PROTECTED) && strcmp (p->keyword, keyword) == 0)
1419 + if (!p->prefix && (p->flags & XHDR_PROTECTED) && strcmp (p->keyword, keyword) == 0)
1423 @@ -1470,6 +1548,71 @@ volume_filename_decoder (struct tar_stat
1427 +xattr_selinux_coder (struct tar_stat_info const *st, char const *keyword,
1428 + struct xheader *xhdr, void const *data)
1430 + code_string (st->cntx_name, keyword, xhdr);
1434 +xattr_selinux_decoder (struct tar_stat_info *st,
1435 + char const *keyword, char const *arg, size_t size)
1437 + decode_string (&st->cntx_name, arg);
1441 +xattr_acls_a_coder (struct tar_stat_info const *st , char const *keyword,
1442 + struct xheader *xhdr, void const *data)
1444 + xheader_print_n (xhdr, keyword, st->acls_a_ptr, st->acls_a_len);
1448 +xattr_acls_a_decoder (struct tar_stat_info *st,
1449 + char const *keyword, char const *arg, size_t size)
1451 + st->acls_a_ptr = xmemdup (arg, size + 1);
1452 + st->acls_a_len = size;
1456 +xattr_acls_d_coder (struct tar_stat_info const *st , char const *keyword,
1457 + struct xheader *xhdr, void const *data)
1459 + xheader_print_n (xhdr, keyword, st->acls_d_ptr, st->acls_d_len);
1463 +xattr_acls_d_decoder (struct tar_stat_info *st,
1464 + char const *keyword, char const *arg, size_t size)
1466 + st->acls_d_ptr = xmemdup (arg, size + 1);
1467 + st->acls_d_len = size;
1471 +xattr_coder (struct tar_stat_info const *st , char const *keyword,
1472 + struct xheader *xhdr, void const *data)
1474 + struct xattr_array *xattr_map = st->xattr_map;
1475 + const size_t *off = data;
1476 + xheader_print_n (xhdr, keyword,
1477 + xattr_map[*off].xval_ptr, xattr_map[*off].xval_len);
1481 +xattr_decoder (struct tar_stat_info *st,
1482 + char const *keyword, char const *arg, size_t size)
1484 + char *xstr = NULL;
1486 + xstr = xmemdup(arg, size + 1);
1487 + xheader_xattr_add(st, keyword + strlen("SCHILY.xattr."), xstr, size);
1492 sparse_major_coder (struct tar_stat_info const *st, char const *keyword,
1493 struct xheader *xhdr, void const *data)
1495 @@ -1506,53 +1649,53 @@ sparse_minor_decoder (struct tar_stat_in
1498 struct xhdr_tab const xhdr_tab[] = {
1499 - { "atime", atime_coder, atime_decoder, 0 },
1500 - { "comment", dummy_coder, dummy_decoder, 0 },
1501 - { "charset", dummy_coder, dummy_decoder, 0 },
1502 - { "ctime", ctime_coder, ctime_decoder, 0 },
1503 - { "gid", gid_coder, gid_decoder, 0 },
1504 - { "gname", gname_coder, gname_decoder, 0 },
1505 - { "linkpath", linkpath_coder, linkpath_decoder, 0 },
1506 - { "mtime", mtime_coder, mtime_decoder, 0 },
1507 - { "path", path_coder, path_decoder, 0 },
1508 - { "size", size_coder, size_decoder, 0 },
1509 - { "uid", uid_coder, uid_decoder, 0 },
1510 - { "uname", uname_coder, uname_decoder, 0 },
1511 + { "atime", atime_coder, atime_decoder, 0, false },
1512 + { "comment", dummy_coder, dummy_decoder, 0, false },
1513 + { "charset", dummy_coder, dummy_decoder, 0, false },
1514 + { "ctime", ctime_coder, ctime_decoder, 0, false },
1515 + { "gid", gid_coder, gid_decoder, 0, false },
1516 + { "gname", gname_coder, gname_decoder, 0, false },
1517 + { "linkpath", linkpath_coder, linkpath_decoder, 0, false },
1518 + { "mtime", mtime_coder, mtime_decoder, 0, false },
1519 + { "path", path_coder, path_decoder, 0, false },
1520 + { "size", size_coder, size_decoder, 0, false },
1521 + { "uid", uid_coder, uid_decoder, 0, false },
1522 + { "uname", uname_coder, uname_decoder, 0, false },
1524 /* Sparse file handling */
1525 { "GNU.sparse.name", path_coder, path_decoder,
1527 + XHDR_PROTECTED, false },
1528 { "GNU.sparse.major", sparse_major_coder, sparse_major_decoder,
1530 + XHDR_PROTECTED, false },
1531 { "GNU.sparse.minor", sparse_minor_coder, sparse_minor_decoder,
1533 + XHDR_PROTECTED, false },
1534 { "GNU.sparse.realsize", sparse_size_coder, sparse_size_decoder,
1536 + XHDR_PROTECTED, false },
1537 { "GNU.sparse.numblocks", sparse_numblocks_coder, sparse_numblocks_decoder,
1539 + XHDR_PROTECTED, false },
1541 /* tar 1.14 - 1.15.90 keywords. */
1542 { "GNU.sparse.size", sparse_size_coder, sparse_size_decoder,
1544 + XHDR_PROTECTED, false },
1545 /* tar 1.14 - 1.15.1 keywords. Multiple instances of these appeared in 'x'
1546 headers, and each of them was meaningful. It confilcted with POSIX specs,
1547 which requires that "when extended header records conflict, the last one
1548 given in the header shall take precedence." */
1549 { "GNU.sparse.offset", sparse_offset_coder, sparse_offset_decoder,
1551 + XHDR_PROTECTED, false },
1552 { "GNU.sparse.numbytes", sparse_numbytes_coder, sparse_numbytes_decoder,
1554 + XHDR_PROTECTED, false },
1555 /* tar 1.15.90 keyword, introduced to remove the above-mentioned conflict. */
1556 { "GNU.sparse.map", NULL /* Unused, see pax_dump_header() */,
1557 - sparse_map_decoder, 0 },
1558 + sparse_map_decoder, 0, false },
1560 { "GNU.dumpdir", dumpdir_coder, dumpdir_decoder,
1562 + XHDR_PROTECTED, false },
1564 /* Keeps the tape/volume label. May be present only in the global headers.
1565 Equivalent to GNUTYPE_VOLHDR. */
1566 { "GNU.volume.label", volume_label_coder, volume_label_decoder,
1567 - XHDR_PROTECTED | XHDR_GLOBAL },
1568 + XHDR_PROTECTED | XHDR_GLOBAL, false },
1570 /* These may be present in a first global header of the archive.
1571 They provide the same functionality as GNUTYPE_MULTIVOL header.
1572 @@ -1561,11 +1704,41 @@ struct xhdr_tab const xhdr_tab[] = {
1573 GNU.volume.offset keeps the offset of the start of this volume,
1574 otherwise kept in oldgnu_header.offset. */
1575 { "GNU.volume.filename", volume_label_coder, volume_filename_decoder,
1576 - XHDR_PROTECTED | XHDR_GLOBAL },
1577 + XHDR_PROTECTED | XHDR_GLOBAL, false },
1578 { "GNU.volume.size", volume_size_coder, volume_size_decoder,
1579 - XHDR_PROTECTED | XHDR_GLOBAL },
1580 + XHDR_PROTECTED | XHDR_GLOBAL, false },
1581 { "GNU.volume.offset", volume_offset_coder, volume_offset_decoder,
1582 - XHDR_PROTECTED | XHDR_GLOBAL },
1583 + XHDR_PROTECTED | XHDR_GLOBAL, false },
1585 + /* We get the SELinux value from filecon, so add a namespace for SELinux
1586 + instead of storing it in SCHILY.xattr.* (which would be RAW). */
1587 + { "RHT.security.selinux",
1588 + xattr_selinux_coder, xattr_selinux_decoder, 0, false },
1590 + /* ACLs, use the star format... */
1591 + { "SCHILY.acl.access",
1592 + xattr_acls_a_coder, xattr_acls_a_decoder, 0, false },
1594 + { "SCHILY.acl.default",
1595 + xattr_acls_d_coder, xattr_acls_d_decoder, 0, false },
1597 + /* FIXME: These are compat. for FC-6 ... we shipped a tar using the generic
1598 + header names by accident. */
1599 + { "SCHILY.xattr.security.selinux",
1600 + xattr_selinux_coder, xattr_selinux_decoder, 0, false },
1601 + { "SCHILY.xattr.system.posix_acl_access",
1602 + xattr_acls_a_coder, xattr_acls_a_decoder, 0, false },
1603 + { "SCHILY.xattr.system.posix_acl_default",
1604 + xattr_acls_d_coder, xattr_acls_d_decoder, 0, false },
1606 + /* xattrs use the star format. note we only save some variants... */
1607 + { "SCHILY.xattr.user", xattr_coder, xattr_decoder, 0, true },
1608 + { "SCHILY.xattr.trusted", xattr_coder, xattr_decoder, 0, true },
1609 + { "SCHILY.xattr.lustre", xattr_coder, xattr_decoder, 0, true },
1610 + { "SCHILY.xattr.security.NTACL", xattr_coder, xattr_decoder, 0, true },
1612 + /* ignore everything else in the xattr namespaces... */
1613 + { "SCHILY.xattr", dummy_coder, dummy_decoder, 0, true },
1615 - { NULL, NULL, NULL, 0 }
1616 + { NULL, NULL, NULL, 0, false }