diff options
author | Koushik Dutta <koushd@gmail.com> | 2012-11-24 16:50:10 -0800 |
---|---|---|
committer | Koushik Dutta <koushd@gmail.com> | 2012-11-24 17:01:08 -0800 |
commit | eaee7190f5ab851a76cd59e899dce253297cbb31 (patch) | |
tree | f2a2551ed2c38e45fb0bcd838c304a489bd6f225 | |
parent | 53e139f8b3b982f130d387a6261a1613435d6f40 (diff) | |
download | bootable_recovery-eaee7190f5ab851a76cd59e899dce253297cbb31.zip bootable_recovery-eaee7190f5ab851a76cd59e899dce253297cbb31.tar.gz bootable_recovery-eaee7190f5ab851a76cd59e899dce253297cbb31.tar.bz2 |
Pull in android 4.2 updater bits willy nilly. Next commit will fix.
Change-Id: Id2616d1fead045688a5acf13b3420016322f664b
-rw-r--r-- | applypatch/Android.mk | 1 | ||||
-rw-r--r-- | applypatch/applypatch.c | 13 | ||||
-rw-r--r-- | applypatch/applypatch.h | 6 | ||||
-rw-r--r-- | applypatch/imgdiff.c | 57 | ||||
-rw-r--r-- | applypatch/imgpatch.c | 21 | ||||
-rw-r--r-- | applypatch/main.c | 23 | ||||
-rw-r--r-- | minzip/inline_magic.h | 2 | ||||
-rw-r--r-- | testdata/otasigned_f4.zip | bin | 0 -> 5195 bytes | |||
-rw-r--r-- | testdata/test_f4.pk8 | bin | 0 -> 1217 bytes | |||
-rw-r--r-- | testdata/test_f4.x509.pem | 25 | ||||
-rw-r--r-- | tools/ota/check-lost+found.c | 2 | ||||
-rw-r--r-- | updater/Android.mk | 32 | ||||
-rw-r--r-- | updater/install.c | 99 |
13 files changed, 233 insertions, 48 deletions
diff --git a/applypatch/Android.mk b/applypatch/Android.mk index 0e529d4..ef57f24 100644 --- a/applypatch/Android.mk +++ b/applypatch/Android.mk @@ -50,7 +50,6 @@ include $(CLEAR_VARS) LOCAL_SRC_FILES := imgdiff.c utils.c bsdiff.c LOCAL_MODULE := imgdiff LOCAL_FORCE_STATIC_EXECUTABLE := true -LOCAL_MODULE_TAGS := eng LOCAL_C_INCLUDES += external/zlib external/bzip2 LOCAL_STATIC_LIBRARIES += libz libbz diff --git a/applypatch/applypatch.c b/applypatch/applypatch.c index 488fd8c..7b8a010 100644 --- a/applypatch/applypatch.c +++ b/applypatch/applypatch.c @@ -39,7 +39,8 @@ static int GenerateTarget(FileContents* source_file, const char* source_filename, const char* target_filename, const uint8_t target_sha1[SHA_DIGEST_SIZE], - size_t target_size); + size_t target_size, + const Value* bonus_data); static int mtd_partitions_scanned = 0; @@ -617,7 +618,8 @@ int applypatch(const char* source_filename, size_t target_size, int num_patches, char** const patch_sha1_str, - Value** patch_data) { + Value** patch_data, + Value* bonus_data) { printf("\napplying patch to %s\n", source_filename); if (target_filename[0] == '-' && @@ -699,7 +701,7 @@ int applypatch(const char* source_filename, int result = GenerateTarget(&source_file, source_patch_value, ©_file, copy_patch_value, source_filename, target_filename, - target_sha1, target_size); + target_sha1, target_size, bonus_data); free(source_file.data); free(copy_file.data); @@ -713,7 +715,8 @@ static int GenerateTarget(FileContents* source_file, const char* source_filename, const char* target_filename, const uint8_t target_sha1[SHA_DIGEST_SIZE], - size_t target_size) { + size_t target_size, + const Value* bonus_data) { int retry = 1; SHA_CTX ctx; int output; @@ -867,7 +870,7 @@ static int GenerateTarget(FileContents* source_file, } else if (header_bytes_read >= 8 && memcmp(header, "IMGDIFF2", 8) == 0) { result = ApplyImagePatch(source_to_use->data, source_to_use->size, - patch, sink, token, &ctx); + patch, sink, token, &ctx, bonus_data); } else { printf("Unknown patch file format\n"); return 1; diff --git a/applypatch/applypatch.h b/applypatch/applypatch.h index fb58843..d1a0232 100644 --- a/applypatch/applypatch.h +++ b/applypatch/applypatch.h @@ -55,7 +55,8 @@ int applypatch(const char* source_filename, size_t target_size, int num_patches, char** const patch_sha1_str, - Value** patch_data); + Value** patch_data, + Value* bonus_data); int applypatch_check(const char* filename, int num_patches, char** const patch_sha1_str); @@ -79,7 +80,8 @@ int ApplyBSDiffPatchMem(const unsigned char* old_data, ssize_t old_size, // imgpatch.c int ApplyImagePatch(const unsigned char* old_data, ssize_t old_size, const Value* patch, - SinkFn sink, void* token, SHA_CTX* ctx); + SinkFn sink, void* token, SHA_CTX* ctx, + const Value* bonus_data); // freecache.c int MakeFreeSpaceOnCache(size_t bytes_needed); diff --git a/applypatch/imgdiff.c b/applypatch/imgdiff.c index 6b9ebee..05c4f25 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", diff --git a/applypatch/imgpatch.c b/applypatch/imgpatch.c index e3ee80a..3a1df38 100644 --- a/applypatch/imgpatch.c +++ b/applypatch/imgpatch.c @@ -37,7 +37,8 @@ */ int ApplyImagePatch(const unsigned char* old_data, ssize_t old_size, const Value* patch, - SinkFn sink, void* token, SHA_CTX* ctx) { + SinkFn sink, void* token, SHA_CTX* ctx, + const Value* bonus_data) { ssize_t pos = 12; char* header = patch->data; if (patch->size < 12) { @@ -123,6 +124,12 @@ int ApplyImagePatch(const unsigned char* old_data, ssize_t old_size, // Decompress the source data; the chunk header tells us exactly // how big we expect it to be when decompressed. + // Note: expanded_len will include the bonus data size if + // the patch was constructed with bonus data. The + // deflation will come up 'bonus_size' bytes short; these + // must be appended from the bonus_data value. + size_t bonus_size = (i == 1 && bonus_data != NULL) ? bonus_data->size : 0; + unsigned char* expanded_source = malloc(expanded_len); if (expanded_source == NULL) { printf("failed to allocate %d bytes for expanded_source\n", @@ -153,13 +160,19 @@ int ApplyImagePatch(const unsigned char* old_data, ssize_t old_size, printf("source inflation returned %d\n", ret); return -1; } - // We should have filled the output buffer exactly. - if (strm.avail_out != 0) { - printf("source inflation short by %d bytes\n", strm.avail_out); + // We should have filled the output buffer exactly, except + // for the bonus_size. + if (strm.avail_out != bonus_size) { + printf("source inflation short by %d bytes\n", strm.avail_out-bonus_size); return -1; } inflateEnd(&strm); + if (bonus_size) { + memcpy(expanded_source + (expanded_len - bonus_size), + bonus_data->data, bonus_size); + } + // Next, apply the bsdiff patch (in memory) to the uncompressed // data. unsigned char* uncompressed_target_data; diff --git a/applypatch/main.c b/applypatch/main.c index 7025a2e..f61db5d 100644 --- a/applypatch/main.c +++ b/applypatch/main.c @@ -100,6 +100,21 @@ static int ParsePatchArgs(int argc, char** argv, } int PatchMode(int argc, char** argv) { + Value* bonus = NULL; + if (argc >= 3 && strcmp(argv[1], "-b") == 0) { + FileContents fc; + if (LoadFileContents(argv[2], &fc, RETOUCH_DONT_MASK) != 0) { + printf("failed to load bonus file %s\n", argv[2]); + return 1; + } + bonus = malloc(sizeof(Value)); + bonus->type = VAL_BLOB; + bonus->size = fc.size; + bonus->data = (char*)fc.data; + argc -= 2; + argv += 2; + } + if (argc < 6) { return 2; } @@ -120,7 +135,7 @@ int PatchMode(int argc, char** argv) { } int result = applypatch(argv[1], argv[2], argv[3], target_size, - num_patches, sha1s, patches); + num_patches, sha1s, patches, bonus); int i; for (i = 0; i < num_patches; ++i) { @@ -130,6 +145,10 @@ int PatchMode(int argc, char** argv) { free(p); } } + if (bonus) { + free(bonus->data); + free(bonus); + } free(sha1s); free(patches); @@ -163,7 +182,7 @@ int main(int argc, char** argv) { if (argc < 2) { usage: printf( - "usage: %s <src-file> <tgt-file> <tgt-sha1> <tgt-size> " + "usage: %s [-b <bonus-file>] <src-file> <tgt-file> <tgt-sha1> <tgt-size> " "[<src-sha1>:<patch> ...]\n" " or %s -c <file> [<sha1> ...]\n" " or %s -s <bytes>\n" diff --git a/minzip/inline_magic.h b/minzip/inline_magic.h index 8c185e1..59c659f 100644 --- a/minzip/inline_magic.h +++ b/minzip/inline_magic.h @@ -18,7 +18,7 @@ #define MINZIP_INLINE_MAGIC_H_ #ifndef MINZIP_GENERATE_INLINES -#define INLINE extern __inline__ +#define INLINE extern inline __attribute((__gnu_inline__)) #else #define INLINE #endif diff --git a/testdata/otasigned_f4.zip b/testdata/otasigned_f4.zip Binary files differnew file mode 100644 index 0000000..dd1e4dd --- /dev/null +++ b/testdata/otasigned_f4.zip diff --git a/testdata/test_f4.pk8 b/testdata/test_f4.pk8 Binary files differnew file mode 100644 index 0000000..3052613 --- /dev/null +++ b/testdata/test_f4.pk8 diff --git a/testdata/test_f4.x509.pem b/testdata/test_f4.x509.pem new file mode 100644 index 0000000..814abcf --- /dev/null +++ b/testdata/test_f4.x509.pem @@ -0,0 +1,25 @@ +-----BEGIN CERTIFICATE----- +MIIENjCCAx6gAwIBAgIJAKhkCO1dDYMaMA0GCSqGSIb3DQEBBQUAMG8xCzAJBgNV +BAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1Nb3VudGFpbiBW +aWV3MQ8wDQYDVQQKEwZHb29nbGUxEDAOBgNVBAsTB0FuZHJvaWQxEDAOBgNVBAMT +B1Rlc3QxMjMwHhcNMTIwNzI1MTg1NzAzWhcNMzkxMjExMTg1NzAzWjBvMQswCQYD +VQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4g +VmlldzEPMA0GA1UEChMGR29vZ2xlMRAwDgYDVQQLEwdBbmRyb2lkMRAwDgYDVQQD +EwdUZXN0MTIzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu8WwMN9x +4Mz7YgkG2qy9g8/kl5ZoYrUM0ApHhaITAcL7RXLZaNipCf0w/YjYTQgj+75MK30x +TsnPeWNOEwA62gkHrZyyWfxBRO6kBYuIuI4roGDBJOmKQ1OEaDeIRKu7q5V8v3Cs +0wQDAQWTbhpxBZr9UYFgJUg8XWBfPrGJLVwsoiy4xrMhoTlNZKHfwOMMqVtSHkZX +qydYrcIzyjh+TO0e/xSNQ8MMRRbtqWgCHN6Rzhog3IHZu0RaPoukariopjXM/s0V +gTm3rHDHCOpna2pNblyiFlvbkoCs769mtNmx/yrDShO30jg/xaG8RypKDvTChzOT +oWW/XQ5VEXjbHwIDAQABo4HUMIHRMB0GA1UdDgQWBBRlT2dEZJY1tmUM8mZ0xnhS +GdD9TTCBoQYDVR0jBIGZMIGWgBRlT2dEZJY1tmUM8mZ0xnhSGdD9TaFzpHEwbzEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 +YWluIFZpZXcxDzANBgNVBAoTBkdvb2dsZTEQMA4GA1UECxMHQW5kcm9pZDEQMA4G +A1UEAxMHVGVzdDEyM4IJAKhkCO1dDYMaMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcN +AQEFBQADggEBAHqnXHtE+h3hvGmHh24GT51vGAYLc68WUUtCVlMIU85zQ757wlxZ +BmRypZ1i9hSqnXj5n+mETV5rFX3g2gvdAPVHkRycuDa2aUdZSE8cW4Z6qYFx6SaD +e+3SyXokpUquW64RuHJrf/yd/FnGjneBe3Qpm2reuzGWNH90qZGdbsfNaCm5kx2L +X+ZNHM3CcGMLaphY5++sM0JxSEcju5EK33ZYgLf4YdlbyMp8LDFVNd7ff0SFi9fF +0ZlAsJWoS3QmVCj2744BFdsCu7UHpnYpG6X3MT4SHAawdOaT5zSuaCl2xx6H0O7t +w/Fvbl/KVD1ZmLHgBKjDMNSh0OB9mSsDWpw= +-----END CERTIFICATE----- diff --git a/tools/ota/check-lost+found.c b/tools/ota/check-lost+found.c index f856275..da02f46 100644 --- a/tools/ota/check-lost+found.c +++ b/tools/ota/check-lost+found.c @@ -44,7 +44,7 @@ static const char *kPartitions[] = { "/system", "/data", "/cache", NULL }; * 2. Write a log entry with the number of files in lost+found directories. */ -int main(int argc, char **argv) { +int main(int argc __attribute__((unused)), char **argv __attribute__((unused))) { mkdir(kOutputDir, 0755); chown(kOutputDir, AID_SYSTEM, AID_SYSTEM); FILE *out = fopen(kOutputFile, "a"); diff --git a/updater/Android.mk b/updater/Android.mk index a3f6c28..8876120 100644 --- a/updater/Android.mk +++ b/updater/Android.mk @@ -3,7 +3,6 @@ LOCAL_PATH := $(call my-dir) updater_src_files := \ - ../mounts.c \ install.c \ updater.c @@ -22,7 +21,10 @@ LOCAL_SRC_FILES := $(updater_src_files) ifeq ($(TARGET_USERIMAGES_USE_EXT4), true) LOCAL_CFLAGS += -DUSE_EXT4 LOCAL_C_INCLUDES += system/extras/ext4_utils -LOCAL_STATIC_LIBRARIES += libext4_utils_static libz libsparse_static +LOCAL_STATIC_LIBRARIES += \ + libext4_utils_static \ + libsparse_static \ + libz endif ifeq ($(HAVE_SELINUX), true) @@ -31,8 +33,6 @@ LOCAL_STATIC_LIBRARIES += libselinux LOCAL_CFLAGS += -DHAVE_SELINUX endif # HAVE_SELINUX -LOCAL_STATIC_LIBRARIES += libflashutils libmtdutils libmmcutils libbmlutils - LOCAL_STATIC_LIBRARIES += $(TARGET_RECOVERY_UPDATER_LIBS) $(TARGET_RECOVERY_UPDATER_EXTRA_LIBS) LOCAL_STATIC_LIBRARIES += libapplypatch libedify libmtdutils libminzip libz LOCAL_STATIC_LIBRARIES += libmincrypt libbz @@ -53,18 +53,19 @@ LOCAL_C_INCLUDES += $(LOCAL_PATH)/.. inc := $(call intermediates-dir-for,PACKAGING,updater_extensions)/register.inc -# During the first pass of reading the makefiles, we dump the list of -# extension libs to a temp file, then copy that to the ".list" file if -# it is different than the existing .list (if any). The register.inc -# file then uses the .list as a prerequisite, so it is only rebuilt -# (and updater.o recompiled) when the list of extension libs changes. - -junk := $(shell mkdir -p $(dir $(inc));\ - echo $(TARGET_RECOVERY_UPDATER_LIBS) > $(inc).temp;\ - diff -q $(inc).temp $(inc).list 2>/dev/null || cp -f $(inc).temp $(inc).list) +# Encode the value of TARGET_RECOVERY_UPDATER_LIBS into the filename of the dependency. +# So if TARGET_RECOVERY_UPDATER_LIBS is changed, a new dependency file will be generated. +# Note that we have to remove any existing depency files before creating new one, +# so no obsolete dependecy file gets used if you switch back to an old value. +inc_dep_file := $(inc).dep.$(subst $(space),-,$(sort $(TARGET_RECOVERY_UPDATER_LIBS))) +$(inc_dep_file): stem := $(inc).dep +$(inc_dep_file) : + $(hide) mkdir -p $(dir $@) + $(hide) rm -f $(stem).* + $(hide) touch $@ $(inc) : libs := $(TARGET_RECOVERY_UPDATER_LIBS) -$(inc) : $(inc).list +$(inc) : $(inc_dep_file) $(hide) mkdir -p $(dir $@) $(hide) echo "" > $@ $(hide) $(foreach lib,$(libs),echo "extern void Register_$(lib)(void);" >> $@;) @@ -75,6 +76,9 @@ $(inc) : $(inc).list $(call intermediates-dir-for,EXECUTABLES,updater)/updater.o : $(inc) LOCAL_C_INCLUDES += $(dir $(inc)) +inc := +inc_dep_file := + LOCAL_MODULE := updater LOCAL_FORCE_STATIC_EXECUTABLE := true diff --git a/updater/install.c b/updater/install.c index 1ad6d81..41f053d 100644 --- a/updater/install.c +++ b/updater/install.c @@ -33,7 +33,7 @@ #include "edify/expr.h" #include "mincrypt/sha.h" #include "minzip/DirUtil.h" -#include "mounts.h" +#include "mtdutils/mounts.h" #include "mtdutils/mtdutils.h" #include "updater.h" #include "applypatch/applypatch.h" @@ -456,6 +456,26 @@ Value* PackageExtractFileFn(const char* name, State* state, } } +// Create all parent directories of name, if necessary. +static int make_parents(char* name) { + char* p; + for (p = name + (strlen(name)-1); p > name; --p) { + if (*p != '/') continue; + *p = '\0'; + if (make_parents(name) < 0) return -1; + int result = mkdir(name, 0700); + if (result == 0) fprintf(stderr, "symlink(): created [%s]\n", name); + *p = '/'; + if (result == 0 || errno == EEXIST) { + // successfully created or already existed; we're done + return 0; + } else { + fprintf(stderr, "failed to mkdir %s: %s\n", name, strerror(errno)); + return -1; + } + } + return 0; +} // symlink target src1 src2 ... // unlinks any previously existing src1, src2, etc before creating symlinks. @@ -483,6 +503,11 @@ Value* SymlinkFn(const char* name, State* state, int argc, Expr* argv[]) { ++bad; } } + if (make_parents(srcs[i])) { + fprintf(stderr, "%s: failed to symlink %s to %s: making parents failed\n", + name, srcs[i], target); + ++bad; + } if (symlink(target, srcs[i]) < 0) { fprintf(stderr, "%s: failed to symlink %s to %s: %s\n", name, srcs[i], target, strerror(errno)); @@ -504,7 +529,8 @@ Value* SetPermFn(const char* name, State* state, int argc, Expr* argv[]) { int min_args = 4 + (recursive ? 1 : 0); if (argc < min_args) { - return ErrorAbort(state, "%s() expects %d+ args, got %d", name, argc); + return ErrorAbort(state, "%s() expects %d+ args, got %d", + name, min_args, argc); } char** args = ReadVarArgs(state, argc, argv); @@ -626,7 +652,7 @@ Value* FileGetPropFn(const char* name, State* state, int argc, Expr* argv[]) { buffer = malloc(st.st_size+1); if (buffer == NULL) { - ErrorAbort(state, "%s: failed to alloc %d bytes", name, st.st_size+1); + ErrorAbort(state, "%s: failed to alloc %lld bytes", name, st.st_size+1); goto done; } @@ -638,7 +664,7 @@ Value* FileGetPropFn(const char* name, State* state, int argc, Expr* argv[]) { } if (fread(buffer, 1, st.st_size, f) != st.st_size) { - ErrorAbort(state, "%s: failed to read %d bytes from %s", + ErrorAbort(state, "%s: failed to read %lld bytes from %s", name, st.st_size+1, filename); fclose(f); goto done; @@ -712,11 +738,12 @@ Value* WriteRawImageFn(const char* name, State* state, int argc, Expr* argv[]) { return NULL; } + char* partition = NULL; if (partition_value->type != VAL_STRING) { ErrorAbort(state, "partition argument to %s must be string", name); goto done; } - char* partition = partition_value->data; + partition = partition_value->data; if (strlen(partition) == 0) { ErrorAbort(state, "partition argument to %s can't be empty", name); goto done; @@ -726,14 +753,66 @@ Value* WriteRawImageFn(const char* name, State* state, int argc, Expr* argv[]) { goto done; } - char* filename = contents->data; - if (0 == restore_raw_partition(NULL, partition, filename)) - result = strdup(partition); - else { + mtd_scan_partitions(); + const MtdPartition* mtd = mtd_find_partition_by_name(partition); + if (mtd == NULL) { + fprintf(stderr, "%s: no mtd partition named \"%s\"\n", name, partition); + result = strdup(""); + goto done; + } + + MtdWriteContext* ctx = mtd_write_partition(mtd); + if (ctx == NULL) { + fprintf(stderr, "%s: can't write mtd partition \"%s\"\n", + name, partition); result = strdup(""); goto done; } + bool success; + + if (contents->type == VAL_STRING) { + // we're given a filename as the contents + char* filename = contents->data; + FILE* f = fopen(filename, "rb"); + if (f == NULL) { + fprintf(stderr, "%s: can't open %s: %s\n", + name, filename, strerror(errno)); + result = strdup(""); + goto done; + } + + success = true; + char* buffer = malloc(BUFSIZ); + int read; + while (success && (read = fread(buffer, 1, BUFSIZ, f)) > 0) { + int wrote = mtd_write_data(ctx, buffer, read); + success = success && (wrote == read); + } + free(buffer); + fclose(f); + } else { + // we're given a blob as the contents + ssize_t wrote = mtd_write_data(ctx, contents->data, contents->size); + success = (wrote == contents->size); + } + if (!success) { + fprintf(stderr, "mtd_write_data to %s failed: %s\n", + partition, strerror(errno)); + } + + if (mtd_erase_blocks(ctx, -1) == -1) { + fprintf(stderr, "%s: error erasing blocks of %s\n", name, partition); + } + if (mtd_write_close(ctx) != 0) { + fprintf(stderr, "%s: error closing write of %s\n", name, partition); + } + + printf("%s %s partition\n", + success ? "wrote" : "failed to write", partition); + + result = success ? partition : strdup(""); + done: if (result != partition) FreeValue(partition_value); FreeValue(contents); @@ -822,7 +901,7 @@ Value* ApplyPatchFn(const char* name, State* state, int argc, Expr* argv[]) { int result = applypatch(source_filename, target_filename, target_sha1, target_size, - patchcount, patch_sha_str, patches); + patchcount, patch_sha_str, patches, NULL); for (i = 0; i < patchcount; ++i) { FreeValue(patches[i]); |