Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(6)

Side by Side Diff: chrome/installer/mac/third_party/bsdiff/goobsdiff.c

Issue 2716005: Modify bsdiff 4.3 to goobsdiff, which is appropriate for use as the Mac binary differ/patcher (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 10 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /*- 1 /*-
2 * Copyright 2003-2005 Colin Percival 2 * Copyright 2003-2005 Colin Percival
3 * All rights reserved 3 * All rights reserved
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted providing that the following conditions 6 * modification, are permitted providing that the following conditions
7 * are met: 7 * are met:
8 * 1. Redistributions of source code must retain the above copyright 8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
(...skipping 15 matching lines...) Expand all
26 26
27 #if 0 27 #if 0
28 __FBSDID("$FreeBSD: src/usr.bin/bsdiff/bsdiff/bsdiff.c,v 1.1 2005/08/06 01:59:05 cperciva Exp $"); 28 __FBSDID("$FreeBSD: src/usr.bin/bsdiff/bsdiff/bsdiff.c,v 1.1 2005/08/06 01:59:05 cperciva Exp $");
29 #endif 29 #endif
30 30
31 #include <sys/types.h> 31 #include <sys/types.h>
32 32
33 #include <bzlib.h> 33 #include <bzlib.h>
34 #include <err.h> 34 #include <err.h>
35 #include <fcntl.h> 35 #include <fcntl.h>
36 #include <openssl/sha.h>
36 #include <stdio.h> 37 #include <stdio.h>
37 #include <stdlib.h> 38 #include <stdlib.h>
38 #include <string.h> 39 #include <string.h>
39 #include <unistd.h> 40 #include <unistd.h>
41 #include <zlib.h>
42
43 #if defined(__APPLE__)
44 #include <libkern/OSByteOrder.h>
45 #define htole64(x) OSSwapHostToLittleInt64(x)
46 #elif defined(__linux__)
47 #include <endian.h>
48 #elif defined(_WIN32) && (defined(_M_IX86) || defined(_M_X64))
49 #define htole64(x) (x)
50 #else
51 #error Provide htole64 for this platform
52 #endif
40 53
41 #define MIN(x,y) (((x)<(y)) ? (x) : (y)) 54 #define MIN(x,y) (((x)<(y)) ? (x) : (y))
42 55
43 static void split(off_t *I,off_t *V,off_t start,off_t len,off_t h) 56 static void split(off_t *I,off_t *V,off_t start,off_t len,off_t h)
44 { 57 {
45 off_t i,j,k,x,tmp,jj,kk; 58 off_t i,j,k,x,tmp,jj,kk;
46 59
47 if(len<16) { 60 if(len<16) {
48 for(k=start;k<start+len;k+=j) { 61 for(k=start;k<start+len;k+=j) {
49 j=1;x=V[I[k]+h]; 62 j=1;x=V[I[k]+h];
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
168 }; 181 };
169 182
170 x=st+(en-st)/2; 183 x=st+(en-st)/2;
171 if(memcmp(old+I[x],new,MIN(oldsize-I[x],newsize))<0) { 184 if(memcmp(old+I[x],new,MIN(oldsize-I[x],newsize))<0) {
172 return search(I,old,oldsize,new,newsize,x,en,pos); 185 return search(I,old,oldsize,new,newsize,x,en,pos);
173 } else { 186 } else {
174 return search(I,old,oldsize,new,newsize,st,x,pos); 187 return search(I,old,oldsize,new,newsize,st,x,pos);
175 }; 188 };
176 } 189 }
177 190
178 static void offtout(off_t x,u_char *buf) 191 static inline void offtout(off_t x,u_char *buf)
179 { 192 {
180 » off_t y; 193 » *((off_t*)buf) = htole64(x);
194 }
181 195
182 » if(x<0) y=-x; else y=x; 196 /* zlib provides compress2, which deflates to deflate (zlib) format. This is
197 * unfortunately distinct from gzip format in that the headers wrapping the
198 * decompressed data are different. gbspatch reads gzip-compressed data using
199 * the file-oriented gzread interface, which only supports gzip format.
200 * compress2gzip is identical to zlib's compress2 except that it produces gzip
201 * output compatible with gzread. This change is achieved by calling
202 * deflateInit2 instead of deflateInit and specifying 31 for windowBits;
203 * numbers greater than 15 cause the addition of a gzip wrapper. */
204 static int compress2gzip(Bytef *dest, uLongf *destLen,
205 const Bytef *source, uLong sourceLen, int level)
206 {
207 » z_stream stream;
208 » int err;
183 209
184 » » buf[0]=y%256;y-=buf[0]; 210 » stream.next_in = (Bytef*)source;
185 » y=y/256;buf[1]=y%256;y-=buf[1]; 211 » stream.avail_in = (uInt)sourceLen;
186 » y=y/256;buf[2]=y%256;y-=buf[2];
187 » y=y/256;buf[3]=y%256;y-=buf[3];
188 » y=y/256;buf[4]=y%256;y-=buf[4];
189 » y=y/256;buf[5]=y%256;y-=buf[5];
190 » y=y/256;buf[6]=y%256;y-=buf[6];
191 » y=y/256;buf[7]=y%256;
192 212
193 » if(x<0) buf[7]|=0x80; 213 » stream.next_out = dest;
214 » stream.avail_out = (uInt)*destLen;
215 » if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
216
217 » stream.zalloc = (alloc_func)0;
218 » stream.zfree = (free_func)0;
219 » stream.opaque = (voidpf)0;
220
221 » err = deflateInit2(&stream,
222 » level, Z_DEFLATED, 31, 8, Z_DEFAULT_STRATEGY);
223 » if (err != Z_OK) return err;
224
225 » err = deflate(&stream, Z_FINISH);
226 » if (err != Z_STREAM_END) {
227 » » deflateEnd(&stream);
228 » » return err == Z_OK ? Z_BUF_ERROR : err;
229 » }
230 » *destLen = stream.total_out;
231
232 » err = deflateEnd(&stream);
233 » return err;
234 }
235
236 /* Recompress buf of size buf_len using bzip2 or gzip. The smallest version is
237 * used. The original uncompressed variant may be the smallest. Returns a
238 * number identifying the encoding, 1 for uncompressed, 2 for bzip2, and 3 for
239 * gzip. If the original uncompressed variant is not smallest, it is freed.
240 * The caller must free any buf after this function returns. */
241 static char make_small(u_char **buf, off_t *buf_len)
242 {
243 » u_char *source = *buf;
244 » off_t source_len = *buf_len;
245 » u_char *bz2, *gz;
246 » unsigned int bz2_len;
247 » unsigned long gz_len;
248 » int zerr;
249 » char smallest;
250
251 » smallest = 1;
252
253 » bz2_len = source_len + 1;
254 » bz2 = malloc(bz2_len);
255 » zerr = BZ2_bzBuffToBuffCompress((char*)bz2, &bz2_len, (char*)source,
256 » source_len, 9, 0, 0);
257 » if (zerr == BZ_OK) {
258 » » if (bz2_len < *buf_len) {
259 » » » smallest = 2;
260 » » » *buf = bz2;
261 » » » *buf_len = bz2_len;
262 » » } else {
263 » » » free(bz2);
264 » » » bz2 = NULL;
265 » » }
266 » } else if (zerr == BZ_OUTBUFF_FULL) {
267 » » free(bz2);
268 » » bz2 = NULL;
269 » } else {
270 » » errx(1, "BZ2_bzBuffToBuffCompress: %d", zerr);
271 » }
272
273 » gz_len = source_len + 1;
274 » gz = malloc(gz_len);
275 » zerr = compress2gzip(gz, &gz_len, source, source_len, 9);
276 » if (zerr == Z_OK) {
277 » » if (gz_len < *buf_len) {
278 » » » smallest = 3;
279 » » » *buf = gz;
280 » » » *buf_len = gz_len;
281 » » } else {
282 » » » free(gz);
283 » » » gz = NULL;
284 » » }
285 » } else if (zerr == Z_BUF_ERROR) {
286 » » free(gz);
287 » » gz = NULL;
288 » } else {
289 » » errx(1, "compress2gzip: %d", zerr);
290 » }
291
292 » if (smallest != 1) {
293 » » free(source);
294 » }
295
296 » return smallest;
194 } 297 }
195 298
196 int main(int argc,char *argv[]) 299 int main(int argc,char *argv[])
197 { 300 {
198 int fd; 301 int fd;
199 u_char *old,*new; 302 u_char *old,*new;
200 off_t oldsize,newsize; 303 off_t oldsize,newsize;
201 off_t *I,*V; 304 off_t *I,*V;
202 off_t scan,pos,len; 305 off_t scan,pos,len;
203 off_t lastscan,lastpos,lastoffset; 306 off_t lastscan,lastpos,lastoffset;
204 off_t oldscore,scsc; 307 off_t oldscore,scsc;
205 off_t s,Sf,lenf,Sb,lenb; 308 off_t s,Sf,lenf,Sb,lenb;
206 off_t overlap,Ss,lens; 309 off_t overlap,Ss,lens;
207 off_t i; 310 off_t i;
208 » off_t dblen,eblen; 311 » off_t cblen, dblen, eblen;
209 » u_char *db,*eb; 312 » u_char *cb, *db, *eb;
210 » u_char buf[8]; 313 » u_char header[96];
211 » u_char header[32];
212 FILE * pf; 314 FILE * pf;
213 BZFILE * pfbz2;
214 int bz2err;
215 315
216 » if(argc!=4) errx(1,"usage: %s oldfile newfile patchfile\n",argv[0]); 316 » if(argc!=4) errx(1,"usage: %s oldfile newfile patchfile",argv[0]);
217 317
218 /* Allocate oldsize+1 bytes instead of oldsize bytes to ensure 318 /* Allocate oldsize+1 bytes instead of oldsize bytes to ensure
219 that we never try to malloc(0) and get a NULL pointer */ 319 that we never try to malloc(0) and get a NULL pointer */
220 if(((fd=open(argv[1],O_RDONLY,0))<0) || 320 if(((fd=open(argv[1],O_RDONLY,0))<0) ||
221 ((oldsize=lseek(fd,0,SEEK_END))==-1) || 321 ((oldsize=lseek(fd,0,SEEK_END))==-1) ||
222 ((old=malloc(oldsize+1))==NULL) || 322 ((old=malloc(oldsize+1))==NULL) ||
223 (lseek(fd,0,SEEK_SET)!=0) || 323 (lseek(fd,0,SEEK_SET)!=0) ||
224 (read(fd,old,oldsize)!=oldsize) || 324 (read(fd,old,oldsize)!=oldsize) ||
225 (close(fd)==-1)) err(1,"%s",argv[1]); 325 (close(fd)==-1)) err(1,"%s",argv[1]);
226 326
227 if(((I=malloc((oldsize+1)*sizeof(off_t)))==NULL) || 327 if(((I=malloc((oldsize+1)*sizeof(off_t)))==NULL) ||
228 ((V=malloc((oldsize+1)*sizeof(off_t)))==NULL)) err(1,NULL); 328 ((V=malloc((oldsize+1)*sizeof(off_t)))==NULL)) err(1,NULL);
229 329
230 qsufsort(I,V,old,oldsize); 330 qsufsort(I,V,old,oldsize);
231 331
232 free(V); 332 free(V);
233 333
234 /* Allocate newsize+1 bytes instead of newsize bytes to ensure 334 /* Allocate newsize+1 bytes instead of newsize bytes to ensure
235 that we never try to malloc(0) and get a NULL pointer */ 335 that we never try to malloc(0) and get a NULL pointer */
236 if(((fd=open(argv[2],O_RDONLY,0))<0) || 336 if(((fd=open(argv[2],O_RDONLY,0))<0) ||
237 ((newsize=lseek(fd,0,SEEK_END))==-1) || 337 ((newsize=lseek(fd,0,SEEK_END))==-1) ||
238 ((new=malloc(newsize+1))==NULL) || 338 ((new=malloc(newsize+1))==NULL) ||
239 (lseek(fd,0,SEEK_SET)!=0) || 339 (lseek(fd,0,SEEK_SET)!=0) ||
240 (read(fd,new,newsize)!=newsize) || 340 (read(fd,new,newsize)!=newsize) ||
241 (close(fd)==-1)) err(1,"%s",argv[2]); 341 (close(fd)==-1)) err(1,"%s",argv[2]);
242 342
243 » if(((db=malloc(newsize+1))==NULL) || 343 » if(((cb=malloc(newsize+1))==NULL) ||
344 » » ((db=malloc(newsize+1))==NULL) ||
244 ((eb=malloc(newsize+1))==NULL)) err(1,NULL); 345 ((eb=malloc(newsize+1))==NULL)) err(1,NULL);
346 cblen=0;
245 dblen=0; 347 dblen=0;
246 eblen=0; 348 eblen=0;
247 349
248 /* Create the patch file */ 350 /* Create the patch file */
249 » if ((pf = fopen(argv[3], "w")) == NULL) 351 » if ((pf = fopen(argv[3], "wb")) == NULL)
250 err(1, "%s", argv[3]); 352 err(1, "%s", argv[3]);
251 353
252 » /* Header is 354 » /* File format:
253 » » 0» 8» "BSDIFF40" 355 » » 0» 8» "BSDIFF4G"
254 » » 8» 8» length of bzip2ed ctrl block 356 » » 8» 8» length of compressed control block (x)
255 » » 16» 8» length of bzip2ed diff block 357 » » 16» 8» length of compressed diff block (y)
256 » » 24» 8» length of new file */ 358 » » 24» 8» length of compressed extra block (z)
257 » /* File is 359 » » 32» 8» length of old file
258 » » 0» 32» Header 360 » » 40» 8» length of new file
259 » » 32» ??» Bzip2ed ctrl block 361 » » 48» 20» SHA1 of old file
260 » » ??» ??» Bzip2ed diff block 362 » » 68» 20» SHA1 of new file
261 » » ??» ??» Bzip2ed extra block */ 363 » » 88» 1» encoding of control block
262 » memcpy(header,"BSDIFF40",8); 364 » » 89» 1» encoding of diff block
263 » offtout(0, header + 8); 365 » » 90» 1» encoding of extra block
264 » offtout(0, header + 16); 366 » » 91» 5» unused
265 » offtout(newsize, header + 24); 367 » » 96» x» compressed control block
266 » if (fwrite(header, 32, 1, pf) != 1) 368 » » 96+x» y» compressed diff block
369 » » 96+x+y» z» compressed extra block
370 » Encodings are 1 (uncompressed), 2 (bzip2), and 3 (gzip). */
371 » memset(header, 0, sizeof(header));
372 » if (fwrite(header, sizeof(header), 1, pf) != 1)
267 err(1, "fwrite(%s)", argv[3]); 373 err(1, "fwrite(%s)", argv[3]);
374 memcpy(header, "BSDIFF4G", 8);
375 offtout(oldsize, header + 32);
376 offtout(newsize, header + 40);
377 SHA1(old, oldsize, header + 48);
378 SHA1(new, newsize, header + 68);
268 379
269 » /* Compute the differences, writing ctrl as we go */ 380 » /* Compute the differences */
270 » if ((pfbz2 = BZ2_bzWriteOpen(&bz2err, pf, 9, 0, 0)) == NULL)
271 » » errx(1, "BZ2_bzWriteOpen, bz2err = %d", bz2err);
272 scan=0;len=0; 381 scan=0;len=0;
273 lastscan=0;lastpos=0;lastoffset=0; 382 lastscan=0;lastpos=0;lastoffset=0;
274 while(scan<newsize) { 383 while(scan<newsize) {
275 oldscore=0; 384 oldscore=0;
276 385
277 for(scsc=scan+=len;scan<newsize;scan++) { 386 for(scsc=scan+=len;scan<newsize;scan++) {
278 len=search(I,old,oldsize,new+scan,newsize-scan, 387 len=search(I,old,oldsize,new+scan,newsize-scan,
279 0,oldsize,&pos); 388 0,oldsize,&pos);
280 389
281 for(;scsc<scan+len;scsc++) 390 for(;scsc<scan+len;scsc++)
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
324 }; 433 };
325 434
326 for(i=0;i<lenf;i++) 435 for(i=0;i<lenf;i++)
327 db[dblen+i]=new[lastscan+i]-old[lastpos+i]; 436 db[dblen+i]=new[lastscan+i]-old[lastpos+i];
328 for(i=0;i<(scan-lenb)-(lastscan+lenf);i++) 437 for(i=0;i<(scan-lenb)-(lastscan+lenf);i++)
329 eb[eblen+i]=new[lastscan+lenf+i]; 438 eb[eblen+i]=new[lastscan+lenf+i];
330 439
331 dblen+=lenf; 440 dblen+=lenf;
332 eblen+=(scan-lenb)-(lastscan+lenf); 441 eblen+=(scan-lenb)-(lastscan+lenf);
333 442
334 » » » offtout(lenf,buf); 443 » » » offtout(lenf, cb + cblen);
335 » » » BZ2_bzWrite(&bz2err, pfbz2, buf, 8); 444 » » » cblen += 8;
336 » » » if (bz2err != BZ_OK)
337 » » » » errx(1, "BZ2_bzWrite, bz2err = %d", bz2err);
338 445
339 » » » offtout((scan-lenb)-(lastscan+lenf),buf); 446 » » » offtout((scan - lenb) - (lastscan + lenf), cb + cblen);
340 » » » BZ2_bzWrite(&bz2err, pfbz2, buf, 8); 447 » » » cblen += 8;
341 » » » if (bz2err != BZ_OK)
342 » » » » errx(1, "BZ2_bzWrite, bz2err = %d", bz2err);
343 448
344 » » » offtout((pos-lenb)-(lastpos+lenf),buf); 449 » » » offtout((pos - lenb) - (lastpos + lenf), cb + cblen);
345 » » » BZ2_bzWrite(&bz2err, pfbz2, buf, 8); 450 » » » cblen += 8;
346 » » » if (bz2err != BZ_OK)
347 » » » » errx(1, "BZ2_bzWrite, bz2err = %d", bz2err);
348 451
349 lastscan=scan-lenb; 452 lastscan=scan-lenb;
350 lastpos=pos-lenb; 453 lastpos=pos-lenb;
351 lastoffset=pos-scan; 454 lastoffset=pos-scan;
352 }; 455 };
353 }; 456 };
354 BZ2_bzWriteClose(&bz2err, pfbz2, 0, NULL, NULL);
355 if (bz2err != BZ_OK)
356 errx(1, "BZ2_bzWriteClose, bz2err = %d", bz2err);
357 457
358 » /* Compute size of compressed ctrl data */ 458 » header[88] = make_small(&cb, &cblen);
359 » if ((len = ftello(pf)) == -1) 459 » header[89] = make_small(&db, &dblen);
360 » » err(1, "ftello"); 460 » header[90] = make_small(&eb, &eblen);
361 » offtout(len-32, header + 8);
362 461
363 » /* Write compressed diff data */ 462 » if (fwrite(cb, 1, cblen, pf) != cblen)
364 » if ((pfbz2 = BZ2_bzWriteOpen(&bz2err, pf, 9, 0, 0)) == NULL) 463 » » err(1, "fwrite");
365 » » errx(1, "BZ2_bzWriteOpen, bz2err = %d", bz2err); 464 » if (fwrite(db, 1, dblen, pf) != dblen)
366 » BZ2_bzWrite(&bz2err, pfbz2, db, dblen); 465 » » err(1, "fwrite");
367 » if (bz2err != BZ_OK) 466 » if (fwrite(eb, 1, eblen, pf) != eblen)
368 » » errx(1, "BZ2_bzWrite, bz2err = %d", bz2err); 467 » » err(1, "fwrite");
369 » BZ2_bzWriteClose(&bz2err, pfbz2, 0, NULL, NULL);
370 » if (bz2err != BZ_OK)
371 » » errx(1, "BZ2_bzWriteClose, bz2err = %d", bz2err);
372 468
373 » /* Compute size of compressed diff data */ 469 » offtout(cblen, header + 8);
374 » if ((newsize = ftello(pf)) == -1) 470 » offtout(dblen, header + 16);
375 » » err(1, "ftello"); 471 » offtout(eblen, header + 24);
376 » offtout(newsize - len, header + 16);
377
378 » /* Write compressed extra data */
379 » if ((pfbz2 = BZ2_bzWriteOpen(&bz2err, pf, 9, 0, 0)) == NULL)
380 » » errx(1, "BZ2_bzWriteOpen, bz2err = %d", bz2err);
381 » BZ2_bzWrite(&bz2err, pfbz2, eb, eblen);
382 » if (bz2err != BZ_OK)
383 » » errx(1, "BZ2_bzWrite, bz2err = %d", bz2err);
384 » BZ2_bzWriteClose(&bz2err, pfbz2, 0, NULL, NULL);
385 » if (bz2err != BZ_OK)
386 » » errx(1, "BZ2_bzWriteClose, bz2err = %d", bz2err);
387 472
388 /* Seek to the beginning, write the header, and close the file */ 473 /* Seek to the beginning, write the header, and close the file */
389 if (fseeko(pf, 0, SEEK_SET)) 474 if (fseeko(pf, 0, SEEK_SET))
390 err(1, "fseeko"); 475 err(1, "fseeko");
391 » if (fwrite(header, 32, 1, pf) != 1) 476 » if (fwrite(header, sizeof(header), 1, pf) != 1)
392 err(1, "fwrite(%s)", argv[3]); 477 err(1, "fwrite(%s)", argv[3]);
393 if (fclose(pf)) 478 if (fclose(pf))
394 err(1, "fclose"); 479 err(1, "fclose");
395 480
396 /* Free the memory we used */ 481 /* Free the memory we used */
482 free(cb);
397 free(db); 483 free(db);
398 free(eb); 484 free(eb);
399 free(I); 485 free(I);
400 free(old); 486 free(old);
401 free(new); 487 free(new);
402 488
403 return 0; 489 return 0;
404 } 490 }
OLDNEW
« no previous file with comments | « chrome/installer/mac/third_party/bsdiff/bspatch.c ('k') | chrome/installer/mac/third_party/bsdiff/goobsdiff.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698