aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2021-08-20 17:58:49 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2021-08-20 17:58:49 +0200
commit62d5a1e56f4022002c5c55e02d7d29e1e68bc236 (patch)
tree2712cc1241e294c23f77528d83448853e20f3ccc
parent38e9c8c95b919e949b1cdd16f05b648a75983f57 (diff)
downloadbusybox-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.c35
-rw-r--r--archival/tar.c31
-rw-r--r--include/bb_archive.h1
-rw-r--r--procps/smemcap.c16
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
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;
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
257static 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
284static void writeLongname(int fd, int type, const char *name, int dir) 258static 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 */
167struct BUG_tar_header { 167struct 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};
170void chksum_and_xwrite_tar_header(int fd, struct tar_header_t *hp) FAST_FUNC;
170 171
171 172
172extern const char cpio_TRAILER[]; 173extern 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 {
29static void writeheader(const char *path, struct stat *sb, int type) 29static 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
59static void archivefile(const char *path) 45static void archivefile(const char *path)