1c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project/*-
2c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project * Copyright 2003-2005 Colin Percival
3c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project * All rights reserved
4c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project *
5c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project * Redistribution and use in source and binary forms, with or without
6c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project * modification, are permitted providing that the following conditions
7c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project * are met:
8c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project * 1. Redistributions of source code must retain the above copyright
9c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project *    notice, this list of conditions and the following disclaimer.
10c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright
11c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project *    notice, this list of conditions and the following disclaimer in the
12c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project *    documentation and/or other materials provided with the distribution.
13c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project *
14c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
18c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
22c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
23c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project * POSSIBILITY OF SUCH DAMAGE.
25c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project */
26c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project
27c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project#if 0
28c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project__FBSDID("$FreeBSD: src/usr.bin/bsdiff/bsdiff/bsdiff.c,v 1.1 2005/08/06 01:59:05 cperciva Exp $");
29c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project#endif
30c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project
31c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project#include <sys/types.h>
32c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project
33c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project#include <bzlib.h>
34c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project#include <err.h>
35c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project#include <fcntl.h>
36c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project#include <stdio.h>
37c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project#include <stdlib.h>
38c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project#include <string.h>
39c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project#include <unistd.h>
40c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project
41c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project#define MIN(x,y) (((x)<(y)) ? (x) : (y))
42c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project
43c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Projectstatic void split(off_t *I,off_t *V,off_t start,off_t len,off_t h)
44c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project{
45c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	off_t i,j,k,x,tmp,jj,kk;
46c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project
47c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	if(len<16) {
48c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project		for(k=start;k<start+len;k+=j) {
49c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project			j=1;x=V[I[k]+h];
50c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project			for(i=1;k+i<start+len;i++) {
51c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project				if(V[I[k+i]+h]<x) {
52c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project					x=V[I[k+i]+h];
53c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project					j=0;
54c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project				};
55c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project				if(V[I[k+i]+h]==x) {
56c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project					tmp=I[k+j];I[k+j]=I[k+i];I[k+i]=tmp;
57c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project					j++;
58c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project				};
59c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project			};
60c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project			for(i=0;i<j;i++) V[I[k+i]]=k+j-1;
61c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project			if(j==1) I[k]=-1;
62c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project		};
63c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project		return;
64c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	};
65c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project
66c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	x=V[I[start+len/2]+h];
67c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	jj=0;kk=0;
68c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	for(i=start;i<start+len;i++) {
69c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project		if(V[I[i]+h]<x) jj++;
70c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project		if(V[I[i]+h]==x) kk++;
71c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	};
72c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	jj+=start;kk+=jj;
73c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project
74c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	i=start;j=0;k=0;
75c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	while(i<jj) {
76c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project		if(V[I[i]+h]<x) {
77c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project			i++;
78c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project		} else if(V[I[i]+h]==x) {
79c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project			tmp=I[i];I[i]=I[jj+j];I[jj+j]=tmp;
80c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project			j++;
81c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project		} else {
82c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project			tmp=I[i];I[i]=I[kk+k];I[kk+k]=tmp;
83c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project			k++;
84c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project		};
85c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	};
86c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project
87c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	while(jj+j<kk) {
88c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project		if(V[I[jj+j]+h]==x) {
89c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project			j++;
90c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project		} else {
91c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project			tmp=I[jj+j];I[jj+j]=I[kk+k];I[kk+k]=tmp;
92c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project			k++;
93c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project		};
94c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	};
95c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project
96c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	if(jj>start) split(I,V,start,jj-start,h);
97c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project
98c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	for(i=0;i<kk-jj;i++) V[I[jj+i]]=kk-1;
99c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	if(jj==kk-1) I[jj]=-1;
100c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project
101c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	if(start+len>kk) split(I,V,kk,start+len-kk,h);
102c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project}
103c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project
104c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Projectstatic void qsufsort(off_t *I,off_t *V,u_char *old,off_t oldsize)
105c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project{
106c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	off_t buckets[256];
107c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	off_t i,h,len;
108c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project
109c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	for(i=0;i<256;i++) buckets[i]=0;
110c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	for(i=0;i<oldsize;i++) buckets[old[i]]++;
111c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	for(i=1;i<256;i++) buckets[i]+=buckets[i-1];
112c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	for(i=255;i>0;i--) buckets[i]=buckets[i-1];
113c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	buckets[0]=0;
114c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project
115c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	for(i=0;i<oldsize;i++) I[++buckets[old[i]]]=i;
116c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	I[0]=oldsize;
117c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	for(i=0;i<oldsize;i++) V[i]=buckets[old[i]];
118c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	V[oldsize]=0;
119c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	for(i=1;i<256;i++) if(buckets[i]==buckets[i-1]+1) I[buckets[i]]=-1;
120c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	I[0]=-1;
121c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project
122c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	for(h=1;I[0]!=-(oldsize+1);h+=h) {
123c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project		len=0;
124c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project		for(i=0;i<oldsize+1;) {
125c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project			if(I[i]<0) {
126c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project				len-=I[i];
127c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project				i-=I[i];
128c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project			} else {
129c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project				if(len) I[i-len]=-len;
130c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project				len=V[I[i]]+1-i;
131c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project				split(I,V,i,len,h);
132c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project				i+=len;
133c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project				len=0;
134c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project			};
135c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project		};
136c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project		if(len) I[i-len]=-len;
137c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	};
138c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project
139c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	for(i=0;i<oldsize+1;i++) I[V[i]]=i;
140c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project}
141c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project
142c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Projectstatic off_t matchlen(u_char *old,off_t oldsize,u_char *new,off_t newsize)
143c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project{
144c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	off_t i;
145c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project
146c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	for(i=0;(i<oldsize)&&(i<newsize);i++)
147c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project		if(old[i]!=new[i]) break;
148c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project
149c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	return i;
150c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project}
151c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project
152c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Projectstatic off_t search(off_t *I,u_char *old,off_t oldsize,
153c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project		u_char *new,off_t newsize,off_t st,off_t en,off_t *pos)
154c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project{
155c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	off_t x,y;
156c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project
157c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	if(en-st<2) {
158c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project		x=matchlen(old+I[st],oldsize-I[st],new,newsize);
159c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project		y=matchlen(old+I[en],oldsize-I[en],new,newsize);
160c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project
161c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project		if(x>y) {
162c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project			*pos=I[st];
163c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project			return x;
164c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project		} else {
165c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project			*pos=I[en];
166c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project			return y;
167c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project		}
168c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	};
169c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project
170c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	x=st+(en-st)/2;
171c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	if(memcmp(old+I[x],new,MIN(oldsize-I[x],newsize))<0) {
172c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project		return search(I,old,oldsize,new,newsize,x,en,pos);
173c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	} else {
174c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project		return search(I,old,oldsize,new,newsize,st,x,pos);
175c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	};
176c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project}
177c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project
178c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Projectstatic void offtout(off_t x,u_char *buf)
179c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project{
180c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	off_t y;
181c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project
182c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	if(x<0) y=-x; else y=x;
183c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project
184c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project		buf[0]=y%256;y-=buf[0];
185c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	y=y/256;buf[1]=y%256;y-=buf[1];
186c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	y=y/256;buf[2]=y%256;y-=buf[2];
187c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	y=y/256;buf[3]=y%256;y-=buf[3];
188c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	y=y/256;buf[4]=y%256;y-=buf[4];
189c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	y=y/256;buf[5]=y%256;y-=buf[5];
190c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	y=y/256;buf[6]=y%256;y-=buf[6];
191c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	y=y/256;buf[7]=y%256;
192c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project
193c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	if(x<0) buf[7]|=0x80;
194c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project}
195c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project
196c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Projectint main(int argc,char *argv[])
197c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project{
198c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	int fd;
199c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	u_char *old,*new;
200c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	off_t oldsize,newsize;
201c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	off_t *I,*V;
202c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	off_t scan,pos,len;
203c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	off_t lastscan,lastpos,lastoffset;
204c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	off_t oldscore,scsc;
205c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	off_t s,Sf,lenf,Sb,lenb;
206c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	off_t overlap,Ss,lens;
207c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	off_t i;
208c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	off_t dblen,eblen;
209c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	u_char *db,*eb;
210c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	u_char buf[8];
211c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	u_char header[32];
212c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	FILE * pf;
213c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	BZFILE * pfbz2;
214c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	int bz2err;
215c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project
216c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	if(argc!=4) errx(1,"usage: %s oldfile newfile patchfile\n",argv[0]);
217c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project
218c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	/* Allocate oldsize+1 bytes instead of oldsize bytes to ensure
219c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project		that we never try to malloc(0) and get a NULL pointer */
220c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	if(((fd=open(argv[1],O_RDONLY,0))<0) ||
221c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project		((oldsize=lseek(fd,0,SEEK_END))==-1) ||
222c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project		((old=malloc(oldsize+1))==NULL) ||
223c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project		(lseek(fd,0,SEEK_SET)!=0) ||
224c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project		(read(fd,old,oldsize)!=oldsize) ||
225c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project		(close(fd)==-1)) err(1,"%s",argv[1]);
226c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project
227c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	if(((I=malloc((oldsize+1)*sizeof(off_t)))==NULL) ||
228c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project		((V=malloc((oldsize+1)*sizeof(off_t)))==NULL)) err(1,NULL);
229c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project
230c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	qsufsort(I,V,old,oldsize);
231c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project
232c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	free(V);
233c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project
234c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	/* Allocate newsize+1 bytes instead of newsize bytes to ensure
235c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project		that we never try to malloc(0) and get a NULL pointer */
236c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	if(((fd=open(argv[2],O_RDONLY,0))<0) ||
237c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project		((newsize=lseek(fd,0,SEEK_END))==-1) ||
238c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project		((new=malloc(newsize+1))==NULL) ||
239c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project		(lseek(fd,0,SEEK_SET)!=0) ||
240c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project		(read(fd,new,newsize)!=newsize) ||
241c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project		(close(fd)==-1)) err(1,"%s",argv[2]);
242c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project
243c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	if(((db=malloc(newsize+1))==NULL) ||
244c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project		((eb=malloc(newsize+1))==NULL)) err(1,NULL);
245c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	dblen=0;
246c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	eblen=0;
247c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project
248c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	/* Create the patch file */
249c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	if ((pf = fopen(argv[3], "w")) == NULL)
250c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project		err(1, "%s", argv[3]);
251c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project
252c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	/* Header is
253c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project		0	8	 "BSDIFF40"
254c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project		8	8	length of bzip2ed ctrl block
255c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project		16	8	length of bzip2ed diff block
256c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project		24	8	length of new file */
257c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	/* File is
258c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project		0	32	Header
259c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project		32	??	Bzip2ed ctrl block
260c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project		??	??	Bzip2ed diff block
261c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project		??	??	Bzip2ed extra block */
262c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	memcpy(header,"BSDIFF40",8);
263c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	offtout(0, header + 8);
264c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	offtout(0, header + 16);
265c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	offtout(newsize, header + 24);
266c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	if (fwrite(header, 32, 1, pf) != 1)
267c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project		err(1, "fwrite(%s)", argv[3]);
268c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project
269c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	/* Compute the differences, writing ctrl as we go */
270c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	if ((pfbz2 = BZ2_bzWriteOpen(&bz2err, pf, 9, 0, 0)) == NULL)
271c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project		errx(1, "BZ2_bzWriteOpen, bz2err = %d", bz2err);
272c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	scan=0;len=0;
273c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	lastscan=0;lastpos=0;lastoffset=0;
274c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	while(scan<newsize) {
275c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project		oldscore=0;
276c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project
277c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project		for(scsc=scan+=len;scan<newsize;scan++) {
278c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project			len=search(I,old,oldsize,new+scan,newsize-scan,
279c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project					0,oldsize,&pos);
280c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project
281c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project			for(;scsc<scan+len;scsc++)
282c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project			if((scsc+lastoffset<oldsize) &&
283c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project				(old[scsc+lastoffset] == new[scsc]))
284c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project				oldscore++;
285c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project
286c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project			if(((len==oldscore) && (len!=0)) ||
287c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project				(len>oldscore+8)) break;
288c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project
289c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project			if((scan+lastoffset<oldsize) &&
290c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project				(old[scan+lastoffset] == new[scan]))
291c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project				oldscore--;
292c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project		};
293c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project
294c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project		if((len!=oldscore) || (scan==newsize)) {
295c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project			s=0;Sf=0;lenf=0;
296c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project			for(i=0;(lastscan+i<scan)&&(lastpos+i<oldsize);) {
297c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project				if(old[lastpos+i]==new[lastscan+i]) s++;
298c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project				i++;
299c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project				if(s*2-i>Sf*2-lenf) { Sf=s; lenf=i; };
300c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project			};
301c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project
302c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project			lenb=0;
303c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project			if(scan<newsize) {
304c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project				s=0;Sb=0;
305c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project				for(i=1;(scan>=lastscan+i)&&(pos>=i);i++) {
306c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project					if(old[pos-i]==new[scan-i]) s++;
307c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project					if(s*2-i>Sb*2-lenb) { Sb=s; lenb=i; };
308c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project				};
309c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project			};
310c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project
311c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project			if(lastscan+lenf>scan-lenb) {
312c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project				overlap=(lastscan+lenf)-(scan-lenb);
313c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project				s=0;Ss=0;lens=0;
314c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project				for(i=0;i<overlap;i++) {
315c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project					if(new[lastscan+lenf-overlap+i]==
316c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project					   old[lastpos+lenf-overlap+i]) s++;
317c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project					if(new[scan-lenb+i]==
318c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project					   old[pos-lenb+i]) s--;
319c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project					if(s>Ss) { Ss=s; lens=i+1; };
320c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project				};
321c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project
322c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project				lenf+=lens-overlap;
323c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project				lenb-=lens;
324c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project			};
325c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project
326c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project			for(i=0;i<lenf;i++)
327c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project				db[dblen+i]=new[lastscan+i]-old[lastpos+i];
328c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project			for(i=0;i<(scan-lenb)-(lastscan+lenf);i++)
329c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project				eb[eblen+i]=new[lastscan+lenf+i];
330c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project
331c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project			dblen+=lenf;
332c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project			eblen+=(scan-lenb)-(lastscan+lenf);
333c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project
334c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project			offtout(lenf,buf);
335c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project			BZ2_bzWrite(&bz2err, pfbz2, buf, 8);
336c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project			if (bz2err != BZ_OK)
337c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project				errx(1, "BZ2_bzWrite, bz2err = %d", bz2err);
338c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project
339c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project			offtout((scan-lenb)-(lastscan+lenf),buf);
340c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project			BZ2_bzWrite(&bz2err, pfbz2, buf, 8);
341c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project			if (bz2err != BZ_OK)
342c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project				errx(1, "BZ2_bzWrite, bz2err = %d", bz2err);
343c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project
344c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project			offtout((pos-lenb)-(lastpos+lenf),buf);
345c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project			BZ2_bzWrite(&bz2err, pfbz2, buf, 8);
346c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project			if (bz2err != BZ_OK)
347c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project				errx(1, "BZ2_bzWrite, bz2err = %d", bz2err);
348c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project
349c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project			lastscan=scan-lenb;
350c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project			lastpos=pos-lenb;
351c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project			lastoffset=pos-scan;
352c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project		};
353c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	};
354c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	BZ2_bzWriteClose(&bz2err, pfbz2, 0, NULL, NULL);
355c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	if (bz2err != BZ_OK)
356c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project		errx(1, "BZ2_bzWriteClose, bz2err = %d", bz2err);
357c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project
358c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	/* Compute size of compressed ctrl data */
359c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	if ((len = ftello(pf)) == -1)
360c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project		err(1, "ftello");
361c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	offtout(len-32, header + 8);
362c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project
363c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	/* Write compressed diff data */
364c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	if ((pfbz2 = BZ2_bzWriteOpen(&bz2err, pf, 9, 0, 0)) == NULL)
365c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project		errx(1, "BZ2_bzWriteOpen, bz2err = %d", bz2err);
366c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	BZ2_bzWrite(&bz2err, pfbz2, db, dblen);
367c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	if (bz2err != BZ_OK)
368c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project		errx(1, "BZ2_bzWrite, bz2err = %d", bz2err);
369c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	BZ2_bzWriteClose(&bz2err, pfbz2, 0, NULL, NULL);
370c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	if (bz2err != BZ_OK)
371c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project		errx(1, "BZ2_bzWriteClose, bz2err = %d", bz2err);
372c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project
373c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	/* Compute size of compressed diff data */
374c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	if ((newsize = ftello(pf)) == -1)
375c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project		err(1, "ftello");
376c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	offtout(newsize - len, header + 16);
377c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project
378c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	/* Write compressed extra data */
379c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	if ((pfbz2 = BZ2_bzWriteOpen(&bz2err, pf, 9, 0, 0)) == NULL)
380c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project		errx(1, "BZ2_bzWriteOpen, bz2err = %d", bz2err);
381c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	BZ2_bzWrite(&bz2err, pfbz2, eb, eblen);
382c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	if (bz2err != BZ_OK)
383c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project		errx(1, "BZ2_bzWrite, bz2err = %d", bz2err);
384c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	BZ2_bzWriteClose(&bz2err, pfbz2, 0, NULL, NULL);
385c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	if (bz2err != BZ_OK)
386c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project		errx(1, "BZ2_bzWriteClose, bz2err = %d", bz2err);
387c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project
388c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	/* Seek to the beginning, write the header, and close the file */
389c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	if (fseeko(pf, 0, SEEK_SET))
390c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project		err(1, "fseeko");
391c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	if (fwrite(header, 32, 1, pf) != 1)
392c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project		err(1, "fwrite(%s)", argv[3]);
393c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	if (fclose(pf))
394c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project		err(1, "fclose");
395c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project
396c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	/* Free the memory we used */
397c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	free(db);
398c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	free(eb);
399c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	free(I);
400c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	free(old);
401c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	free(new);
402c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project
403c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project	return 0;
404c285feace7a051368d4c5069cc6e0f30cd769f0dThe Android Open Source Project}
405