diff options
author | Ron Yorston <rmy@pobox.com> | 2021-08-22 09:17:10 +0100 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2021-08-22 09:17:10 +0100 |
commit | 46c5767e7e39d1e173e382bda86ab88b4cad354d (patch) | |
tree | d22c7f2376527aebd556eec36e115f037f8a467e /archival | |
parent | f13defb1c8f892ecf3e8dd5dbe486cc2b53e6f03 (diff) | |
parent | 74c4f356aee9c64978a881e5760055d0e3510a6a (diff) | |
download | busybox-w32-46c5767e7e39d1e173e382bda86ab88b4cad354d.tar.gz busybox-w32-46c5767e7e39d1e173e382bda86ab88b4cad354d.tar.bz2 busybox-w32-46c5767e7e39d1e173e382bda86ab88b4cad354d.zip |
Merge branch 'busybox' into merge
Diffstat (limited to 'archival')
-rw-r--r-- | archival/chksum_and_xwrite_tar_header.c | 35 | ||||
-rw-r--r-- | archival/tar.c | 31 |
2 files changed, 37 insertions, 29 deletions
diff --git a/archival/chksum_and_xwrite_tar_header.c b/archival/chksum_and_xwrite_tar_header.c new file mode 100644 index 000000000..25934f898 --- /dev/null +++ b/archival/chksum_and_xwrite_tar_header.c | |||
@@ -0,0 +1,35 @@ | |||
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; | ||
18 | int chksum, size; | ||
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 | } | ||
diff --git a/archival/tar.c b/archival/tar.c index 67c90e6fd..054640c01 100644 --- a/archival/tar.c +++ b/archival/tar.c | |||
@@ -256,32 +256,6 @@ static void putOctal(char *cp, int len, off_t value) | |||
256 | } | 256 | } |
257 | #define PUT_OCTAL(a, b) putOctal((a), sizeof(a), (b)) | 257 | #define PUT_OCTAL(a, b) putOctal((a), sizeof(a), (b)) |
258 | 258 | ||
259 | static void chksum_and_xwrite(int fd, struct tar_header_t* hp) | ||
260 | { | ||
261 | /* POSIX says that checksum is done on unsigned bytes | ||
262 | * (Sun and HP-UX gets it wrong... more details in | ||
263 | * GNU tar source) */ | ||
264 | const unsigned char *cp; | ||
265 | int chksum, size; | ||
266 | |||
267 | strcpy(hp->magic, "ustar "); | ||
268 | |||
269 | /* Calculate and store the checksum (i.e., the sum of all of the bytes of | ||
270 | * the header). The checksum field must be filled with blanks for the | ||
271 | * calculation. The checksum field is formatted differently from the | ||
272 | * other fields: it has 6 digits, a null, then a space -- rather than | ||
273 | * digits, followed by a null like the other fields... */ | ||
274 | memset(hp->chksum, ' ', sizeof(hp->chksum)); | ||
275 | cp = (const unsigned char *) hp; | ||
276 | chksum = 0; | ||
277 | size = sizeof(*hp); | ||
278 | do { chksum += *cp++; } while (--size); | ||
279 | putOctal(hp->chksum, sizeof(hp->chksum)-1, chksum); | ||
280 | |||
281 | /* Now write the header out to disk */ | ||
282 | xwrite(fd, hp, sizeof(*hp)); | ||
283 | } | ||
284 | |||
285 | # if ENABLE_FEATURE_TAR_GNU_EXTENSIONS | 259 | # if ENABLE_FEATURE_TAR_GNU_EXTENSIONS |
286 | static void writeLongname(int fd, int type, const char *name, int dir) | 260 | static void writeLongname(int fd, int type, const char *name, int dir) |
287 | { | 261 | { |
@@ -312,7 +286,7 @@ static void writeLongname(int fd, int type, const char *name, int dir) | |||
312 | /* + dir: account for possible '/' */ | 286 | /* + dir: account for possible '/' */ |
313 | 287 | ||
314 | PUT_OCTAL(header.size, size); | 288 | PUT_OCTAL(header.size, size); |
315 | chksum_and_xwrite(fd, &header); | 289 | chksum_and_xwrite_tar_header(fd, &header); |
316 | 290 | ||
317 | /* Write filename[/] and pad the block. */ | 291 | /* Write filename[/] and pad the block. */ |
318 | /* dir=0: writes 'name<NUL>', pads */ | 292 | /* dir=0: writes 'name<NUL>', pads */ |
@@ -443,8 +417,7 @@ static int writeTarHeader(struct TarBallInfo *tbInfo, | |||
443 | header_name, S_ISDIR(statbuf->st_mode)); | 417 | header_name, S_ISDIR(statbuf->st_mode)); |
444 | # endif | 418 | # endif |
445 | 419 | ||
446 | /* Now write the header out to disk */ | 420 | chksum_and_xwrite_tar_header(tbInfo->tarFd, &header); |
447 | chksum_and_xwrite(tbInfo->tarFd, &header); | ||
448 | 421 | ||
449 | /* Now do the verbose thing (or not) */ | 422 | /* Now do the verbose thing (or not) */ |
450 | if (tbInfo->verboseFlag) { | 423 | if (tbInfo->verboseFlag) { |