summaryrefslogtreecommitdiff
path: root/archival/chksum_and_xwrite_tar_header.c
diff options
context:
space:
mode:
authorDenys Vlasenko2021-08-20 17:58:49 +0200
committerDenys Vlasenko2021-08-20 17:58:49 +0200
commit62d5a1e56f4022002c5c55e02d7d29e1e68bc236 (patch)
tree2712cc1241e294c23f77528d83448853e20f3ccc /archival/chksum_and_xwrite_tar_header.c
parent38e9c8c95b919e949b1cdd16f05b648a75983f57 (diff)
downloadbusybox-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.c35
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));
+}