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