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