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

Unified Diff: dev-util/bsdiff/files/4.3_bspatch-support-input-output-positioning.patch

Issue 2779016: bsdiff: convert ebuild to the new eclass format (Closed) Base URL: ssh://gitrw.chromium.org/chromiumos-overlay
Patch Set: Ahem: fixed the keywords, too 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « dev-util/bsdiff/bsdiff-4.3-r1.ebuild ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: dev-util/bsdiff/files/4.3_bspatch-support-input-output-positioning.patch
diff --git a/dev-util/bsdiff/files/4.3_bspatch-support-input-output-positioning.patch b/dev-util/bsdiff/files/4.3_bspatch-support-input-output-positioning.patch
new file mode 100644
index 0000000000000000000000000000000000000000..205085ee1d1308471e1cbcd4b578d89457b0848f
--- /dev/null
+++ b/dev-util/bsdiff/files/4.3_bspatch-support-input-output-positioning.patch
@@ -0,0 +1,332 @@
+From f8c00fab208cb07e46bc3cb7f651cead857adf07 Mon Sep 17 00:00:00 2001
+From: Andrew de los Reyes <adlr@chromium.org>
+Date: Mon, 19 Apr 2010 15:05:56 -0700
+Subject: [PATCH] bspatch: support input/output positioning
+
+For autoupdate, we need bspatch to read specific blocks from the
+filesystem devic and write back to specific blocks of the device.
+
+Review URL: http://codereview.chromium.org/1595025
+---
+ files/bspatch.c | 270 ++++++++++++++++++++++++++++++++++++++++++++++++++++---
+ 1 files changed, 259 insertions(+), 11 deletions(-)
+
+diff --git a/files/bspatch.c b/files/bspatch.c
+index f4b821c..48ac79a 100644
+--- a/files/bspatch.c
++++ b/files/bspatch.c
+@@ -3,7 +3,7 @@
+ * All rights reserved
+ *
+ * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted providing that the following conditions
++ * 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.
+@@ -29,6 +29,9 @@ __FBSDID("$FreeBSD: src/usr.bin/bsdiff/bspatch/bspatch.c,v 1.1 2005/08/06 01:59:
+ #endif
+
+ #include <bzlib.h>
++#include <errno.h>
++#include <inttypes.h>
++#include <stdint.h>
+ #include <stdlib.h>
+ #include <stdio.h>
+ #include <string.h>
+@@ -36,6 +39,235 @@ __FBSDID("$FreeBSD: src/usr.bin/bsdiff/bspatch/bspatch.c,v 1.1 2005/08/06 01:59:
+ #include <unistd.h>
+ #include <fcntl.h>
+
++#define JOIN(a, b) __JOIN(a, b)
++#define __JOIN(a, b) a ## b
++#define COMPILE_ASSERT(expr, message) \
++ typedef char JOIN(message, JOIN(_, __LINE__)) [(expr) ? 1 : -1]
++
++COMPILE_ASSERT(sizeof(int64_t) == 8, int64_t_64_bit);
++
++#define MIN(a, b) \
++ ((a) < (b) ? (a) : (b))
++
++// Reads next int from *ints. The int should be terminated with a comma
++// or NULL char. *ints will be updated to the space right after the comma
++// or set to NULL if this was the last number. This assumes the input is
++// a valid string, as validated with PositionsStringIsValid().
++// Returns 1 on success.
++int NextInt64(const char** ints, int64_t *out) {
++ if (!ints[0])
++ return 0;
++ int r = sscanf(*ints, "%" PRIi64, out);
++ if (r == 1) {
++ const char* next_comma = strchr(*ints, ',');
++ const char* next_colon = strchr(*ints, ':');
++ if (!next_comma && !next_colon)
++ *ints = NULL;
++ else if (!next_comma)
++ *ints = next_colon + 1;
++ else if (!next_colon)
++ *ints = next_comma + 1;
++ else
++ *ints = MIN(next_comma, next_colon) + 1;
++ return 1;
++ }
++ return 0;
++}
++
++COMPILE_ASSERT(sizeof(intmax_t) == 8, intmax_t_not_64_bit);
++
++// Returns 1 if str can be converted to int64_t without over/underflowing.
++// str is assumed to point to an optional negative sign followed by numbers,
++// optionally followed by non-numeric characters, followed by '\0'.
++int IsValidInt64(const char* str) {
++ const char* end_ptr;
++ errno = 0;
++ intmax_t result = strtoimax(str, &end_ptr, /* base: */ 10);
++ return errno == 0;
++}
++
++// Input validator. Make sure the positions string is well formatted.
++// All numerical values are checked to make sure they don't over/underflow
++// int64_t. Returns 1 if valid.
++int PositionsStringIsValid(const char* positions) {
++ if (positions == NULL)
++ errx(1, "bad string");
++
++ // Special case: empty string is valid
++ if (!positions[0])
++ return 1;
++
++ // Use a state machine to determine if the string is valid.
++ // Key: (s): state, ((s)) valid end state.
++ // n (negative_valid) is a boolean that starts out as true.
++ // If n is true, ':' is the delimiter, otherwise ','.
++ //
++ // .--------------------------.
++ // | | n ? ':' : ',' ; n = !n
++ // V '-'&&n 0-9 |
++ // start->(0)------------->(1)----->((2))---.
++ // `---------------------> <--' 0-9
++ // 0-9
++ int state = 0;
++ int negative_valid = 1;
++ const char* number_start = positions;
++ for (;; positions++) {
++ char c = *positions;
++ switch (state) {
++ case 0:
++ if (c == '-' && negative_valid) {
++ state = 1;
++ continue;
++ }
++ if (isdigit(c)) {
++ state = 2;
++ continue;
++ }
++ return 0;
++ case 1:
++ if (isdigit(c)) {
++ state = 2;
++ continue;
++ }
++ return 0;
++ case 2:
++ if (isdigit(c))
++ continue;
++ // number_start must point to a valid number
++ if (!IsValidInt64(number_start)) {
++ return 0;
++ }
++ if ((negative_valid && c == ':') ||
++ (!negative_valid && c == ',')) {
++ state = 0;
++ number_start = positions + 1;
++ negative_valid = !negative_valid;
++ continue;
++ }
++ return (c == '\0');
++ }
++ }
++}
++
++// Reads into a buffer a series of byte ranges from filename.
++// Each range is a pair of comma-separated ints from positions.
++// -1 as an offset means a sparse-hole.
++// E.g. If positions were "1,5:23,4:-1,8:3,7", then we would return a buffer
++// consisting of 5 bytes from offset 1 of the file, followed by
++// 4 bytes from offset 23, then 8 bytes of all zeros, then 7 bytes from
++// offset 3 in the file.
++// Returns NULL on error.
++static char* PositionedRead(const char* filename,
++ const char* positions,
++ ssize_t* old_size) {
++ if (!PositionsStringIsValid(positions)) {
++ errx(1, "invalid positions string for read\n");
++ }
++
++ // Get length
++ const char* p = positions;
++ int64_t length = 0;
++ for (;;) {
++ int64_t value;
++ if (0 == NextInt64(&p, &value)) {
++ break;
++ }
++ int r = NextInt64(&p, &value);
++ if (r == 0) {
++ errx(1, "bad length parse\n");
++ }
++ if (value < 0) {
++ errx(1, "length can't be negative\n");
++ }
++ length += value;
++ }
++
++ // Malloc
++ if (length > 0x40000000) { // 1 GiB; sanity check
++ errx(1, "Read length too long (exceeds 1 GiB)");
++ }
++ // Following bsdiff convention, allocate length + 1 to avoid malloc(0)
++ char* buf = malloc(length + 1);
++ if (buf == NULL) {
++ errx(1, "malloc failed\n");
++ }
++ char* buf_tail = buf;
++
++ int fd = open(filename, O_RDONLY);
++ if (fd < 0) {
++ errx(1, "open failed for read\n");
++ }
++
++ // Read bytes
++ p = positions;
++ for (;;) {
++ int64_t offset, read_length;
++ if (NextInt64(&p, &offset) == 0) {
++ break;
++ }
++ if (offset < 0) {
++ errx(1, "no support for sparse positions "
++ "yet during read\n");
++ }
++ if (NextInt64(&p, &read_length) == 0) {
++ errx(1, "bad length parse (should never happen)\n");
++ }
++ if (read_length < 0) {
++ errx(1, "length can't be negative "
++ "(should never happen)\n");
++ }
++ ssize_t rc = pread(fd, buf_tail, read_length, offset);
++ if (rc != read_length) {
++ errx(1, "read failed\n");
++ }
++ buf_tail += rc;
++ }
++ close(fd);
++ *old_size = length;
++ return buf;
++}
++
++static void PositionedWrite(const char* filename,
++ const char* positions,
++ const char* buf,
++ ssize_t new_size) {
++ if (!PositionsStringIsValid(positions)) {
++ errx(1, "invalid positions string for write\n");
++ }
++ int fd = open(filename, O_WRONLY | O_CREAT, 0666);
++ if (fd < 0) {
++ errx(1, "open failed for write\n");
++ }
++
++ for (;;) {
++ int64_t offset, length;
++ if (NextInt64(&positions, &offset) == 0) {
++ break;
++ }
++ if (NextInt64(&positions, &length) == 0) {
++ errx(1, "bad length parse for write\n");
++ }
++ if (length < 0) {
++ errx(1, "length can't be negative for write\n");
++ }
++
++ if (offset < 0) {
++ // Sparse hole. Skip.
++ } else {
++ ssize_t rc = pwrite(fd, buf, length, offset);
++ if (rc != length) {
++ errx(1, "write failed\n");
++ }
++ }
++ buf += length;
++ new_size -= length;
++ }
++ if (new_size != 0) {
++ errx(1, "output position length doesn't match new size\n");
++ }
++ close(fd);
++}
++
+ static off_t offtin(u_char *buf)
+ {
+ off_t y;
+@@ -69,7 +301,13 @@ int main(int argc,char * argv[])
+ off_t lenread;
+ off_t i;
+
+- if(argc!=4) errx(1,"usage: %s oldfile newfile patchfile\n",argv[0]);
++ if ((argc != 6) && (argc != 4)) {
++ errx(1,"usage: %s oldfile newfile patchfile \\\n"
++ " [in_offset,in_length,in_offset,in_length,... \\\n"
++ " out_offset,out_length,"
++ "out_offset,out_length,...]\n",argv[0]);
++ }
++ int using_positioning = (argc == 6);
+
+ /* Open patch file */
+ if ((f = fopen(argv[3], "r")) == NULL)
+@@ -132,12 +370,18 @@ int main(int argc,char * argv[])
+ 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]);
++ // Read
++
++ if (!using_positioning) {
++ 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]);
++ } else {
++ old = PositionedRead(argv[1], argv[4], &oldsize);
++ }
+ if((new=malloc(newsize+1))==NULL) err(1,NULL);
+
+ oldpos=0;newpos=0;
+@@ -193,9 +437,13 @@ int main(int argc,char * argv[])
+ 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]);
++ if (!using_positioning) {
++ 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]);
++ } else {
++ PositionedWrite(argv[2], argv[5], new, newsize);
++ }
+
+ free(new);
+ free(old);
+--
+1.6.4.4
+
« no previous file with comments | « dev-util/bsdiff/bsdiff-4.3-r1.ebuild ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698