Import upstream version 1.28
[debian/tar] / src / xheader.c
1 /* POSIX extended headers for tar.
2
3    Copyright (C) 2003-2007, 2009-2010, 2012-2014 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
760 static void
761 decg (void *data, char const *keyword, char const *value,
762       size_t size __attribute__((unused)))
763 {
764   struct keyword_list **kwl = data;
765   struct xhdr_tab const *tab = locate_handler (keyword);
766   if (tab && (tab->flags & XHDR_GLOBAL))
767     tab->decoder (data, keyword, value, size);
768   else
769     xheader_list_append (kwl, keyword, value);
770 }
771
772 void
773 xheader_decode_global (struct xheader *xhdr)
774 {
775   if (xhdr->size)
776     {
777       char *p = xhdr->buffer + BLOCKSIZE;
778
779       xheader_list_destroy (&global_header_override_list);
780       while (decode_record (xhdr, &p, decg, &global_header_override_list))
781         continue;
782     }
783 }
784
785 static void
786 xheader_init (struct xheader *xhdr)
787 {
788   if (!xhdr->stk)
789     {
790       xhdr->stk = xmalloc (sizeof *xhdr->stk);
791       obstack_init (xhdr->stk);
792     }
793 }
794
795 void
796 xheader_store (char const *keyword, struct tar_stat_info *st,
797                void const *data)
798 {
799   struct xhdr_tab const *t;
800
801   if (st->xhdr.buffer)
802     return;
803   t = locate_handler (keyword);
804   if (!t || !t->coder)
805     return;
806   if (xheader_keyword_deleted_p (keyword)
807       || xheader_keyword_override_p (keyword))
808     return;
809   xheader_init (&st->xhdr);
810   t->coder (st, keyword, &st->xhdr, data);
811 }
812
813 void
814 xheader_read (struct xheader *xhdr, union block *p, off_t size)
815 {
816   size_t j = 0;
817
818   if (size < 0)
819     size = 0; /* Already diagnosed.  */
820
821   if (SIZE_MAX - BLOCKSIZE <= size)
822     xalloc_die ();
823
824   size += BLOCKSIZE;
825   xhdr->size = size;
826   xhdr->buffer = xmalloc (size + 1);
827   xhdr->buffer[size] = '\0';
828
829   do
830     {
831       size_t len = size;
832
833       if (len > BLOCKSIZE)
834         len = BLOCKSIZE;
835
836       if (!p)
837         FATAL_ERROR ((0, 0, _("Unexpected EOF in archive")));
838
839       memcpy (&xhdr->buffer[j], p->buffer, len);
840       set_next_block_after (p);
841
842       p = find_next_block ();
843
844       j += len;
845       size -= len;
846     }
847   while (size > 0);
848 }
849
850 /* xattr_encode_keyword() substitutes '=' ~~> '%3D' and '%' ~~> '%25'
851    in extended attribute keywords.  This is needed because the '=' character
852    has special purpose in extended attribute header - it splits keyword and
853    value part of header.  If there was the '=' occurrence allowed inside
854    keyword, there would be no unambiguous way how to decode this extended
855    attribute.
856
857    (http://lists.gnu.org/archive/html/bug-tar/2012-10/msg00017.html)
858  */
859 static char *
860 xattr_encode_keyword(const char *keyword)
861 {
862   static char *encode_buffer = NULL;
863   static size_t encode_buffer_size = 0;
864   size_t bp; /* keyword/buffer pointers */
865
866   if (!encode_buffer)
867     {
868       encode_buffer_size = 256;
869       encode_buffer = xmalloc (encode_buffer_size);
870     }
871   else
872     *encode_buffer = 0;
873
874   for (bp = 0; *keyword != 0; ++bp, ++keyword)
875     {
876       char c = *keyword;
877
878       if (bp + 2 /* enough for URL encoding also.. */ >= encode_buffer_size)
879         {
880           encode_buffer = x2realloc (encode_buffer, &encode_buffer_size);
881         }
882
883       if (c == '%')
884         {
885           strcpy (encode_buffer + bp, "%25");
886           bp += 2;
887         }
888       else if (c == '=')
889         {
890           strcpy (encode_buffer + bp, "%3D");
891           bp += 2;
892         }
893       else
894         encode_buffer[bp] = c;
895     }
896
897   encode_buffer[bp] = 0;
898
899   return encode_buffer;
900 }
901
902 static void
903 xheader_print_n (struct xheader *xhdr, char const *keyword,
904                  char const *value, size_t vsize)
905 {
906   size_t p;
907   size_t n = 0;
908   char nbuf[UINTMAX_STRSIZE_BOUND];
909   char const *np;
910   size_t len, klen;
911
912   keyword = xattr_encode_keyword (keyword);
913   klen = strlen (keyword);
914   len = klen + vsize + 3; /* ' ' + '=' + '\n' */
915
916   do
917     {
918       p = n;
919       np = umaxtostr (len + p, nbuf);
920       n = nbuf + sizeof nbuf - 1 - np;
921     }
922   while (n != p);
923
924   x_obstack_grow (xhdr, np, n);
925   x_obstack_1grow (xhdr, ' ');
926   x_obstack_grow (xhdr, keyword, klen);
927   x_obstack_1grow (xhdr, '=');
928   x_obstack_grow (xhdr, value, vsize);
929   x_obstack_1grow (xhdr, '\n');
930 }
931
932 static void
933 xheader_print (struct xheader *xhdr, char const *keyword, char const *value)
934 {
935   xheader_print_n (xhdr, keyword, value, strlen (value));
936 }
937
938 void
939 xheader_finish (struct xheader *xhdr)
940 {
941   struct keyword_list *kp;
942
943   for (kp = keyword_override_list; kp; kp = kp->next)
944     code_string (kp->value, kp->pattern, xhdr);
945
946   xhdr->buffer = obstack_finish (xhdr->stk);
947 }
948
949 void
950 xheader_destroy (struct xheader *xhdr)
951 {
952   if (xhdr->stk)
953     {
954       obstack_free (xhdr->stk, NULL);
955       free (xhdr->stk);
956       xhdr->stk = NULL;
957     }
958   else
959     free (xhdr->buffer);
960   xhdr->buffer = 0;
961   xhdr->size = 0;
962 }
963
964 \f
965 /* Buildable strings */
966
967 void
968 xheader_string_begin (struct xheader *xhdr)
969 {
970   xhdr->string_length = 0;
971 }
972
973 void
974 xheader_string_add (struct xheader *xhdr, char const *s)
975 {
976   if (xhdr->buffer)
977     return;
978   xheader_init (xhdr);
979   xhdr->string_length += strlen (s);
980   x_obstack_grow (xhdr, s, strlen (s));
981 }
982
983 bool
984 xheader_string_end (struct xheader *xhdr, char const *keyword)
985 {
986   uintmax_t len;
987   uintmax_t p;
988   uintmax_t n = 0;
989   size_t size;
990   char nbuf[UINTMAX_STRSIZE_BOUND];
991   char const *np;
992   char *cp;
993
994   if (xhdr->buffer)
995     return false;
996   xheader_init (xhdr);
997
998   len = strlen (keyword) + xhdr->string_length + 3; /* ' ' + '=' + '\n' */
999
1000   do
1001     {
1002       p = n;
1003       np = umaxtostr (len + p, nbuf);
1004       n = nbuf + sizeof nbuf - 1 - np;
1005     }
1006   while (n != p);
1007
1008   p = strlen (keyword) + n + 2;
1009   size = p;
1010   if (size != p)
1011     {
1012       ERROR ((0, 0,
1013         _("Generated keyword/value pair is too long (keyword=%s, length=%s)"),
1014               keyword, nbuf));
1015       obstack_free (xhdr->stk, obstack_finish (xhdr->stk));
1016       return false;
1017     }
1018   x_obstack_blank (xhdr, p);
1019   x_obstack_1grow (xhdr, '\n');
1020   cp = obstack_next_free (xhdr->stk) - xhdr->string_length - p - 1;
1021   memmove (cp + p, cp, xhdr->string_length);
1022   cp = stpcpy (cp, np);
1023   *cp++ = ' ';
1024   cp = stpcpy (cp, keyword);
1025   *cp++ = '=';
1026   return true;
1027 }
1028
1029 \f
1030 /* Implementations */
1031
1032 static void
1033 out_of_range_header (char const *keyword, char const *value,
1034                      intmax_t minval, uintmax_t maxval)
1035 {
1036   char minval_buf[INT_BUFSIZE_BOUND (intmax_t)];
1037   char maxval_buf[UINTMAX_STRSIZE_BOUND];
1038   char *minval_string = imaxtostr (minval, minval_buf);
1039   char *maxval_string = umaxtostr (maxval, maxval_buf);
1040
1041   /* TRANSLATORS: The first %s is the pax extended header keyword
1042      (atime, gid, etc.).  */
1043   ERROR ((0, 0, _("Extended header %s=%s is out of range %s..%s"),
1044           keyword, value, minval_string, maxval_string));
1045 }
1046
1047 static void
1048 code_string (char const *string, char const *keyword, struct xheader *xhdr)
1049 {
1050   char *outstr;
1051   if (!utf8_convert (true, string, &outstr))
1052     {
1053       /* FIXME: report error */
1054       outstr = xstrdup (string);
1055     }
1056   xheader_print (xhdr, keyword, outstr);
1057   free (outstr);
1058 }
1059
1060 static void
1061 decode_string (char **string, char const *arg)
1062 {
1063   if (*string)
1064     {
1065       free (*string);
1066       *string = NULL;
1067     }
1068   if (!utf8_convert (false, arg, string))
1069     {
1070       /* FIXME: report error and act accordingly to --pax invalid=UTF-8 */
1071       assign_string (string, arg);
1072     }
1073 }
1074
1075 static void
1076 code_time (struct timespec t, char const *keyword, struct xheader *xhdr)
1077 {
1078   char buf[TIMESPEC_STRSIZE_BOUND];
1079   xheader_print (xhdr, keyword, code_timespec (t, buf));
1080 }
1081
1082 static bool
1083 decode_time (struct timespec *ts, char const *arg, char const *keyword)
1084 {
1085   char *arg_lim;
1086   struct timespec t = decode_timespec (arg, &arg_lim, true);
1087
1088   if (! valid_timespec (t))
1089     {
1090       if (arg < arg_lim && !*arg_lim)
1091         out_of_range_header (keyword, arg, TYPE_MINIMUM (time_t),
1092                              TYPE_MAXIMUM (time_t));
1093       else
1094         ERROR ((0, 0, _("Malformed extended header: invalid %s=%s"),
1095                 keyword, arg));
1096       return false;
1097     }
1098
1099   *ts = t;
1100   return true;
1101 }
1102
1103 static void
1104 code_signed_num (uintmax_t value, char const *keyword,
1105                  intmax_t minval, uintmax_t maxval, struct xheader *xhdr)
1106 {
1107   char sbuf[SYSINT_BUFSIZE];
1108   xheader_print (xhdr, keyword, sysinttostr (value, minval, maxval, sbuf));
1109 }
1110
1111 static void
1112 code_num (uintmax_t value, char const *keyword, struct xheader *xhdr)
1113 {
1114   code_signed_num (value, keyword, 0, UINTMAX_MAX, xhdr);
1115 }
1116
1117 static bool
1118 decode_signed_num (intmax_t *num, char const *arg,
1119                    intmax_t minval, uintmax_t maxval,
1120                    char const *keyword)
1121 {
1122   char *arg_lim;
1123   intmax_t u = strtosysint (arg, &arg_lim, minval, maxval);
1124
1125   if (errno == EINVAL || *arg_lim)
1126     {
1127       ERROR ((0, 0, _("Malformed extended header: invalid %s=%s"),
1128               keyword, arg));
1129       return false;
1130     }
1131
1132   if (errno == ERANGE)
1133     {
1134       out_of_range_header (keyword, arg, minval, maxval);
1135       return false;
1136     }
1137
1138   *num = u;
1139   return true;
1140 }
1141
1142 static bool
1143 decode_num (uintmax_t *num, char const *arg, uintmax_t maxval,
1144             char const *keyword)
1145 {
1146   intmax_t i;
1147   if (! decode_signed_num (&i, arg, 0, maxval, keyword))
1148     return false;
1149   *num = i;
1150   return true;
1151 }
1152
1153 static void
1154 dummy_coder (struct tar_stat_info const *st __attribute__ ((unused)),
1155              char const *keyword __attribute__ ((unused)),
1156              struct xheader *xhdr __attribute__ ((unused)),
1157              void const *data __attribute__ ((unused)))
1158 {
1159 }
1160
1161 static void
1162 dummy_decoder (struct tar_stat_info *st __attribute__ ((unused)),
1163                char const *keyword __attribute__ ((unused)),
1164                char const *arg __attribute__ ((unused)),
1165                size_t size __attribute__((unused)))
1166 {
1167 }
1168
1169 static void
1170 atime_coder (struct tar_stat_info const *st, char const *keyword,
1171              struct xheader *xhdr, void const *data __attribute__ ((unused)))
1172 {
1173   code_time (st->atime, keyword, xhdr);
1174 }
1175
1176 static void
1177 atime_decoder (struct tar_stat_info *st,
1178                char const *keyword,
1179                char const *arg,
1180                size_t size __attribute__((unused)))
1181 {
1182   struct timespec ts;
1183   if (decode_time (&ts, arg, keyword))
1184     st->atime = ts;
1185 }
1186
1187 static void
1188 gid_coder (struct tar_stat_info const *st, char const *keyword,
1189            struct xheader *xhdr, void const *data __attribute__ ((unused)))
1190 {
1191   code_signed_num (st->stat.st_gid, keyword,
1192                    TYPE_MINIMUM (gid_t), TYPE_MAXIMUM (gid_t), xhdr);
1193 }
1194
1195 static void
1196 gid_decoder (struct tar_stat_info *st,
1197              char const *keyword,
1198              char const *arg,
1199              size_t size __attribute__((unused)))
1200 {
1201   intmax_t u;
1202   if (decode_signed_num (&u, arg, TYPE_MINIMUM (gid_t),
1203                          TYPE_MAXIMUM (gid_t), keyword))
1204     st->stat.st_gid = u;
1205 }
1206
1207 static void
1208 gname_coder (struct tar_stat_info const *st, char const *keyword,
1209              struct xheader *xhdr, void const *data __attribute__ ((unused)))
1210 {
1211   code_string (st->gname, keyword, xhdr);
1212 }
1213
1214 static void
1215 gname_decoder (struct tar_stat_info *st,
1216                char const *keyword __attribute__((unused)),
1217                char const *arg,
1218                size_t size __attribute__((unused)))
1219 {
1220   decode_string (&st->gname, arg);
1221 }
1222
1223 static void
1224 linkpath_coder (struct tar_stat_info const *st, char const *keyword,
1225                 struct xheader *xhdr, void const *data __attribute__ ((unused)))
1226 {
1227   code_string (st->link_name, keyword, xhdr);
1228 }
1229
1230 static void
1231 linkpath_decoder (struct tar_stat_info *st,
1232                   char const *keyword __attribute__((unused)),
1233                   char const *arg,
1234                   size_t size __attribute__((unused)))
1235 {
1236   decode_string (&st->link_name, arg);
1237 }
1238
1239 static void
1240 ctime_coder (struct tar_stat_info const *st, char const *keyword,
1241              struct xheader *xhdr, void const *data __attribute__ ((unused)))
1242 {
1243   code_time (st->ctime, keyword, xhdr);
1244 }
1245
1246 static void
1247 ctime_decoder (struct tar_stat_info *st,
1248                char const *keyword,
1249                char const *arg,
1250                size_t size __attribute__((unused)))
1251 {
1252   struct timespec ts;
1253   if (decode_time (&ts, arg, keyword))
1254     st->ctime = ts;
1255 }
1256
1257 static void
1258 mtime_coder (struct tar_stat_info const *st, char const *keyword,
1259              struct xheader *xhdr, void const *data)
1260 {
1261   struct timespec const *mtime = data;
1262   code_time (mtime ? *mtime : st->mtime, keyword, xhdr);
1263 }
1264
1265 static void
1266 mtime_decoder (struct tar_stat_info *st,
1267                char const *keyword,
1268                char const *arg,
1269                size_t size __attribute__((unused)))
1270 {
1271   struct timespec ts;
1272   if (decode_time (&ts, arg, keyword))
1273     st->mtime = ts;
1274 }
1275
1276 static void
1277 path_coder (struct tar_stat_info const *st, char const *keyword,
1278             struct xheader *xhdr, void const *data __attribute__ ((unused)))
1279 {
1280   code_string (st->file_name, keyword, xhdr);
1281 }
1282
1283 static void
1284 path_decoder (struct tar_stat_info *st,
1285               char const *keyword __attribute__((unused)),
1286               char const *arg,
1287               size_t size __attribute__((unused)))
1288 {
1289   decode_string (&st->orig_file_name, arg);
1290   decode_string (&st->file_name, arg);
1291   st->had_trailing_slash = strip_trailing_slashes (st->file_name);
1292 }
1293
1294 static void
1295 size_coder (struct tar_stat_info const *st, char const *keyword,
1296             struct xheader *xhdr, void const *data __attribute__ ((unused)))
1297 {
1298   code_num (st->stat.st_size, keyword, xhdr);
1299 }
1300
1301 static void
1302 size_decoder (struct tar_stat_info *st,
1303               char const *keyword,
1304               char const *arg,
1305               size_t size __attribute__((unused)))
1306 {
1307   uintmax_t u;
1308   if (decode_num (&u, arg, TYPE_MAXIMUM (off_t), keyword))
1309     st->stat.st_size = u;
1310 }
1311
1312 static void
1313 uid_coder (struct tar_stat_info const *st, char const *keyword,
1314            struct xheader *xhdr, void const *data __attribute__ ((unused)))
1315 {
1316   code_signed_num (st->stat.st_uid, keyword,
1317                    TYPE_MINIMUM (uid_t), TYPE_MAXIMUM (uid_t), xhdr);
1318 }
1319
1320 static void
1321 uid_decoder (struct tar_stat_info *st,
1322              char const *keyword,
1323              char const *arg,
1324              size_t size __attribute__((unused)))
1325 {
1326   intmax_t u;
1327   if (decode_signed_num (&u, arg, TYPE_MINIMUM (uid_t),
1328                          TYPE_MAXIMUM (uid_t), keyword))
1329     st->stat.st_uid = u;
1330 }
1331
1332 static void
1333 uname_coder (struct tar_stat_info const *st, char const *keyword,
1334              struct xheader *xhdr, void const *data __attribute__ ((unused)))
1335 {
1336   code_string (st->uname, keyword, xhdr);
1337 }
1338
1339 static void
1340 uname_decoder (struct tar_stat_info *st,
1341                char const *keyword __attribute__((unused)),
1342                char const *arg,
1343                size_t size __attribute__((unused)))
1344 {
1345   decode_string (&st->uname, arg);
1346 }
1347
1348 static void
1349 sparse_size_coder (struct tar_stat_info const *st, char const *keyword,
1350              struct xheader *xhdr, void const *data)
1351 {
1352   size_coder (st, keyword, xhdr, data);
1353 }
1354
1355 static void
1356 sparse_size_decoder (struct tar_stat_info *st,
1357                      char const *keyword,
1358                      char const *arg,
1359                      size_t size __attribute__((unused)))
1360 {
1361   uintmax_t u;
1362   if (decode_num (&u, arg, TYPE_MAXIMUM (off_t), keyword))
1363     st->stat.st_size = u;
1364 }
1365
1366 static void
1367 sparse_numblocks_coder (struct tar_stat_info const *st, char const *keyword,
1368                         struct xheader *xhdr,
1369                         void const *data __attribute__ ((unused)))
1370 {
1371   code_num (st->sparse_map_avail, keyword, xhdr);
1372 }
1373
1374 static void
1375 sparse_numblocks_decoder (struct tar_stat_info *st,
1376                           char const *keyword,
1377                           char const *arg,
1378                           size_t size __attribute__((unused)))
1379 {
1380   uintmax_t u;
1381   if (decode_num (&u, arg, SIZE_MAX, keyword))
1382     {
1383       st->sparse_map_size = u;
1384       st->sparse_map = xcalloc (u, sizeof st->sparse_map[0]);
1385       st->sparse_map_avail = 0;
1386     }
1387 }
1388
1389 static void
1390 sparse_offset_coder (struct tar_stat_info const *st, char const *keyword,
1391                      struct xheader *xhdr, void const *data)
1392 {
1393   size_t const *pi = data;
1394   code_num (st->sparse_map[*pi].offset, keyword, xhdr);
1395 }
1396
1397 static void
1398 sparse_offset_decoder (struct tar_stat_info *st,
1399                        char const *keyword,
1400                        char const *arg,
1401                        size_t size __attribute__((unused)))
1402 {
1403   uintmax_t u;
1404   if (decode_num (&u, arg, TYPE_MAXIMUM (off_t), keyword))
1405     {
1406       if (st->sparse_map_avail < st->sparse_map_size)
1407         st->sparse_map[st->sparse_map_avail].offset = u;
1408       else
1409         ERROR ((0, 0, _("Malformed extended header: excess %s=%s"),
1410                 "GNU.sparse.offset", arg));
1411     }
1412 }
1413
1414 static void
1415 sparse_numbytes_coder (struct tar_stat_info const *st, char const *keyword,
1416                        struct xheader *xhdr, void const *data)
1417 {
1418   size_t const *pi = data;
1419   code_num (st->sparse_map[*pi].numbytes, keyword, xhdr);
1420 }
1421
1422 static void
1423 sparse_numbytes_decoder (struct tar_stat_info *st,
1424                          char const *keyword,
1425                          char const *arg,
1426                          size_t size __attribute__((unused)))
1427 {
1428   uintmax_t u;
1429   if (decode_num (&u, arg, TYPE_MAXIMUM (off_t), keyword))
1430     {
1431       if (st->sparse_map_avail < st->sparse_map_size)
1432         st->sparse_map[st->sparse_map_avail++].numbytes = u;
1433       else
1434         ERROR ((0, 0, _("Malformed extended header: excess %s=%s"),
1435                 keyword, arg));
1436     }
1437 }
1438
1439 static void
1440 sparse_map_decoder (struct tar_stat_info *st,
1441                     char const *keyword,
1442                     char const *arg,
1443                     size_t size __attribute__((unused)))
1444 {
1445   int offset = 1;
1446
1447   st->sparse_map_avail = 0;
1448   while (1)
1449     {
1450       intmax_t u;
1451       char *delim;
1452       struct sp_array e;
1453
1454       if (!ISDIGIT (*arg))
1455         {
1456           ERROR ((0, 0, _("Malformed extended header: invalid %s=%s"),
1457                   keyword, arg));
1458           return;
1459         }
1460
1461       errno = 0;
1462       u = strtoimax (arg, &delim, 10);
1463       if (TYPE_MAXIMUM (off_t) < u)
1464         {
1465           u = TYPE_MAXIMUM (off_t);
1466           errno = ERANGE;
1467         }
1468       if (offset)
1469         {
1470           e.offset = u;
1471           if (errno == ERANGE)
1472             {
1473               out_of_range_header (keyword, arg, 0, TYPE_MAXIMUM (off_t));
1474               return;
1475             }
1476         }
1477       else
1478         {
1479           e.numbytes = u;
1480           if (errno == ERANGE)
1481             {
1482               out_of_range_header (keyword, arg, 0, TYPE_MAXIMUM (off_t));
1483               return;
1484             }
1485           if (st->sparse_map_avail < st->sparse_map_size)
1486             st->sparse_map[st->sparse_map_avail++] = e;
1487           else
1488             {
1489               ERROR ((0, 0, _("Malformed extended header: excess %s=%s"),
1490                       keyword, arg));
1491               return;
1492             }
1493         }
1494
1495       offset = !offset;
1496
1497       if (*delim == 0)
1498         break;
1499       else if (*delim != ',')
1500         {
1501           ERROR ((0, 0,
1502                   _("Malformed extended header: invalid %s: unexpected delimiter %c"),
1503                   keyword, *delim));
1504           return;
1505         }
1506
1507       arg = delim + 1;
1508     }
1509
1510   if (!offset)
1511     ERROR ((0, 0,
1512             _("Malformed extended header: invalid %s: odd number of values"),
1513             keyword));
1514 }
1515
1516 static void
1517 dumpdir_coder (struct tar_stat_info const *st, char const *keyword,
1518                struct xheader *xhdr, void const *data)
1519 {
1520   xheader_print_n (xhdr, keyword, data, dumpdir_size (data));
1521 }
1522
1523 static void
1524 dumpdir_decoder (struct tar_stat_info *st,
1525                  char const *keyword __attribute__((unused)),
1526                  char const *arg,
1527                  size_t size)
1528 {
1529   st->dumpdir = xmalloc (size);
1530   memcpy (st->dumpdir, arg, size);
1531 }
1532
1533 static void
1534 volume_label_coder (struct tar_stat_info const *st, char const *keyword,
1535                     struct xheader *xhdr, void const *data)
1536 {
1537   code_string (data, keyword, xhdr);
1538 }
1539
1540 static void
1541 volume_label_decoder (struct tar_stat_info *st,
1542                       char const *keyword __attribute__((unused)),
1543                       char const *arg,
1544                       size_t size __attribute__((unused)))
1545 {
1546   decode_string (&volume_label, arg);
1547 }
1548
1549 static void
1550 volume_size_coder (struct tar_stat_info const *st, char const *keyword,
1551                    struct xheader *xhdr, void const *data)
1552 {
1553   off_t const *v = data;
1554   code_num (*v, keyword, xhdr);
1555 }
1556
1557 static void
1558 volume_size_decoder (struct tar_stat_info *st,
1559                      char const *keyword,
1560                      char const *arg, size_t size)
1561 {
1562   uintmax_t u;
1563   if (decode_num (&u, arg, TYPE_MAXIMUM (uintmax_t), keyword))
1564     continued_file_size = u;
1565 }
1566
1567 /* FIXME: Merge with volume_size_coder */
1568 static void
1569 volume_offset_coder (struct tar_stat_info const *st, char const *keyword,
1570                      struct xheader *xhdr, void const *data)
1571 {
1572   off_t const *v = data;
1573   code_num (*v, keyword, xhdr);
1574 }
1575
1576 static void
1577 volume_offset_decoder (struct tar_stat_info *st,
1578                        char const *keyword,
1579                        char const *arg, size_t size)
1580 {
1581   uintmax_t u;
1582   if (decode_num (&u, arg, TYPE_MAXIMUM (uintmax_t), keyword))
1583     continued_file_offset = u;
1584 }
1585
1586 static void
1587 volume_filename_decoder (struct tar_stat_info *st,
1588                          char const *keyword __attribute__((unused)),
1589                          char const *arg,
1590                          size_t size __attribute__((unused)))
1591 {
1592   decode_string (&continued_file_name, arg);
1593 }
1594
1595 static void
1596 xattr_selinux_coder (struct tar_stat_info const *st, char const *keyword,
1597                      struct xheader *xhdr, void const *data)
1598 {
1599   code_string (st->cntx_name, keyword, xhdr);
1600 }
1601
1602 static void
1603 xattr_selinux_decoder (struct tar_stat_info *st,
1604                        char const *keyword, char const *arg, size_t size)
1605 {
1606   decode_string (&st->cntx_name, arg);
1607 }
1608
1609 static void
1610 xattr_acls_a_coder (struct tar_stat_info const *st , char const *keyword,
1611                     struct xheader *xhdr, void const *data)
1612 {
1613   xheader_print_n (xhdr, keyword, st->acls_a_ptr, st->acls_a_len);
1614 }
1615
1616 static void
1617 xattr_acls_a_decoder (struct tar_stat_info *st,
1618                       char const *keyword, char const *arg, size_t size)
1619 {
1620   st->acls_a_ptr = xmemdup (arg, size + 1);
1621   st->acls_a_len = size;
1622 }
1623
1624 static void
1625 xattr_acls_d_coder (struct tar_stat_info const *st , char const *keyword,
1626                     struct xheader *xhdr, void const *data)
1627 {
1628   xheader_print_n (xhdr, keyword, st->acls_d_ptr, st->acls_d_len);
1629 }
1630
1631 static void
1632 xattr_acls_d_decoder (struct tar_stat_info *st,
1633                       char const *keyword, char const *arg, size_t size)
1634 {
1635   st->acls_d_ptr = xmemdup (arg, size + 1);
1636   st->acls_d_len = size;
1637 }
1638
1639 static void
1640 xattr_coder (struct tar_stat_info const *st, char const *keyword,
1641              struct xheader *xhdr, void const *data)
1642 {
1643   struct xattr_array *xattr_map = st->xattr_map;
1644   const size_t *off = data;
1645   xheader_print_n (xhdr, keyword,
1646                    xattr_map[*off].xval_ptr, xattr_map[*off].xval_len);
1647 }
1648
1649 static void
1650 xattr_decoder (struct tar_stat_info *st,
1651                char const *keyword, char const *arg, size_t size)
1652 {
1653   char *xstr, *xkey;
1654
1655   /* copy keyword */
1656   size_t klen_raw = strlen (keyword);
1657   xkey = alloca (klen_raw + 1);
1658   memcpy (xkey, keyword, klen_raw + 1) /* including null-terminating */;
1659
1660   /* copy value */
1661   xstr = alloca (size + 1);
1662   memcpy (xstr, arg, size + 1); /* separator included, for GNU tar '\n' */;
1663
1664   xattr_decode_keyword (xkey);
1665
1666   xheader_xattr_add (st, xkey + strlen("SCHILY.xattr."), xstr, size);
1667 }
1668
1669 static void
1670 sparse_major_coder (struct tar_stat_info const *st, char const *keyword,
1671                     struct xheader *xhdr, void const *data)
1672 {
1673   code_num (st->sparse_major, keyword, xhdr);
1674 }
1675
1676 static void
1677 sparse_major_decoder (struct tar_stat_info *st,
1678                       char const *keyword,
1679                       char const *arg,
1680                       size_t size)
1681 {
1682   uintmax_t u;
1683   if (decode_num (&u, arg, TYPE_MAXIMUM (unsigned), keyword))
1684     st->sparse_major = u;
1685 }
1686
1687 static void
1688 sparse_minor_coder (struct tar_stat_info const *st, char const *keyword,
1689                       struct xheader *xhdr, void const *data)
1690 {
1691   code_num (st->sparse_minor, keyword, xhdr);
1692 }
1693
1694 static void
1695 sparse_minor_decoder (struct tar_stat_info *st,
1696                       char const *keyword,
1697                       char const *arg,
1698                       size_t size)
1699 {
1700   uintmax_t u;
1701   if (decode_num (&u, arg, TYPE_MAXIMUM (unsigned), keyword))
1702     st->sparse_minor = u;
1703 }
1704
1705 struct xhdr_tab const xhdr_tab[] = {
1706   { "atime",    atime_coder,    atime_decoder,    0, false },
1707   { "comment",  dummy_coder,    dummy_decoder,    0, false },
1708   { "charset",  dummy_coder,    dummy_decoder,    0, false },
1709   { "ctime",    ctime_coder,    ctime_decoder,    0, false },
1710   { "gid",      gid_coder,      gid_decoder,      0, false },
1711   { "gname",    gname_coder,    gname_decoder,    0, false },
1712   { "linkpath", linkpath_coder, linkpath_decoder, 0, false },
1713   { "mtime",    mtime_coder,    mtime_decoder,    0, false },
1714   { "path",     path_coder,     path_decoder,     0, false },
1715   { "size",     size_coder,     size_decoder,     0, false },
1716   { "uid",      uid_coder,      uid_decoder,      0, false },
1717   { "uname",    uname_coder,    uname_decoder,    0, false },
1718
1719   /* Sparse file handling */
1720   { "GNU.sparse.name",       path_coder, path_decoder,
1721     XHDR_PROTECTED, false },
1722   { "GNU.sparse.major",      sparse_major_coder, sparse_major_decoder,
1723     XHDR_PROTECTED, false },
1724   { "GNU.sparse.minor",      sparse_minor_coder, sparse_minor_decoder,
1725     XHDR_PROTECTED, false },
1726   { "GNU.sparse.realsize",   sparse_size_coder, sparse_size_decoder,
1727     XHDR_PROTECTED, false },
1728   { "GNU.sparse.numblocks",  sparse_numblocks_coder, sparse_numblocks_decoder,
1729     XHDR_PROTECTED, false },
1730
1731   /* tar 1.14 - 1.15.90 keywords. */
1732   { "GNU.sparse.size",       sparse_size_coder, sparse_size_decoder,
1733     XHDR_PROTECTED, false },
1734   /* tar 1.14 - 1.15.1 keywords. Multiple instances of these appeared in 'x'
1735      headers, and each of them was meaningful. It confilcted with POSIX specs,
1736      which requires that "when extended header records conflict, the last one
1737      given in the header shall take precedence." */
1738   { "GNU.sparse.offset",     sparse_offset_coder, sparse_offset_decoder,
1739     XHDR_PROTECTED, false },
1740   { "GNU.sparse.numbytes",   sparse_numbytes_coder, sparse_numbytes_decoder,
1741     XHDR_PROTECTED, false },
1742   /* tar 1.15.90 keyword, introduced to remove the above-mentioned conflict. */
1743   { "GNU.sparse.map",        NULL /* Unused, see pax_dump_header() */,
1744     sparse_map_decoder, 0, false },
1745
1746   { "GNU.dumpdir",           dumpdir_coder, dumpdir_decoder,
1747     XHDR_PROTECTED, false },
1748
1749   /* Keeps the tape/volume label. May be present only in the global headers.
1750      Equivalent to GNUTYPE_VOLHDR.  */
1751   { "GNU.volume.label", volume_label_coder, volume_label_decoder,
1752     XHDR_PROTECTED | XHDR_GLOBAL, false },
1753
1754   /* These may be present in a first global header of the archive.
1755      They provide the same functionality as GNUTYPE_MULTIVOL header.
1756      The GNU.volume.size keeps the real_s_sizeleft value, which is
1757      otherwise kept in the size field of a multivolume header.  The
1758      GNU.volume.offset keeps the offset of the start of this volume,
1759      otherwise kept in oldgnu_header.offset.  */
1760   { "GNU.volume.filename", volume_label_coder, volume_filename_decoder,
1761     XHDR_PROTECTED | XHDR_GLOBAL, false },
1762   { "GNU.volume.size", volume_size_coder, volume_size_decoder,
1763     XHDR_PROTECTED | XHDR_GLOBAL, false },
1764   { "GNU.volume.offset", volume_offset_coder, volume_offset_decoder,
1765     XHDR_PROTECTED | XHDR_GLOBAL, false },
1766
1767   /* We get the SELinux value from filecon, so add a namespace for SELinux
1768      instead of storing it in SCHILY.xattr.* (which would be RAW). */
1769   { "RHT.security.selinux",
1770     xattr_selinux_coder, xattr_selinux_decoder, 0, false },
1771
1772   /* ACLs, use the star format... */
1773   { "SCHILY.acl.access",
1774     xattr_acls_a_coder, xattr_acls_a_decoder, 0, false },
1775
1776   { "SCHILY.acl.default",
1777     xattr_acls_d_coder, xattr_acls_d_decoder, 0, false },
1778
1779   /* We are storing all extended attributes using this rule even if some of them
1780      were stored by some previous rule (duplicates) -- we just have to make sure
1781      they are restored *only once* during extraction later on. */
1782   { "SCHILY.xattr", xattr_coder, xattr_decoder, 0, true },
1783
1784   { NULL, NULL, NULL, 0, false }
1785 };