diff options
author | Eelco Dolstra <e.dolstra@tudelft.nl> | 2006-02-01T16·48+0000 |
---|---|---|
committer | Eelco Dolstra <e.dolstra@tudelft.nl> | 2006-02-01T16·48+0000 |
commit | 8291f6d96845163850a2451fff4a03a292fa71b6 (patch) | |
tree | 62609f683f51d883c5a710acff0272eca5a085d5 /src/bsdiff-4.2 | |
parent | 9e4ffc43a2a6b67643765efd48198f218fcf0530 (diff) |
* bsdiff updated to 4.3. This makes Nix depend on libbz2.
Diffstat (limited to 'src/bsdiff-4.2')
-rw-r--r-- | src/bsdiff-4.2/LICENSE | 121 | ||||
-rw-r--r-- | src/bsdiff-4.2/Makefile.am | 7 | ||||
-rw-r--r-- | src/bsdiff-4.2/Makefile.old | 18 | ||||
-rw-r--r-- | src/bsdiff-4.2/bsdiff.1 | 36 | ||||
-rw-r--r-- | src/bsdiff-4.2/bsdiff.c | 385 | ||||
-rw-r--r-- | src/bsdiff-4.2/bspatch.1 | 32 | ||||
-rw-r--r-- | src/bsdiff-4.2/bspatch.c | 216 |
7 files changed, 0 insertions, 815 deletions
diff --git a/src/bsdiff-4.2/LICENSE b/src/bsdiff-4.2/LICENSE deleted file mode 100644 index c146b5b399f0..000000000000 --- a/src/bsdiff-4.2/LICENSE +++ /dev/null @@ -1,121 +0,0 @@ -BSD Protection License -February 2002 - -Preamble --------- - -The Berkeley Software Distribution ("BSD") license has proven very effective -over the years at allowing for a wide spread of work throughout both -commercial and non-commercial products. For programmers whose primary -intention is to improve the general quality of available software, it is -arguable that there is no better license than the BSD license, as it -permits improvements to be used wherever they will help, without idealogical -or metallic constraint. - -This is of particular value to those who produce reference implementations -of proposed standards: The case of TCP/IP clearly illustrates that freely -and universally available implementations leads the rapid acceptance of -standards -- often even being used instead of a de jure standard (eg, OSI -network models). - -With the rapid proliferation of software licensed under the GNU General -Public License, however, the continued success of this role is called into -question. Given that the inclusion of a few lines of "GPL-tainted" work -into a larger body of work will result in restricted distribution -- and -given that further work will likely build upon the "tainted" portions, -making them difficult to remove at a future date -- there are inevitable -circumstances where authors would, in order to protect their goal of -providing for the widespread usage of their work, wish to guard against -such "GPL-taint". - -In addition, one can imagine that companies which operate by producing and -selling (possibly closed-source) code would wish to protect themselves -against the rise of a GPL-licensed competitor. While under existing -licenses this would mean not releasing their code under any form of open -license, if a license existed under which they could incorporate any -improvements back into their own (commercial) products then they might be -far more willing to provide for non-closed distribution. - -For the above reasons, we put forth this "BSD Protection License": A -license designed to retain the freedom granted by the BSD license to use -licensed works in a wide variety of settings, both non-commercial and -commercial, while protecting the work from having future contributors -restrict that freedom. - -The precise terms and conditions for copying, distribution, and -modification follow. - -BSD PROTECTION LICENSE -TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION, AND MODIFICATION ----------------------------------------------------------------- - -0. Definitions. - a) "Program", below, refers to any program or work distributed under - the terms of this license. - b) A "work based on the Program", below, refers to either the Program - or any derivative work under copyright law. - c) "Modification", below, refers to the act of creating derivative works. - d) "You", below, refers to each licensee. - -1. Scope. - This license governs the copying, distribution, and modification of the - Program. Other activities are outside the scope of this license; The - act of running the Program is not restricted, and the output from the - Program is covered only if its contents constitute a work based on the - Program. - -2. Verbatim copies. - You may copy and distribute verbatim copies of the Program as you - receive it, in any medium, provided that you conspicuously and - appropriately publish on each copy an appropriate copyright notice; keep - intact all the notices that refer to this License and to the absence of - any warranty; and give any other recipients of the Program a copy of this - License along with the Program. - -3. Modification and redistribution under closed license. - You may modify your copy or copies of the Program, and distribute - the resulting derivative works, provided that you meet the - following conditions: - a) The copyright notice and disclaimer on the Program must be reproduced - and included in the source code, documentation, and/or other materials - provided in a manner in which such notices are normally distributed. - b) The derivative work must be clearly identified as such, in order that - it may not be confused with the original work. - c) The license under which the derivative work is distributed must - expressly prohibit the distribution of further derivative works. - -4. Modification and redistribution under open license. - You may modify your copy or copies of the Program, and distribute - the resulting derivative works, provided that you meet the - following conditions: - a) The copyright notice and disclaimer on the Program must be reproduced - and included in the source code, documentation, and/or other materials - provided in a manner in which such notices are normally distributed. - b) You must clearly indicate the nature and date of any changes made - to the Program. The full details need not necessarily be included in - the individual modified files, provided that each modified file is - clearly marked as such and instructions are included on where the - full details of the modifications may be found. - c) You must cause any work that you distribute or publish, that in whole - or in part contains or is derived from the Program or any part - thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - -5. Implied acceptance. - You may not copy or distribute the Program or any derivative works except - as expressly provided under this license. Consequently, any such action - will be taken as implied acceptance of the terms of this license. - -6. NO WARRANTY. - THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - THE COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR - REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING, BUT - NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR - TORT, EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE - POSSIBILITY OF SUCH DAMAGES. diff --git a/src/bsdiff-4.2/Makefile.am b/src/bsdiff-4.2/Makefile.am deleted file mode 100644 index 70f2ead7cc48..000000000000 --- a/src/bsdiff-4.2/Makefile.am +++ /dev/null @@ -1,7 +0,0 @@ -libexec_PROGRAMS = bsdiff bspatch - -bsdiff_SOURCES = bsdiff.c - -bspatch_SOURCES = bspatch.c - -AM_CFLAGS = -O3 -DBZIP2=\"$(bzip2)\" diff --git a/src/bsdiff-4.2/Makefile.old b/src/bsdiff-4.2/Makefile.old deleted file mode 100644 index ce5dd344d403..000000000000 --- a/src/bsdiff-4.2/Makefile.old +++ /dev/null @@ -1,18 +0,0 @@ -CFLAGS += -O3 -.ifdef BZIP2 -CFLAGS += -DBZIP2=\"${BZIP2}\" -.endif - -PREFIX ?= /usr/local -INSTALL_PROGRAM ?= ${INSTALL} -c -s -m 555 -INSTALL_MAN ?= ${INSTALL} -c -m 444 - -all: bsdiff bspatch -bsdiff: bsdiff.c -bspatch: bspatch.c - -install: - ${INSTALL_PROGRAM} bsdiff bspatch ${PREFIX}/bin -.ifndef WITHOUT_MAN - ${INSTALL_MAN} bsdiff.1 bspatch.1 ${PREFIX}/man/man1 -.endif diff --git a/src/bsdiff-4.2/bsdiff.1 b/src/bsdiff-4.2/bsdiff.1 deleted file mode 100644 index 8d3926d3298c..000000000000 --- a/src/bsdiff-4.2/bsdiff.1 +++ /dev/null @@ -1,36 +0,0 @@ -.Dd May 18, 2003 -.Dt BSDIFF 1 -.Os FreeBSD -.Sh NAME -.Nm bsdiff -.Nd generate a patch between two binary files -.Sh SYNOPSIS -.Nm -.Ao Ar oldfile Ac Ao Ar newfile Ac Ao Ar patchfile Ac -.Sh DESCRIPTION -.Nm -compares -.Ao Ar oldfile Ac -to -.Ao Ar newfile Ac -and writes to -.Ao Ar patchfile Ac -a binary patch suitable for use by bspatch(1). -When -.Ao Ar oldfile Ac -and -.Ao Ar newfile Ac -are two versions of an executable program, the -patches produced are on average a factor of five smaller -than those produced by any other binary patch tool known -to the author. -.Pp -.Nm -uses memory equal to 17 times the size of -.Ao Ar oldfile Ac , -and requires -an absolute minimum working set size of 8 times the size of oldfile. -.Sh SEE ALSO -.Xr bspatch 1 -.Sh AUTHORS -.An Colin Percival Aq cperciva@daemonology.net diff --git a/src/bsdiff-4.2/bsdiff.c b/src/bsdiff-4.2/bsdiff.c deleted file mode 100644 index f47226c1e0a6..000000000000 --- a/src/bsdiff-4.2/bsdiff.c +++ /dev/null @@ -1,385 +0,0 @@ -/* - bsdiff.c -- Binary patch generator. - - Copyright 2003 Colin Percival - - For the terms under which this work may be distributed, please see - the adjoining file "LICENSE". -*/ - -#ifndef BZIP2 -#define BZIP2 "/usr/bin/bzip2" -#endif - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <err.h> -#include <unistd.h> -#include <fcntl.h> -#include <sys/wait.h> - -#define MIN(x,y) (((x)<(y)) ? (x) : (y)) - -void split(off_t *I,off_t *V,off_t start,off_t len,off_t h) -{ - off_t i,j,k,x,tmp,jj,kk; - - if(len<16) { - for(k=start;k<start+len;k+=j) { - j=1;x=V[I[k]+h]; - for(i=1;k+i<start+len;i++) { - if(V[I[k+i]+h]<x) { - x=V[I[k+i]+h]; - j=0; - }; - if(V[I[k+i]+h]==x) { - tmp=I[k+j];I[k+j]=I[k+i];I[k+i]=tmp; - j++; - }; - }; - for(i=0;i<j;i++) V[I[k+i]]=k+j-1; - if(j==1) I[k]=-1; - }; - return; - }; - - x=V[I[start+len/2]+h]; - jj=0;kk=0; - for(i=start;i<start+len;i++) { - if(V[I[i]+h]<x) jj++; - if(V[I[i]+h]==x) kk++; - }; - jj+=start;kk+=jj; - - i=start;j=0;k=0; - while(i<jj) { - if(V[I[i]+h]<x) { - i++; - } else if(V[I[i]+h]==x) { - tmp=I[i];I[i]=I[jj+j];I[jj+j]=tmp; - j++; - } else { - tmp=I[i];I[i]=I[kk+k];I[kk+k]=tmp; - k++; - }; - }; - - while(jj+j<kk) { - if(V[I[jj+j]+h]==x) { - j++; - } else { - tmp=I[jj+j];I[jj+j]=I[kk+k];I[kk+k]=tmp; - k++; - }; - }; - - if(jj>start) split(I,V,start,jj-start,h); - - for(i=0;i<kk-jj;i++) V[I[jj+i]]=kk-1; - if(jj==kk-1) I[jj]=-1; - - if(start+len>kk) split(I,V,kk,start+len-kk,h); -} - -void qsufsort(off_t *I,off_t *V,u_char *old,off_t oldsize) -{ - off_t buckets[256]; - off_t i,h,len; - - for(i=0;i<256;i++) buckets[i]=0; - for(i=0;i<oldsize;i++) buckets[old[i]]++; - for(i=1;i<256;i++) buckets[i]+=buckets[i-1]; - for(i=255;i>0;i--) buckets[i]=buckets[i-1]; - buckets[0]=0; - - for(i=0;i<oldsize;i++) I[++buckets[old[i]]]=i; - I[0]=oldsize; - for(i=0;i<oldsize;i++) V[i]=buckets[old[i]]; - V[oldsize]=0; - for(i=1;i<256;i++) if(buckets[i]==buckets[i-1]+1) I[buckets[i]]=-1; - I[0]=-1; - - for(h=1;I[0]!=-(oldsize+1);h+=h) { - len=0; - for(i=0;i<oldsize+1;) { - if(I[i]<0) { - len-=I[i]; - i-=I[i]; - } else { - if(len) I[i-len]=-len; - len=V[I[i]]+1-i; - split(I,V,i,len,h); - i+=len; - len=0; - }; - }; - if(len) I[i-len]=-len; - }; - - for(i=0;i<oldsize+1;i++) I[V[i]]=i; -} - -off_t matchlen(u_char *old,off_t oldsize,u_char *new,off_t newsize) -{ - off_t i; - - for(i=0;(i<oldsize)&&(i<newsize);i++) - if(old[i]!=new[i]) break; - - return i; -} - -off_t search(off_t *I,u_char *old,off_t oldsize, - u_char *new,off_t newsize,off_t st,off_t en,off_t *pos) -{ - off_t x,y; - - if(en-st<2) { - x=matchlen(old+I[st],oldsize-I[st],new,newsize); - y=matchlen(old+I[en],oldsize-I[en],new,newsize); - - if(x>y) { - *pos=I[st]; - return x; - } else { - *pos=I[en]; - return y; - } - }; - - x=st+(en-st)/2; - if(memcmp(old+I[x],new,MIN(oldsize-I[x],newsize))<0) { - return search(I,old,oldsize,new,newsize,x,en,pos); - } else { - return search(I,old,oldsize,new,newsize,st,x,pos); - }; -} - -void offtout(off_t x,u_char *buf) -{ - off_t y; - - if(x<0) y=-x; else y=x; - - buf[0]=y%256;y-=buf[0]; - y=y/256;buf[1]=y%256;y-=buf[1]; - y=y/256;buf[2]=y%256;y-=buf[2]; - y=y/256;buf[3]=y%256;y-=buf[3]; - y=y/256;buf[4]=y%256;y-=buf[4]; - y=y/256;buf[5]=y%256;y-=buf[5]; - y=y/256;buf[6]=y%256;y-=buf[6]; - y=y/256;buf[7]=y%256; - - if(x<0) buf[7]|=0x80; -} - -int main(int argc,char *argv[]) -{ - int fd,p[2]; - pid_t pid; - 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]; - - 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,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=malloc((oldsize+1)*sizeof(off_t)))==NULL) || - ((V=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,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=malloc(newsize+1))==NULL) || - ((eb=malloc(newsize+1))==NULL)) err(1,NULL); - dblen=0; - eblen=0; - - if((fd=open(argv[3],O_CREAT|O_TRUNC|O_WRONLY,0666))<0) - 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); - memset(header+8,0,24); - if(write(fd,header,32)!=32) err(1,"%s",argv[3]); - - if((pipe(p)==-1) || ((pid=fork())==-1)) err(1,NULL); - if(pid==0) { - if((close(0)==-1) || (close(1)==-1) || (dup2(fd,1)==-1) || - (dup2(p[0],0)==-1) || (close(fd)==-1) || - (close(p[0])==-1) || (close(p[1])==-1)) - err(1,NULL); - execl(BZIP2,BZIP2,"-zc",NULL); - err(1,"%s",BZIP2); - }; - if(close(p[0])==-1) err(1,NULL); - - 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); - if(write(p[1],buf,8)!=8) err(1,NULL); - offtout((scan-lenb)-(lastscan+lenf),buf); - if(write(p[1],buf,8)!=8) err(1,NULL); - offtout((pos-lenb)-(lastpos+lenf),buf); - if(write(p[1],buf,8)!=8) err(1,NULL); - - lastscan=scan-lenb; - lastpos=pos-lenb; - lastoffset=pos-scan; - }; - }; - - if((close(p[1])==-1) || (waitpid(pid,NULL,0)!=pid)) err(1,NULL); - - if((len=lseek(fd,0,SEEK_END))==-1) err(1,"%s",argv[3]); - offtout(len-32,buf); - if((lseek(fd,8,SEEK_SET)!=8) || (write(fd,buf,8)!=8)) - err(1,"%s",argv[3]); - offtout(newsize,buf); - if((lseek(fd,24,SEEK_SET)!=24) || (write(fd,buf,8)!=8)) - err(1,"%s",argv[3]); - - if(lseek(fd,0,SEEK_END)==-1) err(1,"%s",argv[3]); - if((pipe(p)==-1) || ((pid=fork())==-1)) err(1,NULL); - if(pid==0) { - if((close(0)==-1) || (close(1)==-1) || (dup2(fd,1)==-1) || - (dup2(p[0],0)==-1) || (close(fd)==-1) || - (close(p[0])==-1) || (close(p[1])==-1)) - err(1,NULL); - execl(BZIP2,BZIP2,"-zc",NULL); - err(1,"%s",BZIP2); - }; - if(close(p[0])==-1) err(1,NULL); - if(write(p[1],db,dblen)!=dblen) err(1,NULL); - if((close(p[1])==-1) || (waitpid(pid,NULL,0)!=pid)) err(1,NULL); - - if((newsize=lseek(fd,0,SEEK_END))==-1) err(1,"%s",argv[3]); - offtout(newsize-len,buf); - if((lseek(fd,16,SEEK_SET)!=16) || (write(fd,buf,8)!=8)) - err(1,"%s",argv[3]); - - if(lseek(fd,0,SEEK_END)==-1) err(1,"%s",argv[3]); - if((pipe(p)==-1) || ((pid=fork())==-1)) err(1,NULL); - if(pid==0) { - if((close(0)==-1) || (close(1)==-1) || (dup2(fd,1)==-1) || - (dup2(p[0],0)==-1) || (close(fd)==-1) || - (close(p[0])==-1) || (close(p[1])==-1)) - err(1,NULL); - execl(BZIP2,BZIP2,"-zc",NULL); - err(1,"%s",BZIP2); - }; - if(close(p[0])==-1) err(1,NULL); - if(write(p[1],eb,eblen)!=eblen) err(1,NULL); - if((close(p[1])==-1) || (waitpid(pid,NULL,0)!=pid)) err(1,NULL); - if(close(fd)==-1) err(1,"%s",argv[3]); - - free(db); - free(eb); - free(I); - free(old); - free(new); - - return 0; -} diff --git a/src/bsdiff-4.2/bspatch.1 b/src/bsdiff-4.2/bspatch.1 deleted file mode 100644 index b243f2b7b120..000000000000 --- a/src/bsdiff-4.2/bspatch.1 +++ /dev/null @@ -1,32 +0,0 @@ -.Dd May 18, 2003 -.Dt BSPATCH 1 -.Os FreeBSD -.Sh NAME -.Nm bspatch -.Nd apply a patch built with bsdiff(1) -.Sh SYNOPSIS -.Nm -.Ao Ar oldfile Ac Ao Ar newfile Ac Ao Ar patchfile Ac -.Sh DESCRIPTION -.Nm -generates -.Ao Ar newfile Ac -from -.Ao Ar oldfile Ac -and -.Ao Ar patchfile Ac -where -.Ao Ar patchfile Ac -is a binary patch built by bsdiff(1). -.Pp -.Nm -uses memory equal to the size of -.Ao Ar oldfile Ac -plus the size of -.Ao Ar newfile Ac , -but can tolerate a very small working set without a dramatic loss -of performance. -.Sh SEE ALSO -.Xr bsdiff 1 -.Sh AUTHORS -.An Colin Percival Aq cperciva@daemonology.net diff --git a/src/bsdiff-4.2/bspatch.c b/src/bsdiff-4.2/bspatch.c deleted file mode 100644 index 1386a7096213..000000000000 --- a/src/bsdiff-4.2/bspatch.c +++ /dev/null @@ -1,216 +0,0 @@ -/* - .c -- Binary patcher - - Copyright 2003,2004 Colin Percival - - For the terms under which this work may be distributed, please see - the adjoining file "LICENSE". -*/ - -#ifndef BZIP2 -#define BZIP2 "/usr/bin/bzip2" -#endif - -#include <stdlib.h> -#include <stdio.h> -#include <err.h> -#include <unistd.h> -#include <fcntl.h> -#include <sys/wait.h> - -ssize_t loopread(int d,void *buf,size_t nbytes) -{ - ssize_t ptr,lenread; - - for(ptr=0;ptr<nbytes;ptr+=lenread) { - lenread=read(d,buf+ptr,nbytes-ptr); - if(lenread==0) return ptr; - if(lenread==-1) return -1; - }; - return ptr; -} - -int bz2read(int fd,off_t offset,off_t len,char * fname,pid_t * pids) -{ - int p0[2],p1[2]; - u_char * data; - - if((pipe(p0)==-1) || (pipe(p1)==-1)) err(1,NULL); - - if((pids[0]=fork())==-1) err(1,NULL); - if(pids[0]==0) { - if(close(0) || close(1) || close(p0[0]) || - close(p1[0]) || close(p1[1])) err(1,NULL); - if((data=malloc(len+1))==NULL) err(1,NULL); - if((pread(fd,data,len,offset)!=len) || close(fd)) - err(1,"%s",fname); - if((write(p0[1],data,len)!=len) || close(p0[1])) - err(1,NULL); - free(data); - _exit(0); - }; - - if((pids[1]=fork())==-1) err(1,NULL); - if(pids[1]==0) { - if(close(0) || close(1) || close(p0[1]) || - close(p1[0])) err(1,NULL); - if((dup2(p0[0],0)==-1) || close(p0[0])) err(1,NULL); - if((dup2(p1[1],1)==-1) || close(p1[1])) err(1,NULL); - if(close(fd)==-1) err(1,"%s",fname); - - execl(BZIP2,BZIP2,"-dc",NULL); - err(1,"%s",BZIP2); - }; - - if(close(p0[0]) || close(p0[1]) || close(p1[1])) err(1,NULL); - - return p1[0]; -} - -off_t offtin(u_char *buf) -{ - off_t y; - - y=buf[7]&0x7F; - y=y*256;y+=buf[6]; - y=y*256;y+=buf[5]; - y=y*256;y+=buf[4]; - y=y*256;y+=buf[3]; - y=y*256;y+=buf[2]; - y=y*256;y+=buf[1]; - y=y*256;y+=buf[0]; - - if(buf[7]&0x80) y=-y; - - return y; -} - -int main(int argc,char * argv[]) -{ - int fd,ctrlpipe,diffpipe,extrapipe; - pid_t pids[6]; - ssize_t patchsize,oldsize,newsize; - ssize_t bzctrllen,bzdatalen; - u_char header[32],buf[8]; - int version=0; - u_char *old, *new; - off_t oldpos,newpos; - off_t ctrl[3]; - off_t lenread; - off_t i; - - if(argc!=4) errx(1,"usage: %s oldfile newfile patchfile\n",argv[0]); - - if(((fd=open(argv[3],O_RDONLY,0))<0) || - ((patchsize=lseek(fd,0,SEEK_END))==-1) || - (lseek(fd,0,SEEK_SET)!=0)) err(1,"%s",argv[3]); - if(patchsize<32) errx(1,"Corrupt patch\n"); - - /* - Ok, this is going to be messy. There are two different patch - formats which we need to support. - - The old format (pre-4.0) is: - 0 8 "QSUFDIFF" or "BSDIFF30" - 8 8 X - 16 8 Y - 24 8 sizeof(newfile) - 32 X bzip2(control block) - 32+X Y bzip2(data block) - with control block a set of pairs (x,y) meaning "seek forward - in oldfile by y bytes, and add the next x bytes to x bytes from - the data block". - - The new format (4.0) is: - 0 8 "BSDIFF40" - 8 8 X - 16 8 Y - 24 8 sizeof(newfile) - 32 X bzip2(control block) - 32+X Y bzip2(diff block) - 32+X+Y ??? bzip2(extra block) - with control block a set of triples (x,y,z) meaning "add x bytes - from oldfile to x bytes from the diff block; copy y bytes from the - extra block; seek forwards in oldfile by z bytes". - */ - - if(read(fd,header,32)!=32) err(1,"%s",argv[3]); - if(memcmp(header,"QSUFDIFF",8)==0) version=1; - if(memcmp(header,"BSDIFF30",8)==0) version=1; - if(memcmp(header,"BSDIFF40",8)==0) version=2; - - if(!version) errx(1,"Corrupt patch\n"); - - bzctrllen=offtin(header+8); - bzdatalen=offtin(header+16); - newsize=offtin(header+24); - if((bzctrllen<0) || (bzdatalen<0) || (newsize<0) || - ((version==1) && (32+bzctrllen+bzdatalen!=patchsize))) - errx(1,"Corrupt patch\n"); - - ctrlpipe=bz2read(fd,32,bzctrllen,argv[3],pids); - diffpipe=bz2read(fd,32+bzctrllen,bzdatalen,argv[3],pids+2); - if(version==2) { - extrapipe=bz2read(fd,32+bzctrllen+bzdatalen, - patchsize-(32+bzctrllen+bzdatalen),argv[3],pids+4); - }; - - if(close(fd)==-1) err(1,"%s",argv[3]); - 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((new=malloc(newsize+1))==NULL) err(1,NULL); - - oldpos=0;newpos=0; - while(newpos<newsize) { - for(i=0;i<=version;i++) { - if((lenread=loopread(ctrlpipe,buf,8))<0) err(1,NULL); - if(lenread<8) errx(1,"Corrupt patch\n"); - ctrl[i]=offtin(buf); - }; - - if(version==1) oldpos+=ctrl[1]; - - if(newpos+ctrl[0]>newsize) errx(1,"Corrupt patch\n"); - if((lenread=loopread(diffpipe,new+newpos,ctrl[0]))<0) - err(1,NULL); - if(lenread!=ctrl[0]) errx(1,"Corrupt patch\n"); - for(i=0;i<ctrl[0];i++) - if((oldpos+i>=0) && (oldpos+i<oldsize)) - new[newpos+i]+=old[oldpos+i]; - newpos+=ctrl[0]; - oldpos+=ctrl[0]; - - if(version==2) { - if(newpos+ctrl[1]>newsize) errx(1,"Corrupt patch\n"); - if((lenread=loopread(extrapipe,new+newpos,ctrl[1]))<0) - err(1,NULL); - if(lenread!=ctrl[1]) errx(1,"Corrupt patch\n"); - - newpos+=ctrl[1]; - oldpos+=ctrl[2]; - }; - }; - - if(loopread(ctrlpipe,buf,1)!=0) errx(1,"Corrupt patch\n"); - if(loopread(diffpipe,buf,1)!=0) errx(1,"Corrupt patch\n"); - if(version==2) - if(loopread(extrapipe,buf,1)!=0) errx(1,"Corrupt patch\n"); - - if(close(ctrlpipe) || close(diffpipe) || - ((version==2) && close(extrapipe))) - err(1,NULL); - for(i=0;i<(version+1)*2;i++) waitpid(pids[i],NULL,0); - - if(((fd=open(argv[2],O_CREAT|O_TRUNC|O_WRONLY,0666))<0) || - (write(fd,new,newsize)!=newsize) || (close(fd)==-1)) - err(1,"%s",argv[2]); - - free(new); - free(old); - - return 0; -} |