Fix savannah bug #63250
[tar.git] / src / xheader.c
blobdfab650042d0356e3ff9ea5fe12e4f830c4c41fa
1 /* POSIX extended headers for tar.
3 Copyright (C) 2003-2022 Free Software Foundation, Inc.
5 This file is part of GNU tar.
7 GNU tar is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 GNU tar is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
20 #include <system.h>
22 #include <fnmatch.h>
23 #include <hash.h>
24 #include <inttostr.h>
25 #include <quotearg.h>
27 #include "common.h"
29 static void xheader_init (struct xheader *xhdr);
30 static bool xheader_protected_pattern_p (char const *pattern);
31 static bool xheader_protected_keyword_p (char const *keyword);
33 /* Used by xheader_finish() */
34 static void code_string (char const *string, char const *keyword,
35 struct xheader *xhdr);
37 /* Number of global headers written so far. */
38 static size_t global_header_count;
39 /* FIXME: Possibly it should be reset after changing the volume.
40 POSIX %n specification says that it is expanded to the sequence
41 number of current global header in *the* archive. However, for
42 multi-volume archives this will yield duplicate header names
43 in different volumes, which I'd like to avoid. The best way
44 to solve this would be to use per-archive header count as required
45 by POSIX *and* set globexthdr.name to, say,
46 $TMPDIR/GlobalHead.%p.$NUMVOLUME.%n.
48 However it should wait until buffer.c is finally rewritten */
51 /* Interface functions to obstacks */
53 static void
54 x_obstack_grow (struct xheader *xhdr, const char *ptr, size_t length)
56 obstack_grow (xhdr->stk, ptr, length);
57 xhdr->size += length;
60 static void
61 x_obstack_1grow (struct xheader *xhdr, char c)
63 obstack_1grow (xhdr->stk, c);
64 xhdr->size++;
67 static void
68 x_obstack_blank (struct xheader *xhdr, size_t length)
70 obstack_blank (xhdr->stk, length);
71 xhdr->size += length;
75 /* Keyword options */
77 struct keyword_list
79 struct keyword_list *next;
80 char *pattern;
81 char *value;
85 /* List of keyword patterns set by delete= option */
86 static struct keyword_list *keyword_pattern_list;
88 /* List of keyword/value pairs set by 'keyword=value' option */
89 static struct keyword_list *keyword_global_override_list;
91 /* List of keyword/value pairs set by 'keyword:=value' option */
92 static struct keyword_list *keyword_override_list;
94 /* List of keyword/value pairs decoded from the last 'g' type header */
95 static struct keyword_list *global_header_override_list;
97 /* Template for the name field of an 'x' type header */
98 static char *exthdr_name;
100 static char *exthdr_mtime_option;
101 static time_t exthdr_mtime;
103 /* Template for the name field of a 'g' type header */
104 static char *globexthdr_name;
106 static char *globexthdr_mtime_option;
107 static time_t globexthdr_mtime;
109 bool
110 xheader_keyword_deleted_p (const char *kw)
112 struct keyword_list *kp;
114 for (kp = keyword_pattern_list; kp; kp = kp->next)
115 if (fnmatch (kp->pattern, kw, 0) == 0)
116 return true;
117 return false;
120 static bool
121 xheader_keyword_override_p (const char *keyword)
123 struct keyword_list *kp;
125 for (kp = keyword_override_list; kp; kp = kp->next)
126 if (strcmp (kp->pattern, keyword) == 0)
127 return true;
128 return false;
131 static void
132 xheader_list_append (struct keyword_list **root, char const *kw,
133 char const *value)
135 struct keyword_list *kp = xmalloc (sizeof *kp);
136 kp->pattern = xstrdup (kw);
137 kp->value = value ? xstrdup (value) : NULL;
138 kp->next = *root;
139 *root = kp;
142 static void
143 xheader_list_destroy (struct keyword_list **root)
145 if (root)
147 struct keyword_list *kw = *root;
148 while (kw)
150 struct keyword_list *next = kw->next;
151 free (kw->pattern);
152 free (kw->value);
153 free (kw);
154 kw = next;
156 *root = NULL;
160 static _Noreturn void
161 xheader_set_single_keyword (char *kw)
163 USAGE_ERROR ((0, 0, _("Keyword %s is unknown or not yet implemented"), kw));
166 static void
167 assign_time_option (char **sval, time_t *tval, const char *input)
169 char *p;
170 struct timespec t = decode_timespec (input, &p, false);
171 if (! valid_timespec (t) || *p)
172 ERROR ((0, 0, _("Time stamp is out of allowed range")));
173 else
175 *tval = t.tv_sec;
176 assign_string (sval, input);
180 static void
181 xheader_set_keyword_equal (char *kw, char *eq)
183 bool global = true;
184 char *p = eq;
186 if (eq == kw)
187 USAGE_ERROR ((0, 0, _("Malformed pax option: %s"), quote (kw)));
189 if (eq[-1] == ':')
191 p--;
192 global = false;
195 while (p > kw && isspace ((unsigned char) *p))
196 p--;
198 *p = 0;
200 for (p = eq + 1; *p && isspace ((unsigned char) *p); p++)
203 if (strcmp (kw, "delete") == 0)
205 if (xheader_protected_pattern_p (p))
206 USAGE_ERROR ((0, 0, _("Pattern %s cannot be used"), quote (p)));
207 xheader_list_append (&keyword_pattern_list, p, NULL);
209 else if (strcmp (kw, "exthdr.name") == 0)
210 assign_string (&exthdr_name, p);
211 else if (strcmp (kw, "globexthdr.name") == 0)
212 assign_string (&globexthdr_name, p);
213 else if (strcmp (kw, "exthdr.mtime") == 0)
214 assign_time_option (&exthdr_mtime_option, &exthdr_mtime, p);
215 else if (strcmp (kw, "globexthdr.mtime") == 0)
216 assign_time_option (&globexthdr_mtime_option, &globexthdr_mtime, p);
217 else
219 if (xheader_protected_keyword_p (kw))
220 USAGE_ERROR ((0, 0, _("Keyword %s cannot be overridden"), kw));
221 if (global)
222 xheader_list_append (&keyword_global_override_list, kw, p);
223 else
224 xheader_list_append (&keyword_override_list, kw, p);
228 void
229 xheader_set_option (char *string)
231 char *token;
232 for (token = strtok (string, ","); token; token = strtok (NULL, ","))
234 char *p = strchr (token, '=');
235 if (!p)
236 xheader_set_single_keyword (token);
237 else
238 xheader_set_keyword_equal (token, p);
243 string Includes: Replaced By:
244 %d The directory name of the file,
245 equivalent to the result of the
246 dirname utility on the translated
247 file name.
248 %f The filename of the file, equivalent
249 to the result of the basename
250 utility on the translated file name.
251 %p The process ID of the pax process.
252 %n The value of the 3rd argument.
253 %% A '%' character. */
255 char *
256 xheader_format_name (struct tar_stat_info *st, const char *fmt, size_t n)
258 char *buf;
259 size_t len;
260 char *q;
261 const char *p;
262 char *dirp = NULL;
263 char *dir = NULL;
264 char *base = NULL;
265 char pidbuf[UINTMAX_STRSIZE_BOUND];
266 char const *pptr = NULL;
267 char nbuf[UINTMAX_STRSIZE_BOUND];
268 char const *nptr = NULL;
270 len = 0;
271 for (p = fmt; *p; p++)
273 if (*p == '%' && p[1])
275 switch (*++p)
277 case '%':
278 len++;
279 break;
281 case 'd':
282 if (st)
284 if (!dirp)
285 dirp = dir_name (st->orig_file_name);
286 dir = safer_name_suffix (dirp, false, absolute_names_option);
287 len += strlen (dir);
289 break;
291 case 'f':
292 if (st)
294 base = last_component (st->orig_file_name);
295 len += strlen (base);
297 break;
299 case 'p':
300 pptr = umaxtostr (getpid (), pidbuf);
301 len += pidbuf + sizeof pidbuf - 1 - pptr;
302 break;
304 case 'n':
305 nptr = umaxtostr (n, nbuf);
306 len += nbuf + sizeof nbuf - 1 - nptr;
307 break;
309 default:
310 len += 2;
313 else
314 len++;
317 buf = xmalloc (len + 1);
318 for (q = buf, p = fmt; *p; )
320 if (*p == '%')
322 switch (p[1])
324 case '%':
325 *q++ = *p++;
326 p++;
327 break;
329 case 'd':
330 if (dir)
331 q = stpcpy (q, dir);
332 p += 2;
333 break;
335 case 'f':
336 if (base)
337 q = stpcpy (q, base);
338 p += 2;
339 break;
341 case 'p':
342 q = stpcpy (q, pptr);
343 p += 2;
344 break;
346 case 'n':
347 q = stpcpy (q, nptr);
348 p += 2;
349 break;
352 default:
353 *q++ = *p++;
354 if (*p)
355 *q++ = *p++;
358 else
359 *q++ = *p++;
362 free (dirp);
364 /* Do not allow it to end in a slash */
365 while (q > buf && ISSLASH (q[-1]))
366 q--;
367 *q = 0;
368 return buf;
371 /* Table of templates for the names of POSIX extended headers.
372 Indexed by the the type of the header (per-file or global)
373 and POSIX compliance mode (0 or q depending on whether
374 POSIXLY_CORRECT environment variable is set. */
375 static const char *header_template[][2] = {
376 /* Individual header templates: */
377 { "%d/PaxHeaders/%f", "%d/PaxHeaders.%p/%f" },
378 /* Global header templates: */
379 { "/GlobalHead.%n", "/GlobalHead.%p.%n" }
381 /* Indices to the above table */
382 enum {
383 pax_file_header,
384 pax_global_header
386 /* Return the name for the POSIX extended header T */
387 #define HEADER_TEMPLATE(t) header_template[t][posixly_correct]
389 char *
390 xheader_xhdr_name (struct tar_stat_info *st)
392 if (!exthdr_name)
393 assign_string (&exthdr_name, HEADER_TEMPLATE (pax_file_header));
394 return xheader_format_name (st, exthdr_name, 0);
397 char *
398 xheader_ghdr_name (void)
400 if (!globexthdr_name)
402 size_t len;
403 const char *global_header_template = HEADER_TEMPLATE (pax_global_header);
404 const char *tmp = getenv ("TMPDIR");
405 if (!tmp)
406 tmp = "/tmp";
407 len = strlen (tmp) + strlen (global_header_template) + 1;
408 globexthdr_name = xmalloc (len);
409 strcpy(globexthdr_name, tmp);
410 strcat(globexthdr_name, global_header_template);
413 return xheader_format_name (NULL, globexthdr_name, global_header_count + 1);
416 void
417 xheader_write (char type, char *name, time_t t, struct xheader *xhdr)
419 union block *header;
420 size_t size;
421 char *p;
423 size = xhdr->size;
424 switch (type)
426 case XGLTYPE:
427 if (globexthdr_mtime_option)
428 t = globexthdr_mtime;
429 break;
431 case XHDTYPE:
432 if (exthdr_mtime_option)
433 t = exthdr_mtime;
434 break;
436 header = start_private_header (name, size, t);
437 header->header.typeflag = type;
439 simple_finish_header (header);
441 p = xhdr->buffer;
445 size_t len;
447 header = find_next_block ();
448 len = BLOCKSIZE;
449 if (len > size)
450 len = size;
451 memcpy (header->buffer, p, len);
452 if (len < BLOCKSIZE)
453 memset (header->buffer + len, 0, BLOCKSIZE - len);
454 p += len;
455 size -= len;
456 set_next_block_after (header);
458 while (size > 0);
459 xheader_destroy (xhdr);
461 if (type == XGLTYPE)
462 global_header_count++;
465 void
466 xheader_write_global (struct xheader *xhdr)
468 if (keyword_global_override_list)
470 struct keyword_list *kp;
472 xheader_init (xhdr);
473 for (kp = keyword_global_override_list; kp; kp = kp->next)
474 code_string (kp->value, kp->pattern, xhdr);
476 if (xhdr->stk)
478 char *name;
480 xheader_finish (xhdr);
481 name = xheader_ghdr_name ();
482 xheader_write (XGLTYPE, name, start_time.tv_sec, xhdr);
483 free (name);
487 /* Forbid modifications of the global extended header */
488 void
489 xheader_forbid_global (void)
491 if (keyword_global_override_list)
492 USAGE_ERROR ((0, 0, _("can't update global extended header record")));
495 /* This is reversal function for xattr_encode_keyword. See comment for
496 xattr_encode_keyword() for more info. */
497 static void
498 xattr_decode_keyword (char *keyword)
500 char *kpr, *kpl; /* keyword pointer left/right */
501 kpr = kpl = keyword;
503 for (;;)
505 if (*kpr == '%')
507 if (kpr[1] == '3' && kpr[2] == 'D')
509 *kpl = '=';
510 kpr += 3;
511 kpl ++;
512 continue;
514 else if (kpr[1] == '2' && kpr[2] == '5')
516 *kpl = '%';
517 kpr += 3;
518 kpl ++;
519 continue;
523 *kpl = *kpr;
525 if (*kpr == 0)
526 break;
528 kpr++;
529 kpl++;
533 /* General Interface */
535 #define XHDR_PROTECTED 0x01
536 #define XHDR_GLOBAL 0x02
538 struct xhdr_tab
540 char const *keyword;
541 void (*coder) (struct tar_stat_info const *, char const *,
542 struct xheader *, void const *data);
543 void (*decoder) (struct tar_stat_info *, char const *, char const *, size_t);
544 int flags;
545 bool prefix; /* select handler comparing prefix only */
548 /* This declaration must be extern, because ISO C99 section 6.9.2
549 prohibits a tentative definition that has both internal linkage and
550 incomplete type. If we made it static, we'd have to declare its
551 size which would be a maintenance pain; if we put its initializer
552 here, we'd need a boatload of forward declarations, which would be
553 even more of a pain. */
554 extern struct xhdr_tab const xhdr_tab[];
556 static struct xhdr_tab const *
557 locate_handler (char const *keyword)
559 struct xhdr_tab const *p;
560 for (p = xhdr_tab; p->keyword; p++)
561 if (p->prefix)
563 size_t kwlen = strlen (p->keyword);
564 if (keyword[kwlen] == '.' && strncmp (p->keyword, keyword, kwlen) == 0)
565 return p;
567 else
569 if (strcmp (p->keyword, keyword) == 0)
570 return p;
573 return NULL;
576 static bool
577 xheader_protected_pattern_p (const char *pattern)
579 struct xhdr_tab const *p;
581 for (p = xhdr_tab; p->keyword; p++)
582 if (!p->prefix && (p->flags & XHDR_PROTECTED)
583 && fnmatch (pattern, p->keyword, 0) == 0)
584 return true;
585 return false;
588 static bool
589 xheader_protected_keyword_p (const char *keyword)
591 struct xhdr_tab const *p;
593 for (p = xhdr_tab; p->keyword; p++)
594 if (!p->prefix && (p->flags & XHDR_PROTECTED)
595 && strcmp (p->keyword, keyword) == 0)
596 return true;
597 return false;
600 /* Decode a single extended header record, advancing *PTR to the next record.
601 Return true on success, false otherwise. */
602 static bool
603 decode_record (struct xheader *xhdr,
604 char **ptr,
605 void (*handler) (void *, char const *, char const *, size_t),
606 void *data)
608 char *start = *ptr;
609 char *p = start;
610 size_t len;
611 char *len_lim;
612 char const *keyword;
613 char *nextp;
614 size_t len_max = xhdr->buffer + xhdr->size - start;
616 while (*p == ' ' || *p == '\t')
617 p++;
619 if (! ISDIGIT (*p))
621 if (*p)
622 ERROR ((0, 0, _("Malformed extended header: missing length")));
623 return false;
626 len = strtoumax (p, &len_lim, 10);
628 if (len_max < len)
630 int len_len = len_lim - p;
631 ERROR ((0, 0, _("Extended header length %.*s is out of range"),
632 len_len, p));
633 return false;
636 nextp = start + len;
638 for (p = len_lim; *p == ' ' || *p == '\t'; p++)
639 continue;
640 if (p == len_lim)
642 ERROR ((0, 0,
643 _("Malformed extended header: missing blank after length")));
644 return false;
647 keyword = p;
648 p = strchr (p, '=');
649 if (! (p && p < nextp))
651 ERROR ((0, 0, _("Malformed extended header: missing equal sign")));
652 return false;
655 if (nextp[-1] != '\n')
657 ERROR ((0, 0, _("Malformed extended header: missing newline")));
658 return false;
661 *p = nextp[-1] = '\0';
662 handler (data, keyword, p + 1, nextp - p - 2); /* '=' + trailing '\n' */
663 *p = '=';
664 nextp[-1] = '\n';
665 *ptr = nextp;
666 return true;
669 static void
670 run_override_list (struct keyword_list *kp, struct tar_stat_info *st)
672 for (; kp; kp = kp->next)
674 struct xhdr_tab const *t = locate_handler (kp->pattern);
675 if (t)
676 t->decoder (st, t->keyword, kp->value, strlen (kp->value));
680 static void
681 decx (void *data, char const *keyword, char const *value, size_t size)
683 struct xhdr_tab const *t;
684 struct tar_stat_info *st = data;
686 if (xheader_keyword_deleted_p (keyword)
687 || xheader_keyword_override_p (keyword))
688 return;
690 t = locate_handler (keyword);
691 if (t)
692 t->decoder (st, keyword, value, size);
693 else
694 WARNOPT (WARN_UNKNOWN_KEYWORD,
695 (0, 0, _("Ignoring unknown extended header keyword '%s'"),
696 keyword));
699 void
700 xheader_decode (struct tar_stat_info *st)
702 run_override_list (keyword_global_override_list, st);
703 run_override_list (global_header_override_list, st);
705 if (st->xhdr.size)
707 char *p = st->xhdr.buffer + BLOCKSIZE;
708 while (decode_record (&st->xhdr, &p, decx, st))
709 continue;
711 run_override_list (keyword_override_list, st);
713 /* The archived (effective) file size is always set directly in tar header
714 field, possibly overridden by "size" extended header - in both cases,
715 result is now decoded in st->stat.st_size */
716 st->archive_file_size = st->stat.st_size;
718 /* The real file size (given by stat()) may be redefined for sparse
719 files in "GNU.sparse.realsize" extended header */
720 if (st->real_size_set)
721 st->stat.st_size = st->real_size;
724 static void
725 decg (void *data, char const *keyword, char const *value,
726 size_t size MAYBE_UNUSED)
728 struct keyword_list **kwl = data;
729 struct xhdr_tab const *tab = locate_handler (keyword);
730 if (tab && (tab->flags & XHDR_GLOBAL))
731 tab->decoder (data, keyword, value, size);
732 else
733 xheader_list_append (kwl, keyword, value);
736 void
737 xheader_decode_global (struct xheader *xhdr)
739 if (xhdr->size)
741 char *p = xhdr->buffer + BLOCKSIZE;
743 xheader_list_destroy (&global_header_override_list);
744 while (decode_record (xhdr, &p, decg, &global_header_override_list))
745 continue;
749 static void
750 xheader_init (struct xheader *xhdr)
752 if (!xhdr->stk)
754 xhdr->stk = xmalloc (sizeof *xhdr->stk);
755 obstack_init (xhdr->stk);
759 void
760 xheader_store (char const *keyword, struct tar_stat_info *st,
761 void const *data)
763 struct xhdr_tab const *t;
765 if (st->xhdr.buffer)
766 return;
767 t = locate_handler (keyword);
768 if (!t || !t->coder)
769 return;
770 if (xheader_keyword_deleted_p (keyword))
771 return;
772 xheader_init (&st->xhdr);
773 if (!xheader_keyword_override_p (keyword))
774 t->coder (st, keyword, &st->xhdr, data);
777 void
778 xheader_read (struct xheader *xhdr, union block *p, off_t size)
780 size_t j = 0;
782 if (size < 0)
783 size = 0; /* Already diagnosed. */
785 if (SIZE_MAX - BLOCKSIZE <= size)
786 xalloc_die ();
788 size += BLOCKSIZE;
789 xhdr->size = size;
790 xhdr->buffer = xmalloc (size + 1);
791 xhdr->buffer[size] = '\0';
795 size_t len = size;
797 if (len > BLOCKSIZE)
798 len = BLOCKSIZE;
800 if (!p)
801 FATAL_ERROR ((0, 0, _("Unexpected EOF in archive")));
803 memcpy (&xhdr->buffer[j], p->buffer, len);
804 set_next_block_after (p);
806 p = find_next_block ();
808 j += len;
809 size -= len;
811 while (size > 0);
814 /* xattr_encode_keyword() substitutes '=' ~~> '%3D' and '%' ~~> '%25'
815 in extended attribute keywords. This is needed because the '=' character
816 has special purpose in extended attribute header - it splits keyword and
817 value part of header. If there was the '=' occurrence allowed inside
818 keyword, there would be no unambiguous way how to decode this extended
819 attribute.
821 (http://lists.gnu.org/archive/html/bug-tar/2012-10/msg00017.html)
823 static char *
824 xattr_encode_keyword(const char *keyword)
826 static char *encode_buffer = NULL;
827 static size_t encode_buffer_size = 0;
828 size_t bp; /* keyword/buffer pointers */
830 if (!encode_buffer)
832 encode_buffer_size = 256;
833 encode_buffer = xmalloc (encode_buffer_size);
835 else
836 *encode_buffer = 0;
838 for (bp = 0; *keyword != 0; ++bp, ++keyword)
840 char c = *keyword;
842 if (bp + 3 /* enough for URL encoding also.. */ >= encode_buffer_size)
844 encode_buffer = x2realloc (encode_buffer, &encode_buffer_size);
847 if (c == '%')
849 strcpy (encode_buffer + bp, "%25");
850 bp += 2;
852 else if (c == '=')
854 strcpy (encode_buffer + bp, "%3D");
855 bp += 2;
857 else
858 encode_buffer[bp] = c;
861 encode_buffer[bp] = 0;
863 return encode_buffer;
866 static void
867 xheader_print_n (struct xheader *xhdr, char const *keyword,
868 char const *value, size_t vsize)
870 size_t p;
871 size_t n = 0;
872 char nbuf[UINTMAX_STRSIZE_BOUND];
873 char const *np;
874 size_t len, klen;
876 keyword = xattr_encode_keyword (keyword);
877 klen = strlen (keyword);
878 len = klen + vsize + 3; /* ' ' + '=' + '\n' */
882 p = n;
883 np = umaxtostr (len + p, nbuf);
884 n = nbuf + sizeof nbuf - 1 - np;
886 while (n != p);
888 x_obstack_grow (xhdr, np, n);
889 x_obstack_1grow (xhdr, ' ');
890 x_obstack_grow (xhdr, keyword, klen);
891 x_obstack_1grow (xhdr, '=');
892 x_obstack_grow (xhdr, value, vsize);
893 x_obstack_1grow (xhdr, '\n');
896 static void
897 xheader_print (struct xheader *xhdr, char const *keyword, char const *value)
899 xheader_print_n (xhdr, keyword, value, strlen (value));
902 void
903 xheader_finish (struct xheader *xhdr)
905 struct keyword_list *kp;
907 for (kp = keyword_override_list; kp; kp = kp->next)
908 code_string (kp->value, kp->pattern, xhdr);
910 xhdr->buffer = obstack_finish (xhdr->stk);
913 void
914 xheader_destroy (struct xheader *xhdr)
916 if (xhdr->stk)
918 obstack_free (xhdr->stk, NULL);
919 free (xhdr->stk);
920 xhdr->stk = NULL;
922 else
923 free (xhdr->buffer);
924 xhdr->buffer = 0;
925 xhdr->size = 0;
929 /* Buildable strings */
931 void
932 xheader_string_begin (struct xheader *xhdr)
934 xhdr->string_length = 0;
937 void
938 xheader_string_add (struct xheader *xhdr, char const *s)
940 if (xhdr->buffer)
941 return;
942 xheader_init (xhdr);
943 xhdr->string_length += strlen (s);
944 x_obstack_grow (xhdr, s, strlen (s));
947 bool
948 xheader_string_end (struct xheader *xhdr, char const *keyword)
950 uintmax_t len;
951 uintmax_t p;
952 uintmax_t n = 0;
953 size_t size;
954 char nbuf[UINTMAX_STRSIZE_BOUND];
955 char const *np;
956 char *cp;
958 if (xhdr->buffer)
959 return false;
960 xheader_init (xhdr);
962 len = strlen (keyword) + xhdr->string_length + 3; /* ' ' + '=' + '\n' */
966 p = n;
967 np = umaxtostr (len + p, nbuf);
968 n = nbuf + sizeof nbuf - 1 - np;
970 while (n != p);
972 p = strlen (keyword) + n + 2;
973 size = p;
974 if (size != p)
976 ERROR ((0, 0,
977 _("Generated keyword/value pair is too long (keyword=%s, length=%s)"),
978 keyword, nbuf));
979 obstack_free (xhdr->stk, obstack_finish (xhdr->stk));
980 return false;
982 x_obstack_blank (xhdr, p);
983 x_obstack_1grow (xhdr, '\n');
984 cp = (char*) obstack_next_free (xhdr->stk) - xhdr->string_length - p - 1;
985 memmove (cp + p, cp, xhdr->string_length);
986 cp = stpcpy (cp, np);
987 *cp++ = ' ';
988 cp = stpcpy (cp, keyword);
989 *cp++ = '=';
990 return true;
994 /* Implementations */
996 static void
997 out_of_range_header (char const *keyword, char const *value,
998 intmax_t minval, uintmax_t maxval)
1000 char minval_buf[INT_BUFSIZE_BOUND (intmax_t)];
1001 char maxval_buf[UINTMAX_STRSIZE_BOUND];
1002 char *minval_string = imaxtostr (minval, minval_buf);
1003 char *maxval_string = umaxtostr (maxval, maxval_buf);
1005 /* TRANSLATORS: The first %s is the pax extended header keyword
1006 (atime, gid, etc.). */
1007 ERROR ((0, 0, _("Extended header %s=%s is out of range %s..%s"),
1008 keyword, value, minval_string, maxval_string));
1011 static void
1012 code_string (char const *string, char const *keyword, struct xheader *xhdr)
1014 char *outstr;
1015 if (!utf8_convert (true, string, &outstr))
1017 /* FIXME: report error */
1018 outstr = xstrdup (string);
1020 xheader_print (xhdr, keyword, outstr);
1021 free (outstr);
1024 static void
1025 decode_string (char **string, char const *arg)
1027 if (*string)
1029 free (*string);
1030 *string = NULL;
1032 if (!utf8_convert (false, arg, string))
1034 /* FIXME: report error and act accordingly to --pax invalid=UTF-8 */
1035 assign_string (string, arg);
1039 static void
1040 code_time (struct timespec t, char const *keyword, struct xheader *xhdr)
1042 char buf[TIMESPEC_STRSIZE_BOUND];
1043 xheader_print (xhdr, keyword, code_timespec (t, buf));
1046 static bool
1047 decode_time (struct timespec *ts, char const *arg, char const *keyword)
1049 char *arg_lim;
1050 struct timespec t = decode_timespec (arg, &arg_lim, true);
1052 if (! valid_timespec (t))
1054 if (arg < arg_lim && !*arg_lim)
1055 out_of_range_header (keyword, arg, TYPE_MINIMUM (time_t),
1056 TYPE_MAXIMUM (time_t));
1057 else
1058 ERROR ((0, 0, _("Malformed extended header: invalid %s=%s"),
1059 keyword, arg));
1060 return false;
1063 *ts = t;
1064 return true;
1067 static void
1068 code_signed_num (uintmax_t value, char const *keyword,
1069 intmax_t minval, uintmax_t maxval, struct xheader *xhdr)
1071 char sbuf[SYSINT_BUFSIZE];
1072 xheader_print (xhdr, keyword, sysinttostr (value, minval, maxval, sbuf));
1075 static void
1076 code_num (uintmax_t value, char const *keyword, struct xheader *xhdr)
1078 code_signed_num (value, keyword, 0, UINTMAX_MAX, xhdr);
1081 static bool
1082 decode_signed_num (intmax_t *num, char const *arg,
1083 intmax_t minval, uintmax_t maxval,
1084 char const *keyword)
1086 char *arg_lim;
1087 intmax_t u = strtosysint (arg, &arg_lim, minval, maxval);
1089 if (errno == EINVAL || *arg_lim)
1091 ERROR ((0, 0, _("Malformed extended header: invalid %s=%s"),
1092 keyword, arg));
1093 return false;
1096 if (errno == ERANGE)
1098 out_of_range_header (keyword, arg, minval, maxval);
1099 return false;
1102 *num = u;
1103 return true;
1106 static bool
1107 decode_num (uintmax_t *num, char const *arg, uintmax_t maxval,
1108 char const *keyword)
1110 intmax_t i;
1111 if (! decode_signed_num (&i, arg, 0, maxval, keyword))
1112 return false;
1113 *num = i;
1114 return true;
1117 static void
1118 dummy_coder (struct tar_stat_info const *st MAYBE_UNUSED,
1119 char const *keyword MAYBE_UNUSED,
1120 struct xheader *xhdr MAYBE_UNUSED,
1121 void const *data MAYBE_UNUSED)
1125 static void
1126 dummy_decoder (struct tar_stat_info *st MAYBE_UNUSED,
1127 char const *keyword MAYBE_UNUSED,
1128 char const *arg MAYBE_UNUSED,
1129 size_t size MAYBE_UNUSED)
1133 static void
1134 atime_coder (struct tar_stat_info const *st, char const *keyword,
1135 struct xheader *xhdr, void const *data MAYBE_UNUSED)
1137 code_time (st->atime, keyword, xhdr);
1140 static void
1141 atime_decoder (struct tar_stat_info *st,
1142 char const *keyword,
1143 char const *arg,
1144 size_t size MAYBE_UNUSED)
1146 struct timespec ts;
1147 if (decode_time (&ts, arg, keyword))
1148 st->atime = ts;
1151 static void
1152 gid_coder (struct tar_stat_info const *st, char const *keyword,
1153 struct xheader *xhdr, void const *data MAYBE_UNUSED)
1155 code_signed_num (st->stat.st_gid, keyword,
1156 TYPE_MINIMUM (gid_t), TYPE_MAXIMUM (gid_t), xhdr);
1159 static void
1160 gid_decoder (struct tar_stat_info *st,
1161 char const *keyword,
1162 char const *arg,
1163 size_t size MAYBE_UNUSED)
1165 intmax_t u;
1166 if (decode_signed_num (&u, arg, TYPE_MINIMUM (gid_t),
1167 TYPE_MAXIMUM (gid_t), keyword))
1168 st->stat.st_gid = u;
1171 static void
1172 gname_coder (struct tar_stat_info const *st, char const *keyword,
1173 struct xheader *xhdr, void const *data MAYBE_UNUSED)
1175 code_string (st->gname, keyword, xhdr);
1178 static void
1179 gname_decoder (struct tar_stat_info *st,
1180 char const *keyword MAYBE_UNUSED,
1181 char const *arg,
1182 size_t size MAYBE_UNUSED)
1184 decode_string (&st->gname, arg);
1187 static void
1188 linkpath_coder (struct tar_stat_info const *st, char const *keyword,
1189 struct xheader *xhdr, void const *data MAYBE_UNUSED)
1191 code_string (st->link_name, keyword, xhdr);
1194 static void
1195 linkpath_decoder (struct tar_stat_info *st,
1196 char const *keyword MAYBE_UNUSED,
1197 char const *arg,
1198 size_t size MAYBE_UNUSED)
1200 decode_string (&st->link_name, arg);
1203 static void
1204 ctime_coder (struct tar_stat_info const *st, char const *keyword,
1205 struct xheader *xhdr, void const *data MAYBE_UNUSED)
1207 code_time (st->ctime, keyword, xhdr);
1210 static void
1211 ctime_decoder (struct tar_stat_info *st,
1212 char const *keyword,
1213 char const *arg,
1214 size_t size MAYBE_UNUSED)
1216 struct timespec ts;
1217 if (decode_time (&ts, arg, keyword))
1218 st->ctime = ts;
1221 static void
1222 mtime_coder (struct tar_stat_info const *st, char const *keyword,
1223 struct xheader *xhdr, void const *data)
1225 struct timespec const *mtime = data;
1226 code_time (mtime ? *mtime : st->mtime, keyword, xhdr);
1229 static void
1230 mtime_decoder (struct tar_stat_info *st,
1231 char const *keyword,
1232 char const *arg,
1233 size_t size MAYBE_UNUSED)
1235 struct timespec ts;
1236 if (decode_time (&ts, arg, keyword))
1237 st->mtime = ts;
1240 static void
1241 path_coder (struct tar_stat_info const *st, char const *keyword,
1242 struct xheader *xhdr, void const *data MAYBE_UNUSED)
1244 code_string (st->file_name, keyword, xhdr);
1247 static void
1248 raw_path_decoder (struct tar_stat_info *st, char const *arg)
1250 decode_string (&st->orig_file_name, arg);
1251 decode_string (&st->file_name, arg);
1252 st->had_trailing_slash = strip_trailing_slashes (st->file_name);
1256 static void
1257 path_decoder (struct tar_stat_info *st,
1258 char const *keyword MAYBE_UNUSED,
1259 char const *arg,
1260 size_t size MAYBE_UNUSED)
1262 if (! st->sparse_name_done)
1263 raw_path_decoder (st, arg);
1266 static void
1267 sparse_path_decoder (struct tar_stat_info *st,
1268 char const *keyword MAYBE_UNUSED,
1269 char const *arg,
1270 size_t size MAYBE_UNUSED)
1272 st->sparse_name_done = true;
1273 raw_path_decoder (st, arg);
1276 static void
1277 size_coder (struct tar_stat_info const *st, char const *keyword,
1278 struct xheader *xhdr, void const *data MAYBE_UNUSED)
1280 code_num (st->stat.st_size, keyword, xhdr);
1283 static void
1284 size_decoder (struct tar_stat_info *st,
1285 char const *keyword,
1286 char const *arg,
1287 size_t size MAYBE_UNUSED)
1289 uintmax_t u;
1290 if (decode_num (&u, arg, TYPE_MAXIMUM (off_t), keyword))
1291 st->stat.st_size = u;
1294 static void
1295 uid_coder (struct tar_stat_info const *st, char const *keyword,
1296 struct xheader *xhdr, void const *data MAYBE_UNUSED)
1298 code_signed_num (st->stat.st_uid, keyword,
1299 TYPE_MINIMUM (uid_t), TYPE_MAXIMUM (uid_t), xhdr);
1302 static void
1303 uid_decoder (struct tar_stat_info *st,
1304 char const *keyword,
1305 char const *arg,
1306 size_t size MAYBE_UNUSED)
1308 intmax_t u;
1309 if (decode_signed_num (&u, arg, TYPE_MINIMUM (uid_t),
1310 TYPE_MAXIMUM (uid_t), keyword))
1311 st->stat.st_uid = u;
1314 static void
1315 uname_coder (struct tar_stat_info const *st, char const *keyword,
1316 struct xheader *xhdr, void const *data MAYBE_UNUSED)
1318 code_string (st->uname, keyword, xhdr);
1321 static void
1322 uname_decoder (struct tar_stat_info *st,
1323 char const *keyword MAYBE_UNUSED,
1324 char const *arg,
1325 size_t size MAYBE_UNUSED)
1327 decode_string (&st->uname, arg);
1330 static void
1331 sparse_size_coder (struct tar_stat_info const *st, char const *keyword,
1332 struct xheader *xhdr, void const *data)
1334 size_coder (st, keyword, xhdr, data);
1337 static void
1338 sparse_size_decoder (struct tar_stat_info *st,
1339 char const *keyword,
1340 char const *arg,
1341 size_t size MAYBE_UNUSED)
1343 uintmax_t u;
1344 if (decode_num (&u, arg, TYPE_MAXIMUM (off_t), keyword))
1346 st->real_size_set = true;
1347 st->real_size = u;
1351 static void
1352 sparse_numblocks_coder (struct tar_stat_info const *st, char const *keyword,
1353 struct xheader *xhdr,
1354 void const *data MAYBE_UNUSED)
1356 code_num (st->sparse_map_avail, keyword, xhdr);
1359 static void
1360 sparse_numblocks_decoder (struct tar_stat_info *st,
1361 char const *keyword,
1362 char const *arg,
1363 size_t size MAYBE_UNUSED)
1365 uintmax_t u;
1366 if (decode_num (&u, arg, SIZE_MAX, keyword))
1368 st->sparse_map_size = u;
1369 st->sparse_map = xcalloc (u, sizeof st->sparse_map[0]);
1370 st->sparse_map_avail = 0;
1374 static void
1375 sparse_offset_coder (struct tar_stat_info const *st, char const *keyword,
1376 struct xheader *xhdr, void const *data)
1378 size_t const *pi = data;
1379 code_num (st->sparse_map[*pi].offset, keyword, xhdr);
1382 static void
1383 sparse_offset_decoder (struct tar_stat_info *st,
1384 char const *keyword,
1385 char const *arg,
1386 size_t size MAYBE_UNUSED)
1388 uintmax_t u;
1389 if (decode_num (&u, arg, TYPE_MAXIMUM (off_t), keyword))
1391 if (st->sparse_map_avail < st->sparse_map_size)
1392 st->sparse_map[st->sparse_map_avail].offset = u;
1393 else
1394 ERROR ((0, 0, _("Malformed extended header: excess %s=%s"),
1395 "GNU.sparse.offset", arg));
1399 static void
1400 sparse_numbytes_coder (struct tar_stat_info const *st, char const *keyword,
1401 struct xheader *xhdr, void const *data)
1403 size_t const *pi = data;
1404 code_num (st->sparse_map[*pi].numbytes, keyword, xhdr);
1407 static void
1408 sparse_numbytes_decoder (struct tar_stat_info *st,
1409 char const *keyword,
1410 char const *arg,
1411 size_t size MAYBE_UNUSED)
1413 uintmax_t u;
1414 if (decode_num (&u, arg, TYPE_MAXIMUM (off_t), keyword))
1416 if (st->sparse_map_avail < st->sparse_map_size)
1417 st->sparse_map[st->sparse_map_avail++].numbytes = u;
1418 else
1419 ERROR ((0, 0, _("Malformed extended header: excess %s=%s"),
1420 keyword, arg));
1424 static void
1425 sparse_map_decoder (struct tar_stat_info *st,
1426 char const *keyword,
1427 char const *arg,
1428 size_t size MAYBE_UNUSED)
1430 int offset = 1;
1431 struct sp_array e;
1433 st->sparse_map_avail = 0;
1434 while (1)
1436 intmax_t u;
1437 char *delim;
1439 if (!ISDIGIT (*arg))
1441 ERROR ((0, 0, _("Malformed extended header: invalid %s=%s"),
1442 keyword, arg));
1443 return;
1446 errno = 0;
1447 u = strtoimax (arg, &delim, 10);
1448 if (TYPE_MAXIMUM (off_t) < u)
1450 u = TYPE_MAXIMUM (off_t);
1451 errno = ERANGE;
1453 if (offset)
1455 e.offset = u;
1456 if (errno == ERANGE)
1458 out_of_range_header (keyword, arg, 0, TYPE_MAXIMUM (off_t));
1459 return;
1462 else
1464 e.numbytes = u;
1465 if (errno == ERANGE)
1467 out_of_range_header (keyword, arg, 0, TYPE_MAXIMUM (off_t));
1468 return;
1470 if (st->sparse_map_avail < st->sparse_map_size)
1471 st->sparse_map[st->sparse_map_avail++] = e;
1472 else
1474 ERROR ((0, 0, _("Malformed extended header: excess %s=%s"),
1475 keyword, arg));
1476 return;
1480 offset = !offset;
1482 if (*delim == 0)
1483 break;
1484 else if (*delim != ',')
1486 ERROR ((0, 0,
1487 _("Malformed extended header: invalid %s: unexpected delimiter %c"),
1488 keyword, *delim));
1489 return;
1492 arg = delim + 1;
1495 if (!offset)
1496 ERROR ((0, 0,
1497 _("Malformed extended header: invalid %s: odd number of values"),
1498 keyword));
1501 static void
1502 dumpdir_coder (struct tar_stat_info const *st, char const *keyword,
1503 struct xheader *xhdr, void const *data)
1505 xheader_print_n (xhdr, keyword, data, dumpdir_size (data));
1508 static void
1509 dumpdir_decoder (struct tar_stat_info *st,
1510 char const *keyword MAYBE_UNUSED,
1511 char const *arg,
1512 size_t size)
1514 st->dumpdir = xmalloc (size);
1515 memcpy (st->dumpdir, arg, size);
1518 static void
1519 volume_label_coder (struct tar_stat_info const *st, char const *keyword,
1520 struct xheader *xhdr, void const *data)
1522 code_string (data, keyword, xhdr);
1525 static void
1526 volume_label_decoder (struct tar_stat_info *st,
1527 char const *keyword MAYBE_UNUSED,
1528 char const *arg,
1529 size_t size MAYBE_UNUSED)
1531 decode_string (&volume_label, arg);
1534 static void
1535 volume_size_coder (struct tar_stat_info const *st, char const *keyword,
1536 struct xheader *xhdr, void const *data)
1538 off_t const *v = data;
1539 code_num (*v, keyword, xhdr);
1542 static void
1543 volume_size_decoder (struct tar_stat_info *st,
1544 char const *keyword,
1545 char const *arg, size_t size)
1547 uintmax_t u;
1548 if (decode_num (&u, arg, TYPE_MAXIMUM (uintmax_t), keyword))
1549 continued_file_size = u;
1552 /* FIXME: Merge with volume_size_coder */
1553 static void
1554 volume_offset_coder (struct tar_stat_info const *st, char const *keyword,
1555 struct xheader *xhdr, void const *data)
1557 off_t const *v = data;
1558 code_num (*v, keyword, xhdr);
1561 static void
1562 volume_offset_decoder (struct tar_stat_info *st,
1563 char const *keyword,
1564 char const *arg, size_t size)
1566 uintmax_t u;
1567 if (decode_num (&u, arg, TYPE_MAXIMUM (uintmax_t), keyword))
1568 continued_file_offset = u;
1571 static void
1572 volume_filename_decoder (struct tar_stat_info *st,
1573 char const *keyword MAYBE_UNUSED,
1574 char const *arg,
1575 size_t size MAYBE_UNUSED)
1577 decode_string (&continued_file_name, arg);
1580 static void
1581 xattr_selinux_coder (struct tar_stat_info const *st, char const *keyword,
1582 struct xheader *xhdr, void const *data)
1584 code_string (st->cntx_name, keyword, xhdr);
1587 static void
1588 xattr_selinux_decoder (struct tar_stat_info *st,
1589 char const *keyword, char const *arg, size_t size)
1591 decode_string (&st->cntx_name, arg);
1594 static void
1595 xattr_acls_a_coder (struct tar_stat_info const *st , char const *keyword,
1596 struct xheader *xhdr, void const *data)
1598 xheader_print_n (xhdr, keyword, st->acls_a_ptr, st->acls_a_len);
1601 static void
1602 xattr_acls_a_decoder (struct tar_stat_info *st,
1603 char const *keyword, char const *arg, size_t size)
1605 st->acls_a_ptr = xmemdup (arg, size + 1);
1606 st->acls_a_len = size;
1609 static void
1610 xattr_acls_d_coder (struct tar_stat_info const *st , char const *keyword,
1611 struct xheader *xhdr, void const *data)
1613 xheader_print_n (xhdr, keyword, st->acls_d_ptr, st->acls_d_len);
1616 static void
1617 xattr_acls_d_decoder (struct tar_stat_info *st,
1618 char const *keyword, char const *arg, size_t size)
1620 st->acls_d_ptr = xmemdup (arg, size + 1);
1621 st->acls_d_len = size;
1624 static void
1625 xattr_coder (struct tar_stat_info const *st, char const *keyword,
1626 struct xheader *xhdr, void const *data)
1628 size_t n = *(size_t *)data;
1629 xheader_print_n (xhdr, keyword,
1630 st->xattr_map.xm_map[n].xval_ptr,
1631 st->xattr_map.xm_map[n].xval_len);
1634 static void
1635 xattr_decoder (struct tar_stat_info *st,
1636 char const *keyword, char const *arg, size_t size)
1638 char *xkey;
1640 /* copy keyword */
1641 xkey = xstrdup (keyword);
1643 xattr_decode_keyword (xkey);
1645 xattr_map_add (&st->xattr_map, xkey, arg, size);
1647 free (xkey);
1650 static void
1651 sparse_major_coder (struct tar_stat_info const *st, char const *keyword,
1652 struct xheader *xhdr, void const *data)
1654 code_num (st->sparse_major, keyword, xhdr);
1657 static void
1658 sparse_major_decoder (struct tar_stat_info *st,
1659 char const *keyword,
1660 char const *arg,
1661 size_t size)
1663 uintmax_t u;
1664 if (decode_num (&u, arg, TYPE_MAXIMUM (unsigned), keyword))
1665 st->sparse_major = u;
1668 static void
1669 sparse_minor_coder (struct tar_stat_info const *st, char const *keyword,
1670 struct xheader *xhdr, void const *data)
1672 code_num (st->sparse_minor, keyword, xhdr);
1675 static void
1676 sparse_minor_decoder (struct tar_stat_info *st,
1677 char const *keyword,
1678 char const *arg,
1679 size_t size)
1681 uintmax_t u;
1682 if (decode_num (&u, arg, TYPE_MAXIMUM (unsigned), keyword))
1683 st->sparse_minor = u;
1686 struct xhdr_tab const xhdr_tab[] = {
1687 { "atime", atime_coder, atime_decoder, 0, false },
1688 { "comment", dummy_coder, dummy_decoder, 0, false },
1689 { "charset", dummy_coder, dummy_decoder, 0, false },
1690 { "ctime", ctime_coder, ctime_decoder, 0, false },
1691 { "gid", gid_coder, gid_decoder, 0, false },
1692 { "gname", gname_coder, gname_decoder, 0, false },
1693 { "linkpath", linkpath_coder, linkpath_decoder, 0, false },
1694 { "mtime", mtime_coder, mtime_decoder, 0, false },
1695 { "path", path_coder, path_decoder, 0, false },
1696 { "size", size_coder, size_decoder, 0, false },
1697 { "uid", uid_coder, uid_decoder, 0, false },
1698 { "uname", uname_coder, uname_decoder, 0, false },
1700 /* Sparse file handling */
1701 { "GNU.sparse.name", path_coder, sparse_path_decoder,
1702 XHDR_PROTECTED, false },
1703 { "GNU.sparse.major", sparse_major_coder, sparse_major_decoder,
1704 XHDR_PROTECTED, false },
1705 { "GNU.sparse.minor", sparse_minor_coder, sparse_minor_decoder,
1706 XHDR_PROTECTED, false },
1707 { "GNU.sparse.realsize", sparse_size_coder, sparse_size_decoder,
1708 XHDR_PROTECTED, false },
1709 { "GNU.sparse.numblocks", sparse_numblocks_coder, sparse_numblocks_decoder,
1710 XHDR_PROTECTED, false },
1712 /* tar 1.14 - 1.15.90 keywords. */
1713 { "GNU.sparse.size", sparse_size_coder, sparse_size_decoder,
1714 XHDR_PROTECTED, false },
1715 /* tar 1.14 - 1.15.1 keywords. Multiple instances of these appeared in 'x'
1716 headers, and each of them was meaningful. It confilcted with POSIX specs,
1717 which requires that "when extended header records conflict, the last one
1718 given in the header shall take precedence." */
1719 { "GNU.sparse.offset", sparse_offset_coder, sparse_offset_decoder,
1720 XHDR_PROTECTED, false },
1721 { "GNU.sparse.numbytes", sparse_numbytes_coder, sparse_numbytes_decoder,
1722 XHDR_PROTECTED, false },
1723 /* tar 1.15.90 keyword, introduced to remove the above-mentioned conflict. */
1724 { "GNU.sparse.map", NULL /* Unused, see pax_dump_header() */,
1725 sparse_map_decoder, 0, false },
1727 { "GNU.dumpdir", dumpdir_coder, dumpdir_decoder,
1728 XHDR_PROTECTED, false },
1730 /* Keeps the tape/volume label. May be present only in the global headers.
1731 Equivalent to GNUTYPE_VOLHDR. */
1732 { "GNU.volume.label", volume_label_coder, volume_label_decoder,
1733 XHDR_PROTECTED | XHDR_GLOBAL, false },
1735 /* These may be present in a first global header of the archive.
1736 They provide the same functionality as GNUTYPE_MULTIVOL header.
1737 The GNU.volume.size keeps the real_s_sizeleft value, which is
1738 otherwise kept in the size field of a multivolume header. The
1739 GNU.volume.offset keeps the offset of the start of this volume,
1740 otherwise kept in oldgnu_header.offset. */
1741 { "GNU.volume.filename", volume_label_coder, volume_filename_decoder,
1742 XHDR_PROTECTED | XHDR_GLOBAL, false },
1743 { "GNU.volume.size", volume_size_coder, volume_size_decoder,
1744 XHDR_PROTECTED | XHDR_GLOBAL, false },
1745 { "GNU.volume.offset", volume_offset_coder, volume_offset_decoder,
1746 XHDR_PROTECTED | XHDR_GLOBAL, false },
1748 /* We get the SELinux value from filecon, so add a namespace for SELinux
1749 instead of storing it in SCHILY.xattr.* (which would be RAW). */
1750 { "RHT.security.selinux",
1751 xattr_selinux_coder, xattr_selinux_decoder, 0, false },
1753 /* ACLs, use the star format... */
1754 { "SCHILY.acl.access",
1755 xattr_acls_a_coder, xattr_acls_a_decoder, 0, false },
1757 { "SCHILY.acl.default",
1758 xattr_acls_d_coder, xattr_acls_d_decoder, 0, false },
1760 /* We are storing all extended attributes using this rule even if some of them
1761 were stored by some previous rule (duplicates) -- we just have to make sure
1762 they are restored *only once* during extraction later on. */
1763 { "SCHILY.xattr", xattr_coder, xattr_decoder, 0, true },
1765 { NULL, NULL, NULL, 0, false }