summaryrefslogtreecommitdiffstats
path: root/updater/install.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--updater/install.cpp (renamed from updater/install.c)366
1 files changed, 186 insertions, 180 deletions
diff --git a/updater/install.c b/updater/install.cpp
index 01a5dd24b..a2efc0b97 100644
--- a/updater/install.c
+++ b/updater/install.cpp
@@ -34,16 +34,24 @@
#include <linux/xattr.h>
#include <inttypes.h>
+#include <memory>
+#include <vector>
+
+#include <android-base/parseint.h>
+#include <android-base/strings.h>
+#include <android-base/stringprintf.h>
+
#include "bootloader.h"
#include "applypatch/applypatch.h"
#include "cutils/android_reboot.h"
#include "cutils/misc.h"
#include "cutils/properties.h"
#include "edify/expr.h"
-#include "mincrypt/sha.h"
+#include "openssl/sha.h"
#include "minzip/DirUtil.h"
#include "mtdutils/mounts.h"
#include "mtdutils/mtdutils.h"
+#include "otafault/ota_io.h"
#include "updater.h"
#include "install.h"
#include "tune2fs.h"
@@ -53,32 +61,44 @@
#include "wipe.h"
#endif
-void uiPrint(State* state, char* buffer) {
- char* line = strtok(buffer, "\n");
- UpdaterInfo* ui = (UpdaterInfo*)(state->cookie);
- while (line) {
- fprintf(ui->cmd_pipe, "ui_print %s\n", line);
- line = strtok(NULL, "\n");
+// Send over the buffer to recovery though the command pipe.
+static void uiPrint(State* state, const std::string& buffer) {
+ UpdaterInfo* ui = reinterpret_cast<UpdaterInfo*>(state->cookie);
+
+ // "line1\nline2\n" will be split into 3 tokens: "line1", "line2" and "".
+ // So skip sending empty strings to UI.
+ std::vector<std::string> lines = android::base::Split(buffer, "\n");
+ for (auto& line: lines) {
+ if (!line.empty()) {
+ fprintf(ui->cmd_pipe, "ui_print %s\n", line.c_str());
+ fprintf(ui->cmd_pipe, "ui_print\n");
+ }
}
- fprintf(ui->cmd_pipe, "ui_print\n");
+
+ // On the updater side, we need to dump the contents to stderr (which has
+ // been redirected to the log file). Because the recovery will only print
+ // the contents to screen when processing pipe command ui_print.
+ fprintf(stderr, "%s", buffer.c_str());
}
__attribute__((__format__(printf, 2, 3))) __nonnull((2))
void uiPrintf(State* state, const char* format, ...) {
- char error_msg[1024];
+ std::string error_msg;
+
va_list ap;
va_start(ap, format);
- vsnprintf(error_msg, sizeof(error_msg), format, ap);
+ android::base::StringAppendV(&error_msg, format, ap);
va_end(ap);
+
uiPrint(state, error_msg);
}
// Take a sha-1 digest and return it as a newly-allocated hex string.
char* PrintSha1(const uint8_t* digest) {
- char* buffer = malloc(SHA_DIGEST_SIZE*2 + 1);
- int i;
+ char* buffer = reinterpret_cast<char*>(malloc(SHA_DIGEST_LENGTH*2 + 1));
const char* alphabet = "0123456789abcdef";
- for (i = 0; i < SHA_DIGEST_SIZE; ++i) {
+ size_t i;
+ for (i = 0; i < SHA_DIGEST_LENGTH; ++i) {
buffer[i*2] = alphabet[(digest[i] >> 4) & 0xf];
buffer[i*2+1] = alphabet[digest[i] & 0xf];
}
@@ -133,18 +153,20 @@ Value* MountFn(const char* name, State* state, int argc, Expr* argv[]) {
goto done;
}
- char *secontext = NULL;
+ {
+ char *secontext = NULL;
- if (sehandle) {
- selabel_lookup(sehandle, &secontext, mount_point, 0755);
- setfscreatecon(secontext);
- }
+ if (sehandle) {
+ selabel_lookup(sehandle, &secontext, mount_point, 0755);
+ setfscreatecon(secontext);
+ }
- mkdir(mount_point, 0755);
+ mkdir(mount_point, 0755);
- if (secontext) {
- freecon(secontext);
- setfscreatecon(NULL);
+ if (secontext) {
+ freecon(secontext);
+ setfscreatecon(NULL);
+ }
}
if (strcmp(partition_type, "MTD") == 0) {
@@ -152,7 +174,7 @@ Value* MountFn(const char* name, State* state, int argc, Expr* argv[]) {
const MtdPartition* mtd;
mtd = mtd_find_partition_by_name(location);
if (mtd == NULL) {
- uiPrintf(state, "%s: no mtd partition named \"%s\"",
+ uiPrintf(state, "%s: no mtd partition named \"%s\"\n",
name, location);
result = strdup("");
goto done;
@@ -202,11 +224,13 @@ Value* IsMountedFn(const char* name, State* state, int argc, Expr* argv[]) {
}
scan_mounted_volumes();
- const MountedVolume* vol = find_mounted_volume_by_mount_point(mount_point);
- if (vol == NULL) {
- result = strdup("");
- } else {
- result = mount_point;
+ {
+ const MountedVolume* vol = find_mounted_volume_by_mount_point(mount_point);
+ if (vol == NULL) {
+ result = strdup("");
+ } else {
+ result = mount_point;
+ }
}
done:
@@ -230,17 +254,19 @@ Value* UnmountFn(const char* name, State* state, int argc, Expr* argv[]) {
}
scan_mounted_volumes();
- const MountedVolume* vol = find_mounted_volume_by_mount_point(mount_point);
- if (vol == NULL) {
- uiPrintf(state, "unmount of %s failed; no such volume\n", mount_point);
- result = strdup("");
- } else {
- int ret = unmount_mounted_volume(vol);
- if (ret != 0) {
- uiPrintf(state, "unmount of %s failed (%d): %s\n",
- mount_point, ret, strerror(errno));
+ {
+ const MountedVolume* vol = find_mounted_volume_by_mount_point(mount_point);
+ if (vol == NULL) {
+ uiPrintf(state, "unmount of %s failed; no such volume\n", mount_point);
+ result = strdup("");
+ } else {
+ int ret = unmount_mounted_volume(vol);
+ if (ret != 0) {
+ uiPrintf(state, "unmount of %s failed (%d): %s\n",
+ mount_point, ret, strerror(errno));
+ }
+ result = mount_point;
}
- result = mount_point;
}
done:
@@ -413,13 +439,11 @@ done:
}
Value* DeleteFn(const char* name, State* state, int argc, Expr* argv[]) {
- char** paths = malloc(argc * sizeof(char*));
- int i;
- for (i = 0; i < argc; ++i) {
+ char** paths = reinterpret_cast<char**>(malloc(argc * sizeof(char*)));
+ for (int i = 0; i < argc; ++i) {
paths[i] = Evaluate(state, argv[i]);
if (paths[i] == NULL) {
- int j;
- for (j = 0; j < i; ++i) {
+ for (int j = 0; j < i; ++j) {
free(paths[j]);
}
free(paths);
@@ -430,7 +454,7 @@ Value* DeleteFn(const char* name, State* state, int argc, Expr* argv[]) {
bool recursive = (strcmp(name, "delete_recursive") == 0);
int success = 0;
- for (i = 0; i < argc; ++i) {
+ for (int i = 0; i < argc; ++i) {
if ((recursive ? dirUnlinkHierarchy(paths[i]) : unlink(paths[i])) == 0)
++success;
free(paths[i]);
@@ -454,7 +478,8 @@ Value* ShowProgressFn(const char* name, State* state, int argc, Expr* argv[]) {
}
double frac = strtod(frac_str, NULL);
- int sec = strtol(sec_str, NULL, 10);
+ int sec;
+ android::base::ParseInt(sec_str, &sec);
UpdaterInfo* ui = (UpdaterInfo*)(state->cookie);
fprintf(ui->cmd_pipe, "progress %f %d\n", frac, sec);
@@ -517,8 +542,6 @@ Value* PackageExtractFileFn(const char* name, State* state,
}
bool success = false;
- UpdaterInfo* ui = (UpdaterInfo*)(state->cookie);
-
if (argc == 2) {
// The two-argument version extracts to a file.
@@ -534,14 +557,23 @@ Value* PackageExtractFileFn(const char* name, State* state,
goto done2;
}
- FILE* f = fopen(dest_path, "wb");
- if (f == NULL) {
- printf("%s: can't open %s for write: %s\n",
- name, dest_path, strerror(errno));
- goto done2;
+ {
+ int fd = TEMP_FAILURE_RETRY(ota_open(dest_path, O_WRONLY | O_CREAT | O_TRUNC | O_SYNC,
+ S_IRUSR | S_IWUSR));
+ if (fd == -1) {
+ printf("%s: can't open %s for write: %s\n", name, dest_path, strerror(errno));
+ goto done2;
+ }
+ success = mzExtractZipEntryToFile(za, entry, fd);
+ if (ota_fsync(fd) == -1) {
+ printf("fsync of \"%s\" failed: %s\n", dest_path, strerror(errno));
+ success = false;
+ }
+ if (ota_close(fd) == -1) {
+ printf("close of \"%s\" failed: %s\n", dest_path, strerror(errno));
+ success = false;
+ }
}
- success = mzExtractZipEntryToFile(za, entry, fileno(f));
- fclose(f);
done2:
free(zip_path);
@@ -552,13 +584,13 @@ Value* PackageExtractFileFn(const char* name, State* state,
// as the result.
char* zip_path;
- Value* v = malloc(sizeof(Value));
+ if (ReadArgs(state, argv, 1, &zip_path) < 0) return NULL;
+
+ Value* v = reinterpret_cast<Value*>(malloc(sizeof(Value)));
v->type = VAL_BLOB;
v->size = -1;
v->data = NULL;
- if (ReadArgs(state, argv, 1, &zip_path) < 0) return NULL;
-
ZipArchive* za = ((UpdaterInfo*)(state->cookie))->package_zip;
const ZipEntry* entry = mzFindZipEntry(za, zip_path);
if (entry == NULL) {
@@ -567,7 +599,7 @@ Value* PackageExtractFileFn(const char* name, State* state,
}
v->size = mzGetZipEntryUncompLen(entry);
- v->data = malloc(v->size);
+ v->data = reinterpret_cast<char*>(malloc(v->size));
if (v->data == NULL) {
printf("%s: failed to allocate %ld bytes for %s\n",
name, (long)v->size, zip_path);
@@ -866,17 +898,14 @@ static int do_SetMetadataRecursive(const char* filename, const struct stat *stat
}
static Value* SetMetadataFn(const char* name, State* state, int argc, Expr* argv[]) {
- int i;
int bad = 0;
- static int nwarnings = 0;
struct stat sb;
Value* result = NULL;
bool recursive = (strcmp(name, "set_metadata_recursive") == 0);
if ((argc % 2) != 1) {
- return ErrorAbort(state, "%s() expects an odd number of arguments, got %d",
- name, argc);
+ return ErrorAbort(state, "%s() expects an odd number of arguments, got %d", name, argc);
}
char** args = ReadVarArgs(state, argc, argv);
@@ -887,20 +916,22 @@ static Value* SetMetadataFn(const char* name, State* state, int argc, Expr* argv
goto done;
}
- struct perm_parsed_args parsed = ParsePermArgs(state, argc, args);
+ {
+ struct perm_parsed_args parsed = ParsePermArgs(state, argc, args);
- if (recursive) {
- recursive_parsed_args = parsed;
- recursive_state = state;
- bad += nftw(args[0], do_SetMetadataRecursive, 30, FTW_CHDIR | FTW_DEPTH | FTW_PHYS);
- memset(&recursive_parsed_args, 0, sizeof(recursive_parsed_args));
- recursive_state = NULL;
- } else {
- bad += ApplyParsedPerms(state, args[0], &sb, parsed);
+ if (recursive) {
+ recursive_parsed_args = parsed;
+ recursive_state = state;
+ bad += nftw(args[0], do_SetMetadataRecursive, 30, FTW_CHDIR | FTW_DEPTH | FTW_PHYS);
+ memset(&recursive_parsed_args, 0, sizeof(recursive_parsed_args));
+ recursive_state = NULL;
+ } else {
+ bad += ApplyParsedPerms(state, args[0], &sb, parsed);
+ }
}
done:
- for (i = 0; i < argc; ++i) {
+ for (int i = 0; i < argc; ++i) {
free(args[i]);
}
free(args);
@@ -920,8 +951,7 @@ Value* GetPropFn(const char* name, State* state, int argc, Expr* argv[]) {
if (argc != 1) {
return ErrorAbort(state, "%s() expects 1 arg, got %d", name, argc);
}
- char* key;
- key = Evaluate(state, argv[0]);
+ char* key = Evaluate(state, argv[0]);
if (key == NULL) return NULL;
char value[PROPERTY_VALUE_MAX];
@@ -948,33 +978,31 @@ Value* FileGetPropFn(const char* name, State* state, int argc, Expr* argv[]) {
struct stat st;
if (stat(filename, &st) < 0) {
- ErrorAbort(state, "%s: failed to stat \"%s\": %s",
- name, filename, strerror(errno));
+ ErrorAbort(state, "%s: failed to stat \"%s\": %s", name, filename, strerror(errno));
goto done;
}
#define MAX_FILE_GETPROP_SIZE 65536
if (st.st_size > MAX_FILE_GETPROP_SIZE) {
- ErrorAbort(state, "%s too large for %s (max %d)",
- filename, name, MAX_FILE_GETPROP_SIZE);
+ ErrorAbort(state, "%s too large for %s (max %d)", filename, name, MAX_FILE_GETPROP_SIZE);
goto done;
}
- buffer = malloc(st.st_size+1);
+ buffer = reinterpret_cast<char*>(malloc(st.st_size+1));
if (buffer == NULL) {
ErrorAbort(state, "%s: failed to alloc %lld bytes", name, (long long)st.st_size+1);
goto done;
}
- FILE* f = fopen(filename, "rb");
+ FILE* f;
+ f = fopen(filename, "rb");
if (f == NULL) {
- ErrorAbort(state, "%s: failed to open %s: %s",
- name, filename, strerror(errno));
+ ErrorAbort(state, "%s: failed to open %s: %s", name, filename, strerror(errno));
goto done;
}
- if (fread(buffer, 1, st.st_size, f) != st.st_size) {
+ if (ota_fread(buffer, 1, st.st_size, f) != static_cast<size_t>(st.st_size)) {
ErrorAbort(state, "%s: failed to read %lld bytes from %s",
name, (long long)st.st_size+1, filename);
fclose(f);
@@ -984,7 +1012,8 @@ Value* FileGetPropFn(const char* name, State* state, int argc, Expr* argv[]) {
fclose(f);
- char* line = strtok(buffer, "\n");
+ char* line;
+ line = strtok(buffer, "\n");
do {
// skip whitespace at start of line
while (*line && isspace(*line)) ++line;
@@ -1028,15 +1057,6 @@ Value* FileGetPropFn(const char* name, State* state, int argc, Expr* argv[]) {
return StringValue(result);
}
-
-static bool write_raw_image_cb(const unsigned char* data,
- int data_len, void* ctx) {
- int r = mtd_write_data((MtdWriteContext*)ctx, (const char *)data, data_len);
- if (r == data_len) return true;
- printf("%s\n", strerror(errno));
- return false;
-}
-
// write_raw_image(filename_or_blob, partition)
Value* WriteRawImageFn(const char* name, State* state, int argc, Expr* argv[]) {
char* result = NULL;
@@ -1063,14 +1083,16 @@ Value* WriteRawImageFn(const char* name, State* state, int argc, Expr* argv[]) {
}
mtd_scan_partitions();
- const MtdPartition* mtd = mtd_find_partition_by_name(partition);
+ const MtdPartition* mtd;
+ mtd = mtd_find_partition_by_name(partition);
if (mtd == NULL) {
printf("%s: no mtd partition named \"%s\"\n", name, partition);
result = strdup("");
goto done;
}
- MtdWriteContext* ctx = mtd_write_partition(mtd);
+ MtdWriteContext* ctx;
+ ctx = mtd_write_partition(mtd);
if (ctx == NULL) {
printf("%s: can't write mtd partition \"%s\"\n",
name, partition);
@@ -1083,23 +1105,22 @@ Value* WriteRawImageFn(const char* name, State* state, int argc, Expr* argv[]) {
if (contents->type == VAL_STRING) {
// we're given a filename as the contents
char* filename = contents->data;
- FILE* f = fopen(filename, "rb");
+ FILE* f = ota_fopen(filename, "rb");
if (f == NULL) {
- printf("%s: can't open %s: %s\n",
- name, filename, strerror(errno));
+ printf("%s: can't open %s: %s\n", name, filename, strerror(errno));
result = strdup("");
goto done;
}
success = true;
- char* buffer = malloc(BUFSIZ);
+ char* buffer = reinterpret_cast<char*>(malloc(BUFSIZ));
int read;
- while (success && (read = fread(buffer, 1, BUFSIZ, f)) > 0) {
+ while (success && (read = ota_fread(buffer, 1, BUFSIZ, f)) > 0) {
int wrote = mtd_write_data(ctx, buffer, read);
success = success && (wrote == read);
}
free(buffer);
- fclose(f);
+ ota_fclose(f);
} else {
// we're given a blob as the contents
ssize_t wrote = mtd_write_data(ctx, contents->data, contents->size);
@@ -1136,13 +1157,11 @@ Value* ApplyPatchSpaceFn(const char* name, State* state,
return NULL;
}
- char* endptr;
- size_t bytes = strtol(bytes_str, &endptr, 10);
- if (bytes == 0 && endptr == bytes_str) {
- ErrorAbort(state, "%s(): can't parse \"%s\" as byte count\n\n",
- name, bytes_str);
+ size_t bytes;
+ if (!android::base::ParseUint(bytes_str, &bytes)) {
+ ErrorAbort(state, "%s(): can't parse \"%s\" as byte count\n\n", name, bytes_str);
free(bytes_str);
- return NULL;
+ return nullptr;
}
return StringValue(strdup(CacheSizeCheck(bytes) ? "" : "t"));
@@ -1166,57 +1185,51 @@ Value* ApplyPatchFn(const char* name, State* state, int argc, Expr* argv[]) {
return NULL;
}
- char* endptr;
- size_t target_size = strtol(target_size_str, &endptr, 10);
- if (target_size == 0 && endptr == target_size_str) {
- ErrorAbort(state, "%s(): can't parse \"%s\" as byte count",
- name, target_size_str);
+ size_t target_size;
+ if (!android::base::ParseUint(target_size_str, &target_size)) {
+ ErrorAbort(state, "%s(): can't parse \"%s\" as byte count", name, target_size_str);
free(source_filename);
free(target_filename);
free(target_sha1);
free(target_size_str);
- return NULL;
+ return nullptr;
}
int patchcount = (argc-4) / 2;
- Value** patches = ReadValueVarArgs(state, argc-4, argv+4);
+ std::unique_ptr<Value*, decltype(&free)> arg_values(ReadValueVarArgs(state, argc-4, argv+4),
+ free);
+ if (!arg_values) {
+ return nullptr;
+ }
+ std::vector<std::unique_ptr<Value, decltype(&FreeValue)>> patch_shas;
+ std::vector<std::unique_ptr<Value, decltype(&FreeValue)>> patches;
+ // Protect values by unique_ptrs first to get rid of memory leak.
+ for (int i = 0; i < patchcount * 2; i += 2) {
+ patch_shas.emplace_back(arg_values.get()[i], FreeValue);
+ patches.emplace_back(arg_values.get()[i+1], FreeValue);
+ }
- int i;
- for (i = 0; i < patchcount; ++i) {
- if (patches[i*2]->type != VAL_STRING) {
+ for (int i = 0; i < patchcount; ++i) {
+ if (patch_shas[i]->type != VAL_STRING) {
ErrorAbort(state, "%s(): sha-1 #%d is not string", name, i);
- break;
+ return nullptr;
}
- if (patches[i*2+1]->type != VAL_BLOB) {
+ if (patches[i]->type != VAL_BLOB) {
ErrorAbort(state, "%s(): patch #%d is not blob", name, i);
- break;
+ return nullptr;
}
}
- if (i != patchcount) {
- for (i = 0; i < patchcount*2; ++i) {
- FreeValue(patches[i]);
- }
- free(patches);
- return NULL;
- }
- char** patch_sha_str = malloc(patchcount * sizeof(char*));
- for (i = 0; i < patchcount; ++i) {
- patch_sha_str[i] = patches[i*2]->data;
- patches[i*2]->data = NULL;
- FreeValue(patches[i*2]);
- patches[i] = patches[i*2+1];
+ std::vector<char*> patch_sha_str;
+ std::vector<Value*> patch_ptrs;
+ for (int i = 0; i < patchcount; ++i) {
+ patch_sha_str.push_back(patch_shas[i]->data);
+ patch_ptrs.push_back(patches[i].get());
}
int result = applypatch(source_filename, target_filename,
target_sha1, target_size,
- patchcount, patch_sha_str, patches, NULL);
-
- for (i = 0; i < patchcount; ++i) {
- FreeValue(patches[i]);
- }
- free(patch_sha_str);
- free(patches);
+ patchcount, patch_sha_str.data(), patch_ptrs.data(), NULL);
return StringValue(strdup(result == 0 ? "t" : ""));
}
@@ -1248,28 +1261,24 @@ Value* ApplyPatchCheckFn(const char* name, State* state,
return StringValue(strdup(result == 0 ? "t" : ""));
}
+// This is the updater side handler for ui_print() in edify script. Contents
+// will be sent over to the recovery side for on-screen display.
Value* UIPrintFn(const char* name, State* state, int argc, Expr* argv[]) {
char** args = ReadVarArgs(state, argc, argv);
if (args == NULL) {
return NULL;
}
- int size = 0;
- int i;
- for (i = 0; i < argc; ++i) {
- size += strlen(args[i]);
- }
- char* buffer = malloc(size+1);
- size = 0;
- for (i = 0; i < argc; ++i) {
- strcpy(buffer+size, args[i]);
- size += strlen(args[i]);
+ std::string buffer;
+ for (int i = 0; i < argc; ++i) {
+ buffer += args[i];
free(args[i]);
}
free(args);
- buffer[size] = '\0';
+
+ buffer += "\n";
uiPrint(state, buffer);
- return StringValue(buffer);
+ return StringValue(strdup(buffer.c_str()));
}
Value* WipeCacheFn(const char* name, State* state, int argc, Expr* argv[]) {
@@ -1289,7 +1298,7 @@ Value* RunProgramFn(const char* name, State* state, int argc, Expr* argv[]) {
return NULL;
}
- char** args2 = malloc(sizeof(char*) * (argc+1));
+ char** args2 = reinterpret_cast<char**>(malloc(sizeof(char*) * (argc+1)));
memcpy(args2, args, sizeof(char*) * argc);
args2[argc] = NULL;
@@ -1339,24 +1348,27 @@ Value* Sha1CheckFn(const char* name, State* state, int argc, Expr* argv[]) {
return ErrorAbort(state, "%s() expects at least 1 arg", name);
}
- Value** args = ReadValueVarArgs(state, argc, argv);
- if (args == NULL) {
- return NULL;
+ std::unique_ptr<Value*, decltype(&free)> arg_values(ReadValueVarArgs(state, argc, argv), free);
+ if (arg_values == nullptr) {
+ return nullptr;
+ }
+ std::vector<std::unique_ptr<Value, decltype(&FreeValue)>> args;
+ for (int i = 0; i < argc; ++i) {
+ args.emplace_back(arg_values.get()[i], FreeValue);
}
if (args[0]->size < 0) {
return StringValue(strdup(""));
}
- uint8_t digest[SHA_DIGEST_SIZE];
- SHA_hash(args[0]->data, args[0]->size, digest);
- FreeValue(args[0]);
+ uint8_t digest[SHA_DIGEST_LENGTH];
+ SHA1(reinterpret_cast<uint8_t*>(args[0]->data), args[0]->size, digest);
if (argc == 1) {
return StringValue(PrintSha1(digest));
}
int i;
- uint8_t* arg_digest = malloc(SHA_DIGEST_SIZE);
+ uint8_t arg_digest[SHA_DIGEST_LENGTH];
for (i = 1; i < argc; ++i) {
if (args[i]->type != VAL_STRING) {
printf("%s(): arg %d is not a string; skipping",
@@ -1365,22 +1377,16 @@ Value* Sha1CheckFn(const char* name, State* state, int argc, Expr* argv[]) {
// Warn about bad args and skip them.
printf("%s(): error parsing \"%s\" as sha-1; skipping",
name, args[i]->data);
- } else if (memcmp(digest, arg_digest, SHA_DIGEST_SIZE) == 0) {
+ } else if (memcmp(digest, arg_digest, SHA_DIGEST_LENGTH) == 0) {
break;
}
- FreeValue(args[i]);
}
if (i >= argc) {
// Didn't match any of the hex strings; return false.
return StringValue(strdup(""));
}
- // Found a match; free all the remaining arguments and return the
- // matched one.
- int j;
- for (j = i+1; j < argc; ++j) {
- FreeValue(args[j]);
- }
- return args[i];
+ // Found a match.
+ return args[i].release();
}
// Read a local file and return its contents (the Value* returned
@@ -1392,7 +1398,7 @@ Value* ReadFileFn(const char* name, State* state, int argc, Expr* argv[]) {
char* filename;
if (ReadArgs(state, argv, 1, &filename) < 0) return NULL;
- Value* v = malloc(sizeof(Value));
+ Value* v = reinterpret_cast<Value*>(malloc(sizeof(Value)));
v->type = VAL_BLOB;
FileContents fc;
@@ -1435,7 +1441,7 @@ Value* RebootNowFn(const char* name, State* state, int argc, Expr* argv[]) {
memset(buffer, 0, sizeof(((struct bootloader_message*)0)->command));
FILE* f = fopen(filename, "r+b");
fseek(f, offsetof(struct bootloader_message, command), SEEK_SET);
- fwrite(buffer, sizeof(((struct bootloader_message*)0)->command), 1, f);
+ ota_fwrite(buffer, sizeof(((struct bootloader_message*)0)->command), 1, f);
fclose(f);
free(filename);
@@ -1483,7 +1489,7 @@ Value* SetStageFn(const char* name, State* state, int argc, Expr* argv[]) {
to_write = max_size;
stagestr[max_size-1] = 0;
}
- fwrite(stagestr, to_write, 1, f);
+ ota_fwrite(stagestr, to_write, 1, f);
fclose(f);
free(stagestr);
@@ -1503,7 +1509,7 @@ Value* GetStageFn(const char* name, State* state, int argc, Expr* argv[]) {
char buffer[sizeof(((struct bootloader_message*)0)->stage)];
FILE* f = fopen(filename, "rb");
fseek(f, offsetof(struct bootloader_message, stage), SEEK_SET);
- fread(buffer, sizeof(buffer), 1, f);
+ ota_fread(buffer, sizeof(buffer), 1, f);
fclose(f);
buffer[sizeof(buffer)-1] = '\0';
@@ -1519,14 +1525,15 @@ Value* WipeBlockDeviceFn(const char* name, State* state, int argc, Expr* argv[])
char* len_str;
if (ReadArgs(state, argv, 2, &filename, &len_str) < 0) return NULL;
- size_t len = strtoull(len_str, NULL, 0);
- int fd = open(filename, O_WRONLY, 0644);
+ size_t len;
+ android::base::ParseUint(len_str, &len);
+ int fd = ota_open(filename, O_WRONLY, 0644);
int success = wipe_block_device(fd, len);
free(filename);
free(len_str);
- close(fd);
+ ota_close(fd);
return StringValue(strdup(success ? "t" : ""));
}
@@ -1550,15 +1557,14 @@ Value* Tune2FsFn(const char* name, State* state, int argc, Expr* argv[]) {
return ErrorAbort(state, "%s() could not read args", name);
}
- int i;
- char** args2 = malloc(sizeof(char*) * (argc+1));
+ char** args2 = reinterpret_cast<char**>(malloc(sizeof(char*) * (argc+1)));
// Tune2fs expects the program name as its args[0]
args2[0] = strdup(name);
- for (i = 0; i < argc; ++i) {
+ for (int i = 0; i < argc; ++i) {
args2[i + 1] = args[i];
}
int result = tune2fs_main(argc + 1, args2);
- for (i = 0; i < argc; ++i) {
+ for (int i = 0; i < argc; ++i) {
free(args[i]);
}
free(args);