tar,smemcap: commonalyze checksumming code for tar header
No binary (build failed)
—
(log yok)
| @@ -0,0 +1,35 @@ | |
| + | /* |
| + | * Copyright (C) 2021 Denys Vlasenko <[email protected]> |
| + | * |
| + | * 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)) | |
| - | 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 | |
| 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 '/' */ | |
| PUT_OCTAL(header.size, size); | |
| - | chksum_and_xwrite(fd, &header); |
| + | chksum_and_xwrite_tar_header(fd, &header); |
| /* Write filename[/] and pad the block. */ | |
| /* dir=0: writes 'name<NUL>', pads */ | |
| @@ -441,8 +415,7 @@ static int writeTarHeader(struct TarBallInfo *tbInfo, | |
| header_name, S_ISDIR(statbuf->st_mode)); | |
| # endif | |
| - | /* Now write the header out to disk */ |
| - | chksum_and_xwrite(tbInfo->tarFd, &header); |
| + | chksum_and_xwrite_tar_header(tbInfo->tarFd, &header); |
| /* Now do the verbose thing (or not) */ | |
| if (tbInfo->verboseFlag) { | |
| @@ -167,6 +167,7 @@ typedef struct tar_header_t { /* byte offset */ | |
| struct BUG_tar_header { | |
| 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[]; | |
| @@ -29,7 +29,6 @@ struct fileblock { | |
| static void writeheader(const char *path, struct stat *sb, int type) | |
| { | |
| struct tar_header_t header; | |
| - | int i, sum; |
| memset(&header, 0, TAR_BLOCK_SIZE); | |
| 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.mtime, "%llo", sb->st_mtime & 077777777777LL); | |
| header.typeflag = type; | |
| - | strcpy(header.magic, "ustar "); /* like GNU tar */ |
| - | |
| - | /* 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); |
| + | chksum_and_xwrite_tar_header(STDOUT_FILENO, &header); |
| } | |
| static void archivefile(const char *path) | |