blob: 89554d74553ff78a6bc94fc9018367c37206d4ca [file] [log] [blame]
Koushik Duttabec09952010-12-19 20:37:57 -08001#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 }
Koushik Dutta33fd0d02011-02-27 12:42:24 -0800137
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 }
Koushik Dutta7364e822011-04-23 19:01:16 -0700144 if (0 != format_volume("/sdcard/.android_secure")) {
145 free(path);
146 return StringValue(strdup(""));
147 }
Koushik Dutta33fd0d02011-02-27 12:42:24 -0800148 }
Koushik Duttabec09952010-12-19 20:37:57 -0800149
150done:
151 return StringValue(strdup(path));
152}
153
154Value* BackupFn(const char* name, State* state, int argc, Expr* argv[]) {
155 char* result = NULL;
156 if (argc != 1) {
157 return ErrorAbort(state, "%s() expects 1 args, got %d", name, argc);
158 }
159 char* path;
160 if (ReadArgs(state, argv, 1, &path) < 0) {
161 return NULL;
162 }
163
164 if (0 != nandroid_backup(path))
165 return StringValue(strdup(""));
166
167 return StringValue(strdup(path));
168}
169
170Value* RestoreFn(const char* name, State* state, int argc, Expr* argv[]) {
171 if (argc < 1) {
172 return ErrorAbort(state, "%s() expects at least 1 arg", name);
173 }
174 char** args = ReadVarArgs(state, argc, argv);
175 if (args == NULL) {
176 return NULL;
177 }
178
179 char** args2 = malloc(sizeof(char*) * (argc+1));
180 memcpy(args2, args, sizeof(char*) * argc);
181 args2[argc] = NULL;
182
183 char* path = strdup(args2[0]);
184 int restoreboot = 1;
185 int restoresystem = 1;
186 int restoredata = 1;
187 int restorecache = 1;
188 int restoresdext = 1;
189 int i;
190 for (i = 1; i < argc; i++)
191 {
192 if (args2[i] == NULL)
193 continue;
194 if (strcmp(args2[i], "noboot") == 0)
195 restoreboot = 0;
196 else if (strcmp(args2[i], "nosystem") == 0)
197 restoresystem = 0;
198 else if (strcmp(args2[i], "nodata") == 0)
199 restoredata = 0;
200 else if (strcmp(args2[i], "nocache") == 0)
201 restorecache = 0;
202 else if (strcmp(args2[i], "nosd-ext") == 0)
203 restoresdext = 0;
204 }
205
206 for (i = 0; i < argc; ++i) {
207 free(args[i]);
208 }
209 free(args);
210 free(args2);
211
Koushik Dutta5b7f34a2010-12-29 23:36:03 -0800212 if (0 != nandroid_restore(path, restoreboot, restoresystem, restoredata, restorecache, restoresdext, 0)) {
Koushik Duttabec09952010-12-19 20:37:57 -0800213 free(path);
214 return StringValue(strdup(""));
215 }
216
217 return StringValue(path);
218}
219
220Value* InstallZipFn(const char* name, State* state, int argc, Expr* argv[]) {
221 char* result = NULL;
222 if (argc != 1) {
223 return ErrorAbort(state, "%s() expects 1 args, got %d", name, argc);
224 }
225 char* path;
226 if (ReadArgs(state, argv, 1, &path) < 0) {
227 return NULL;
228 }
229
230 if (0 != install_zip(path))
231 return StringValue(strdup(""));
232
233 return StringValue(strdup(path));
234}
235
236void RegisterRecoveryHooks() {
237 RegisterFunction("format", FormatFn);
238 RegisterFunction("ui_print", UIPrintFn);
239 RegisterFunction("run_program", RunProgramFn);
240 RegisterFunction("backup_rom", BackupFn);
241 RegisterFunction("restore_rom", RestoreFn);
242 RegisterFunction("install_zip", InstallZipFn);
243}
244
245static int hasInitializedEdify = 0;
246int run_script_from_buffer(char* script_data, int script_len, char* filename)
247{
248 if (!hasInitializedEdify) {
249 RegisterBuiltins();
250 RegisterRecoveryHooks();
251 FinishRegistration();
252 hasInitializedEdify = 1;
253 }
254
255 Expr* root;
256 int error_count = 0;
257 yy_scan_bytes(script_data, script_len);
258 int error = yyparse(&root, &error_count);
259 printf("parse returned %d; %d errors encountered\n", error, error_count);
260 if (error == 0 || error_count > 0) {
261 //ExprDump(0, root, buffer);
262
263 State state;
264 state.cookie = NULL;
265 state.script = script_data;
266 state.errmsg = NULL;
267
268 char* result = Evaluate(&state, root);
269 if (result == NULL) {
270 printf("result was NULL, message is: %s\n",
271 (state.errmsg == NULL ? "(NULL)" : state.errmsg));
272 free(state.errmsg);
273 return -1;
274 } else {
275 printf("result is [%s]\n", result);
276 }
277 }
278 return 0;
279}