diff options
author | Denys Vlasenko | 2021-08-20 17:58:49 +0200 |
---|---|---|
committer | Denys Vlasenko | 2021-08-20 17:58:49 +0200 |
commit | 62d5a1e56f4022002c5c55e02d7d29e1e68bc236 (patch) | |
tree | 2712cc1241e294c23f77528d83448853e20f3ccc /archival/chksum_and_xwrite_tar_header.c | |
parent | 38e9c8c95b919e949b1cdd16f05b648a75983f57 (diff) | |
download | busybox-62d5a1e56f4022002c5c55e02d7d29e1e68bc236.zip busybox-62d5a1e56f4022002c5c55e02d7d29e1e68bc236.tar.gz |
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>
Diffstat (limited to 'archival/chksum_and_xwrite_tar_header.c')
-rw-r--r-- | archival/chksum_and_xwrite_tar_header.c | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/archival/chksum_and_xwrite_tar_header.c b/archival/chksum_and_xwrite_tar_header.c new file mode 100644 index 0000000..25934f8 --- /dev/null +++ b/archival/chksum_and_xwrite_tar_header.c @@ -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)); +} |