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