Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use a header structure for reading / writing the header structure. #17

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions bscommon.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#ifndef BS_COMMON_H
#define BS_COMMON_H

# include <stdint.h>

#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
77 changes: 60 additions & 17 deletions bsdiff.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,18 @@
*/

#include "bsdiff.h"

#include "bscommon.h"
#include <limits.h>
#include <string.h>

#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;k<start+len;k+=j) {
Expand All @@ -55,7 +58,20 @@ static void split(int64_t *I,int64_t *V,int64_t start,int64_t len,int64_t h)
return;
};

x=V[I[start+len/2]+h];
/* Select pivot, algorithm by Bentley & McIlroy */
j=start+len/2;
k=start+len-1;
x=V[I[j]+h];
y=V[I[start]+h];
z=V[I[k]+h];
if(len>40) { /* 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;i<start+len;i++) {
if(V[I[i]+h]<x) jj++;
Expand Down Expand Up @@ -373,22 +389,36 @@ static int bz2_write(struct bsdiff_stream* stream, const void* buffer, int size)
return 0;
}

static int raw_write(struct bsdiff_stream* stream, const void* buffer, int size)
{
int bz2err;
int bytes_wrote = fwrite ( buffer, 1, size, (FILE*) stream->opaque );
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;

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
Expand All @@ -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");
Expand Down
51 changes: 40 additions & 11 deletions bspatch.c
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ int bspatch(const uint8_t* old, int64_t oldsize, uint8_t* new, int64_t newsize,
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>

#include "bscommon.h"
static int bz2_read(const struct bspatch_stream* stream, void* buffer, int length)
{
int n;
Expand All @@ -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;
Expand All @@ -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) ||
Expand All @@ -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 */
Expand Down