blob: b5da07894587e0bf829c3a3e800415de66740aba [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>
Dees_Troy51a0e822012-09-05 15:24:24 -040022
Conn O'Griofad9201042014-03-25 01:26:49 +000023#include <bmlutils.h>
Dees_Troy51a0e822012-09-05 15:24:24 -040024
Ethan Yonkerbcc502c2014-11-10 11:22:10 -060025#include "../libcrecovery/common.h"
Dees_Troy51a0e822012-09-05 15:24:24 -040026
27static int restore_internal(const char* bml, const char* filename)
28{
29 char buf[4096];
Ethan Yonker58f21322018-08-24 11:17:36 -050030 int dstfd, srcfd, bytes_read, total_read = 0;
Dees_Troy51a0e822012-09-05 15:24:24 -040031 if (filename == NULL)
32 srcfd = 0;
33 else {
34 srcfd = open(filename, O_RDONLY | O_LARGEFILE);
35 if (srcfd < 0)
36 return 2;
37 }
38 dstfd = open(bml, O_RDWR | O_LARGEFILE);
39 if (dstfd < 0)
40 return 3;
41 if (ioctl(dstfd, BML_UNLOCK_ALL, 0))
42 return 4;
43 do {
44 total_read += bytes_read = read(srcfd, buf, 4096);
45 if (!bytes_read)
46 break;
47 if (bytes_read < 4096)
48 memset(&buf[bytes_read], 0, 4096 - bytes_read);
49 if (write(dstfd, buf, 4096) < 4096)
50 return 5;
51 } while(bytes_read == 4096);
52
53 close(dstfd);
54 close(srcfd);
55
56 return 0;
57}
58
59int cmd_bml_restore_raw_partition(const char *partition, const char *filename)
60{
61 if (strcmp(partition, "boot") != 0 && strcmp(partition, "recovery") != 0 && strcmp(partition, "recoveryonly") != 0 && partition[0] != '/')
62 return 6;
63
64 int ret = -1;
65 if (strcmp(partition, "recoveryonly") != 0) {
66 // always restore boot, regardless of whether recovery or boot is flashed.
67 // this is because boot and recovery are the same on some samsung phones.
68 // unless of course, recoveryonly is explictly chosen (bml8)
69 ret = restore_internal(BOARD_BML_BOOT, filename);
70 if (ret != 0)
71 return ret;
72 }
73
74 if (strcmp(partition, "recovery") == 0 || strcmp(partition, "recoveryonly") == 0)
75 ret = restore_internal(BOARD_BML_RECOVERY, filename);
76
77 // support explicitly provided device paths
78 if (partition[0] == '/')
79 ret = restore_internal(partition, filename);
80 return ret;
81}
82
83int cmd_bml_backup_raw_partition(const char *partition, const char *out_file)
84{
Ethan Yonker58f21322018-08-24 11:17:36 -050085 const char* bml;
Dees_Troy51a0e822012-09-05 15:24:24 -040086 if (strcmp("boot", partition) == 0)
87 bml = BOARD_BML_BOOT;
88 else if (strcmp("recovery", partition) == 0)
89 bml = BOARD_BML_RECOVERY;
90 else if (partition[0] == '/') {
91 // support explicitly provided device paths
92 bml = partition;
93 }
94 else {
95 printf("Invalid partition.\n");
96 return -1;
97 }
98
99 int ch;
100 FILE *in;
101 FILE *out;
Dees_Troy51a0e822012-09-05 15:24:24 -0400102 char buf[512];
103 unsigned sz = 0;
104 unsigned i;
105 int ret = -1;
Ethan Yonker58f21322018-08-24 11:17:36 -0500106 const char *in_file = bml;
Dees_Troy51a0e822012-09-05 15:24:24 -0400107
108 in = fopen ( in_file, "r" );
109 if (in == NULL)
110 goto ERROR3;
111
112 out = fopen ( out_file, "w" );
113 if (out == NULL)
114 goto ERROR2;
115
116 fseek(in, 0L, SEEK_END);
117 sz = ftell(in);
118 fseek(in, 0L, SEEK_SET);
119
120 if (sz % 512)
121 {
122 while ( ( ch = fgetc ( in ) ) != EOF )
123 fputc ( ch, out );
124 }
125 else
126 {
127 for (i=0; i< (sz/512); i++)
128 {
129 if ((fread(buf, 512, 1, in)) != 1)
130 goto ERROR1;
131 if ((fwrite(buf, 512, 1, out)) != 1)
132 goto ERROR1;
133 }
134 }
135
Dan Pasanen8abeee12015-11-11 10:07:42 -0600136 fsync(fileno(out));
Dees_Troy51a0e822012-09-05 15:24:24 -0400137 ret = 0;
138ERROR1:
139 fclose ( out );
140ERROR2:
141 fclose ( in );
142ERROR3:
143 return ret;
144}
145
Ethan Yonker58f21322018-08-24 11:17:36 -0500146int cmd_bml_erase_raw_partition(const char *partition __unused)
Dees_Troy51a0e822012-09-05 15:24:24 -0400147{
148 // TODO: implement raw wipe
149 return 0;
150}
151
Ethan Yonker58f21322018-08-24 11:17:36 -0500152int cmd_bml_erase_partition(const char *partition __unused, const char *filesystem __unused)
Dees_Troy51a0e822012-09-05 15:24:24 -0400153{
154 return -1;
155}
156
Ethan Yonker58f21322018-08-24 11:17:36 -0500157int cmd_bml_mount_partition(const char *partition __unused, const char *mount_point __unused, const char *filesystem __unused, int read_only __unused)
Dees_Troy51a0e822012-09-05 15:24:24 -0400158{
159 return -1;
160}
161
Ethan Yonker58f21322018-08-24 11:17:36 -0500162int cmd_bml_get_partition_device(const char *partition __unused, char *device __unused)
Dees_Troy51a0e822012-09-05 15:24:24 -0400163{
164 return -1;
165}
166
167int format_rfs_device (const char *device, const char *path) {
168 const char *fatsize = "32";
169 const char *sectorsize = "1";
170
171 if (strcmp(path, "/datadata") == 0 || strcmp(path, "/cache") == 0) {
172 fatsize = "16";
173 }
174
175 // Just in case /data sector size needs to be altered
176 else if (strcmp(path, "/data") == 0 ) {
177 sectorsize = "1";
178 }
179
180 // dump 10KB of zeros to partition before format due to fat.format bug
181 char cmd[PATH_MAX];
182
183 sprintf(cmd, "/sbin/dd if=/dev/zero of=%s bs=4096 count=10", device);
184 if(__system(cmd)) {
185 printf("failure while zeroing rfs partition.\n");
186 return -1;
187 }
188
189 // Run fat.format
190 sprintf(cmd, "/sbin/fat.format -F %s -S 4096 -s %s %s", fatsize, sectorsize, device);
191 if(__system(cmd)) {
192 printf("failure while running fat.format\n");
193 return -1;
194 }
195
196 return 0;
197}