blob: 83f089f5b1df8c059e651ed7112f0962c1cd9a36 [file] [log] [blame]
preludedrew38058dc2011-01-29 23:30:44 -07001#include <ctype.h>
2#include <errno.h>
3#include <fcntl.h>
4#include <getopt.h>
5#include <limits.h>
6#include <linux/input.h>
7#include <stdio.h>
8#include <stdlib.h>
9#include <string.h>
10#include <sys/reboot.h>
11#include <sys/types.h>
12#include <time.h>
13#include <unistd.h>
14
15#include <sys/wait.h>
16#include <sys/limits.h>
17#include <dirent.h>
18#include <sys/stat.h>
19
20#include <signal.h>
21#include <sys/wait.h>
22
23#include "bootloader.h"
24#include "common.h"
25#include "cutils/properties.h"
26#include "firmware.h"
27#include "install.h"
28#include "minui/minui.h"
29#include "minzip/DirUtil.h"
30#include "roots.h"
31#include "recovery_ui.h"
32
33#include "../../external/yaffs2/yaffs2/utils/mkyaffs2image.h"
34#include "../../external/yaffs2/yaffs2/utils/unyaffs.h"
35
36#include "extendedcommands.h"
37#include "nandroid.h"
38#include "mounts.h"
39#include "flashutils/flashutils.h"
40#include "edify/expr.h"
41#include "mtdutils/mtdutils.h"
42#include "mmcutils/mmcutils.h"
43//#include "edify/parser.h"
44
45Value* UIPrintFn(const char* name, State* state, int argc, Expr* argv[]) {
46 char** args = ReadVarArgs(state, argc, argv);
47 if (args == NULL) {
48 return NULL;
49 }
50
51 int size = 0;
52 int i;
53 for (i = 0; i < argc; ++i) {
54 size += strlen(args[i]);
55 }
56 char* buffer = malloc(size+1);
57 size = 0;
58 for (i = 0; i < argc; ++i) {
59 strcpy(buffer+size, args[i]);
60 size += strlen(args[i]);
61 free(args[i]);
62 }
63 free(args);
64 buffer[size] = '\0';
65
66 char* line = strtok(buffer, "\n");
67 while (line) {
68 ui_print("%s\n", line);
69 line = strtok(NULL, "\n");
70 }
71
72 return StringValue(buffer);
73}
74
75Value* RunProgramFn(const char* name, State* state, int argc, Expr* argv[]) {
76 if (argc < 1) {
77 return ErrorAbort(state, "%s() expects at least 1 arg", name);
78 }
79 char** args = ReadVarArgs(state, argc, argv);
80 if (args == NULL) {
81 return NULL;
82 }
83
84 char** args2 = malloc(sizeof(char*) * (argc+1));
85 memcpy(args2, args, sizeof(char*) * argc);
86 args2[argc] = NULL;
87
88 fprintf(stderr, "about to run program [%s] with %d args\n", args2[0], argc);
89
90 pid_t child = fork();
91 if (child == 0) {
92 execv(args2[0], args2);
93 fprintf(stderr, "run_program: execv failed: %s\n", strerror(errno));
94 _exit(1);
95 }
96 int status;
97 waitpid(child, &status, 0);
98 if (WIFEXITED(status)) {
99 if (WEXITSTATUS(status) != 0) {
100 fprintf(stderr, "run_program: child exited with status %d\n",
101 WEXITSTATUS(status));
102 }
103 } else if (WIFSIGNALED(status)) {
104 fprintf(stderr, "run_program: child terminated by signal %d\n",
105 WTERMSIG(status));
106 }
107
108 int i;
109 for (i = 0; i < argc; ++i) {
110 free(args[i]);
111 }
112 free(args);
113 free(args2);
114
115 char buffer[20];
116 sprintf(buffer, "%d", status);
117
118 return StringValue(strdup(buffer));
119}
120
121Value* FormatFn(const char* name, State* state, int argc, Expr* argv[]) {
122 char* result = NULL;
123 if (argc != 1) {
124 return ErrorAbort(state, "%s() expects 1 arg, got %d", name, argc);
125 }
126
127 char *path;
128 if (ReadArgs(state, argv, 1, &path) < 0) {
129 return NULL;
130 }
131
132 ui_print("Formatting %s...\n", path);
133 if (0 != format_volume(path)) {
134 free(path);
135 return StringValue(strdup(""));
136 }
andrew.boren1acd15e2011-03-31 21:41:22 -0700137
138 if (strcmp(path, "/data") == 0 && has_datadata()) {
139 ui_print("Formatting /datadata...\n", path);
140 if (0 != format_volume("/datadata")) {
141 free(path);
142 return StringValue(strdup(""));
143 }
144 }
preludedrew38058dc2011-01-29 23:30:44 -0700145
146done:
147 return StringValue(strdup(path));
148}
149
150Value* BackupFn(const char* name, State* state, int argc, Expr* argv[]) {
151 char* result = NULL;
152 if (argc != 1) {
153 return ErrorAbort(state, "%s() expects 1 args, got %d", name, argc);
154 }
155 char* path;
156 if (ReadArgs(state, argv, 1, &path) < 0) {
157 return NULL;
158 }
159
160 if (0 != nandroid_backup(path))
161 return StringValue(strdup(""));
162
163 return StringValue(strdup(path));
164}
165
166Value* RestoreFn(const char* name, State* state, int argc, Expr* argv[]) {
167 if (argc < 1) {
168 return ErrorAbort(state, "%s() expects at least 1 arg", name);
169 }
170 char** args = ReadVarArgs(state, argc, argv);
171 if (args == NULL) {
172 return NULL;
173 }
174
175 char** args2 = malloc(sizeof(char*) * (argc+1));
176 memcpy(args2, args, sizeof(char*) * argc);
177 args2[argc] = NULL;
178
179 char* path = strdup(args2[0]);
180 int restoreboot = 1;
181 int restoresystem = 1;
182 int restoredata = 1;
183 int restorecache = 1;
184 int restoresdext = 1;
185 int i;
186 for (i = 1; i < argc; i++)
187 {
188 if (args2[i] == NULL)
189 continue;
190 if (strcmp(args2[i], "noboot") == 0)
191 restoreboot = 0;
192 else if (strcmp(args2[i], "nosystem") == 0)
193 restoresystem = 0;
194 else if (strcmp(args2[i], "nodata") == 0)
195 restoredata = 0;
196 else if (strcmp(args2[i], "nocache") == 0)
197 restorecache = 0;
198 else if (strcmp(args2[i], "nosd-ext") == 0)
199 restoresdext = 0;
200 }
201
202 for (i = 0; i < argc; ++i) {
203 free(args[i]);
204 }
205 free(args);
206 free(args2);
207
208 if (0 != nandroid_restore(path, restoreboot, restoresystem, restoredata, restorecache, restoresdext, 0)) {
209 free(path);
210 return StringValue(strdup(""));
211 }
212
213 return StringValue(path);
214}
215
216Value* InstallZipFn(const char* name, State* state, int argc, Expr* argv[]) {
217 char* result = NULL;
218 if (argc != 1) {
219 return ErrorAbort(state, "%s() expects 1 args, got %d", name, argc);
220 }
221 char* path;
222 if (ReadArgs(state, argv, 1, &path) < 0) {
223 return NULL;
224 }
225
226 if (0 != install_zip(path))
227 return StringValue(strdup(""));
228
229 return StringValue(strdup(path));
230}
231
232void RegisterRecoveryHooks() {
233 RegisterFunction("format", FormatFn);
234 RegisterFunction("ui_print", UIPrintFn);
235 RegisterFunction("run_program", RunProgramFn);
236 RegisterFunction("backup_rom", BackupFn);
237 RegisterFunction("restore_rom", RestoreFn);
238 RegisterFunction("install_zip", InstallZipFn);
239}
240
241static int hasInitializedEdify = 0;
242int run_script_from_buffer(char* script_data, int script_len, char* filename)
243{
244 if (!hasInitializedEdify) {
245 RegisterBuiltins();
246 RegisterRecoveryHooks();
247 FinishRegistration();
248 hasInitializedEdify = 1;
249 }
250
251 Expr* root;
252 int error_count = 0;
253 yy_scan_bytes(script_data, script_len);
254 int error = yyparse(&root, &error_count);
255 printf("parse returned %d; %d errors encountered\n", error, error_count);
256 if (error == 0 || error_count > 0) {
257 //ExprDump(0, root, buffer);
258
259 State state;
260 state.cookie = NULL;
261 state.script = script_data;
262 state.errmsg = NULL;
263
264 char* result = Evaluate(&state, root);
265 if (result == NULL) {
266 printf("result was NULL, message is: %s\n",
267 (state.errmsg == NULL ? "(NULL)" : state.errmsg));
268 free(state.errmsg);
269 return -1;
270 } else {
271 printf("result is [%s]\n", result);
272 }
273 }
274 return 0;
275}