예제 #1
0
파일: nile.c 프로젝트: Gottox/nile
int
nileDiff(FILE *oldfile, FILE *newfile, FILE *output, enum Options options) {
	int rv = 1;
	off_t oldoff = 0, newoff = 0, lastSkip = 0;
	size_t oldsize, newsize;
	char *olddata = NULL, *newdata = NULL, md5sum[MD5_DIGEST_LENGTH] = { 0 }, header[8];

	if((oldsize = mapfile(oldfile, &olddata)) == -1)
		rv = 1;
	else if((newsize = mapfile(newfile, &newdata)) == -1)
		rv = 1;

	fputs(MAGIC, output);

	// newfile: uncompress and build md5sum
	if((newfile = uncompress(newfile, output, options)) == NULL)
		goto diff_cleanup;
	buildhash(md5sum, newfile);
	fwrite(md5sum, sizeof(md5sum), 1, output);

	// oldfile: uncompress and build md5sum
	if((oldfile = uncompress(oldfile, NULL, options)) == NULL)
		goto diff_cleanup;
	buildhash(md5sum, oldfile);
	fwrite(md5sum, sizeof(md5sum), 1, output);

	// Building Diff
	for(oldoff = newoff = 0; oldoff < oldsize && newoff < newsize;) {
		if(lcs(olddata, &oldoff, oldsize, newdata, &newoff, newsize, &lastSkip, output)) break;
	}
	// write trailing diff
	offtout(lastSkip, header);
	fwrite(header, sizeof(header), 1, output);
	offtout(oldsize - oldoff, header);
	fwrite(header, sizeof(header), 1, output);
	offtout(newsize - newoff, header);
	fwrite(header, sizeof(header), 1, output);
	fwrite(&newdata[newoff], newsize - newoff, 1, output);

diff_cleanup:
	if(oldsize >= 0)
		munmap(olddata, oldsize);
	if(newsize >= 0)
		munmap(newdata, newsize);
	return rv;
}
예제 #2
0
/**
 * I have rewritten this function so it can be called from other places;
 * I have also rewritten it to not use a patch file but instead a passed
 * buffer; the bsdiff patch is already in memory.
 *
 * ryan, 7.2.09
 */
int bsdiff_create_patch(char *patchFile, char *oldFile, char *newFile)
{
	FILE* fd = NULL;
	BZFILE * bz = NULL;
	u_char *old,*pnew;
	off_t oldsize,newsize;
	off_t *I,*V;

	off_t scan,pos,len;
	off_t lastscan,lastpos,lastoffset;
	off_t oldscore,scsc;

	off_t s,Sf,lenf,Sb,lenb;
	off_t overlap,Ss,lens;
	off_t i;

	off_t dblen,eblen;
	u_char *db,*eb;

	u_char buf[8];
	u_char header[32];

	int bzerror;

	/*if(argc!=4) err(1,"usage: %s oldfile newfile patchfile\n",argv[0]);*/

	/* Allocate oldsize+1 bytes instead of oldsize bytes to ensure
		that we never try to malloc(0) and get a NULL pointer */
	if(((fd = fopen(oldFile, "rb")) <= 0) ||
		(fseek(fd, 0, SEEK_END) != 0) ||
		((oldsize = ftell(fd)) == 0) ||
		((old = (u_char *) malloc(oldsize + 1)) == NULL) ||
		(fseek(fd, 0, SEEK_SET) != 0) ||
		(fread(old,1, oldsize, fd) != oldsize) ||
		(fclose(fd) == -1)) err(1, "%s", oldFile);

	if(((I = (off_t*) malloc((oldsize + 1) * sizeof(off_t))) == NULL) ||
		((V = (off_t*) malloc((oldsize + 1) * sizeof(off_t))) == NULL)) err(1, NULL);

	qsufsort(I, V, old, oldsize);

	free(V);

	/* Allocate newsize+1 bytes instead of newsize bytes to ensure
		that we never try to malloc(0) and get a NULL pointer */
	if(((fd = fopen(newFile, "rb")) < 0) ||
		(fseek(fd, 0, SEEK_END) != 0) ||
		((newsize = ftell(fd)) == 0) ||
		((pnew = (u_char *) malloc(newsize + 1)) == NULL) ||
		(fseek(fd, 0, SEEK_SET) != 0) ||
		(fread(pnew, 1, newsize, fd) != newsize) ||
		(fclose(fd) == -1)) err(1, "%s", newFile);

	if(((db=(u_char*)malloc(newsize+1))==NULL) ||
		((eb=(u_char*)malloc(newsize+1))==NULL)) err(1,NULL);
	dblen=0;
	eblen=0;

	fd = fopen(patchFile, "wb");
	if(fd == NULL)
		err(1,"%s",patchFile);

	/* Header is
		0	8	 "BSDIFF40"
		8	8	length of bzip2ed ctrl block
		16	8	length of bzip2ed diff block
		24	8	length of new file */
	/* File is
		0	32	Header
		32	??	Bzip2ed ctrl block
		??	??	Bzip2ed diff block
		??	??	Bzip2ed extra block */
	memcpy(header,"BSDIFF40",8);
	memset(header+8,0,24);
	if(fwrite(header,1,32,fd)!=32) err(1,"%s",patchFile);


	scan=0;len=0;
	lastscan=0;lastpos=0;lastoffset=0;

	bz = BZ2_bzWriteOpen ( &bzerror, fd, 
                         blockSize100k, 0, 30);
    if (bzerror != BZ_OK) err(1, "Problem bzWriteOpen");
    
	while(scan<newsize) {
		oldscore=0;

		for(scsc=scan+=len;scan<newsize;scan++) {
			len=search(I,old,oldsize,pnew+scan,newsize-scan,
					0,oldsize,&pos);

			for(;scsc<scan+len;scsc++)
			if((scsc+lastoffset<oldsize) &&
				(old[scsc+lastoffset] == pnew[scsc]))
				oldscore++;

			if(((len==oldscore) && (len!=0)) || 
				(len>oldscore+8)) break;

			if((scan+lastoffset<oldsize) &&
				(old[scan+lastoffset] == pnew[scan]))
				oldscore--;
		};

		if((len!=oldscore) || (scan==newsize)) {
			s=0;Sf=0;lenf=0;
			for(i=0;(lastscan+i<scan)&&(lastpos+i<oldsize);) {
				if(old[lastpos+i]==pnew[lastscan+i]) s++;
				i++;
				if(s*2-i>Sf*2-lenf) { Sf=s; lenf=i; };
			};

			lenb=0;
			if(scan<newsize) {
				s=0;Sb=0;
				for(i=1;(scan>=lastscan+i)&&(pos>=i);i++) {
					if(old[pos-i]==pnew[scan-i]) s++;
					if(s*2-i>Sb*2-lenb) { Sb=s; lenb=i; };
				};
			};

			if(lastscan+lenf>scan-lenb) {
				overlap=(lastscan+lenf)-(scan-lenb);
				s=0;Ss=0;lens=0;
				for(i=0;i<overlap;i++) {
					if(pnew[lastscan+lenf-overlap+i]==
					   old[lastpos+lenf-overlap+i]) s++;
					if(pnew[scan-lenb+i]==
					   old[pos-lenb+i]) s--;
					if(s>Ss) { Ss=s; lens=i+1; };
				};

				lenf+=lens-overlap;
				lenb-=lens;
			};

			for(i=0;i<lenf;i++)
				db[dblen+i]=pnew[lastscan+i]-old[lastpos+i];
			for(i=0;i<(scan-lenb)-(lastscan+lenf);i++)
				eb[eblen+i]=pnew[lastscan+lenf+i];

			dblen+=lenf;
			eblen+=(scan-lenb)-(lastscan+lenf);

			offtout(lenf,buf);
			if((8 != BZ2_bzwrite(bz,buf,8)) || (bzerror != BZ_OK)) err(1,"bzwrite");
			offtout((scan-lenb)-(lastscan+lenf),buf);
			if((8 != BZ2_bzwrite(bz,buf,8)) || (bzerror != BZ_OK)) err(1,"bzwrite");
			offtout((pos-lenb)-(lastpos+lenf),buf);
			if((8 != BZ2_bzwrite(bz,buf,8)) || (bzerror != BZ_OK)) err(1,"bzwrite");

			lastscan=scan-lenb;
			lastpos=pos-lenb;
			lastoffset=pos-scan;
		};
	};
	BZ2_bzWriteClose ( &bzerror, bz, 0, NULL, NULL);

	if((fseek(fd,0,SEEK_END))!=0 || ((len=ftell(fd))==-1)) err(1,"problem 0: %s",patchFile);
	offtout(len-32,buf);
	if((fseek(fd,8,SEEK_SET)!=0) || (ftell(fd) != 8) || (fwrite(buf,1,8,fd)!=8))
		err(1,"problem 1: %s",patchFile);
	offtout(newsize,buf);
	if((fseek(fd,24,SEEK_SET)!=0) || (ftell(fd) != 24)|| (fwrite(buf,1,8,fd)!=8))
		err(1,"problem 2:%s",patchFile);

	if(fseek(fd,0,SEEK_END)!=0) err(1,"problem 3: %s",patchFile);

	bz = BZ2_bzWriteOpen ( &bzerror, fd, 
                         blockSize100k, 0, 30);
    if (bzerror != BZ_OK) err(1, "Problem bzWriteOpen");
	if((dblen !=  BZ2_bzwrite(bz,db,dblen)) || (bzerror != BZ_OK)) 
	{
	    // printf("%s", BZ2_bzerror ( bz, &bzerror ));
       err(1,"bzwrite");
    }   
	BZ2_bzWriteClose ( &bzerror, bz, 0, NULL, NULL);



	if((fseek(fd,0,SEEK_END)!=0) || ((newsize=ftell(fd))==-1)) err(1,"problem 4: %s",patchFile);
	offtout(newsize-len,buf);
	if((fseek(fd,16,SEEK_SET)!=0) || (ftell(fd)!=16) || (fwrite(buf,1,8,fd)!=8))
		err(1,"problem 5:%s",patchFile);

	if(fseek(fd,0,SEEK_END)!=0 || (ftell(fd) == -1)) err(1,"problem 6: %s",patchFile);

	bz = BZ2_bzWriteOpen ( &bzerror, fd, 
                         blockSize100k, 0, 30);
    if (bzerror != BZ_OK) err(1, "Problem bzWriteOpen");
	if((eblen != BZ2_bzwrite(bz,eb,eblen)) || (bzerror != BZ_OK)) err(1,"bzwrite");
	BZ2_bzWriteClose ( &bzerror, bz, 0, NULL, NULL);
 	fclose(fd);
	free(db);
	free(eb);
	free(I);
	free(old);
	free(pnew);

	return 0;
}
예제 #3
0
int DIFF_main(int argc,char *argv[])
{
	int fd;
	u_char *old,*_new;
	off_t oldsize,newsize;
	off_t *I,*V;
	off_t scan,pos,len;
	off_t lastscan,lastpos,lastoffset;
	off_t oldscore,scsc;
	off_t s,Sf,lenf,Sb,lenb;
	off_t overlap,Ss,lens;
	off_t i;
	off_t dblen,eblen;
	u_char *db,*eb;
	u_char buf[8];
	u_char header[32];
	FILE * pf;
	BZFILE * pfbz2;
	int bz2err;

	int bytesWritten=0;

	if(argc!=4) errx(1,"usage: %s oldfile newfile patchfile\n",argv[0]);

	/* Allocate oldsize+1 bytes instead of oldsize bytes to ensure
	that we never try to malloc(0) and get a NULL pointer */
	if(((fd=open(argv[1],O_RDONLY|O_BINARY,0))<0) ||
		((oldsize=lseek(fd,0,SEEK_END))==-1) ||
		((old=(u_char*)malloc(oldsize+1))==NULL) ||
		(lseek(fd,0,SEEK_SET)!=0) ||
		(read(fd,old,oldsize)!=oldsize) ||
		(close(fd)==-1)) err(1,"%s",argv[1]);

	if(((I=(off_t*)malloc((oldsize+1)*sizeof(off_t)))==NULL) ||
		((V=(off_t*)malloc((oldsize+1)*sizeof(off_t)))==NULL)) err(1,NULL);

	qsufsort(I,V,old,oldsize);

	free(V);

	/* Allocate newsize+1 bytes instead of newsize bytes to ensure
	that we never try to malloc(0) and get a NULL pointer */
	if(((fd=open(argv[2],O_RDONLY|O_BINARY,0))<0) ||
		((newsize=lseek(fd,0,SEEK_END))==-1) ||
		((_new=(u_char*)malloc(newsize+1))==NULL) ||
		(lseek(fd,0,SEEK_SET)!=0) ||
		(read(fd,_new,newsize)!=newsize) ||
		(close(fd)==-1)) err(1,"%s",argv[2]);

	if(((db=(u_char*)malloc(newsize+1))==NULL) ||
		((eb=(u_char*)malloc(newsize+1))==NULL)) err(1,NULL);
	dblen=0;
	eblen=0;

	/* Create the patch file */
	if ((pf = fopen(argv[3], "wb")) == NULL)
		err(1, "%s", argv[3]);

	/* Header is
	0	8	 "BSDIFF40"
	8	8	length of bzip2ed ctrl block
	16	8	length of bzip2ed diff block
	24	8	length of new file */
	/* File is
	0	32	Header
	32	??	Bzip2ed ctrl block
	??	??	Bzip2ed diff block
	??	??	Bzip2ed extra block */
	memcpy(header,"BSDIFF40",8);
	offtout(0, header + 8);
	offtout(0, header + 16);
	offtout(newsize, header + 24);
	if (fwrite(header, 32, 1, pf) != 1)
		err(1, "fwrite(%s)", argv[3]);

	/* Compute the differences, writing ctrl as we go */
	if ((pfbz2 = BZ2_bzWriteOpen(&bz2err, pf, 9, 0, 0)) == NULL)
		errx(1, "BZ2_bzWriteOpen, bz2err = %d", bz2err);
	scan=0;len=0;
	lastscan=0;lastpos=0;lastoffset=0;
	while(scan<newsize) {
		oldscore=0;

		for(scsc=scan+=len;scan<newsize;scan++) {
			len=search(I,old,oldsize,_new+scan,newsize-scan,
				0,oldsize,&pos);

			for(;scsc<scan+len;scsc++)
				if((scsc+lastoffset<oldsize) &&
					(old[scsc+lastoffset] == _new[scsc]))
					oldscore++;

			if(((len==oldscore) && (len!=0)) || 
				(len>oldscore+8)) break;

			if((scan+lastoffset<oldsize) &&
				(old[scan+lastoffset] == _new[scan]))
				oldscore--;
		};

		if((len!=oldscore) || (scan==newsize)) {
			s=0;Sf=0;lenf=0;
			for(i=0;(lastscan+i<scan)&&(lastpos+i<oldsize);) {
				if(old[lastpos+i]==_new[lastscan+i]) s++;
				i++;
				if(s*2-i>Sf*2-lenf) { Sf=s; lenf=i; };
			};

			lenb=0;
			if(scan<newsize) {
				s=0;Sb=0;
				for(i=1;(scan>=lastscan+i)&&(pos>=i);i++) {
					if(old[pos-i]==_new[scan-i]) s++;
					if(s*2-i>Sb*2-lenb) { Sb=s; lenb=i; };
				};
			};

			if(lastscan+lenf>scan-lenb) {
				overlap=(lastscan+lenf)-(scan-lenb);
				s=0;Ss=0;lens=0;
				for(i=0;i<overlap;i++) {
					if(_new[lastscan+lenf-overlap+i]==
						old[lastpos+lenf-overlap+i]) s++;
					if(_new[scan-lenb+i]==
						old[pos-lenb+i]) s--;
					if(s>Ss) { Ss=s; lens=i+1; };
				};

				lenf+=lens-overlap;
				lenb-=lens;
			};

			for(i=0;i<lenf;i++)
				db[dblen+i]=_new[lastscan+i]-old[lastpos+i];
			for(i=0;i<(scan-lenb)-(lastscan+lenf);i++)
				eb[eblen+i]=_new[lastscan+lenf+i];

			dblen+=lenf;
			eblen+=(scan-lenb)-(lastscan+lenf);

			offtout(lenf,buf);
			BZ2_bzWrite(&bz2err, pfbz2, buf, 8);
			if (bz2err != BZ_OK)
				errx(1, "BZ2_bzWrite, bz2err = %d", bz2err);
			bytesWritten+=8;
		//	printf("bz2err 8 %i\n", bytesWritten);

			offtout((scan-lenb)-(lastscan+lenf),buf);
			BZ2_bzWrite(&bz2err, pfbz2, buf, 8);
			if (bz2err != BZ_OK)
				errx(1, "BZ2_bzWrite, bz2err = %d", bz2err);
			bytesWritten+=8;
		//	printf("bz2err 8 %i\n", bytesWritten);

			offtout((pos-lenb)-(lastpos+lenf),buf);
			BZ2_bzWrite(&bz2err, pfbz2, buf, 8);
			if (bz2err != BZ_OK)
				errx(1, "BZ2_bzWrite, bz2err = %d", bz2err);
			bytesWritten+=8;
		//	printf("bz2err 8 %i\n", bytesWritten);

			lastscan=scan-lenb;
			lastpos=pos-lenb;
			lastoffset=pos-scan;
		};
	};
	BZ2_bzWriteClose(&bz2err, pfbz2, 0, NULL, NULL);
	if (bz2err != BZ_OK)
		errx(1, "BZ2_bzWriteClose, bz2err = %d", bz2err);

	/* Compute size of compressed ctrl data */
	if ((len = ftello(pf)) == -1)
		err(1, "ftello");
	offtout(len-32, header + 8);

	/* Write compressed diff data */
	if ((pfbz2 = BZ2_bzWriteOpen(&bz2err, pf, 9, 0, 0)) == NULL)
		errx(1, "BZ2_bzWriteOpen, bz2err = %d", bz2err);
	BZ2_bzWrite(&bz2err, pfbz2, db, dblen);
	bytesWritten+=dblen;
//	printf("bz2err dblen %i %i\n", dblen, bytesWritten);
	if (bz2err != BZ_OK)
		errx(1, "BZ2_bzWrite, bz2err = %d", bz2err);
	BZ2_bzWriteClose(&bz2err, pfbz2, 0, NULL, NULL);
	if (bz2err != BZ_OK)
		errx(1, "BZ2_bzWriteClose, bz2err = %d", bz2err);

	/* Compute size of compressed diff data */
	if ((newsize = ftello(pf)) == -1)
		err(1, "ftello");
	offtout(newsize - len, header + 16);

	/* Write compressed extra data */
	if ((pfbz2 = BZ2_bzWriteOpen(&bz2err, pf, 9, 0, 0)) == NULL)
		errx(1, "BZ2_bzWriteOpen, bz2err = %d", bz2err);
	BZ2_bzWrite(&bz2err, pfbz2, eb, eblen);
	if (bz2err != BZ_OK)
		errx(1, "BZ2_bzWrite, bz2err = %d", bz2err);
	bytesWritten+=eblen;
	//printf("bz2err eblen %i %i\n", eblen, bytesWritten);
	BZ2_bzWriteClose(&bz2err, pfbz2, 0, NULL, NULL);
	if (bz2err != BZ_OK)
		errx(1, "BZ2_bzWriteClose, bz2err = %d", bz2err);

	// REMOVEME
//	if ((newsize = ftello(pf)) == -1)
//		err(1, "ftello");

	/* Seek to the beginning, write the header, and close the file */
	if (fseeko(pf, 0, SEEK_SET))
		err(1, "fseeko");
	if (fwrite(header, 32, 1, pf) != 1)
		err(1, "fwrite(%s)", argv[3]);
	if (fclose(pf))
		err(1, "fclose");

	/* Free the memory we used */
	free(db);
	free(eb);
	free(I);
	free(old);
	free(_new);

	return 0;
}
예제 #4
0
// This function modifies the main() function included in bsdiff.c of bsdiff-4.3 found at http://www.daemonology.net/bsdiff/
// It is changed to be a standalone function, to work entirely in memory, and to use my class MemoryCompressor as an interface to BZip
// Up to the caller to delete out
bool CreatePatch(const char *old, unsigned oldsize, char *_new, unsigned int newsize, char **out, unsigned *outSize)
{
//	int fd;
//	u_char *old,*new;
//	off_t oldsize,newsize;
	off_t *I,*V;
	off_t scan,pos,len;
	off_t lastscan,lastpos,lastoffset;
	off_t oldscore,scsc;
	off_t s,Sf,lenf,Sb,lenb;
	off_t overlap,Ss,lens;
	off_t i;
	off_t dblen,eblen;
	u_char *db,*eb;
	u_char buf[8];
	u_char header[32];
	MemoryCompressor patch;
//	unsigned outWriteOffset;
//	FILE * pf;
//	BZFILE * pfbz2;
//	int bz2err;


//	if(argc!=4) errx(1,"usage: %s oldfile newfile patchfile\n",argv[0]);

	/* Allocate oldsize+1 bytes instead of oldsize bytes to ensure
		that we never try to malloc(0) and get a NULL pointer */
	/*
	if(((fd=open(argv[1],O_RDONLY | _O_BINARY ,0))<0) ||
		((oldsize=lseek(fd,0,SEEK_END))==-1) ||
		((old=malloc(oldsize+1))==NULL) ||
		(lseek(fd,0,SEEK_SET)!=0) ||
		(read(fd,old,oldsize)!=oldsize) ||
		(close(fd)==-1)) err(1,"%s",argv[1]);
		*/

	if(((I=(off_t*)malloc((oldsize+1)*sizeof(off_t)))==NULL) ||
		((V=(off_t*)malloc((oldsize+1)*sizeof(off_t)))==NULL))
		// err(1,NULL);
			return false;

	qsufsort(I,V,(u_char*)old,oldsize);

	free(V);

	/* Allocate newsize+1 bytes instead of newsize bytes to ensure
		that we never try to malloc(0) and get a NULL pointer */
	/*
	if(((fd=open(argv[2],O_RDONLY | _O_BINARY ,0))<0) ||
		((newsize=lseek(fd,0,SEEK_END))==-1) ||
		((new=malloc(newsize+1))==NULL) ||
		(lseek(fd,0,SEEK_SET)!=0) ||
		(read(fd,new,newsize)!=newsize) ||
		(close(fd)==-1)) err(1,"%s",argv[2]);

		*/

	if(((db=(u_char*)malloc(newsize+1))==NULL) ||
		((eb=(u_char*)malloc(newsize+1))==NULL))
		// err(1,NULL);
		{
			free(I);
			return false;
		}

	dblen=0;
	eblen=0;

	/* Create the patch file */
//	if ((pf = fopen(argv[3], "wb")) == NULL)
//		err(1, "%s", argv[3]);

	/* Header is
		0	8	 "BSDIFF40"
		8	8	length of bzip2ed ctrl block
		16	8	length of bzip2ed diff block
		24	8	length of new file */
	/* File is
		0	32	Header
		32	??	Bzip2ed ctrl block
		??	??	Bzip2ed diff block
		??	??	Bzip2ed extra block */

	memcpy(header,"BSDIFF40",8);
	offtout(0, header + 8);
	offtout(0, header + 16);
	offtout(newsize, header + 24);
//	if (fwrite(header, 32, 1, pf) != 1)
//		err(1, "fwrite(%s)", argv[3]);

	// Allocate enough to hold any output
//	*out = (char*) malloc(oldsize+newsize);
	// Copy out the header
//	memcpy(*out, header, 32);
	//outWriteOffset=32;

	/* Compute the differences, writing ctrl as we go */
//	if ((pfbz2 = BZ2_bzWriteOpen(&bz2err, pf, 9, 0, 0)) == NULL)
//		errx(1, "BZ2_bzWriteOpen, bz2err = %d", bz2err);

	scan=0;len=0;
	lastscan=0;lastpos=0;lastoffset=0;
	while(scan<newsize) {
		oldscore=0;

		for(scsc=scan+=len;scan<newsize;scan++) {
			len=search(I,(u_char*)old,oldsize,(u_char*)_new+scan,newsize-scan,
					0,oldsize,&pos);

			for(;scsc<scan+len;scsc++)
			if((scsc+lastoffset<oldsize) &&
				(old[scsc+lastoffset] == _new[scsc]))
				oldscore++;

			if(((len==oldscore) && (len!=0)) || 
				(len>oldscore+8)) break;

			if((scan+lastoffset<oldsize) &&
				(old[scan+lastoffset] == _new[scan]))
				oldscore--;
		};

		if((len!=oldscore) || (scan==newsize)) {
			s=0;Sf=0;lenf=0;
			for(i=0;(lastscan+i<scan)&&(lastpos+i<oldsize);) {
				if(old[lastpos+i]==_new[lastscan+i]) s++;
				i++;
				if(s*2-i>Sf*2-lenf) { Sf=s; lenf=i; };
			};

			lenb=0;
			if(scan<newsize) {
				s=0;Sb=0;
				for(i=1;(scan>=lastscan+i)&&(pos>=i);i++) {
					if(old[pos-i]==_new[scan-i]) s++;
					if(s*2-i>Sb*2-lenb) { Sb=s; lenb=i; };
				};
			};

			if(lastscan+lenf>scan-lenb) {
				overlap=(lastscan+lenf)-(scan-lenb);
				s=0;Ss=0;lens=0;
				for(i=0;i<overlap;i++) {
					if(_new[lastscan+lenf-overlap+i]==
					   old[lastpos+lenf-overlap+i]) s++;
					if(_new[scan-lenb+i]==
					   old[pos-lenb+i]) s--;
					if(s>Ss) { Ss=s; lens=i+1; };
				};

				lenf+=lens-overlap;
				lenb-=lens;
			};

			for(i=0;i<lenf;i++)
				db[dblen+i]=_new[lastscan+i]-old[lastpos+i];
			for(i=0;i<(scan-lenb)-(lastscan+lenf);i++)
				eb[eblen+i]=_new[lastscan+lenf+i];

			dblen+=lenf;
			eblen+=(scan-lenb)-(lastscan+lenf);

			offtout(lenf,buf);
			if (patch.Compress((char*)buf, 8, false)==false)
			{
				free(db);
				free(eb);
				free(I);
				return false;
			}
			//BZ2_bzWrite(&bz2err, pfbz2, buf, 8);
			//if (bz2err != BZ_OK)
			//	errx(1, "BZ2_bzWrite, bz2err = %d", bz2err);

			offtout((scan-lenb)-(lastscan+lenf),buf);
			if (patch.Compress((char*)buf, 8, false)==false)
			{
				free(db);
				free(eb);
				free(I);
				return false;
			}
			//BZ2_bzWrite(&bz2err, pfbz2, buf, 8);
			//if (bz2err != BZ_OK)
			//	errx(1, "BZ2_bzWrite, bz2err = %d", bz2err);

			offtout((pos-lenb)-(lastpos+lenf),buf);
			if (patch.Compress((char*)buf, 8, false)==false)
			{
				free(db);
				free(eb);
				free(I);
				return false;
			}
			//BZ2_bzWrite(&bz2err, pfbz2, buf, 8);
			//if (bz2err != BZ_OK)
			//	errx(1, "BZ2_bzWrite, bz2err = %d", bz2err);

			lastscan=scan-lenb;
			lastpos=pos-lenb;
			lastoffset=pos-scan;
		};
	};

//	BZ2_bzWriteClose(&bz2err, pfbz2, 0, NULL, NULL);
//	if (bz2err != BZ_OK)
//		errx(1, "BZ2_bzWriteClose, bz2err = %d", bz2err);

	/* Compute size of compressed ctrl data */
//	if ((len = ftello(pf)) == -1)
//		err(1, "ftello");
	if (patch.Compress(0,0,true)==false)
	{
		free(db);
		free(eb);
		free(I);
		return false;
	}
	len=patch.GetTotalOutputSize()+32; // test: len should be 188
	offtout(len-32, header + 8);
	//memcpy(*out+outWriteOffset, patch.GetOutput(), patch.GetTotalOutputSize());
	//outWriteOffset+=patch.GetTotalOutputSize();
	//patch.Clear(_FILE_AND_LINE_);
	

	/* Write compressed diff data */
//	if ((pfbz2 = BZ2_bzWriteOpen(&bz2err, pf, 9, 0, 0)) == NULL)
//		errx(1, "BZ2_bzWriteOpen, bz2err = %d", bz2err);
//	BZ2_bzWrite(&bz2err, pfbz2, db, dblen);
	if (patch.Compress((char*)db,dblen,true)==false)
	{
		free(db);
		free(eb);
		free(I);
		return false;
	}
//	memcpy(*out+outWriteOffset, patch.GetOutput(), patch.GetTotalOutputSize());
//	outWriteOffset+=patch.GetTotalOutputSize();
//	patch.Clear(_FILE_AND_LINE_);
//	if (bz2err != BZ_OK)
//		errx(1, "BZ2_bzWrite, bz2err = %d", bz2err);
//	BZ2_bzWriteClose(&bz2err, pfbz2, 0, NULL, NULL);
//	if (bz2err != BZ_OK)
//		errx(1, "BZ2_bzWriteClose, bz2err = %d", bz2err);

	/* Compute size of compressed diff data */
//	if ((newsize = ftello(pf)) == -1)
//		err(1, "ftello");
	newsize=32+patch.GetTotalOutputSize();
	offtout(newsize - len, header + 16);
//	memcpy(*out+outWriteOffset, patch.GetOutput(), patch.GetTotalOutputSize());
//	outWriteOffset+=patch.GetTotalOutputSize();
//	patch.Clear(_FILE_AND_LINE_);

	/* Write compressed extra data */
//	if ((pfbz2 = BZ2_bzWriteOpen(&bz2err, pf, 9, 0, 0)) == NULL)
//		errx(1, "BZ2_bzWriteOpen, bz2err = %d", bz2err);
//	BZ2_bzWrite(&bz2err, pfbz2, eb, eblen);
	if (patch.Compress((char*)eb,eblen,true)==false)
	{
		free(db);
		free(eb);
		free(I);
		return false;
	}
//	memcpy(*out+outWriteOffset, patch.GetOutput(), patch.GetTotalOutputSize());
//	outWriteOffset+=patch.GetTotalOutputSize();
//	patch.Clear(_FILE_AND_LINE_);
//	if (bz2err != BZ_OK)
//		errx(1, "BZ2_bzWrite, bz2err = %d", bz2err);
//	BZ2_bzWriteClose(&bz2err, pfbz2, 0, NULL, NULL);
//	if (bz2err != BZ_OK)
//		errx(1, "BZ2_bzWriteClose, bz2err = %d", bz2err);

	/* Seek to the beginning, write the header, and close the file */
//	if (fseeko(pf, 0, SEEK_SET))
//		err(1, "fseeko");
//	if (fwrite(header, 32, 1, pf) != 1)
//		err(1, "fwrite(%s)", argv[3]);
//	if (fclose(pf))
//		err(1, "fclose");

//	memcpy(*out,header,32);
//	*out=(char*) realloc(*out, outWriteOffset);
//	*outSize=outWriteOffset;

	*outSize=patch.GetTotalOutputSize()+32;
	*out = new char [*outSize];
	memcpy(*out, header, 32);
	memcpy(*out+32, patch.GetOutput(), patch.GetTotalOutputSize());
	

	/* Free the memory we used */
	free(db);
	free(eb);
	free(I);
	//free(old);
	//free(new);

	return true;
}
예제 #5
0
// This is main() from bsdiff.c, with the following changes:
//
//    - old, oldsize, newdata, newsize are arguments; we don't load this
//      data from files.  old and newdata are owned by the caller; we
//      don't free them at the end.
//
//    - the "I" block of memory is owned by the caller, who passes a
//      pointer to *I, which can be NULL.  This way if we call
//      bsdiff() multiple times with the same 'old' data, we only do
//      the qsufsort() step the first time.
//
int bsdiff(u_char* old, off_t oldsize, off_t** IP, u_char* newdata, off_t newsize,
           const char* patch_filename)
{
    int fd;
    off_t *I;
    off_t scan,pos,len;
    off_t lastscan,lastpos,lastoffset;
    off_t oldscore,scsc;
    off_t s,Sf,lenf,Sb,lenb;
    off_t overlap,Ss,lens;
    off_t i;
    off_t dblen,eblen;
    u_char *db,*eb;
    u_char buf[8];
    u_char header[32];
    FILE * pf;
    BZFILE * pfbz2;
    int bz2err;

    if (*IP == NULL) {
        off_t* V;
        *IP = reinterpret_cast<off_t*>(malloc((oldsize+1) * sizeof(off_t)));
        V = reinterpret_cast<off_t*>(malloc((oldsize+1) * sizeof(off_t)));
        qsufsort(*IP, V, old, oldsize);
        free(V);
    }
    I = *IP;

    if(((db=reinterpret_cast<u_char*>(malloc(newsize+1)))==NULL) ||
            ((eb=reinterpret_cast<u_char*>(malloc(newsize+1)))==NULL)) err(1,NULL);
    dblen=0;
    eblen=0;

    /* Create the patch file */
    if ((pf = fopen(patch_filename, "w")) == NULL)
        err(1, "%s", patch_filename);

    /* Header is
    	0	8	 "BSDIFF40"
    	8	8	length of bzip2ed ctrl block
    	16	8	length of bzip2ed diff block
    	24	8	length of new file */
    /* File is
    	0	32	Header
    	32	??	Bzip2ed ctrl block
    	??	??	Bzip2ed diff block
    	??	??	Bzip2ed extra block */
    memcpy(header,"BSDIFF40",8);
    offtout(0, header + 8);
    offtout(0, header + 16);
    offtout(newsize, header + 24);
    if (fwrite(header, 32, 1, pf) != 1)
        err(1, "fwrite(%s)", patch_filename);

    /* Compute the differences, writing ctrl as we go */
    if ((pfbz2 = BZ2_bzWriteOpen(&bz2err, pf, 9, 0, 0)) == NULL)
        errx(1, "BZ2_bzWriteOpen, bz2err = %d", bz2err);
    scan=0;
    len=0;
    lastscan=0;
    lastpos=0;
    lastoffset=0;
    while(scan<newsize) {
        oldscore=0;

        for(scsc=scan+=len; scan<newsize; scan++) {
            len=search(I,old,oldsize,newdata+scan,newsize-scan,
                       0,oldsize,&pos);

            for(; scsc<scan+len; scsc++)
                if((scsc+lastoffset<oldsize) &&
                        (old[scsc+lastoffset] == newdata[scsc]))
                    oldscore++;

            if(((len==oldscore) && (len!=0)) ||
                    (len>oldscore+8)) break;

            if((scan+lastoffset<oldsize) &&
                    (old[scan+lastoffset] == newdata[scan]))
                oldscore--;
        };

        if((len!=oldscore) || (scan==newsize)) {
            s=0;
            Sf=0;
            lenf=0;
            for(i=0; (lastscan+i<scan)&&(lastpos+i<oldsize);) {
                if(old[lastpos+i]==newdata[lastscan+i]) s++;
                i++;
                if(s*2-i>Sf*2-lenf) {
                    Sf=s;
                    lenf=i;
                };
            };

            lenb=0;
            if(scan<newsize) {
                s=0;
                Sb=0;
                for(i=1; (scan>=lastscan+i)&&(pos>=i); i++) {
                    if(old[pos-i]==newdata[scan-i]) s++;
                    if(s*2-i>Sb*2-lenb) {
                        Sb=s;
                        lenb=i;
                    };
                };
            };

            if(lastscan+lenf>scan-lenb) {
                overlap=(lastscan+lenf)-(scan-lenb);
                s=0;
                Ss=0;
                lens=0;
                for(i=0; i<overlap; i++) {
                    if(newdata[lastscan+lenf-overlap+i]==
                            old[lastpos+lenf-overlap+i]) s++;
                    if(newdata[scan-lenb+i]==
                            old[pos-lenb+i]) s--;
                    if(s>Ss) {
                        Ss=s;
                        lens=i+1;
                    };
                };

                lenf+=lens-overlap;
                lenb-=lens;
            };

            for(i=0; i<lenf; i++)
                db[dblen+i]=newdata[lastscan+i]-old[lastpos+i];
            for(i=0; i<(scan-lenb)-(lastscan+lenf); i++)
                eb[eblen+i]=newdata[lastscan+lenf+i];

            dblen+=lenf;
            eblen+=(scan-lenb)-(lastscan+lenf);

            offtout(lenf,buf);
            BZ2_bzWrite(&bz2err, pfbz2, buf, 8);
            if (bz2err != BZ_OK)
                errx(1, "BZ2_bzWrite, bz2err = %d", bz2err);

            offtout((scan-lenb)-(lastscan+lenf),buf);
            BZ2_bzWrite(&bz2err, pfbz2, buf, 8);
            if (bz2err != BZ_OK)
                errx(1, "BZ2_bzWrite, bz2err = %d", bz2err);

            offtout((pos-lenb)-(lastpos+lenf),buf);
            BZ2_bzWrite(&bz2err, pfbz2, buf, 8);
            if (bz2err != BZ_OK)
                errx(1, "BZ2_bzWrite, bz2err = %d", bz2err);

            lastscan=scan-lenb;
            lastpos=pos-lenb;
            lastoffset=pos-scan;
        };
    };
    BZ2_bzWriteClose(&bz2err, pfbz2, 0, NULL, NULL);
    if (bz2err != BZ_OK)
        errx(1, "BZ2_bzWriteClose, bz2err = %d", bz2err);

    /* Compute size of compressed ctrl data */
    if ((len = ftello(pf)) == -1)
        err(1, "ftello");
    offtout(len-32, header + 8);

    /* Write compressed diff data */
    if ((pfbz2 = BZ2_bzWriteOpen(&bz2err, pf, 9, 0, 0)) == NULL)
        errx(1, "BZ2_bzWriteOpen, bz2err = %d", bz2err);
    BZ2_bzWrite(&bz2err, pfbz2, db, dblen);
    if (bz2err != BZ_OK)
        errx(1, "BZ2_bzWrite, bz2err = %d", bz2err);
    BZ2_bzWriteClose(&bz2err, pfbz2, 0, NULL, NULL);
    if (bz2err != BZ_OK)
        errx(1, "BZ2_bzWriteClose, bz2err = %d", bz2err);

    /* Compute size of compressed diff data */
    if ((newsize = ftello(pf)) == -1)
        err(1, "ftello");
    offtout(newsize - len, header + 16);

    /* Write compressed extra data */
    if ((pfbz2 = BZ2_bzWriteOpen(&bz2err, pf, 9, 0, 0)) == NULL)
        errx(1, "BZ2_bzWriteOpen, bz2err = %d", bz2err);
    BZ2_bzWrite(&bz2err, pfbz2, eb, eblen);
    if (bz2err != BZ_OK)
        errx(1, "BZ2_bzWrite, bz2err = %d", bz2err);
    BZ2_bzWriteClose(&bz2err, pfbz2, 0, NULL, NULL);
    if (bz2err != BZ_OK)
        errx(1, "BZ2_bzWriteClose, bz2err = %d", bz2err);

    /* Seek to the beginning, write the header, and close the file */
    if (fseeko(pf, 0, SEEK_SET))
        err(1, "fseeko");
    if (fwrite(header, 32, 1, pf) != 1)
        err(1, "fwrite(%s)", patch_filename);
    if (fclose(pf))
        err(1, "fclose");

    /* Free the memory we used */
    free(db);
    free(eb);

    return 0;
}
예제 #6
0
파일: bsdiff.c 프로젝트: kc5nra/sporkel
int sporkel_bsdiff(u_char* oldp, off_t oldsize,
           u_char* newp, off_t newsize,
           u_char* patch, off_t patchsz)
{
  off_t *I;//,*V;
  off_t scan,pos,len;
  off_t lastscan,lastpos,lastoffset;
  off_t oldscore,scsc;
  off_t s,Sf,lenf,Sb,lenb;
  off_t overlap,Ss,lens;
  off_t i;
  off_t dblen,eblen;
  u_char *db,*eb;
  u_char buf[8];
  u_char header[32];
  u_char *fileblock;

  off_t ctrllen;

  /* Sanity checks */
  if (oldp == NULL || newp == NULL || patch == NULL) return -1;
  if (oldsize < 0 || newsize < 0 || patchsz < 0)     return -1;
  if (sporkel_bsdiff_patchsize_max(oldsize, newsize) > patchsz) return -1;

  /* Allocate oldsize+1 bytes instead of oldsize bytes to ensure
     that we never try to malloc(0) and get a NULL pointer */
  if(((I=malloc((oldsize+1)*sizeof(off_t)))==NULL) /*||
     ((V=malloc((oldsize+1)*sizeof(off_t)))==NULL)*/) return -1;

  I[0] = oldsize;
  sporkel_sais(oldp, I + 1, oldsize);
  //qsufsort(I,V,oldp,oldsize);

  //free(V);

  /* Allocate newsize+1 bytes instead of newsize bytes to ensure
     that we never try to malloc(0) and get a NULL pointer */
  if(((db=malloc(newsize+1))==NULL) ||
     ((eb=malloc(newsize+1))==NULL)) {
    free(I);
    return -1;
  }
  dblen=0;
  eblen=0;

  /* Write initial header */
  memcpy(header,BSDIFF_CONFIG_MAGIC,8);
  offtout(0, header + 8);
  offtout(0, header + 16);
  offtout(newsize, header + 24);
  memcpy(patch, header, 32);

  /* Set up initial pointers */
  fileblock = patch + 32;
  ctrllen = 0;

  /* Compute the differences, writing ctrl as we go */
  scan=0;len=0;pos=0;
  lastscan=0;lastpos=0;lastoffset=0;
  while(scan<newsize) {
    oldscore=0;

    for(scsc=scan+=len;scan<newsize;scan++) {
      len=search(I,oldp,oldsize,newp+scan,newsize-scan,
                 0,oldsize,&pos);

      for(;scsc<scan+len;scsc++)
        if((scsc+lastoffset<oldsize) &&
           (oldp[scsc+lastoffset] == newp[scsc]))
          oldscore++;

      if(((len==oldscore) && (len!=0)) ||
         (len>oldscore+8)) break;

      if((scan+lastoffset<oldsize) &&
         (oldp[scan+lastoffset] == newp[scan]))
        oldscore--;
    };

    if((len!=oldscore) || (scan==newsize)) {
      s=0;Sf=0;lenf=0;
      for(i=0;(lastscan+i<scan)&&(lastpos+i<oldsize);) {
        if(oldp[lastpos+i]==newp[lastscan+i]) s++;
        i++;
        if(s*2-i>Sf*2-lenf) { Sf=s; lenf=i; };
      };

      lenb=0;
      if(scan<newsize) {
        s=0;Sb=0;
        for(i=1;(scan>=lastscan+i)&&(pos>=i);i++) {
          if(oldp[pos-i]==newp[scan-i]) s++;
          if(s*2-i>Sb*2-lenb) { Sb=s; lenb=i; };
        };
      };

      if(lastscan+lenf>scan-lenb) {
        overlap=(lastscan+lenf)-(scan-lenb);
        s=0;Ss=0;lens=0;
        for(i=0;i<overlap;i++) {
          if(newp[lastscan+lenf-overlap+i]==
             oldp[lastpos+lenf-overlap+i]) s++;
          if(newp[scan-lenb+i]==
             oldp[pos-lenb+i]) s--;
          if(s>Ss) { Ss=s; lens=i+1; };
        };

        lenf+=lens-overlap;
        lenb-=lens;
      };

      for(i=0;i<lenf;i++)
        db[dblen+i]=newp[lastscan+i]-oldp[lastpos+i];
      for(i=0;i<(scan-lenb)-(lastscan+lenf);i++)
        eb[eblen+i]=newp[lastscan+lenf+i];

      dblen+=lenf;
      eblen+=(scan-lenb)-(lastscan+lenf);

      offtout(lenf,buf);
      memcpy(fileblock, buf, 8);
      fileblock += 8; ctrllen += 8;

      offtout((scan-lenb)-(lastscan+lenf),buf);
      memcpy(fileblock, buf, 8);
      fileblock += 8; ctrllen += 8;

      offtout((pos-lenb)-(lastpos+lenf),buf);
      memcpy(fileblock, buf, 8);
      fileblock += 8; ctrllen += 8;

      lastscan=scan-lenb;
      lastpos=pos-lenb;
      lastoffset=pos-scan;
    };
  };

  /* Write size of ctrl data */
  offtout(ctrllen, header + 8);

  /* Write diff data */
  memcpy(fileblock, db, dblen);
  fileblock += dblen;
  /* Write size of diff data */
  offtout(dblen, header + 16);

  /* Write extra data */
  memcpy(fileblock, eb, eblen);

  /* Write the final header */
  memcpy(patch, header, 32);

  /* Free the memory we used */
  free(db);
  free(eb);
  free(I);

  return (32+ctrllen+dblen+eblen);
}
예제 #7
0
int bsdiff(u_char* old, off_t oldsize, u_char* newp, off_t newsize, FILE* pf)
{
	size_t offset;
	off_t *I=NULL,*V=NULL;
	off_t scan,pos = 0,len;
	off_t lastscan,lastpos,lastoffset;
	off_t oldscore,scsc;
	off_t s,Sf,lenf,Sb,lenb;
	off_t overlap,Ss,lens;
	off_t i;
	off_t dblen,eblen;
	u_char *db=NULL,*eb=NULL;
	u_char buf[8];
	u_char header[32];
	BZFILE * pfbz2=NULL;
	int bz2err;
	unsigned int nbytes_in;
	unsigned int nbytes_out;


	if(((I=malloc((oldsize+1)*sizeof(off_t)))==NULL) ||
		((V=malloc((oldsize+1)*sizeof(off_t)))==NULL)) {
		goto error;
	}

	qsufsort(I,V,old,oldsize);

	free(V);
	V = NULL;

	if(((db=malloc(newsize+1))==NULL) ||
		((eb=malloc(newsize+1))==NULL)) {
		goto error;
	}
	dblen=0;
	eblen=0;

	offset = ftell(pf);

	/* Header is
		0	8	length of newp file
		8	8	length of bzip2ed ctrl block
		16	8	length of bzip2ed diff block
		24	8	length of bzip2ed extra block */
	/* File is
		0	32	Header
		32	??	Bzip2ed ctrl block
		??	??	Bzip2ed diff block
		??	??	Bzip2ed extra block */
	memcpy(header, "BSDIFFXX", 8);
	offtout(0, header + 8);
	offtout(0, header + 16);
	offtout(newsize, header + 24);
	if (fwrite(header, 32, 1, pf) != 1) {
		printf("fwrite(%s)", "patch_file");
		goto error;
	}

	/* Compute the differences, writing ctrl as we go */
	if ((pfbz2 = BZ2_bzWriteOpen(&bz2err, pf, 9, 0, 0)) == NULL) {
		printf("BZ2_bzWriteOpen, bz2err = %d", bz2err);
		goto error;
	}
	scan=0;len=0;
	lastscan=0;lastpos=0;lastoffset=0;
	while(scan<newsize) {
		oldscore=0;

		for(scsc=scan+=len;scan<newsize;scan++) {
			len=search(I,old,oldsize,newp+scan,newsize-scan,
					0,oldsize,&pos);

			for(;scsc<scan+len;scsc++)
			if((scsc+lastoffset<oldsize) &&
				(old[scsc+lastoffset] == newp[scsc]))
				oldscore++;

			if(((len==oldscore) && (len!=0)) || 
				(len>oldscore+8)) break;

			if((scan+lastoffset<oldsize) &&
				(old[scan+lastoffset] == newp[scan]))
				oldscore--;
		};

		if((len!=oldscore) || (scan==newsize)) {
			s=0;Sf=0;lenf=0;
			for(i=0;(lastscan+i<scan)&&(lastpos+i<oldsize);) {
				if(old[lastpos+i]==newp[lastscan+i]) s++;
				i++;
				if(s*2-i>Sf*2-lenf) { Sf=s; lenf=i; };
			};

			lenb=0;
			if(scan<newsize) {
				s=0;Sb=0;
				for(i=1;(scan>=lastscan+i)&&(pos>=i);i++) {
					if(old[pos-i]==newp[scan-i]) s++;
					if(s*2-i>Sb*2-lenb) { Sb=s; lenb=i; };
				};
			};

			if(lastscan+lenf>scan-lenb) {
				overlap=(lastscan+lenf)-(scan-lenb);
				s=0;Ss=0;lens=0;
				for(i=0;i<overlap;i++) {
					if(newp[lastscan+lenf-overlap+i]==
					   old[lastpos+lenf-overlap+i]) s++;
					if(newp[scan-lenb+i]==
					   old[pos-lenb+i]) s--;
					if(s>Ss) { Ss=s; lens=i+1; };
				};

				lenf+=lens-overlap;
				lenb-=lens;
			};

			for(i=0;i<lenf;i++)
				db[dblen+i]=newp[lastscan+i]-old[lastpos+i];
			for(i=0;i<(scan-lenb)-(lastscan+lenf);i++)
				eb[eblen+i]=newp[lastscan+lenf+i];

			dblen+=lenf;
			eblen+=(scan-lenb)-(lastscan+lenf);

			offtout(lenf,buf);
			BZ2_bzWrite(&bz2err, pfbz2, buf, 8);
			if (bz2err != BZ_OK) {
				printf("BZ2_bzWrite, bz2err = %d", bz2err);
				goto error;
			}

			offtout((scan-lenb)-(lastscan+lenf),buf);
			BZ2_bzWrite(&bz2err, pfbz2, buf, 8);
			if (bz2err != BZ_OK) {
				printf("BZ2_bzWrite, bz2err = %d", bz2err);
				goto error;
			}

			offtout((pos-lenb)-(lastpos+lenf),buf);
			BZ2_bzWrite(&bz2err, pfbz2, buf, 8);
			if (bz2err != BZ_OK) {
				printf("BZ2_bzWrite, bz2err = %d", bz2err);
				goto error;
			}

			lastscan=scan-lenb;
			lastpos=pos-lenb;
			lastoffset=pos-scan;
		};
	};

	BZ2_bzWriteClose(&bz2err, pfbz2, 0, &nbytes_in, &nbytes_out);
	pfbz2 = NULL;
	if (bz2err != BZ_OK) {
		printf("BZ2_bzWriteClose, bz2err = %d", bz2err);
		goto error;
	}

	/* Compute size of compressed ctrl data */
	if ((len = ftell(pf)) == -1) {
		printf("ftello");
		goto error;
	}
	offtout((off_t)(len-32-offset), header + 8);
	printf("--ctrl data %d %d %d\n", len-32-offset, nbytes_in, nbytes_out);

	/* Write compressed diff data */
	if ((pfbz2 = BZ2_bzWriteOpen(&bz2err, pf, 9, 0, 0)) == NULL) {
		printf("BZ2_bzWriteOpen, bz2err = %d", bz2err);
		goto error;
	}
	BZ2_bzWrite(&bz2err, pfbz2, db, dblen);
	if (bz2err != BZ_OK) {
		printf("BZ2_bzWrite, bz2err = %d", bz2err);
		goto error;
	}
	BZ2_bzWriteClose(&bz2err, pfbz2, 0, &nbytes_in, &nbytes_out);
	pfbz2 = NULL;
	if (bz2err != BZ_OK) {
		printf("BZ2_bzWriteClose, bz2err = %d", bz2err);
		goto error;
	}

	/* Compute size of compressed diff data */
	if ((newsize = ftell(pf)) == -1) {
		printf("ftello");
		goto error;
	}
	offtout(newsize - len, header + 16);
	printf("--diff data %d %d %d\n", newsize - len, nbytes_in, nbytes_out);

	/* Write compressed extra data */
	if ((pfbz2 = BZ2_bzWriteOpen(&bz2err, pf, 9, 0, 0)) == NULL) {
		printf("BZ2_bzWriteOpen, bz2err = %d", bz2err);
		goto error;
	}
	BZ2_bzWrite(&bz2err, pfbz2, eb, eblen);
	if (bz2err != BZ_OK) {
		printf("BZ2_bzWrite, bz2err = %d", bz2err);
		goto error;
	}
	BZ2_bzWriteClose(&bz2err, pfbz2, 0, &nbytes_in, &nbytes_out);
	pfbz2 = NULL;
	if (bz2err != BZ_OK) {
		printf("BZ2_bzWriteClose, bz2err = %d", bz2err);
		goto error;
	}
	if ((len = ftell(pf)) == -1) {
		printf("ftello");
		goto error;
	}
	printf("--extra data %d %d %d\n", len - newsize, nbytes_in, nbytes_out);
	printf("--total %d\n", len - offset);

	/* Seek to the beginning, write the header, and close the file */
	if (fseek(pf, (long)(0+offset), SEEK_SET)) {
		printf("fseeko");
		goto error;
	}
	if (fwrite(header, 32, 1, pf) != 1) {
		printf("fwrite(%s)", "patch_file");
		goto error;
	}
	fseek(pf, len, SEEK_SET);
	/* Free the memory we used */
	free(db);
	free(eb);
	free(I);

	return 0;

error:
	if(pfbz2) BZ2_bzWriteClose(&bz2err, pfbz2, 0, NULL, NULL);
	if(I) free(I);
	if(V) free(V);
	if(db) free(db);
	if(eb) free(eb);
	return -1;
}
예제 #8
0
파일: nile.c 프로젝트: Gottox/nile
static int
lcs(const char *olddata, off_t *oldoff, size_t oldsize, const char *newdata, off_t *newoff, size_t newsize, off_t *lastSkip, FILE *output) {
	off_t oi, ni, bufi, lastni, lastoi, no = *newoff, oo = *oldoff, skip, baseSkip = *lastSkip, end = 0;
	int map[LCS_BLOCKSIZE][LCS_BLOCKSIZE] = { { 0 } };
	char buf[LCS_BLOCKSIZE * 17], *p = NULL;

	// Build LCS Map
	for(oi = 0; oi < oldsize - oo && oi < LCS_BLOCKSIZE; oi++) {
		for(ni = 0; ni < newsize - no && ni < LCS_BLOCKSIZE; ni++) {
			if(olddata[oo + oi] == newdata[no + ni]) {
				map[oi][ni] = oi == 0 || ni == 0 ? 1 : map[oi-1][ni-1] + 1;
			}
			else if(map[oi][ni-1] < map[oi-1][ni]) {
				map[oi][ni] = oi == 0 ? 0 : map[oi-1][ni];
			}
			else {
				map[oi][ni] = ni == 0 ? 0 : map[oi][ni-1];
			}
		}
	}

	// Check if we hit boundarys
	end = oi == oldsize - oo || ni == newsize - no;

	// Tell caller about the new maximal offsets;
	*oldoff = oo + oi;
	*newoff = no + ni;

	for(skip = 0, lastni = --ni, lastoi = --oi, bufi = sizeof(buf);oi >= 0 && ni >= 0;) {
		// LEFT
		if(ni != 0 && map[oi][ni-1] == map[oi][ni]) {
			buf[--bufi] = newdata[no + ni];
			ni--;
		}
		// UP
		else if(oi != 0 && map[oi-1][ni] == map[oi][ni]) {
			oi--;
		}
		// DIAGONAL
		else {
			// Set Offset to last common sequence
			if(oldoff != NULL) {
				*oldoff = oo + oi;
				*newoff = no + ni;
				newoff = oldoff = NULL;
			}
			// This is the first common character after
			// differences, so set new diff header
			if(skip == 0 && (lastni - ni != 0 || lastoi - oi != 0)) {
				bufi-=8;
				offtout(lastni - ni, &buf[bufi]);
				bufi-=8;
				offtout(lastoi - oi, &buf[bufi]);
				bufi-=8;
				p=&buf[bufi];
			}
			ni--;oi--;
			skip++;
			lastni = ni;
			lastoi = oi;
			continue;
		}

		if(p != NULL) {
			offtout(skip, p);
			p = NULL;
		}
		// tell caller how much data we skipped
		if(lastSkip) {
			*lastSkip += skip;
			lastSkip = NULL;
		}
		skip = 0;
	}
	// Set skip for first header in this round
	if(p != NULL)
		offtout(skip+baseSkip, p);
	// tell caller how much data we skipped if we haven't done
	// that already.
	if(lastSkip)
		*lastSkip += skip;
	fwrite(&buf[bufi], sizeof(buf) - bufi, 1, output);
	return end;
}