| 215 |
} |
} |
| 216 |
|
|
| 217 |
static struct tar_sparse_optab oldgnu_optab; |
static struct tar_sparse_optab oldgnu_optab; |
| 218 |
|
static struct tar_sparse_optab star_optab; |
| 219 |
|
|
| 220 |
static bool |
static bool |
| 221 |
sparse_select_optab (struct tar_sparse_file *file) |
sparse_select_optab (struct tar_sparse_file *file) |
| 222 |
{ |
{ |
| 223 |
switch (archive_format) |
switch (current_format == DEFAULT_FORMAT ? archive_format : current_format) |
| 224 |
{ |
{ |
| 225 |
case V7_FORMAT: |
case V7_FORMAT: |
| 226 |
case USTAR_FORMAT: |
case USTAR_FORMAT: |
| 232 |
break; |
break; |
| 233 |
|
|
| 234 |
case POSIX_FORMAT: |
case POSIX_FORMAT: |
| 235 |
case STAR_FORMAT: |
/* FIXME: Add method */ |
|
/* FIXME: Add methods */ |
|
| 236 |
return false; |
return false; |
| 237 |
|
|
| 238 |
default: |
case STAR_FORMAT: |
| 239 |
|
file->optab = &star_optab; |
| 240 |
break; |
break; |
| 241 |
|
|
| 242 |
|
default: |
| 243 |
|
return false; |
| 244 |
} |
} |
| 245 |
return true; |
return true; |
| 246 |
} |
} |
| 644 |
sparse_dump_region, |
sparse_dump_region, |
| 645 |
sparse_extract_region, |
sparse_extract_region, |
| 646 |
}; |
}; |
| 647 |
|
|
| 648 |
|
|
| 649 |
|
/* Star */ |
| 650 |
|
|
| 651 |
|
/* Convert STAR format sparse data to internal representation |
| 652 |
|
FIXME: Clubbers current_header! */ |
| 653 |
|
static bool |
| 654 |
|
star_get_sparse_info (struct tar_sparse_file *file) |
| 655 |
|
{ |
| 656 |
|
size_t i; |
| 657 |
|
union block *h = current_header; |
| 658 |
|
int ext_p; |
| 659 |
|
static enum oldgnu_add_status rc; |
| 660 |
|
|
| 661 |
|
/* FIXME: note this! st_size was initialized from the header |
| 662 |
|
which actually contains archived size. The following fixes it */ |
| 663 |
|
file->stat_info->archive_file_size = file->stat_info->stat.st_size; |
| 664 |
|
file->stat_info->stat.st_size = |
| 665 |
|
OFF_FROM_HEADER (current_header->star_in_header.realsize); |
| 666 |
|
|
| 667 |
|
file->stat_info->sparse_map_size = 0; |
| 668 |
|
|
| 669 |
|
if (h->star_in_header.prefix[0] == '\0' |
| 670 |
|
&& h->star_in_header.sp[0].offset[10] != '\0') |
| 671 |
|
{ |
| 672 |
|
/* Old star format */ |
| 673 |
|
for (i = 0; i < SPARSES_IN_STAR_HEADER; i++) |
| 674 |
|
{ |
| 675 |
|
rc = oldgnu_add_sparse (file, &h->star_in_header.sp[i]); |
| 676 |
|
if (rc != add_ok) |
| 677 |
|
break; |
| 678 |
|
} |
| 679 |
|
ext_p = h->star_in_header.isextended; |
| 680 |
|
} |
| 681 |
|
else |
| 682 |
|
ext_p = 1; |
| 683 |
|
|
| 684 |
|
for (; rc == add_ok && ext_p; ext_p = h->star_ext_header.isextended) |
| 685 |
|
{ |
| 686 |
|
h = find_next_block (); |
| 687 |
|
if (!h) |
| 688 |
|
{ |
| 689 |
|
ERROR ((0, 0, _("Unexpected EOF in archive"))); |
| 690 |
|
return false; |
| 691 |
|
} |
| 692 |
|
set_next_block_after (h); |
| 693 |
|
for (i = 0; i < SPARSES_IN_STAR_EXT_HEADER && rc == add_ok; i++) |
| 694 |
|
rc = oldgnu_add_sparse (file, &h->star_ext_header.sp[i]); |
| 695 |
|
} |
| 696 |
|
|
| 697 |
|
if (rc == add_fail) |
| 698 |
|
{ |
| 699 |
|
ERROR ((0, 0, _("%s: invalid sparse archive member"), |
| 700 |
|
file->stat_info->orig_file_name)); |
| 701 |
|
return false; |
| 702 |
|
} |
| 703 |
|
return true; |
| 704 |
|
} |
| 705 |
|
|
| 706 |
|
|
| 707 |
|
static struct tar_sparse_optab star_optab = { |
| 708 |
|
NULL, /* No init function */ |
| 709 |
|
NULL, /* No done function */ |
| 710 |
|
NULL, |
| 711 |
|
star_get_sparse_info, |
| 712 |
|
NULL, /* No scan_block function */ |
| 713 |
|
NULL, /* No dump region function */ |
| 714 |
|
sparse_extract_region, |
| 715 |
|
}; |