mirror of https://github.com/mirror/busybox.git
tar: improve OLDGNU compat, make old SUN compat configurable
parent
9a33780152
commit
a80b4a0fa7
|
@ -205,6 +205,15 @@ config FEATURE_TAR_OLDGNU_COMPATIBILITY
|
||||||
the old GNU format; help to kill this old format by
|
the old GNU format; help to kill this old format by
|
||||||
repacking your ancient archives with the new format.
|
repacking your ancient archives with the new format.
|
||||||
|
|
||||||
|
config FEATURE_TAR_OLDSUN_COMPATIBILITY
|
||||||
|
bool "Enable untarring of tarballs with checksums produced by buggy Sun tar"
|
||||||
|
default N
|
||||||
|
depends on TAR
|
||||||
|
help
|
||||||
|
This option is required to unpack archives created by some old
|
||||||
|
version of Sun's tar (it was calculating checksum using signed arithmetic).
|
||||||
|
It is said to be fixed in newer Sun tar, but "old" tarballs still exist.
|
||||||
|
|
||||||
config FEATURE_TAR_GNU_EXTENSIONS
|
config FEATURE_TAR_GNU_EXTENSIONS
|
||||||
bool "Enable support for some GNU tar extensions"
|
bool "Enable support for some GNU tar extensions"
|
||||||
default y
|
default y
|
||||||
|
|
|
@ -16,8 +16,9 @@ typedef struct hardlinks_s {
|
||||||
char get_header_cpio(archive_handle_t *archive_handle)
|
char get_header_cpio(archive_handle_t *archive_handle)
|
||||||
{
|
{
|
||||||
static hardlinks_t *saved_hardlinks = NULL;
|
static hardlinks_t *saved_hardlinks = NULL;
|
||||||
static unsigned short pending_hardlinks = 0;
|
static unsigned pending_hardlinks = 0;
|
||||||
static int inode;
|
static int inode;
|
||||||
|
|
||||||
file_header_t *file_header = archive_handle->file_header;
|
file_header_t *file_header = archive_handle->file_header;
|
||||||
char cpio_header[110];
|
char cpio_header[110];
|
||||||
int namesize;
|
int namesize;
|
||||||
|
|
|
@ -36,7 +36,7 @@ static unsigned long long getOctal(char *str, int len)
|
||||||
*/
|
*/
|
||||||
str[len] = '\0';
|
str[len] = '\0';
|
||||||
v = strtoull(str, &str, 8);
|
v = strtoull(str, &str, 8);
|
||||||
if (*str)
|
if (*str && (!ENABLE_FEATURE_TAR_OLDGNU_COMPATIBILITY || *str != ' '))
|
||||||
bb_error_msg_and_die("corrupted octal value in tar header");
|
bb_error_msg_and_die("corrupted octal value in tar header");
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,7 @@ static unsigned long long getOctal(char *str, int len)
|
||||||
void BUG_tar_header_size(void);
|
void BUG_tar_header_size(void);
|
||||||
char get_header_tar(archive_handle_t *archive_handle)
|
char get_header_tar(archive_handle_t *archive_handle)
|
||||||
{
|
{
|
||||||
static int end;
|
static smallint end;
|
||||||
|
|
||||||
file_header_t *file_header = archive_handle->file_header;
|
file_header_t *file_header = archive_handle->file_header;
|
||||||
struct {
|
struct {
|
||||||
|
@ -69,7 +69,10 @@ char get_header_tar(archive_handle_t *archive_handle)
|
||||||
char padding[12]; /* 500-512 */
|
char padding[12]; /* 500-512 */
|
||||||
} tar;
|
} tar;
|
||||||
char *cp;
|
char *cp;
|
||||||
int i, sum_u, sum_s, sum;
|
int i, sum_u, sum;
|
||||||
|
#if ENABLE_FEATURE_TAR_OLDSUN_COMPATIBILITY
|
||||||
|
int sum_s;
|
||||||
|
#endif
|
||||||
int parse_names;
|
int parse_names;
|
||||||
|
|
||||||
if (sizeof(tar) != 512)
|
if (sizeof(tar) != 512)
|
||||||
|
@ -115,20 +118,36 @@ char get_header_tar(archive_handle_t *archive_handle)
|
||||||
* POSIX says that checksum is done on unsigned bytes, but
|
* POSIX says that checksum is done on unsigned bytes, but
|
||||||
* Sun and HP-UX gets it wrong... more details in
|
* Sun and HP-UX gets it wrong... more details in
|
||||||
* GNU tar source. */
|
* GNU tar source. */
|
||||||
sum_s = sum_u = ' ' * sizeof(tar.chksum);
|
#if ENABLE_FEATURE_TAR_OLDSUN_COMPATIBILITY
|
||||||
|
sum_s = ' ' * sizeof(tar.chksum);
|
||||||
|
#endif
|
||||||
|
sum_u = ' ' * sizeof(tar.chksum);
|
||||||
for (i = 0; i < 148 ; i++) {
|
for (i = 0; i < 148 ; i++) {
|
||||||
sum_u += ((unsigned char*)&tar)[i];
|
sum_u += ((unsigned char*)&tar)[i];
|
||||||
|
#if ENABLE_FEATURE_TAR_OLDSUN_COMPATIBILITY
|
||||||
sum_s += ((signed char*)&tar)[i];
|
sum_s += ((signed char*)&tar)[i];
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
for (i = 156; i < 512 ; i++) {
|
for (i = 156; i < 512 ; i++) {
|
||||||
sum_u += ((unsigned char*)&tar)[i];
|
sum_u += ((unsigned char*)&tar)[i];
|
||||||
|
#if ENABLE_FEATURE_TAR_OLDSUN_COMPATIBILITY
|
||||||
sum_s += ((signed char*)&tar)[i];
|
sum_s += ((signed char*)&tar)[i];
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
/* This field does not need special treatment (getOctal) */
|
#if ENABLE_FEATURE_TAR_OLDGNU_COMPATIBILITY
|
||||||
sum = xstrtoul(tar.chksum, 8);
|
sum = strtoul(tar.chksum, &cp, 8);
|
||||||
if (sum_u != sum && sum_s != sum) {
|
if ((*cp && *cp != ' ')
|
||||||
|
|| (sum_u != sum USE_FEATURE_TAR_OLDSUN_COMPATIBILITY(&& sum_s != sum))
|
||||||
|
) {
|
||||||
bb_error_msg_and_die("invalid tar header checksum");
|
bb_error_msg_and_die("invalid tar header checksum");
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
/* This field does not need special treatment (getOctal) */
|
||||||
|
sum = xstrtoul(tar.chksum, 8);
|
||||||
|
if (sum_u != sum USE_FEATURE_TAR_OLDSUN_COMPATIBILITY(&& sum_s != sum)) {
|
||||||
|
bb_error_msg_and_die("invalid tar header checksum");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* 0 is reserved for high perf file, treat as normal file */
|
/* 0 is reserved for high perf file, treat as normal file */
|
||||||
if (!tar.typeflag) tar.typeflag = '0';
|
if (!tar.typeflag) tar.typeflag = '0';
|
||||||
|
|
Loading…
Reference in New Issue