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 2, 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
30static bool xheader_protected_pattern_p (char const *pattern);
31static bool xheader_protected_keyword_p (char const *keyword);
32static void xheader_set_single_keyword (char *) __attribute__ ((noreturn));
33
34/* Used by xheader_finish() */
35static void code_string (char const *string, char const *keyword,
36			 struct xheader *xhdr);
37
38/* Number of global headers written so far. */
39static 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
52/* Interface functions to obstacks */
53
54static void
55x_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
61static void
62x_obstack_1grow (struct xheader *xhdr, char c)
63{
64  obstack_1grow (xhdr->stk, c);
65  xhdr->size++;
66}
67
68static void
69x_obstack_blank (struct xheader *xhdr, size_t length)
70{
71  obstack_blank (xhdr->stk, length);
72  xhdr->size += length;
73}
74
75
76/* Keyword options */
77
78struct 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 */
87static struct keyword_list *keyword_pattern_list;
88
89/* List of keyword/value pairs set by `keyword=value' option */
90static struct keyword_list *keyword_global_override_list;
91
92/* List of keyword/value pairs set by `keyword:=value' option */
93static struct keyword_list *keyword_override_list;
94
95/* List of keyword/value pairs decoded from the last 'g' type header */
96static struct keyword_list *global_header_override_list;
97
98/* Template for the name field of an 'x' type header */
99static char *exthdr_name;
100
101/* Template for the name field of a 'g' type header */
102static char *globexthdr_name;
103
104bool
105xheader_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
115static bool
116xheader_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
126static void
127xheader_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
137static void
138xheader_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
155static void
156xheader_set_single_keyword (char *kw)
157{
158  USAGE_ERROR ((0, 0, _("Keyword %s is unknown or not yet implemented"), kw));
159}
160
161static void
162xheader_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
202void
203xheader_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
229char *
230xheader_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
340char *
341xheader_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
350char *
351xheader_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
368void
369xheader_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
405void
406xheader_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
423/* General Interface */
424
425struct 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.  */
440extern struct xhdr_tab const xhdr_tab[];
441
442static struct xhdr_tab const *
443locate_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
453static bool
454xheader_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
464static bool
465xheader_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.  */
477static bool
478decode_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
551static void
552run_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
562static void
563decx (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
580void
581xheader_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
595static void
596decg (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
603void
604xheader_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
616void
617xheader_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
626void
627xheader_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
644void
645xheader_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
673static void
674xheader_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
699static void
700xheader_print (struct xheader *xhdr, char const *keyword, char const *value)
701{
702  xheader_print_n (xhdr, keyword, value, strlen (value));
703}
704
705void
706xheader_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
716void
717xheader_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
732/* Buildable strings */
733
734void
735xheader_string_begin (struct xheader *xhdr)
736{
737  xhdr->string_length = 0;
738}
739
740void
741xheader_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
750bool
751xheader_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
797/* Implementations */
798
799static void
800out_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
816static void
817code_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
829static void
830decode_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
844static void
845code_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
851enum decode_time_status
852  {
853    decode_time_success,
854    decode_time_range,
855    decode_time_bad_header
856  };
857
858static 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
935static bool
936decode_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
956static void
957code_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
963static bool
964decode_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
988static void
989dummy_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
996static void
997dummy_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
1004static void
1005atime_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
1011static void
1012atime_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
1022static void
1023gid_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
1029static void
1030gid_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
1040static void
1041gname_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
1047static void
1048gname_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
1056static void
1057linkpath_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
1063static void
1064linkpath_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
1072static void
1073ctime_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
1079static void
1080ctime_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
1090static void
1091mtime_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
1098static void
1099mtime_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
1109static void
1110path_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
1116static void
1117path_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
1127static void
1128size_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
1134static void
1135size_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
1145static void
1146uid_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
1152static void
1153uid_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
1163static void
1164uname_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
1170static void
1171uname_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
1179static void
1180sparse_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
1186static void
1187sparse_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
1197static void
1198sparse_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
1205static void
1206sparse_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
1220static void
1221sparse_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
1228static void
1229sparse_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
1245static void
1246sparse_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
1253static void
1254sparse_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
1270static void
1271sparse_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
1342static void
1343dumpdir_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
1349static void
1350dumpdir_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
1359static void
1360volume_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
1366static void
1367volume_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
1375static void
1376volume_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
1383static void
1384volume_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 */
1394static void
1395volume_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
1402static void
1403volume_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
1412static void
1413volume_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
1421static void
1422sparse_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
1428static void
1429sparse_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
1439static void
1440sparse_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
1446static void
1447sparse_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
1457struct 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};
1517