summaryrefslogtreecommitdiffstats
path: root/recovery.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'recovery.cpp')
-rw-r--r--recovery.cpp56
1 files changed, 52 insertions, 4 deletions
diff --git a/recovery.cpp b/recovery.cpp
index 2541e54d8..c82844d25 100644
--- a/recovery.cpp
+++ b/recovery.cpp
@@ -15,11 +15,13 @@
*/
#include <ctype.h>
+#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
#include <limits.h>
#include <linux/input.h>
+#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -27,7 +29,6 @@
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
-#include <dirent.h>
#include "bootloader.h"
#include "common.h"
@@ -58,10 +59,11 @@ static const struct option OPTIONS[] = {
{ NULL, 0, NULL, 0 },
};
+#define LAST_LOG_FILE "/cache/recovery/last_log"
+
static const char *COMMAND_FILE = "/cache/recovery/command";
static const char *INTENT_FILE = "/cache/recovery/intent";
static const char *LOG_FILE = "/cache/recovery/log";
-static const char *LAST_LOG_FILE = "/cache/recovery/last_log";
static const char *LAST_INSTALL_FILE = "/cache/recovery/last_install";
static const char *LOCALE_FILE = "/cache/recovery/last_locale";
static const char *CACHE_ROOT = "/cache";
@@ -265,6 +267,21 @@ copy_log_file(const char* source, const char* destination, int append) {
}
}
+// Rename last_log -> last_log.1 -> last_log.2 -> ... -> last_log.$max
+// Overwrites any existing last_log.$max.
+static void
+rotate_last_logs(int max) {
+ char oldfn[256];
+ char newfn[256];
+
+ int i;
+ for (i = max-1; i >= 0; --i) {
+ snprintf(oldfn, sizeof(oldfn), (i==0) ? LAST_LOG_FILE : (LAST_LOG_FILE ".%d"), i);
+ snprintf(newfn, sizeof(newfn), LAST_LOG_FILE ".%d", i+1);
+ // ignore errors
+ rename(oldfn, newfn);
+ }
+}
// clear the recovery command and prepare to boot a (hopefully working) system,
// copy our log file to cache as well (for the system to read), and
@@ -710,7 +727,6 @@ prompt_and_wait(Device* device, int status) {
break;
case Device::WIPE_CACHE:
- ui->ShowText(false);
ui->Print("\n-- Wiping cache...\n");
erase_volume("/cache");
ui->Print("Cache wipe complete.\n");
@@ -808,6 +824,24 @@ load_locale_from_cache() {
}
}
+static RecoveryUI* gCurrentUI = NULL;
+
+void
+ui_print(const char* format, ...) {
+ char buffer[256];
+
+ va_list ap;
+ va_start(ap, format);
+ vsnprintf(buffer, sizeof(buffer), format, ap);
+ va_end(ap);
+
+ if (gCurrentUI != NULL) {
+ gCurrentUI->Print("%s", buffer);
+ } else {
+ fputs(buffer, stdout);
+ }
+}
+
int
main(int argc, char **argv) {
time_t start = time(NULL);
@@ -831,6 +865,8 @@ main(int argc, char **argv) {
printf("Starting recovery on %s", ctime(&start));
load_volume_table();
+ ensure_path_mounted(LAST_LOG_FILE);
+ rotate_last_logs(5);
get_args(&argc, &argv);
int previous_runs = 0;
@@ -863,6 +899,7 @@ main(int argc, char **argv) {
Device* device = make_device();
ui = device->GetUI();
+ gCurrentUI = ui;
ui->Init();
ui->SetLocale(locale);
@@ -916,7 +953,18 @@ main(int argc, char **argv) {
LOGE("Cache wipe (requested by package) failed.");
}
}
- if (status != INSTALL_SUCCESS) ui->Print("Installation aborted.\n");
+ if (status != INSTALL_SUCCESS) {
+ ui->Print("Installation aborted.\n");
+
+ // If this is an eng or userdebug build, then automatically
+ // turn the text display on if the script fails so the error
+ // message is visible.
+ char buffer[PROPERTY_VALUE_MAX+1];
+ property_get("ro.build.fingerprint", buffer, "");
+ if (strstr(buffer, ":userdebug/") || strstr(buffer, ":eng/")) {
+ ui->ShowText(true);
+ }
+ }
} else if (wipe_data) {
if (device->WipeData()) status = INSTALL_ERROR;
if (erase_volume("/data")) status = INSTALL_ERROR;