blob: 7d0d7284dc3bd824c8f2e68b2381801fbce4c8d1 [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 }
137
138done:
139 return StringValue(strdup(path));
140}
141
142Value* BackupFn(const char* name, State* state, int argc, Expr* argv[]) {
143 char* result = NULL;
144 if (argc != 1) {
145 return ErrorAbort(state, "%s() expects 1 args, got %d", name, argc);
146 }
147 char* path;
148 if (ReadArgs(state, argv, 1, &path) < 0) {
149 return NULL;
150 }
151
152 if (0 != nandroid_backup(path))
153 return StringValue(strdup(""));
154
155 return StringValue(strdup(path));
156}
157
158Value* RestoreFn(const char* name, State* state, int argc, Expr* argv[]) {
159 if (argc < 1) {
160 return ErrorAbort(state, "%s() expects at least 1 arg", name);
161 }
162 char** args = ReadVarArgs(state, argc, argv);
163 if (args == NULL) {
164 return NULL;
165 }
166
167 char** args2 = malloc(sizeof(char*) * (argc+1));
168 memcpy(args2, args, sizeof(char*) * argc);
169 args2[argc] = NULL;
170
171 char* path = strdup(args2[0]);
172 int restoreboot = 1;
173 int restoresystem = 1;
174 int restoredata = 1;
175 int restorecache = 1;
176 int restoresdext = 1;
177 int i;
178 for (i = 1; i < argc; i++)
179 {
180 if (args2[i] == NULL)
181 continue;
182 if (strcmp(args2[i], "noboot") == 0)
183 restoreboot = 0;
184 else if (strcmp(args2[i], "nosystem") == 0)
185 restoresystem = 0;
186 else if (strcmp(args2[i], "nodata") == 0)
187 restoredata = 0;
188 else if (strcmp(args2[i], "nocache") == 0)
189 restorecache = 0;
190 else if (strcmp(args2[i], "nosd-ext") == 0)
191 restoresdext = 0;
192 }
193
194 for (i = 0; i < argc; ++i) {
195 free(args[i]);
196 }
197 free(args);
198 free(args2);
199
200 if (0 != nandroid_restore(path, restoreboot, restoresystem, restoredata, restorecache, restoresdext, 0)) {
201 free(path);
202 return StringValue(strdup(""));
203 }
204
205 return StringValue(path);
206}
207
208Value* InstallZipFn(const char* name, State* state, int argc, Expr* argv[]) {
209 char* result = NULL;
210 if (argc != 1) {
211 return ErrorAbort(state, "%s() expects 1 args, got %d", name, argc);
212 }
213 char* path;
214 if (ReadArgs(state, argv, 1, &path) < 0) {
215 return NULL;
216 }
217
218 if (0 != install_zip(path))
219 return StringValue(strdup(""));
220
221 return StringValue(strdup(path));
222}
223
224void RegisterRecoveryHooks() {
225 RegisterFunction("format", FormatFn);
226 RegisterFunction("ui_print", UIPrintFn);
227 RegisterFunction("run_program", RunProgramFn);
228 RegisterFunction("backup_rom", BackupFn);
229 RegisterFunction("restore_rom", RestoreFn);
230 RegisterFunction("install_zip", InstallZipFn);
231}
232
233static int hasInitializedEdify = 0;
234int run_script_from_buffer(char* script_data, int script_len, char* filename)
235{
236 if (!hasInitializedEdify) {
237 RegisterBuiltins();
238 RegisterRecoveryHooks();
239 FinishRegistration();
240 hasInitializedEdify = 1;
241 }
242
243 Expr* root;
244 int error_count = 0;
245 yy_scan_bytes(script_data, script_len);
246 int error = yyparse(&root, &error_count);
247 printf("parse returned %d; %d errors encountered\n", error, error_count);
248 if (error == 0 || error_count > 0) {
249 //ExprDump(0, root, buffer);
250
251 State state;
252 state.cookie = NULL;
253 state.script = script_data;
254 state.errmsg = NULL;
255
256 char* result = Evaluate(&state, root);
257 if (result == NULL) {
258 printf("result was NULL, message is: %s\n",
259 (state.errmsg == NULL ? "(NULL)" : state.errmsg));
260 free(state.errmsg);
261 return -1;
262 } else {
263 printf("result is [%s]\n", result);
264 }
265 }
266 return 0;
267}