(tar_checksum): sync with GNU tar b5db9788306d45cd9432fda71236f07b8a214212.

Signed-off-by: Andrew Borodin <aborodin@vmail.ru>
This commit is contained in:
Andrew Borodin 2020-06-28 16:42:26 +03:00
parent c4e20d3176
commit 4ae197e788
1 changed files with 28 additions and 29 deletions

View File

@ -412,45 +412,44 @@ tar_skip_n_records (struct vfs_s_super *archive, int tard, size_t n)
/* --------------------------------------------------------------------------------------------- */ /* --------------------------------------------------------------------------------------------- */
/** Check header checksum.
*/
static read_header static read_header
tar_checksum (const union block *header) tar_checksum (const union block *header)
{ {
long recsum; size_t i;
long signed_sum = 0; int unsigned_sum = 0; /* the POSIX one :-) */
long sum = 0; int signed_sum = 0; /* the Sun one :-( */
int i; int recorded_sum;
long parsed_sum;
const char *p = header->buffer; const char *p = header->buffer;
recsum = tar_from_oct (8, header->header.chksum); for (i = sizeof (*header); i-- != 0;)
for (i = sizeof (*header); --i >= 0;)
{ {
/* unsigned_sum += (unsigned char) *p;
* We can't use unsigned char here because of old compilers, signed_sum += (signed char) (*p++);
* e.g. V7.
*/
signed_sum += *p;
sum += 0xFF & *p++;
} }
/* Adjust checksum to count the "chksum" field as blanks. */ if (unsigned_sum == 0)
for (i = sizeof (header->header.chksum); --i >= 0;)
{
sum -= 0xFF & header->header.chksum[i];
signed_sum -= (char) header->header.chksum[i];
}
sum += ' ' * sizeof (header->header.chksum);
signed_sum += ' ' * sizeof (header->header.chksum);
/*
* This is a zeroed block... whole block is 0's except
* for the 8 blanks we faked for the checksum field.
*/
if (sum == 8 * ' ')
return HEADER_ZERO_BLOCK; return HEADER_ZERO_BLOCK;
if (sum != recsum && signed_sum != recsum) /* Adjust checksum to count the "chksum" field as blanks. */
for (i = sizeof (header->header.chksum); i-- != 0;)
{
unsigned_sum -= (unsigned char) header->header.chksum[i];
signed_sum -= (signed char) (header->header.chksum[i]);
}
unsigned_sum += ' ' * sizeof (header->header.chksum);
signed_sum += ' ' * sizeof (header->header.chksum);
parsed_sum = tar_from_oct (8, header->header.chksum);
if (parsed_sum == -1)
return HEADER_FAILURE;
recorded_sum = parsed_sum;
if (unsigned_sum != recorded_sum && signed_sum != recorded_sum)
return HEADER_FAILURE; return HEADER_FAILURE;
return HEADER_SUCCESS; return HEADER_SUCCESS;