summaryrefslogtreecommitdiffstats
path: root/updater
diff options
context:
space:
mode:
Diffstat (limited to 'updater')
-rw-r--r--updater/blockimg.cpp55
-rw-r--r--updater/install.cpp58
2 files changed, 58 insertions, 55 deletions
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, " ", &params.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(&params.cpos, &tgt, blocks, &params.buffer,
+ status = LoadSrcTgtVersion1(&params.cpos, tgt, blocks, &params.buffer,
&params.bufsize, params.fd);
} else if (params.version == 2) {
- status = LoadSrcTgtVersion2(&params.cpos, &tgt, blocks, &params.buffer,
+ status = LoadSrcTgtVersion2(&params.cpos, tgt, blocks, &params.buffer,
&params.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(&params.cpos, &tgt, blocks, &params.buffer,
+ status = LoadSrcTgtVersion1(&params.cpos, tgt, blocks, &params.buffer,
&params.bufsize, params.fd);
} else if (params.version == 2) {
- status = LoadSrcTgtVersion2(&params.cpos, &tgt, blocks, &params.buffer,
+ status = LoadSrcTgtVersion2(&params.cpos, tgt, blocks, &params.buffer,
&params.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[]) {