1 /* POSIX extended headers for tar.
3 Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
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
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.
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. */
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
));
34 /* Used by xheader_finish() */
35 static void code_string (char const *string
, char const *keyword
,
36 struct xheader
*xhdr
);
37 static void extended_header_init (void);
39 /* Number of global headers written so far. */
40 static size_t global_header_count
;
41 /* FIXME: Possibly it should be reset after changing the volume.
42 POSIX %n specification says that it is expanded to the sequence
43 number of current global header in *the* archive. However, for
44 multi-volume archives this will yield duplicate header names
45 in different volumes, which I'd like to avoid. The best way
46 to solve this would be to use per-archive header count as required
47 by POSIX *and* set globexthdr.name to, say,
48 $TMPDIR/GlobalHead.%p.$NUMVOLUME.%n.
50 However it should wait until buffer.c is finally rewritten */
53 /* Interface functions to obstacks */
56 x_obstack_grow (struct xheader
*xhdr
, const char *ptr
, size_t length
)
58 obstack_grow (xhdr
->stk
, ptr
, length
);
63 x_obstack_1grow (struct xheader
*xhdr
, char c
)
65 obstack_1grow (xhdr
->stk
, c
);
70 x_obstack_blank (struct xheader
*xhdr
, size_t length
)
72 obstack_blank (xhdr
->stk
, length
);
81 struct keyword_list
*next
;
87 /* List of keyword patterns set by delete= option */
88 static struct keyword_list
*keyword_pattern_list
;
90 /* List of keyword/value pairs set by `keyword=value' option */
91 static struct keyword_list
*keyword_global_override_list
;
93 /* List of keyword/value pairs set by `keyword:=value' option */
94 static struct keyword_list
*keyword_override_list
;
96 /* List of keyword/value pairs decoded from the last 'g' type header */
97 static struct keyword_list
*global_header_override_list
;
99 /* Template for the name field of an 'x' type header */
100 static char *exthdr_name
;
102 /* Template for the name field of a 'g' type header */
103 static char *globexthdr_name
;
106 xheader_keyword_deleted_p (const char *kw
)
108 struct keyword_list
*kp
;
110 for (kp
= keyword_pattern_list
; kp
; kp
= kp
->next
)
111 if (fnmatch (kp
->pattern
, kw
, 0) == 0)
117 xheader_keyword_override_p (const char *keyword
)
119 struct keyword_list
*kp
;
121 for (kp
= keyword_override_list
; kp
; kp
= kp
->next
)
122 if (strcmp (kp
->pattern
, keyword
) == 0)
128 xheader_list_append (struct keyword_list
**root
, char const *kw
,
131 struct keyword_list
*kp
= xmalloc (sizeof *kp
);
132 kp
->pattern
= xstrdup (kw
);
133 kp
->value
= value
? xstrdup (value
) : NULL
;
139 xheader_list_destroy (struct keyword_list
**root
)
143 struct keyword_list
*kw
= *root
;
146 struct keyword_list
*next
= kw
->next
;
157 xheader_set_single_keyword (char *kw
)
159 USAGE_ERROR ((0, 0, _("Keyword %s is unknown or not yet implemented"), kw
));
163 xheader_set_keyword_equal (char *kw
, char *eq
)
174 while (p
> kw
&& isspace (*p
))
179 for (p
= eq
+ 1; *p
&& isspace (*p
); p
++)
182 if (strcmp (kw
, "delete") == 0)
184 if (xheader_protected_pattern_p (p
))
185 USAGE_ERROR ((0, 0, _("Pattern %s cannot be used"), quote (p
)));
186 xheader_list_append (&keyword_pattern_list
, p
, NULL
);
188 else if (strcmp (kw
, "exthdr.name") == 0)
189 assign_string (&exthdr_name
, p
);
190 else if (strcmp (kw
, "globexthdr.name") == 0)
191 assign_string (&globexthdr_name
, p
);
194 if (xheader_protected_keyword_p (kw
))
195 USAGE_ERROR ((0, 0, _("Keyword %s cannot be overridden"), kw
));
197 xheader_list_append (&keyword_global_override_list
, kw
, p
);
199 xheader_list_append (&keyword_override_list
, kw
, p
);
204 xheader_set_option (char *string
)
207 for (token
= strtok (string
, ","); token
; token
= strtok (NULL
, ","))
209 char *p
= strchr (token
, '=');
211 xheader_set_single_keyword (token
);
213 xheader_set_keyword_equal (token
, p
);
218 string Includes: Replaced By:
219 %d The directory name of the file,
220 equivalent to the result of the
221 dirname utility on the translated
223 %f The filename of the file, equivalent
224 to the result of the basename
225 utility on the translated file name.
226 %p The process ID of the pax process.
227 %n The value of the 3rd argument.
228 %% A '%' character. */
231 xheader_format_name (struct tar_stat_info
*st
, const char *fmt
, size_t n
)
234 size_t len
= strlen (fmt
);
240 char pidbuf
[UINTMAX_STRSIZE_BOUND
];
242 char nbuf
[UINTMAX_STRSIZE_BOUND
];
243 char const *nptr
= NULL
;
245 for (p
= fmt
; *p
&& (p
= strchr (p
, '%')); )
257 dirp
= dir_name (st
->orig_file_name
);
258 dir
= safer_name_suffix (dirp
, false, absolute_names_option
);
259 len
+= strlen (dir
) - 2;
266 base
= last_component (st
->orig_file_name
);
267 len
+= strlen (base
) - 2;
272 pptr
= umaxtostr (getpid (), pidbuf
);
273 len
+= pidbuf
+ sizeof pidbuf
- 1 - pptr
- 2;
277 nptr
= umaxtostr (n
, nbuf
);
278 len
+= nbuf
+ sizeof nbuf
- 1 - nptr
- 2;
284 buf
= xmalloc (len
+ 1);
285 for (q
= buf
, p
= fmt
; *p
; )
304 q
= stpcpy (q
, base
);
309 q
= stpcpy (q
, pptr
);
316 q
= stpcpy (q
, nptr
);
320 /* else fall through */
334 /* Do not allow it to end in a slash */
335 while (q
> buf
&& ISSLASH (q
[-1]))
342 xheader_xhdr_name (struct tar_stat_info
*st
)
345 assign_string (&exthdr_name
, "%d/PaxHeaders.%p/%f");
346 return xheader_format_name (st
, exthdr_name
, 0);
349 #define GLOBAL_HEADER_TEMPLATE "/GlobalHead.%p.%n"
352 xheader_ghdr_name (void)
354 if (!globexthdr_name
)
357 const char *tmp
= getenv ("TMPDIR");
360 len
= strlen (tmp
) + sizeof (GLOBAL_HEADER_TEMPLATE
); /* Includes nul */
361 globexthdr_name
= xmalloc (len
);
362 strcpy(globexthdr_name
, tmp
);
363 strcat(globexthdr_name
, GLOBAL_HEADER_TEMPLATE
);
366 return xheader_format_name (NULL
, globexthdr_name
, global_header_count
+ 1);
370 xheader_write (char type
, char *name
, struct xheader
*xhdr
)
377 header
= start_private_header (name
, size
);
378 header
->header
.typeflag
= type
;
380 simple_finish_header (header
);
388 header
= find_next_block ();
392 memcpy (header
->buffer
, p
, len
);
394 memset (header
->buffer
+ len
, 0, BLOCKSIZE
- len
);
397 set_next_block_after (header
);
400 xheader_destroy (xhdr
);
403 global_header_count
++;
407 xheader_write_global (void)
410 struct keyword_list
*kp
;
412 if (!keyword_global_override_list
)
415 extended_header_init ();
416 for (kp
= keyword_global_override_list
; kp
; kp
= kp
->next
)
417 code_string (kp
->value
, kp
->pattern
, &extended_header
);
418 xheader_finish (&extended_header
);
419 xheader_write (XGLTYPE
, name
= xheader_ghdr_name (),
425 /* General Interface */
430 void (*coder
) (struct tar_stat_info
const *, char const *,
431 struct xheader
*, void const *data
);
432 void (*decoder
) (struct tar_stat_info
*, char const *, char const *, size_t);
436 /* This declaration must be extern, because ISO C99 section 6.9.2
437 prohibits a tentative definition that has both internal linkage and
438 incomplete type. If we made it static, we'd have to declare its
439 size which would be a maintenance pain; if we put its initializer
440 here, we'd need a boatload of forward declarations, which would be
441 even more of a pain. */
442 extern struct xhdr_tab
const xhdr_tab
[];
444 static struct xhdr_tab
const *
445 locate_handler (char const *keyword
)
447 struct xhdr_tab
const *p
;
449 for (p
= xhdr_tab
; p
->keyword
; p
++)
450 if (strcmp (p
->keyword
, keyword
) == 0)
456 xheader_protected_pattern_p (const char *pattern
)
458 struct xhdr_tab
const *p
;
460 for (p
= xhdr_tab
; p
->keyword
; p
++)
461 if (p
->protect
&& fnmatch (pattern
, p
->keyword
, 0) == 0)
467 xheader_protected_keyword_p (const char *keyword
)
469 struct xhdr_tab
const *p
;
471 for (p
= xhdr_tab
; p
->keyword
; p
++)
472 if (p
->protect
&& strcmp (p
->keyword
, keyword
) == 0)
477 /* Decode a single extended header record, advancing *PTR to the next record.
478 Return true on success, false otherwise. */
480 decode_record (char **ptr
,
481 void (*handler
) (void *, char const *, char const *, size_t),
491 size_t len_max
= extended_header
.buffer
+ extended_header
.size
- start
;
493 while (*p
== ' ' || *p
== '\t')
499 ERROR ((0, 0, _("Malformed extended header: missing length")));
504 len
= u
= strtoumax (p
, &len_lim
, 10);
505 if (len
!= u
|| errno
== ERANGE
)
507 ERROR ((0, 0, _("Extended header length is out of allowed range")));
513 int len_len
= len_lim
- p
;
514 ERROR ((0, 0, _("Extended header length %*s is out of range"),
521 for (p
= len_lim
; *p
== ' ' || *p
== '\t'; p
++)
526 _("Malformed extended header: missing blank after length")));
532 if (! (p
&& p
< nextp
))
534 ERROR ((0, 0, _("Malformed extended header: missing equal sign")));
538 if (nextp
[-1] != '\n')
540 ERROR ((0, 0, _("Malformed extended header: missing newline")));
544 *p
= nextp
[-1] = '\0';
545 handler (data
, keyword
, p
+ 1, nextp
- p
- 2); /* '=' + trailing '\n' */
553 run_override_list (struct keyword_list
*kp
, struct tar_stat_info
*st
)
555 for (; kp
; kp
= kp
->next
)
557 struct xhdr_tab
const *t
= locate_handler (kp
->pattern
);
559 t
->decoder (st
, t
->keyword
, kp
->value
, strlen (kp
->value
));
564 decx (void *data
, char const *keyword
, char const *value
, size_t size
)
566 struct xhdr_tab
const *t
;
567 struct tar_stat_info
*st
= data
;
569 if (xheader_keyword_deleted_p (keyword
)
570 || xheader_keyword_override_p (keyword
))
573 t
= locate_handler (keyword
);
575 t
->decoder (st
, keyword
, value
, size
);
577 ERROR((0, 0, _("Ignoring unknown extended header keyword `%s'"),
582 xheader_decode (struct tar_stat_info
*st
)
584 run_override_list (keyword_global_override_list
, st
);
585 run_override_list (global_header_override_list
, st
);
587 if (extended_header
.size
)
589 char *p
= extended_header
.buffer
+ BLOCKSIZE
;
590 while (decode_record (&p
, decx
, st
))
593 run_override_list (keyword_override_list
, st
);
597 decg (void *data
, char const *keyword
, char const *value
,
598 size_t size
__attribute__((unused
)))
600 struct keyword_list
**kwl
= data
;
601 xheader_list_append (kwl
, keyword
, value
);
605 xheader_decode_global (void)
607 if (extended_header
.size
)
609 char *p
= extended_header
.buffer
+ BLOCKSIZE
;
611 xheader_list_destroy (&global_header_override_list
);
612 while (decode_record (&p
, decg
, &global_header_override_list
))
618 extended_header_init (void)
620 if (!extended_header
.stk
)
622 extended_header
.stk
= xmalloc (sizeof *extended_header
.stk
);
623 obstack_init (extended_header
.stk
);
628 xheader_store (char const *keyword
, struct tar_stat_info
const *st
,
631 struct xhdr_tab
const *t
;
633 if (extended_header
.buffer
)
635 t
= locate_handler (keyword
);
638 if (xheader_keyword_deleted_p (keyword
)
639 || xheader_keyword_override_p (keyword
))
641 extended_header_init ();
642 t
->coder (st
, keyword
, &extended_header
, data
);
646 xheader_read (union block
*p
, size_t size
)
650 free (extended_header
.buffer
);
652 extended_header
.size
= size
;
653 extended_header
.buffer
= xmalloc (size
+ 1);
654 extended_header
.buffer
[size
] = '\0';
663 memcpy (&extended_header
.buffer
[j
], p
->buffer
, len
);
664 set_next_block_after (p
);
666 p
= find_next_block ();
675 xheader_print_n (struct xheader
*xhdr
, char const *keyword
,
676 char const *value
, size_t vsize
)
678 size_t len
= strlen (keyword
) + vsize
+ 3; /* ' ' + '=' + '\n' */
681 char nbuf
[UINTMAX_STRSIZE_BOUND
];
687 np
= umaxtostr (len
+ p
, nbuf
);
688 n
= nbuf
+ sizeof nbuf
- 1 - np
;
692 x_obstack_grow (xhdr
, np
, n
);
693 x_obstack_1grow (xhdr
, ' ');
694 x_obstack_grow (xhdr
, keyword
, strlen (keyword
));
695 x_obstack_1grow (xhdr
, '=');
696 x_obstack_grow (xhdr
, value
, vsize
);
697 x_obstack_1grow (xhdr
, '\n');
701 xheader_print (struct xheader
*xhdr
, char const *keyword
, char const *value
)
703 xheader_print_n (xhdr
, keyword
, value
, strlen (value
));
707 xheader_finish (struct xheader
*xhdr
)
709 struct keyword_list
*kp
;
711 for (kp
= keyword_override_list
; kp
; kp
= kp
->next
)
712 code_string (kp
->value
, kp
->pattern
, xhdr
);
714 xhdr
->buffer
= obstack_finish (xhdr
->stk
);
718 xheader_destroy (struct xheader
*xhdr
)
722 obstack_free (xhdr
->stk
, NULL
);
733 /* Buildable strings */
734 static uintmax_t string_length
;
737 xheader_string_begin ()
743 xheader_string_add (char const *s
)
745 if (extended_header
.buffer
)
747 extended_header_init ();
748 string_length
+= strlen (s
);
749 x_obstack_grow (&extended_header
, s
, strlen (s
));
753 xheader_string_end (char const *keyword
)
759 char nbuf
[UINTMAX_STRSIZE_BOUND
];
763 if (extended_header
.buffer
)
765 extended_header_init ();
767 len
= strlen (keyword
) + string_length
+ 3; /* ' ' + '=' + '\n' */
772 np
= umaxtostr (len
+ p
, nbuf
);
773 n
= nbuf
+ sizeof nbuf
- 1 - np
;
777 p
= strlen (keyword
) + n
+ 2;
782 _("Generated keyword/value pair is too long (keyword=%s, length=%s)"),
784 obstack_free (extended_header
.stk
, obstack_finish (extended_header
.stk
));
787 x_obstack_blank (&extended_header
, p
);
788 x_obstack_1grow (&extended_header
, '\n');
789 cp
= obstack_next_free (extended_header
.stk
) - string_length
- p
- 1;
790 memmove (cp
+ p
, cp
, string_length
);
791 cp
= stpcpy (cp
, np
);
793 cp
= stpcpy (cp
, keyword
);
799 /* Implementations */
802 out_of_range_header (char const *keyword
, char const *value
,
803 uintmax_t minus_minval
, uintmax_t maxval
)
805 char minval_buf
[UINTMAX_STRSIZE_BOUND
+ 1];
806 char maxval_buf
[UINTMAX_STRSIZE_BOUND
];
807 char *minval_string
= umaxtostr (minus_minval
, minval_buf
+ 1);
808 char *maxval_string
= umaxtostr (maxval
, maxval_buf
);
810 *--minval_string
= '-';
812 /* TRANSLATORS: The first %s is the pax extended header keyword
813 (atime, gid, etc.). */
814 ERROR ((0, 0, _("Extended header %s=%s is out of range %s..%s"),
815 keyword
, value
, minval_string
, maxval_string
));
819 code_string (char const *string
, char const *keyword
, struct xheader
*xhdr
)
822 if (!utf8_convert (true, string
, &outstr
))
824 /* FIXME: report error */
825 outstr
= xstrdup (string
);
827 xheader_print (xhdr
, keyword
, outstr
);
832 decode_string (char **string
, char const *arg
)
839 if (!utf8_convert (false, arg
, string
))
841 /* FIXME: report error and act accordingly to --pax invalid=UTF-8 */
842 assign_string (string
, arg
);
847 code_time (struct timespec t
, char const *keyword
, struct xheader
*xhdr
)
849 char buf
[TIMESPEC_STRSIZE_BOUND
];
850 xheader_print (xhdr
, keyword
, code_timespec (t
, buf
));
853 enum decode_time_status
857 decode_time_bad_header
860 static enum decode_time_status
861 _decode_time (struct timespec
*ts
, char const *arg
, char const *keyword
)
864 unsigned long int ns
= 0;
867 bool negative
= *arg
== '-';
871 if (ISDIGIT (arg
[negative
]))
875 intmax_t i
= strtoimax (arg
, &arg_lim
, 10);
876 if (TYPE_SIGNED (time_t) ? i
< TYPE_MINIMUM (time_t) : i
< 0)
877 return decode_time_range
;
882 uintmax_t i
= strtoumax (arg
, &arg_lim
, 10);
883 if (TYPE_MAXIMUM (time_t) < i
)
884 return decode_time_range
;
891 return decode_time_range
;
896 bool trailing_nonzero
= false;
898 while (ISDIGIT (*++p
))
899 if (digits
< LOG10_BILLION
)
901 ns
= 10 * ns
+ (*p
- '0');
905 trailing_nonzero
|= *p
!= '0';
907 while (digits
++ < LOG10_BILLION
)
912 /* Convert "-1.10000000000001" to s == -2, ns == 89999999.
913 I.e., truncate time stamps towards minus infinity while
914 converting them to internal form. */
915 ns
+= trailing_nonzero
;
918 if (s
== TYPE_MINIMUM (time_t))
919 return decode_time_range
;
930 return decode_time_success
;
934 return decode_time_bad_header
;
938 decode_time (struct timespec
*ts
, char const *arg
, char const *keyword
)
940 switch (_decode_time (ts
, arg
, keyword
))
942 case decode_time_success
:
944 case decode_time_bad_header
:
945 ERROR ((0, 0, _("Malformed extended header: invalid %s=%s"),
948 case decode_time_range
:
949 out_of_range_header (keyword
, arg
, - (uintmax_t) TYPE_MINIMUM (time_t),
950 TYPE_MAXIMUM (time_t));
959 code_num (uintmax_t value
, char const *keyword
, struct xheader
*xhdr
)
961 char sbuf
[UINTMAX_STRSIZE_BOUND
];
962 xheader_print (xhdr
, keyword
, umaxtostr (value
, sbuf
));
966 decode_num (uintmax_t *num
, char const *arg
, uintmax_t maxval
,
972 if (! (ISDIGIT (*arg
)
973 && (errno
= 0, u
= strtoumax (arg
, &arg_lim
, 10), !*arg_lim
)))
975 ERROR ((0, 0, _("Malformed extended header: invalid %s=%s"),
980 if (! (u
<= maxval
&& errno
!= ERANGE
))
982 out_of_range_header (keyword
, arg
, 0, maxval
);
991 dummy_coder (struct tar_stat_info
const *st
__attribute__ ((unused
)),
992 char const *keyword
__attribute__ ((unused
)),
993 struct xheader
*xhdr
__attribute__ ((unused
)),
994 void const *data
__attribute__ ((unused
)))
999 dummy_decoder (struct tar_stat_info
*st
__attribute__ ((unused
)),
1000 char const *keyword
__attribute__ ((unused
)),
1001 char const *arg
__attribute__ ((unused
)),
1002 size_t size
__attribute__((unused
)))
1007 atime_coder (struct tar_stat_info
const *st
, char const *keyword
,
1008 struct xheader
*xhdr
, void const *data
__attribute__ ((unused
)))
1010 code_time (st
->atime
, keyword
, xhdr
);
1014 atime_decoder (struct tar_stat_info
*st
,
1015 char const *keyword
,
1017 size_t size
__attribute__((unused
)))
1020 if (decode_time (&ts
, arg
, keyword
))
1025 gid_coder (struct tar_stat_info
const *st
, char const *keyword
,
1026 struct xheader
*xhdr
, void const *data
__attribute__ ((unused
)))
1028 code_num (st
->stat
.st_gid
, keyword
, xhdr
);
1032 gid_decoder (struct tar_stat_info
*st
,
1033 char const *keyword
,
1035 size_t size
__attribute__((unused
)))
1038 if (decode_num (&u
, arg
, TYPE_MAXIMUM (gid_t
), keyword
))
1039 st
->stat
.st_gid
= u
;
1043 gname_coder (struct tar_stat_info
const *st
, char const *keyword
,
1044 struct xheader
*xhdr
, void const *data
__attribute__ ((unused
)))
1046 code_string (st
->gname
, keyword
, xhdr
);
1050 gname_decoder (struct tar_stat_info
*st
,
1051 char const *keyword
__attribute__((unused
)),
1053 size_t size
__attribute__((unused
)))
1055 decode_string (&st
->gname
, arg
);
1059 linkpath_coder (struct tar_stat_info
const *st
, char const *keyword
,
1060 struct xheader
*xhdr
, void const *data
__attribute__ ((unused
)))
1062 code_string (st
->link_name
, keyword
, xhdr
);
1066 linkpath_decoder (struct tar_stat_info
*st
,
1067 char const *keyword
__attribute__((unused
)),
1069 size_t size
__attribute__((unused
)))
1071 decode_string (&st
->link_name
, arg
);
1075 ctime_coder (struct tar_stat_info
const *st
, char const *keyword
,
1076 struct xheader
*xhdr
, void const *data
__attribute__ ((unused
)))
1078 code_time (st
->ctime
, keyword
, xhdr
);
1082 ctime_decoder (struct tar_stat_info
*st
,
1083 char const *keyword
,
1085 size_t size
__attribute__((unused
)))
1088 if (decode_time (&ts
, arg
, keyword
))
1093 mtime_coder (struct tar_stat_info
const *st
, char const *keyword
,
1094 struct xheader
*xhdr
, void const *data
)
1096 struct timespec
const *mtime
= data
;
1097 code_time (mtime
? *mtime
: st
->mtime
, keyword
, xhdr
);
1101 mtime_decoder (struct tar_stat_info
*st
,
1102 char const *keyword
,
1104 size_t size
__attribute__((unused
)))
1107 if (decode_time (&ts
, arg
, keyword
))
1112 path_coder (struct tar_stat_info
const *st
, char const *keyword
,
1113 struct xheader
*xhdr
, void const *data
__attribute__ ((unused
)))
1115 code_string (st
->file_name
, keyword
, xhdr
);
1119 path_decoder (struct tar_stat_info
*st
,
1120 char const *keyword
__attribute__((unused
)),
1122 size_t size
__attribute__((unused
)))
1124 decode_string (&st
->orig_file_name
, arg
);
1125 decode_string (&st
->file_name
, arg
);
1126 st
->had_trailing_slash
= strip_trailing_slashes (st
->file_name
);
1130 size_coder (struct tar_stat_info
const *st
, char const *keyword
,
1131 struct xheader
*xhdr
, void const *data
__attribute__ ((unused
)))
1133 code_num (st
->stat
.st_size
, keyword
, xhdr
);
1137 size_decoder (struct tar_stat_info
*st
,
1138 char const *keyword
,
1140 size_t size
__attribute__((unused
)))
1143 if (decode_num (&u
, arg
, TYPE_MAXIMUM (off_t
), keyword
))
1144 st
->stat
.st_size
= u
;
1148 uid_coder (struct tar_stat_info
const *st
, char const *keyword
,
1149 struct xheader
*xhdr
, void const *data
__attribute__ ((unused
)))
1151 code_num (st
->stat
.st_uid
, keyword
, xhdr
);
1155 uid_decoder (struct tar_stat_info
*st
,
1156 char const *keyword
,
1158 size_t size
__attribute__((unused
)))
1161 if (decode_num (&u
, arg
, TYPE_MAXIMUM (uid_t
), keyword
))
1162 st
->stat
.st_uid
= u
;
1166 uname_coder (struct tar_stat_info
const *st
, char const *keyword
,
1167 struct xheader
*xhdr
, void const *data
__attribute__ ((unused
)))
1169 code_string (st
->uname
, keyword
, xhdr
);
1173 uname_decoder (struct tar_stat_info
*st
,
1174 char const *keyword
__attribute__((unused
)),
1176 size_t size
__attribute__((unused
)))
1178 decode_string (&st
->uname
, arg
);
1182 sparse_size_coder (struct tar_stat_info
const *st
, char const *keyword
,
1183 struct xheader
*xhdr
, void const *data
)
1185 size_coder (st
, keyword
, xhdr
, data
);
1189 sparse_size_decoder (struct tar_stat_info
*st
,
1190 char const *keyword
,
1192 size_t size
__attribute__((unused
)))
1195 if (decode_num (&u
, arg
, TYPE_MAXIMUM (off_t
), keyword
))
1196 st
->stat
.st_size
= u
;
1200 sparse_numblocks_coder (struct tar_stat_info
const *st
, char const *keyword
,
1201 struct xheader
*xhdr
,
1202 void const *data
__attribute__ ((unused
)))
1204 code_num (st
->sparse_map_avail
, keyword
, xhdr
);
1208 sparse_numblocks_decoder (struct tar_stat_info
*st
,
1209 char const *keyword
,
1211 size_t size
__attribute__((unused
)))
1214 if (decode_num (&u
, arg
, SIZE_MAX
, keyword
))
1216 st
->sparse_map_size
= u
;
1217 st
->sparse_map
= xcalloc (u
, sizeof st
->sparse_map
[0]);
1218 st
->sparse_map_avail
= 0;
1223 sparse_offset_coder (struct tar_stat_info
const *st
, char const *keyword
,
1224 struct xheader
*xhdr
, void const *data
)
1226 size_t const *pi
= data
;
1227 code_num (st
->sparse_map
[*pi
].offset
, keyword
, xhdr
);
1231 sparse_offset_decoder (struct tar_stat_info
*st
,
1232 char const *keyword
,
1234 size_t size
__attribute__((unused
)))
1237 if (decode_num (&u
, arg
, TYPE_MAXIMUM (off_t
), keyword
))
1239 if (st
->sparse_map_avail
< st
->sparse_map_size
)
1240 st
->sparse_map
[st
->sparse_map_avail
].offset
= u
;
1242 ERROR ((0, 0, _("Malformed extended header: excess %s=%s"),
1243 "GNU.sparse.offset", arg
));
1248 sparse_numbytes_coder (struct tar_stat_info
const *st
, char const *keyword
,
1249 struct xheader
*xhdr
, void const *data
)
1251 size_t const *pi
= data
;
1252 code_num (st
->sparse_map
[*pi
].numbytes
, keyword
, xhdr
);
1256 sparse_numbytes_decoder (struct tar_stat_info
*st
,
1257 char const *keyword
,
1259 size_t size
__attribute__((unused
)))
1262 if (decode_num (&u
, arg
, SIZE_MAX
, keyword
))
1264 if (st
->sparse_map_avail
< st
->sparse_map_size
)
1265 st
->sparse_map
[st
->sparse_map_avail
++].numbytes
= u
;
1267 ERROR ((0, 0, _("Malformed extended header: excess %s=%s"),
1273 sparse_map_decoder (struct tar_stat_info
*st
,
1274 char const *keyword
,
1276 size_t size
__attribute__((unused
)))
1280 st
->sparse_map_avail
= 0;
1287 if (!ISDIGIT (*arg
))
1289 ERROR ((0, 0, _("Malformed extended header: invalid %s=%s"),
1295 u
= strtoumax (arg
, &delim
, 10);
1299 if (!(u
== e
.offset
&& errno
!= ERANGE
))
1301 out_of_range_header (keyword
, arg
, 0, TYPE_MAXIMUM (off_t
));
1308 if (!(u
== e
.numbytes
&& errno
!= ERANGE
))
1310 out_of_range_header (keyword
, arg
, 0, TYPE_MAXIMUM (size_t));
1313 if (st
->sparse_map_avail
< st
->sparse_map_size
)
1314 st
->sparse_map
[st
->sparse_map_avail
++] = e
;
1317 ERROR ((0, 0, _("Malformed extended header: excess %s=%s"),
1327 else if (*delim
!= ',')
1330 _("Malformed extended header: invalid %s: unexpected delimiter %c"),
1340 _("Malformed extended header: invalid %s: odd number of values"),
1345 dumpdir_coder (struct tar_stat_info
const *st
, char const *keyword
,
1346 struct xheader
*xhdr
, void const *data
)
1348 xheader_print_n (xhdr
, keyword
, data
, dumpdir_size (data
));
1352 dumpdir_decoder (struct tar_stat_info
*st
,
1353 char const *keyword
__attribute__((unused
)),
1357 st
->dumpdir
= xmalloc (size
);
1358 memcpy (st
->dumpdir
, arg
, size
);
1362 volume_label_coder (struct tar_stat_info
const *st
, char const *keyword
,
1363 struct xheader
*xhdr
, void const *data
)
1365 code_string (data
, keyword
, xhdr
);
1369 volume_label_decoder (struct tar_stat_info
*st
,
1370 char const *keyword
__attribute__((unused
)),
1372 size_t size
__attribute__((unused
)))
1374 decode_string (&volume_label
, arg
);
1378 volume_size_coder (struct tar_stat_info
const *st
, char const *keyword
,
1379 struct xheader
*xhdr
, void const *data
)
1381 off_t
const *v
= data
;
1382 code_num (*v
, keyword
, xhdr
);
1386 volume_size_decoder (struct tar_stat_info
*st
,
1387 char const *keyword
,
1388 char const *arg
, size_t size
)
1391 if (decode_num (&u
, arg
, TYPE_MAXIMUM (uintmax_t), keyword
))
1392 continued_file_size
= u
;
1395 /* FIXME: Merge with volume_size_coder */
1397 volume_offset_coder (struct tar_stat_info
const *st
, char const *keyword
,
1398 struct xheader
*xhdr
, void const *data
)
1400 off_t
const *v
= data
;
1401 code_num (*v
, keyword
, xhdr
);
1405 volume_offset_decoder (struct tar_stat_info
*st
,
1406 char const *keyword
,
1407 char const *arg
, size_t size
)
1410 if (decode_num (&u
, arg
, TYPE_MAXIMUM (uintmax_t), keyword
))
1411 continued_file_offset
= u
;
1415 volume_filename_decoder (struct tar_stat_info
*st
,
1416 char const *keyword
__attribute__((unused
)),
1418 size_t size
__attribute__((unused
)))
1420 decode_string (&continued_file_name
, arg
);
1424 sparse_major_coder (struct tar_stat_info
const *st
, char const *keyword
,
1425 struct xheader
*xhdr
, void const *data
)
1427 code_num (st
->sparse_major
, keyword
, xhdr
);
1431 sparse_major_decoder (struct tar_stat_info
*st
,
1432 char const *keyword
,
1437 if (decode_num (&u
, arg
, TYPE_MAXIMUM (unsigned), keyword
))
1438 st
->sparse_major
= u
;
1442 sparse_minor_coder (struct tar_stat_info
const *st
, char const *keyword
,
1443 struct xheader
*xhdr
, void const *data
)
1445 code_num (st
->sparse_minor
, keyword
, xhdr
);
1449 sparse_minor_decoder (struct tar_stat_info
*st
,
1450 char const *keyword
,
1455 if (decode_num (&u
, arg
, TYPE_MAXIMUM (unsigned), keyword
))
1456 st
->sparse_minor
= u
;
1459 struct xhdr_tab
const xhdr_tab
[] = {
1460 { "atime", atime_coder
, atime_decoder
, false },
1461 { "comment", dummy_coder
, dummy_decoder
, false },
1462 { "charset", dummy_coder
, dummy_decoder
, false },
1463 { "ctime", ctime_coder
, ctime_decoder
, false },
1464 { "gid", gid_coder
, gid_decoder
, false },
1465 { "gname", gname_coder
, gname_decoder
, false },
1466 { "linkpath", linkpath_coder
, linkpath_decoder
, false },
1467 { "mtime", mtime_coder
, mtime_decoder
, false },
1468 { "path", path_coder
, path_decoder
, false },
1469 { "size", size_coder
, size_decoder
, false },
1470 { "uid", uid_coder
, uid_decoder
, false },
1471 { "uname", uname_coder
, uname_decoder
, false },
1473 /* Sparse file handling */
1474 { "GNU.sparse.name", path_coder
, path_decoder
,
1476 { "GNU.sparse.major", sparse_major_coder
, sparse_major_decoder
,
1478 { "GNU.sparse.minor", sparse_minor_coder
, sparse_minor_decoder
,
1480 { "GNU.sparse.realsize", sparse_size_coder
, sparse_size_decoder
,
1482 { "GNU.sparse.numblocks", sparse_numblocks_coder
, sparse_numblocks_decoder
,
1485 /* tar 1.14 - 1.15.90 keywords. */
1486 { "GNU.sparse.size", sparse_size_coder
, sparse_size_decoder
, true },
1487 /* tar 1.14 - 1.15.1 keywords. Multiple instances of these appeared in 'x'
1488 headers, and each of them was meaningful. It confilcted with POSIX specs,
1489 which requires that "when extended header records conflict, the last one
1490 given in the header shall take precedence." */
1491 { "GNU.sparse.offset", sparse_offset_coder
, sparse_offset_decoder
,
1493 { "GNU.sparse.numbytes", sparse_numbytes_coder
, sparse_numbytes_decoder
,
1495 /* tar 1.15.90 keyword, introduced to remove the above-mentioned conflict. */
1496 { "GNU.sparse.map", NULL
/* Unused, see pax_dump_header() */,
1497 sparse_map_decoder
, false },
1499 { "GNU.dumpdir", dumpdir_coder
, dumpdir_decoder
,
1502 /* Keeps the tape/volume label. May be present only in the global headers.
1503 Equivalent to GNUTYPE_VOLHDR. */
1504 { "GNU.volume.label", volume_label_coder
, volume_label_decoder
, true },
1506 /* These may be present in a first global header of the archive.
1507 They provide the same functionality as GNUTYPE_MULTIVOL header.
1508 The GNU.volume.size keeps the real_s_sizeleft value, which is
1509 otherwise kept in the size field of a multivolume header. The
1510 GNU.volume.offset keeps the offset of the start of this volume,
1511 otherwise kept in oldgnu_header.offset. */
1512 { "GNU.volume.filename", volume_label_coder
, volume_filename_decoder
,
1514 { "GNU.volume.size", volume_size_coder
, volume_size_decoder
, true },
1515 { "GNU.volume.offset", volume_offset_coder
, volume_offset_decoder
, true },
1517 { NULL
, NULL
, NULL
, false }