tar,smemcap: commonalyze checksumming code for tar header
function old new delta chksum_and_xwrite_tar_header - 99 +99 writeheader 280 199 -81 chksum_and_xwrite 102 - -102 ------------------------------------------------------------------------------ (add/remove: 2/1 grow/shrink: 0/1 up/down: 99/-183) Total: -84 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
38e9c8c95b
commit
62d5a1e56f
35
archival/chksum_and_xwrite_tar_header.c
Normal file
35
archival/chksum_and_xwrite_tar_header.c
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2021 Denys Vlasenko <vda.linux@googlemail.com>
|
||||||
|
*
|
||||||
|
* Licensed under GPLv2, see file LICENSE in this source tree.
|
||||||
|
*/
|
||||||
|
//kbuild:lib-$(CONFIG_FEATURE_TAR_CREATE) += chksum_and_xwrite_tar_header.o
|
||||||
|
//kbuild:lib-$(CONFIG_SMEMCAP) += chksum_and_xwrite_tar_header.o
|
||||||
|
|
||||||
|
#include "libbb.h"
|
||||||
|
#include "bb_archive.h"
|
||||||
|
|
||||||
|
void FAST_FUNC chksum_and_xwrite_tar_header(int fd, struct tar_header_t *hp)
|
||||||
|
{
|
||||||
|
/* POSIX says that checksum is done on unsigned bytes
|
||||||
|
* (Sun and HP-UX gets it wrong... more details in
|
||||||
|
* GNU tar source) */
|
||||||
|
const unsigned char *cp;
|
||||||
|
int chksum, size;
|
||||||
|
|
||||||
|
strcpy(hp->magic, "ustar ");
|
||||||
|
|
||||||
|
/* Calculate and store the checksum (the sum of all of the bytes of
|
||||||
|
* the header). The checksum field must be filled with blanks for the
|
||||||
|
* calculation. The checksum field is formatted differently from the
|
||||||
|
* other fields: it has 6 digits, a NUL, then a space -- rather than
|
||||||
|
* digits, followed by a NUL like the other fields... */
|
||||||
|
memset(hp->chksum, ' ', sizeof(hp->chksum));
|
||||||
|
cp = (const unsigned char *) hp;
|
||||||
|
chksum = 0;
|
||||||
|
size = sizeof(*hp);
|
||||||
|
do { chksum += *cp++; } while (--size);
|
||||||
|
sprintf(hp->chksum, "%06o", chksum);
|
||||||
|
|
||||||
|
xwrite(fd, hp, sizeof(*hp));
|
||||||
|
}
|
@ -254,32 +254,6 @@ static void putOctal(char *cp, int len, off_t value)
|
|||||||
}
|
}
|
||||||
#define PUT_OCTAL(a, b) putOctal((a), sizeof(a), (b))
|
#define PUT_OCTAL(a, b) putOctal((a), sizeof(a), (b))
|
||||||
|
|
||||||
static void chksum_and_xwrite(int fd, struct tar_header_t* hp)
|
|
||||||
{
|
|
||||||
/* POSIX says that checksum is done on unsigned bytes
|
|
||||||
* (Sun and HP-UX gets it wrong... more details in
|
|
||||||
* GNU tar source) */
|
|
||||||
const unsigned char *cp;
|
|
||||||
int chksum, size;
|
|
||||||
|
|
||||||
strcpy(hp->magic, "ustar ");
|
|
||||||
|
|
||||||
/* Calculate and store the checksum (i.e., the sum of all of the bytes of
|
|
||||||
* the header). The checksum field must be filled with blanks for the
|
|
||||||
* calculation. The checksum field is formatted differently from the
|
|
||||||
* other fields: it has 6 digits, a null, then a space -- rather than
|
|
||||||
* digits, followed by a null like the other fields... */
|
|
||||||
memset(hp->chksum, ' ', sizeof(hp->chksum));
|
|
||||||
cp = (const unsigned char *) hp;
|
|
||||||
chksum = 0;
|
|
||||||
size = sizeof(*hp);
|
|
||||||
do { chksum += *cp++; } while (--size);
|
|
||||||
putOctal(hp->chksum, sizeof(hp->chksum)-1, chksum);
|
|
||||||
|
|
||||||
/* Now write the header out to disk */
|
|
||||||
xwrite(fd, hp, sizeof(*hp));
|
|
||||||
}
|
|
||||||
|
|
||||||
# if ENABLE_FEATURE_TAR_GNU_EXTENSIONS
|
# if ENABLE_FEATURE_TAR_GNU_EXTENSIONS
|
||||||
static void writeLongname(int fd, int type, const char *name, int dir)
|
static void writeLongname(int fd, int type, const char *name, int dir)
|
||||||
{
|
{
|
||||||
@ -310,7 +284,7 @@ static void writeLongname(int fd, int type, const char *name, int dir)
|
|||||||
/* + dir: account for possible '/' */
|
/* + dir: account for possible '/' */
|
||||||
|
|
||||||
PUT_OCTAL(header.size, size);
|
PUT_OCTAL(header.size, size);
|
||||||
chksum_and_xwrite(fd, &header);
|
chksum_and_xwrite_tar_header(fd, &header);
|
||||||
|
|
||||||
/* Write filename[/] and pad the block. */
|
/* Write filename[/] and pad the block. */
|
||||||
/* dir=0: writes 'name<NUL>', pads */
|
/* dir=0: writes 'name<NUL>', pads */
|
||||||
@ -441,8 +415,7 @@ static int writeTarHeader(struct TarBallInfo *tbInfo,
|
|||||||
header_name, S_ISDIR(statbuf->st_mode));
|
header_name, S_ISDIR(statbuf->st_mode));
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
/* Now write the header out to disk */
|
chksum_and_xwrite_tar_header(tbInfo->tarFd, &header);
|
||||||
chksum_and_xwrite(tbInfo->tarFd, &header);
|
|
||||||
|
|
||||||
/* Now do the verbose thing (or not) */
|
/* Now do the verbose thing (or not) */
|
||||||
if (tbInfo->verboseFlag) {
|
if (tbInfo->verboseFlag) {
|
||||||
|
@ -167,6 +167,7 @@ typedef struct tar_header_t { /* byte offset */
|
|||||||
struct BUG_tar_header {
|
struct BUG_tar_header {
|
||||||
char c[sizeof(tar_header_t) == TAR_BLOCK_SIZE ? 1 : -1];
|
char c[sizeof(tar_header_t) == TAR_BLOCK_SIZE ? 1 : -1];
|
||||||
};
|
};
|
||||||
|
void chksum_and_xwrite_tar_header(int fd, struct tar_header_t *hp) FAST_FUNC;
|
||||||
|
|
||||||
|
|
||||||
extern const char cpio_TRAILER[];
|
extern const char cpio_TRAILER[];
|
||||||
|
@ -29,7 +29,6 @@ struct fileblock {
|
|||||||
static void writeheader(const char *path, struct stat *sb, int type)
|
static void writeheader(const char *path, struct stat *sb, int type)
|
||||||
{
|
{
|
||||||
struct tar_header_t header;
|
struct tar_header_t header;
|
||||||
int i, sum;
|
|
||||||
|
|
||||||
memset(&header, 0, TAR_BLOCK_SIZE);
|
memset(&header, 0, TAR_BLOCK_SIZE);
|
||||||
strcpy(header.name, path);
|
strcpy(header.name, path);
|
||||||
@ -40,20 +39,7 @@ static void writeheader(const char *path, struct stat *sb, int type)
|
|||||||
sprintf(header.size, "%o", (unsigned)sb->st_size);
|
sprintf(header.size, "%o", (unsigned)sb->st_size);
|
||||||
sprintf(header.mtime, "%llo", sb->st_mtime & 077777777777LL);
|
sprintf(header.mtime, "%llo", sb->st_mtime & 077777777777LL);
|
||||||
header.typeflag = type;
|
header.typeflag = type;
|
||||||
strcpy(header.magic, "ustar "); /* like GNU tar */
|
chksum_and_xwrite_tar_header(STDOUT_FILENO, &header);
|
||||||
|
|
||||||
/* Calculate and store the checksum (the sum of all of the bytes of
|
|
||||||
* the header). The checksum field must be filled with blanks for the
|
|
||||||
* calculation. The checksum field is formatted differently from the
|
|
||||||
* other fields: it has 6 digits, a NUL, then a space -- rather than
|
|
||||||
* digits, followed by a NUL like the other fields... */
|
|
||||||
header.chksum[7] = ' ';
|
|
||||||
sum = ' ' * 7;
|
|
||||||
for (i = 0; i < TAR_BLOCK_SIZE; i++)
|
|
||||||
sum += ((unsigned char*)&header)[i];
|
|
||||||
sprintf(header.chksum, "%06o", sum);
|
|
||||||
|
|
||||||
xwrite(STDOUT_FILENO, &header, TAR_BLOCK_SIZE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void archivefile(const char *path)
|
static void archivefile(const char *path)
|
||||||
|
Loading…
Reference in New Issue
Block a user