diff options
-rw-r--r-- | applypatch/imgdiff.cpp | 10 | ||||
-rw-r--r-- | recovery.cpp | 3 | ||||
-rw-r--r-- | screen_ui.cpp | 2 | ||||
-rw-r--r-- | uncrypt/Android.mk | 2 | ||||
-rw-r--r-- | uncrypt/uncrypt.rc | 9 | ||||
-rw-r--r-- | updater/blockimg.cpp | 55 | ||||
-rw-r--r-- | updater/install.cpp | 58 |
7 files changed, 79 insertions, 60 deletions
diff --git a/applypatch/imgdiff.cpp b/applypatch/imgdiff.cpp index 4d83ffb2e..50cabbe6b 100644 --- a/applypatch/imgdiff.cpp +++ b/applypatch/imgdiff.cpp @@ -628,7 +628,15 @@ unsigned char* MakePatch(ImageChunk* src, ImageChunk* tgt, size_t* size) { } char ptemp[] = "/tmp/imgdiff-patch-XXXXXX"; - mkstemp(ptemp); + int fd = mkstemp(ptemp); + + if (fd == -1) { + printf("MakePatch failed to create a temporary file: %s\n", + strerror(errno)); + return NULL; + } + close(fd); // temporary file is created and we don't need its file + // descriptor int r = bsdiff(src->data, src->len, &(src->I), tgt->data, tgt->len, ptemp); if (r != 0) { diff --git a/recovery.cpp b/recovery.cpp index c683bae1d..379137a64 100644 --- a/recovery.cpp +++ b/recovery.cpp @@ -745,10 +745,7 @@ static void choose_recovery_file(Device* device) { int chosen_item = get_menu_selection(headers, entries, 1, 0, device); if (strcmp(entries[chosen_item], "Back") == 0) break; - // TODO: do we need to redirect? ShowFile could just avoid writing to stdio. - redirect_stdio("/dev/null"); ui->ShowFile(entries[chosen_item]); - redirect_stdio(TEMPORARY_LOG_FILE); } for (size_t i = 0; i < (sizeof(entries) / sizeof(*entries)); i++) { diff --git a/screen_ui.cpp b/screen_ui.cpp index ddf85c19e..f2fda2fb5 100644 --- a/screen_ui.cpp +++ b/screen_ui.cpp @@ -581,7 +581,7 @@ void ScreenRecoveryUI::ShowFile(FILE* fp) { bool show_prompt = false; while (true) { if (show_prompt) { - Print("--(%d%% of %d bytes)--", + PrintOnScreenOnly("--(%d%% of %d bytes)--", static_cast<int>(100 * (double(ftell(fp)) / double(sb.st_size))), static_cast<int>(sb.st_size)); Redraw(); diff --git a/uncrypt/Android.mk b/uncrypt/Android.mk index f31db4243..6422cb2f4 100644 --- a/uncrypt/Android.mk +++ b/uncrypt/Android.mk @@ -26,4 +26,6 @@ LOCAL_MODULE := uncrypt LOCAL_STATIC_LIBRARIES := libbase liblog libfs_mgr libcutils +LOCAL_INIT_RC := uncrypt.rc + include $(BUILD_EXECUTABLE) diff --git a/uncrypt/uncrypt.rc b/uncrypt/uncrypt.rc new file mode 100644 index 000000000..5f4c47936 --- /dev/null +++ b/uncrypt/uncrypt.rc @@ -0,0 +1,9 @@ +service uncrypt /system/bin/uncrypt + class main + disabled + oneshot + +service pre-recovery /system/bin/uncrypt --reboot + class main + disabled + oneshot diff --git a/updater/blockimg.cpp b/updater/blockimg.cpp index 5f5f9bd72..091bedf53 100644 --- a/updater/blockimg.cpp +++ b/updater/blockimg.cpp @@ -378,19 +378,16 @@ static int WriteBlocks(const RangeSet& tgt, uint8_t* buffer, int fd) { // <src_range> <tgt_range> // // The source range is loaded into the provided buffer, reallocating -// it to make it larger if necessary. The target ranges are returned -// in *tgt, if tgt is non-null. +// it to make it larger if necessary. -static int LoadSrcTgtVersion1(char** wordsave, RangeSet* tgt, size_t& src_blocks, +static int LoadSrcTgtVersion1(char** wordsave, RangeSet& tgt, size_t& src_blocks, uint8_t** buffer, size_t* buffer_alloc, int fd) { char* word = strtok_r(nullptr, " ", wordsave); RangeSet src; parse_range(word, src); - if (tgt != nullptr) { - word = strtok_r(nullptr, " ", wordsave); - parse_range(word, *tgt); - } + word = strtok_r(nullptr, " ", wordsave); + parse_range(word, tgt); allocate(src.size * BLOCKSIZE, buffer, buffer_alloc); int rc = ReadBlocks(src, *buffer, fd); @@ -730,9 +727,15 @@ static int SaveStash(const std::string& base, char** wordsave, uint8_t** buffer, return 0; } - if (LoadSrcTgtVersion1(wordsave, nullptr, blocks, buffer, buffer_alloc, fd) == -1) { + char* word = strtok_r(nullptr, " ", wordsave); + RangeSet src; + parse_range(word, src); + + allocate(src.size * BLOCKSIZE, buffer, buffer_alloc); + if (ReadBlocks(src, *buffer, fd) == -1) { return -1; } + blocks = src.size; if (usehash && VerifyBlocks(id, *buffer, blocks, true) != 0) { // Source blocks have unexpected contents. If we actually need this @@ -791,7 +794,7 @@ static void MoveRange(uint8_t* dest, const RangeSet& locs, const uint8_t* source // reallocated if needed to accommodate the source data. *tgt is the // target RangeSet. Any stashes required are loaded using LoadStash. -static int LoadSrcTgtVersion2(char** wordsave, RangeSet* tgt, size_t& src_blocks, uint8_t** buffer, +static int LoadSrcTgtVersion2(char** wordsave, RangeSet& tgt, size_t& src_blocks, uint8_t** buffer, size_t* buffer_alloc, int fd, const std::string& stashbase, bool* overlap) { char* word; char* colonsave; @@ -800,10 +803,8 @@ static int LoadSrcTgtVersion2(char** wordsave, RangeSet* tgt, size_t& src_blocks size_t stashalloc = 0; uint8_t* stash = nullptr; - if (tgt != nullptr) { - word = strtok_r(nullptr, " ", wordsave); - parse_range(word, *tgt); - } + word = strtok_r(nullptr, " ", wordsave); + parse_range(word, tgt); word = strtok_r(nullptr, " ", wordsave); src_blocks = strtol(word, nullptr, 0); @@ -818,8 +819,8 @@ static int LoadSrcTgtVersion2(char** wordsave, RangeSet* tgt, size_t& src_blocks parse_range(word, src); int res = ReadBlocks(src, *buffer, fd); - if (overlap && tgt) { - *overlap = range_overlaps(src, *tgt); + if (overlap) { + *overlap = range_overlaps(src, tgt); } if (res == -1) { @@ -902,13 +903,9 @@ struct CommandParameters { // If the return value is 0, source blocks have expected content and the command // can be performed. -static int LoadSrcTgtVersion3(CommandParameters& params, RangeSet* tgt, size_t& src_blocks, +static int LoadSrcTgtVersion3(CommandParameters& params, RangeSet& tgt, size_t& src_blocks, bool onehash, bool& overlap) { - if (!tgt) { - return -1; - } - char* srchash = strtok_r(nullptr, " ", ¶ms.cpos); if (srchash == nullptr) { fprintf(stderr, "missing source hash\n"); @@ -932,13 +929,13 @@ static int LoadSrcTgtVersion3(CommandParameters& params, RangeSet* tgt, size_t& return -1; } - std::vector<uint8_t> tgtbuffer(tgt->size * BLOCKSIZE); + std::vector<uint8_t> tgtbuffer(tgt.size * BLOCKSIZE); - if (ReadBlocks(*tgt, tgtbuffer.data(), params.fd) == -1) { + if (ReadBlocks(tgt, tgtbuffer.data(), params.fd) == -1) { return -1; } - if (VerifyBlocks(tgthash, tgtbuffer.data(), tgt->size, false) == 0) { + if (VerifyBlocks(tgthash, tgtbuffer.data(), tgt.size, false) == 0) { // Target blocks already have expected content, command should be skipped fprintf(stderr, "verified, to return 1"); return 1; @@ -989,13 +986,13 @@ static int PerformCommandMove(CommandParameters& params) { RangeSet tgt; if (params.version == 1) { - status = LoadSrcTgtVersion1(¶ms.cpos, &tgt, blocks, ¶ms.buffer, + status = LoadSrcTgtVersion1(¶ms.cpos, tgt, blocks, ¶ms.buffer, ¶ms.bufsize, params.fd); } else if (params.version == 2) { - status = LoadSrcTgtVersion2(¶ms.cpos, &tgt, blocks, ¶ms.buffer, + status = LoadSrcTgtVersion2(¶ms.cpos, tgt, blocks, ¶ms.buffer, ¶ms.bufsize, params.fd, params.stashbase, nullptr); } else if (params.version >= 3) { - status = LoadSrcTgtVersion3(params, &tgt, blocks, true, overlap); + status = LoadSrcTgtVersion3(params, tgt, blocks, true, overlap); } if (status == -1) { @@ -1149,13 +1146,13 @@ static int PerformCommandDiff(CommandParameters& params) { size_t blocks = 0; int status = 0; if (params.version == 1) { - status = LoadSrcTgtVersion1(¶ms.cpos, &tgt, blocks, ¶ms.buffer, + status = LoadSrcTgtVersion1(¶ms.cpos, tgt, blocks, ¶ms.buffer, ¶ms.bufsize, params.fd); } else if (params.version == 2) { - status = LoadSrcTgtVersion2(¶ms.cpos, &tgt, blocks, ¶ms.buffer, + status = LoadSrcTgtVersion2(¶ms.cpos, tgt, blocks, ¶ms.buffer, ¶ms.bufsize, params.fd, params.stashbase, nullptr); } else if (params.version >= 3) { - status = LoadSrcTgtVersion3(params, &tgt, blocks, false, overlap); + status = LoadSrcTgtVersion3(params, tgt, blocks, false, overlap); } if (status == -1) { diff --git a/updater/install.cpp b/updater/install.cpp index 422a1bb1e..a6ed078ba 100644 --- a/updater/install.cpp +++ b/updater/install.cpp @@ -34,6 +34,9 @@ #include <linux/xattr.h> #include <inttypes.h> +#include <base/strings.h> +#include <base/stringprintf.h> + #include "bootloader.h" #include "applypatch/applypatch.h" #include "cutils/android_reboot.h" @@ -53,28 +56,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"); - // The recovery will only print the contents to screen for pipe command - // ui_print. We need to dump the contents to stderr (which has been - // redirected to the log file) directly. - fprintf(stderr, "%s", buffer); + // 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); } @@ -159,7 +169,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; @@ -1246,28 +1256,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[]) { |