blob: 017af8829be94ee9d3b158e8f5ba72371c8bba70 [file] [log] [blame]
Dees_Troy51a0e822012-09-05 15:24:24 -04001/* Partition class for TWRP
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 *
17 * The code was written from scratch by Dees_Troy dees_troy at
18 * yahoo
19 *
20 * Copyright (c) 2012
21 */
22
23#include <stdio.h>
24#include <stdlib.h>
25#include <string.h>
26#include <sys/stat.h>
27#include <sys/vfs.h>
Dees_Troy5bf43922012-09-07 16:07:55 -040028#include <sys/mount.h>
Dees_Troy51a0e822012-09-05 15:24:24 -040029#include <unistd.h>
Dees_Troy51127312012-09-08 13:08:49 -040030#include <dirent.h>
Dees_Troy51a0e822012-09-05 15:24:24 -040031
32#include "variables.h"
33#include "common.h"
34#include "partitions.hpp"
Dees_Troy5bf43922012-09-07 16:07:55 -040035#include "data.hpp"
36extern "C" {
37 #include "extra-functions.h"
38 int __system(const char *command);
Dees_Troy5bf43922012-09-07 16:07:55 -040039}
Dees_Troy51a0e822012-09-05 15:24:24 -040040
41TWPartition::TWPartition(void) {
42 Can_Be_Mounted = false;
43 Can_Be_Wiped = false;
44 Wipe_During_Factory_Reset = false;
45 Wipe_Available_in_GUI = false;
46 Is_SubPartition = false;
47 SubPartition_Of = "";
48 Symlink_Path = "";
49 Symlink_Mount_Point = "";
50 Mount_Point = "";
51 Block_Device = "";
52 Alternate_Block_Device = "";
53 Removable = false;
54 Is_Present = false;
55 Length = 0;
56 Size = 0;
57 Used = 0;
58 Free = 0;
59 Backup_Size = 0;
60 Can_Be_Encrypted = false;
61 Is_Encrypted = false;
62 Is_Decrypted = false;
63 Decrypted_Block_Device = "";
64 Display_Name = "";
65 Backup_Name = "";
66 Backup_Method = NONE;
67 Has_Data_Media = false;
68 Is_Storage = false;
69 Storage_Path = "";
70 Current_File_System = "";
71 Fstab_File_System = "";
72 Format_Block_Size = 0;
73}
74
75TWPartition::~TWPartition(void) {
76 // Do nothing
77}
78
Dees_Troy5bf43922012-09-07 16:07:55 -040079bool TWPartition::Process_Fstab_Line(string Line, bool Display_Error) {
80 char full_line[MAX_FSTAB_LINE_LENGTH], item[MAX_FSTAB_LINE_LENGTH];
81 int line_len = Line.size(), index = 0, item_index = 0;
82 char* ptr;
Dees_Troy51127312012-09-08 13:08:49 -040083 string Flags;
Dees_Troy5bf43922012-09-07 16:07:55 -040084
85 strncpy(full_line, Line.c_str(), line_len);
86
Dees_Troy51127312012-09-08 13:08:49 -040087 for (index = 0; index < line_len; index++) {
Dees_Troy5bf43922012-09-07 16:07:55 -040088 if (full_line[index] <= 32)
89 full_line[index] = '\0';
Dees_Troy5bf43922012-09-07 16:07:55 -040090 }
91 string mount_pt(full_line);
92 Mount_Point = mount_pt;
93 index = Mount_Point.size();
94 while (index < line_len) {
95 while (index < line_len && full_line[index] == '\0')
96 index++;
97 if (index >= line_len)
98 continue;
99 ptr = full_line + index;
100 if (item_index == 0) {
101 // File System
102 Fstab_File_System = ptr;
103 Current_File_System = ptr;
104 item_index++;
105 } else if (item_index == 1) {
106 // Primary Block Device
107 if (*ptr != '/') {
108 if (Display_Error)
109 LOGE("Invalid block device on '%s', '%s', %i\n", Line.c_str(), ptr, index);
110 else
111 LOGI("Invalid block device on '%s', '%s', %i\n", Line.c_str(), ptr, index);
112 return 0;
113 }
114 Block_Device = ptr;
115 Find_Real_Block_Device(Block_Device, Display_Error);
116 item_index++;
117 } else if (item_index > 1) {
118 if (*ptr == '/') {
119 // Alternate Block Device
120 Alternate_Block_Device = ptr;
121 Find_Real_Block_Device(Alternate_Block_Device, Display_Error);
122 } else if (strlen(ptr) > 7 && strncmp(ptr, "length=", 7) == 0) {
123 // Partition length
124 ptr += 7;
125 Length = atoi(ptr);
Dees_Troy51127312012-09-08 13:08:49 -0400126 } else if (strlen(ptr) > 6 && strncmp(ptr, "flags=", 6) == 0) {
127 // Custom flags, save for later so that new values aren't overwritten by defaults
128 ptr += 6;
129 Flags = ptr;
Dees_Troy5bf43922012-09-07 16:07:55 -0400130 } else {
131 // Unhandled data
132 LOGI("Unhandled fstab information: '%s', %i\n", ptr, index);
133 }
134 }
135 while (index < line_len && full_line[index] != '\0')
136 index++;
137 }
138
139 if (!Is_File_System(Fstab_File_System) && !Is_Image(Fstab_File_System)) {
140 if (Display_Error)
141 LOGE("Unknown File System: '%s'\n", Fstab_File_System.c_str());
142 else
143 LOGI("Unknown File System: '%s'\n", Fstab_File_System.c_str());
144 return 0;
145 } else if (Is_File_System(Fstab_File_System)) {
146 Setup_File_System(Display_Error);
147 if (Mount_Point == "/system") {
148 Display_Name = "System";
149 Wipe_Available_in_GUI = true;
Dees_Troy5bf43922012-09-07 16:07:55 -0400150 } else if (Mount_Point == "/data") {
151 Display_Name = "Data";
152 Wipe_Available_in_GUI = true;
Dees_Troy51127312012-09-08 13:08:49 -0400153 Wipe_During_Factory_Reset = true;
Dees_Troy5bf43922012-09-07 16:07:55 -0400154#ifdef RECOVERY_SDCARD_ON_DATA
155 Has_Data_Media = true;
Dees_Troy51127312012-09-08 13:08:49 -0400156 Is_Storage = true;
157 Storage_Path = "/data/media";
158 Make_Dir("/sdcard", Display_Error);
159 Make_Dir("/emmc", Display_Error);
Dees_Troy5bf43922012-09-07 16:07:55 -0400160#endif
161#ifdef TW_INCLUDE_CRYPTO
162 Can_Be_Encrypted = true;
163 if (!Mount(false)) {
164 Is_Encrypted = true;
165 Is_Decrypted = false;
166 DataManager::SetValue(TW_IS_ENCRYPTED, 1);
167 DataManager::SetValue(TW_CRYPTO_PASSWORD, "");
168 DataManager::SetValue("tw_crypto_display", "");
Dees_Troy51127312012-09-08 13:08:49 -0400169 }
Dees_Troy5bf43922012-09-07 16:07:55 -0400170#endif
Dees_Troy5bf43922012-09-07 16:07:55 -0400171 } else if (Mount_Point == "/cache") {
172 Display_Name = "Cache";
173 Wipe_Available_in_GUI = true;
Dees_Troy51127312012-09-08 13:08:49 -0400174 Wipe_During_Factory_Reset = true;
Dees_Troy5bf43922012-09-07 16:07:55 -0400175 Update_Size(Display_Error);
Dees_Troy5bf43922012-09-07 16:07:55 -0400176 } else if (Mount_Point == "/datadata") {
Dees_Troy51127312012-09-08 13:08:49 -0400177 Wipe_During_Factory_Reset = true;
Dees_Troy5bf43922012-09-07 16:07:55 -0400178 Display_Name = "DataData";
179 Is_SubPartition = true;
180 SubPartition_Of = "/data";
Dees_Troy5bf43922012-09-07 16:07:55 -0400181 DataManager::SetValue(TW_HAS_DATADATA, 1);
182 } else if (Mount_Point == "/sd-ext") {
Dees_Troy51127312012-09-08 13:08:49 -0400183 Wipe_During_Factory_Reset = true;
Dees_Troy5bf43922012-09-07 16:07:55 -0400184 Display_Name = "SD-Ext";
185 Wipe_Available_in_GUI = true;
Dees_Troy5bf43922012-09-07 16:07:55 -0400186 } else
187 Update_Size(Display_Error);
188 } else if (Is_Image(Fstab_File_System)) {
189 Setup_Image(Display_Error);
190 if (Mount_Point == "/boot") {
191 int backup_display_size = (int)(Backup_Size / 1048576LLU);
192 DataManager::SetValue(TW_BACKUP_BOOT_SIZE, backup_display_size);
193 if (Backup_Size == 0) {
194 DataManager::SetValue(TW_HAS_BOOT_PARTITION, 0);
195 DataManager::SetValue(TW_BACKUP_BOOT_VAR, 0);
196 } else
197 DataManager::SetValue(TW_HAS_BOOT_PARTITION, 1);
198 } else if (Mount_Point == "/recovery") {
199 int backup_display_size = (int)(Backup_Size / 1048576LLU);
200 DataManager::SetValue(TW_BACKUP_RECOVERY_SIZE, backup_display_size);
201 if (Backup_Size == 0) {
202 DataManager::SetValue(TW_HAS_RECOVERY_PARTITION, 0);
203 DataManager::SetValue(TW_BACKUP_RECOVERY_VAR, 0);
204 } else
205 DataManager::SetValue(TW_HAS_RECOVERY_PARTITION, 1);
206 }
207 }
208
Dees_Troy51127312012-09-08 13:08:49 -0400209 // Process any custom flags
210 if (Flags.size() > 0)
211 Process_Flags(Flags, Display_Error);
212
213 return true;
214}
215
216bool TWPartition::Process_Flags(string Flags, bool Display_Error) {
217 char flags[MAX_FSTAB_LINE_LENGTH];
218 int flags_len, index = 0;
219 char* ptr;
220
221 strcpy(flags, Flags.c_str());
222 flags_len = Flags.size();
223 for (index = 0; index < flags_len; index++) {
224 if (flags[index] == ';')
225 flags[index] = '\0';
226 }
227
228 index = 0;
229 while (index < flags_len) {
230 while (index < flags_len && flags[index] == '\0')
231 index++;
232 if (index >= flags_len)
233 continue;
234 ptr = flags + index;
235 if (strcmp(ptr, "removable") == 0) {
236 Removable = true;
237 } else if (strcmp(ptr, "storage") == 0) {
238 Is_Storage = true;
239 } else if (strlen(ptr) > 15 && strncmp(ptr, "subpartitionof=", 15) == 0) {
240 ptr += 13;
241 Is_SubPartition = true;
242 SubPartition_Of = ptr;
243 } else if (strlen(ptr) > 8 && strncmp(ptr, "symlink=", 8) == 0) {
244 ptr += 8;
245 Symlink_Path = ptr;
246 } else if (strlen(ptr) > 8 && strncmp(ptr, "display=", 8) == 0) {
247 ptr += 8;
248 Display_Name = ptr;
249 } else if (strlen(ptr) > 10 && strncmp(ptr, "blocksize=", 10) == 0) {
250 ptr += 10;
251 Format_Block_Size = atoi(ptr);
252 } else if (strlen(ptr) > 7 && strncmp(ptr, "length=", 7) == 0) {
253 ptr += 7;
254 Length = atoi(ptr);
255 } else {
256 if (Display_Error)
257 LOGE("Unhandled flag: '%s'\n", ptr);
258 else
259 LOGI("Unhandled flag: '%s'\n", ptr);
260 }
261 while (index < flags_len && flags[index] != '\0')
262 index++;
263 }
264 return true;
Dees_Troy51a0e822012-09-05 15:24:24 -0400265}
266
Dees_Troy5bf43922012-09-07 16:07:55 -0400267bool TWPartition::Is_File_System(string File_System) {
268 if (File_System == "ext2" ||
269 File_System == "ext3" ||
270 File_System == "ext4" ||
271 File_System == "vfat" ||
272 File_System == "ntfs" ||
273 File_System == "yaffs2" ||
274 File_System == "auto")
275 return true;
276 else
277 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400278}
279
Dees_Troy5bf43922012-09-07 16:07:55 -0400280bool TWPartition::Is_Image(string File_System) {
281 if (File_System == "emmc" ||
282 File_System == "mtd")
283 return true;
284 else
285 return false;
286}
287
Dees_Troy51127312012-09-08 13:08:49 -0400288bool TWPartition::Make_Dir(string Path, bool Display_Error) {
289 if (!Path_Exists(Path)) {
290 if (mkdir(Path.c_str(), 0777) == -1) {
291 if (Display_Error)
292 LOGE("Can not create '%s' folder.\n", Path.c_str());
293 else
294 LOGI("Can not create '%s' folder.\n", Path.c_str());
295 return false;
296 } else {
297 LOGI("Created '%s' folder.\n", Path.c_str());
298 return true;
299 }
300 }
301 return true;
302}
303
Dees_Troy5bf43922012-09-07 16:07:55 -0400304void TWPartition::Setup_File_System(bool Display_Error) {
305 struct statfs st;
306
307 Can_Be_Mounted = true;
308 Can_Be_Wiped = true;
309
310 // Check to see if the block device exists
311 if (Path_Exists(Block_Device)) {
312 Is_Present = true;
313 } else if (Alternate_Block_Device != "" && Path_Exists(Alternate_Block_Device)) {
314 Flip_Block_Device();
315 Is_Present = true;
316 }
317 // Make the mount point folder if it doesn't exist
Dees_Troy51127312012-09-08 13:08:49 -0400318 Make_Dir(Mount_Point, Display_Error);
Dees_Troy5bf43922012-09-07 16:07:55 -0400319 Display_Name = Mount_Point.substr(1, Mount_Point.size() - 1);
320 Backup_Name = Display_Name;
321 Backup_Method = FILES;
322}
323
324void TWPartition::Setup_Image(bool Display_Error) {
325 if (Path_Exists(Block_Device)) {
326 Is_Present = true;
327 } else if (Alternate_Block_Device != "" && Path_Exists(Alternate_Block_Device)) {
328 Flip_Block_Device();
329 Is_Present = true;
330 }
331 Display_Name = Mount_Point.substr(1, Mount_Point.size() - 1);
332 Backup_Name = Display_Name;
333 if (Fstab_File_System == "emmc")
334 Backup_Method = DD;
335 else if (Fstab_File_System == "mtd")
336 Backup_Method = FLASH_UTILS;
337 else
338 LOGI("Unhandled file system '%s' on image '%s'\n", Fstab_File_System.c_str(), Display_Name.c_str());
339 if (Find_Partition_Size()) {
340 Used = Size;
341 Backup_Size = Size;
Dees_Troy51a0e822012-09-05 15:24:24 -0400342 } else {
Dees_Troy5bf43922012-09-07 16:07:55 -0400343 if (Display_Error)
344 LOGE("Unable to find parition size for '%s'\n", Block_Device.c_str());
345 else
346 LOGI("Unable to find parition size for '%s'\n", Block_Device.c_str());
Dees_Troy51a0e822012-09-05 15:24:24 -0400347 }
348}
349
Dees_Troy5bf43922012-09-07 16:07:55 -0400350void TWPartition::Find_Real_Block_Device(string& Block, bool Display_Error) {
351 char device[512], realDevice[512];
352
353 strcpy(device, Block.c_str());
354 memset(realDevice, 0, sizeof(realDevice));
355 while (readlink(device, realDevice, sizeof(realDevice)) > 0)
356 {
357 strcpy(device, realDevice);
358 memset(realDevice, 0, sizeof(realDevice));
359 }
360
361 if (device[0] != '/') {
362 if (Display_Error)
363 LOGE("Invalid symlink path '%s' found on block device '%s'\n", device, Block.c_str());
364 else
365 LOGI("Invalid symlink path '%s' found on block device '%s'\n", device, Block.c_str());
366 return;
Dees_Troy51a0e822012-09-05 15:24:24 -0400367 } else {
Dees_Troy5bf43922012-09-07 16:07:55 -0400368 Block = device;
369 return;
370 }
371}
372
Dees_Troy51127312012-09-08 13:08:49 -0400373bool TWPartition::Get_Size_Via_statfs(bool Display_Error) {
374 struct statfs st;
375 string Local_Path = Mount_Point + "/.";
376
377 if (!Mount(Display_Error))
378 return false;
379
380 if (statfs(Local_Path.c_str(), &st) != 0) {
381 if (!Removable) {
382 if (Display_Error)
383 LOGE("Unable to statfs '%s'\n", Local_Path.c_str());
384 else
385 LOGI("Unable to statfs '%s'\n", Local_Path.c_str());
386 }
387 return false;
388 }
389 Size = (st.f_blocks * st.f_bsize);
390 Used = ((st.f_blocks - st.f_bfree) * st.f_bsize);
391 Free = (st.f_bfree * st.f_bsize);
392 Backup_Size = Used;
393 return true;
394}
395
396bool TWPartition::Get_Size_Via_df(bool Display_Error) {
Dees_Troy5bf43922012-09-07 16:07:55 -0400397 FILE* fp;
398 char command[255], line[512];
399 int include_block = 1;
400 unsigned int min_len;
401
402 if (!Mount(Display_Error))
403 return false;
404
405 min_len = Block_Device.size() + 2;
Dees_Troy51127312012-09-08 13:08:49 -0400406 sprintf(command, "df %s > /tmp/dfoutput.txt", Mount_Point.c_str());
407 __system(command);
408 fp = fopen("/tmp/dfoutput.txt", "rt");
409 if (fp == NULL) {
410 LOGI("Unable to open /tmp/dfoutput.txt.\n");
Dees_Troy5bf43922012-09-07 16:07:55 -0400411 return false;
Dees_Troy51127312012-09-08 13:08:49 -0400412 }
Dees_Troy5bf43922012-09-07 16:07:55 -0400413
414 while (fgets(line, sizeof(line), fp) != NULL)
415 {
416 unsigned long blocks, used, available;
417 char device[64];
418 char tmpString[64];
419
420 if (strncmp(line, "Filesystem", 10) == 0)
421 continue;
422 if (strlen(line) < min_len) {
423 include_block = 0;
424 continue;
425 }
426 if (include_block) {
427 sscanf(line, "%s %lu %lu %lu", device, &blocks, &used, &available);
428 } else {
429 // The device block string is so long that the df information is on the next line
430 int space_count = 0;
431 while (tmpString[space_count] == 32)
432 space_count++;
433 sscanf(line + space_count, "%lu %lu %lu", &blocks, &used, &available);
434 }
435
436 // Adjust block size to byte size
437 Size = blocks * 1024ULL;
438 Used = used * 1024ULL;
439 Free = available * 1024ULL;
440 Backup_Size = Used;
441 }
442 fclose(fp);
443 return true;
444}
445
Dees_Troy51127312012-09-08 13:08:49 -0400446unsigned long long TWPartition::Get_Folder_Size(string Path, bool Display_Error) {
447 DIR* d;
448 struct dirent* de;
449 struct stat st;
450 char path2[1024], filename[1024];
451 unsigned long long dusize = 0;
Dees_Troy5bf43922012-09-07 16:07:55 -0400452
Dees_Troy51127312012-09-08 13:08:49 -0400453 // Make a copy of path in case the data in the pointer gets overwritten later
454 strcpy(path2, Path.c_str());
Dees_Troy5bf43922012-09-07 16:07:55 -0400455
Dees_Troy51127312012-09-08 13:08:49 -0400456 d = opendir(path2);
457 if (d == NULL)
458 {
459 LOGE("error opening '%s'\n", path2);
460 return 0;
461 }
462
463 while ((de = readdir(d)) != NULL)
464 {
465 if (de->d_type == DT_DIR && strcmp(de->d_name, ".") != 0 && strcmp(de->d_name, "..") != 0)
466 {
467 strcpy(filename, path2);
468 strcat(filename, "/");
469 strcat(filename, de->d_name);
470 dusize += Get_Folder_Size(filename, Display_Error);
471 }
472 else if (de->d_type == DT_REG)
473 {
474 strcpy(filename, path2);
475 strcat(filename, "/");
476 strcat(filename, de->d_name);
477 stat(filename, &st);
478 dusize += (unsigned long long)(st.st_size);
479 }
480 }
481 closedir(d);
Dees_Troy5bf43922012-09-07 16:07:55 -0400482
483 return dusize;
484}
485
486bool TWPartition::Find_Partition_Size(void) {
487 FILE* fp;
488 char line[512];
489 string tmpdevice;
490
491 // In this case, we'll first get the partitions we care about (with labels)
492 fp = fopen("/proc/partitions", "rt");
493 if (fp == NULL)
494 return false;
495
496 while (fgets(line, sizeof(line), fp) != NULL)
497 {
498 unsigned long major, minor, blocks;
499 char device[512];
500 char tmpString[64];
501
502 if (strlen(line) < 7 || line[0] == 'm') continue;
503 sscanf(line + 1, "%lu %lu %lu %s", &major, &minor, &blocks, device);
504
505 tmpdevice = "/dev/block/";
506 tmpdevice += device;
507 if (tmpdevice == Block_Device || tmpdevice == Alternate_Block_Device) {
508 // Adjust block size to byte size
509 Size = blocks * 1024ULL;
510 fclose(fp);
511 return true;
512 }
513 }
514 fclose(fp);
515 return false;
516}
517
518bool TWPartition::Path_Exists(string Path) {
519 // Check to see if the Path exists
520 struct statfs st;
521
522 if (statfs(Path.c_str(), &st) != 0)
523 return false;
524 else
525 return true;
526}
527
528void TWPartition::Flip_Block_Device(void) {
529 string temp;
530
531 temp = Alternate_Block_Device;
532 Block_Device = Alternate_Block_Device;
533 Alternate_Block_Device = temp;
534}
535
536bool TWPartition::Is_Mounted(void) {
537 if (!Can_Be_Mounted)
538 return false;
539
540 struct stat st1, st2;
541 string test_path;
542
543 // Check to see if the mount point directory exists
544 test_path = Mount_Point + "/.";
545 if (stat(test_path.c_str(), &st1) != 0) return false;
546
547 // Check to see if the directory above the mount point exists
548 test_path = Mount_Point + "/../.";
549 if (stat(test_path.c_str(), &st2) != 0) return false;
550
551 // Compare the device IDs -- if they match then we're (probably) using tmpfs instead of an actual device
552 int ret = (st1.st_dev != st2.st_dev) ? true : false;
553
554 return ret;
555}
556
557bool TWPartition::Mount(bool Display_Error) {
558 if (Is_Mounted()) {
559 return true;
560 } else if (!Can_Be_Mounted) {
561 return false;
562 }
Dees_Troy51127312012-09-08 13:08:49 -0400563 if (Removable)
564 Check_FS_Type();
Dees_Troy5bf43922012-09-07 16:07:55 -0400565 if (Is_Decrypted) {
566 if (mount(Decrypted_Block_Device.c_str(), Mount_Point.c_str(), Current_File_System.c_str(), 0, NULL) != 0) {
567 Check_FS_Type();
568 if (mount(Decrypted_Block_Device.c_str(), Mount_Point.c_str(), Current_File_System.c_str(), 0, NULL) != 0) {
569 if (Display_Error)
570 LOGE("Unable to mount decrypted block device '%s' to '%s'\n", Decrypted_Block_Device.c_str(), Mount_Point.c_str());
571 else
572 LOGI("Unable to mount decrypted block device '%s' to '%s'\n", Decrypted_Block_Device.c_str(), Mount_Point.c_str());
573 return false;
Dees_Troy51127312012-09-08 13:08:49 -0400574 } else {
575 if (Removable)
576 Update_Size(Display_Error);
Dees_Troy5bf43922012-09-07 16:07:55 -0400577 return true;
Dees_Troy51127312012-09-08 13:08:49 -0400578 }
579 } else {
580 if (Removable)
581 Update_Size(Display_Error);
Dees_Troy5bf43922012-09-07 16:07:55 -0400582 return true;
Dees_Troy51127312012-09-08 13:08:49 -0400583 }
Dees_Troy5bf43922012-09-07 16:07:55 -0400584 }
585 if (mount(Block_Device.c_str(), Mount_Point.c_str(), Current_File_System.c_str(), 0, NULL) != 0) {
586 Check_FS_Type();
587 if (mount(Block_Device.c_str(), Mount_Point.c_str(), Current_File_System.c_str(), 0, NULL) != 0) {
588 if (Alternate_Block_Device != "" && Path_Exists(Alternate_Block_Device)) {
589 Flip_Block_Device();
590 Check_FS_Type();
591 if (mount(Block_Device.c_str(), Mount_Point.c_str(), Current_File_System.c_str(), 0, NULL) != 0) {
592 if (Display_Error)
593 LOGE("Unable to mount '%s'\n", Mount_Point.c_str());
594 else
595 LOGI("Unable to mount '%s'\n", Mount_Point.c_str());
596 return false;
Dees_Troy51127312012-09-08 13:08:49 -0400597 } else {
598 if (Removable)
599 Update_Size(Display_Error);
Dees_Troy5bf43922012-09-07 16:07:55 -0400600 return true;
Dees_Troy51127312012-09-08 13:08:49 -0400601 }
Dees_Troy5bf43922012-09-07 16:07:55 -0400602 } else
603 return false;
Dees_Troy51127312012-09-08 13:08:49 -0400604 } else {
605 if (Removable)
606 Update_Size(Display_Error);
Dees_Troy5bf43922012-09-07 16:07:55 -0400607 return true;
Dees_Troy51127312012-09-08 13:08:49 -0400608 }
Dees_Troy5bf43922012-09-07 16:07:55 -0400609 }
Dees_Troy51127312012-09-08 13:08:49 -0400610 if (Removable)
611 Update_Size(Display_Error);
Dees_Troy5bf43922012-09-07 16:07:55 -0400612 return true;
613}
614
615bool TWPartition::UnMount(bool Display_Error) {
616 if (Is_Mounted()) {
617 int never_unmount_system;
618
619 DataManager::GetValue(TW_DONT_UNMOUNT_SYSTEM, never_unmount_system);
620 if (never_unmount_system == 1 && Mount_Point == "/system")
621 return true; // Never unmount system if you're not supposed to unmount it
622
623 if (umount(Mount_Point.c_str()) != 0) {
624 if (Display_Error)
625 LOGE("Unable to unmount '%s'\n", Mount_Point.c_str());
626 else
627 LOGI("Unable to unmount '%s'\n", Mount_Point.c_str());
628 return false;
629 } else
630 return true;
631 } else {
632 return true;
Dees_Troy51a0e822012-09-05 15:24:24 -0400633 }
634}
635
636bool TWPartition::Wipe() {
637 LOGI("STUB TWPartition::Wipe\n");
638 return 1;
639}
640
641bool TWPartition::Backup(string backup_folder) {
642 LOGI("STUB TWPartition::Backup, backup_folder: '%s'\n", backup_folder.c_str());
643 return 1;
644}
645
646bool TWPartition::Restore(string restore_folder) {
647 LOGI("STUB TWPartition::Restore, restore_folder: '%s'\n", restore_folder.c_str());
648 return 1;
649}
650
651string TWPartition::Backup_Method_By_Name() {
652 LOGI("STUB TWPartition::Backup_Method_By_Name\n");
653 return "STUB";
654}
655
656bool TWPartition::Decrypt(string Password) {
657 LOGI("STUB TWPartition::Decrypt, password: '%s'\n", Password.c_str());
658 return 1;
659}
660
661bool TWPartition::Wipe_Encryption() {
662 LOGI("STUB TWPartition::Wipe_Encryption\n");
663 return 1;
664}
665
666void TWPartition::Check_FS_Type() {
Dees_Troy5bf43922012-09-07 16:07:55 -0400667 FILE *fp;
668 string blkCommand;
669 char blkOutput[255];
670 char* blk;
671 char* arg;
672 char* ptr;
673
674 if (Fstab_File_System == "yaffs2" || Fstab_File_System == "mtd")
675 return; // Running blkid on some mtd devices causes a massive crash
676
677 if (Is_Decrypted)
Dees_Troy51127312012-09-08 13:08:49 -0400678 blkCommand = "blkid " + Decrypted_Block_Device + " > /tmp/blkidoutput.txt";
Dees_Troy5bf43922012-09-07 16:07:55 -0400679 else
Dees_Troy51127312012-09-08 13:08:49 -0400680 blkCommand = "blkid " + Block_Device + " > /tmp/blkidoutput.txt";
681
682 __system(blkCommand.c_str());
683 fp = fopen("/tmp/blkidoutput.txt", "rt");
Dees_Troy5bf43922012-09-07 16:07:55 -0400684 while (fgets(blkOutput, sizeof(blkOutput), fp) != NULL)
685 {
686 blk = blkOutput;
687 ptr = blkOutput;
688 while (*ptr > 32 && *ptr != ':') ptr++;
689 if (*ptr == 0) continue;
690 *ptr = 0;
691
692 // Increment by two, but verify that we don't hit a NULL
693 ptr++;
694 if (*ptr != 0) ptr++;
695
696 // Now, find the TYPE field
697 while (1)
698 {
699 arg = ptr;
700 while (*ptr > 32) ptr++;
701 if (*ptr != 0)
702 {
703 *ptr = 0;
704 ptr++;
705 }
706
707 if (strlen(arg) > 6)
708 {
709 if (memcmp(arg, "TYPE=\"", 6) == 0) break;
710 }
711
712 if (*ptr == 0)
713 {
714 arg = NULL;
715 break;
716 }
717 }
718
719 if (arg && strlen(arg) > 7)
720 {
721 arg += 6; // Skip the TYPE=" portion
722 arg[strlen(arg)-1] = '\0'; // Drop the tail quote
723 }
724 else
725 continue;
726
727 if (strcmp(Current_File_System.c_str(), arg) != 0) {
728 LOGI("'%s' was '%s' now set to '%s'\n", Mount_Point.c_str(), Current_File_System.c_str(), arg);
729 Current_File_System = arg;
730 }
731 }
732 __pclose(fp);
Dees_Troy51a0e822012-09-05 15:24:24 -0400733 return;
734}
735
736bool TWPartition::Wipe_EXT23() {
737 LOGI("STUB TWPartition::Wipe_EXT23\n");
738 return 1;
739}
740
741bool TWPartition::Wipe_EXT4() {
742 LOGI("STUB TWPartition::Wipe_EXT4\n");
743 return 1;
744}
745
746bool TWPartition::Wipe_FAT() {
747 LOGI("STUB TWPartition::Wipe_FAT\n");
748 return 1;
749}
750
751bool TWPartition::Wipe_YAFFS2() {
752 LOGI("STUB TWPartition::Wipe_YAFFS2\n");
753 return 1;
754}
755
756bool TWPartition::Wipe_RMRF() {
757 LOGI("STUB TWPartition::Wipe_RMRF\n");
758 return 1;
759}
760
761bool TWPartition::Wipe_Data_Without_Wiping_Media() {
762 LOGI("STUB TWPartition::Wipe_Data_Without_Wiping_Media\n");
763 return 1;
764}
765
766bool TWPartition::Backup_Tar(string backup_folder) {
767 LOGI("STUB TWPartition::Backup_Tar, backup_folder: '%s'\n", backup_folder.c_str());
768 return 1;
769}
770
771bool TWPartition::Backup_DD(string backup_folder) {
772 LOGI("STUB TWPartition::Backup_DD, backup_folder: '%s'\n", backup_folder.c_str());
773 return 1;
774}
775
776bool TWPartition::Backup_Dump_Image(string backup_folder) {
777 LOGI("STUB TWPartition::Backup_Dump_Image, backup_folder: '%s'\n", backup_folder.c_str());
778 return 1;
779}
780
781bool TWPartition::Restore_Tar(string restore_folder) {
782 LOGI("STUB TWPartition::Restore_Tar, backup_folder: '%s'\n", restore_folder.c_str());
783 return 1;
784}
785
786bool TWPartition::Restore_DD(string restore_folder) {
787 LOGI("STUB TWPartition::Restore_DD, backup_folder: '%s'\n", restore_folder.c_str());
788 return 1;
789}
790
791bool TWPartition::Restore_Flash_Image(string restore_folder) {
792 LOGI("STUB TWPartition::Restore_Flash_Image, backup_folder: '%s'\n", restore_folder.c_str());
793 return 1;
794}
Dees_Troy5bf43922012-09-07 16:07:55 -0400795
796bool TWPartition::Update_Size(bool Display_Error) {
Dees_Troy51127312012-09-08 13:08:49 -0400797 bool ret = false;
798
Dees_Troy5bf43922012-09-07 16:07:55 -0400799 if (!Can_Be_Mounted)
800 return false;
801
Dees_Troy51127312012-09-08 13:08:49 -0400802 if (!Mount(Display_Error))
Dees_Troy5bf43922012-09-07 16:07:55 -0400803 return false;
Dees_Troy51127312012-09-08 13:08:49 -0400804
805 ret = Get_Size_Via_statfs(Display_Error);
806 if (!ret || Size == 0)
807 if (!Get_Size_Via_df(Display_Error))
808 return false;
809
Dees_Troy5bf43922012-09-07 16:07:55 -0400810 if (Has_Data_Media) {
811 if (Mount(Display_Error)) {
Dees_Troy51127312012-09-08 13:08:49 -0400812 unsigned long long data_media_used, actual_data;
813 data_media_used = Get_Folder_Size("/data/media", Display_Error);
814 actual_data = Used - data_media_used;
Dees_Troy5bf43922012-09-07 16:07:55 -0400815 Backup_Size = actual_data;
Dees_Troy51127312012-09-08 13:08:49 -0400816 int bak = (int)(Backup_Size / 1048576LLU);
817 int total = (int)(Size / 1048576LLU);
818 int us = (int)(Used / 1048576LLU);
819 int fre = (int)(Free / 1048576LLU);
820 int datmed = (int)(data_media_used / 1048576LLU);
821 LOGI("Data backup size is %iMB, size: %iMB, used: %iMB, free: %iMB, in data/media: %iMB.\n", bak, total, us, fre, datmed);
Dees_Troy5bf43922012-09-07 16:07:55 -0400822 } else
823 return false;
824 }
825 return true;
Dees_Troy51127312012-09-08 13:08:49 -0400826}