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