Changes in extended header decoder
[tar.git] / src / xheader.c
bloba195f3e53e5efb0d221b6d5900b4c64a74f70ddd
1 /* POSIX extended headers for tar.
3 Copyright (C) 2003-2023 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 (strncmp (p->keyword, keyword, kwlen) == 0 && keyword[kwlen] == '.')
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;
1062 if (*arg_lim)
1064 ERROR ((0, 0, _("Malformed extended header: invalid %s=%s"),
1065 keyword, arg));
1066 return false;
1069 *ts = t;
1070 return true;
1073 static void
1074 code_signed_num (uintmax_t value, char const *keyword,
1075 intmax_t minval, uintmax_t maxval, struct xheader *xhdr)
1077 char sbuf[SYSINT_BUFSIZE];
1078 xheader_print (xhdr, keyword, sysinttostr (value, minval, maxval, sbuf));
1081 static void
1082 code_num (uintmax_t value, char const *keyword, struct xheader *xhdr)
1084 code_signed_num (value, keyword, 0, UINTMAX_MAX, xhdr);
1087 static bool
1088 decode_signed_num (intmax_t *num, char const *arg,
1089 intmax_t minval, uintmax_t maxval,
1090 char const *keyword)
1092 char *arg_lim;
1093 intmax_t u = strtosysint (arg, &arg_lim, minval, maxval);
1095 if (errno == EINVAL || *arg_lim)
1097 ERROR ((0, 0, _("Malformed extended header: invalid %s=%s"),
1098 keyword, arg));
1099 return false;
1102 if (errno == ERANGE)
1104 out_of_range_header (keyword, arg, minval, maxval);
1105 return false;
1108 *num = u;
1109 return true;
1112 static bool
1113 decode_num (uintmax_t *num, char const *arg, uintmax_t maxval,
1114 char const *keyword)
1116 intmax_t i;
1117 if (! decode_signed_num (&i, arg, 0, maxval, keyword))
1118 return false;
1119 *num = i;
1120 return true;
1123 static void
1124 dummy_coder (struct tar_stat_info const *st MAYBE_UNUSED,
1125 char const *keyword MAYBE_UNUSED,
1126 struct xheader *xhdr MAYBE_UNUSED,
1127 void const *data MAYBE_UNUSED)
1131 static void
1132 dummy_decoder (struct tar_stat_info *st MAYBE_UNUSED,
1133 char const *keyword MAYBE_UNUSED,
1134 char const *arg MAYBE_UNUSED,
1135 size_t size MAYBE_UNUSED)
1139 static void
1140 atime_coder (struct tar_stat_info const *st, char const *keyword,
1141 struct xheader *xhdr, void const *data MAYBE_UNUSED)
1143 code_time (st->atime, keyword, xhdr);
1146 static void
1147 atime_decoder (struct tar_stat_info *st,
1148 char const *keyword,
1149 char const *arg,
1150 size_t size MAYBE_UNUSED)
1152 struct timespec ts;
1153 if (decode_time (&ts, arg, keyword))
1154 st->atime = ts;
1157 static void
1158 gid_coder (struct tar_stat_info const *st, char const *keyword,
1159 struct xheader *xhdr, void const *data MAYBE_UNUSED)
1161 code_signed_num (st->stat.st_gid, keyword,
1162 TYPE_MINIMUM (gid_t), TYPE_MAXIMUM (gid_t), xhdr);
1165 static void
1166 gid_decoder (struct tar_stat_info *st,
1167 char const *keyword,
1168 char const *arg,
1169 size_t size MAYBE_UNUSED)
1171 intmax_t u;
1172 if (decode_signed_num (&u, arg, TYPE_MINIMUM (gid_t),
1173 TYPE_MAXIMUM (gid_t), keyword))
1174 st->stat.st_gid = u;
1177 static void
1178 gname_coder (struct tar_stat_info const *st, char const *keyword,
1179 struct xheader *xhdr, void const *data MAYBE_UNUSED)
1181 code_string (st->gname, keyword, xhdr);
1184 static void
1185 gname_decoder (struct tar_stat_info *st,
1186 char const *keyword MAYBE_UNUSED,
1187 char const *arg,
1188 size_t size MAYBE_UNUSED)
1190 decode_string (&st->gname, arg);
1193 static void
1194 linkpath_coder (struct tar_stat_info const *st, char const *keyword,
1195 struct xheader *xhdr, void const *data MAYBE_UNUSED)
1197 code_string (st->link_name, keyword, xhdr);
1200 static void
1201 linkpath_decoder (struct tar_stat_info *st,
1202 char const *keyword MAYBE_UNUSED,
1203 char const *arg,
1204 size_t size MAYBE_UNUSED)
1206 decode_string (&st->link_name, arg);
1209 static void
1210 ctime_coder (struct tar_stat_info const *st, char const *keyword,
1211 struct xheader *xhdr, void const *data MAYBE_UNUSED)
1213 code_time (st->ctime, keyword, xhdr);
1216 static void
1217 ctime_decoder (struct tar_stat_info *st,
1218 char const *keyword,
1219 char const *arg,
1220 size_t size MAYBE_UNUSED)
1222 struct timespec ts;
1223 if (decode_time (&ts, arg, keyword))
1224 st->ctime = ts;
1227 static void
1228 mtime_coder (struct tar_stat_info const *st, char const *keyword,
1229 struct xheader *xhdr, void const *data)
1231 struct timespec const *mtime = data;
1232 code_time (mtime ? *mtime : st->mtime, keyword, xhdr);
1235 static void
1236 mtime_decoder (struct tar_stat_info *st,
1237 char const *keyword,
1238 char const *arg,
1239 size_t size MAYBE_UNUSED)
1241 struct timespec ts;
1242 if (decode_time (&ts, arg, keyword))
1243 st->mtime = ts;
1246 static void
1247 path_coder (struct tar_stat_info const *st, char const *keyword,
1248 struct xheader *xhdr, void const *data MAYBE_UNUSED)
1250 code_string (st->file_name, keyword, xhdr);
1253 static void
1254 raw_path_decoder (struct tar_stat_info *st, char const *arg)
1256 if (*arg)
1258 decode_string (&st->orig_file_name, arg);
1259 decode_string (&st->file_name, arg);
1260 st->had_trailing_slash = strip_trailing_slashes (st->file_name);
1265 static void
1266 path_decoder (struct tar_stat_info *st,
1267 char const *keyword MAYBE_UNUSED,
1268 char const *arg,
1269 size_t size MAYBE_UNUSED)
1271 if (! st->sparse_name_done)
1272 raw_path_decoder (st, arg);
1275 static void
1276 sparse_path_decoder (struct tar_stat_info *st,
1277 char const *keyword MAYBE_UNUSED,
1278 char const *arg,
1279 size_t size MAYBE_UNUSED)
1281 st->sparse_name_done = true;
1282 raw_path_decoder (st, arg);
1285 static void
1286 size_coder (struct tar_stat_info const *st, char const *keyword,
1287 struct xheader *xhdr, void const *data MAYBE_UNUSED)
1289 code_num (st->stat.st_size, keyword, xhdr);
1292 static void
1293 size_decoder (struct tar_stat_info *st,
1294 char const *keyword,
1295 char const *arg,
1296 size_t size MAYBE_UNUSED)
1298 uintmax_t u;
1299 if (decode_num (&u, arg, TYPE_MAXIMUM (off_t), keyword))
1300 st->stat.st_size = u;
1303 static void
1304 uid_coder (struct tar_stat_info const *st, char const *keyword,
1305 struct xheader *xhdr, void const *data MAYBE_UNUSED)
1307 code_signed_num (st->stat.st_uid, keyword,
1308 TYPE_MINIMUM (uid_t), TYPE_MAXIMUM (uid_t), xhdr);
1311 static void
1312 uid_decoder (struct tar_stat_info *st,
1313 char const *keyword,
1314 char const *arg,
1315 size_t size MAYBE_UNUSED)
1317 intmax_t u;
1318 if (decode_signed_num (&u, arg, TYPE_MINIMUM (uid_t),
1319 TYPE_MAXIMUM (uid_t), keyword))
1320 st->stat.st_uid = u;
1323 static void
1324 uname_coder (struct tar_stat_info const *st, char const *keyword,
1325 struct xheader *xhdr, void const *data MAYBE_UNUSED)
1327 code_string (st->uname, keyword, xhdr);
1330 static void
1331 uname_decoder (struct tar_stat_info *st,
1332 char const *keyword MAYBE_UNUSED,
1333 char const *arg,
1334 size_t size MAYBE_UNUSED)
1336 decode_string (&st->uname, arg);
1339 static void
1340 sparse_size_coder (struct tar_stat_info const *st, char const *keyword,
1341 struct xheader *xhdr, void const *data)
1343 size_coder (st, keyword, xhdr, data);
1346 static void
1347 sparse_size_decoder (struct tar_stat_info *st,
1348 char const *keyword,
1349 char const *arg,
1350 size_t size MAYBE_UNUSED)
1352 uintmax_t u;
1353 if (decode_num (&u, arg, TYPE_MAXIMUM (off_t), keyword))
1355 st->real_size_set = true;
1356 st->real_size = u;
1360 static void
1361 sparse_numblocks_coder (struct tar_stat_info const *st, char const *keyword,
1362 struct xheader *xhdr,
1363 void const *data MAYBE_UNUSED)
1365 code_num (st->sparse_map_avail, keyword, xhdr);
1368 static void
1369 sparse_numblocks_decoder (struct tar_stat_info *st,
1370 char const *keyword,
1371 char const *arg,
1372 size_t size MAYBE_UNUSED)
1374 uintmax_t u;
1375 if (decode_num (&u, arg, SIZE_MAX, keyword))
1377 st->sparse_map_size = u;
1378 st->sparse_map = xcalloc (u, sizeof st->sparse_map[0]);
1379 st->sparse_map_avail = 0;
1383 static void
1384 sparse_offset_coder (struct tar_stat_info const *st, char const *keyword,
1385 struct xheader *xhdr, void const *data)
1387 size_t const *pi = data;
1388 code_num (st->sparse_map[*pi].offset, keyword, xhdr);
1391 static void
1392 sparse_offset_decoder (struct tar_stat_info *st,
1393 char const *keyword,
1394 char const *arg,
1395 size_t size MAYBE_UNUSED)
1397 uintmax_t u;
1398 if (decode_num (&u, arg, TYPE_MAXIMUM (off_t), keyword))
1400 if (st->sparse_map_avail < st->sparse_map_size)
1401 st->sparse_map[st->sparse_map_avail].offset = u;
1402 else
1403 ERROR ((0, 0, _("Malformed extended header: excess %s=%s"),
1404 "GNU.sparse.offset", arg));
1408 static void
1409 sparse_numbytes_coder (struct tar_stat_info const *st, char const *keyword,
1410 struct xheader *xhdr, void const *data)
1412 size_t const *pi = data;
1413 code_num (st->sparse_map[*pi].numbytes, keyword, xhdr);
1416 static void
1417 sparse_numbytes_decoder (struct tar_stat_info *st,
1418 char const *keyword,
1419 char const *arg,
1420 size_t size MAYBE_UNUSED)
1422 uintmax_t u;
1423 if (decode_num (&u, arg, TYPE_MAXIMUM (off_t), keyword))
1425 if (st->sparse_map_avail < st->sparse_map_size)
1426 st->sparse_map[st->sparse_map_avail++].numbytes = u;
1427 else
1428 ERROR ((0, 0, _("Malformed extended header: excess %s=%s"),
1429 keyword, arg));
1433 static void
1434 sparse_map_decoder (struct tar_stat_info *st,
1435 char const *keyword,
1436 char const *arg,
1437 size_t size MAYBE_UNUSED)
1439 int offset = 1;
1440 struct sp_array e;
1442 st->sparse_map_avail = 0;
1443 while (1)
1445 intmax_t u;
1446 char *delim;
1448 if (!ISDIGIT (*arg))
1450 ERROR ((0, 0, _("Malformed extended header: invalid %s=%s"),
1451 keyword, arg));
1452 return;
1455 errno = 0;
1456 u = strtoimax (arg, &delim, 10);
1457 if (TYPE_MAXIMUM (off_t) < u)
1459 u = TYPE_MAXIMUM (off_t);
1460 errno = ERANGE;
1462 if (offset)
1464 e.offset = u;
1465 if (errno == ERANGE)
1467 out_of_range_header (keyword, arg, 0, TYPE_MAXIMUM (off_t));
1468 return;
1471 else
1473 e.numbytes = u;
1474 if (errno == ERANGE)
1476 out_of_range_header (keyword, arg, 0, TYPE_MAXIMUM (off_t));
1477 return;
1479 if (st->sparse_map_avail < st->sparse_map_size)
1480 st->sparse_map[st->sparse_map_avail++] = e;
1481 else
1483 ERROR ((0, 0, _("Malformed extended header: excess %s=%s"),
1484 keyword, arg));
1485 return;
1489 offset = !offset;
1491 if (*delim == 0)
1492 break;
1493 else if (*delim != ',')
1495 ERROR ((0, 0,
1496 _("Malformed extended header: invalid %s: unexpected delimiter %c"),
1497 keyword, *delim));
1498 return;
1501 arg = delim + 1;
1504 if (!offset)
1505 ERROR ((0, 0,
1506 _("Malformed extended header: invalid %s: odd number of values"),
1507 keyword));
1510 static void
1511 dumpdir_coder (struct tar_stat_info const *st, char const *keyword,
1512 struct xheader *xhdr, void const *data)
1514 xheader_print_n (xhdr, keyword, data, dumpdir_size (data));
1517 static void
1518 dumpdir_decoder (struct tar_stat_info *st,
1519 char const *keyword MAYBE_UNUSED,
1520 char const *arg,
1521 size_t size)
1523 st->dumpdir = xmalloc (size);
1524 memcpy (st->dumpdir, arg, size);
1527 static void
1528 volume_label_coder (struct tar_stat_info const *st, char const *keyword,
1529 struct xheader *xhdr, void const *data)
1531 code_string (data, keyword, xhdr);
1534 static void
1535 volume_label_decoder (struct tar_stat_info *st,
1536 char const *keyword MAYBE_UNUSED,
1537 char const *arg,
1538 size_t size MAYBE_UNUSED)
1540 decode_string (&volume_label, arg);
1543 static void
1544 volume_size_coder (struct tar_stat_info const *st, char const *keyword,
1545 struct xheader *xhdr, void const *data)
1547 off_t const *v = data;
1548 code_num (*v, keyword, xhdr);
1551 static void
1552 volume_size_decoder (struct tar_stat_info *st,
1553 char const *keyword,
1554 char const *arg, size_t size)
1556 uintmax_t u;
1557 if (decode_num (&u, arg, TYPE_MAXIMUM (uintmax_t), keyword))
1558 continued_file_size = u;
1561 /* FIXME: Merge with volume_size_coder */
1562 static void
1563 volume_offset_coder (struct tar_stat_info const *st, char const *keyword,
1564 struct xheader *xhdr, void const *data)
1566 off_t const *v = data;
1567 code_num (*v, keyword, xhdr);
1570 static void
1571 volume_offset_decoder (struct tar_stat_info *st,
1572 char const *keyword,
1573 char const *arg, size_t size)
1575 uintmax_t u;
1576 if (decode_num (&u, arg, TYPE_MAXIMUM (uintmax_t), keyword))
1577 continued_file_offset = u;
1580 static void
1581 volume_filename_decoder (struct tar_stat_info *st,
1582 char const *keyword MAYBE_UNUSED,
1583 char const *arg,
1584 size_t size MAYBE_UNUSED)
1586 decode_string (&continued_file_name, arg);
1589 static void
1590 xattr_selinux_coder (struct tar_stat_info const *st, char const *keyword,
1591 struct xheader *xhdr, void const *data)
1593 code_string (st->cntx_name, keyword, xhdr);
1596 static void
1597 xattr_selinux_decoder (struct tar_stat_info *st,
1598 char const *keyword, char const *arg, size_t size)
1600 decode_string (&st->cntx_name, arg);
1603 static void
1604 xattr_acls_a_coder (struct tar_stat_info const *st , char const *keyword,
1605 struct xheader *xhdr, void const *data)
1607 xheader_print_n (xhdr, keyword, st->acls_a_ptr, st->acls_a_len);
1610 static void
1611 xattr_acls_a_decoder (struct tar_stat_info *st,
1612 char const *keyword, char const *arg, size_t size)
1614 st->acls_a_ptr = xmemdup (arg, size + 1);
1615 st->acls_a_len = size;
1618 static void
1619 xattr_acls_d_coder (struct tar_stat_info const *st , char const *keyword,
1620 struct xheader *xhdr, void const *data)
1622 xheader_print_n (xhdr, keyword, st->acls_d_ptr, st->acls_d_len);
1625 static void
1626 xattr_acls_d_decoder (struct tar_stat_info *st,
1627 char const *keyword, char const *arg, size_t size)
1629 st->acls_d_ptr = xmemdup (arg, size + 1);
1630 st->acls_d_len = size;
1633 static void
1634 xattr_coder (struct tar_stat_info const *st, char const *keyword,
1635 struct xheader *xhdr, void const *data)
1637 size_t n = *(size_t *)data;
1638 xheader_print_n (xhdr, keyword,
1639 st->xattr_map.xm_map[n].xval_ptr,
1640 st->xattr_map.xm_map[n].xval_len);
1643 static void
1644 xattr_decoder (struct tar_stat_info *st,
1645 char const *keyword, char const *arg, size_t size)
1647 char *xkey;
1649 /* copy keyword */
1650 xkey = xstrdup (keyword);
1652 xattr_decode_keyword (xkey);
1654 xattr_map_add (&st->xattr_map, xkey, arg, size);
1656 free (xkey);
1659 static void
1660 sparse_major_coder (struct tar_stat_info const *st, char const *keyword,
1661 struct xheader *xhdr, void const *data)
1663 code_num (st->sparse_major, keyword, xhdr);
1666 static void
1667 sparse_major_decoder (struct tar_stat_info *st,
1668 char const *keyword,
1669 char const *arg,
1670 size_t size)
1672 uintmax_t u;
1673 if (decode_num (&u, arg, TYPE_MAXIMUM (unsigned), keyword))
1674 st->sparse_major = u;
1677 static void
1678 sparse_minor_coder (struct tar_stat_info const *st, char const *keyword,
1679 struct xheader *xhdr, void const *data)
1681 code_num (st->sparse_minor, keyword, xhdr);
1684 static void
1685 sparse_minor_decoder (struct tar_stat_info *st,
1686 char const *keyword,
1687 char const *arg,
1688 size_t size)
1690 uintmax_t u;
1691 if (decode_num (&u, arg, TYPE_MAXIMUM (unsigned), keyword))
1692 st->sparse_minor = u;
1695 struct xhdr_tab const xhdr_tab[] = {
1696 { "atime", atime_coder, atime_decoder, 0, false },
1697 { "comment", dummy_coder, dummy_decoder, 0, false },
1698 { "charset", dummy_coder, dummy_decoder, 0, false },
1699 { "ctime", ctime_coder, ctime_decoder, 0, false },
1700 { "gid", gid_coder, gid_decoder, 0, false },
1701 { "gname", gname_coder, gname_decoder, 0, false },
1702 { "linkpath", linkpath_coder, linkpath_decoder, 0, false },
1703 { "mtime", mtime_coder, mtime_decoder, 0, false },
1704 { "path", path_coder, path_decoder, 0, false },
1705 { "size", size_coder, size_decoder, 0, false },
1706 { "uid", uid_coder, uid_decoder, 0, false },
1707 { "uname", uname_coder, uname_decoder, 0, false },
1709 /* Sparse file handling */
1710 { "GNU.sparse.name", path_coder, sparse_path_decoder,
1711 XHDR_PROTECTED, false },
1712 { "GNU.sparse.major", sparse_major_coder, sparse_major_decoder,
1713 XHDR_PROTECTED, false },
1714 { "GNU.sparse.minor", sparse_minor_coder, sparse_minor_decoder,
1715 XHDR_PROTECTED, false },
1716 { "GNU.sparse.realsize", sparse_size_coder, sparse_size_decoder,
1717 XHDR_PROTECTED, false },
1718 { "GNU.sparse.numblocks", sparse_numblocks_coder, sparse_numblocks_decoder,
1719 XHDR_PROTECTED, false },
1721 /* tar 1.14 - 1.15.90 keywords. */
1722 { "GNU.sparse.size", sparse_size_coder, sparse_size_decoder,
1723 XHDR_PROTECTED, false },
1724 /* tar 1.14 - 1.15.1 keywords. Multiple instances of these appeared in 'x'
1725 headers, and each of them was meaningful. It confilcted with POSIX specs,
1726 which requires that "when extended header records conflict, the last one
1727 given in the header shall take precedence." */
1728 { "GNU.sparse.offset", sparse_offset_coder, sparse_offset_decoder,
1729 XHDR_PROTECTED, false },
1730 { "GNU.sparse.numbytes", sparse_numbytes_coder, sparse_numbytes_decoder,
1731 XHDR_PROTECTED, false },
1732 /* tar 1.15.90 keyword, introduced to remove the above-mentioned conflict. */
1733 { "GNU.sparse.map", NULL /* Unused, see pax_dump_header() */,
1734 sparse_map_decoder, 0, false },
1736 { "GNU.dumpdir", dumpdir_coder, dumpdir_decoder,
1737 XHDR_PROTECTED, false },
1739 /* Keeps the tape/volume label. May be present only in the global headers.
1740 Equivalent to GNUTYPE_VOLHDR. */
1741 { "GNU.volume.label", volume_label_coder, volume_label_decoder,
1742 XHDR_PROTECTED | XHDR_GLOBAL, false },
1744 /* These may be present in a first global header of the archive.
1745 They provide the same functionality as GNUTYPE_MULTIVOL header.
1746 The GNU.volume.size keeps the real_s_sizeleft value, which is
1747 otherwise kept in the size field of a multivolume header. The
1748 GNU.volume.offset keeps the offset of the start of this volume,
1749 otherwise kept in oldgnu_header.offset. */
1750 { "GNU.volume.filename", volume_label_coder, volume_filename_decoder,
1751 XHDR_PROTECTED | XHDR_GLOBAL, false },
1752 { "GNU.volume.size", volume_size_coder, volume_size_decoder,
1753 XHDR_PROTECTED | XHDR_GLOBAL, false },
1754 { "GNU.volume.offset", volume_offset_coder, volume_offset_decoder,
1755 XHDR_PROTECTED | XHDR_GLOBAL, false },
1757 /* We get the SELinux value from filecon, so add a namespace for SELinux
1758 instead of storing it in SCHILY.xattr.* (which would be RAW). */
1759 { "RHT.security.selinux",
1760 xattr_selinux_coder, xattr_selinux_decoder, 0, false },
1762 /* ACLs, use the star format... */
1763 { "SCHILY.acl.access",
1764 xattr_acls_a_coder, xattr_acls_a_decoder, 0, false },
1766 { "SCHILY.acl.default",
1767 xattr_acls_d_coder, xattr_acls_d_decoder, 0, false },
1769 /* We are storing all extended attributes using this rule even if some of them
1770 were stored by some previous rule (duplicates) -- we just have to make sure
1771 they are restored *only once* during extraction later on. */
1772 { "SCHILY.xattr", xattr_coder, xattr_decoder, 0, true },
1774 { NULL, NULL, NULL, 0, false }