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