int write_raw_image(const char* partition, const char* filename) {
    char tmp[PATH_MAX];
    sprintf(tmp, "flash_image boot %s", filename);
    return __system(tmp);
}
int convert_mtd_device(const char *root, const char* fs_list)
{
    static char* headers[] = {  "Converting Menu",
                                "",
    							NULL,
                                NULL
    };

    static char* confirm_convert  = "Confirm convert?";
    static char* confirm = "Yes - Convert";

    const char* root_fs = get_type_internal_fs(root);
    headers[2] = root;

    typedef char* string;
    string tfs[NUM_FILESYSTEMS] = { "rfs", "ext4" };
    static string options[NUM_FILESYSTEMS*2 + 1 + 1];
    int sel_fs[NUM_FILESYSTEMS*2 + 1 + 1];

	int i,j=0;
	// with backup
	for (i=0; i<NUM_FILESYSTEMS; i++) {
    	if (fs_list[i] == '*') {
    		if (strcmp(tfs[i], root_fs)) {
    			sel_fs[j] = i;
    			options[j] = (string)malloc(32);
    			sprintf(options[j++], "to %s with backup", tfs[i]);
    		}
    	}
    	else break;
    }
    options[j++] = "";

	// without backup
	for (i=0; i<NUM_FILESYSTEMS; i++) {
    	if (fs_list[i] == '*') {
    		if (strcmp(tfs[i], root_fs)) {
    			sel_fs[j] = i;
    			options[j] = (string)malloc(32);
    			sprintf(options[j++], "to %s through format", tfs[i]);
    		}
    	}
    	else break;
    }
    options[j] = NULL;

    int chosen_item = get_menu_selection(headers, options, 0);
    if (chosen_item == GO_BACK)
        return 1;

    if (chosen_item < i) {
        // with backup
        if (!confirm_selection(confirm_convert, confirm))
            return 1;

    	ui_set_background(BACKGROUND_ICON_INSTALLING);
        ui_show_indeterminate_progress();

    	// mount $root
    	if (0 != ensure_root_path_mounted(root)) {
    		ui_print("Can't mount %s for backup\n", root);
    		return -1;
    	}

    	// check size of $root
    	struct statfs stat_root;
    	if (0 != statfs(get_mount_point_for_root(root), &stat_root)) {
    		ui_print("Can't get size of %s\n", root);
    		return -1;
    	}

    	// mount SDCARD
    	if (0 != ensure_root_path_mounted("SDCARD:")) {
    		ui_print("Can't mount sdcard for backup\n", root);
    		return -1;
    	}

    	// check size SD
    	struct statfs stat_sd;
    	if (0 != statfs(get_mount_point_for_root("SDCARD:"), &stat_sd)) {
    		ui_print("Can't get size of sdcard\n");
    		return -1;
    	}

        uint64_t root_fsize = (uint64_t)(stat_root.f_blocks-stat_root.f_bfree)*(uint64_t)stat_root.f_bsize;
        uint64_t sd_free_size = (uint64_t)stat_sd.f_bfree*(uint64_t)stat_sd.f_bsize;
        ui_print("SD free: %lluMB / need: %lluMB\n", sd_free_size/(1024*1024), root_fsize/(1024*1024));
        if (root_fsize > sd_free_size) {
        	ui_print("Can't backup need: %lluMB on SD\n", root_fsize/(1024*1024));
        	return -1;
        }

    	// create folder for backup [/sdcard/ebrecovery/tmp] [mkdir -p /sdcard/ebrecovery/tmp]
    	if (0 != __system("mkdir -p /sdcard/ebrecovery/tmp")) {
    		ui_print("Can't create tmp folder for backup\n");
    		return -1;
    	}

        ui_show_progress(0.3, root_fsize*30/(140*1024*1024));

    	// backup
    	ui_print("Backuping %s...\n", root);
    	char br_exec[256];
    	sprintf(br_exec, "tar -c --exclude=*RFS_LOG.LO* -f /sdcard/ebrecovery/tmp/ctmp.tar %s", get_mount_point_for_root(root)+1);
    	if (0 != __system(br_exec)) {
    		ui_print("Can't create backup file\n");
    		return -1;
    	}

    	// check size of backup file > sizeof($root)?
    	// set new FS
    	ui_print("Change fs type %s -> %s\n", get_type_internal_fs(root), tfs[sel_fs[chosen_item]]);
    	if (0 != set_type_internal_fs(root, tfs[sel_fs[chosen_item]])) {
    		ui_print("Error change type of file system to %s for %s\n", tfs[sel_fs[chosen_item]], root);
    		return -1;
    	}

    	// format $root
        ui_show_progress(0.05, 10);
        ui_print("Formatting %s...\n", root);
        if (0 != format_root_device(root)) {
    		ui_print("Error format %s\n", root);
    		return -1;
        }

        // mount $root
    	if (0 != ensure_root_path_mounted(root)) {
    		ui_print("Can't mount %s for backup\n", root);
    		return -1;
    	}

    	// restore $root
        ui_show_progress(0.65, root_fsize*500/(140*1024*1024));
    	ui_print("Restoring %s...\n", root);
    	if (0 != __system("tar -x -f /sdcard/ebrecovery/tmp/ctmp.tar")) {
    		ui_print("Can't restore backup file\n");
    		return -1;
    	}

    	// check size of $root ?
    	// delete temp backup files (delete tmp folder)
        ui_show_indeterminate_progress();
    	if (0 != __system("rm /sdcard/ebrecovery/tmp/ctmp.tar")) {
    		ui_print("Can't remove backup file\n");
    		return -1;
    	}

        return 0;
    }
    else {
    	// without
        if (!confirm_selection(confirm_convert, confirm))
            return 1;
    	// change file system to new
    	ui_print("Change fs type %s -> %s\n", get_type_internal_fs(root), tfs[sel_fs[chosen_item]]);
    	if (0 != set_type_internal_fs(root, tfs[sel_fs[chosen_item]])) {
    		ui_print("Error change type of file system to %s for %s\n", tfs[sel_fs[chosen_item]], root);
    		return -1;
    	}
    	// format
        ui_set_background(BACKGROUND_ICON_INSTALLING);
        ui_show_indeterminate_progress();
        ui_print("Formatting %s...\n", root);
        return format_root_device(root);
    }

    return -1;
}
int format_unknown_device(const char *device, const char* path, const char *fs_type)
{
    LOGI("Formatting unknown device.\n");

    if (fs_type != NULL && get_flash_type(fs_type) != UNSUPPORTED)
        return erase_raw_partition(fs_type, device);

    // if this is SDEXT:, don't worry about it if it does not exist.
    if (0 == strcmp(path, "/sd-ext"))
    {
        struct stat st;
        Volume *vol = volume_for_path("/sd-ext");
        if (vol == NULL || 0 != stat(vol->device, &st))
        {
            ui_print("No app2sd partition found. Skipping format of /sd-ext.\n");
            return 0;
        }
    }

    if (NULL != fs_type) {
        if (strcmp("ext3", fs_type) == 0) {
            LOGI("Formatting ext3 device.\n");
            if (0 != ensure_path_unmounted(path)) {
                LOGE("Error while unmounting %s.\n", path);
                return -12;
            }
            return format_ext3_device(device);
        }

        if (strcmp("ext2", fs_type) == 0) {
            LOGI("Formatting ext2 device.\n");
            if (0 != ensure_path_unmounted(path)) {
                LOGE("Error while unmounting %s.\n", path);
                return -12;
            }
            return format_ext2_device(device);
        }
    }

    if (0 != ensure_path_mounted(path))
    {
        ui_print("Error mounting %s!\n", path);
        ui_print("Skipping format...\n");
        return 0;
    }

    static char tmp[PATH_MAX];
    if (strcmp(path, "/data") == 0) {
        sprintf(tmp, "cd /data ; for f in $(ls -a | grep -v ^media$); do rm -rf $f; done");
        __system(tmp);
    }
    else {
        sprintf(tmp, "rm -rf %s/*", path);
        __system(tmp);
        sprintf(tmp, "rm -rf %s/.*", path);
        __system(tmp);
    }

    ensure_path_unmounted(path);
    return 0;
}
int
nandroid_back_exe()
{
	if (ensure_path_mounted(SDCARD_ROOT) != 0) {
		ui_print("-- Could not mount: %s.\n-- Aborting.\n",SDCARD_ROOT);
		return 1;
	}
    struct tm *t;
    char timestamp[15];
	char tw_image_dir[255];
	char exe[255];
	time_t start, stop;
	time_t seconds;
	seconds = time(0);
    t = localtime(&seconds);
    sprintf(timestamp,"%02d%02d%d%02d%02d%02d",t->tm_mon+1,t->tm_mday,t->tm_year+1900,t->tm_hour,t->tm_min,t->tm_sec); // make time stamp
	sprintf(tw_image_dir,"%s/%s/%s/",backup_folder,device_id,timestamp); // for backup folder
	sprintf(exe,"mkdir -p %s",tw_image_dir); // make the folder with timestamp
	if (__system(exe) != 0) {
		ui_print("-- Could not create: %s.\n-- Aborting.",tw_image_dir);
		return 1;
	} else {
		LOGI("=> Created folder: %s\n",tw_image_dir);
	}
	FILE *fp;
	char pOutput[25];
	int sdSpaceFinal;
	LOGI("=> Checking space on %s.\n",SDCARD_ROOT);
	fp = __popen("df -k /sdcard | grep sdcard | awk '{ print $4 \" \" $3 }'", "r"); // how much space left on sdcard?
	fgets(pOutput,25,fp);
	__pclose(fp);
	if(pOutput[2] == '%') { // oh o, crespo devices report diskspace on the 3rd argument.
		if (sscanf(pOutput,"%*s %d",&sdSpaceFinal) != 1) { // is it a number?
			ui_print("-- Could not determine free space on %s.",SDCARD_ROOT); // oh noes! Can't find sdcard's free space.
			return 1;
		}
	} else {
		if (sscanf(pOutput,"%d %*s",&sdSpaceFinal) != 1) { // is it a number?
			ui_print("-- Could not determine free space on %s.",SDCARD_ROOT); // oh noes! Can't find sdcard's free space.
			return 1;
		}
	}
	LOGI("=> %s",pOutput);
	sdSpace = sdSpaceFinal; // set starting and running count of sd space
	LOGI("=> /sdcard has %d MB free.\n",sdSpace/1024);
	time(&start);
	ui_print("\n[BACKUP STARTED]\n\n");
	ui_print("-- Verifying filesystems, please wait...\n");
	verifyFst();
	ui_print("-- Updating fstab.\n");
	createFstab();
	ui_print("-- Done.\n");
	// SYSTEM
	if (DataManager_GetIntValue(TW_NANDROID_SYSTEM_VAR)) { // was system backup enabled?
		if (tw_backup(sys,tw_image_dir) == 1) { // did the backup process return an error ? 0 = no error
			ui_print("-- Error occured, check recovery.log. Aborting.\n"); //oh noes! abort abort!
			return 1;
		}
	}
	// DATA
	if (DataManager_GetIntValue(TW_NANDROID_DATA_VAR)) {
		if (tw_backup(dat,tw_image_dir) == 1) {
			ui_print("-- Error occured, check recovery.log. Aborting.\n");
			return 1;
		}
	}
	// BOOT
	if (DataManager_GetIntValue(TW_NANDROID_BOOT_VAR)) {
		if (tw_backup(boo,tw_image_dir) == 1) {
			ui_print("-- Error occured, check recovery.log. Aborting.\n");
			return 1;
		}
	}
	// RECOVERY
	if (DataManager_GetIntValue(TW_NANDROID_RECOVERY_VAR)) {
		if (tw_backup(rec,tw_image_dir) == 1) {
			ui_print("-- Error occured, check recovery.log. Aborting.\n");
			return 1;
		}
	}
	// CACHE
	if (DataManager_GetIntValue(TW_NANDROID_CACHE_VAR)) {
		if (tw_backup(cac,tw_image_dir) == 1) {
			ui_print("-- Error occured, check recovery.log. Aborting.\n");
			return 1;
		}
	}
	// WIMAX
	if (DataManager_GetIntValue(TW_NANDROID_WIMAX_VAR)) {
		if (tw_backup(wim,tw_image_dir) == 1) {
			ui_print("-- Error occured, check recovery.log. Aborting.\n");
			return 1;
		}
	}
	// ANDROID-SECURE
	if (DataManager_GetIntValue(TW_NANDROID_ANDSEC_VAR)) {
		if (tw_backup(ase,tw_image_dir) == 1) {
			ui_print("-- Error occured, check recovery.log. Aborting.\n");
			return 1;
		}
	}
	// SD-EXT
	if (DataManager_GetIntValue(TW_NANDROID_SDEXT_VAR)) {
		if (tw_backup(sde,tw_image_dir) == 1) {
			ui_print("-- Error occured, check recovery.log. Aborting.\n");
			return 1;
		}
	}
	LOGI("=> Checking /sdcard space again.\n\n");
	fp = __popen("df -k /sdcard| grep sdcard | awk '{ print $4 \" \" $3 }'", "r");
	fgets(pOutput,25,fp);
	__pclose(fp);
	if(pOutput[2] == '%') {
		if (sscanf(pOutput,"%*s %d",&sdSpace) != 1) { // is it a number?
			ui_print("-- Could not determine free space on %s.\n",SDCARD_ROOT); // oh noes! Can't find sdcard's free space.
			return 1;
		}
	} else {
		if (sscanf(pOutput,"%d %*s",&sdSpace) != 1) { // is it a number?
			ui_print("-- Could not determine free space on %s.\n",SDCARD_ROOT); // oh noes! Can't find sdcard's free space.
			return 1;
		}
	}
	time(&stop);
	ui_print("[%d MB TOTAL BACKED UP TO SDCARD]\n",(int)(sdSpaceFinal - sdSpace) / 1024);
	output_time("BACKUP", "COMPLETED", (int)difftime(stop, start));
	return 0;
}
void dumping_odin_image(const char* root)
{
	if (strcmp(get_type_internal_fs(root), "rfs")) {
		ui_print("You can use this only for RFS filesystem!\n");
		return -1;
	}

    struct statfs s;
    if (0 != statfs("/sdcard", &s))
        return print_and_error("Unable to stat /sdcard\n");
    uint64_t bavail = s.f_bavail;
    uint64_t bsize = s.f_bsize;
    uint64_t sdcard_free = bavail * bsize;
    uint64_t sdcard_free_mb = sdcard_free / (uint64_t)(1024 * 1024);
    ui_print("SD Card space free: %lluMB\n", sdcard_free_mb);
    if (sdcard_free_mb < 400)
        ui_print("There may not be enough free space to complete dump... continuing...\n");

	int n_odin_ifile=0;
	const char* odin_ifile[3] = { "factoryfs.rfs", "datafs.rfs", "cache.rfs" };
    char backup_path[PATH_MAX], sdev[32], *st;
	if (!strcmp(root, "DATA:")) n_odin_ifile = 1;
	else if (!strcmp(root, "CACHE:")) n_odin_ifile = 2;

    char tar_file[PATH_MAX];
    time_t t = time(NULL);
    struct tm *tmp = localtime(&t);
    if (tmp == NULL)
    {
        struct timeval tp;
        gettimeofday(&tp, NULL);
        sprintf(tar_file, "%d", tp.tv_sec);
    }
    else
    {
        strftime(tar_file, sizeof(tar_file), "%F.%H.%M.%S", tmp);
    }

	ensure_root_path_unmounted(root);

    if (ensure_root_path_mounted("SDCARD:") != 0) {
        LOGE ("Can't mount /sdcard\n");
        return;
    }

    if (0 != __system("mkdir -p /sdcard/ebrecovery/odin/tmp")) {
		ui_print("Can't create tmp folder for backup\n");
		return -1;
	}

    strcpy(sdev, get_dev_for_root(root));
    if (st = strstr(sdev, "stl")) {
    	memcpy(st, "bml", 3);
    }
    else {
    	ui_print("Mistake in device name %s\n", sdev);
    	return -1;
    }

    ui_print("Dumping %s..\n", root);
    sprintf(backup_path, "fdump -t %s /sdcard/ebrecovery/odin/tmp/%s", sdev, odin_ifile[n_odin_ifile]);
    if (0 != __system(backup_path)) {
		ui_print("Can't create odin image [%s]\n", odin_ifile[n_odin_ifile]);
		return -1;
	}

    sprintf(backup_path, "cd /sdcard/ebrecovery/odin/tmp && tar -cf ../%s.tar %s", tar_file, odin_ifile[n_odin_ifile]);
    if (0 != __system(backup_path)) {
		ui_print("Can't create odin image [%s]\n", odin_ifile[n_odin_ifile]);
		return -1;
	}

    __system("rm -r /sdcard/ebrecovery/odin/tmp");

    ui_print("Done\n");
}
Exemple #6
0
int ensure_path_mounted(const char* path) {
    Volume* v = volume_for_path(path);
    if (v == NULL) {
        // no /sdcard? let's assume /data/media
        if (strstr(path, "/sdcard") == path && is_data_media()) {
            LOGW("using /data/media, no /sdcard found.\n");
            int ret;
            if (0 != (ret = ensure_path_mounted("/data")))
                return ret;
            setup_data_media();
            return 0;
        }
        LOGE("unknown volume for path [%s]\n", path);
        return -1;
    }
    if (strcmp(v->fs_type, "ramdisk") == 0) {
        // the ramdisk is always mounted.
        return 0;
    }

    int result;
    result = scan_mounted_volumes();
    if (result < 0) {
        LOGE("failed to scan mounted volumes\n");
        return -1;
    }

    const MountedVolume* mv =
        find_mounted_volume_by_mount_point(v->mount_point);
    if (mv) {
        // volume is already mounted
        return 0;
    }

    mkdir(v->mount_point, 0755);  // in case it doesn't already exist

    if (strcmp(v->fs_type, "yaffs2") == 0) {
        // mount an MTD partition as a YAFFS2 filesystem.
        mtd_scan_partitions();
        const MtdPartition* partition;
        partition = mtd_find_partition_by_name(v->device);
        if (partition == NULL) {
            LOGE("failed to find \"%s\" partition to mount at \"%s\"\n",
                 v->device, v->mount_point);
            return -1;
        } 
	 return mtd_mount_partition(partition, v->mount_point, v->fs_type, 0); 
    } else if (strcmp(v->fs_type, "ext4") == 0 ||
               strcmp(v->fs_type, "ext3") == 0 ||
               strcmp(v->fs_type, "rfs") == 0 ||
               strcmp(v->fs_type, "vfat") == 0) {
        if ((result = try_mount(v->device, v->mount_point, v->fs_type, v->fs_options)) == 0)
            return 0;
        if ((result = try_mount(v->device2, v->mount_point, v->fs_type, v->fs_options)) == 0)
            return 0;
        if ((result = try_mount(v->device, v->mount_point, v->fs_type2, v->fs_options2)) == 0)
            return 0;
        if ((result = try_mount(v->device2, v->mount_point, v->fs_type2, v->fs_options2)) == 0)
            return 0;
        return result;
    } else {
        // let's try mounting with the mount binary and hope for the best.
        char mount_cmd[PATH_MAX];
        sprintf(mount_cmd, "mount %s", path);
        return __system(mount_cmd);
    }

    LOGE("unknown fs_type \"%s\" for %s\n", v->fs_type, v->mount_point);
    return -1;
}
Exemple #7
0
int nandroid_restore(const char* backup_path, int restore_boot, int restore_system, int restore_data, int restore_cache, int restore_sdext, int restore_wimax, int restore_preload)
{
    ui_set_background(BACKGROUND_ICON_INSTALLING);
    ui_show_indeterminate_progress();
    nandroid_files_total = 0;

    if (ensure_path_mounted(backup_path) != 0)
        return print_and_error("Can't mount backup path\n");
    
    char tmp[PATH_MAX];

    ui_print("Checking MD5 sums...\n");
    sprintf(tmp, "cd %s && md5sum -c nandroid.md5", backup_path);
    if (0 != __system(tmp))
        return print_and_error("MD5 mismatch!\n");
    
    int ret;

    if (restore_boot && NULL != volume_for_path("/boot") && 0 != (ret = nandroid_restore_partition(backup_path, "/boot")))
        return ret;
    
    struct stat s;
    Volume *vol = volume_for_path("/wimax");
    if (restore_wimax && vol != NULL && 0 == stat(vol->device, &s))
    {
        char serialno[PROPERTY_VALUE_MAX];
        
        serialno[0] = 0;
        property_get("ro.serialno", serialno, "");
        sprintf(tmp, "%s/wimax.%s.img", backup_path, serialno);

        struct stat st;
        if (0 != stat(tmp, &st))
        {
            ui_print("WARNING: WiMAX partition exists, but nandroid\n");
            ui_print("         backup does not contain WiMAX image.\n");
            ui_print("         You should create a new backup to\n");
            ui_print("         protect your WiMAX keys.\n");
        }
        else
        {
            ui_print("Erasing WiMAX before restore...\n");
            if (0 != (ret = format_volume("/wimax")))
                return print_and_error("Error while formatting wimax!\n");
            ui_print("Restoring WiMAX image...\n");
            if (0 != (ret = restore_raw_partition(vol->fs_type, vol->device, tmp)))
                return ret;
        }
    }

    if (restore_system && 0 != (ret = nandroid_restore_partition(backup_path, "/system")))
        return ret;

    if (restore_preload && 0 != (ret = nandroid_restore_partition(backup_path, "/preload")))
        return ret;

    if (restore_data && 0 != (ret = nandroid_restore_partition(backup_path, "/data")))
        return ret;
        
    if (has_datadata()) {
        if (restore_data && 0 != (ret = nandroid_restore_partition(backup_path, "/datadata")))
            return ret;
    }

    if (restore_data && 0 != (ret = nandroid_restore_partition_extended(backup_path, "/sdcard/.android_secure", 0)))
        return ret;

    if (restore_cache && 0 != (ret = nandroid_restore_partition_extended(backup_path, "/cache", 0)))
        return ret;

    if (restore_sdext && 0 != (ret = nandroid_restore_partition(backup_path, "/sd-ext")))
        return ret;

    sync();
    ui_set_background(BACKGROUND_ICON_NONE);
    ui_reset_progress();
    ui_print("\nRestore complete!\n");
    return 0;
}
void show_advanced_menu()
{
    static char* headers[] = {  "Advanced Menu",
                                "",
                                NULL
                             };

    static char* list[] = { "reboot recovery",
                            "wipe dalvik cache",
                            "wipe battery stats",
                            "report error",
                            "key test",
                            "show log",
                            "fix permissions",
                            "partition sdcard",
                            "partition external sdcard",
                            "partition internal sdcard",
                            NULL
                          };

    if (!can_partition("/sdcard")) {
        list[7] = NULL;
    }
    if (!can_partition("/external_sd")) {
        list[8] = NULL;
    }
    if (!can_partition("/emmc")) {
        list[9] = NULL;
    }

    for (;;)
    {
        int chosen_item = get_filtered_menu_selection(headers, list, 0, 0, sizeof(list) / sizeof(char*));
        if (chosen_item == GO_BACK)
            break;
        switch (chosen_item)
        {
        case 0:
            android_reboot(ANDROID_RB_RESTART2, 0, "recovery");
            break;
        case 1:
            if (0 != ensure_path_mounted("/data"))
                break;
            ensure_path_mounted("/sd-ext");
            ensure_path_mounted("/cache");
            if (confirm_selection( "Confirm wipe?", "Yes - Wipe Dalvik Cache")) {
                __system("rm -r /data/dalvik-cache");
                __system("rm -r /cache/dalvik-cache");
                __system("rm -r /sd-ext/dalvik-cache");
                ui_print("Dalvik Cache wiped.\n");
            }
            ensure_path_unmounted("/data");
            break;
        case 2:
            if (confirm_selection( "Confirm wipe?", "Yes - Wipe Battery Stats"))
                wipe_battery_stats();
            break;
        case 3:
            handle_failure(1);
            break;
        case 4:
        {
            ui_print("Outputting key codes.\n");
            ui_print("Go back to end debugging.\n");
            int key;
            int action;
            do
            {
                key = ui_wait_key();
                action = device_handle_key(key, 1);
                ui_print("Key: %d\n", key);
            }
            while (action != GO_BACK);
            break;
        }
        case 5:
            ui_printlogtail(12);
            break;
        case 6:
            ensure_path_mounted("/system");
            ensure_path_mounted("/data");
            ui_print("Fixing permissions...\n");
            __system("fix_permissions");
            ui_print("Done!\n");
            break;
        case 7:
            partition_sdcard("/sdcard");
            break;
        case 8:
            partition_sdcard("/external_sd");
            break;
        case 9:
            partition_sdcard("/emmc");
            break;
        }
    }
}
int ensure_path_mounted(const char* path) {
#ifdef RECOVERY_SDCARD_ON_DATA
    //if (strcmp(path, "/sdcard") == 0)   return 0;
#endif

	if (strncmp(path, "/sdcard", 7) == 0) {
		if (DataManager_GetIntValue(TW_HAS_DUAL_STORAGE) == 1) {
			char mount_command[255], mount_point[255];
			memset(mount_command, 0, sizeof(mount_command));
			memset(mount_point, 0, sizeof(mount_point));

			strcpy(mount_point, DataManager_GetCurrentStoragePath());
			sprintf(mount_command, "mount %s /sdcard", mount_point);
			LOGI("Mounting '%s'\n", mount_point);
			if (ensure_path_mounted(mount_point) != 0) {
				LOGI("Unable to mount '%s'\n", mount_point);
				return -1;
			}
			LOGI("Mounting /sdcard using: '%s'\n", mount_command);
			__system(mount_command);
			return 0;
		} else if (DataManager_GetIntValue(TW_HAS_DATA_MEDIA) == 1) {
			if (ensure_path_mounted("/data")) {
				LOGI("Unable to mount /data\n");
				return -1;
			}
			LOGI("Mounting /sdcard using: 'mount /data/media /sdcard'\n");
			__system("mount /data/media /sdcard");
			return 0;
		}
	}

    Volume* v = volume_for_path(path);
    if (v == NULL) {
        LOGE("unknown volume for path [%s]\n", path);
        return -1;
    }
    if (strcmp(v->fs_type, "ramdisk") == 0) {
        // the ramdisk is always mounted.
        return 0;
    }

    int result;
    result = scan_mounted_volumes();
    if (result < 0) {
        LOGE("failed to scan mounted volumes\n");
        return -1;
    }

    const MountedVolume* mv =
        find_mounted_volume_by_mount_point(v->mount_point);
    if (mv) {
        // volume is already mounted
        return 0;
    }

    mkdir(v->mount_point, 0755);  // in case it doesn't already exist

    if (strcmp(v->fs_type, "yaffs2") == 0) {
        // mount an MTD partition as a YAFFS2 filesystem.
        mtd_scan_partitions();
        const MtdPartition* partition;
        partition = mtd_find_partition_by_name(v->device);
        if (partition == NULL) {
            LOGE("failed to find \"%s\" partition to mount at \"%s\"\n",
                 v->device, v->mount_point);
            return -1;
        }
        return mtd_mount_partition(partition, v->mount_point, v->fs_type, 0);
    } else if (strcmp(v->fs_type, "ext4") == 0 ||
               strcmp(v->fs_type, "ext3") == 0 ||
               strcmp(v->fs_type, "ext2") == 0 ||
               strcmp(v->fs_type, "vfat") == 0) {
        result = mount(v->device, v->mount_point, v->fs_type,
                       MS_NOATIME | MS_NODEV | MS_NODIRATIME, "");
        if (result == 0) return 0;

        if (v->device2) {
            LOGW("failed to mount %s (%s); trying %s\n",
                 v->device, strerror(errno), v->device2);
            result = mount(v->device2, v->mount_point, v->fs_type,
                           MS_NOATIME | MS_NODEV | MS_NODIRATIME, "");
            if (result == 0) return 0;
        }

        LOGE("failed to mount %s (%s)\n", v->mount_point, strerror(errno));
        return -1;
    }

    LOGE("unknown fs_type \"%s\" for %s\n", v->fs_type, v->mount_point);
    return -1;
}
Exemple #10
0
void create_rom_dirs() {

	// Rom Backup Dir
	__system("mkdir /sdcard/Android/data/g3mod/roms/CyanogenMod6_ROM");
	__system("mkdir /sdcard/Android/data/g3mod/roms/CyanogenMod7_ROM"); //Add CM7 Support
	__system("mkdir /sdcard/Android/data/g3mod/roms/G3MOD_ROM");
	__system("mkdir /sdcard/Android/data/g3mod/roms/Kyrillos_ROM");
	__system("mkdir /sdcard/Android/data/g3mod/roms/Grigora_ROM");
	__system("mkdir /sdcard/Android/data/g3mod/roms/AOSP_ROM");
	__system("mkdir /sdcard/Android/data/g3mod/roms/DutchMods_ROM");
	__system("mkdir /sdcard/Android/data/g3mod/roms/Kyorarom_ROM");
	__system("mkdir /sdcard/Android/data/g3mod/roms/Indroid_ROM");
	__system("mkdir /sdcard/Android/data/g3mod/roms/rom1_ROM");
	__system("mkdir /sdcard/Android/data/g3mod/roms/rom2_ROM");
	__system("mkdir /sdcard/Android/data/g3mod/roms/rom3_ROM");
	__system("mkdir /sdcard/Android/data/g3mod/roms/rom4_ROM");
	
	//Data + sd-ext Backup Dir
	__system("mkdir /sdcard/Android/data/g3mod/data/Froyo_DATA");
	__system("mkdir /sdcard/Android/data/g3mod/data/CM6_DATA");
	__system("mkdir /sdcard/Android/data/g3mod/data/CM7_DATA");
	
	//Kernel dir
	__system("mkdir /sdcard/Android/data/g3mod/kernel/Froyo");
	__system("mkdir /sdcard/Android/data/g3mod/kernel/CM6");
	__system("mkdir /sdcard/Android/data/g3mod/kernel/CM7");
}
Exemple #11
0
void show_multi_boot_menu()
{
    static char* headers[] = {  "MultiBoot Menu",
                                "",
                                NULL
    };

    static char* list[] = { "~~~> Go Back <~~~",
			    "Switch ROM",
                            "Backup Current ROM",
			    "Switch Kernel",
			    "Backup Data",
			    "Restore Data",
                            NULL
    };

    for (;;)
    {	
	create_rom_dirs();
        int chosen_item = get_menu_selection(headers, list, 0);
	if (chosen_item == GO_BACK)
            break;
        switch (chosen_item)
        {
		case 0:
		{
		return;
		break;
		}
            
		case 1:
                {
		if (ensure_root_path_mounted("SDCARD:") != 0) {
		LOGE ("Can't mount /sdcard\n");
		return;
		}
		
   		static char* advancedheaders1[] = {  "Choose Which ROM to Activate",
                                			NULL
   						 };
  		char* file = choose_file_menu("/sdcard/Android/data/g3mod/roms/", NULL, advancedheaders1);
   		 if (file == NULL)
     		   return;

    		static char* headers[] = {  "Activating ROM",
                           		     "",
                            		    NULL
  					  };

    		static char* confirm_restore  = "Confirm activate?";
       	        if (confirm_selection(confirm_restore, "Yes - Activate ROM"))
		{		
		nandroid_restore_system(file,1);
		
		}
		
		if (0 != ensure_root_path_mounted("DATA:"))
                    break;
                ensure_root_path_mounted("SDEXT:");
                ensure_root_path_mounted("CACHE:");
                    __system("rm -r /data/dalvik-cache");
                    __system("rm -r /cache/dalvik-cache");
                    __system("rm -r /sd-ext/dalvik-cache");
                ensure_root_path_unmounted("DATA:");
                ui_print("Dalvik Cache wiped.\n");

		show_choose_kernel_menu();
		
                break;
	}
            case 2:
            {
                backup_rom();
                break;
            }
	case 3:
                {
		show_choose_kernel_menu();
                break;
	}
	case 4:
                {
		backup_data();
                break;
	}
	case 5:
                {
		if (ensure_root_path_mounted("SDCARD:") != 0) {
		LOGE ("Can't mount /sdcard\n");
		return;
		}
		
   		static char* advancedheaders1[] = {  "Choose Which Data to Restore",
                                			NULL
   						 };
  		char* file = choose_file_menu("/sdcard/Android/data/g3mod/data/", NULL, advancedheaders1);
   		 if (file == NULL)
     		   return;

    		static char* headers[] = {  "Restoring Data",
                           		     "",
                            		    NULL
  					  };

    		static char* confirm_restore  = "Confirm restore?";
       	        if (confirm_selection(confirm_restore, "Yes - Restore Data"))
		{		
			nandroid_restore_data(file,1);
			nandroid_restore_sd(file,1);
			nandroid_restore_androidSecure(file,1);
		}
                break;
	}
        }
    }
}
Exemple #12
0
void show_wipe_menu()
{

static char* headers[] = {  "Wipe Menu",
                                "",
                                NULL
    };

 static char* list[] = { "~~~> Go Back <~~~",
                         "Data / Factory Reset",
                         "Cache",
                         "Wipe Dalvik Cache",
                         "Wipe Battery Stats",
                            NULL
};

for (;;)
    {
        int chosen_item = get_menu_selection(headers, list, 0);
	if (chosen_item == GO_BACK)
            break;
	switch (chosen_item)
	{
		case 0:
		{
		return;
		break;
		}
		case 1:
		{
		wipe_data1(ui_text_visible());
                if (!ui_text_visible()) return;
		break;
		}
		case 2:
		{
		  if (confirm_selection("Confirm wipe?", "Yes - Wipe Cache"))
                {
                    ui_print("\n-- Wiping cache...\n");
                    erase_root1("CACHE:");
                    ui_print("Cache wipe complete.\n");
                    if (!ui_text_visible()) return;
                }
		break;
		}
		case 3:
		{
		if (0 != ensure_root_path_mounted("DATA:"))
                    break;
                ensure_root_path_mounted("SDEXT:");
                ensure_root_path_mounted("CACHE:");
                if (confirm_selection( "Confirm wipe?", "Yes - Wipe Dalvik Cache")) {
                    __system("rm -r /data/dalvik-cache");
                    __system("rm -r /cache/dalvik-cache");
                    __system("rm -r /sd-ext/dalvik-cache");
                }
                ensure_root_path_unmounted("DATA:");
                ui_print("Dalvik Cache wiped.\n");
                break;
		}
		case 4:
		{
		if (confirm_selection( "Confirm wipe?", "Yes - Wipe Battery Stats"))
                    wipe_battery_stats();
                break;
		}
	}
     }
}
Exemple #13
0
void show_advanced_menu()
{
    static char* headers[] = {  "Advanced and Debugging Menu",
                                "",
                                NULL
    };

    static char* list[] = { "~~~> Go Back <~~~",
			    "Report Error",
                            "Key Test",
#ifndef BOARD_HAS_SMALL_RECOVERY
                            "Partition SD Card",
                            "Fix Permissions",
#ifdef BOARD_HAS_SDCARD_INTERNAL
                            "Partition Internal SD Card",
#endif
#endif
                            NULL
    };

    for (;;)
    {
        int chosen_item = get_menu_selection(headers, list, 0);
        if (chosen_item == GO_BACK)
            break;
        switch (chosen_item)
        {
	    case 0:
	    {
		return;
		break;
	    }
            case 1:
                handle_failure(1);
                break;
            case 2:
            {
                ui_print("Outputting key codes.\n");
                ui_print("Go back to end debugging.\n");
                int key;
                int action;
                do
                {
                    key = ui_wait_key();
                    action = device_handle_key(key, 1);
                    ui_print("Key: %d\n", key);
                }
                while (action != GO_BACK);
                break;
            }
            case 3:
            {
                static char* ext_sizes[] = { "128M",
                                             "256M",
                                             "512M",
                                             "1024M",
                                             "2048M",
                                             "4096M",
                                             NULL };

                static char* swap_sizes[] = { "0M",
                                              "32M",
                                              "64M",
                                              "128M",
                                              "256M",
                                              NULL };

                static char* ext_headers[] = { "Ext Size", "", NULL };
                static char* swap_headers[] = { "Swap Size", "", NULL };

                int ext_size = get_menu_selection(ext_headers, ext_sizes, 0);
                if (ext_size == GO_BACK)
                    continue;

                int swap_size = get_menu_selection(swap_headers, swap_sizes, 0);
                if (swap_size == GO_BACK)
                    continue;

                char sddevice[256];
                const RootInfo *ri = get_root_info_for_path("SDCARD:");
                strcpy(sddevice, ri->device);
                // we only want the mmcblk, not the partition
                sddevice[strlen("/dev/block/mmcblkX")] = NULL;
                char cmd[PATH_MAX];
                setenv("SDPATH", sddevice, 1);
                sprintf(cmd, "sdparted -es %s -ss %s -efs ext3 -s", ext_sizes[ext_size], swap_sizes[swap_size]);
                ui_print("Partitioning SD Card... please wait...\n");
                if (0 == __system(cmd))
                    ui_print("Done!\n");
                else
                    ui_print("An error occured while partitioning your SD Card. Please see /tmp/recovery.log for more details.\n");
                break;
            }
            case 4:
            {
                ensure_root_path_mounted("SYSTEM:");
                ensure_root_path_mounted("DATA:");
                ui_print("Fixing permissions...\n");
                __system("fix_permissions");
                ui_print("Done!\n");
                break;
            }
            case 5:
            {
                static char* ext_sizes[] = { "128M",
                                             "256M",
                                             "512M",
                                             "1024M",
                                             "2048M",
                                             "4096M",
                                             NULL };

                static char* swap_sizes[] = { "0M",
                                              "32M",
                                              "64M",
                                              "128M",
                                              "256M",
                                              NULL };

                static char* ext_headers[] = { "Data Size", "", NULL };
                static char* swap_headers[] = { "Swap Size", "", NULL };
                int ext_size = get_menu_selection(ext_headers, ext_sizes, 0);
                if (ext_size == GO_BACK)
                    continue;

                int swap_size = 0;
                if (swap_size == GO_BACK)
                    continue;

                char sddevice[256];
                const RootInfo *ri = get_root_info_for_path("SDINTERNAL:");
                strcpy(sddevice, ri->device);
                // we only want the mmcblk, not the partition
                sddevice[strlen("/dev/block/mmcblkX")] = NULL;
                char cmd[PATH_MAX];
                setenv("SDPATH", sddevice, 1);
                sprintf(cmd, "sdparted -es %s -ss %s -efs ext3 -s", ext_sizes[ext_size], swap_sizes[swap_size]);
                ui_print("Partitioning Internal SD Card... please wait...\n");
                if (0 == __system(cmd))
                    ui_print("Done!\n");
                else
                    ui_print("An error occured while partitioning your Internal SD Card. Please see /tmp/recovery.log for more details.\n");
                break;
            }
        }
    }
}
int nandroid_restore(const char* backup_path, int restore_boot, int restore_system, int restore_data, int restore_cache, int restore_sdext)
{
    ui_set_background(BACKGROUND_ICON_INSTALLING);
    ui_show_indeterminate_progress();
    yaffs_files_total = 0;

    if (ensure_root_path_mounted("SDCARD:") != 0)
        return print_and_error("Can't mount /sdcard\n");
    
    char tmp[PATH_MAX];

    ui_print("Checking MD5 sums...\n");
    sprintf(tmp, "cd %s && md5sum -c nandroid.md5", backup_path);
    if (0 != __system(tmp))
        return print_and_error("MD5 mismatch!\n");
    
    int ret;
#ifndef BOARD_RECOVERY_IGNORE_BOOTABLES
    if (restore_boot)
    {
        ui_print("Erasing boot before restore...\n");
        if (0 != (ret = format_root_device("BOOT:")))
            return print_and_error("Error while formatting BOOT:!\n");
        sprintf(tmp, "%s/boot.img", backup_path);
        ui_print("Restoring boot image...\n");
        if (0 != (ret = write_raw_image("boot", tmp))) {
            ui_print("Error while flashing boot image!");
            return ret;
        }
    }
#endif
   
    if (restore_system) {
      if (0 != (ret = nandroid_restore_partition(backup_path, "SYSTEM:")))
          return ret;
      // we don't want to restore the /system/etc/lagfix.conf files as they can cause problems
      ensure_root_path_mounted("SYSTEM:");
      __system("rm /system/etc/lagfix.conf");
      __system("rm /system/etc/lagfix.conf.old");
    }

    if (restore_data && 0 != (ret = nandroid_restore_partition(backup_path, "DATA:")))
        return ret;
        
#ifdef HAS_DATADATA
    if (restore_data && 0 != (ret = nandroid_restore_partition(backup_path, "DATADATA:")))
        return ret;
#endif

    if (restore_data && 0 != (ret = nandroid_restore_partition_extended(backup_path, "SDCARD:/.android_secure", 0)))
        return ret;

    if (restore_cache && 0 != (ret = nandroid_restore_partition_extended(backup_path, "CACHE:", 0)))
        return ret;

    if (restore_sdext && 0 != (ret = nandroid_restore_partition(backup_path, "SDEXT:")))
        return ret;

    sync();
    ui_set_background(BACKGROUND_ICON_EBCLOCKWORK);
    ui_reset_progress();
    ui_print("\nRestore complete!\n");
    return 0;
}
Exemple #15
0
int
main(int argc, char **argv) {
	if (strstr(argv[0], "recovery") == NULL)
	{
	    if (strstr(argv[0], "flash_image") != NULL)
	        return flash_image_main(argc, argv);
	    if (strstr(argv[0], "dump_image") != NULL)
	        return dump_image_main(argc, argv);
	    if (strstr(argv[0], "erase_image") != NULL)
	        return erase_image_main(argc, argv);
	    if (strstr(argv[0], "mkyaffs2image") != NULL)
	        return mkyaffs2image_main(argc, argv);
	    if (strstr(argv[0], "unyaffs") != NULL)
	        return unyaffs_main(argc, argv);
        if (strstr(argv[0], "amend"))
            return amend_main(argc, argv);
        if (strstr(argv[0], "nandroid"))
            return nandroid_main(argc, argv);
        if (strstr(argv[0], "reboot"))
            return reboot_main(argc, argv);
        if (strstr(argv[0], "setprop"))
            return setprop_main(argc, argv);
		return busybox_driver(argc, argv);
	}
    __system("/sbin/postrecoveryboot.sh");
    create_fstab();
    
    int is_user_initiated_recovery = 0;
    time_t start = time(NULL);

    // If these fail, there's not really anywhere to complain...
    freopen(TEMPORARY_LOG_FILE, "a", stdout); setbuf(stdout, NULL);
    freopen(TEMPORARY_LOG_FILE, "a", stderr); setbuf(stderr, NULL);
    fprintf(stderr, "Starting recovery on %s", ctime(&start));

    ui_init();
    ui_print(EXPAND(RECOVERY_VERSION)"\n");
#ifdef BOARD_GOAPK_DEFY
    ui_print(EXPAND(RECOVERY_VERSION_GOAPK)"\n");
    ui_print(EXPAND(RECOVERY_VERSION_QUN)"\n");
#endif
    get_args(&argc, &argv);

    int previous_runs = 0;
    const char *send_intent = NULL;
    const char *update_package = NULL;
    int wipe_data = 0, wipe_cache = 0;

    int arg;
    while ((arg = getopt_long(argc, argv, "", OPTIONS, NULL)) != -1) {
        switch (arg) {
        case 'p': previous_runs = atoi(optarg); break;
        case 's': send_intent = optarg; break;
        case 'u': update_package = optarg; break;
        case 'w': wipe_data = wipe_cache = 1; break;
        case 'c': wipe_cache = 1; break;
        case '?':
            LOGE("Invalid command argument\n");
            continue;
        }
    }

    device_recovery_start();

    fprintf(stderr, "Command:");
    for (arg = 0; arg < argc; arg++) {
        fprintf(stderr, " \"%s\"", argv[arg]);
    }
    fprintf(stderr, "\n\n");

    property_list(print_property, NULL);
    fprintf(stderr, "\n");

    int status = INSTALL_SUCCESS;
    
    RecoveryCommandContext ctx = { NULL };
    if (register_update_commands(&ctx)) {
        LOGE("Can't install update commands\n");
    }

    if (update_package != NULL) {
        if (wipe_data && erase_root("DATA:")) status = INSTALL_ERROR;
        status = install_package(update_package);
        if (status != INSTALL_SUCCESS) ui_print("Installation aborted.\n");
    } else if (wipe_data) {
        if (device_wipe_data()) status = INSTALL_ERROR;
        if (erase_root("DATA:")) status = INSTALL_ERROR;
        if (wipe_cache && erase_root("CACHE:")) status = INSTALL_ERROR;
        if (status != INSTALL_SUCCESS) ui_print("Data wipe failed.\n");
    } else if (wipe_cache) {
        if (wipe_cache && erase_root("CACHE:")) status = INSTALL_ERROR;
        if (status != INSTALL_SUCCESS) ui_print("Cache wipe failed.\n");
    } else {
        LOGI("Checking for extendedcommand...\n");
        status = INSTALL_ERROR;  // No command specified
        // we are starting up in user initiated recovery here
        // let's set up some default options
        signature_check_enabled = 0;
        script_assert_enabled = 0;
        is_user_initiated_recovery = 1;
        ui_set_show_text(1);
        
        if (extendedcommand_file_exists()) {
            LOGI("Running extendedcommand...\n");
            int ret;
            if (0 == (ret = run_and_remove_extendedcommand())) {
                status = INSTALL_SUCCESS;
                ui_set_show_text(0);
            }
            else {
                handle_failure(ret);
            }
        } else {
            LOGI("Skipping execution of extendedcommand, file not found...\n");
        }
    }

    if (status != INSTALL_SUCCESS && !is_user_initiated_recovery) ui_set_background(BACKGROUND_ICON_ERROR);
    if (status != INSTALL_SUCCESS || ui_text_visible()) prompt_and_wait();

#ifndef BOARD_HAS_NO_MISC_PARTITION
    // If there is a radio image pending, reboot now to install it.
    maybe_install_firmware_update(send_intent);
#endif

    // Otherwise, get ready to boot the main system...
    finish_recovery(send_intent);
    ui_print("Rebooting...\n");
    sync();
    reboot(RB_AUTOBOOT);
    return EXIT_SUCCESS;
}
void show_advanced_menu()
{
    static char* headers[] = {  "Advanced Menu",
                                "",
                                NULL
    };

    static char* list[] = { "reboot recovery",
                            "reboot to bootloader",
                            "power off",
                            "wipe dalvik cache",
                            "report error",
                            "key test",
                            "show log",
                            "partition sdcard",
                            "partition external sdcard",
                            "partition internal sdcard",
                            NULL
    };

    char bootloader_mode[PROPERTY_VALUE_MAX];
    property_get("ro.bootloader.mode", bootloader_mode, "");
    if (!strcmp(bootloader_mode, "download")) {
        list[1] = "reboot to download mode";
    }

    if (!can_partition("/sdcard")) {
        list[7] = NULL;
    }
    if (!can_partition("/external_sd")) {
        list[8] = NULL;
    }
    if (!can_partition("/emmc")) {
        list[9] = NULL;
    }

    for (;;)
    {
        int chosen_item = get_filtered_menu_selection(headers, list, 0, 0, sizeof(list) / sizeof(char*));
        if (chosen_item == GO_BACK)
            break;
        switch (chosen_item)
        {
            case 0:
            {
                ui_print("Rebooting recovery...\n");
                reboot_main_system(ANDROID_RB_RESTART2, 0, "recovery");
                break;
            }
            case 1:
            {
                if (!strcmp(bootloader_mode, "download")) {
                    ui_print("Rebooting to download mode...\n");
                    reboot_main_system(ANDROID_RB_RESTART2, 0, "download");
                } else {
                    ui_print("Rebooting to bootloader...\n");
                    reboot_main_system(ANDROID_RB_RESTART2, 0, "bootloader");
                }
                break;
            }
            case 2:
            {
                ui_print("Shutting down...\n");
                reboot_main_system(ANDROID_RB_POWEROFF, 0, 0);
                break;
            }
            case 3:
                if (0 != ensure_path_mounted("/data"))
                    break;
                ensure_path_mounted("/sd-ext");
                ensure_path_mounted("/cache");
                if (confirm_selection( "Confirm wipe?", "Yes - Wipe Dalvik Cache")) {
                    __system("rm -r /data/dalvik-cache");
                    __system("rm -r /cache/dalvik-cache");
                    __system("rm -r /sd-ext/dalvik-cache");
                    ui_print("Dalvik Cache wiped.\n");
                }
                ensure_path_unmounted("/data");
                break;
            case 4:
                handle_failure(1);
                break;
            case 5:
            {
                ui_print("Outputting key codes.\n");
                ui_print("Go back to end debugging.\n");
                int key;
                int action;
                do
                {
                    key = ui_wait_key();
                    action = device_handle_key(key, 1);
                    ui_print("Key: %d\n", key);
                }
                while (action != GO_BACK);
                break;
            }
            case 6:
                ui_printlogtail(12);
                break;
            case 7:
                partition_sdcard("/sdcard");
                break;
            case 8:
                partition_sdcard("/external_sd");
                break;
            case 9:
                partition_sdcard("/emmc");
                break;
        }
    }
}
Exemple #17
0
R_API int r_sandbox_system (const char *x, int n) {
	if (enabled) {
		eprintf ("sandbox: system call disabled\n");
		return -1;
	}
#if LIBC_HAVE_FORK
#if LIBC_HAVE_SYSTEM
	if (n) {
#if APPLE_SDK_IPHONEOS
#include <dlfcn.h>
		int (*__system)(const char *cmd)
			= dlsym (NULL, "system");
		if (__system) {
			return __system (x);
		}
		return -1;
#else
		return system (x);
#endif
	}
	return execl ("/bin/sh", "sh", "-c", x, (const char*)NULL);
#else
	#include <spawn.h>
	if (n && !strchr (x, '|')) {
		char **argv, *cmd = strdup (x);
		int rc, pid, argc;
		char *isbg = strchr (cmd, '&');
		// XXX this is hacky
		if (isbg) {
			*isbg = 0;
		}
		argv = r_str_argv (cmd, &argc);
		if (argv) {
			char *argv0 = r_file_path (argv[0]);
			if (!argv0) {
				eprintf ("Cannot find '%s'\n", argv[0]);
				return -1;
			}
			pid = 0;
			posix_spawn (&pid, argv0, NULL, NULL, argv, NULL);
			if (isbg) {
				// XXX. wait for children
				rc = 0;
			} else {
				rc = waitpid (pid, NULL, 0);
			}
			r_str_argv_free (argv);
			free (argv0);
			return rc;
		}
		eprintf ("Error parsing command arguments\n");
		return -1;
	}
	int child = fork();
	if (child == -1) return -1;
	if (child) {
		return waitpid (child, NULL, 0);
	}
	execl ("/bin/sh", "sh", "-c", x, (const char*)NULL);
	exit (1);
#endif
#endif
	return -1;
}
int verify_root_and_recovery() {
    if (ensure_path_mounted("/system") != 0)
        return 0;

    int ret = 0;
    struct stat st;
    // check to see if install-recovery.sh is going to clobber recovery
    // install-recovery.sh is also used to run the su daemon on stock rom for 4.3+
    // so verify that doesn't exist...
    if (0 != lstat("/system/etc/.installed_su_daemon", &st)) {
        // check install-recovery.sh exists and is executable
        if (0 == lstat("/system/etc/install-recovery.sh", &st)) {
            if (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)) {
                ui_show_text(1);
                ret = 1;
                if (confirm_selection("ROM may flash stock recovery on boot. Fix?", "Yes - Disable recovery flash")) {
                    __system("chmod -x /system/etc/install-recovery.sh");
                }
            }
        }
    }


    int exists = 0;
    if (0 == lstat("/system/bin/su", &st)) {
        exists = 1;
        if (S_ISREG(st.st_mode)) {
            if ((st.st_mode & (S_ISUID | S_ISGID)) != (S_ISUID | S_ISGID)) {
                ui_show_text(1);
                ret = 1;
                if (confirm_selection("Root access possibly lost. Fix?", "Yes - Fix root (/system/bin/su)")) {
                    __system("chmod 6755 /system/bin/su");
                }
            }
        }
    }

    if (0 == lstat("/system/xbin/su", &st)) {
        exists = 1;
        if (S_ISREG(st.st_mode)) {
            if ((st.st_mode & (S_ISUID | S_ISGID)) != (S_ISUID | S_ISGID)) {
                ui_show_text(1);
                ret = 1;
                if (confirm_selection("Root access possibly lost. Fix?", "Yes - Fix root (/system/xbin/su)")) {
                    __system("chmod 6755 /system/xbin/su");
                }
            }
        }
    }

    if (!exists) {
        ui_show_text(1);
        ret = 1;
        if (confirm_selection("Root access is missing. Root device?", "Yes - Root device (/system/xbin/su)")) {
            __system("/sbin/install-su.sh");
        }
    }

    ensure_path_unmounted("/system");
    return ret;
}
Exemple #19
0
static void ensure_directory(const char* dir) {
    char tmp[PATH_MAX];
    sprintf(tmp, "mkdir -p %s ; chmod 777 %s", dir, dir);
    __system(tmp);
}
int format_unknown_device(const char *device, const char* path, const char *fs_type)
{
    LOGI("Formatting unknown device.\n");

    if (fs_type != NULL && get_flash_type(fs_type) != UNSUPPORTED)
        return erase_raw_partition(fs_type, device);

    // if this is SDEXT:, don't worry about it if it does not exist.
    if (0 == strcmp(path, "/sd-ext"))
    {
        struct stat st;
        Volume *vol = volume_for_path("/sd-ext");
        if (vol == NULL || 0 != stat(vol->device, &st))
        {
            ui_print("No app2sd partition found. Skipping format of /sd-ext.\n");
            return 0;
        }
    }

    if (NULL != fs_type) {
        if (strcmp("ext3", fs_type) == 0) {
            LOGI("Formatting ext3 device.\n");
            if (0 != ensure_path_unmounted(path)) {
                LOGE("Error while unmounting %s.\n", path);
                return -12;
            }
            return format_ext3_device(device);
        }

        if (strcmp("ext2", fs_type) == 0) {
            LOGI("Formatting ext2 device.\n");
            if (0 != ensure_path_unmounted(path)) {
                LOGE("Error while unmounting %s.\n", path);
                return -12;
            }
            return format_ext2_device(device);
        }
    }

    if (0 != ensure_path_mounted(path))
    {
        ui_print("Error mounting %s!\n", path);
        ui_print("Skipping format...\n");
        return 0;
    }

    static char tmp[PATH_MAX];
    if (strcmp(path, "/data") == 0) {
        sprintf(tmp, "cd /data ; for f in $(ls -a | grep -v ^media$); do rm -rf $f; done");
        __system(tmp);
        // if the /data/media sdcard has already been migrated for android 4.2,
        // prevent the migration from happening again by writing the .layout_version
        struct stat st;
        if (0 == lstat("/data/media/0", &st)) {
            char* layout_version = "2";
            FILE* f = fopen("/data/.layout_version", "wb");
            if (NULL != f) {
                fwrite(layout_version, 1, 2, f);
                fclose(f);
            }
            else {
                LOGI("error opening /data/.layout_version for write.\n");
            }
        }
        else {
            LOGI("/data/media/0 not found. migration may occur.\n");
        }
    }
    else {
        sprintf(tmp, "rm -rf %s/*", path);
        __system(tmp);
        sprintf(tmp, "rm -rf %s/.*", path);
        __system(tmp);
    }

    ensure_path_unmounted(path);
    return 0;
}
int
main(int argc, char **argv) {

    if (argc == 2 && strcmp(argv[1], "adbd") == 0) {
        adb_main();
        return 0;
    }

    // Recovery needs to install world-readable files, so clear umask
    // set by init
    umask(0);

    if (strcmp(basename(argv[0]), "recovery") != 0)
    {
        if (strstr(argv[0], "minizip") != NULL)
            return minizip_main(argc, argv);
        if (strstr(argv[0], "dedupe") != NULL)
            return dedupe_main(argc, argv);
        if (strstr(argv[0], "flash_image") != NULL)
            return flash_image_main(argc, argv);
        if (strstr(argv[0], "volume") != NULL)
            return volume_main(argc, argv);
        if (strstr(argv[0], "edify") != NULL)
            return edify_main(argc, argv);
        if (strstr(argv[0], "dump_image") != NULL)
            return dump_image_main(argc, argv);
        if (strstr(argv[0], "erase_image") != NULL)
            return erase_image_main(argc, argv);
        if (strstr(argv[0], "mkyaffs2image") != NULL)
            return mkyaffs2image_main(argc, argv);
        if (strstr(argv[0], "unyaffs") != NULL)
            return unyaffs_main(argc, argv);
        if (strstr(argv[0], "nandroid"))
            return nandroid_main(argc, argv);
        if (strstr(argv[0], "reboot"))
            return reboot_main(argc, argv);
#ifdef BOARD_RECOVERY_HANDLES_MOUNT
        if (strstr(argv[0], "mount") && argc == 2 && !strstr(argv[0], "umount"))
        {
            load_volume_table();
            return ensure_path_mounted(argv[1]);
        }
#endif
        if (strstr(argv[0], "poweroff")){
            return reboot_main(argc, argv);
        }
        if (strstr(argv[0], "setprop"))
            return setprop_main(argc, argv);
        return busybox_driver(argc, argv);
    }
    __system("/sbin/postrecoveryboot.sh");

    int is_user_initiated_recovery = 0;
    time_t start = time(NULL);

    // If these fail, there's not really anywhere to complain...
    freopen(TEMPORARY_LOG_FILE, "a", stdout); setbuf(stdout, NULL);
    freopen(TEMPORARY_LOG_FILE, "a", stderr); setbuf(stderr, NULL);
    printf("Starting recovery on %s", ctime(&start));

    device_ui_init(&ui_parameters);
    ui_init();
    ui_print(EXPAND(RECOVERY_VERSION)"\n");
    load_volume_table();
    process_volumes();
    LOGI("Processing arguments.\n");
    get_args(&argc, &argv);

    int previous_runs = 0;
    const char *send_intent = NULL;
    const char *update_package = NULL;
    int wipe_data = 0, wipe_cache = 0;

    LOGI("Checking arguments.\n");
    int arg;
    while ((arg = getopt_long(argc, argv, "", OPTIONS, NULL)) != -1) {
        switch (arg) {
        case 'p': previous_runs = atoi(optarg); break;
        case 's': send_intent = optarg; break;
        case 'u': update_package = optarg; break;
        case 'w': 
#ifndef BOARD_RECOVERY_ALWAYS_WIPES
        wipe_data = wipe_cache = 1;
#endif
        break;
        case 'c': wipe_cache = 1; break;
        case 't': ui_show_text(1); break;
        case '?':
            LOGE("Invalid command argument\n");
            continue;
        }
    }

    LOGI("device_recovery_start()\n");
    device_recovery_start();

    printf("Command:");
    for (arg = 0; arg < argc; arg++) {
        printf(" \"%s\"", argv[arg]);
    }
    printf("\n");

    if (update_package) {
        // For backwards compatibility on the cache partition only, if
        // we're given an old 'root' path "CACHE:foo", change it to
        // "/cache/foo".
        if (strncmp(update_package, "CACHE:", 6) == 0) {
            int len = strlen(update_package) + 10;
            char* modified_path = malloc(len);
            strlcpy(modified_path, "/cache/", len);
            strlcat(modified_path, update_package+6, len);
            printf("(replacing path \"%s\" with \"%s\")\n",
                   update_package, modified_path);
            update_package = modified_path;
        }
    }
    printf("\n");

    property_list(print_property, NULL);
    printf("\n");

    int status = INSTALL_SUCCESS;

    if (update_package != NULL) {
        status = install_package(update_package);
        if (status != INSTALL_SUCCESS) ui_print("Installation aborted.\n");
    } else if (wipe_data) {
        if (device_wipe_data()) status = INSTALL_ERROR;
        if (erase_volume("/data")) status = INSTALL_ERROR;
        if (has_datadata() && erase_volume("/datadata")) status = INSTALL_ERROR;
        if (wipe_cache && erase_volume("/cache")) status = INSTALL_ERROR;
        if (status != INSTALL_SUCCESS) ui_print("Data wipe failed.\n");
    } else if (wipe_cache) {
        if (wipe_cache && erase_volume("/cache")) status = INSTALL_ERROR;
        if (status != INSTALL_SUCCESS) ui_print("Cache wipe failed.\n");
    } else {
        LOGI("Checking for extendedcommand...\n");
        status = INSTALL_ERROR;  // No command specified
        // we are starting up in user initiated recovery here
        // let's set up some default options
        signature_check_enabled = 0;
        script_assert_enabled = 0;
        is_user_initiated_recovery = 1;
        ui_set_show_text(1);
        ui_set_background(BACKGROUND_ICON_CLOCKWORK);
        
        if (extendedcommand_file_exists()) {
            LOGI("Running extendedcommand...\n");
            int ret;
            if (0 == (ret = run_and_remove_extendedcommand())) {
                status = INSTALL_SUCCESS;
                ui_set_show_text(0);
            }
            else {
                handle_failure(ret);
            }
        } else {
            LOGI("Skipping execution of extendedcommand, file not found...\n");
        }
    }

    setup_adbd();

    if (status != INSTALL_SUCCESS && !is_user_initiated_recovery) {
        ui_set_show_text(1);
        ui_set_background(BACKGROUND_ICON_ERROR);
    }
    if (status != INSTALL_SUCCESS || ui_text_visible()) {
        prompt_and_wait();
    }

    verify_root_and_recovery();

    // If there is a radio image pending, reboot now to install it.
    maybe_install_firmware_update(send_intent);

    // Otherwise, get ready to boot the main system...
    finish_recovery(send_intent);

    sync();
    if(!poweroff) {
        ui_print("Rebooting...\n");
        android_reboot(ANDROID_RB_RESTART, 0, 0);
    }
    else {
        ui_print("Shutting down...\n");
        android_reboot(ANDROID_RB_POWEROFF, 0, 0);
    }
    return EXIT_SUCCESS;
}
void extract_ramdisk() {
    int elf_fd, return_val = 0;
    Elf *e;
    GElf_Phdr phdr;
    char elf_filename[PATH_MAX], output[PATH_MAX], output2[PATH_MAX];
    char command[4096];
    size_t result;
    unsigned long fota_location;

    // Make sure that tmp_dir ends with a /
    if (tmp_dir[strlen(tmp_dir) - 1] != '/')
        strcat(tmp_dir, "/");

    if (elf_version(EV_CURRENT) == EV_NONE) {
        printf("ELF library initialization failed.\n");
        exit(-1);
    }

    if (use_dump_image) {
        strcpy(elf_filename, tmp_dir);
        strcat(elf_filename, "dumped.elf");
        printf("Dumping image to '%s'\n", elf_filename);
        sprintf(command, "dump_image '%s' '%s'\n", input_filename,
                elf_filename);
        __system(command);
    } else {
        strcpy(elf_filename, input_filename);
    }

    if ((elf_fd = open(elf_filename, O_RDONLY, 0)) < 0) {
        printf("Unable to open '%s' for read.\n", elf_filename);
        exit(-1);
    }

    if ((e = elf_begin(elf_fd, ELF_C_READ, NULL)) == NULL) {
        printf("elf_begin failed.\n");
        close(elf_fd);
        exit(-1);
    }

    if (elf_kind(e) != ELF_K_ELF) {
        printf("'%s' is not an ELF file.\n", elf_filename);
        elf_end(e);
        close(elf_fd);
        exit(-1);
    }

    if (gelf_getphdr(e, ramdisk_loc - 1, &phdr) != &phdr) {
        printf("Failed to get header %i\n", ramdisk_loc - 1);
        elf_end(e);
        close(elf_fd);
        exit(-1);
    }
    printf("Offset:      %llu\n", phdr.p_offset);
    printf("Size:        %llu\n", phdr.p_filesz);
    // printf("Flags:       %ll\n", phdr.e_flags); Does not exist in Android's
    //                                             libelf
    elf_end(e);
    close(elf_fd);

    if (dont_unzip) {
        strcpy(output, output_filename);
    } else {
        strcpy(output, tmp_dir);
        strcat(output, EER_TMP_RAMDISK_GZ);
        if (path_exists(output) && unlink(output)) {
            printf("Unable to unlink '%s'\n", output);
            exit(-1);
        }
    }

    copy_file_part(elf_filename, output, (unsigned long) phdr.p_offset,
                   (unsigned long) phdr.p_filesz);

    if (!dont_unzip) {
        if (check_ramdisk) {
            strcpy(output2, tmp_dir);
            strcat(output2, EER_TMP_RAMDISK_CPIO);
        } else {
            unlink(output_filename);
            strcpy(output2, output_filename);
        }
        sprintf(command, "busybox gunzip -c '%s' > '%s'", output,
                output2);
        __system(command);
        unlink(output);
        printf("Uncompressed ramdisk written to '%s'\n", output2);
        if (check_ramdisk) {
            printf("Checking ramdisk to ensure it is not a stock Sony ");
            printf("recovery.\n");
            printf("  (Checking for %s)\n", EER_SEARCH_STRING);
            // Find the ramdisk offset table
            unsigned char needle[7] = EER_SEARCH_STRING;
            return_val = scan_file_for_data(output2, needle, sizeof(needle), 0,
                                            &fota_location);
            if (return_val < 0) {
                printf("This is not a stock Sony recovery ramdisk.\n");
                copy_file_part(output2, output_filename, 0, 0);
                printf("Ramdisk copied to '%s'\nDONE!\n", output_filename);
            } else {
                printf("This is a stock Sony recovery ramdisk.\n");
                printf("Ramdisk NOT copied to '%s'\n", output_filename);
            }
            unlink(output2);
        } else {
            printf("DONE!\n");
        }
    } else {
        printf("Ramdisk copied to '%s'\nDONE!\n", output_filename);
    }
}
int 
nandroid_rest_exe()
{
	if (ensure_path_mounted(SDCARD_ROOT) != 0) {
		ui_print("-- Could not mount: %s.\n-- Aborting.\n",SDCARD_ROOT);
		return 1;
	}
	time_t rStart, rStop;
	time(&rStart);
	ui_print("\n[RESTORE STARTED]\n\n");
	if (tw_nan_system_x == 1) {
		if (tw_restore(sys,nan_dir) == 1) {
			ui_print("-- Error occured, check recovery.log. Aborting.\n");
			return 1;
		}
	}
	if (tw_nan_data_x == 1) {
		if (tw_restore(dat,nan_dir) == 1) {
			ui_print("-- Error occured, check recovery.log. Aborting.\n");
			return 1;
		}
	}
	if (tw_nan_boot_x == 1) {
		if (tw_restore(boo,nan_dir) == 1) {
			ui_print("-- Error occured, check recovery.log. Aborting.\n");
			return 1;
		}
	}
	if (tw_nan_recovery_x == 1) {
		if (tw_restore(rec,nan_dir) == 1) {
			ui_print("-- Error occured, check recovery.log. Aborting.\n");
			return 1;
		}
	}
	if (tw_nan_cache_x == 1) {
		if (tw_restore(cac,nan_dir) == 1) {
			ui_print("-- Error occured, check recovery.log. Aborting.\n");
			return 1;
		}
	}
	if (tw_nan_wimax_x == 1) {
		if (tw_restore(wim,nan_dir) == 1) {
			ui_print("-- Error occured, check recovery.log. Aborting.\n");
			return 1;
		}
	}
	if (tw_nan_andsec_x == 1) {
		if (tw_restore(ase,nan_dir) == 1) {
			ui_print("-- Error occured, check recovery.log. Aborting.\n");
			return 1;
		}
	}
	if (tw_nan_sdext_x == 1) {
		if (tw_restore(sde,nan_dir) == 1) {
			ui_print("-- Error occured, check recovery.log. Aborting.\n");
			return 1;
		}
	}
	time(&rStop);
	output_time("RESTORE", "COMPLETED", (int)difftime(rStop, rStart));
	__system("sync");
	LOGI("=> Let's update filesystem types.\n");
	verifyFst();
	LOGI("=> And update our fstab also.\n");
	createFstab();
	return 0;
}
Exemple #24
0
int GUIAction::flash_zip(std::string filename, std::string pageName, const int simulate)
{
    int ret_val = 0;

	DataManager::SetValue("ui_progress", 0);

    if (filename.empty())
    {
        LOGE("No file specified.\n");
        return -1;
    }

    // We're going to jump to this page first, like a loading page
    gui_changePage(pageName);

    int fd = -1;
    ZipArchive zip;

    if (mzOpenZipArchive(filename.c_str(), &zip))
    {
        LOGE("Unable to open zip file.\n");
        return -1;
    }

    // Check the zip to see if it has a custom installer theme
	const ZipEntry* twrp = mzFindZipEntry(&zip, "META-INF/teamwin/twrp.zip");
    if (twrp != NULL)
    {
        unlink("/tmp/twrp.zip");
        fd = creat("/tmp/twrp.zip", 0666);
    }
    if (fd >= 0 && twrp != NULL && 
        mzExtractZipEntryToFile(&zip, twrp, fd) && 
        !PageManager::LoadPackage("install", "/tmp/twrp.zip"))
    {
        mzCloseZipArchive(&zip);
        PageManager::SelectPackage("install");
        gui_changePage("main");
    }
    else
    {
        // In this case, we just use the default page
        mzCloseZipArchive(&zip);
        gui_changePage(pageName);
    }
    if (fd >= 0)
        close(fd);

	if (simulate) {
		simulate_progress_bar();
	} else {
		ret_val = install_zip_package(filename.c_str());

		// Now, check if we need to ensure TWRP remains installed...
		struct stat st;
		if (stat("/sbin/installTwrp", &st) == 0)
		{
			DataManager::SetValue("tw_operation", "Configuring TWRP");
			DataManager::SetValue("tw_partition", "");
			ui_print("Configuring TWRP...\n");
			if (__system("/sbin/installTwrp reinstall") < 0)
			{
				ui_print("Unable to configure TWRP with this kernel.\n");
			}
		}
	}

    // Done
    DataManager::SetValue("ui_progress", 100);
    DataManager::SetValue("ui_progress", 0);
    return ret_val;
}
void show_advanced_menu()
{
    static char* headers[] = {  "Advanced and Debugging Menu",
                                "",
                                NULL
    };

    static char* list[] = { "Reboot Recovery",
                            "Wipe Dalvik Cache",
                            "Wipe Battery Stats",
                            "Wipe /data/userinit script",
                            "Report Error",
                            "Key Test",
#ifndef BOARD_HAS_SMALL_RECOVERY
                            "Partition SD Card",
                            "Fix Permissions",
#endif
                            "Create image for Odin",
                            "---Flash Kernel------",
                            "---Flash Recovery----",
                            "Unlock Kernel 4 Flash",
                            "Unlock Recovery 4 Flash",
                            NULL
    };

    for (;;)
    {
        int chosen_item = get_menu_selection(headers, list, 0);
        if (chosen_item == GO_BACK)
            break;
        switch (chosen_item)
        {
            case 0:
                __reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, LINUX_REBOOT_CMD_RESTART2, "recovery");
                break;
            case 1:
            {
                if (0 != ensure_root_path_mounted("DATA:"))
                    break;
                ensure_root_path_mounted("SDEXT:");
                ensure_root_path_mounted("CACHE:");
                if (confirm_selection( "Confirm wipe?", "Yes - Wipe Dalvik Cache")) {
                    __system("rm -r /data/dalvik-cache");
                    __system("rm -r /cache/dalvik-cache");
                    __system("rm -r /sd-ext/dalvik-cache");
                }
                ensure_root_path_unmounted("DATA:");
                ui_print("Dalvik Cache wiped.\n");
                break;
            }
            case 2:
            {
                if (confirm_selection( "Confirm wipe?", "Yes - Wipe Battery Stats"))
                    wipe_battery_stats();
                break;
            }
            case 3:
                ui_print("Wiping /data/userinit.sh...\n");
                ensure_root_path_mounted("DATA:");
                remove("/data/userinit.sh");
                ensure_root_path_unmounted("DATA:");
                ui_print("Done.\n");
            	break;
            case 4:
                handle_failure(1);
                break;
            case 5:
            {
                ui_print("Outputting key codes.\n");
                ui_print("Go back to end debugging.\n");
                int key;
                int action;
                do
                {
                    key = ui_wait_key();
                    action = device_handle_key(key, 1);
                    ui_print("Key: %d\n", key);
                }
                while (action != GO_BACK);
                break;
            }
            case 6:
            {
                static char* ext_sizes[] = { "128M",
                                             "256M",
                                             "512M",
                                             "1024M",
                                             "2048M",
                                             "4096M",
                                             "8192M",
                                             "16384M",
                                             NULL };

                static char* swap_sizes[] = { "0M",
                                              "32M",
                                              "64M",
                                              "128M",
                                              "256M",
                                              NULL };

                static char* ext_headers[] = { "Ext Size", "", NULL };
                static char* swap_headers[] = { "Swap Size", "", NULL };

                int ext_size = get_menu_selection(ext_headers, ext_sizes, 0);
                if (ext_size == GO_BACK)
                    continue;
                 
                int swap_size = get_menu_selection(swap_headers, swap_sizes, 0);
                if (swap_size == GO_BACK)
                    continue;

                char sddevice[256];
                const RootInfo *ri = get_root_info_for_path("SDCARD:");
                strcpy(sddevice, ri->device);
                // we only want the mmcblk, not the partition
                sddevice[strlen("/dev/block/mmcblkX")] = NULL;
                char cmd[PATH_MAX];
                setenv("SDPATH", sddevice, 1);
                sprintf(cmd, "sdparted -es %s -ss %s -efs ext3 -s", ext_sizes[ext_size], swap_sizes[swap_size]);
                ui_print("Partitioning SD Card... please wait...\n");
                if (0 == __system(cmd))
                    ui_print("Done!\n");
                else
                    ui_print("An error occured while partitioning your SD Card. Please see /tmp/recovery.log for more details.\n");
                break;
            }
            case 7:
            {
                ensure_root_path_mounted("SYSTEM:");
                ensure_root_path_mounted("DATA:");
                ui_print("Fixing permissions...\n");
                __system("fix_permissions");
                ui_print("Done!\n");
                break;
            }
            case 8:
            {
            	// create image for Odin
            	dump_odin_image();
            	break;
            }
            case 9:
            {
                ui_print("Flashing kernel...\n");
                __system("flash_kernel");
                ui_print("Done!\n");
                break;
            }
            case 10:
            {
                ui_print("Flashing recovery...\n");
                __system("flash_recovery");
                ui_print("Done!\n");
                break;
            }
            case 11:
            {
                ui_print("Unlocking Kernel...\n");
                __system("unlock_kernel");
                ui_print("Done!\n");
                break;
            }
            case 12:
            {
                ui_print("Unlocking Recovery...\n");
                __system("unlock_recovery");
                ui_print("Done!\n");
                break;
            }
        }
    }
}
Exemple #26
0
int GUIAction::doAction(Action action, int isThreaded /* = 0 */)
{
	static string zip_queue[10];
	static int zip_queue_index;
	int simulate;

	std::string arg = gui_parse_text(action.mArg);

	std::string function = gui_parse_text(action.mFunction);

	DataManager::GetValue(TW_SIMULATE_ACTIONS, simulate);

    if (function == "reboot")
    {
        //curtainClose(); this sometimes causes a crash

        sync();

        if (arg == "recovery")
            tw_reboot(rb_recovery);
        else if (arg == "poweroff")
            tw_reboot(rb_poweroff);
        else if (arg == "bootloader")
            tw_reboot(rb_bootloader);
        else if (arg == "download")
	    tw_reboot(rb_download);
        else
            tw_reboot(rb_system);

        // This should never occur
        return -1;
    }
    if (function == "home")
    {
        PageManager::SelectPackage("TWRP");
        gui_changePage("main");
        return 0;
    }

    if (function == "key")
    {
        PageManager::NotifyKey(getKeyByName(arg));
        return 0;
    }

    if (function == "page") {
		std::string page_name = gui_parse_text(arg);
        return gui_changePage(page_name);
	}

    if (function == "reload") {
		int check = 0, ret_val = 0;
		std::string theme_path;

		operation_start("Reload Theme");
		theme_path = DataManager::GetSettingsStoragePath();
		if (ensure_path_mounted(theme_path.c_str()) < 0) {
			LOGE("Unable to mount %s during reload function startup.\n", theme_path.c_str());
			check = 1;
		}

		theme_path += "/TWRP/theme/ui.zip";
		if (check != 0 || PageManager::ReloadPackage("TWRP", theme_path) != 0)
		{
			// Loading the custom theme failed - try loading the stock theme
			LOGI("Attempting to reload stock theme...\n");
			if (PageManager::ReloadPackage("TWRP", "/res/ui.xml"))
			{
				LOGE("Failed to load base packages.\n");
				ret_val = 1;
			}
		}
        operation_end(ret_val, simulate);
	}

    if (function == "readBackup")
    {
		set_restore_files();
        return 0;
    }

    if (function == "set")
    {
        if (arg.find('=') != string::npos)
        {
            string varName = arg.substr(0, arg.find('='));
            string value = arg.substr(arg.find('=') + 1, string::npos);

            DataManager::GetValue(value, value);
            DataManager::SetValue(varName, value);
        }
        else
            DataManager::SetValue(arg, "1");
        return 0;
    }
    if (function == "clear")
    {
        DataManager::SetValue(arg, "0");
        return 0;
    }

    if (function == "mount")
    {
        if (arg == "usb")
        {
            DataManager::SetValue(TW_ACTION_BUSY, 1);
			if (!simulate)
				usb_storage_enable();
			else
				ui_print("Simulating actions...\n");
        }
        else if (!simulate)
        {
            string cmd;
			if (arg == "EXTERNAL")
				cmd = "mount " + DataManager::GetStrValue(TW_EXTERNAL_MOUNT);
			else if (arg == "INTERNAL")
				cmd = "mount " + DataManager::GetStrValue(TW_INTERNAL_MOUNT);
			else
				cmd = "mount " + arg;
            __system(cmd.c_str());
			if (arg == "/data" && DataManager::GetIntValue(TW_HAS_DATADATA) == 1)
				__system("mount /datadata");
        } else
			ui_print("Simulating actions...\n");
        return 0;
    }

    if (function == "umount" || function == "unmount")
    {
        if (arg == "usb")
        {
            if (!simulate)
				usb_storage_disable();
			else
				ui_print("Simulating actions...\n");
			DataManager::SetValue(TW_ACTION_BUSY, 0);
        }
        else if (!simulate)
        {
            string cmd;
			if (arg == "EXTERNAL")
				cmd = "umount " + DataManager::GetStrValue(TW_EXTERNAL_MOUNT);
			else if (arg == "INTERNAL")
				cmd = "umount " + DataManager::GetStrValue(TW_INTERNAL_MOUNT);
			else if (DataManager::GetIntValue(TW_DONT_UNMOUNT_SYSTEM) == 1 && (arg == "system" || arg == "/system"))
				return 0;
			else
				cmd = "umount " + arg;
            __system(cmd.c_str());
			if (arg == "/data" && DataManager::GetIntValue(TW_HAS_DATADATA) == 1)
				__system("umount /datadata");
        } else
			ui_print("Simulating actions...\n");
        return 0;
    }
	
	if (function == "restoredefaultsettings")
	{
		operation_start("Restore Defaults");
		if (simulate) // Simulated so that people don't accidently wipe out the "simulation is on" setting
			ui_print("Simulating actions...\n");
		else {
			DataManager::ResetDefaults();
			mount_current_storage();
		}
		operation_end(0, simulate);
	}
	
	if (function == "copylog")
	{
		operation_start("Copy Log");
		if (!simulate)
		{
			char command[255];

			mount_current_storage();
			sprintf(command, "cp /tmp/recovery.log %s", DataManager::GetCurrentStoragePath().c_str());
			__system(command);
			sync();
			ui_print("Copied recovery log to %s.\n", DataManager::GetCurrentStoragePath().c_str());
		} else
			simulate_progress_bar();
		operation_end(0, simulate);
		return 0;
	}
	
	if (function == "compute" || function == "addsubtract")
	{
		if (arg.find("+") != string::npos)
        {
            string varName = arg.substr(0, arg.find('+'));
            string string_to_add = arg.substr(arg.find('+') + 1, string::npos);
			int amount_to_add = atoi(string_to_add.c_str());
			int value;

			DataManager::GetValue(varName, value);
            DataManager::SetValue(varName, value + amount_to_add);
			return 0;
        }
		if (arg.find("-") != string::npos)
        {
            string varName = arg.substr(0, arg.find('-'));
            string string_to_subtract = arg.substr(arg.find('-') + 1, string::npos);
			int amount_to_subtract = atoi(string_to_subtract.c_str());
			int value;

			DataManager::GetValue(varName, value);
			value -= amount_to_subtract;
			if (value <= 0)
				value = 0;
            DataManager::SetValue(varName, value);
			return 0;
        }
	}
	
	if (function == "setguitimezone")
	{
		string SelectedZone;
		DataManager::GetValue(TW_TIME_ZONE_GUISEL, SelectedZone); // read the selected time zone into SelectedZone
		string Zone = SelectedZone.substr(0, SelectedZone.find(';')); // parse to get time zone
		string DSTZone = SelectedZone.substr(SelectedZone.find(';') + 1, string::npos); // parse to get DST component
		
		int dst;
		DataManager::GetValue(TW_TIME_ZONE_GUIDST, dst); // check wether user chose to use DST
		
		string offset;
		DataManager::GetValue(TW_TIME_ZONE_GUIOFFSET, offset); // pull in offset
		
		string NewTimeZone = Zone;
		if (offset != "0")
			NewTimeZone += ":" + offset;
		
		if (dst != 0)
			NewTimeZone += DSTZone;
		
		DataManager::SetValue(TW_TIME_ZONE_VAR, NewTimeZone);
		update_tz_environment_variables();
		return 0;
	}

	if (function == "togglestorage") {
		if (arg == "internal") {
			DataManager::SetValue(TW_USE_EXTERNAL_STORAGE, 0);
			DataManager::SetValue(TW_STORAGE_FREE_SIZE, (int)((sdcint.sze - sdcint.used) / 1048576LLU));
		} else if (arg == "external") {
			DataManager::SetValue(TW_USE_EXTERNAL_STORAGE, 1);
			DataManager::SetValue(TW_STORAGE_FREE_SIZE, (int)((sdcext.sze - sdcext.used) / 1048576LLU));
		}
		if (mount_current_storage() == 0) {
			if (arg == "internal") {
				// Save the current zip location to the external variable
				DataManager::SetValue(TW_ZIP_EXTERNAL_VAR, DataManager::GetStrValue(TW_ZIP_LOCATION_VAR));
				// Change the current zip location to the internal variable
				DataManager::SetValue(TW_ZIP_LOCATION_VAR, DataManager::GetStrValue(TW_ZIP_INTERNAL_VAR));
			} else if (arg == "external") {
				// Save the current zip location to the internal variable
				DataManager::SetValue(TW_ZIP_INTERNAL_VAR, DataManager::GetStrValue(TW_ZIP_LOCATION_VAR));
				// Change the current zip location to the external variable
				DataManager::SetValue(TW_ZIP_LOCATION_VAR, DataManager::GetStrValue(TW_ZIP_EXTERNAL_VAR));
			}
		} else {
			// We weren't able to toggle for some reason, restore original setting
			if (arg == "internal") {
				DataManager::SetValue(TW_USE_EXTERNAL_STORAGE, 1);
				DataManager::SetValue(TW_STORAGE_FREE_SIZE, (int)((sdcext.sze - sdcext.used) / 1048576LLU));
			} else if (arg == "external") {
				DataManager::SetValue(TW_USE_EXTERNAL_STORAGE, 0);
				DataManager::SetValue(TW_STORAGE_FREE_SIZE, (int)((sdcint.sze - sdcint.used) / 1048576LLU));
			}
		}
		return 0;
	}
	
	if (function == "overlay")
        return gui_changeOverlay(arg);

	if (function == "queuezip")
    {
        if (zip_queue_index >= 10) {
			ui_print("Maximum zip queue reached!\n");
			return 0;
		}
		DataManager::GetValue("tw_filename", zip_queue[zip_queue_index]);
		if (strlen(zip_queue[zip_queue_index].c_str()) > 0) {
			zip_queue_index++;
			DataManager::SetValue(TW_ZIP_QUEUE_COUNT, zip_queue_index);
		}
		return 0;
	}

	if (function == "cancelzip")
    {
        if (zip_queue_index <= 0) {
			ui_print("Minimum zip queue reached!\n");
			return 0;
		} else {
			zip_queue_index--;
			DataManager::SetValue(TW_ZIP_QUEUE_COUNT, zip_queue_index);
		}
		return 0;
	}

	if (function == "queueclear")
	{
		zip_queue_index = 0;
		DataManager::SetValue(TW_ZIP_QUEUE_COUNT, zip_queue_index);
		return 0;
	}

	if (function == "sleep")
	{
		usleep(atoi(arg.c_str()));
		return 0;
	}

    if (isThreaded)
    {
        if (function == "flash")
        {
			int i, ret_val = 0;

			for (i=0; i<zip_queue_index; i++) {
				operation_start("Flashing");
		        DataManager::SetValue("tw_filename", zip_queue[i]);
		        DataManager::SetValue(TW_ZIP_INDEX, (i + 1));

				ret_val = flash_zip(zip_queue[i], arg, simulate);
				if (ret_val != 0) {
					ui_print("Error flashing zip '%s'\n", zip_queue[i].c_str());
					i = 10; // Error flashing zip - exit queue
					ret_val = 1;
				}
			}
			zip_queue_index = 0;
			DataManager::SetValue(TW_ZIP_QUEUE_COUNT, zip_queue_index);

			if (DataManager::GetIntValue(TW_HAS_INJECTTWRP) == 1 && DataManager::GetIntValue(TW_INJECT_AFTER_ZIP) == 1) {
				operation_start("ReinjectTWRP");
				ui_print("Injecting TWRP into boot image...\n");
				if (simulate) {
					simulate_progress_bar();
				} else {
					__system("injecttwrp --dump /tmp/backup_recovery_ramdisk.img /tmp/injected_boot.img --flash");
					ui_print("TWRP injection complete.\n");
				}
			}
			operation_end(ret_val, simulate);
            return 0;
        }
        if (function == "wipe")
        {
            operation_start("Format");
            DataManager::SetValue("tw_partition", arg);

			if (simulate) {
				simulate_progress_bar();
			} else {
				if (arg == "data")
					wipe_data(0);
				else if (arg == "battery")
					wipe_battery_stats();
				else if (arg == "rotate")
					wipe_rotate_data();
				else if (arg == "dalvik")
					wipe_dalvik_cache();
				else
					erase_volume(arg.c_str());
				
				if (arg == "/sdcard") {
					ensure_path_mounted(SDCARD_ROOT);
					mkdir("/sdcard/TWRP", 0777);
					DataManager::Flush();
				}
			}
			update_system_details();
            operation_end(0, simulate);
            return 0;
        }
		if (function == "refreshsizes")
		{
			operation_start("Refreshing Sizes");
			if (simulate) {
				simulate_progress_bar();
			} else
				update_system_details();
			operation_end(0, simulate);
		}
        if (function == "nandroid")
        {
            operation_start("Nandroid");

			if (simulate) {
				DataManager::SetValue("tw_partition", "Simulation");
				simulate_progress_bar();
			} else {
				if (arg == "backup")
					nandroid_back_exe();
				else if (arg == "restore")
					nandroid_rest_exe();
				else {
					operation_end(1, simulate);
					return -1;
				}
			}
            operation_end(0, simulate);
			return 0;
        }
		if (function == "fixpermissions")
		{
			operation_start("Fix Permissions");
            LOGI("fix permissions started!\n");
			if (simulate) {
				simulate_progress_bar();
			} else
				fix_perms();

			LOGI("fix permissions DONE!\n");
			operation_end(0, simulate);
			return 0;
		}
        if (function == "dd")
        {
            operation_start("imaging");

			if (simulate) {
				simulate_progress_bar();
			} else {
				char cmd[512];
				sprintf(cmd, "dd %s", arg.c_str());
				__system(cmd);
			}
            operation_end(0, simulate);
            return 0;
        }
		if (function == "partitionsd")
		{
			operation_start("Partition SD Card");

			if (simulate) {
				simulate_progress_bar();
			} else {
				int allow_partition;
				DataManager::GetValue(TW_ALLOW_PARTITION_SDCARD, allow_partition);
				if (allow_partition == 0) {
					ui_print("This device does not have a real SD Card!\nAborting!\n");
				} else {
					// Below seen in Koush's recovery
					char sddevice[256];
					Volume *vol = volume_for_path("/sdcard");
					strcpy(sddevice, vol->device);
					// Just need block not whole partition
					sddevice[strlen("/dev/block/mmcblkX")] = NULL;

					char es[64];
					std::string ext_format;
					int ext, swap;
					DataManager::GetValue("tw_sdext_size", ext);
					DataManager::GetValue("tw_swap_size", swap);
					DataManager::GetValue("tw_sdpart_file_system", ext_format);
					sprintf(es, "/sbin/sdparted -es %dM -ss %dM -efs %s -s > /cache/part.log",ext,swap,ext_format.c_str());
					LOGI("\nrunning script: %s\n", es);
					run_script("\nContinue partitioning?",
						   "\nPartitioning sdcard : ",
						   es,
						   "\nunable to execute parted!\n(%s)\n",
						   "\nOops... something went wrong!\nPlease check the recovery log!\n",
						   "\nPartitioning complete!\n\n",
						   "\nPartitioning aborted!\n\n", 0);
					
					// recreate TWRP folder and rewrite settings - these will be gone after sdcard is partitioned
					ensure_path_mounted(SDCARD_ROOT);
					mkdir("/sdcard/TWRP", 0777);
					DataManager::Flush();
					DataManager::SetValue(TW_ZIP_EXTERNAL_VAR, "/sdcard");
					if (DataManager::GetIntValue(TW_USE_EXTERNAL_STORAGE) == 1)
						DataManager::SetValue(TW_ZIP_LOCATION_VAR, "/sdcard");

					update_system_details();
				}
			}
			operation_end(0, simulate);
			return 0;
		}
		if (function == "installhtcdumlock")
		{
			operation_start("Install HTC Dumlock");
			if (simulate) {
				simulate_progress_bar();
			} else
				install_htc_dumlock();

			operation_end(0, simulate);
			return 0;
		}
		if (function == "htcdumlockrestoreboot")
		{
			operation_start("HTC Dumlock Restore Boot");
			if (simulate) {
				simulate_progress_bar();
			} else
				htc_dumlock_restore_original_boot();

			operation_end(0, simulate);
			return 0;
		}
		if (function == "htcdumlockreflashrecovery")
		{
			operation_start("HTC Dumlock Reflash Recovery");
			if (simulate) {
				simulate_progress_bar();
			} else
				htc_dumlock_reflash_recovery_to_boot();

			operation_end(0, simulate);
			return 0;
		}
		if (function == "cmd")
		{
			int op_status = 0;

			operation_start("Command");
			ui_print("Running command: '%s'\n", arg.c_str());
			if (simulate) {
				simulate_progress_bar();
			} else {
				op_status = __system(arg.c_str());
				if (op_status != 0)
					op_status = 1;
			}

			operation_end(op_status, simulate);
			return 0;
		}
		if (function == "reinjecttwrp")
		{
			int op_status = 0;

			operation_start("ReinjectTWRP");
			ui_print("Injecting TWRP into boot image...\n");
			if (simulate) {
				simulate_progress_bar();
			} else {
				__system("injecttwrp --dump /tmp/backup_recovery_ramdisk.img /tmp/injected_boot.img --flash");
				ui_print("TWRP injection complete.\n");
			}

			operation_end(op_status, simulate);
			return 0;
		}
    }
    else
    {
        pthread_t t;
        pthread_create(&t, NULL, thread_start, this);
        return 0;
    }
    return -1;
}
void show_advanced_menu()
{
    static char* headers[] = {  "Advanced and Debugging Menu",
                                "",
                                NULL
    };

    static char* list[] = { "Reboot Recovery",
                            "Wipe Dalvik Cache",
                            "Wipe Battery Stats",
                            "Report Error",
                            "Key Test",
                            "Show log",
#ifndef BOARD_HAS_SMALL_RECOVERY
                            "Partition SD Card",
                            "Fix Permissions",
#ifdef BOARD_HAS_SDCARD_INTERNAL
//                            "Partition Internal SD Card",
#endif
#endif
                            NULL
    };

    for (;;)
    {
        int chosen_item = get_menu_selection(headers, list, 0, 0);
        if (chosen_item == GO_BACK)
            break;
        switch (chosen_item)
        {
            case 0:
            {
                reboot_wrapper("recovery");
                break;
            }
            case 1:
            {
                if (0 != ensure_path_mounted("/data"))
                    break;
                ensure_path_mounted("/sd-ext");
                ensure_path_mounted("/cache");
                if (confirm_selection( "Confirm wipe?", "Yes - Wipe Dalvik Cache")) {
                    __system("rm -r /data/dalvik-cache");
                    __system("rm -r /cache/dalvik-cache");
                    __system("rm -r /sd-ext/dalvik-cache");
                }
                ensure_path_unmounted("/data");
                ui_print("Dalvik Cache wiped.\n");
                break;
            }
            case 2:
            {
                if (confirm_selection( "Confirm wipe?", "Yes - Wipe Battery Stats"))
                    wipe_battery_stats();
                break;
            }
            case 3:
                handle_failure(1);
                break;
            case 4:
            {
                ui_print("Outputting key codes.\n");
                ui_print("Go back to end debugging.\n");
                int key;
                int action;
                do
                {
                    key = ui_wait_key();
                    action = device_handle_key(key, 1);
                    ui_print("Key: %d\n", key);
                }
                while (action != GO_BACK);
                break;
            }
            case 5:
            {
                ui_printlogtail(12);
                break;
            }
            case 6:
            {
                static char* ext_sizes[] = { "128M",
                                             "256M",
                                             "512M",
                                             "1024M",
                                             "2048M",
                                             "4096M",
                                             NULL };

                static char* swap_sizes[] = { "0M",
                                              "32M",
                                              "64M",
                                              "128M",
                                              "256M",
                                              NULL };

                static char* ext_headers[] = { "Ext Size", "", NULL };
                static char* swap_headers[] = { "Swap Size", "", NULL };

                int ext_size = get_menu_selection(ext_headers, ext_sizes, 0, 0);
                if (ext_size == GO_BACK)
                    continue;

                int swap_size = get_menu_selection(swap_headers, swap_sizes, 0, 0);
                if (swap_size == GO_BACK)
                    continue;

                char sddevice[256];
#ifdef BOARD_HAS_SDCARD_INTERNAL
                Volume *vol = volume_for_path("/sdcard-ext");
#else
                Volume *vol = volume_for_path("/sdcard");
#endif
                strcpy(sddevice, vol->device);
                // we only want the mmcblk, not the partition
                sddevice[strlen("/dev/block/mmcblkX")] = NULL;
                char cmd[PATH_MAX];
                setenv("SDPATH", sddevice, 1);
                sprintf(cmd, "sdparted -es %s -ss %s -efs ext3 -s", ext_sizes[ext_size], swap_sizes[swap_size]);
                ui_print("Partitioning SD Card... please wait...\n");
                if (0 == __system(cmd))
                    ui_print("Done!\n");
                else
                    ui_print("An error occured while partitioning your SD Card. Please see /tmp/recovery.log for more details.\n");
                break;
            }
            case 7:
            {
                ensure_path_mounted("/system");
                ensure_path_mounted("/data");
                ui_print("Fixing permissions...\n");
                __system("fix_permissions");
                ui_print("Done!\n");
                break;
            }
            case 8:
            {
                static char* ext_sizes[] = { "128M",
                                             "256M",
                                             "512M",
                                             "1024M",
                                             "2048M",
                                             "4096M",
                                             NULL };

                static char* swap_sizes[] = { "0M",
                                              "32M",
                                              "64M",
                                              "128M",
                                              "256M",
                                              NULL };

                static char* ext_headers[] = { "Data Size", "", NULL };
                static char* swap_headers[] = { "Swap Size", "", NULL };

                int ext_size = get_menu_selection(ext_headers, ext_sizes, 0, 0);
                if (ext_size == GO_BACK)
                    continue;

                int swap_size = 0;
                if (swap_size == GO_BACK)
                    continue;

                char sddevice[256];
                Volume *vol = volume_for_path("/emmc");
                strcpy(sddevice, vol->device);
                // we only want the mmcblk, not the partition
                sddevice[strlen("/dev/block/mmcblkX")] = NULL;
                char cmd[PATH_MAX];
                setenv("SDPATH", sddevice, 1);
                sprintf(cmd, "sdparted -es %s -ss %s -efs ext3 -s", ext_sizes[ext_size], swap_sizes[swap_size]);
                ui_print("Partitioning Internal SD Card... please wait...\n");
                if (0 == __system(cmd))
                    ui_print("Done!\n");
                else
                    ui_print("An error occured while partitioning your Internal SD Card. Please see /tmp/recovery.log for more details.\n");
                break;
            }
        }
    }
}
int
main(int argc, char **argv) {
	if (strcmp(basename(argv[0]), "recovery") != 0)
	{
        if (strstr(argv[0], "flash_image") != NULL)
            return flash_image_main(argc, argv);
        if (strstr(argv[0], "dump_image") != NULL)
            return dump_image_main(argc, argv);
        if (strstr(argv[0], "erase_image") != NULL)
            return erase_image_main(argc, argv);
        if (strstr(argv[0], "mkyaffs2image") != NULL)
            return mkyaffs2image_main(argc, argv);
        if (strstr(argv[0], "unyaffs") != NULL)
            return unyaffs_main(argc, argv);
        if (strstr(argv[0], "nandroid"))
            return nandroid_main(argc, argv);
        if (strstr(argv[0], "reboot"))
            return reboot_main(argc, argv);
#ifdef BOARD_RECOVERY_HANDLES_MOUNT
        if (strstr(argv[0], "mount") && argc == 2 && !strstr(argv[0], "umount"))
        {
            load_volume_table();
            return ensure_path_mounted(argv[1]);
        }
#endif
        if (strstr(argv[0], "poweroff")){
            return reboot_main(argc, argv);
        }
    }
	__system("/sbin/postrecoveryboot.sh");

    time_t start = time(NULL);

    // If these fail, there's not really anywhere to complain...
#ifndef DEBUG
    unlink(TEMPORARY_LOG_FILE);
#endif

    freopen(TEMPORARY_LOG_FILE, "a", stdout); setbuf(stdout, NULL);
    freopen(TEMPORARY_LOG_FILE, "a", stderr); setbuf(stderr, NULL);
    printf("Starting recovery on %s", ctime(&start));
    //miuiIntent init
    miuiIntent_init(10);
    miuiIntent_register(INTENT_MOUNT, &intent_mount);
    miuiIntent_register(INTENT_ISMOUNT, &intent_ismount);
    miuiIntent_register(INTENT_UNMOUNT, &intent_unmount);
    miuiIntent_register(INTENT_REBOOT, &intent_reboot);
    miuiIntent_register(INTENT_INSTALL, &intent_install);
    miuiIntent_register(INTENT_WIPE, &intent_wipe);
    miuiIntent_register(INTENT_TOGGLE, &intent_toggle);
    miuiIntent_register(INTENT_FORMAT, &intent_format);
    miuiIntent_register(INTENT_RESTORE, &intent_restore);
    miuiIntent_register(INTENT_BACKUP, &intent_backup);
    miuiIntent_register(INTENT_ADVANCED_BACKUP, &intent_advanced_backup);
    miuiIntent_register(INTENT_SYSTEM, &intent_system);
    miuiIntent_register(INTENT_COPY, &intent_copy);
    device_ui_init();
    load_volume_table();
    get_args(&argc, &argv);

    struct bootloader_message boot;
    memset(&boot, 0, sizeof(boot));
    set_bootloader_message(&boot);
	create_fstab();
    int previous_runs = 0;
    const char *send_intent = NULL;
    const char *update_package = NULL;
    int wipe_data = 0, wipe_cache = 0;

    int arg;
    while ((arg = getopt_long(argc, argv, "", OPTIONS, NULL)) != -1) {
        switch (arg) {
        case 'p': previous_runs = atoi(optarg); break;
        case 's': send_intent = optarg; break;
        case 'u': update_package = optarg; break;
        case 'w': wipe_data = wipe_cache = 1; break;
        case 'c': wipe_cache = 1; break;
        //case 't': ui_show_text(1); break;
        case '?':
            LOGE("Invalid command argument\n");
            continue;
        }
    }

    device_recovery_start();

    printf("Command:");
    for (arg = 0; arg < argc; arg++) {
        printf(" \"%s\"", argv[arg]);
    }
    printf("\n");

    if (update_package) {
        // For backwards compatibility on the cache partition only, if
        // we're given an old 'root' path "CACHE:foo", change it to
        // "/cache/foo".
        if (strncmp(update_package, "CACHE:", 6) == 0) {
            int len = strlen(update_package) + 10;
            char* modified_path = malloc(len);
            strlcpy(modified_path, "/cache/", len);
            strlcat(modified_path, update_package+6, len);
            printf("(replacing path \"%s\" with \"%s\")\n",
                   update_package, modified_path);
            update_package = modified_path;
        }
    }
    printf("\n");

    property_list(print_property, NULL);
    printf("\n");

    int status = INSTALL_SUCCESS;

    if (update_package != NULL) {
        if (wipe_cache) erase_volume("/cache");
        miuiIntent_send(INTENT_INSTALL, 3, update_package,"0", "0");
        //if echo 0 ,don't print success dialog 
        status = miuiIntent_result_get_int();
        if (status != INSTALL_SUCCESS) ui_print("Installation aborted.\n");
    } else if (wipe_data) {
        if (device_wipe_data()) status = INSTALL_ERROR;
        if (erase_volume("/data")) status = INSTALL_ERROR;
        if (wipe_cache && erase_volume("/cache")) status = INSTALL_ERROR;
        if (status != INSTALL_SUCCESS) ui_print("Data wipe failed.\n");
    } else if (wipe_cache) {
        if (wipe_cache && erase_volume("/cache")) status = INSTALL_ERROR;
        if (status != INSTALL_SUCCESS) ui_print("Cache wipe failed.\n");
    } else {
        status = INSTALL_ERROR;  // No command specified
    }
    if (status != INSTALL_SUCCESS) device_main_ui_show();//show menu
    device_main_ui_release();
    // Otherwise, get ready to boot the main system...
    finish_recovery(send_intent);
    ui_print("Rebooting...\n");
    android_reboot(ANDROID_RB_RESTART, 0, 0);
    return EXIT_SUCCESS;
}
Exemple #29
0
int nandroid_backup(const char* backup_path)
{
    ui_set_background(BACKGROUND_ICON_INSTALLING);
    
    if (ensure_path_mounted(backup_path) != 0) {
        return print_and_error("Can't mount backup path.\n");
    }
    
    Volume* volume = volume_for_path(backup_path);
    if (NULL == volume) {
      if (strstr(backup_path, "/sdcard") == backup_path && is_data_media())
          volume = volume_for_path("/data");
      else
          return print_and_error("Unable to find volume for backup path.\n");
    }
    int ret;
    struct statfs s;
    if (NULL != volume) {
        if (0 != (ret = statfs(volume->mount_point, &s)))
            return print_and_error("Unable to stat backup path.\n");
        uint64_t bavail = s.f_bavail;
        uint64_t bsize = s.f_bsize;
        uint64_t sdcard_free = bavail * bsize;
        uint64_t sdcard_free_mb = sdcard_free / (uint64_t)(1024 * 1024);
        ui_print("SD Card space free: %lluMB\n", sdcard_free_mb);
        if (sdcard_free_mb < 150)
            ui_print("There may not be enough free space to complete backup... continuing...\n");
    }
    char tmp[PATH_MAX];
    sprintf(tmp, "mkdir -p %s", backup_path);
    __system(tmp);

    if (0 != (ret = nandroid_backup_partition(backup_path, "/boot")))
        return ret;

    if (0 != (ret = nandroid_backup_partition(backup_path, "/recovery")))
        return ret;

    Volume *vol = volume_for_path("/wimax");
    if (vol != NULL && 0 == stat(vol->device, &s))
    {
        char serialno[PROPERTY_VALUE_MAX];
        ui_print("Backing up WiMAX...\n");
        serialno[0] = 0;
        property_get("ro.serialno", serialno, "");
        sprintf(tmp, "%s/wimax.%s.img", backup_path, serialno);
        ret = backup_raw_partition(vol->fs_type, vol->device, tmp);
        if (0 != ret)
            return print_and_error("Error while dumping WiMAX image!\n");
    }

    if (0 != (ret = nandroid_backup_partition(backup_path, "/system")))
        return ret;

    if (0 != (ret = nandroid_backup_partition(backup_path, "/data")))
        return ret;

    if (has_datadata()) {
        if (0 != (ret = nandroid_backup_partition(backup_path, "/datadata")))
            return ret;
    }

    if (0 != stat("/sdcard/.android_secure", &s))
    {
        ui_print("No /sdcard/.android_secure found. Skipping backup of applications on external storage.\n");
    }
    else
    {
        if (0 != (ret = nandroid_backup_partition_extended(backup_path, "/sdcard/.android_secure", 0)))
            return ret;
    }

    if (0 != (ret = nandroid_backup_partition_extended(backup_path, "/cache", 0)))
        return ret;

    vol = volume_for_path("/sd-ext");
    if (vol == NULL || 0 != stat(vol->device, &s))
    {
        ui_print("No sd-ext found. Skipping backup of sd-ext.\n");
    }
    else
    {
        if (0 != ensure_path_mounted("/sd-ext"))
            ui_print("Could not mount sd-ext. sd-ext backup may not be supported on this device. Skipping backup of sd-ext.\n");
        else if (0 != (ret = nandroid_backup_partition(backup_path, "/sd-ext")))
            return ret;
    }

    ui_print("Generating md5 sum...\n");
    sprintf(tmp, "nandroid-md5.sh %s", backup_path);
    if (0 != (ret = __system(tmp))) {
        ui_print("Error while generating md5 sum!\n");
        return ret;
    }
    
    sync();
    ui_set_background(BACKGROUND_ICON_NONE);
    ui_reset_progress();
    ui_print("\nBackup complete!\n");
    return 0;
}
int nandroid_backup_flags(const char* backup_path, int flags)
{
    ui_set_background(BACKGROUND_ICON_INSTALLING);
    
    if (ensure_root_path_mounted("SDCARD:") != 0)
        return print_and_error("Can't mount /sdcard\n");
    
    int ret;
    struct statfs s;
    if (0 != (ret = statfs("/sdcard", &s)))
        return print_and_error("Unable to stat /sdcard\n");
    uint64_t bavail = s.f_bavail;
    uint64_t bsize = s.f_bsize;
    uint64_t sdcard_free = bavail * bsize;
    uint64_t sdcard_free_mb = sdcard_free / (uint64_t)(1024 * 1024);
    ui_print("SD Card space free: %lluMB\n", sdcard_free_mb);
    if (sdcard_free_mb < 150)
        ui_print("There may not be enough free space to complete backup... continuing...\n");
    
    char tmp[PATH_MAX];
    sprintf(tmp, "mkdir -p %s", backup_path);
    __system(tmp);

#ifndef BOARD_RECOVERY_IGNORE_BOOTABLES
    ui_print("Backing up boot...\n");
    sprintf(tmp, "%s/%s", backup_path, "boot.img");
    ret = read_raw_image("boot", tmp);
    if (0 != ret)
        return print_and_error("Error while dumping boot image!\n");

    ui_print("Backing up recovery...\n");
    sprintf(tmp, "%s/%s", backup_path, "recovery.img");
    ret = read_raw_image("recovery", tmp);
    if (0 != ret)
        return print_and_error("Error while dumping recovery image!\n");
#endif

    if (0 != (ret = nandroid_backup_partition(backup_path, "SYSTEM:")))
          return ret;

    if (0 != (ret = nandroid_backup_partition(backup_path, "DATA:")))
        return ret;

#ifdef HAS_DATADATA
    if (0 != (ret = nandroid_backup_partition(backup_path, "DATADATA:")))
        return ret;
#endif

    struct stat st;
      if (0 != stat("/sdcard/.android_secure", &st))
      {
          ui_print("No /sdcard/.android_secure found. Skipping backup of applications on external storage.\n");
      }
      else
      {
          if (0 != (ret = nandroid_backup_partition_extended(backup_path, "SDCARD:/.android_secure", 0)))
              return ret;
    }

    if (0 != (ret = nandroid_backup_partition_extended(backup_path, "CACHE:", 0)))
        return ret;

      if (0 != stat(SDEXT_DEVICE, &st))
      {
          ui_print("No sd-ext found. Skipping backup of sd-ext.\n");
      }
      else
      {
          if (0 != ensure_root_path_mounted("SDEXT:"))
              ui_print("Could not mount sd-ext. sd-ext backup may not be supported on this device. Skipping backup of sd-ext.\n");
          else if (0 != (ret = nandroid_backup_partition(backup_path, "SDEXT:")))
              return ret;
    }

    ui_print("Generating md5 sum...\n");
    sprintf(tmp, "nandroid-md5.sh %s", backup_path);
    if (0 != (ret = __system(tmp))) {
        ui_print("Error while generating md5 sum!\n");
        return ret;
    }
    
    sync();
    ui_set_background(BACKGROUND_ICON_EBCLOCKWORK);
    ui_reset_progress();
    ui_print("\nBackup complete!\n");
    return 0;
}