Denys Vlasenko | 62d5a1e | 2021-08-20 17:58:49 +0200 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2021 Denys Vlasenko <vda.linux@googlemail.com> |
| 3 | * |
| 4 | * Licensed under GPLv2, see file LICENSE in this source tree. |
| 5 | */ |
| 6 | //kbuild:lib-$(CONFIG_FEATURE_TAR_CREATE) += chksum_and_xwrite_tar_header.o |
| 7 | //kbuild:lib-$(CONFIG_SMEMCAP) += chksum_and_xwrite_tar_header.o |
| 8 | |
| 9 | #include "libbb.h" |
| 10 | #include "bb_archive.h" |
| 11 | |
| 12 | void FAST_FUNC chksum_and_xwrite_tar_header(int fd, struct tar_header_t *hp) |
| 13 | { |
| 14 | /* POSIX says that checksum is done on unsigned bytes |
| 15 | * (Sun and HP-UX gets it wrong... more details in |
| 16 | * GNU tar source) */ |
| 17 | const unsigned char *cp; |
Ron Yorston | 922b58b | 2021-08-22 11:24:46 +0100 | [diff] [blame] | 18 | unsigned int chksum, size; |
Denys Vlasenko | 62d5a1e | 2021-08-20 17:58:49 +0200 | [diff] [blame] | 19 | |
| 20 | strcpy(hp->magic, "ustar "); |
| 21 | |
| 22 | /* Calculate and store the checksum (the sum of all of the bytes of |
| 23 | * the header). The checksum field must be filled with blanks for the |
| 24 | * calculation. The checksum field is formatted differently from the |
| 25 | * other fields: it has 6 digits, a NUL, then a space -- rather than |
| 26 | * digits, followed by a NUL like the other fields... */ |
| 27 | memset(hp->chksum, ' ', sizeof(hp->chksum)); |
| 28 | cp = (const unsigned char *) hp; |
| 29 | chksum = 0; |
| 30 | size = sizeof(*hp); |
| 31 | do { chksum += *cp++; } while (--size); |
| 32 | sprintf(hp->chksum, "%06o", chksum); |
| 33 | |
| 34 | xwrite(fd, hp, sizeof(*hp)); |
| 35 | } |