diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2021-08-20 17:58:49 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2021-08-20 17:58:49 +0200 |
commit | 62d5a1e56f4022002c5c55e02d7d29e1e68bc236 (patch) | |
tree | 2712cc1241e294c23f77528d83448853e20f3ccc | |
parent | 38e9c8c95b919e949b1cdd16f05b648a75983f57 (diff) | |
download | busybox-w32-62d5a1e56f4022002c5c55e02d7d29e1e68bc236.tar.gz busybox-w32-62d5a1e56f4022002c5c55e02d7d29e1e68bc236.tar.bz2 busybox-w32-62d5a1e56f4022002c5c55e02d7d29e1e68bc236.zip |
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>
-rw-r--r-- | archival/chksum_and_xwrite_tar_header.c | 35 | ||||
-rw-r--r-- | archival/tar.c | 31 | ||||
-rw-r--r-- | include/bb_archive.h | 1 | ||||
-rw-r--r-- | procps/smemcap.c | 16 |
4 files changed, 39 insertions, 44 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 94fb61a29..9de37592e 100644 --- a/archival/tar.c +++ b/archival/tar.c | |||
@@ -254,32 +254,6 @@ static void putOctal(char *cp, int len, off_t value) | |||
254 | } | 254 | } |
255 | #define PUT_OCTAL(a, b) putOctal((a), sizeof(a), (b)) | 255 | #define PUT_OCTAL(a, b) putOctal((a), sizeof(a), (b)) |
256 | 256 | ||
257 | static void chksum_and_xwrite(int fd, struct tar_header_t* hp) | ||
258 | { | ||
259 | /* POSIX says that checksum is done on unsigned bytes | ||
260 | * (Sun and HP-UX gets it wrong... more details in | ||
261 | * GNU tar source) */ | ||
262 | const unsigned char *cp; | ||
263 | int chksum, size; | ||
264 | |||
265 | strcpy(hp->magic, "ustar "); | ||
266 | |||
267 | /* Calculate and store the checksum (i.e., the sum of all of the bytes of | ||
268 | * the header). The checksum field must be filled with blanks for the | ||
269 | * calculation. The checksum field is formatted differently from the | ||
270 | * other fields: it has 6 digits, a null, then a space -- rather than | ||
271 | * digits, followed by a null like the other fields... */ | ||
272 | memset(hp->chksum, ' ', sizeof(hp->chksum)); | ||
273 | cp = (const unsigned char *) hp; | ||
274 | chksum = 0; | ||
275 | size = sizeof(*hp); | ||
276 | do { chksum += *cp++; } while (--size); | ||
277 | putOctal(hp->chksum, sizeof(hp->chksum)-1, chksum); | ||
278 | |||
279 | /* Now write the header out to disk */ | ||
280 | xwrite(fd, hp, sizeof(*hp)); | ||
281 | } | ||
282 | |||
283 | # if ENABLE_FEATURE_TAR_GNU_EXTENSIONS | 257 | # if ENABLE_FEATURE_TAR_GNU_EXTENSIONS |
284 | static void writeLongname(int fd, int type, const char *name, int dir) | 258 | static void writeLongname(int fd, int type, const char *name, int dir) |
285 | { | 259 | { |
@@ -310,7 +284,7 @@ static void writeLongname(int fd, int type, const char *name, int dir) | |||
310 | /* + dir: account for possible '/' */ | 284 | /* + dir: account for possible '/' */ |
311 | 285 | ||
312 | PUT_OCTAL(header.size, size); | 286 | PUT_OCTAL(header.size, size); |
313 | chksum_and_xwrite(fd, &header); | 287 | chksum_and_xwrite_tar_header(fd, &header); |
314 | 288 | ||
315 | /* Write filename[/] and pad the block. */ | 289 | /* Write filename[/] and pad the block. */ |
316 | /* dir=0: writes 'name<NUL>', pads */ | 290 | /* dir=0: writes 'name<NUL>', pads */ |
@@ -441,8 +415,7 @@ static int writeTarHeader(struct TarBallInfo *tbInfo, | |||
441 | header_name, S_ISDIR(statbuf->st_mode)); | 415 | header_name, S_ISDIR(statbuf->st_mode)); |
442 | # endif | 416 | # endif |
443 | 417 | ||
444 | /* Now write the header out to disk */ | 418 | chksum_and_xwrite_tar_header(tbInfo->tarFd, &header); |
445 | chksum_and_xwrite(tbInfo->tarFd, &header); | ||
446 | 419 | ||
447 | /* Now do the verbose thing (or not) */ | 420 | /* Now do the verbose thing (or not) */ |
448 | if (tbInfo->verboseFlag) { | 421 | if (tbInfo->verboseFlag) { |
diff --git a/include/bb_archive.h b/include/bb_archive.h index 9b1db5b3e..dc5e55f0a 100644 --- a/include/bb_archive.h +++ b/include/bb_archive.h | |||
@@ -167,6 +167,7 @@ typedef struct tar_header_t { /* byte offset */ | |||
167 | struct BUG_tar_header { | 167 | struct BUG_tar_header { |
168 | char c[sizeof(tar_header_t) == TAR_BLOCK_SIZE ? 1 : -1]; | 168 | char c[sizeof(tar_header_t) == TAR_BLOCK_SIZE ? 1 : -1]; |
169 | }; | 169 | }; |
170 | void chksum_and_xwrite_tar_header(int fd, struct tar_header_t *hp) FAST_FUNC; | ||
170 | 171 | ||
171 | 172 | ||
172 | extern const char cpio_TRAILER[]; | 173 | extern const char cpio_TRAILER[]; |
diff --git a/procps/smemcap.c b/procps/smemcap.c index 2f8ab192e..2f1897dae 100644 --- a/procps/smemcap.c +++ b/procps/smemcap.c | |||
@@ -29,7 +29,6 @@ struct fileblock { | |||
29 | static void writeheader(const char *path, struct stat *sb, int type) | 29 | static void writeheader(const char *path, struct stat *sb, int type) |
30 | { | 30 | { |
31 | struct tar_header_t header; | 31 | struct tar_header_t header; |
32 | int i, sum; | ||
33 | 32 | ||
34 | memset(&header, 0, TAR_BLOCK_SIZE); | 33 | memset(&header, 0, TAR_BLOCK_SIZE); |
35 | strcpy(header.name, path); | 34 | strcpy(header.name, path); |
@@ -40,20 +39,7 @@ static void writeheader(const char *path, struct stat *sb, int type) | |||
40 | sprintf(header.size, "%o", (unsigned)sb->st_size); | 39 | sprintf(header.size, "%o", (unsigned)sb->st_size); |
41 | sprintf(header.mtime, "%llo", sb->st_mtime & 077777777777LL); | 40 | sprintf(header.mtime, "%llo", sb->st_mtime & 077777777777LL); |
42 | header.typeflag = type; | 41 | header.typeflag = type; |
43 | strcpy(header.magic, "ustar "); /* like GNU tar */ | 42 | chksum_and_xwrite_tar_header(STDOUT_FILENO, &header); |
44 | |||
45 | /* Calculate and store the checksum (the sum of all of the bytes of | ||
46 | * the header). The checksum field must be filled with blanks for the | ||
47 | * calculation. The checksum field is formatted differently from the | ||
48 | * other fields: it has 6 digits, a NUL, then a space -- rather than | ||
49 | * digits, followed by a NUL like the other fields... */ | ||
50 | header.chksum[7] = ' '; | ||
51 | sum = ' ' * 7; | ||
52 | for (i = 0; i < TAR_BLOCK_SIZE; i++) | ||
53 | sum += ((unsigned char*)&header)[i]; | ||
54 | sprintf(header.chksum, "%06o", sum); | ||
55 | |||
56 | xwrite(STDOUT_FILENO, &header, TAR_BLOCK_SIZE); | ||
57 | } | 43 | } |
58 | 44 | ||
59 | static void archivefile(const char *path) | 45 | static void archivefile(const char *path) |