blob: c491d845e440f759eb395e173053420d9889622a [file] [log] [blame]
Koushik K. Dutta6060e5c2010-02-11 22:27:06 -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
Koushik K. Duttae9234872010-02-12 00:43:24 -080015#include <sys/wait.h>
16#include <sys/limits.h>
17#include <dirent.h>
18
Koushik K. Dutta6060e5c2010-02-11 22:27:06 -080019#include "bootloader.h"
20#include "common.h"
21#include "cutils/properties.h"
22#include "firmware.h"
23#include "install.h"
24#include "minui/minui.h"
25#include "minzip/DirUtil.h"
26#include "roots.h"
27#include "recovery_ui.h"
28
29int signature_check_enabled = 1;
30int script_assert_enabled = 1;
Koushik K. Duttabcdd0032010-02-21 21:10:25 -080031static const char *SDCARD_PACKAGE_FILE = "SDCARD:update.zip";
Koushik K. Dutta6060e5c2010-02-11 22:27:06 -080032
33void
34toggle_signature_check()
35{
36 signature_check_enabled = !signature_check_enabled;
37 ui_print("Signature Check: %s\n", signature_check_enabled ? "Enabled" : "Disabled");
38}
39
40void toggle_script_asserts()
41{
42 script_assert_enabled = !script_assert_enabled;
Koushik K. Duttae9234872010-02-12 00:43:24 -080043 ui_print("Script Asserts: %s\n", script_assert_enabled ? "Enabled" : "Disabled");
44}
45
Koushik K. Duttabcdd0032010-02-21 21:10:25 -080046void install_zip(const char* packagefilepath)
Koushik K. Duttae9234872010-02-12 00:43:24 -080047{
Koushik K. Duttabcdd0032010-02-21 21:10:25 -080048 ui_print("\n-- Installing: %s\n", packagefilepath);
49 set_sdcard_update_bootloader_message();
50 int status = install_package(packagefilepath);
51 if (status != INSTALL_SUCCESS) {
52 ui_set_background(BACKGROUND_ICON_ERROR);
53 ui_print("Installation aborted.\n");
54 } else if (!ui_text_visible()) {
55 return; // reboot if logs aren't visible
56 } else {
57 if (firmware_update_pending()) {
58 ui_print("\nReboot via menu to complete\n"
59 "installation.\n");
60 } else {
61 ui_print("\nInstall from sdcard complete.\n");
62 }
63 }
64}
65
66char* INSTALL_MENU_ITEMS[] = { "apply sdcard:update.zip",
67 "choose zip from sdcard",
68 "toggle signature verification",
69 "toggle script asserts",
70 NULL };
71#define ITEM_APPLY_SDCARD 0
72#define ITEM_CHOOSE_ZIP 1
73#define ITEM_SIG_CHECK 2
74#define ITEM_ASSERTS 3
75
76void show_install_update_menu()
77{
78 static char* headers[] = { "Apply update from .zip file on SD card",
79 "",
80 NULL
81 };
82 for (;;)
83 {
84 int chosen_item = get_menu_selection(headers, INSTALL_MENU_ITEMS, 0);
85 switch (chosen_item)
86 {
87 case ITEM_ASSERTS:
88 toggle_script_asserts();
89 break;
90 case ITEM_SIG_CHECK:
91 toggle_signature_check();
92 break;
93 case ITEM_APPLY_SDCARD:
94 install_zip(SDCARD_PACKAGE_FILE);
95 break;
96 case ITEM_CHOOSE_ZIP:
97 show_choose_zip_menu();
98 break;
99 default:
100 return;
101 }
102
103 }
104}
105
106char* choose_file_menu(const char* directory, const char* extension, const char* headers[])
107{
Koushik K. Duttae9234872010-02-12 00:43:24 -0800108 char path[PATH_MAX] = "";
109 DIR *dir;
110 struct dirent *de;
111 int total = 0;
112 int i;
113 char** files;
114 char** list;
115
Koushik K. Duttabcdd0032010-02-21 21:10:25 -0800116 dir = opendir(directory);
117 if (dir == NULL) {
118 ui_print("Couldn't open directory.\n");
119 return NULL;
120 }
121
122 const int extension_length = strlen(extension);
123
124 while ((de=readdir(dir)) != NULL) {
125 if (de->d_name[0] != '.' && strlen(de->d_name) > extension_length && strcmp(de->d_name + strlen(de->d_name) - extension_length, extension) == 0) {
126 total++;
127 }
128 }
129
130 if (total==0) {
131 ui_print("No files found.\n");
132 if(closedir(dir) < 0) {
133 LOGE("Failed to close directory.");
134 }
135 return NULL;
136 }
137
138 files = (char**) malloc((total+1)*sizeof(char*));
139 files[total]=NULL;
140
141 list = (char**) malloc((total+1)*sizeof(char*));
142 list[total]=NULL;
143
144 rewinddir(dir);
145
146 i = 0;
147 while ((de = readdir(dir)) != NULL) {
148 if (de->d_name[0] != '.' && strlen(de->d_name) > extension_length && strcmp(de->d_name + strlen(de->d_name) - extension_length, extension) == 0) {
149 files[i] = (char*) malloc(strlen(directory)+strlen(de->d_name)+1);
150 strcpy(files[i], directory);
151 strcat(files[i], de->d_name);
152
153 list[i] = (char*) malloc(strlen(de->d_name)+1);
154 strcpy(list[i], de->d_name);
155
156 i++;
157 }
158 }
159
160 if (closedir(dir) <0) {
161 LOGE("Failure closing directory.");
162 return NULL;
163 }
164
165 int chosen_item = get_menu_selection(headers, list, 1);
166 static char ret[PATH_MAX];
167 strcpy(ret, files[chosen_item]);
168 return ret;
169}
170
171void show_choose_zip_menu()
172{
Koushik K. Duttae9234872010-02-12 00:43:24 -0800173 if (ensure_root_path_mounted("SDCARD:") != 0) {
174 LOGE ("Can't mount /sdcard\n");
175 return;
176 }
177
Koushik K. Duttabcdd0032010-02-21 21:10:25 -0800178 static char* headers[] = { "Choose a zip to apply",
179 "",
180 NULL
181 };
182
183 char* file = choose_file_menu("/sdcard/", ".zip", headers);
184 if (file == NULL)
185 return;
186 char sdcard_package_file[1024];
187 strcpy(sdcard_package_file, "SDCARD:");
188 strcat(sdcard_package_file, file + strlen("/sdcard/"));
189 install_zip(sdcard_package_file);
190}
191
192void do_nandroid_backup()
193{
194 ui_print("Performing backup...\n");
195 system("/sbin/nandroid-mobile.sh backup");
196 ui_print("Backup complete.\n");
197}
198
199void show_nandroid_restore_menu()
200{
201 if (ensure_root_path_mounted("SDCARD:") != 0) {
202 LOGE ("Can't mount /sdcard\n");
Koushik K. Duttae9234872010-02-12 00:43:24 -0800203 return;
204 }
Koushik K. Duttabcdd0032010-02-21 21:10:25 -0800205
206 static char* headers[] = { "Choose an image to restore",
207 "",
208 NULL
209 };
Koushik K. Duttae9234872010-02-12 00:43:24 -0800210
Koushik K. Duttabcdd0032010-02-21 21:10:25 -0800211 system("cat /proc/cmdline | sed 's/.*serialno=//' | cut -d' ' -f1 > /.deviceid");
212 FILE *deviceIdFile = fopen(".deviceid", "r");
213 char deviceId[256];
214 if (deviceIdFile == NULL)
215 {
216 ui_print("Unable to retrieve device id.\n");
217 return;
Koushik K. Duttae9234872010-02-12 00:43:24 -0800218 }
Koushik K. Duttabcdd0032010-02-21 21:10:25 -0800219 int readCount = fread(deviceId, 1, sizeof(deviceId), deviceIdFile);
220 if (readCount == 0)
221 {
222 ui_print("Unable to retrieve device id.\n");
223 return;
Koushik K. Duttae9234872010-02-12 00:43:24 -0800224 }
Koushik K. Duttabcdd0032010-02-21 21:10:25 -0800225 deviceId[readCount - 1] = NULL;
226 fclose(deviceIdFile);
227 char backupDirectory[PATH_MAX];
228 sprintf(backupDirectory, "/sdcard/nandroid/%s/", deviceId);
Koushik K. Duttae9234872010-02-12 00:43:24 -0800229
Koushik K. Duttabcdd0032010-02-21 21:10:25 -0800230 char* file = choose_file_menu(backupDirectory, "", headers);
231 if (file == NULL)
232 return;
233 char* command[PATH_MAX];
234 sprintf(command, "nandroid-mobile.sh restore %s", file);
235 ui_print("Performing restore...\n");
236 system(command);
237 ui_print("Restore complete.\n");
Koushik K. Dutta6060e5c2010-02-11 22:27:06 -0800238}