blob: 6971b7640a69274fb350b4561a645171d5fc2f6f [file] [log] [blame]
Dees_Troy51a0e822012-09-05 15:24:24 -04001#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#include "../extra-functions.h"
23
24//extern int __system(const char *command);
25#define BML_UNLOCK_ALL 0x8A29 ///< unlock all partition RO -> RW
26
27#ifndef BOARD_BML_BOOT
28#define BOARD_BML_BOOT "/dev/block/bml7"
29#endif
30
31#ifndef BOARD_BML_RECOVERY
32#define BOARD_BML_RECOVERY "/dev/block/bml8"
33#endif
34
35#undef _PATH_BSHELL
36#define _PATH_BSHELL "/sbin/sh"
37
38int __system(const char *command)
39{
40 pid_t pid;
41 sig_t intsave, quitsave;
42 sigset_t mask, omask;
43 int pstat;
44 char *argp[] = {"sh", "-c", NULL, NULL};
45
46 if (!command) /* just checking... */
47 return(1);
48
49 argp[2] = (char *)command;
50
51 sigemptyset(&mask);
52 sigaddset(&mask, SIGCHLD);
53 sigprocmask(SIG_BLOCK, &mask, &omask);
54 switch (pid = vfork()) {
55 case -1: /* error */
56 sigprocmask(SIG_SETMASK, &omask, NULL);
57 return(-1);
58 case 0: /* child */
59 sigprocmask(SIG_SETMASK, &omask, NULL);
60 execve(_PATH_BSHELL, argp, environ);
61 _exit(127);
62 }
63
64 intsave = (sig_t) bsd_signal(SIGINT, SIG_IGN);
65 quitsave = (sig_t) bsd_signal(SIGQUIT, SIG_IGN);
66 pid = waitpid(pid, (int *)&pstat, 0);
67 sigprocmask(SIG_SETMASK, &omask, NULL);
68 (void)bsd_signal(SIGINT, intsave);
69 (void)bsd_signal(SIGQUIT, quitsave);
70 return (pid == -1 ? -1 : pstat);
71}
72
73static struct pid {
74 struct pid *next;
75 FILE *fp;
76 pid_t pid;
77} *pidlist;
78
79
80static int restore_internal(const char* bml, const char* filename)
81{
82 char buf[4096];
83 int dstfd, srcfd, bytes_read, bytes_written, total_read = 0;
84 if (filename == NULL)
85 srcfd = 0;
86 else {
87 srcfd = open(filename, O_RDONLY | O_LARGEFILE);
88 if (srcfd < 0)
89 return 2;
90 }
91 dstfd = open(bml, O_RDWR | O_LARGEFILE);
92 if (dstfd < 0)
93 return 3;
94 if (ioctl(dstfd, BML_UNLOCK_ALL, 0))
95 return 4;
96 do {
97 total_read += bytes_read = read(srcfd, buf, 4096);
98 if (!bytes_read)
99 break;
100 if (bytes_read < 4096)
101 memset(&buf[bytes_read], 0, 4096 - bytes_read);
102 if (write(dstfd, buf, 4096) < 4096)
103 return 5;
104 } while(bytes_read == 4096);
105
106 close(dstfd);
107 close(srcfd);
108
109 return 0;
110}
111
112int cmd_bml_restore_raw_partition(const char *partition, const char *filename)
113{
114 if (strcmp(partition, "boot") != 0 && strcmp(partition, "recovery") != 0 && strcmp(partition, "recoveryonly") != 0 && partition[0] != '/')
115 return 6;
116
117 int ret = -1;
118 if (strcmp(partition, "recoveryonly") != 0) {
119 // always restore boot, regardless of whether recovery or boot is flashed.
120 // this is because boot and recovery are the same on some samsung phones.
121 // unless of course, recoveryonly is explictly chosen (bml8)
122 ret = restore_internal(BOARD_BML_BOOT, filename);
123 if (ret != 0)
124 return ret;
125 }
126
127 if (strcmp(partition, "recovery") == 0 || strcmp(partition, "recoveryonly") == 0)
128 ret = restore_internal(BOARD_BML_RECOVERY, filename);
129
130 // support explicitly provided device paths
131 if (partition[0] == '/')
132 ret = restore_internal(partition, filename);
133 return ret;
134}
135
136int cmd_bml_backup_raw_partition(const char *partition, const char *out_file)
137{
138 char* bml;
139 if (strcmp("boot", partition) == 0)
140 bml = BOARD_BML_BOOT;
141 else if (strcmp("recovery", partition) == 0)
142 bml = BOARD_BML_RECOVERY;
143 else if (partition[0] == '/') {
144 // support explicitly provided device paths
145 bml = partition;
146 }
147 else {
148 printf("Invalid partition.\n");
149 return -1;
150 }
151
152 int ch;
153 FILE *in;
154 FILE *out;
155 int val = 0;
156 char buf[512];
157 unsigned sz = 0;
158 unsigned i;
159 int ret = -1;
160 char *in_file = bml;
161
162 in = fopen ( in_file, "r" );
163 if (in == NULL)
164 goto ERROR3;
165
166 out = fopen ( out_file, "w" );
167 if (out == NULL)
168 goto ERROR2;
169
170 fseek(in, 0L, SEEK_END);
171 sz = ftell(in);
172 fseek(in, 0L, SEEK_SET);
173
174 if (sz % 512)
175 {
176 while ( ( ch = fgetc ( in ) ) != EOF )
177 fputc ( ch, out );
178 }
179 else
180 {
181 for (i=0; i< (sz/512); i++)
182 {
183 if ((fread(buf, 512, 1, in)) != 1)
184 goto ERROR1;
185 if ((fwrite(buf, 512, 1, out)) != 1)
186 goto ERROR1;
187 }
188 }
189
190 fsync(out);
191 ret = 0;
192ERROR1:
193 fclose ( out );
194ERROR2:
195 fclose ( in );
196ERROR3:
197 return ret;
198}
199
200int cmd_bml_erase_raw_partition(const char *partition)
201{
202 // TODO: implement raw wipe
203 return 0;
204}
205
206int cmd_bml_erase_partition(const char *partition, const char *filesystem)
207{
208 return -1;
209}
210
211int cmd_bml_mount_partition(const char *partition, const char *mount_point, const char *filesystem, int read_only)
212{
213 return -1;
214}
215
216int cmd_bml_get_partition_device(const char *partition, char *device)
217{
218 return -1;
219}
220
221int format_rfs_device (const char *device, const char *path) {
222 const char *fatsize = "32";
223 const char *sectorsize = "1";
224
225 if (strcmp(path, "/datadata") == 0 || strcmp(path, "/cache") == 0) {
226 fatsize = "16";
227 }
228
229 // Just in case /data sector size needs to be altered
230 else if (strcmp(path, "/data") == 0 ) {
231 sectorsize = "1";
232 }
233
234 // dump 10KB of zeros to partition before format due to fat.format bug
235 char cmd[PATH_MAX];
236
237 sprintf(cmd, "/sbin/dd if=/dev/zero of=%s bs=4096 count=10", device);
238 if(__system(cmd)) {
239 printf("failure while zeroing rfs partition.\n");
240 return -1;
241 }
242
243 // Run fat.format
244 sprintf(cmd, "/sbin/fat.format -F %s -S 4096 -s %s %s", fatsize, sectorsize, device);
245 if(__system(cmd)) {
246 printf("failure while running fat.format\n");
247 return -1;
248 }
249
250 return 0;
251}