Tar Header Contains Where Octal Uid_t Value Expected
"Fossies" - the Fresh Open Source Software Archive
Member "tar-1.34/src/list.c" (4 Feb 2021, 41078 Bytes) of package /linux/misc/tar-1.34.tar.xz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "list.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report:
1.33_vs_1.34.
1 /* List a tar archive, with support routines for reading a tar archive. 2 3 Copyright 1988-2021 Free Software Foundation, Inc. 4 5 This file is part of GNU tar. 6 7 GNU tar is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 3 of the License, or 10 (at your option) any later version. 11 12 GNU tar is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program. If not, see <http://www.gnu.org/licenses/>. 19 20 Written by John Gilmore, on 1985-08-26. */ 21 22 #include <system.h> 23 #include <inttostr.h> 24 #include <quotearg.h> 25 #include <time.h> 26 #include "common.h" 27 28 union block *current_header; /* points to current archive header */ 29 enum archive_format current_format; /* recognized format */ 30 union block *recent_long_name; /* recent long name header and contents */ 31 union block *recent_long_link; /* likewise, for long link */ 32 size_t recent_long_name_blocks; /* number of blocks in recent_long_name */ 33 size_t recent_long_link_blocks; /* likewise, for long link */ 34 static union block *recent_global_header; /* Recent global header block */ 35 36 #define GID_FROM_HEADER(where) gid_from_header (where, sizeof (where)) 37 #define MAJOR_FROM_HEADER(where) major_from_header (where, sizeof (where)) 38 #define MINOR_FROM_HEADER(where) minor_from_header (where, sizeof (where)) 39 #define MODE_FROM_HEADER(where, hbits) \ 40 mode_from_header (where, sizeof (where), hbits) 41 #define TIME_FROM_HEADER(where) time_from_header (where, sizeof (where)) 42 #define UID_FROM_HEADER(where) uid_from_header (where, sizeof (where)) 43 44 static gid_t gid_from_header ( const char *buf, size_t size); 45 static major_t major_from_header ( const char *buf, size_t size); 46 static minor_t minor_from_header ( const char *buf, size_t size); 47 static mode_t mode_from_header ( const char *buf, size_t size, bool *hbits); 48 static time_t time_from_header ( const char *buf, size_t size); 49 static uid_t uid_from_header ( const char *buf, size_t size); 50 static intmax_t from_header ( const char *, size_t , const char *, 51 intmax_t , uintmax_t , bool , bool ); 52 53 /* Base 64 digits; see Internet RFC 2045 Table 1. */ 54 static char const base_64_digits[ 64 ] = 55 { 56 'A' , 'B' , 'C' , 'D' , 'E' , 'F' , 'G' , 'H' , 'I' , 'J' , 'K' , 'L' , 'M' , 57 'N' , 'O' , 'P' , 'Q' , 'R' , 'S' , 'T' , 'U' , 'V' , 'W' , 'X' , 'Y' , 'Z' , 58 'a' , 'b' , 'c' , 'd' , 'e' , 'f' , 'g' , 'h' , 'i' , 'j' , 'k' , 'l' , 'm' , 59 'n' , 'o' , 'p' , 'q' , 'r' , 's' , 't' , 'u' , 'v' , 'w' , 'x' , 'y' , 'z' , 60 '0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9' , '+' , '/' 61 }; 62 63 /* Table of base-64 digit values indexed by unsigned chars. 64 The value is 64 for unsigned chars that are not base-64 digits. */ 65 static char base64_map[UCHAR_MAX + 1 ]; 66 67 static void 68 base64_init ( void ) 69 { 70 int i; 71 memset (base64_map, 64 , sizeof base64_map); 72 for (i = 0 ; i < 64 ; i++) 73 base64_map[( int ) base_64_digits[i]] = i; 74 } 75 76 static char * 77 decode_xform ( char *file_name, void *data) 78 { 79 int type = *( int *)data; 80 81 switch (type) 82 { 83 case XFORM_SYMLINK: 84 /* FIXME: It is not quite clear how and to which extent are the symbolic 85 links subject to filename transformation. In the absence of another 86 solution, symbolic links are exempt from component stripping and 87 name suffix normalization, but subject to filename transformation 88 proper. */ 89 return file_name; 90 91 case XFORM_LINK: 92 file_name = safer_name_suffix (file_name, true , absolute_names_option); 93 break ; 94 95 case XFORM_REGFILE: 96 file_name = safer_name_suffix (file_name, false , absolute_names_option); 97 break ; 98 } 99 100 if (strip_name_components) 101 { 102 size_t prefix_len = stripped_prefix_len (file_name, 103 strip_name_components); 104 if (prefix_len == ( size_t ) - 1 ) 105 prefix_len = strlen (file_name); 106 file_name += prefix_len; 107 } 108 return file_name; 109 } 110 111 static bool 112 transform_member_name ( char **pinput, int type) 113 { 114 return transform_name_fp (pinput, type, decode_xform, &type); 115 } 116 117 static void 118 enforce_one_top_level ( char **pfile_name) 119 { 120 char *file_name = *pfile_name; 121 char *p; 122 123 for (p = file_name; *p && ( ISSLASH (*p) || *p == '.' ); p++) 124 ; 125 126 if (*p) 127 { 128 int pos = strlen (one_top_level_dir); 129 if ( strncmp (p, one_top_level_dir, pos) == 0 ) 130 { 131 if ( ISSLASH (p[pos]) || p[pos] == 0 ) 132 return ; 133 } 134 135 *pfile_name = make_file_name (one_top_level_dir, file_name); 136 normalize_filename_x (*pfile_name); 137 } 138 else 139 *pfile_name = xstrdup (one_top_level_dir); 140 free (file_name); 141 } 142 143 void 144 transform_stat_info ( int typeflag, struct tar_stat_info *stat_info) 145 { 146 if (typeflag == GNUTYPE_VOLHDR) 147 /* Name transformations don't apply to volume headers. */ 148 return ; 149 150 transform_member_name (&stat_info->file_name, XFORM_REGFILE); 151 switch (typeflag) 152 { 153 case SYMTYPE: 154 transform_member_name (&stat_info->link_name, XFORM_SYMLINK); 155 break ; 156 157 case LNKTYPE: 158 transform_member_name (&stat_info->link_name, XFORM_LINK); 159 } 160 161 if (one_top_level_option) 162 enforce_one_top_level (¤t_stat_info.file_name); 163 } 164 165 /* Main loop for reading an archive. */ 166 void 167 read_and ( void (*do_something) ( void )) 168 { 169 enum read_header status = HEADER_STILL_UNREAD; 170 enum read_header prev_status; 171 struct timespec mtime; 172 173 base64_init (); 174 name_gather (); 175 176 open_archive (ACCESS_READ); 177 do 178 { 179 prev_status = status; 180 tar_stat_destroy (¤t_stat_info); 181 182 status = read_header (¤t_header, ¤t_stat_info, 183 read_header_auto); 184 switch (status) 185 { 186 case HEADER_STILL_UNREAD: 187 case HEADER_SUCCESS_EXTENDED: 188 abort (); 189 190 case HEADER_SUCCESS: 191 192 /* Valid header. We should decode next field (mode) first. 193 Ensure incoming names are null terminated. */ 194 decode_header (current_header, ¤t_stat_info, 195 ¤t_format, 1 ); 196 if (! name_match (current_stat_info.file_name) 197 || ( TIME_OPTION_INITIALIZED (newer_mtime_option) 198 /* FIXME: We get mtime now, and again later; this causes 199 duplicate diagnostics if header.mtime is bogus. */ 200 && ((mtime.tv_sec 201 = TIME_FROM_HEADER (current_header->header.mtime)), 202 /* FIXME: Grab fractional time stamps from 203 extended header. */ 204 mtime.tv_nsec = 0 , 205 current_stat_info.mtime = mtime, 206 OLDER_TAR_STAT_TIME (current_stat_info, m))) 207 || excluded_name (current_stat_info.file_name, 208 current_stat_info.parent)) 209 { 210 switch (current_header->header.typeflag) 211 { 212 case GNUTYPE_VOLHDR: 213 case GNUTYPE_MULTIVOL: 214 break ; 215 216 case DIRTYPE: 217 if (show_omitted_dirs_option) 218 WARN (( 0 , 0 , _ ( " %s : Omitting" ), 219 quotearg_colon (current_stat_info.file_name))); 220 FALLTHROUGH; 221 default : 222 skip_member (); 223 continue ; 224 } 225 } 226 227 transform_stat_info (current_header->header.typeflag, 228 ¤t_stat_info); 229 (*do_something) (); 230 continue ; 231 232 case HEADER_ZERO_BLOCK: 233 if (block_number_option) 234 { 235 char buf[UINTMAX_STRSIZE_BOUND]; 236 fprintf (stdlis, _ ( "block %s : ** Block of NULs ** \n " ), 237 STRINGIFY_BIGINT ( current_block_ordinal (), buf)); 238 } 239 240 set_next_block_after (current_header); 241 242 if (!ignore_zeros_option) 243 { 244 char buf[UINTMAX_STRSIZE_BOUND]; 245 246 status = read_header (¤t_header, ¤t_stat_info, 247 read_header_auto); 248 if (status == HEADER_ZERO_BLOCK) 249 break ; 250 WARNOPT (WARN_ALONE_ZERO_BLOCK, 251 ( 0 , 0 , _ ( "A lone zero block at %s " ), 252 STRINGIFY_BIGINT ( current_block_ordinal (), buf))); 253 break ; 254 } 255 status = prev_status; 256 continue ; 257 258 case HEADER_END_OF_FILE: 259 if (block_number_option) 260 { 261 char buf[UINTMAX_STRSIZE_BOUND]; 262 fprintf (stdlis, _ ( "block %s : ** End of File ** \n " ), 263 STRINGIFY_BIGINT ( current_block_ordinal (), buf)); 264 } 265 break ; 266 267 case HEADER_FAILURE: 268 /* If the previous header was good, tell them that we are 269 skipping bad ones. */ 270 set_next_block_after (current_header); 271 switch (prev_status) 272 { 273 case HEADER_STILL_UNREAD: 274 ERROR (( 0 , 0 , _ ( "This does not look like a tar archive" ))); 275 FALLTHROUGH; 276 case HEADER_ZERO_BLOCK: 277 case HEADER_SUCCESS: 278 if (block_number_option) 279 { 280 char buf[UINTMAX_STRSIZE_BOUND]; 281 off_t block_ordinal = current_block_ordinal (); 282 block_ordinal -= recent_long_name_blocks; 283 block_ordinal -= recent_long_link_blocks; 284 fprintf (stdlis, _ ( "block %s : " ), 285 STRINGIFY_BIGINT (block_ordinal, buf)); 286 } 287 ERROR (( 0 , 0 , _ ( "Skipping to next header" ))); 288 break ; 289 290 case HEADER_END_OF_FILE: 291 case HEADER_FAILURE: 292 /* We are in the middle of a cascade of errors. */ 293 break ; 294 295 case HEADER_SUCCESS_EXTENDED: 296 abort (); 297 } 298 continue ; 299 } 300 break ; 301 } 302 while (! all_names_found (¤t_stat_info)); 303 304 close_archive (); 305 names_notfound (); /* print names not found */ 306 } 307 308 /* Print a header block, based on tar options. */ 309 void 310 list_archive ( void ) 311 { 312 off_t block_ordinal = current_block_ordinal (); 313 314 /* Print the header block. */ 315 if (verbose_option) 316 print_header (¤t_stat_info, current_header, block_ordinal); 317 318 if (incremental_option) 319 { 320 if (verbose_option > 2 ) 321 { 322 if ( is_dumpdir (¤t_stat_info)) 323 list_dumpdir (current_stat_info.dumpdir, 324 dumpdir_size (current_stat_info.dumpdir)); 325 } 326 } 327 328 skip_member (); 329 } 330 331 /* Check header checksum */ 332 /* The standard BSD tar sources create the checksum by adding up the 333 bytes in the header as type char. I think the type char was unsigned 334 on the PDP-11, but it's signed on the Next and Sun. It looks like the 335 sources to BSD tar were never changed to compute the checksum 336 correctly, so both the Sun and Next add the bytes of the header as 337 signed chars. This doesn't cause a problem until you get a file with 338 a name containing characters with the high bit set. So tar_checksum 339 computes two checksums -- signed and unsigned. */ 340 341 enum read_header 342 tar_checksum ( union block *header, bool silent) 343 { 344 size_t i; 345 int unsigned_sum = 0 ; /* the POSIX one :-) */ 346 int signed_sum = 0 ; /* the Sun one :-( */ 347 int recorded_sum; 348 int parsed_sum; 349 char *p; 350 351 p = header->buffer; 352 for (i = sizeof *header; i-- != 0 ;) 353 { 354 unsigned_sum += ( unsigned char ) *p; 355 signed_sum += ( signed char ) (*p++); 356 } 357 358 if (unsigned_sum == 0 ) 359 return HEADER_ZERO_BLOCK; 360 361 /* Adjust checksum to count the "chksum" field as blanks. */ 362 363 for (i = sizeof header->header.chksum; i-- != 0 ;) 364 { 365 unsigned_sum -= ( unsigned char ) header->header.chksum[i]; 366 signed_sum -= ( signed char ) (header->header.chksum[i]); 367 } 368 unsigned_sum += ' ' * sizeof header->header.chksum; 369 signed_sum += ' ' * sizeof header->header.chksum; 370 371 parsed_sum = from_header (header->header.chksum, 372 sizeof header->header.chksum, 0 , 373 0 , INT_MAX, true , silent); 374 if (parsed_sum < 0 ) 375 return HEADER_FAILURE; 376 377 recorded_sum = parsed_sum; 378 379 if (unsigned_sum != recorded_sum && signed_sum != recorded_sum) 380 return HEADER_FAILURE; 381 382 return HEADER_SUCCESS; 383 } 384 385 /* Read a block that's supposed to be a header block. Return its 386 address in *RETURN_BLOCK, and if it is good, the file's size 387 and names (file name, link name) in *INFO. 388 389 Return one of enum read_header describing the status of the 390 operation. 391 392 The MODE parameter instructs read_header what to do with special 393 header blocks, i.e.: extended POSIX, GNU long name or long link, 394 etc.: 395 396 read_header_auto process them automatically, 397 read_header_x_raw when a special header is read, return 398 HEADER_SUCCESS_EXTENDED without actually 399 processing the header, 400 read_header_x_global when a POSIX global header is read, 401 decode it and return HEADER_SUCCESS_EXTENDED. 402 403 You must always set_next_block_after(*return_block) to skip past 404 the header which this routine reads. */ 405 406 enum read_header 407 read_header ( union block **return_block, struct tar_stat_info *info, 408 enum read_header_mode mode) 409 { 410 union block *header; 411 char *bp; 412 union block *data_block; 413 size_t size, written; 414 union block *next_long_name = NULL; 415 union block *next_long_link = NULL; 416 size_t next_long_name_blocks = 0 ; 417 size_t next_long_link_blocks = 0 ; 418 enum read_header status = HEADER_SUCCESS; 419 420 while ( 1 ) 421 { 422 header = find_next_block (); 423 *return_block = header; 424 if (!header) 425 { 426 status = HEADER_END_OF_FILE; 427 break ; 428 } 429 430 if ((status = tar_checksum (header, false )) != HEADER_SUCCESS) 431 break ; 432 433 /* Good block. Decode file size and return. */ 434 435 if (header->header.typeflag == LNKTYPE) 436 info->stat.st_size = 0 ; /* links 0 size on tape */ 437 else 438 { 439 info->stat.st_size = OFF_FROM_HEADER (header->header.size); 440 if (info->stat.st_size < 0 ) 441 { 442 status = HEADER_FAILURE; 443 break ; 444 } 445 } 446 447 if (header->header.typeflag == GNUTYPE_LONGNAME 448 || header->header.typeflag == GNUTYPE_LONGLINK 449 || header->header.typeflag == XHDTYPE 450 || header->header.typeflag == XGLTYPE 451 || header->header.typeflag == SOLARIS_XHDTYPE) 452 { 453 if (mode == read_header_x_raw) 454 { 455 status = HEADER_SUCCESS_EXTENDED; 456 break ; 457 } 458 else if (header->header.typeflag == GNUTYPE_LONGNAME 459 || header->header.typeflag == GNUTYPE_LONGLINK) 460 { 461 union block *header_copy; 462 size_t name_size = info->stat.st_size; 463 size_t n = name_size % BLOCKSIZE; 464 size = name_size + BLOCKSIZE; 465 if (n) 466 size += BLOCKSIZE - n; 467 468 if (name_size != info->stat.st_size || size < name_size) 469 xalloc_die (); 470 471 header_copy = xmalloc (size + 1 ); 472 473 if (header->header.typeflag == GNUTYPE_LONGNAME) 474 { 475 free (next_long_name); 476 next_long_name = header_copy; 477 next_long_name_blocks = size / BLOCKSIZE; 478 } 479 else 480 { 481 free (next_long_link); 482 next_long_link = header_copy; 483 next_long_link_blocks = size / BLOCKSIZE; 484 } 485 486 set_next_block_after (header); 487 *header_copy = *header; 488 bp = header_copy->buffer + BLOCKSIZE; 489 490 for (size -= BLOCKSIZE; size > 0 ; size -= written) 491 { 492 data_block = find_next_block (); 493 if (! data_block) 494 { 495 ERROR (( 0 , 0 , _ ( "Unexpected EOF in archive" ))); 496 break ; 497 } 498 written = available_space_after (data_block); 499 if (written > size) 500 written = size; 501 502 memcpy (bp, data_block->buffer, written); 503 bp += written; 504 set_next_block_after (( union block *) 505 (data_block->buffer + written - 1 )); 506 } 507 508 *bp = '\0' ; 509 } 510 else if (header->header.typeflag == XHDTYPE 511 || header->header.typeflag == SOLARIS_XHDTYPE) 512 xheader_read (&info->xhdr, header, 513 OFF_FROM_HEADER (header->header.size)); 514 else if (header->header.typeflag == XGLTYPE) 515 { 516 struct xheader xhdr; 517 518 if (!recent_global_header) 519 recent_global_header = xmalloc ( sizeof *recent_global_header); 520 memcpy (recent_global_header, header, 521 sizeof *recent_global_header); 522 memset (&xhdr, 0 , sizeof xhdr); 523 xheader_read (&xhdr, header, 524 OFF_FROM_HEADER (header->header.size)); 525 xheader_decode_global (&xhdr); 526 xheader_destroy (&xhdr); 527 if (mode == read_header_x_global) 528 { 529 status = HEADER_SUCCESS_EXTENDED; 530 break ; 531 } 532 } 533 534 /* Loop! */ 535 536 } 537 else 538 { 539 char const *name; 540 struct posix_header const *h = &header->header; 541 char namebuf[ sizeof h->prefix + 1 + NAME_FIELD_SIZE + 1 ]; 542 543 free (recent_long_name); 544 545 if (next_long_name) 546 { 547 name = next_long_name->buffer + BLOCKSIZE; 548 recent_long_name = next_long_name; 549 recent_long_name_blocks = next_long_name_blocks; 550 next_long_name = NULL; 551 } 552 else 553 { 554 /* Accept file names as specified by POSIX.1-1996 555 section 10.1.1. */ 556 char *np = namebuf; 557 558 if (h->prefix[ 0 ] && strcmp (h->magic, TMAGIC) == 0 ) 559 { 560 memcpy (np, h->prefix, sizeof h->prefix); 561 np[ sizeof h->prefix] = '\0' ; 562 np += strlen (np); 563 *np++ = '/' ; 564 } 565 memcpy (np, h->name, sizeof h->name); 566 np[ sizeof h->name] = '\0' ; 567 name = namebuf; 568 recent_long_name = 0 ; 569 recent_long_name_blocks = 0 ; 570 } 571 assign_string (&info->orig_file_name, name); 572 assign_string (&info->file_name, name); 573 info->had_trailing_slash = strip_trailing_slashes (info->file_name); 574 575 free (recent_long_link); 576 577 if (next_long_link) 578 { 579 name = next_long_link->buffer + BLOCKSIZE; 580 recent_long_link = next_long_link; 581 recent_long_link_blocks = next_long_link_blocks; 582 next_long_link = NULL; 583 } 584 else 585 { 586 memcpy (namebuf, h->linkname, sizeof h->linkname); 587 namebuf[ sizeof h->linkname] = '\0' ; 588 name = namebuf; 589 recent_long_link = 0 ; 590 recent_long_link_blocks = 0 ; 591 } 592 assign_string (&info->link_name, name); 593 594 break ; 595 } 596 } 597 free (next_long_name); 598 free (next_long_link); 599 return status; 600 } 601 602 #define ISOCTAL(c) ((c)>= '0' &&(c)<= '7' ) 603 604 /* Decode things from a file HEADER block into STAT_INFO, also setting 605 *FORMAT_POINTER depending on the header block format. If 606 DO_USER_GROUP, decode the user/group information (this is useful 607 for extraction, but waste time when merely listing). 608 609 read_header() has already decoded the checksum and length, so we don't. 610 611 This routine should *not* be called twice for the same block, since 612 the two calls might use different DO_USER_GROUP values and thus 613 might end up with different uid/gid for the two calls. If anybody 614 wants the uid/gid they should decode it first, and other callers 615 should decode it without uid/gid before calling a routine, 616 e.g. print_header, that assumes decoded data. */ 617 void 618 decode_header ( union block *header, struct tar_stat_info *stat_info, 619 enum archive_format *format_pointer, int do_user_group) 620 { 621 enum archive_format format; 622 bool hbits; 623 mode_t mode = MODE_FROM_HEADER (header->header.mode, &hbits); 624 625 if ( strcmp (header->header.magic, TMAGIC) == 0 ) 626 { 627 if (header->star_header.prefix[ 130 ] == 0 628 && ISOCTAL (header->star_header.atime[ 0 ]) 629 && header->star_header.atime[ 11 ] == ' ' 630 && ISOCTAL (header->star_header.ctime[ 0 ]) 631 && header->star_header.ctime[ 11 ] == ' ' ) 632 format = STAR_FORMAT; 633 else if (stat_info->xhdr.size) 634 format = POSIX_FORMAT; 635 else 636 format = USTAR_FORMAT; 637 } 638 else if ( strcmp (header->buffer + offsetof ( struct posix_header, magic), 639 OLDGNU_MAGIC) 640 == 0 ) 641 format = hbits ? OLDGNU_FORMAT : GNU_FORMAT; 642 else 643 format = V7_FORMAT; 644 *format_pointer = format; 645 646 stat_info->stat.st_mode = mode; 647 stat_info->mtime.tv_sec = TIME_FROM_HEADER (header->header.mtime); 648 stat_info->mtime.tv_nsec = 0 ; 649 assign_string_n (&stat_info->uname, 650 header->header.uname[ 0 ] ? header->header.uname : NULL, 651 sizeof (header->header.uname)); 652 assign_string_n (&stat_info->gname, 653 header->header.gname[ 0 ] ? header->header.gname : NULL, 654 sizeof (header->header.gname)); 655 656 xheader_xattr_init (stat_info); 657 658 if (format == OLDGNU_FORMAT && incremental_option) 659 { 660 stat_info->atime.tv_sec = TIME_FROM_HEADER (header->oldgnu_header.atime); 661 stat_info->ctime.tv_sec = TIME_FROM_HEADER (header->oldgnu_header.ctime); 662 stat_info->atime.tv_nsec = stat_info->ctime.tv_nsec = 0 ; 663 } 664 else if (format == STAR_FORMAT) 665 { 666 stat_info->atime.tv_sec = TIME_FROM_HEADER (header->star_header.atime); 667 stat_info->ctime.tv_sec = TIME_FROM_HEADER (header->star_header.ctime); 668 stat_info->atime.tv_nsec = stat_info->ctime.tv_nsec = 0 ; 669 } 670 else 671 stat_info->atime = stat_info->ctime = start_time; 672 673 if (format == V7_FORMAT) 674 { 675 stat_info->stat.st_uid = UID_FROM_HEADER (header->header.uid); 676 stat_info->stat.st_gid = GID_FROM_HEADER (header->header.gid); 677 stat_info->stat.st_rdev = 0 ; 678 } 679 else 680 { 681 if (do_user_group) 682 { 683 /* FIXME: Decide if this should somewhat depend on -p. */ 684 685 if (numeric_owner_option 686 || !*header->header.uname 687 || ! uname_to_uid (header->header.uname, &stat_info->stat.st_uid)) 688 stat_info->stat.st_uid = UID_FROM_HEADER (header->header.uid); 689 690 if (numeric_owner_option 691 || !*header->header.gname 692 || ! gname_to_gid (header->header.gname, &stat_info->stat.st_gid)) 693 stat_info->stat.st_gid = GID_FROM_HEADER (header->header.gid); 694 } 695 696 switch (header->header.typeflag) 697 { 698 case BLKTYPE: 699 case CHRTYPE: 700 stat_info->stat.st_rdev = 701 makedev ( MAJOR_FROM_HEADER (header->header.devmajor), 702 MINOR_FROM_HEADER (header->header.devminor)); 703 break ; 704 705 default : 706 stat_info->stat.st_rdev = 0 ; 707 } 708 } 709 710 xheader_decode (stat_info); 711 712 if ( sparse_member_p (stat_info)) 713 { 714 sparse_fixup_header (stat_info); 715 stat_info->is_sparse = true ; 716 } 717 else 718 { 719 stat_info->is_sparse = false ; 720 if (((current_format == GNU_FORMAT 721 || current_format == OLDGNU_FORMAT) 722 && current_header->header.typeflag == GNUTYPE_DUMPDIR) 723 || stat_info->dumpdir) 724 stat_info->is_dumpdir = true ; 725 } 726 } 727 728 729 /* Convert buffer at WHERE0 of size DIGS from external format to 730 intmax_t. DIGS must be positive. If TYPE is nonnull, the data are 731 of type TYPE. The buffer must represent a value in the range 732 MINVAL through MAXVAL; if the mathematically correct result V would 733 be greater than INTMAX_MAX, return a negative integer V such that 734 (uintmax_t) V yields the correct result. If OCTAL_ONLY, allow only octal 735 numbers instead of the other GNU extensions. Return -1 on error, 736 diagnosing the error if TYPE is nonnull and if !SILENT. */ 737 #if ! (INTMAX_MAX <= UINTMAX_MAX && - (INTMAX_MIN + 1) <= UINTMAX_MAX) 738 # error "from_header internally represents intmax_t as uintmax_t + sign" 739
0 Response to "Tar Header Contains Where Octal Uid_t Value Expected"
Post a Comment