1From 60babcd97b871c8f037b426beb57f21d20d57a9e Mon Sep 17 00:00:00 2001 2From: Shunqian Zheng <zhengsq@rock-chips.com> 3Date: Thu, 6 Jan 2022 15:06:44 +0800 4Subject: [PATCH] bspatch: adaption to embedded system 5 6Use mmap to avoid large memory allocation. 7Support read old file from block device(e.g. /dev/mmcblkMpN), which 8requires an extra old-file-size argument. 9 10Signed-off-by: Shunqian Zheng <zhengsq@rock-chips.com> 11--- 12 bspatch.c | 50 +++++++++++++++++++++++++++++++++++--------------- 13 1 file changed, 35 insertions(+), 15 deletions(-) 14 15diff --git a/bspatch.c b/bspatch.c 16index de47d2a..0c6952c 100644 17--- a/bspatch.c 18+++ b/bspatch.c 19@@ -36,6 +36,8 @@ __FBSDID("$FreeBSD: src/usr.bin/bsdiff/bspatch/bspatch.c,v 1.1 2005/08/06 01:59: 20 #include <unistd.h> 21 #include <fcntl.h> 22 #include <sys/types.h> 23+#include <sys/mman.h> 24+#include <sys/stat.h> 25 26 static off_t offtin(u_char *buf) 27 { 28@@ -69,8 +71,25 @@ int main(int argc,char * argv[]) 29 off_t ctrl[3]; 30 off_t lenread; 31 off_t i; 32- 33- if(argc!=4) errx(1,"usage: %s oldfile newfile patchfile\n",argv[0]); 34+ struct stat old_stat; 35+ 36+ if(argc!=4 && argc!=5) errx(1,"usage: %s oldfile newfile patchfile\n" 37+ " or\n" 38+ " %s /dev/mmcblkMpN newfile patchfile oldsize\n", argv[0]); 39+ 40+ oldsize = 0; 41+ stat(argv[1], &old_stat); 42+ if (old_stat.st_mode & S_IFBLK && argc == 5) { 43+ oldsize = atoi(argv[4]); 44+ } else if (old_stat.st_mode & S_IFREG && argc == 4) { 45+ if(((fd=open(argv[1],O_RDONLY,0))<0) || 46+ ((oldsize=lseek(fd,0,SEEK_END))<=0) || 47+ (close(fd)==-1)) 48+ err(1,"file %s size err!",argv[1]); 49+ } else { 50+ errx(1, "oldfile shall be regular file or block device,\n" 51+ " for block device, the oldfile_size arg is needed\n"); 52+ } 53 54 /* Open patch file */ 55 if ((f = fopen(argv[3], "r")) == NULL) 56@@ -105,7 +124,7 @@ int main(int argc,char * argv[]) 57 bzctrllen=offtin(header+8); 58 bzdatalen=offtin(header+16); 59 newsize=offtin(header+24); 60- if((bzctrllen<0) || (bzdatalen<0) || (newsize<0)) 61+ if((bzctrllen<0) || (bzdatalen<0) || (newsize<=0)) 62 errx(1,"Corrupt patch\n"); 63 64 /* Close patch file and re-open it via libbzip2 at the right places */ 65@@ -133,13 +152,19 @@ int main(int argc,char * argv[]) 66 if ((epfbz2 = BZ2_bzReadOpen(&ebz2err, epf, 0, 0, NULL, 0)) == NULL) 67 errx(1, "BZ2_bzReadOpen, bz2err = %d", ebz2err); 68 69+ //if oldfile is a block device, get oldsize from arg 70 if(((fd=open(argv[1],O_RDONLY,0))<0) || 71- ((oldsize=lseek(fd,0,SEEK_END))==-1) || 72- ((old=malloc(oldsize+1))==NULL) || 73- (lseek(fd,0,SEEK_SET)!=0) || 74- (read(fd,old,oldsize)!=oldsize) || 75+ ((old=mmap(NULL,oldsize,PROT_READ,MAP_SHARED|MAP_POPULATE,fd,0))==MAP_FAILED) || 76 (close(fd)==-1)) err(1,"%s",argv[1]); 77- if((new=malloc(newsize+1))==NULL) err(1,NULL); 78+ 79+ /* mmap the new file */ 80+ if(((fd=open(argv[2],O_CREAT|O_TRUNC|O_RDWR,0666))<0) || 81+ (lseek(fd,newsize-1,SEEK_SET)!=(newsize-1)) || 82+ (write(fd, "E", 1) != 1) || 83+ (lseek(fd,0,SEEK_SET)!=0) || 84+ ((new=mmap(NULL,newsize,PROT_READ | PROT_WRITE,MAP_SHARED,fd,0))==MAP_FAILED) || 85+ (close(fd)==-1)) 86+ err(1,"%s",argv[2]); 87 88 oldpos=0;newpos=0; 89 while(newpos<newsize) { 90@@ -193,13 +218,8 @@ int main(int argc,char * argv[]) 91 if (fclose(cpf) || fclose(dpf) || fclose(epf)) 92 err(1, "fclose(%s)", argv[3]); 93 94- /* Write the new file */ 95- if(((fd=open(argv[2],O_CREAT|O_TRUNC|O_WRONLY,0666))<0) || 96- (write(fd,new,newsize)!=newsize) || (close(fd)==-1)) 97- err(1,"%s",argv[2]); 98- 99- free(new); 100- free(old); 101+ munmap(new, newsize); 102+ munmap(old, oldsize); 103 104 return 0; 105 } 106-- 1072.25.1 108 109