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>
This commit is contained in:
		
							
								
								
									
										35
									
								
								archival/chksum_and_xwrite_tar_header.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								archival/chksum_and_xwrite_tar_header.c
									
									
									
									
									
										Normal file
									
								
							| @@ -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)); | ||||
| } | ||||
| @@ -254,32 +254,6 @@ static void putOctal(char *cp, int len, off_t value) | ||||
| } | ||||
| #define PUT_OCTAL(a, b) putOctal((a), sizeof(a), (b)) | ||||
|  | ||||
| static void chksum_and_xwrite(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 (i.e., 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 null, then a space -- rather than | ||||
| 	 * digits, followed by a null 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); | ||||
| 	putOctal(hp->chksum, sizeof(hp->chksum)-1, chksum); | ||||
|  | ||||
| 	/* Now write the header out to disk */ | ||||
| 	xwrite(fd, hp, sizeof(*hp)); | ||||
| } | ||||
|  | ||||
| # if ENABLE_FEATURE_TAR_GNU_EXTENSIONS | ||||
| static void writeLongname(int fd, int type, const char *name, int dir) | ||||
| { | ||||
| @@ -310,7 +284,7 @@ static void writeLongname(int fd, int type, const char *name, int dir) | ||||
| 	/* + dir: account for possible '/' */ | ||||
|  | ||||
| 	PUT_OCTAL(header.size, size); | ||||
| 	chksum_and_xwrite(fd, &header); | ||||
| 	chksum_and_xwrite_tar_header(fd, &header); | ||||
|  | ||||
| 	/* Write filename[/] and pad the block. */ | ||||
| 	/* dir=0: writes 'name<NUL>', pads */ | ||||
| @@ -441,8 +415,7 @@ static int writeTarHeader(struct TarBallInfo *tbInfo, | ||||
| 				header_name, S_ISDIR(statbuf->st_mode)); | ||||
| # endif | ||||
|  | ||||
| 	/* Now write the header out to disk */ | ||||
| 	chksum_and_xwrite(tbInfo->tarFd, &header); | ||||
| 	chksum_and_xwrite_tar_header(tbInfo->tarFd, &header); | ||||
|  | ||||
| 	/* Now do the verbose thing (or not) */ | ||||
| 	if (tbInfo->verboseFlag) { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user