}
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:
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;
}
sparse_dump_region,
sparse_extract_region,
};
+
+\f
+/* 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,
+};
/* 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 */
/* This file is a tape/volume header. Ignore it on extraction. */
#define GNUTYPE_VOLHDR 'V'
+\f
+/* 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;
+};
+
+\f
+
/* tar Header Block, overall structure. */
/* tar files are made in basic blocks of this size. */
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. */