diff options
Diffstat (limited to '')
-rw-r--r-- | updater/install.cpp | 81 |
1 files changed, 46 insertions, 35 deletions
diff --git a/updater/install.cpp b/updater/install.cpp index a2bc4029f..97e390560 100644 --- a/updater/install.cpp +++ b/updater/install.cpp @@ -34,6 +34,10 @@ #include <linux/xattr.h> #include <inttypes.h> +#include <base/parseint.h> +#include <base/strings.h> +#include <base/stringprintf.h> + #include "bootloader.h" #include "applypatch/applypatch.h" #include "cutils/android_reboot.h" @@ -53,23 +57,35 @@ #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); } @@ -154,7 +170,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; @@ -459,7 +475,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); @@ -975,7 +992,7 @@ Value* FileGetPropFn(const char* name, State* state, int argc, Expr* argv[]) { goto done; } - if (fread(buffer, 1, st.st_size, f) != st.st_size) { + if (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); @@ -1130,12 +1147,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) { + 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")); @@ -1159,16 +1175,14 @@ 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; @@ -1241,28 +1255,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 = reinterpret_cast<char*>(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[]) { @@ -1512,7 +1522,8 @@ 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); + size_t len; + android::base::ParseUint(len_str, &len); int fd = open(filename, O_WRONLY, 0644); int success = wipe_block_device(fd, len); |