re-mark 1.29b-2 as not yet uploaded (merge madness!)
[debian/tar] / src / xheader.c
1 /* POSIX extended headers for tar.
2
3    Copyright (C) 2003-2007, 2009-2010, 2012-2014, 2016 Free Software
4    Foundation, Inc.
5
6    This file is part of GNU tar.
7
8    GNU tar is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12
13    GNU tar is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
20
21 #include <system.h>
22
23 #include <fnmatch.h>
24 #include <hash.h>
25 #include <inttostr.h>
26 #include <quotearg.h>
27
28 #include "common.h"
29
30 static void xheader_init (struct xheader *xhdr);
31 static bool xheader_protected_pattern_p (char const *pattern);
32 static bool xheader_protected_keyword_p (char const *keyword);
33 static void xheader_set_single_keyword (char *) __attribute__ ((noreturn));
34
35 /* Used by xheader_finish() */
36 static void code_string (char const *string, char const *keyword,
37                          struct xheader *xhdr);
38
39 /* Number of global headers written so far. */
40 static size_t global_header_count;
41 /* FIXME: Possibly it should be reset after changing the volume.
42    POSIX %n specification says that it is expanded to the sequence
43    number of current global header in *the* archive. However, for
44    multi-volume archives this will yield duplicate header names
45    in different volumes, which I'd like to avoid. The best way
46    to solve this would be to use per-archive header count as required
47    by POSIX *and* set globexthdr.name to, say,
48    $TMPDIR/GlobalHead.%p.$NUMVOLUME.%n.
49
50    However it should wait until buffer.c is finally rewritten */
51
52 \f
53 /* Interface functions to obstacks */
54
55 static void
56 x_obstack_grow (struct xheader *xhdr, const char *ptr, size_t length)
57 {
58   obstack_grow (xhdr->stk, ptr, length);
59   xhdr->size += length;
60 }
61
62 static void
63 x_obstack_1grow (struct xheader *xhdr, char c)
64 {
65   obstack_1grow (xhdr->stk, c);
66   xhdr->size++;
67 }
68
69 static void
70 x_obstack_blank (struct xheader *xhdr, size_t length)
71 {
72   obstack_blank (xhdr->stk, length);
73   xhdr->size += length;
74 }
75
76 \f
77 /* Keyword options */
78
79 struct keyword_list
80 {
81   struct keyword_list *next;
82   char *pattern;
83   char *value;
84 };
85
86
87 /* List of keyword patterns set by delete= option */
88 static struct keyword_list *keyword_pattern_list;
89
90 /* List of keyword/value pairs set by 'keyword=value' option */
91 static struct keyword_list *keyword_global_override_list;
92
93 /* List of keyword/value pairs set by 'keyword:=value' option */
94 static struct keyword_list *keyword_override_list;
95
96 /* List of keyword/value pairs decoded from the last 'g' type header */
97 static struct keyword_list *global_header_override_list;
98
99 /* Template for the name field of an 'x' type header */
100 static char *exthdr_name;
101
102 static char *exthdr_mtime_option;
103 static time_t exthdr_mtime;
104
105 /* Template for the name field of a 'g' type header */
106 static char *globexthdr_name;
107
108 static char *globexthdr_mtime_option;
109 static time_t globexthdr_mtime;
110
111 bool
112 xheader_keyword_deleted_p (const char *kw)
113 {
114   struct keyword_list *kp;
115
116   for (kp = keyword_pattern_list; kp; kp = kp->next)
117     if (fnmatch (kp->pattern, kw, 0) == 0)
118       return true;
119   return false;
120 }
121
122 static bool
123 xheader_keyword_override_p (const char *keyword)
124 {
125   struct keyword_list *kp;
126
127   for (kp = keyword_override_list; kp; kp = kp->next)
128     if (strcmp (kp->pattern, keyword) == 0)
129       return true;
130   return false;
131 }
132
133 static void
134 xheader_list_append (struct keyword_list **root, char const *kw,
135                      char const *value)
136 {
137   struct keyword_list *kp = xmalloc (sizeof *kp);
138   kp->pattern = xstrdup (kw);
139   kp->value = value ? xstrdup (value) : NULL;
140   kp->next = *root;
141   *root = kp;
142 }
143
144 static void
145 xheader_list_destroy (struct keyword_list **root)
146 {
147   if (root)
148     {
149       struct keyword_list *kw = *root;
150       while (kw)
151         {
152           struct keyword_list *next = kw->next;
153           free (kw->pattern);
154           free (kw->value);
155           free (kw);
156           kw = next;
157         }
158       *root = NULL;
159     }
160 }
161
162 static void
163 xheader_set_single_keyword (char *kw)
164 {
165   USAGE_ERROR ((0, 0, _("Keyword %s is unknown or not yet implemented"), kw));
166 }
167
168 static void
169 assign_time_option (char **sval, time_t *tval, const char *input)
170 {
171   char *p;
172   struct timespec t = decode_timespec (input, &p, false);
173   if (! valid_timespec (t) || *p)
174     ERROR ((0, 0, _("Time stamp is out of allowed range")));
175   else
176     {
177       *tval = t.tv_sec;
178       assign_string (sval, input);
179     }
180 }
181
182 static void
183 xheader_set_keyword_equal (char *kw, char *eq)
184 {
185   bool global = true;
186   char *p = eq;
187
188   if (eq[-1] == ':')
189     {
190       p--;
191       global = false;
192     }
193
194   while (p > kw && isspace ((unsigned char) *p))
195     p--;
196
197   *p = 0;
198
199   for (p = eq + 1; *p && isspace ((unsigned char) *p); p++)
200     ;
201
202   if (strcmp (kw, "delete") == 0)
203     {
204       if (xheader_protected_pattern_p (p))
205         USAGE_ERROR ((0, 0, _("Pattern %s cannot be used"), quote (p)));
206       xheader_list_append (&keyword_pattern_list, p, NULL);
207     }
208   else if (strcmp (kw, "exthdr.name") == 0)
209     assign_string (&exthdr_name, p);
210   else if (strcmp (kw, "globexthdr.name") == 0)
211     assign_string (&globexthdr_name, p);
212   else if (strcmp (kw, "exthdr.mtime") == 0)
213     assign_time_option (&exthdr_mtime_option, &exthdr_mtime, p);
214   else if (strcmp (kw, "globexthdr.mtime") == 0)
215     assign_time_option (&globexthdr_mtime_option, &globexthdr_mtime, p);
216   else
217     {
218       if (xheader_protected_keyword_p (kw))
219         USAGE_ERROR ((0, 0, _("Keyword %s cannot be overridden"), kw));
220       if (global)
221         xheader_list_append (&keyword_global_override_list, kw, p);
222       else
223         xheader_list_append (&keyword_override_list, kw, p);
224     }
225 }
226
227 void
228 xheader_set_option (char *string)
229 {
230   char *token;
231   for (token = strtok (string, ","); token; token = strtok (NULL, ","))
232     {
233       char *p = strchr (token, '=');
234       if (!p)
235         xheader_set_single_keyword (token);
236       else
237         xheader_set_keyword_equal (token, p);
238     }
239 }
240
241 /*
242     string Includes:          Replaced By:
243      %d                       The directory name of the file,
244                               equivalent to the result of the
245                               dirname utility on the translated
246                               file name.
247      %f                       The filename of the file, equivalent
248                               to the result of the basename
249                               utility on the translated file name.
250      %p                       The process ID of the pax process.
251      %n                       The value of the 3rd argument.
252      %%                       A '%' character. */
253
254 char *
255 xheader_format_name (struct tar_stat_info *st, const char *fmt, size_t n)
256 {
257   char *buf;
258   size_t len = strlen (fmt);
259   char *q;
260   const char *p;
261   char *dirp = NULL;
262   char *dir = NULL;
263   char *base = NULL;
264   char pidbuf[UINTMAX_STRSIZE_BOUND];
265   char const *pptr = NULL;
266   char nbuf[UINTMAX_STRSIZE_BOUND];
267   char const *nptr = NULL;
268
269   for (p = fmt; *p && (p = strchr (p, '%')); )
270     {
271       switch (p[1])
272         {
273         case '%':
274           len--;
275           break;
276
277         case 'd':
278           if (st)
279             {
280               if (!dirp)
281                 dirp = dir_name (st->orig_file_name);
282               dir = safer_name_suffix (dirp, false, absolute_names_option);
283               len += strlen (dir) - 2;
284             }
285           break;
286
287         case 'f':
288           if (st)
289             {
290               base = last_component (st->orig_file_name);
291               len += strlen (base) - 2;
292             }
293           break;
294
295         case 'p':
296           pptr = umaxtostr (getpid (), pidbuf);
297           len += pidbuf + sizeof pidbuf - 1 - pptr - 2;
298           break;
299
300         case 'n':
301           nptr = umaxtostr (n, nbuf);
302           len += nbuf + sizeof nbuf - 1 - nptr - 2;
303           break;
304         }
305       p++;
306     }
307
308   buf = xmalloc (len + 1);
309   for (q = buf, p = fmt; *p; )
310     {
311       if (*p == '%')
312         {
313           switch (p[1])
314             {
315             case '%':
316               *q++ = *p++;
317               p++;
318               break;
319
320             case 'd':
321               if (dir)
322                 q = stpcpy (q, dir);
323               p += 2;
324               break;
325
326             case 'f':
327               if (base)
328                 q = stpcpy (q, base);
329               p += 2;
330               break;
331
332             case 'p':
333               q = stpcpy (q, pptr);
334               p += 2;
335               break;
336
337             case 'n':
338               q = stpcpy (q, nptr);
339               p += 2;
340               break;
341
342
343             default:
344               *q++ = *p++;
345               if (*p)
346                 *q++ = *p++;
347             }
348         }
349       else
350         *q++ = *p++;
351     }
352
353   free (dirp);
354
355   /* Do not allow it to end in a slash */
356   while (q > buf && ISSLASH (q[-1]))
357     q--;
358   *q = 0;
359   return buf;
360 }
361
362 char *
363 xheader_xhdr_name (struct tar_stat_info *st)
364 {
365   if (!exthdr_name)
366     assign_string (&exthdr_name, "%d/PaxHeaders.%p/%f");
367   return xheader_format_name (st, exthdr_name, 0);
368 }
369
370 #define GLOBAL_HEADER_TEMPLATE "/GlobalHead.%p.%n"
371
372 char *
373 xheader_ghdr_name (void)
374 {
375   if (!globexthdr_name)
376     {
377       size_t len;
378       const char *tmp = getenv ("TMPDIR");
379       if (!tmp)
380         tmp = "/tmp";
381       len = strlen (tmp) + sizeof (GLOBAL_HEADER_TEMPLATE); /* Includes nul */
382       globexthdr_name = xmalloc (len);
383       strcpy(globexthdr_name, tmp);
384       strcat(globexthdr_name, GLOBAL_HEADER_TEMPLATE);
385     }
386
387   return xheader_format_name (NULL, globexthdr_name, global_header_count + 1);
388 }
389
390 void
391 xheader_write (char type, char *name, time_t t, struct xheader *xhdr)
392 {
393   union block *header;
394   size_t size;
395   char *p;
396
397   size = xhdr->size;
398   switch (type)
399     {
400     case XGLTYPE:
401       if (globexthdr_mtime_option)
402         t = globexthdr_mtime;
403       break;
404
405     case XHDTYPE:
406       if (exthdr_mtime_option)
407         t = exthdr_mtime;
408       break;
409     }
410   header = start_private_header (name, size, t);
411   header->header.typeflag = type;
412
413   simple_finish_header (header);
414
415   p = xhdr->buffer;
416
417   do
418     {
419       size_t len;
420
421       header = find_next_block ();
422       len = BLOCKSIZE;
423       if (len > size)
424         len = size;
425       memcpy (header->buffer, p, len);
426       if (len < BLOCKSIZE)
427         memset (header->buffer + len, 0, BLOCKSIZE - len);
428       p += len;
429       size -= len;
430       set_next_block_after (header);
431     }
432   while (size > 0);
433   xheader_destroy (xhdr);
434
435   if (type == XGLTYPE)
436     global_header_count++;
437 }
438
439 void
440 xheader_write_global (struct xheader *xhdr)
441 {
442   if (keyword_global_override_list)
443     {
444       struct keyword_list *kp;
445
446       xheader_init (xhdr);
447       for (kp = keyword_global_override_list; kp; kp = kp->next)
448         code_string (kp->value, kp->pattern, xhdr);
449     }
450   if (xhdr->stk)
451     {
452       char *name;
453
454       xheader_finish (xhdr);
455       name = xheader_ghdr_name ();
456       xheader_write (XGLTYPE, name, start_time.tv_sec, xhdr);
457       free (name);
458     }
459 }
460
461 void
462 xheader_xattr_init (struct tar_stat_info *st)
463 {
464   st->xattr_map = NULL;
465   st->xattr_map_size = 0;
466
467   st->acls_a_ptr = NULL;
468   st->acls_a_len = 0;
469   st->acls_d_ptr = NULL;
470   st->acls_d_len = 0;
471   st->cntx_name = NULL;
472 }
473
474 void
475 xheader_xattr_free (struct xattr_array *xattr_map, size_t xattr_map_size)
476 {
477   size_t scan = 0;
478
479   while (scan < xattr_map_size)
480     {
481       free (xattr_map[scan].xkey);
482       free (xattr_map[scan].xval_ptr);
483
484       ++scan;
485     }
486   free (xattr_map);
487 }
488
489 static void
490 xheader_xattr__add (struct xattr_array **xattr_map,
491                     size_t *xattr_map_size,
492                     const char *key, const char *val, size_t len)
493 {
494   size_t pos = (*xattr_map_size)++;
495
496   *xattr_map = xrealloc (*xattr_map,
497                          *xattr_map_size * sizeof(struct xattr_array));
498   (*xattr_map)[pos].xkey = xstrdup (key);
499   (*xattr_map)[pos].xval_ptr = xmemdup (val, len + 1);
500   (*xattr_map)[pos].xval_len = len;
501 }
502
503 /* This is reversal function for xattr_encode_keyword.  See comment for
504    xattr_encode_keyword() for more info. */
505 static void
506 xattr_decode_keyword (char *keyword)
507 {
508   char *kpr, *kpl; /* keyword pointer left/right */
509   kpr = kpl = keyword;
510
511   for (;;)
512     {
513       if (*kpr == '%')
514         {
515           if (kpr[1] == '3' && kpr[2] == 'D')
516             {
517               *kpl = '=';
518               kpr += 3;
519               kpl ++;
520               continue;
521             }
522           else if (kpr[1] == '2' && kpr[2] == '5')
523             {
524               *kpl = '%';
525               kpr += 3;
526               kpl ++;
527               continue;
528             }
529         }
530
531       *kpl = *kpr;
532
533       if (*kpr == 0)
534         break;
535
536       kpr++;
537       kpl++;
538     }
539 }
540
541 void
542 xheader_xattr_add (struct tar_stat_info *st,
543                    const char *key, const char *val, size_t len)
544 {
545   size_t klen = strlen (key);
546   char *xkey = xmalloc (strlen("SCHILY.xattr.") + klen + 1);
547   char *tmp = xkey;
548
549   tmp = stpcpy (tmp, "SCHILY.xattr.");
550   stpcpy (tmp, key);
551
552   xheader_xattr__add (&st->xattr_map, &st->xattr_map_size, xkey, val, len);
553
554   free (xkey);
555 }
556
557 void
558 xheader_xattr_copy (const struct tar_stat_info *st,
559                     struct xattr_array **xattr_map, size_t *xattr_map_size)
560 {
561   size_t scan = 0;
562
563   *xattr_map = NULL;
564   *xattr_map_size = 0;
565
566   while (scan < st->xattr_map_size)
567     {
568       char  *key = st->xattr_map[scan].xkey;
569       char  *val = st->xattr_map[scan].xval_ptr;
570       size_t len = st->xattr_map[scan].xval_len;
571
572       xheader_xattr__add(xattr_map, xattr_map_size, key, val, len);
573
574       ++scan;
575     }
576 }
577
578 \f
579 /* General Interface */
580
581 #define XHDR_PROTECTED 0x01
582 #define XHDR_GLOBAL    0x02
583
584 struct xhdr_tab
585 {
586   char const *keyword;
587   void (*coder) (struct tar_stat_info const *, char const *,
588                  struct xheader *, void const *data);
589   void (*decoder) (struct tar_stat_info *, char const *, char const *, size_t);
590   int flags;
591   bool prefix; /* select handler comparing prefix only */
592 };
593
594 /* This declaration must be extern, because ISO C99 section 6.9.2
595    prohibits a tentative definition that has both internal linkage and
596    incomplete type.  If we made it static, we'd have to declare its
597    size which would be a maintenance pain; if we put its initializer
598    here, we'd need a boatload of forward declarations, which would be
599    even more of a pain.  */
600 extern struct xhdr_tab const xhdr_tab[];
601
602 static struct xhdr_tab const *
603 locate_handler (char const *keyword)
604 {
605   struct xhdr_tab const *p;
606
607   for (p = xhdr_tab; p->keyword; p++)
608     if (p->prefix)
609       {
610         if (strncmp (p->keyword, keyword, strlen(p->keyword)) == 0)
611           return p;
612       }
613     else
614       {
615         if (strcmp (p->keyword, keyword) == 0)
616           return p;
617       }
618
619   return NULL;
620 }
621
622 static bool
623 xheader_protected_pattern_p (const char *pattern)
624 {
625   struct xhdr_tab const *p;
626
627   for (p = xhdr_tab; p->keyword; p++)
628     if (!p->prefix && (p->flags & XHDR_PROTECTED)
629         && fnmatch (pattern, p->keyword, 0) == 0)
630       return true;
631   return false;
632 }
633
634 static bool
635 xheader_protected_keyword_p (const char *keyword)
636 {
637   struct xhdr_tab const *p;
638
639   for (p = xhdr_tab; p->keyword; p++)
640     if (!p->prefix && (p->flags & XHDR_PROTECTED)
641         && strcmp (p->keyword, keyword) == 0)
642       return true;
643   return false;
644 }
645
646 /* Decode a single extended header record, advancing *PTR to the next record.
647    Return true on success, false otherwise.  */
648 static bool
649 decode_record (struct xheader *xhdr,
650                char **ptr,
651                void (*handler) (void *, char const *, char const *, size_t),
652                void *data)
653 {
654   char *start = *ptr;
655   char *p = start;
656   size_t len;
657   char *len_lim;
658   char const *keyword;
659   char *nextp;
660   size_t len_max = xhdr->buffer + xhdr->size - start;
661
662   while (*p == ' ' || *p == '\t')
663     p++;
664
665   if (! ISDIGIT (*p))
666     {
667       if (*p)
668         ERROR ((0, 0, _("Malformed extended header: missing length")));
669       return false;
670     }
671
672   len = strtoumax (p, &len_lim, 10);
673
674   if (len_max < len)
675     {
676       int len_len = len_lim - p;
677       ERROR ((0, 0, _("Extended header length %*s is out of range"),
678               len_len, p));
679       return false;
680     }
681
682   nextp = start + len;
683
684   for (p = len_lim; *p == ' ' || *p == '\t'; p++)
685     continue;
686   if (p == len_lim)
687     {
688       ERROR ((0, 0,
689               _("Malformed extended header: missing blank after length")));
690       return false;
691     }
692
693   keyword = p;
694   p = strchr (p, '=');
695   if (! (p && p < nextp))
696     {
697       ERROR ((0, 0, _("Malformed extended header: missing equal sign")));
698       return false;
699     }
700
701   if (nextp[-1] != '\n')
702     {
703       ERROR ((0, 0, _("Malformed extended header: missing newline")));
704       return false;
705     }
706
707   *p = nextp[-1] = '\0';
708   handler (data, keyword, p + 1, nextp - p - 2); /* '=' + trailing '\n' */
709   *p = '=';
710   nextp[-1] = '\n';
711   *ptr = nextp;
712   return true;
713 }
714
715 static void
716 run_override_list (struct keyword_list *kp, struct tar_stat_info *st)
717 {
718   for (; kp; kp = kp->next)
719     {
720       struct xhdr_tab const *t = locate_handler (kp->pattern);
721       if (t)
722         t->decoder (st, t->keyword, kp->value, strlen (kp->value));
723     }
724 }
725
726 static void
727 decx (void *data, char const *keyword, char const *value, size_t size)
728 {
729   struct xhdr_tab const *t;
730   struct tar_stat_info *st = data;
731
732   if (xheader_keyword_deleted_p (keyword)
733       || xheader_keyword_override_p (keyword))
734     return;
735
736   t = locate_handler (keyword);
737   if (t)
738     t->decoder (st, keyword, value, size);
739   else
740     WARNOPT (WARN_UNKNOWN_KEYWORD,
741              (0, 0, _("Ignoring unknown extended header keyword '%s'"),
742               keyword));
743 }
744
745 void
746 xheader_decode (struct tar_stat_info *st)
747 {
748   run_override_list (keyword_global_override_list, st);
749   run_override_list (global_header_override_list, st);
750
751   if (st->xhdr.size)
752     {
753       char *p = st->xhdr.buffer + BLOCKSIZE;
754       while (decode_record (&st->xhdr, &p, decx, st))
755         continue;
756     }
757   run_override_list (keyword_override_list, st);
758
759   /* The archived (effective) file size is always set directly in tar header
760      field, possibly overridden by "size" extended header - in both cases,
761      result is now decoded in st->stat.st_size */
762   st->archive_file_size = st->stat.st_size;
763
764   /* The real file size (given by stat()) may be redefined for sparse
765      files in "GNU.sparse.realsize" extended header */
766   if (st->real_size_set)
767     st->stat.st_size = st->real_size;
768 }
769
770 static void
771 decg (void *data, char const *keyword, char const *value,
772       size_t size __attribute__((unused)))
773 {
774   struct keyword_list **kwl = data;
775   struct xhdr_tab const *tab = locate_handler (keyword);
776   if (tab && (tab->flags & XHDR_GLOBAL))
777     tab->decoder (data, keyword, value, size);
778   else
779     xheader_list_append (kwl, keyword, value);
780 }
781
782 void
783 xheader_decode_global (struct xheader *xhdr)
784 {
785   if (xhdr->size)
786     {
787       char *p = xhdr->buffer + BLOCKSIZE;
788
789       xheader_list_destroy (&global_header_override_list);
790       while (decode_record (xhdr, &p, decg, &global_header_override_list))
791         continue;
792     }
793 }
794
795 static void
796 xheader_init (struct xheader *xhdr)
797 {
798   if (!xhdr->stk)
799     {
800       xhdr->stk = xmalloc (sizeof *xhdr->stk);
801       obstack_init (xhdr->stk);
802     }
803 }
804
805 void
806 xheader_store (char const *keyword, struct tar_stat_info *st,
807                void const *data)
808 {
809   struct xhdr_tab const *t;
810
811   if (st->xhdr.buffer)
812     return;
813   t = locate_handler (keyword);
814   if (!t || !t->coder)
815     return;
816   if (xheader_keyword_deleted_p (keyword))
817     return;
818   xheader_init (&st->xhdr);
819   if (!xheader_keyword_override_p (keyword))
820     t->coder (st, keyword, &st->xhdr, data);
821 }
822
823 void
824 xheader_read (struct xheader *xhdr, union block *p, off_t size)
825 {
826   size_t j = 0;
827
828   if (size < 0)
829     size = 0; /* Already diagnosed.  */
830
831   if (SIZE_MAX - BLOCKSIZE <= size)
832     xalloc_die ();
833
834   size += BLOCKSIZE;
835   xhdr->size = size;
836   xhdr->buffer = xmalloc (size + 1);
837   xhdr->buffer[size] = '\0';
838
839   do
840     {
841       size_t len = size;
842
843       if (len > BLOCKSIZE)
844         len = BLOCKSIZE;
845
846       if (!p)
847         FATAL_ERROR ((0, 0, _("Unexpected EOF in archive")));
848
849       memcpy (&xhdr->buffer[j], p->buffer, len);
850       set_next_block_after (p);
851
852       p = find_next_block ();
853
854       j += len;
855       size -= len;
856     }
857   while (size > 0);
858 }
859
860 /* xattr_encode_keyword() substitutes '=' ~~> '%3D' and '%' ~~> '%25'
861    in extended attribute keywords.  This is needed because the '=' character
862    has special purpose in extended attribute header - it splits keyword and
863    value part of header.  If there was the '=' occurrence allowed inside
864    keyword, there would be no unambiguous way how to decode this extended
865    attribute.
866
867    (http://lists.gnu.org/archive/html/bug-tar/2012-10/msg00017.html)
868  */
869 static char *
870 xattr_encode_keyword(const char *keyword)
871 {
872   static char *encode_buffer = NULL;
873   static size_t encode_buffer_size = 0;
874   size_t bp; /* keyword/buffer pointers */
875
876   if (!encode_buffer)
877     {
878       encode_buffer_size = 256;
879       encode_buffer = xmalloc (encode_buffer_size);
880     }
881   else
882     *encode_buffer = 0;
883
884   for (bp = 0; *keyword != 0; ++bp, ++keyword)
885     {
886       char c = *keyword;
887
888       if (bp + 2 /* enough for URL encoding also.. */ >= encode_buffer_size)
889         {
890           encode_buffer = x2realloc (encode_buffer, &encode_buffer_size);
891         }
892
893       if (c == '%')
894         {
895           strcpy (encode_buffer + bp, "%25");
896           bp += 2;
897         }
898       else if (c == '=')
899         {
900           strcpy (encode_buffer + bp, "%3D");
901           bp += 2;
902         }
903       else
904         encode_buffer[bp] = c;
905     }
906
907   encode_buffer[bp] = 0;
908
909   return encode_buffer;
910 }
911
912 static void
913 xheader_print_n (struct xheader *xhdr, char const *keyword,
914                  char const *value, size_t vsize)
915 {
916   size_t p;
917   size_t n = 0;
918   char nbuf[UINTMAX_STRSIZE_BOUND];
919   char const *np;
920   size_t len, klen;
921
922   keyword = xattr_encode_keyword (keyword);
923   klen = strlen (keyword);
924   len = klen + vsize + 3; /* ' ' + '=' + '\n' */
925
926   do
927     {
928       p = n;
929       np = umaxtostr (len + p, nbuf);
930       n = nbuf + sizeof nbuf - 1 - np;
931     }
932   while (n != p);
933
934   x_obstack_grow (xhdr, np, n);
935   x_obstack_1grow (xhdr, ' ');
936   x_obstack_grow (xhdr, keyword, klen);
937   x_obstack_1grow (xhdr, '=');
938   x_obstack_grow (xhdr, value, vsize);
939   x_obstack_1grow (xhdr, '\n');
940 }
941
942 static void
943 xheader_print (struct xheader *xhdr, char const *keyword, char const *value)
944 {
945   xheader_print_n (xhdr, keyword, value, strlen (value));
946 }
947
948 void
949 xheader_finish (struct xheader *xhdr)
950 {
951   struct keyword_list *kp;
952
953   for (kp = keyword_override_list; kp; kp = kp->next)
954     code_string (kp->value, kp->pattern, xhdr);
955
956   xhdr->buffer = obstack_finish (xhdr->stk);
957 }
958
959 void
960 xheader_destroy (struct xheader *xhdr)
961 {
962   if (xhdr->stk)
963     {
964       obstack_free (xhdr->stk, NULL);
965       free (xhdr->stk);
966       xhdr->stk = NULL;
967     }
968   else
969     free (xhdr->buffer);
970   xhdr->buffer = 0;
971   xhdr->size = 0;
972 }
973
974 \f
975 /* Buildable strings */
976
977 void
978 xheader_string_begin (struct xheader *xhdr)
979 {
980   xhdr->string_length = 0;
981 }
982
983 void
984 xheader_string_add (struct xheader *xhdr, char const *s)
985 {
986   if (xhdr->buffer)
987     return;
988   xheader_init (xhdr);
989   xhdr->string_length += strlen (s);
990   x_obstack_grow (xhdr, s, strlen (s));
991 }
992
993 bool
994 xheader_string_end (struct xheader *xhdr, char const *keyword)
995 {
996   uintmax_t len;
997   uintmax_t p;
998   uintmax_t n = 0;
999   size_t size;
1000   char nbuf[UINTMAX_STRSIZE_BOUND];
1001   char const *np;
1002   char *cp;
1003
1004   if (xhdr->buffer)
1005     return false;
1006   xheader_init (xhdr);
1007
1008   len = strlen (keyword) + xhdr->string_length + 3; /* ' ' + '=' + '\n' */
1009
1010   do
1011     {
1012       p = n;
1013       np = umaxtostr (len + p, nbuf);
1014       n = nbuf + sizeof nbuf - 1 - np;
1015     }
1016   while (n != p);
1017
1018   p = strlen (keyword) + n + 2;
1019   size = p;
1020   if (size != p)
1021     {
1022       ERROR ((0, 0,
1023         _("Generated keyword/value pair is too long (keyword=%s, length=%s)"),
1024               keyword, nbuf));
1025       obstack_free (xhdr->stk, obstack_finish (xhdr->stk));
1026       return false;
1027     }
1028   x_obstack_blank (xhdr, p);
1029   x_obstack_1grow (xhdr, '\n');
1030   cp = (char*) obstack_next_free (xhdr->stk) - xhdr->string_length - p - 1;
1031   memmove (cp + p, cp, xhdr->string_length);
1032   cp = stpcpy (cp, np);
1033   *cp++ = ' ';
1034   cp = stpcpy (cp, keyword);
1035   *cp++ = '=';
1036   return true;
1037 }
1038
1039 \f
1040 /* Implementations */
1041
1042 static void
1043 out_of_range_header (char const *keyword, char const *value,
1044                      intmax_t minval, uintmax_t maxval)
1045 {
1046   char minval_buf[INT_BUFSIZE_BOUND (intmax_t)];
1047   char maxval_buf[UINTMAX_STRSIZE_BOUND];
1048   char *minval_string = imaxtostr (minval, minval_buf);
1049   char *maxval_string = umaxtostr (maxval, maxval_buf);
1050
1051   /* TRANSLATORS: The first %s is the pax extended header keyword
1052      (atime, gid, etc.).  */
1053   ERROR ((0, 0, _("Extended header %s=%s is out of range %s..%s"),
1054           keyword, value, minval_string, maxval_string));
1055 }
1056
1057 static void
1058 code_string (char const *string, char const *keyword, struct xheader *xhdr)
1059 {
1060   char *outstr;
1061   if (!utf8_convert (true, string, &outstr))
1062     {
1063       /* FIXME: report error */
1064       outstr = xstrdup (string);
1065     }
1066   xheader_print (xhdr, keyword, outstr);
1067   free (outstr);
1068 }
1069
1070 static void
1071 decode_string (char **string, char const *arg)
1072 {
1073   if (*string)
1074     {
1075       free (*string);
1076       *string = NULL;
1077     }
1078   if (!utf8_convert (false, arg, string))
1079     {
1080       /* FIXME: report error and act accordingly to --pax invalid=UTF-8 */
1081       assign_string (string, arg);
1082     }
1083 }
1084
1085 static void
1086 code_time (struct timespec t, char const *keyword, struct xheader *xhdr)
1087 {
1088   char buf[TIMESPEC_STRSIZE_BOUND];
1089   xheader_print (xhdr, keyword, code_timespec (t, buf));
1090 }
1091
1092 static bool
1093 decode_time (struct timespec *ts, char const *arg, char const *keyword)
1094 {
1095   char *arg_lim;
1096   struct timespec t = decode_timespec (arg, &arg_lim, true);
1097
1098   if (! valid_timespec (t))
1099     {
1100       if (arg < arg_lim && !*arg_lim)
1101         out_of_range_header (keyword, arg, TYPE_MINIMUM (time_t),
1102                              TYPE_MAXIMUM (time_t));
1103       else
1104         ERROR ((0, 0, _("Malformed extended header: invalid %s=%s"),
1105                 keyword, arg));
1106       return false;
1107     }
1108
1109   *ts = t;
1110   return true;
1111 }
1112
1113 static void
1114 code_signed_num (uintmax_t value, char const *keyword,
1115                  intmax_t minval, uintmax_t maxval, struct xheader *xhdr)
1116 {
1117   char sbuf[SYSINT_BUFSIZE];
1118   xheader_print (xhdr, keyword, sysinttostr (value, minval, maxval, sbuf));
1119 }
1120
1121 static void
1122 code_num (uintmax_t value, char const *keyword, struct xheader *xhdr)
1123 {
1124   code_signed_num (value, keyword, 0, UINTMAX_MAX, xhdr);
1125 }
1126
1127 static bool
1128 decode_signed_num (intmax_t *num, char const *arg,
1129                    intmax_t minval, uintmax_t maxval,
1130                    char const *keyword)
1131 {
1132   char *arg_lim;
1133   intmax_t u = strtosysint (arg, &arg_lim, minval, maxval);
1134
1135   if (errno == EINVAL || *arg_lim)
1136     {
1137       ERROR ((0, 0, _("Malformed extended header: invalid %s=%s"),
1138               keyword, arg));
1139       return false;
1140     }
1141
1142   if (errno == ERANGE)
1143     {
1144       out_of_range_header (keyword, arg, minval, maxval);
1145       return false;
1146     }
1147
1148   *num = u;
1149   return true;
1150 }
1151
1152 static bool
1153 decode_num (uintmax_t *num, char const *arg, uintmax_t maxval,
1154             char const *keyword)
1155 {
1156   intmax_t i;
1157   if (! decode_signed_num (&i, arg, 0, maxval, keyword))
1158     return false;
1159   *num = i;
1160   return true;
1161 }
1162
1163 static void
1164 dummy_coder (struct tar_stat_info const *st __attribute__ ((unused)),
1165              char const *keyword __attribute__ ((unused)),
1166              struct xheader *xhdr __attribute__ ((unused)),
1167              void const *data __attribute__ ((unused)))
1168 {
1169 }
1170
1171 static void
1172 dummy_decoder (struct tar_stat_info *st __attribute__ ((unused)),
1173                char const *keyword __attribute__ ((unused)),
1174                char const *arg __attribute__ ((unused)),
1175                size_t size __attribute__((unused)))
1176 {
1177 }
1178
1179 static void
1180 atime_coder (struct tar_stat_info const *st, char const *keyword,
1181              struct xheader *xhdr, void const *data __attribute__ ((unused)))
1182 {
1183   code_time (st->atime, keyword, xhdr);
1184 }
1185
1186 static void
1187 atime_decoder (struct tar_stat_info *st,
1188                char const *keyword,
1189                char const *arg,
1190                size_t size __attribute__((unused)))
1191 {
1192   struct timespec ts;
1193   if (decode_time (&ts, arg, keyword))
1194     st->atime = ts;
1195 }
1196
1197 static void
1198 gid_coder (struct tar_stat_info const *st, char const *keyword,
1199            struct xheader *xhdr, void const *data __attribute__ ((unused)))
1200 {
1201   code_signed_num (st->stat.st_gid, keyword,
1202                    TYPE_MINIMUM (gid_t), TYPE_MAXIMUM (gid_t), xhdr);
1203 }
1204
1205 static void
1206 gid_decoder (struct tar_stat_info *st,
1207              char const *keyword,
1208              char const *arg,
1209              size_t size __attribute__((unused)))
1210 {
1211   intmax_t u;
1212   if (decode_signed_num (&u, arg, TYPE_MINIMUM (gid_t),
1213                          TYPE_MAXIMUM (gid_t), keyword))
1214     st->stat.st_gid = u;
1215 }
1216
1217 static void
1218 gname_coder (struct tar_stat_info const *st, char const *keyword,
1219              struct xheader *xhdr, void const *data __attribute__ ((unused)))
1220 {
1221   code_string (st->gname, keyword, xhdr);
1222 }
1223
1224 static void
1225 gname_decoder (struct tar_stat_info *st,
1226                char const *keyword __attribute__((unused)),
1227                char const *arg,
1228                size_t size __attribute__((unused)))
1229 {
1230   decode_string (&st->gname, arg);
1231 }
1232
1233 static void
1234 linkpath_coder (struct tar_stat_info const *st, char const *keyword,
1235                 struct xheader *xhdr, void const *data __attribute__ ((unused)))
1236 {
1237   code_string (st->link_name, keyword, xhdr);
1238 }
1239
1240 static void
1241 linkpath_decoder (struct tar_stat_info *st,
1242                   char const *keyword __attribute__((unused)),
1243                   char const *arg,
1244                   size_t size __attribute__((unused)))
1245 {
1246   decode_string (&st->link_name, arg);
1247 }
1248
1249 static void
1250 ctime_coder (struct tar_stat_info const *st, char const *keyword,
1251              struct xheader *xhdr, void const *data __attribute__ ((unused)))
1252 {
1253   code_time (st->ctime, keyword, xhdr);
1254 }
1255
1256 static void
1257 ctime_decoder (struct tar_stat_info *st,
1258                char const *keyword,
1259                char const *arg,
1260                size_t size __attribute__((unused)))
1261 {
1262   struct timespec ts;
1263   if (decode_time (&ts, arg, keyword))
1264     st->ctime = ts;
1265 }
1266
1267 static void
1268 mtime_coder (struct tar_stat_info const *st, char const *keyword,
1269              struct xheader *xhdr, void const *data)
1270 {
1271   struct timespec const *mtime = data;
1272   code_time (mtime ? *mtime : st->mtime, keyword, xhdr);
1273 }
1274
1275 static void
1276 mtime_decoder (struct tar_stat_info *st,
1277                char const *keyword,
1278                char const *arg,
1279                size_t size __attribute__((unused)))
1280 {
1281   struct timespec ts;
1282   if (decode_time (&ts, arg, keyword))
1283     st->mtime = ts;
1284 }
1285
1286 static void
1287 path_coder (struct tar_stat_info const *st, char const *keyword,
1288             struct xheader *xhdr, void const *data __attribute__ ((unused)))
1289 {
1290   code_string (st->file_name, keyword, xhdr);
1291 }
1292
1293 static void
1294 path_decoder (struct tar_stat_info *st,
1295               char const *keyword __attribute__((unused)),
1296               char const *arg,
1297               size_t size __attribute__((unused)))
1298 {
1299   decode_string (&st->orig_file_name, arg);
1300   decode_string (&st->file_name, arg);
1301   st->had_trailing_slash = strip_trailing_slashes (st->file_name);
1302 }
1303
1304 static void
1305 size_coder (struct tar_stat_info const *st, char const *keyword,
1306             struct xheader *xhdr, void const *data __attribute__ ((unused)))
1307 {
1308   code_num (st->stat.st_size, keyword, xhdr);
1309 }
1310
1311 static void
1312 size_decoder (struct tar_stat_info *st,
1313               char const *keyword,
1314               char const *arg,
1315               size_t size __attribute__((unused)))
1316 {
1317   uintmax_t u;
1318   if (decode_num (&u, arg, TYPE_MAXIMUM (off_t), keyword))
1319     st->stat.st_size = u;
1320 }
1321
1322 static void
1323 uid_coder (struct tar_stat_info const *st, char const *keyword,
1324            struct xheader *xhdr, void const *data __attribute__ ((unused)))
1325 {
1326   code_signed_num (st->stat.st_uid, keyword,
1327                    TYPE_MINIMUM (uid_t), TYPE_MAXIMUM (uid_t), xhdr);
1328 }
1329
1330 static void
1331 uid_decoder (struct tar_stat_info *st,
1332              char const *keyword,
1333              char const *arg,
1334              size_t size __attribute__((unused)))
1335 {
1336   intmax_t u;
1337   if (decode_signed_num (&u, arg, TYPE_MINIMUM (uid_t),
1338                          TYPE_MAXIMUM (uid_t), keyword))
1339     st->stat.st_uid = u;
1340 }
1341
1342 static void
1343 uname_coder (struct tar_stat_info const *st, char const *keyword,
1344              struct xheader *xhdr, void const *data __attribute__ ((unused)))
1345 {
1346   code_string (st->uname, keyword, xhdr);
1347 }
1348
1349 static void
1350 uname_decoder (struct tar_stat_info *st,
1351                char const *keyword __attribute__((unused)),
1352                char const *arg,
1353                size_t size __attribute__((unused)))
1354 {
1355   decode_string (&st->uname, arg);
1356 }
1357
1358 static void
1359 sparse_size_coder (struct tar_stat_info const *st, char const *keyword,
1360              struct xheader *xhdr, void const *data)
1361 {
1362   size_coder (st, keyword, xhdr, data);
1363 }
1364
1365 static void
1366 sparse_size_decoder (struct tar_stat_info *st,
1367                      char const *keyword,
1368                      char const *arg,
1369                      size_t size __attribute__((unused)))
1370 {
1371   uintmax_t u;
1372   if (decode_num (&u, arg, TYPE_MAXIMUM (off_t), keyword))
1373     {
1374       st->real_size_set = 1;
1375       st->real_size = u;
1376     }
1377 }
1378
1379 static void
1380 sparse_numblocks_coder (struct tar_stat_info const *st, char const *keyword,
1381                         struct xheader *xhdr,
1382                         void const *data __attribute__ ((unused)))
1383 {
1384   code_num (st->sparse_map_avail, keyword, xhdr);
1385 }
1386
1387 static void
1388 sparse_numblocks_decoder (struct tar_stat_info *st,
1389                           char const *keyword,
1390                           char const *arg,
1391                           size_t size __attribute__((unused)))
1392 {
1393   uintmax_t u;
1394   if (decode_num (&u, arg, SIZE_MAX, keyword))
1395     {
1396       st->sparse_map_size = u;
1397       st->sparse_map = xcalloc (u, sizeof st->sparse_map[0]);
1398       st->sparse_map_avail = 0;
1399     }
1400 }
1401
1402 static void
1403 sparse_offset_coder (struct tar_stat_info const *st, char const *keyword,
1404                      struct xheader *xhdr, void const *data)
1405 {
1406   size_t const *pi = data;
1407   code_num (st->sparse_map[*pi].offset, keyword, xhdr);
1408 }
1409
1410 static void
1411 sparse_offset_decoder (struct tar_stat_info *st,
1412                        char const *keyword,
1413                        char const *arg,
1414                        size_t size __attribute__((unused)))
1415 {
1416   uintmax_t u;
1417   if (decode_num (&u, arg, TYPE_MAXIMUM (off_t), keyword))
1418     {
1419       if (st->sparse_map_avail < st->sparse_map_size)
1420         st->sparse_map[st->sparse_map_avail].offset = u;
1421       else
1422         ERROR ((0, 0, _("Malformed extended header: excess %s=%s"),
1423                 "GNU.sparse.offset", arg));
1424     }
1425 }
1426
1427 static void
1428 sparse_numbytes_coder (struct tar_stat_info const *st, char const *keyword,
1429                        struct xheader *xhdr, void const *data)
1430 {
1431   size_t const *pi = data;
1432   code_num (st->sparse_map[*pi].numbytes, keyword, xhdr);
1433 }
1434
1435 static void
1436 sparse_numbytes_decoder (struct tar_stat_info *st,
1437                          char const *keyword,
1438                          char const *arg,
1439                          size_t size __attribute__((unused)))
1440 {
1441   uintmax_t u;
1442   if (decode_num (&u, arg, TYPE_MAXIMUM (off_t), keyword))
1443     {
1444       if (st->sparse_map_avail < st->sparse_map_size)
1445         st->sparse_map[st->sparse_map_avail++].numbytes = u;
1446       else
1447         ERROR ((0, 0, _("Malformed extended header: excess %s=%s"),
1448                 keyword, arg));
1449     }
1450 }
1451
1452 static void
1453 sparse_map_decoder (struct tar_stat_info *st,
1454                     char const *keyword,
1455                     char const *arg,
1456                     size_t size __attribute__((unused)))
1457 {
1458   int offset = 1;
1459   struct sp_array e;
1460
1461   st->sparse_map_avail = 0;
1462   while (1)
1463     {
1464       intmax_t u;
1465       char *delim;
1466
1467       if (!ISDIGIT (*arg))
1468         {
1469           ERROR ((0, 0, _("Malformed extended header: invalid %s=%s"),
1470                   keyword, arg));
1471           return;
1472         }
1473
1474       errno = 0;
1475       u = strtoimax (arg, &delim, 10);
1476       if (TYPE_MAXIMUM (off_t) < u)
1477         {
1478           u = TYPE_MAXIMUM (off_t);
1479           errno = ERANGE;
1480         }
1481       if (offset)
1482         {
1483           e.offset = u;
1484           if (errno == ERANGE)
1485             {
1486               out_of_range_header (keyword, arg, 0, TYPE_MAXIMUM (off_t));
1487               return;
1488             }
1489         }
1490       else
1491         {
1492           e.numbytes = u;
1493           if (errno == ERANGE)
1494             {
1495               out_of_range_header (keyword, arg, 0, TYPE_MAXIMUM (off_t));
1496               return;
1497             }
1498           if (st->sparse_map_avail < st->sparse_map_size)
1499             st->sparse_map[st->sparse_map_avail++] = e;
1500           else
1501             {
1502               ERROR ((0, 0, _("Malformed extended header: excess %s=%s"),
1503                       keyword, arg));
1504               return;
1505             }
1506         }
1507
1508       offset = !offset;
1509
1510       if (*delim == 0)
1511         break;
1512       else if (*delim != ',')
1513         {
1514           ERROR ((0, 0,
1515                   _("Malformed extended header: invalid %s: unexpected delimiter %c"),
1516                   keyword, *delim));
1517           return;
1518         }
1519
1520       arg = delim + 1;
1521     }
1522
1523   if (!offset)
1524     ERROR ((0, 0,
1525             _("Malformed extended header: invalid %s: odd number of values"),
1526             keyword));
1527 }
1528
1529 static void
1530 dumpdir_coder (struct tar_stat_info const *st, char const *keyword,
1531                struct xheader *xhdr, void const *data)
1532 {
1533   xheader_print_n (xhdr, keyword, data, dumpdir_size (data));
1534 }
1535
1536 static void
1537 dumpdir_decoder (struct tar_stat_info *st,
1538                  char const *keyword __attribute__((unused)),
1539                  char const *arg,
1540                  size_t size)
1541 {
1542   st->dumpdir = xmalloc (size);
1543   memcpy (st->dumpdir, arg, size);
1544 }
1545
1546 static void
1547 volume_label_coder (struct tar_stat_info const *st, char const *keyword,
1548                     struct xheader *xhdr, void const *data)
1549 {
1550   code_string (data, keyword, xhdr);
1551 }
1552
1553 static void
1554 volume_label_decoder (struct tar_stat_info *st,
1555                       char const *keyword __attribute__((unused)),
1556                       char const *arg,
1557                       size_t size __attribute__((unused)))
1558 {
1559   decode_string (&volume_label, arg);
1560 }
1561
1562 static void
1563 volume_size_coder (struct tar_stat_info const *st, char const *keyword,
1564                    struct xheader *xhdr, void const *data)
1565 {
1566   off_t const *v = data;
1567   code_num (*v, keyword, xhdr);
1568 }
1569
1570 static void
1571 volume_size_decoder (struct tar_stat_info *st,
1572                      char const *keyword,
1573                      char const *arg, size_t size)
1574 {
1575   uintmax_t u;
1576   if (decode_num (&u, arg, TYPE_MAXIMUM (uintmax_t), keyword))
1577     continued_file_size = u;
1578 }
1579
1580 /* FIXME: Merge with volume_size_coder */
1581 static void
1582 volume_offset_coder (struct tar_stat_info const *st, char const *keyword,
1583                      struct xheader *xhdr, void const *data)
1584 {
1585   off_t const *v = data;
1586   code_num (*v, keyword, xhdr);
1587 }
1588
1589 static void
1590 volume_offset_decoder (struct tar_stat_info *st,
1591                        char const *keyword,
1592                        char const *arg, size_t size)
1593 {
1594   uintmax_t u;
1595   if (decode_num (&u, arg, TYPE_MAXIMUM (uintmax_t), keyword))
1596     continued_file_offset = u;
1597 }
1598
1599 static void
1600 volume_filename_decoder (struct tar_stat_info *st,
1601                          char const *keyword __attribute__((unused)),
1602                          char const *arg,
1603                          size_t size __attribute__((unused)))
1604 {
1605   decode_string (&continued_file_name, arg);
1606 }
1607
1608 static void
1609 xattr_selinux_coder (struct tar_stat_info const *st, char const *keyword,
1610                      struct xheader *xhdr, void const *data)
1611 {
1612   code_string (st->cntx_name, keyword, xhdr);
1613 }
1614
1615 static void
1616 xattr_selinux_decoder (struct tar_stat_info *st,
1617                        char const *keyword, char const *arg, size_t size)
1618 {
1619   decode_string (&st->cntx_name, arg);
1620 }
1621
1622 static void
1623 xattr_acls_a_coder (struct tar_stat_info const *st , char const *keyword,
1624                     struct xheader *xhdr, void const *data)
1625 {
1626   xheader_print_n (xhdr, keyword, st->acls_a_ptr, st->acls_a_len);
1627 }
1628
1629 static void
1630 xattr_acls_a_decoder (struct tar_stat_info *st,
1631                       char const *keyword, char const *arg, size_t size)
1632 {
1633   st->acls_a_ptr = xmemdup (arg, size + 1);
1634   st->acls_a_len = size;
1635 }
1636
1637 static void
1638 xattr_acls_d_coder (struct tar_stat_info const *st , char const *keyword,
1639                     struct xheader *xhdr, void const *data)
1640 {
1641   xheader_print_n (xhdr, keyword, st->acls_d_ptr, st->acls_d_len);
1642 }
1643
1644 static void
1645 xattr_acls_d_decoder (struct tar_stat_info *st,
1646                       char const *keyword, char const *arg, size_t size)
1647 {
1648   st->acls_d_ptr = xmemdup (arg, size + 1);
1649   st->acls_d_len = size;
1650 }
1651
1652 static void
1653 xattr_coder (struct tar_stat_info const *st, char const *keyword,
1654              struct xheader *xhdr, void const *data)
1655 {
1656   struct xattr_array *xattr_map = st->xattr_map;
1657   const size_t *off = data;
1658   xheader_print_n (xhdr, keyword,
1659                    xattr_map[*off].xval_ptr, xattr_map[*off].xval_len);
1660 }
1661
1662 static void
1663 xattr_decoder (struct tar_stat_info *st,
1664                char const *keyword, char const *arg, size_t size)
1665 {
1666   char *xstr, *xkey;
1667
1668   /* copy keyword */
1669   size_t klen_raw = strlen (keyword);
1670   xkey = alloca (klen_raw + 1);
1671   memcpy (xkey, keyword, klen_raw + 1) /* including null-terminating */;
1672
1673   /* copy value */
1674   xstr = alloca (size + 1);
1675   memcpy (xstr, arg, size + 1); /* separator included, for GNU tar '\n' */;
1676
1677   xattr_decode_keyword (xkey);
1678
1679   xheader_xattr_add (st, xkey + strlen("SCHILY.xattr."), xstr, size);
1680 }
1681
1682 static void
1683 sparse_major_coder (struct tar_stat_info const *st, char const *keyword,
1684                     struct xheader *xhdr, void const *data)
1685 {
1686   code_num (st->sparse_major, keyword, xhdr);
1687 }
1688
1689 static void
1690 sparse_major_decoder (struct tar_stat_info *st,
1691                       char const *keyword,
1692                       char const *arg,
1693                       size_t size)
1694 {
1695   uintmax_t u;
1696   if (decode_num (&u, arg, TYPE_MAXIMUM (unsigned), keyword))
1697     st->sparse_major = u;
1698 }
1699
1700 static void
1701 sparse_minor_coder (struct tar_stat_info const *st, char const *keyword,
1702                       struct xheader *xhdr, void const *data)
1703 {
1704   code_num (st->sparse_minor, keyword, xhdr);
1705 }
1706
1707 static void
1708 sparse_minor_decoder (struct tar_stat_info *st,
1709                       char const *keyword,
1710                       char const *arg,
1711                       size_t size)
1712 {
1713   uintmax_t u;
1714   if (decode_num (&u, arg, TYPE_MAXIMUM (unsigned), keyword))
1715     st->sparse_minor = u;
1716 }
1717
1718 struct xhdr_tab const xhdr_tab[] = {
1719   { "atime",    atime_coder,    atime_decoder,    0, false },
1720   { "comment",  dummy_coder,    dummy_decoder,    0, false },
1721   { "charset",  dummy_coder,    dummy_decoder,    0, false },
1722   { "ctime",    ctime_coder,    ctime_decoder,    0, false },
1723   { "gid",      gid_coder,      gid_decoder,      0, false },
1724   { "gname",    gname_coder,    gname_decoder,    0, false },
1725   { "linkpath", linkpath_coder, linkpath_decoder, 0, false },
1726   { "mtime",    mtime_coder,    mtime_decoder,    0, false },
1727   { "path",     path_coder,     path_decoder,     0, false },
1728   { "size",     size_coder,     size_decoder,     0, false },
1729   { "uid",      uid_coder,      uid_decoder,      0, false },
1730   { "uname",    uname_coder,    uname_decoder,    0, false },
1731
1732   /* Sparse file handling */
1733   { "GNU.sparse.name",       path_coder, path_decoder,
1734     XHDR_PROTECTED, false },
1735   { "GNU.sparse.major",      sparse_major_coder, sparse_major_decoder,
1736     XHDR_PROTECTED, false },
1737   { "GNU.sparse.minor",      sparse_minor_coder, sparse_minor_decoder,
1738     XHDR_PROTECTED, false },
1739   { "GNU.sparse.realsize",   sparse_size_coder, sparse_size_decoder,
1740     XHDR_PROTECTED, false },
1741   { "GNU.sparse.numblocks",  sparse_numblocks_coder, sparse_numblocks_decoder,
1742     XHDR_PROTECTED, false },
1743
1744   /* tar 1.14 - 1.15.90 keywords. */
1745   { "GNU.sparse.size",       sparse_size_coder, sparse_size_decoder,
1746     XHDR_PROTECTED, false },
1747   /* tar 1.14 - 1.15.1 keywords. Multiple instances of these appeared in 'x'
1748      headers, and each of them was meaningful. It confilcted with POSIX specs,
1749      which requires that "when extended header records conflict, the last one
1750      given in the header shall take precedence." */
1751   { "GNU.sparse.offset",     sparse_offset_coder, sparse_offset_decoder,
1752     XHDR_PROTECTED, false },
1753   { "GNU.sparse.numbytes",   sparse_numbytes_coder, sparse_numbytes_decoder,
1754     XHDR_PROTECTED, false },
1755   /* tar 1.15.90 keyword, introduced to remove the above-mentioned conflict. */
1756   { "GNU.sparse.map",        NULL /* Unused, see pax_dump_header() */,
1757     sparse_map_decoder, 0, false },
1758
1759   { "GNU.dumpdir",           dumpdir_coder, dumpdir_decoder,
1760     XHDR_PROTECTED, false },
1761
1762   /* Keeps the tape/volume label. May be present only in the global headers.
1763      Equivalent to GNUTYPE_VOLHDR.  */
1764   { "GNU.volume.label", volume_label_coder, volume_label_decoder,
1765     XHDR_PROTECTED | XHDR_GLOBAL, false },
1766
1767   /* These may be present in a first global header of the archive.
1768      They provide the same functionality as GNUTYPE_MULTIVOL header.
1769      The GNU.volume.size keeps the real_s_sizeleft value, which is
1770      otherwise kept in the size field of a multivolume header.  The
1771      GNU.volume.offset keeps the offset of the start of this volume,
1772      otherwise kept in oldgnu_header.offset.  */
1773   { "GNU.volume.filename", volume_label_coder, volume_filename_decoder,
1774     XHDR_PROTECTED | XHDR_GLOBAL, false },
1775   { "GNU.volume.size", volume_size_coder, volume_size_decoder,
1776     XHDR_PROTECTED | XHDR_GLOBAL, false },
1777   { "GNU.volume.offset", volume_offset_coder, volume_offset_decoder,
1778     XHDR_PROTECTED | XHDR_GLOBAL, false },
1779
1780   /* We get the SELinux value from filecon, so add a namespace for SELinux
1781      instead of storing it in SCHILY.xattr.* (which would be RAW). */
1782   { "RHT.security.selinux",
1783     xattr_selinux_coder, xattr_selinux_decoder, 0, false },
1784
1785   /* ACLs, use the star format... */
1786   { "SCHILY.acl.access",
1787     xattr_acls_a_coder, xattr_acls_a_decoder, 0, false },
1788
1789   { "SCHILY.acl.default",
1790     xattr_acls_d_coder, xattr_acls_d_decoder, 0, false },
1791
1792   /* We are storing all extended attributes using this rule even if some of them
1793      were stored by some previous rule (duplicates) -- we just have to make sure
1794      they are restored *only once* during extraction later on. */
1795   { "SCHILY.xattr", xattr_coder, xattr_decoder, 0, true },
1796
1797   { NULL, NULL, NULL, 0, false }
1798 };