blob: f2d46b9ef010abaf0c2e2fda8b9a9ab0f4cd94a1 [file] [log] [blame]
Denys Vlasenko62d5a1e2021-08-20 17:58:49 +02001/*
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
12void 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 Yorston922b58b2021-08-22 11:24:46 +010018 unsigned int chksum, size;
Denys Vlasenko62d5a1e2021-08-20 17:58:49 +020019
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}