summaryrefslogtreecommitdiffstats
path: root/updater/install.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'updater/install.cpp')
-rw-r--r--updater/install.cpp81
1 files changed, 46 insertions, 35 deletions
diff --git a/updater/install.cpp b/updater/install.cpp
index a2bc4029f..e2b3db7ce 100644
--- a/updater/install.cpp
+++ b/updater/install.cpp
@@ -34,6 +34,10 @@
#include <linux/xattr.h>
#include <inttypes.h>
+#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"
@@ -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);