Support for star sparse format

This commit is contained in:
Sergey Poznyakoff
2003-11-17 15:20:46 +00:00
parent b3404769c3
commit 8d6e47cc7f
2 changed files with 130 additions and 27 deletions

View File

@@ -215,11 +215,12 @@ sparse_scan_file (struct tar_sparse_file *file)
}
static struct tar_sparse_optab oldgnu_optab;
static struct tar_sparse_optab star_optab;
static bool
sparse_select_optab (struct tar_sparse_file *file)
{
switch (archive_format)
switch (current_format == DEFAULT_FORMAT ? archive_format : current_format)
{
case V7_FORMAT:
case USTAR_FORMAT:
@@ -231,12 +232,15 @@ sparse_select_optab (struct tar_sparse_file *file)
break;
case POSIX_FORMAT:
case STAR_FORMAT:
/* FIXME: Add methods */
/* FIXME: Add method */
return false;
default:
case STAR_FORMAT:
file->optab = &star_optab;
break;
default:
return false;
}
return true;
}
@@ -640,3 +644,72 @@ static struct tar_sparse_optab oldgnu_optab = {
sparse_dump_region,
sparse_extract_region,
};
/* Star */
/* Convert STAR format sparse data to internal representation
FIXME: Clubbers current_header! */
static bool
star_get_sparse_info (struct tar_sparse_file *file)
{
size_t i;
union block *h = current_header;
int ext_p;
static enum oldgnu_add_status rc;
/* FIXME: note this! st_size was initialized from the header
which actually contains archived size. The following fixes it */
file->stat_info->archive_file_size = file->stat_info->stat.st_size;
file->stat_info->stat.st_size =
OFF_FROM_HEADER (current_header->star_in_header.realsize);
file->stat_info->sparse_map_size = 0;
if (h->star_in_header.prefix[0] == '\0'
&& h->star_in_header.sp[0].offset[10] != '\0')
{
/* Old star format */
for (i = 0; i < SPARSES_IN_STAR_HEADER; i++)
{
rc = oldgnu_add_sparse (file, &h->star_in_header.sp[i]);
if (rc != add_ok)
break;
}
ext_p = h->star_in_header.isextended;
}
else
ext_p = 1;
for (; rc == add_ok && ext_p; ext_p = h->star_ext_header.isextended)
{
h = find_next_block ();
if (!h)
{
ERROR ((0, 0, _("Unexpected EOF in archive")));
return false;
}
set_next_block_after (h);
for (i = 0; i < SPARSES_IN_STAR_EXT_HEADER && rc == add_ok; i++)
rc = oldgnu_add_sparse (file, &h->star_ext_header.sp[i]);
}
if (rc == add_fail)
{
ERROR ((0, 0, _("%s: invalid sparse archive member"),
file->stat_info->orig_file_name));
return false;
}
return true;
}
static struct tar_sparse_optab star_optab = {
NULL, /* No init function */
NULL, /* No done function */
NULL,
star_get_sparse_info,
NULL, /* No scan_block function */
NULL, /* No dump region function */
sparse_extract_region,
};

View File

@@ -42,29 +42,6 @@ struct posix_header
/* 500 */
};
struct star_header
{ /* byte offset */
char name[100]; /* 0 */
char mode[8]; /* 100 */
char uid[8]; /* 108 */
char gid[8]; /* 116 */
char size[12]; /* 124 */
char mtime[12]; /* 136 */
char chksum[8]; /* 148 */
char typeflag; /* 156 */
char linkname[100]; /* 157 */
char magic[6]; /* 257 */
char version[2]; /* 263 */
char uname[32]; /* 265 */
char gname[32]; /* 297 */
char devmajor[8]; /* 329 */
char devminor[8]; /* 337 */
char prefix[131]; /* 345 */
char atime[12]; /* 476 */
char ctime[12]; /* 488 */
/* 500 */
};
#define TMAGIC "ustar" /* ustar and a null */
#define TMAGLEN 6
#define TVERSION "00" /* 00 and no null */
@@ -212,6 +189,57 @@ struct oldgnu_header
/* This file is a tape/volume header. Ignore it on extraction. */
#define GNUTYPE_VOLHDR 'V'
/* Jörg Schilling star header */
struct star_header
{ /* byte offset */
char name[100]; /* 0 */
char mode[8]; /* 100 */
char uid[8]; /* 108 */
char gid[8]; /* 116 */
char size[12]; /* 124 */
char mtime[12]; /* 136 */
char chksum[8]; /* 148 */
char typeflag; /* 156 */
char linkname[100]; /* 157 */
char magic[6]; /* 257 */
char version[2]; /* 263 */
char uname[32]; /* 265 */
char gname[32]; /* 297 */
char devmajor[8]; /* 329 */
char devminor[8]; /* 337 */
char prefix[131]; /* 345 */
char atime[12]; /* 476 */
char ctime[12]; /* 488 */
/* 500 */
};
#define SPARSES_IN_STAR_HEADER 4
#define SPARSES_IN_STAR_EXT_HEADER 21
struct star_in_header {
char fill[345]; /* 0 Everything that is before t_prefix */
char prefix[1]; /* 345 t_name prefix */
char fill2; /* 346 */
char fill3[8]; /* 347 */
char isextended; /* 355 */
struct sparse sp[SPARSES_IN_STAR_HEADER]; /* 356 */
char realsize[12]; /* 452 Actual size of the file */
char offset[12]; /* 464 Offset of multivolume contents */
char atime[12]; /* 476 */
char ctime[12]; /* 488 */
char mfill[8]; /* 500 */
char xmagic[4]; /* 508 "tar" */
};
struct star_ext_header {
struct sparse sp[SPARSES_IN_STAR_EXT_HEADER];
char isextended;
};
/* tar Header Block, overall structure. */
/* tar files are made in basic blocks of this size. */
@@ -267,6 +295,8 @@ union block
struct star_header star_header;
struct oldgnu_header oldgnu_header;
struct sparse_header sparse_header;
struct star_in_header star_in_header;
struct star_ext_header star_ext_header;
};
/* End of Format description. */