summaryrefslogtreecommitdiffstats
path: root/applypatch/imgdiff.c
diff options
context:
space:
mode:
Diffstat (limited to 'applypatch/imgdiff.c')
-rw-r--r--applypatch/imgdiff.c57
1 files changed, 49 insertions, 8 deletions
diff --git a/applypatch/imgdiff.c b/applypatch/imgdiff.c
index 6b9ebee5c..05c4f250f 100644
--- a/applypatch/imgdiff.c
+++ b/applypatch/imgdiff.c
@@ -111,6 +111,14 @@
*
* After the header there are 'chunk count' bsdiff patches; the offset
* of each from the beginning of the file is specified in the header.
+ *
+ * This tool can take an optional file of "bonus data". This is an
+ * extra file of data that is appended to chunk #1 after it is
+ * compressed (it must be a CHUNK_DEFLATE chunk). The same file must
+ * be available (and passed to applypatch with -b) when applying the
+ * patch. This is used to reduce the size of recovery-from-boot
+ * patches by combining the boot image with recovery ramdisk
+ * information that is stored on the system partition.
*/
#include <errno.h>
@@ -772,21 +780,45 @@ void DumpChunks(ImageChunk* chunks, int num_chunks) {
}
int main(int argc, char** argv) {
- if (argc != 4 && argc != 5) {
- usage:
- printf("usage: %s [-z] <src-img> <tgt-img> <patch-file>\n",
- argv[0]);
- return 2;
- }
-
int zip_mode = 0;
- if (strcmp(argv[1], "-z") == 0) {
+ if (argc >= 2 && strcmp(argv[1], "-z") == 0) {
zip_mode = 1;
--argc;
++argv;
}
+ size_t bonus_size = 0;
+ unsigned char* bonus_data = NULL;
+ if (argc >= 3 && strcmp(argv[1], "-b") == 0) {
+ struct stat st;
+ if (stat(argv[2], &st) != 0) {
+ printf("failed to stat bonus file %s: %s\n", argv[2], strerror(errno));
+ return 1;
+ }
+ bonus_size = st.st_size;
+ bonus_data = malloc(bonus_size);
+ FILE* f = fopen(argv[2], "rb");
+ if (f == NULL) {
+ printf("failed to open bonus file %s: %s\n", argv[2], strerror(errno));
+ return 1;
+ }
+ if (fread(bonus_data, 1, bonus_size, f) != bonus_size) {
+ printf("failed to read bonus file %s: %s\n", argv[2], strerror(errno));
+ return 1;
+ }
+ fclose(f);
+
+ argc -= 2;
+ argv += 2;
+ }
+
+ if (argc != 4) {
+ usage:
+ printf("usage: %s [-z] [-b <bonus-file>] <src-img> <tgt-img> <patch-file>\n",
+ argv[0]);
+ return 2;
+ }
int num_src_chunks;
ImageChunk* src_chunks;
@@ -909,6 +941,8 @@ int main(int argc, char** argv) {
// Compute bsdiff patches for each chunk's data (the uncompressed
// data, in the case of deflate chunks).
+ DumpChunks(src_chunks, num_src_chunks);
+
printf("Construct patches for %d chunks...\n", num_tgt_chunks);
unsigned char** patch_data = malloc(num_tgt_chunks * sizeof(unsigned char*));
size_t* patch_size = malloc(num_tgt_chunks * sizeof(size_t));
@@ -923,6 +957,13 @@ int main(int argc, char** argv) {
patch_data[i] = MakePatch(src_chunks, tgt_chunks+i, patch_size+i);
}
} else {
+ if (i == 1 && bonus_data) {
+ printf(" using %d bytes of bonus data for chunk %d\n", bonus_size, i);
+ src_chunks[i].data = realloc(src_chunks[i].data, src_chunks[i].len + bonus_size);
+ memcpy(src_chunks[i].data+src_chunks[i].len, bonus_data, bonus_size);
+ src_chunks[i].len += bonus_size;
+ }
+
patch_data[i] = MakePatch(src_chunks+i, tgt_chunks+i, patch_size+i);
}
printf("patch %3d is %d bytes (of %d)\n",