diff --git a/bscommon.h b/bscommon.h new file mode 100644 index 0000000..30bd7f7 --- /dev/null +++ b/bscommon.h @@ -0,0 +1,15 @@ +#ifndef BS_COMMON_H +#define BS_COMMON_H + +# include + +#define HEADER_TXT ("ENDSLEY/BSDIFF44") +typedef struct BSHeader{ + char header_txt[sizeof(HEADER_TXT)]; + uint8_t new_size[8]; + uint8_t old_size[8]; + uint8_t new_chksum[2]; + uint8_t old_chksum[2]; +}BSHeader; + +#endif \ No newline at end of file diff --git a/bsdiff.c b/bsdiff.c index 628f1c1..ef09274 100644 --- a/bsdiff.c +++ b/bsdiff.c @@ -26,15 +26,18 @@ */ #include "bsdiff.h" - +#include "bscommon.h" #include #include #define MIN(x,y) (((x)<(y)) ? (x) : (y)) +#define MEDIAN3(a,b,c) (((a)<(b)) ? \ + ((b)<(c) ? (b) : ((a)<(c) ? (c) : (a))) : \ + ((b)>(c) ? (b) : ((a)>(c) ? (c) : (a)))) static void split(int64_t *I,int64_t *V,int64_t start,int64_t len,int64_t h) { - int64_t i,j,k,x,tmp,jj,kk; + int64_t i,j,k,x,y,z,tmp,jj,kk; if(len<16) { for(k=start;k40) { /* Big array: Pseudomedian of 9 */ + tmp=len/8; + x=MEDIAN3(x,V[I[j-tmp]+h],V[I[j+tmp]+h]); + y=MEDIAN3(y,V[I[start+tmp]+h],V[I[start+tmp+tmp]+h]); + z=MEDIAN3(z,V[I[k-tmp]+h],V[I[k-tmp-tmp]+h]); + }; /* Else medium array: Pseudomedian of 3 */ + x=MEDIAN3(x,y,z); + jj=0;kk=0; for(i=start;iopaque ); + if ( bytes_wrote != size) + return -1; + + return 0; +} + int main(int argc,char *argv[]) { + int use_bz2 = 0; /* Should wwe use bz2 or not ? */ int fd; int bz2err; uint8_t *old,*new; off_t oldsize,newsize; - uint8_t buf[8]; + off_t oldchksum, newchksum; + BSHeader header; FILE * pf; struct bsdiff_stream stream; BZFILE* bz2; @@ -387,8 +415,10 @@ int main(int argc,char *argv[]) memset(&bz2, 0, sizeof(bz2)); stream.malloc = malloc; stream.free = free; - stream.write = bz2_write; - + if(use_bz2) + stream.write = bz2_write; + else + stream.write = raw_write; if(argc!=4) errx(1,"usage: %s oldfile newfile patchfile\n",argv[0]); /* Allocate oldsize+1 bytes instead of oldsize bytes to ensure @@ -414,23 +444,36 @@ int main(int argc,char *argv[]) if ((pf = fopen(argv[3], "w")) == NULL) err(1, "%s", argv[3]); - /* Write header (signature+newsize)*/ - offtout(newsize, buf); - if (fwrite("ENDSLEY/BSDIFF43", 16, 1, pf) != 1 || - fwrite(buf, sizeof(buf), 1, pf) != 1) - err(1, "Failed to write header"); + /* Write header (signature+newsize) */ + strncpy(header.header_txt,HEADER_TXT, sizeof(header.header_txt)); + offtout(newsize, header.new_size); + offtout(oldsize, header.old_size); + /* TODO Write out checksums */ + offtout(newchksum, header.new_chksum); + offtout(oldchksum, header.old_chksum); + if( fwrite(&header,sizeof(header),1,pf) != 1) + err(1, "Failed to write header"); - if (NULL == (bz2 = BZ2_bzWriteOpen(&bz2err, pf, 9, 0, 0))) - errx(1, "BZ2_bzWriteOpen, bz2err=%d", bz2err); + if(use_bz2) + { + if (NULL == (bz2 = BZ2_bzWriteOpen(&bz2err, pf, 9, 0, 0))) + errx(1, "BZ2_bzWriteOpen, bz2err=%d", bz2err); + stream.opaque = bz2; + } + else{ + stream.opaque = pf; + } - stream.opaque = bz2; if (bsdiff(old, oldsize, new, newsize, &stream)) err(1, "bsdiff"); - BZ2_bzWriteClose(&bz2err, bz2, 0, NULL, NULL); - if (bz2err != BZ_OK) - err(1, "BZ2_bzWriteClose, bz2err=%d", bz2err); + if(use_bz2) + { + BZ2_bzWriteClose(&bz2err, bz2, 0, NULL, NULL); + if (bz2err != BZ_OK) + err(1, "BZ2_bzWriteClose, bz2err=%d", bz2err); + } if (fclose(pf)) err(1, "fclose"); diff --git a/bspatch.c b/bspatch.c index b544914..fb30c5d 100644 --- a/bspatch.c +++ b/bspatch.c @@ -106,7 +106,7 @@ int bspatch(const uint8_t* old, int64_t oldsize, uint8_t* new, int64_t newsize, #include #include #include - +#include "bscommon.h" static int bz2_read(const struct bspatch_stream* stream, void* buffer, int length) { int n; @@ -121,12 +121,26 @@ static int bz2_read(const struct bspatch_stream* stream, void* buffer, int lengt return 0; } +static int raw_read(const struct bspatch_stream* stream, void* buffer, int length) +{ + int n; + int bz2err; + BZFILE* bz2; + size_t bytes_read = fread ( buffer, 1, length, (FILE *) stream->opaque ); + + if (bytes_read != length) + return -1; + + return 0; +} + int main(int argc,char * argv[]) { + int use_bz2 = 0; FILE * f; int fd; int bz2err; - uint8_t header[24]; + BSHeader header; uint8_t *old, *new; int64_t oldsize, newsize; BZFILE* bz2; @@ -140,20 +154,23 @@ int main(int argc,char * argv[]) err(1, "fopen(%s)", argv[3]); /* Read header */ - if (fread(header, 1, 24, f) != 24) { + if (fread(&header, sizeof(header), 1 , f) != 1) { if (feof(f)) errx(1, "Corrupt patch\n"); err(1, "fread(%s)", argv[3]); } /* Check for appropriate magic */ - if (memcmp(header, "ENDSLEY/BSDIFF43", 16) != 0) + if (memcmp(header.header_txt, HEADER_TXT, sizeof(HEADER_TXT)) != 0) errx(1, "Corrupt patch\n"); /* Read lengths from header */ - newsize=offtin(header+16); + newsize=offtin(header.new_size); if(newsize<0) errx(1,"Corrupt patch\n"); + int oldsize_in = offtin(header.old_size); + if(oldsize_in != oldsize) + errx(1,"Corrupt patch Header oldsize %d != file %lld\n",oldsize_in, oldsize); /* Close patch file and re-open it via libbzip2 at the right places */ if(((fd=open(argv[1],O_RDONLY,0))<0) || @@ -165,16 +182,28 @@ int main(int argc,char * argv[]) (close(fd)==-1)) err(1,"%s",argv[1]); if((new=malloc(newsize+1))==NULL) err(1,NULL); - if (NULL == (bz2 = BZ2_bzReadOpen(&bz2err, f, 0, 0, NULL, 0))) - errx(1, "BZ2_bzReadOpen, bz2err=%d", bz2err); + if(use_bz2) + { + if (NULL == (bz2 = BZ2_bzReadOpen(&bz2err, f, 0, 0, NULL, 0))) + errx(1, "BZ2_bzReadOpen, bz2err=%d", bz2err); + stream.read = bz2_read; + stream.opaque = bz2; + + } + else{ + stream.read = raw_read; + stream.opaque = f; + + } - stream.read = bz2_read; - stream.opaque = bz2; if (bspatch(old, oldsize, new, newsize, &stream)) errx(1, "bspatch"); - /* Clean up the bzip2 reads */ - BZ2_bzReadClose(&bz2err, bz2); + if(use_bz2) + { + /* Clean up the bzip2 reads */ + BZ2_bzReadClose(&bz2err, bz2); + } fclose(f); /* Write the new file */