#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "bootloader.h" #include "common.h" #include "cutils/properties.h" #include "firmware.h" #include "install.h" #include "minui/minui.h" #include "minzip/DirUtil.h" #include "roots.h" #include "recovery_ui.h" #include "../../external/yaffs2/yaffs2/utils/mkyaffs2image.h" #include "../../external/yaffs2/yaffs2/utils/unyaffs.h" #include "extendedcommands.h" #include "nandroid.h" #include "mounts.h" #include "flashutils/flashutils.h" #include "edify/expr.h" #include "mtdutils/mtdutils.h" #include "mmcutils/mmcutils.h" //#include "edify/parser.h" 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 = malloc(size+1); size = 0; for (i = 0; i < argc; ++i) { strcpy(buffer+size, args[i]); size += strlen(args[i]); free(args[i]); } free(args); buffer[size] = '\0'; char* line = strtok(buffer, "\n"); while (line) { ui_print("%s\n", line); line = strtok(NULL, "\n"); } return StringValue(buffer); } Value* RunProgramFn(const char* name, State* state, int argc, Expr* argv[]) { if (argc < 1) { return ErrorAbort(state, "%s() expects at least 1 arg", name); } char** args = ReadVarArgs(state, argc, argv); if (args == NULL) { return NULL; } char** args2 = malloc(sizeof(char*) * (argc+1)); memcpy(args2, args, sizeof(char*) * argc); args2[argc] = NULL; fprintf(stderr, "about to run program [%s] with %d args\n", args2[0], argc); pid_t child = fork(); if (child == 0) { execv(args2[0], args2); fprintf(stderr, "run_program: execv failed: %s\n", strerror(errno)); _exit(1); } int status; waitpid(child, &status, 0); if (WIFEXITED(status)) { if (WEXITSTATUS(status) != 0) { fprintf(stderr, "run_program: child exited with status %d\n", WEXITSTATUS(status)); } } else if (WIFSIGNALED(status)) { fprintf(stderr, "run_program: child terminated by signal %d\n", WTERMSIG(status)); } int i; for (i = 0; i < argc; ++i) { free(args[i]); } free(args); free(args2); char buffer[20]; sprintf(buffer, "%d", status); return StringValue(strdup(buffer)); } Value* FormatFn(const char* name, State* state, int argc, Expr* argv[]) { char* result = NULL; if (argc != 1) { return ErrorAbort(state, "%s() expects 1 arg, got %d", name, argc); } char *path; if (ReadArgs(state, argv, 1, &path) < 0) { return NULL; } ui_print("Formatting %s...\n", path); if (0 != format_volume(path)) { free(path); return StringValue(strdup("")); } if (strcmp(path, "/data") == 0 && has_datadata()) { ui_print("Formatting /datadata...\n", path); if (0 != format_volume("/datadata")) { free(path); return StringValue(strdup("")); } if (0 != format_volume("/sdcard/.android_secure")) { free(path); return StringValue(strdup("")); } } done: return StringValue(strdup(path)); } Value* BackupFn(const char* name, State* state, int argc, Expr* argv[]) { char* result = NULL; if (argc != 1) { return ErrorAbort(state, "%s() expects 1 args, got %d", name, argc); } char* path; if (ReadArgs(state, argv, 1, &path) < 0) { return NULL; } if (0 != nandroid_backup(path)) return StringValue(strdup("")); return StringValue(strdup(path)); } Value* RestoreFn(const char* name, State* state, int argc, Expr* argv[]) { if (argc < 1) { return ErrorAbort(state, "%s() expects at least 1 arg", name); } char** args = ReadVarArgs(state, argc, argv); if (args == NULL) { return NULL; } char** args2 = malloc(sizeof(char*) * (argc+1)); memcpy(args2, args, sizeof(char*) * argc); args2[argc] = NULL; char* path = strdup(args2[0]); int restoreboot = 1; int restoresystem = 1; int restoredata = 1; int restorecache = 1; int restoresdext = 1; int i; for (i = 1; i < argc; i++) { if (args2[i] == NULL) continue; if (strcmp(args2[i], "noboot") == 0) restoreboot = 0; else if (strcmp(args2[i], "nosystem") == 0) restoresystem = 0; else if (strcmp(args2[i], "nodata") == 0) restoredata = 0; else if (strcmp(args2[i], "nocache") == 0) restorecache = 0; else if (strcmp(args2[i], "nosd-ext") == 0) restoresdext = 0; } for (i = 0; i < argc; ++i) { free(args[i]); } free(args); free(args2); if (0 != nandroid_restore(path, restoreboot, restoresystem, restoredata, restorecache, restoresdext, 0)) { free(path); return StringValue(strdup("")); } return StringValue(path); } Value* InstallZipFn(const char* name, State* state, int argc, Expr* argv[]) { char* result = NULL; if (argc != 1) { return ErrorAbort(state, "%s() expects 1 args, got %d", name, argc); } char* path; if (ReadArgs(state, argv, 1, &path) < 0) { return NULL; } if (0 != install_zip(path)) return StringValue(strdup("")); return StringValue(strdup(path)); } void RegisterRecoveryHooks() { RegisterFunction("format", FormatFn); RegisterFunction("ui_print", UIPrintFn); RegisterFunction("run_program", RunProgramFn); RegisterFunction("backup_rom", BackupFn); RegisterFunction("restore_rom", RestoreFn); RegisterFunction("install_zip", InstallZipFn); } static int hasInitializedEdify = 0; int run_script_from_buffer(char* script_data, int script_len, char* filename) { if (!hasInitializedEdify) { RegisterBuiltins(); RegisterRecoveryHooks(); FinishRegistration(); hasInitializedEdify = 1; } Expr* root; int error_count = 0; yy_scan_bytes(script_data, script_len); int error = yyparse(&root, &error_count); printf("parse returned %d; %d errors encountered\n", error, error_count); if (error == 0 || error_count > 0) { //ExprDump(0, root, buffer); State state; state.cookie = NULL; state.script = script_data; state.errmsg = NULL; char* result = Evaluate(&state, root); if (result == NULL) { printf("result was NULL, message is: %s\n", (state.errmsg == NULL ? "(NULL)" : state.errmsg)); free(state.errmsg); return -1; } else { printf("result is [%s]\n", result); } } return 0; }