Exemple #1
0
static bool bsdiffmain(MCBsDiffInputStream *p_old_file, MCBsDiffInputStream *p_new_file, MCBsDiffOutputStream *p_patch_file)
{
	u_char *old,*newp;
	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;

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

	/* 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,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 (t_success)
	{
		uint32_t t_size;
		t_success = p_old_file -> Measure(t_size);
		oldsize = (signed)t_size;
	}
	if (t_success)
		t_success = MCMemoryNewArray(oldsize + 1, old);
	if (t_success)
		t_success = p_old_file -> ReadBytes(old, oldsize);
	
	/*if(((I=malloc((oldsize+1)*sizeof(off_t)))==NULL) ||
		((V=malloc((oldsize+1)*sizeof(off_t)))==NULL)) err(1,NULL);*/
	if (t_success)
		t_success = MCMemoryNewArray(oldsize + 1, I);
	if (t_success)
		t_success = MCMemoryNewArray(oldsize + 1, V);

    if (t_success)
        qsufsort(I,V,old,oldsize);

	/*free(V);*/
    MCMemoryDeleteArray(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,0))<0) ||
		((newsize=lseek(fd,0,SEEK_END))==-1) ||
		((newp=malloc(newsize+1))==NULL) ||
		(lseek(fd,0,SEEK_SET)!=0) ||
		(read(fd,newp,newsize)!=newsize) ||
		(close(fd)==-1)) err(1,"%s",argv[2]);*/
	if (t_success)
	{
		uint32_t t_size;
		t_success = p_new_file -> Measure(t_size);
		newsize = (signed)t_size;
	}
	if (t_success)
		t_success = MCMemoryNewArray(newsize + 1, newp);
	if (t_success)
		t_success = p_new_file -> ReadBytes(newp, newsize);

	/*if(((db=malloc(newsize+1))==NULL) ||
		((eb=malloc(newsize+1))==NULL)) err(1,NULL);*/
	if (t_success)
		t_success = MCMemoryNewArray(newsize + 1, db);
	if (t_success)
		t_success = MCMemoryNewArray(newsize + 1, eb);

	dblen=0;
	eblen=0;

	/* Create the patch file */
	/*if ((pf = fopen(argv[3], "w")) == 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]);*/
	uint32_t t_control_size, t_diff_size, t_extra_size;
	t_control_size = 0;
	t_diff_size = 0;
	t_extra_size = 0;
	if (t_success)
		t_success =
			p_patch_file -> WriteInt32(t_control_size) &&
			p_patch_file -> WriteInt32(t_diff_size) &&
			p_patch_file -> WriteInt32(t_extra_size) &&
			p_patch_file -> WriteInt32(newsize);

	/* 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(t_success && 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)
				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);*/

			if (t_success)
				t_success =
					p_patch_file -> WriteInt32(lenf) &&
					p_patch_file -> WriteInt32((scan-lenb)-(lastscan+lenf)) &&
					p_patch_file -> WriteInt32((pos-lenb)-(lastpos+lenf));

			if (t_success)
				t_control_size += 12;

			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);*/
	if (t_success)
		t_success = p_patch_file -> WriteBytes(db, dblen);
	if (t_success)
		t_diff_size = dblen;

	/* 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);*/
	if (t_success)
		t_success = p_patch_file -> WriteBytes(eb, eblen);
	if (t_success)
		t_extra_size = eblen;

	/* 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");*/
	if (t_success)
		t_success =
			p_patch_file -> Rewind() &&
			p_patch_file -> WriteInt32(t_control_size) &&
			p_patch_file -> WriteInt32(t_diff_size) &&
			p_patch_file -> WriteInt32(t_extra_size) &&
			p_patch_file -> Rewind();

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

	return t_success;
}
Exemple #2
0
 int CreateBinaryPatch(const char *oldFile, const char *newFile, const char *patchFile)
 {
     if (NULL == oldFile || NULL == newFile || NULL == patchFile) return -1;

 	int fd;
 	unsigned char *old,*newbuf;
 	PROffset32 oldsize,newsize;
 	PROffset32 *I,*V;
 
 	PROffset32 scan,pos,len;
 	PROffset32 lastscan,lastpos,lastoffset;
 	PROffset32 oldscore,scsc;
 
 	PROffset32 s,Sf,lenf,Sb,lenb;
 	PROffset32 overlap,Ss,lens;
 	PROffset32 i;
 
 	PROffset32 dblen,eblen;
 	unsigned char *db,*eb;
 
 	unsigned int scrc;      // 校验码
    
    PRUint32 numtriples;    // 节点个数
 
 	MBSPatchHeader header =
    {
 		{'M','B','D','I','F','F','1','0'},
 		0, 0, 0, 0, 0, 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(oldFile,O_RDONLY|_O_BINARY,0))<0) ||
 		((oldsize=lseek(fd,0,SEEK_END))==-1) ||
 		((old=(unsigned char*) malloc(oldsize+1))==NULL) ||
 		(lseek(fd,0,SEEK_SET)!=0) ||
 		(read(fd,old,oldsize)!=oldsize) ||
 		(close(fd)==-1))
 		reporterr(1,"%s\n",oldFile);
 
 	scrc = crc32(old, oldsize);
 
 	if(((I=(PROffset32*) malloc((oldsize+1)*sizeof(PROffset32)))==NULL) ||
 		((V=(PROffset32*) malloc((oldsize+1)*sizeof(PROffset32)))==NULL))
 		reporterr(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(newFile,O_RDONLY|_O_BINARY,0))<0) ||
 		((newsize=lseek(fd,0,SEEK_END))==-1) ||
 		((newbuf=(unsigned char*) malloc(newsize+1))==NULL) ||
 		(lseek(fd,0,SEEK_SET)!=0) ||
 		(read(fd,newbuf,newsize)!=newsize) ||
 		(close(fd)==-1)) reporterr(1,"%s\n",newFile);
 
 	if(((db=(unsigned char*) malloc(newsize+1))==NULL) ||
 		((eb=(unsigned char*) malloc(newsize+1))==NULL))
 		reporterr(1,NULL);
 
 	dblen=0;
 	eblen=0;
 
 	if((fd=open(patchFile,O_CREAT|O_TRUNC|O_WRONLY|_O_BINARY,0666))<0)
 		reporterr(1,"%s\n",patchFile);
 
 	/* start writing here */
 
 	/* We don't know the lengths yet, so we will write the header again
 		 at the end */
 
 	if(write(fd,&header,sizeof(MBSPatchHeader))!=sizeof(MBSPatchHeader))
 		reporterr(1,"%s\n",patchFile);
 
 	scan=0;len=0;
 	lastscan=0;lastpos=0;lastoffset=0;
 	numtriples = 0;
 	while(scan<newsize) {
 		oldscore=0;
 
 		for(scsc=scan+=len;scan<newsize;scan++) {
 			len=search(I,old,oldsize,newbuf+scan,newsize-scan,
 					0,oldsize,&pos);
 
 			for(;scsc<scan+len;scsc++)
 			if((scsc+lastoffset<oldsize) &&
 				(old[scsc+lastoffset] == newbuf[scsc]))
 				oldscore++;
 
 			if(((len==oldscore) && (len!=0)) || 
 				(len>oldscore+8)) break;
 
 			if((scan+lastoffset<oldsize) &&
 				(old[scan+lastoffset] == newbuf[scan]))
 				oldscore--;
 		};
 
 		if((len!=oldscore) || (scan==newsize)) {
 			MBSPatchTriple triple;
 
 			s=0;Sf=0;lenf=0;
 			for(i=0;(lastscan+i<scan)&&(lastpos+i<oldsize);) {
 				if(old[lastpos+i]==newbuf[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]==newbuf[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(newbuf[lastscan+lenf-overlap+i]==
 					   old[lastpos+lenf-overlap+i]) s++;
 					if(newbuf[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]=newbuf[lastscan+i]-old[lastpos+i];
 			for(i=0;i<(scan-lenb)-(lastscan+lenf);i++)
 				eb[eblen+i]=newbuf[lastscan+lenf+i];
 
 			dblen+=lenf;
 			eblen+=(scan-lenb)-(lastscan+lenf);
 
 			triple.x = htonl(lenf);
 			triple.y = htonl((scan-lenb)-(lastscan+lenf));
 			triple.z = htonl((pos-lenb)-(lastpos+lenf));
 			if (write(fd,&triple,sizeof(triple)) != sizeof(triple))
 				reporterr(1,NULL);
 
 #ifdef _DEBUG
 			TRACE("Writing a block: X=%u,Y=%u,Z=%i\n",
 			       (PRUint32) lenf,
 			       (PRUint32) ((scan-lenb)-(lastscan+lenf)),
 			       (PRUint32) ((pos-lenb)-(lastpos+lenf)));
 #endif
 
 			++numtriples;
 
 			lastscan=scan-lenb;
 			lastpos=pos-lenb;
 			lastoffset=pos-scan;
 		};
 	};
 
 	if(write(fd,db,dblen)!=dblen)
 		reporterr(1,NULL);
 
 	if(write(fd,eb,eblen)!=eblen)
 		reporterr(1,NULL);
 
 	header.slen	    = htonl(oldsize);
 	header.scrc32	= htonl(scrc);
 	header.dlen	    = htonl(newsize);
 	header.cblen	= htonl(numtriples * sizeof(MBSPatchTriple));
 	header.difflen	= htonl(dblen);
 	header.extralen = htonl(eblen);
 
 	if (lseek(fd,0,SEEK_SET) == -1 ||
 	    write(fd,&header,sizeof(header)) != sizeof(header) ||
 	    close(fd) == -1)
 		reporterr(1,NULL);
 
 	free(db);
 	free(eb);
 	free(I);
 	free(old);
 	free(newbuf);

 	return 0;
 }
Exemple #3
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;
}
Exemple #4
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;
}
Exemple #5
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;
}
// 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;
}
Exemple #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;
}