* bsdiff updated to 4.3. This makes Nix depend on libbz2.

This commit is contained in:
Eelco Dolstra 2006-02-01 16:48:49 +00:00
parent 9e4ffc43a2
commit 8291f6d968
15 changed files with 464 additions and 520 deletions

View file

@ -77,8 +77,6 @@ fi
]) ])
NEED_PROG(curl, curl) NEED_PROG(curl, curl)
NEED_PROG(bzip2, bzip2)
NEED_PROG(bunzip2, bunzip2)
NEED_PROG(shell, sh) NEED_PROG(shell, sh)
AC_PATH_PROG(xmllint, xmllint, false) AC_PATH_PROG(xmllint, xmllint, false)
AC_PATH_PROG(xsltproc, xsltproc, false) AC_PATH_PROG(xsltproc, xsltproc, false)
@ -145,6 +143,26 @@ AC_SUBST(aterm_lib)
AC_SUBST(aterm_include) AC_SUBST(aterm_include)
AC_SUBST(aterm_bin) AC_SUBST(aterm_bin)
AC_ARG_WITH(bzip2, AC_HELP_STRING([--with-bzip2=PATH],
[prefix of bzip2]),
bzip2=$withval, bzip2=)
if test -z "$bzip2"; then
AC_CHECK_LIB(bz2, BZ2_bzWriteOpen,
[bzip2_lib="-lbz2"], [AC_MSG_ERROR([cannot find -lbz (bzip2)])])
AC_CHECK_HEADER(bzlib.h,
[bzip2_include=""], [AC_MSG_ERROR([cannot find bzlib.h (bzip2)])])
AC_PATH_PROG(bzip2_prog, bzip2,
[AC_MSG_ERROR([cannot find bzip2])])
bzip2_bin=$(dirname $bzip2_prog)
else
bzip2_lib="-L$bzip2/lib -lbz2"
bzip2_include="-I$bzip2/include"
bzip2_bin="$bzip2/bin"
fi
AC_SUBST(bzip2_lib)
AC_SUBST(bzip2_include)
AC_SUBST(bzip2_bin)
AC_CHECK_LIB(pthread, pthread_mutex_init) AC_CHECK_LIB(pthread, pthread_mutex_init)
AC_ARG_ENABLE(init-state, AC_HELP_STRING([--disable-init-state], AC_ARG_ENABLE(init-state, AC_HELP_STRING([--disable-init-state],
@ -203,7 +221,7 @@ AC_CONFIG_FILES([Makefile
src/nix-instantiate/Makefile src/nix-instantiate/Makefile
src/nix-env/Makefile src/nix-env/Makefile
src/nix-log2xml/Makefile src/nix-log2xml/Makefile
src/bsdiff-4.2/Makefile src/bsdiff-4.3/Makefile
scripts/Makefile scripts/Makefile
corepkgs/Makefile corepkgs/Makefile
corepkgs/nar/Makefile corepkgs/nar/Makefile

View file

@ -1,5 +1,5 @@
SUBDIRS = bin2c boost libutil libstore libmain nix-store nix-hash \ SUBDIRS = bin2c boost libutil libstore libmain nix-store nix-hash \
libexpr nix-instantiate nix-env nix-log2xml bsdiff-4.2 libexpr nix-instantiate nix-env nix-log2xml bsdiff-4.3
EXTRA_DIST = aterm-helper.pl EXTRA_DIST = aterm-helper.pl

View file

@ -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.

View file

@ -1,7 +0,0 @@
libexec_PROGRAMS = bsdiff bspatch
bsdiff_SOURCES = bsdiff.c
bspatch_SOURCES = bspatch.c
AM_CFLAGS = -O3 -DBZIP2=\"$(bzip2)\"

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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;
}

View file

@ -0,0 +1,11 @@
libexec_PROGRAMS = bsdiff bspatch
bsdiff_SOURCES = bsdiff.c
bsdiff_LDADD = ${bzip2_lib}
bspatch_SOURCES = bspatch.c
bspatch_LDADD = ${bzip2_lib}
AM_CFLAGS = -O3 ${bzip2_include}

63
src/bsdiff-4.3/bsdiff.1 Normal file
View file

@ -0,0 +1,63 @@
.\"-
.\" Copyright 2003-2005 Colin Percival
.\" All rights reserved
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted providing that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR BE LIABLE FOR ANY
.\" DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (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 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
.\" IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
.\" $FreeBSD: src/usr.bin/bsdiff/bsdiff/bsdiff.1,v 1.1 2005/08/06 01:59:05 cperciva Exp $
.\"
.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@freebsd.org

View file

@ -1,27 +1,46 @@
/* /*-
bsdiff.c -- Binary patch generator. * Copyright 2003-2005 Colin Percival
* All rights reserved
Copyright 2003 Colin Percival *
* Redistribution and use in source and binary forms, with or without
For the terms under which this work may be distributed, please see * modification, are permitted providing that the following conditions
the adjoining file "LICENSE". * are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (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 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef BZIP2 #if 0
#define BZIP2 "/usr/bin/bzip2" __FBSDID("$FreeBSD: src/usr.bin/bsdiff/bsdiff/bsdiff.c,v 1.1 2005/08/06 01:59:05 cperciva Exp $");
#endif #endif
#include <stdlib.h> #include <sys/types.h>
#include <stdio.h>
#include <string.h> #include <bzlib.h>
#include <err.h> #include <err.h>
#include <unistd.h>
#include <fcntl.h> #include <fcntl.h>
#include <sys/wait.h> #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define MIN(x,y) (((x)<(y)) ? (x) : (y)) #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) static 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; off_t i,j,k,x,tmp,jj,kk;
@ -82,7 +101,7 @@ void split(off_t *I,off_t *V,off_t start,off_t len,off_t h)
if(start+len>kk) split(I,V,kk,start+len-kk,h); 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) static void qsufsort(off_t *I,off_t *V,u_char *old,off_t oldsize)
{ {
off_t buckets[256]; off_t buckets[256];
off_t i,h,len; off_t i,h,len;
@ -120,7 +139,7 @@ void qsufsort(off_t *I,off_t *V,u_char *old,off_t oldsize)
for(i=0;i<oldsize+1;i++) I[V[i]]=i; 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) static off_t matchlen(u_char *old,off_t oldsize,u_char *new,off_t newsize)
{ {
off_t i; off_t i;
@ -130,7 +149,7 @@ off_t matchlen(u_char *old,off_t oldsize,u_char *new,off_t newsize)
return i; return i;
} }
off_t search(off_t *I,u_char *old,off_t oldsize, static 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) u_char *new,off_t newsize,off_t st,off_t en,off_t *pos)
{ {
off_t x,y; off_t x,y;
@ -156,7 +175,7 @@ off_t search(off_t *I,u_char *old,off_t oldsize,
}; };
} }
void offtout(off_t x,u_char *buf) static void offtout(off_t x,u_char *buf)
{ {
off_t y; off_t y;
@ -176,25 +195,23 @@ void offtout(off_t x,u_char *buf)
int main(int argc,char *argv[]) int main(int argc,char *argv[])
{ {
int fd,p[2]; int fd;
pid_t pid;
u_char *old,*new; u_char *old,*new;
off_t oldsize,newsize; off_t oldsize,newsize;
off_t *I,*V; off_t *I,*V;
off_t scan,pos,len; off_t scan,pos,len;
off_t lastscan,lastpos,lastoffset; off_t lastscan,lastpos,lastoffset;
off_t oldscore,scsc; off_t oldscore,scsc;
off_t s,Sf,lenf,Sb,lenb; off_t s,Sf,lenf,Sb,lenb;
off_t overlap,Ss,lens; off_t overlap,Ss,lens;
off_t i; off_t i;
off_t dblen,eblen; off_t dblen,eblen;
u_char *db,*eb; u_char *db,*eb;
u_char buf[8]; u_char buf[8];
u_char header[32]; u_char header[32];
FILE * pf;
BZFILE * pfbz2;
int bz2err;
if(argc!=4) errx(1,"usage: %s oldfile newfile patchfile\n",argv[0]); if(argc!=4) errx(1,"usage: %s oldfile newfile patchfile\n",argv[0]);
@ -228,7 +245,8 @@ int main(int argc,char *argv[])
dblen=0; dblen=0;
eblen=0; eblen=0;
if((fd=open(argv[3],O_CREAT|O_TRUNC|O_WRONLY,0666))<0) /* Create the patch file */
if ((pf = fopen(argv[3], "w")) == NULL)
err(1, "%s", argv[3]); err(1, "%s", argv[3]);
/* Header is /* Header is
@ -242,20 +260,15 @@ int main(int argc,char *argv[])
?? ?? Bzip2ed diff block ?? ?? Bzip2ed diff block
?? ?? Bzip2ed extra block */ ?? ?? Bzip2ed extra block */
memcpy(header,"BSDIFF40",8); memcpy(header,"BSDIFF40",8);
memset(header+8,0,24); offtout(0, header + 8);
if(write(fd,header,32)!=32) err(1,"%s",argv[3]); offtout(0, header + 16);
offtout(newsize, header + 24);
if((pipe(p)==-1) || ((pid=fork())==-1)) err(1,NULL); if (fwrite(header, 32, 1, pf) != 1)
if(pid==0) { err(1, "fwrite(%s)", argv[3]);
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);
/* 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; scan=0;len=0;
lastscan=0;lastpos=0;lastoffset=0; lastscan=0;lastpos=0;lastoffset=0;
while(scan<newsize) { while(scan<newsize) {
@ -319,62 +332,68 @@ int main(int argc,char *argv[])
eblen+=(scan-lenb)-(lastscan+lenf); eblen+=(scan-lenb)-(lastscan+lenf);
offtout(lenf,buf); offtout(lenf,buf);
if(write(p[1],buf,8)!=8) err(1,NULL); BZ2_bzWrite(&bz2err, pfbz2, buf, 8);
if (bz2err != BZ_OK)
errx(1, "BZ2_bzWrite, bz2err = %d", bz2err);
offtout((scan-lenb)-(lastscan+lenf),buf); offtout((scan-lenb)-(lastscan+lenf),buf);
if(write(p[1],buf,8)!=8) err(1,NULL); BZ2_bzWrite(&bz2err, pfbz2, buf, 8);
if (bz2err != BZ_OK)
errx(1, "BZ2_bzWrite, bz2err = %d", bz2err);
offtout((pos-lenb)-(lastpos+lenf),buf); offtout((pos-lenb)-(lastpos+lenf),buf);
if(write(p[1],buf,8)!=8) err(1,NULL); BZ2_bzWrite(&bz2err, pfbz2, buf, 8);
if (bz2err != BZ_OK)
errx(1, "BZ2_bzWrite, bz2err = %d", bz2err);
lastscan=scan-lenb; lastscan=scan-lenb;
lastpos=pos-lenb; lastpos=pos-lenb;
lastoffset=pos-scan; lastoffset=pos-scan;
}; };
}; };
BZ2_bzWriteClose(&bz2err, pfbz2, 0, NULL, NULL);
if (bz2err != BZ_OK)
errx(1, "BZ2_bzWriteClose, bz2err = %d", bz2err);
if((close(p[1])==-1) || (waitpid(pid,NULL,0)!=pid)) err(1,NULL); /* Compute size of compressed ctrl data */
if ((len = ftello(pf)) == -1)
err(1, "ftello");
offtout(len-32, header + 8);
if((len=lseek(fd,0,SEEK_END))==-1) err(1,"%s",argv[3]); /* Write compressed diff data */
offtout(len-32,buf); if ((pfbz2 = BZ2_bzWriteOpen(&bz2err, pf, 9, 0, 0)) == NULL)
if((lseek(fd,8,SEEK_SET)!=8) || (write(fd,buf,8)!=8)) errx(1, "BZ2_bzWriteOpen, bz2err = %d", bz2err);
err(1,"%s",argv[3]); BZ2_bzWrite(&bz2err, pfbz2, db, dblen);
offtout(newsize,buf); if (bz2err != BZ_OK)
if((lseek(fd,24,SEEK_SET)!=24) || (write(fd,buf,8)!=8)) errx(1, "BZ2_bzWrite, bz2err = %d", bz2err);
err(1,"%s",argv[3]); BZ2_bzWriteClose(&bz2err, pfbz2, 0, NULL, NULL);
if (bz2err != BZ_OK)
errx(1, "BZ2_bzWriteClose, bz2err = %d", bz2err);
if(lseek(fd,0,SEEK_END)==-1) err(1,"%s",argv[3]); /* Compute size of compressed diff data */
if((pipe(p)==-1) || ((pid=fork())==-1)) err(1,NULL); if ((newsize = ftello(pf)) == -1)
if(pid==0) { err(1, "ftello");
if((close(0)==-1) || (close(1)==-1) || (dup2(fd,1)==-1) || offtout(newsize - len, header + 16);
(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]); /* Write compressed extra data */
offtout(newsize-len,buf); if ((pfbz2 = BZ2_bzWriteOpen(&bz2err, pf, 9, 0, 0)) == NULL)
if((lseek(fd,16,SEEK_SET)!=16) || (write(fd,buf,8)!=8)) errx(1, "BZ2_bzWriteOpen, bz2err = %d", bz2err);
err(1,"%s",argv[3]); 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(lseek(fd,0,SEEK_END)==-1) err(1,"%s",argv[3]); /* Seek to the beginning, write the header, and close the file */
if((pipe(p)==-1) || ((pid=fork())==-1)) err(1,NULL); if (fseeko(pf, 0, SEEK_SET))
if(pid==0) { err(1, "fseeko");
if((close(0)==-1) || (close(1)==-1) || (dup2(fd,1)==-1) || if (fwrite(header, 32, 1, pf) != 1)
(dup2(p[0],0)==-1) || (close(fd)==-1) || err(1, "fwrite(%s)", argv[3]);
(close(p[0])==-1) || (close(p[1])==-1)) if (fclose(pf))
err(1,NULL); err(1, "fclose");
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 the memory we used */
free(db); free(db);
free(eb); free(eb);
free(I); free(I);

59
src/bsdiff-4.3/bspatch.1 Normal file
View file

@ -0,0 +1,59 @@
.\"-
.\" Copyright 2003-2005 Colin Percival
.\" All rights reserved
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted providing that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR BE LIABLE FOR ANY
.\" DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (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 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
.\" IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
.\" $FreeBSD: src/usr.bin/bsdiff/bspatch/bspatch.1,v 1.1 2005/08/06 01:59:06 cperciva Exp $
.\"
.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@freebsd.org

204
src/bsdiff-4.3/bspatch.c Normal file
View file

@ -0,0 +1,204 @@
/*-
* Copyright 2003-2005 Colin Percival
* All rights reserved
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted providing that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (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 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#if 0
__FBSDID("$FreeBSD: src/usr.bin/bsdiff/bspatch/bspatch.c,v 1.1 2005/08/06 01:59:06 cperciva Exp $");
#endif
#include <bzlib.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <err.h>
#include <unistd.h>
#include <fcntl.h>
static 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[])
{
FILE * f, * cpf, * dpf, * epf;
BZFILE * cpfbz2, * dpfbz2, * epfbz2;
int cbz2err, dbz2err, ebz2err;
int fd;
ssize_t oldsize,newsize;
ssize_t bzctrllen,bzdatalen;
u_char header[32],buf[8];
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]);
/* Open patch file */
if ((f = fopen(argv[3], "r")) == NULL)
err(1, "fopen(%s)", argv[3]);
/*
File format:
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".
*/
/* Read header */
if (fread(header, 1, 32, f) < 32) {
if (feof(f))
errx(1, "Corrupt patch\n");
err(1, "fread(%s)", argv[3]);
}
/* Check for appropriate magic */
if (memcmp(header, "BSDIFF40", 8) != 0)
errx(1, "Corrupt patch\n");
/* Read lengths from header */
bzctrllen=offtin(header+8);
bzdatalen=offtin(header+16);
newsize=offtin(header+24);
if((bzctrllen<0) || (bzdatalen<0) || (newsize<0))
errx(1,"Corrupt patch\n");
/* Close patch file and re-open it via libbzip2 at the right places */
if (fclose(f))
err(1, "fclose(%s)", argv[3]);
if ((cpf = fopen(argv[3], "r")) == NULL)
err(1, "fopen(%s)", argv[3]);
if (fseeko(cpf, 32, SEEK_SET))
err(1, "fseeko(%s, %lld)", argv[3],
(long long)32);
if ((cpfbz2 = BZ2_bzReadOpen(&cbz2err, cpf, 0, 0, NULL, 0)) == NULL)
errx(1, "BZ2_bzReadOpen, bz2err = %d", cbz2err);
if ((dpf = fopen(argv[3], "r")) == NULL)
err(1, "fopen(%s)", argv[3]);
if (fseeko(dpf, 32 + bzctrllen, SEEK_SET))
err(1, "fseeko(%s, %lld)", argv[3],
(long long)(32 + bzctrllen));
if ((dpfbz2 = BZ2_bzReadOpen(&dbz2err, dpf, 0, 0, NULL, 0)) == NULL)
errx(1, "BZ2_bzReadOpen, bz2err = %d", dbz2err);
if ((epf = fopen(argv[3], "r")) == NULL)
err(1, "fopen(%s)", argv[3]);
if (fseeko(epf, 32 + bzctrllen + bzdatalen, SEEK_SET))
err(1, "fseeko(%s, %lld)", argv[3],
(long long)(32 + bzctrllen + bzdatalen));
if ((epfbz2 = BZ2_bzReadOpen(&ebz2err, epf, 0, 0, NULL, 0)) == NULL)
errx(1, "BZ2_bzReadOpen, bz2err = %d", ebz2err);
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) {
/* Read control data */
for(i=0;i<=2;i++) {
lenread = BZ2_bzRead(&cbz2err, cpfbz2, buf, 8);
if ((lenread < 8) || ((cbz2err != BZ_OK) &&
(cbz2err != BZ_STREAM_END)))
errx(1, "Corrupt patch\n");
ctrl[i]=offtin(buf);
};
/* Sanity-check */
if(newpos+ctrl[0]>newsize)
errx(1,"Corrupt patch\n");
/* Read diff string */
lenread = BZ2_bzRead(&dbz2err, dpfbz2, new + newpos, ctrl[0]);
if ((lenread < ctrl[0]) ||
((dbz2err != BZ_OK) && (dbz2err != BZ_STREAM_END)))
errx(1, "Corrupt patch\n");
/* Add old data to diff string */
for(i=0;i<ctrl[0];i++)
if((oldpos+i>=0) && (oldpos+i<oldsize))
new[newpos+i]+=old[oldpos+i];
/* Adjust pointers */
newpos+=ctrl[0];
oldpos+=ctrl[0];
/* Sanity-check */
if(newpos+ctrl[1]>newsize)
errx(1,"Corrupt patch\n");
/* Read extra string */
lenread = BZ2_bzRead(&ebz2err, epfbz2, new + newpos, ctrl[1]);
if ((lenread < ctrl[1]) ||
((ebz2err != BZ_OK) && (ebz2err != BZ_STREAM_END)))
errx(1, "Corrupt patch\n");
/* Adjust pointers */
newpos+=ctrl[1];
oldpos+=ctrl[2];
};
/* Clean up the bzip2 reads */
BZ2_bzReadClose(&cbz2err, cpfbz2);
BZ2_bzReadClose(&dbz2err, dpfbz2);
BZ2_bzReadClose(&ebz2err, epfbz2);
if (fclose(cpf) || fclose(dpf) || fclose(epf))
err(1, "fclose(%s)", argv[3]);
/* Write the new file */
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;
}

View file

@ -66,7 +66,7 @@ Hash hashString(HashType ht, const string & s);
Hash hashFile(HashType ht, const Path & path); Hash hashFile(HashType ht, const Path & path);
/* Compute the hash of the given path. The hash is defined as /* Compute the hash of the given path. The hash is defined as
md5(dump(path)). */ (essentially) hashString(ht, dumpPath(path)). */
Hash hashPath(HashType ht, const Path & path); Hash hashPath(HashType ht, const Path & path);
/* Compress a hash to the specified number of bytes by cyclically /* Compress a hash to the specified number of bytes by cyclically

View file

@ -11,8 +11,8 @@
-e "s^@system\@^$(system)^g" \ -e "s^@system\@^$(system)^g" \
-e "s^@shell\@^$(shell)^g" \ -e "s^@shell\@^$(shell)^g" \
-e "s^@curl\@^$(curl)^g" \ -e "s^@curl\@^$(curl)^g" \
-e "s^@bzip2\@^$(bzip2)^g" \ -e "s^@bzip2\@^$(bzip2_bin)/bzip2^g" \
-e "s^@bunzip2\@^$(bunzip2)^g" \ -e "s^@bunzip2\@^$(bzip2_bin)/bunzip2^g" \
-e "s^@perl\@^$(perl)^g" \ -e "s^@perl\@^$(perl)^g" \
-e "s^@coreutils\@^$(coreutils)^g" \ -e "s^@coreutils\@^$(coreutils)^g" \
-e "s^@tar\@^$(tar)^g" \ -e "s^@tar\@^$(tar)^g" \