int
install_package(const char *root_path)
{
    ui_set_background(BACKGROUND_ICON_INSTALLING);
    ui_print("Finding update package...\n");
    ui_show_indeterminate_progress();
    LOGI("Update location: %s\n", root_path);

    if (ensure_root_path_mounted(root_path) != 0) {
        LOGE("Can't mount %s\n", root_path);
        return INSTALL_CORRUPT;
    }

    char path[PATH_MAX] = "";
    if (translate_root_path(root_path, path, sizeof(path)) == NULL) {
        LOGE("Bad path %s\n", root_path);
        return INSTALL_CORRUPT;
    }

    ui_print("Opening update package...\n");
    LOGI("Update file path: %s\n", path);

    int numKeys;
    RSAPublicKey* loadedKeys = load_keys(PUBLIC_KEYS_FILE, &numKeys);
    if (loadedKeys == NULL) {
        LOGE("Failed to load keys\n");
        return INSTALL_CORRUPT;
    }
    LOGI("%d key(s) loaded from %s\n", numKeys, PUBLIC_KEYS_FILE);

    // Give verification half the progress bar...
    ui_print("Verifying update package...\n");
    ui_show_progress(
            VERIFICATION_PROGRESS_FRACTION,
            VERIFICATION_PROGRESS_TIME);

    int err;
    err = verify_file(path, loadedKeys, numKeys);
    free(loadedKeys);
    LOGI("verify_file returned %d\n", err);
    if (err != VERIFY_SUCCESS) {
        LOGE("signature verification failed\n");
        return INSTALL_CORRUPT;
    }

    /* Try to open the package.
     */
    ZipArchive zip;
    err = mzOpenZipArchive(path, &zip);
    if (err != 0) {
        LOGE("Can't open %s\n(%s)\n", path, err != -1 ? strerror(err) : "bad");
        return INSTALL_CORRUPT;
    }

    /* Verify and install the contents of the package.
     */
    int status = handle_update_package(path, &zip);
    mzCloseZipArchive(&zip);
    return status;
}
示例#2
0
static int
erase_root(const char *root) {
    ui_set_background(BACKGROUND_ICON_INSTALLING);
    ui_show_indeterminate_progress();
    ui_print("Formatting %s...\n", root);
    return format_root_device(root);
}
示例#3
0
文件: nandroid.c 项目: Fengyuan/G3MOD
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 = restore_raw_partition("boot", tmp))) {
            ui_print("Error while flashing boot image!");
            return ret;
        }
    }
#endif
    
    if (restore_system && 0 != (ret = nandroid_restore_partition(backup_path, "SYSTEM:")))
        return ret;

    if (restore_data && 0 != (ret = nandroid_restore_partition(backup_path, "DATA:")))
        return ret;
        
#ifdef BOARD_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_NONE);
    ui_reset_progress();
    ui_print("\nRestore complete!\n");
    return 0;
}
static int
really_install_package(const char *path)
{
    ui_set_background(BACKGROUND_ICON_INSTALLING);
    ui_print("正在查找升级包...\n");
    ui_show_indeterminate_progress();
    LOGI("Update location: %s\n", path);

    if (ensure_path_mounted(path) != 0) {
        LOGE("Can't mount %s\n", path);
        return INSTALL_CORRUPT;
    }

    ui_print("正在打开升级包...\n");

    int err;

    if (signature_check_enabled) {
        int numKeys;
        RSAPublicKey* loadedKeys = load_keys(PUBLIC_KEYS_FILE, &numKeys);
        if (loadedKeys == NULL) {
            LOGE("Failed to load keys\n");
            return INSTALL_CORRUPT;
        }
        LOGI("%d key(s) loaded from %s\n", numKeys, PUBLIC_KEYS_FILE);

        // Give verification half the progress bar...
        ui_print("正在校验升级包...\n");
        ui_show_progress(
                VERIFICATION_PROGRESS_FRACTION,
                VERIFICATION_PROGRESS_TIME);

        err = verify_file(path, loadedKeys, numKeys);
        free(loadedKeys);
        LOGI("verify_file returned %d\n", err);
        if (err != VERIFY_SUCCESS) {
            LOGE("signature verification failed\n");
            ui_show_text(1);
            if (!confirm_selection("Install Untrusted Package?", "确认 - 安装不严格的zip卡刷包"))
                return INSTALL_CORRUPT;
        }
    }

    /* Try to open the package.
     */
    ZipArchive zip;
    err = mzOpenZipArchive(path, &zip);
    if (err != 0) {
        LOGE("Can't open %s\n(%s)\n", path, err != -1 ? strerror(err) : "bad");
        return INSTALL_CORRUPT;
    }

    /* Verify and install the contents of the package.
     */
    ui_print("正在安装更新...\n");
    return try_update_binary(path, &zip);
}
示例#5
0
int
install_package(const char *path)
{
    ui_set_background(BACKGROUND_ICON_INSTALLING);
    ui_print("Finding update package...\n");
    ui_show_indeterminate_progress();
    LOGI("Update location: %s\n", path);

    if (ensure_path_mounted(path) != 0) {
        LOGE("Can't mount %s\n", path);
        return INSTALL_CORRUPT;
    }

    ui_print("Opening update package...\n");

	//TODO: put this back at some point
	/*
    int numKeys;
    RSAPublicKey* loadedKeys = load_keys(PUBLIC_KEYS_FILE, &numKeys);
    if (loadedKeys == NULL) {
        LOGE("Failed to load keys\n");
        return INSTALL_CORRUPT;
    }
    LOGI("%d key(s) loaded from %s\n", numKeys, PUBLIC_KEYS_FILE);

    // Give verification half the progress bar...
    ui_print("Verifying update package...\n");
    ui_show_progress(
            VERIFICATION_PROGRESS_FRACTION,
            VERIFICATION_PROGRESS_TIME);
	*/
    int err;
	/*
    err = verify_file(path, loadedKeys, numKeys);
    free(loadedKeys);
    LOGI("verify_file returned %d\n", err);
    if (err != VERIFY_SUCCESS) {
        LOGE("signature verification failed\n");
        return INSTALL_CORRUPT;
    }
	*/
	
    /* Try to open the package.
     */
    ZipArchive zip;
    err = mzOpenZipArchive(path, &zip);
    if (err != 0) {
        LOGE("Can't open %s\n(%s)\n", path, err != -1 ? strerror(err) : "bad");
        return INSTALL_CORRUPT;
    }

    /* Verify and install the contents of the package.
     */
    ui_print("Installing update...\n");
    return try_update_binary(path, &zip);
}
int
install_package(const char *path)
{
    ui_set_background(BACKGROUND_ICON_INSTALLING);
    ui_print("Finding update package...\n");
    ui_show_indeterminate_progress();
    LOGI("Update location: %s\n", path);

/*
    if (strcmp(root_path, ":") == 0) {
	    if (ensure_root_path_mounted(root_path) != 0) {
	        LOGE("Can't mount %s\n", root_path);
	        return INSTALL_CORRUPT;
	    }

	    if (translate_root_path(root_path, path, sizeof(path)) == NULL) {
	        LOGE("Bad path %s\n", root_path);
	        return INSTALL_CORRUPT;
	    }
    } else {
	    path = strndup(path, root_path);
    }
*/

    ui_print("Opening update package...\n");
    LOGI("Update file path: %s\n", path);

/*
    int numKeys;
    RSAPublicKey* loadedKeys = load_keys(PUBLIC_KEYS_FILE, &numKeys);
    if (loadedKeys == NULL) {
        LOGE("Failed to load keys\n");
        return INSTALL_CORRUPT;
    }
    LOGI("%d key(s) loaded from %s\n", numKeys, PUBLIC_KEYS_FILE);
*/

    /* Try to open the package.
     */
    ZipArchive zip;
    int err = mzOpenZipArchive(path, &zip);
    if (err != 0) {
        LOGE("Can't open %s\n(%s)\n", path, err != -1 ? strerror(err) : "bad");
        return INSTALL_CORRUPT;
    }

    /* Verify and install the contents of the package.
     */
    // int status = handle_update_package(path, &zip, loadedKeys, numKeys);
    int status = handle_update_package(path, &zip);
    mzCloseZipArchive(&zip);
    // free(loadedKeys);
    return status;
}
int erase_volume(const char *volume) {
    ui_set_background(BACKGROUND_ICON_INSTALLING);
    ui_show_indeterminate_progress();
    ui_print("%s %s...\n", edifyformatting, volume);

    if (strcmp(volume, "/cache") == 0) {
        // Any part of the log we'd copied to cache is now gone.
        // Reset the pointer so we copy from the beginning of the temp
        // log.
        tmplog_offset = 0;
    }
    // Finally run format_volume from within roots
    return format_volume(volume);
}
示例#8
0
static int
erase_volume(const char *volume) {
    ui_set_background(BACKGROUND_ICON_INSTALLING);
    ui_show_indeterminate_progress();
    ui_print("正在格式化 %s \n", volume);

    if (strcmp(volume, "/cache") == 0) {
        // Any part of the log we'd copied to cache is now gone.
        // Reset the pointer so we copy from the beginning of the temp
        // log.
        tmplog_offset = 0;
    }

    return format_volume(volume);
}
void device_toggle_truedualboot(void) {
	char confirm[PATH_MAX];
	int enable = dualboot_is_tdb_enabled();

#ifndef PHILZ_TOUCH_RECOVERY
	ui_setMenuTextColor(MENU_TEXT_COLOR_RED);
#endif

	sprintf(confirm, "Yes - %s TrueDualBoot", enable?"DISABLE":"ENABLE");

	if (confirm_selection("This will WIPE DATA. Confirm?", confirm)) {
		// unmount /data
		if(ensure_path_unmounted("/data")!=0) {
			LOGE("Error unmounting /data!\n");
			return;
		}

		// format /data
		ui_set_background(BACKGROUND_ICON_INSTALLING);
		ui_show_indeterminate_progress();
		ui_print("Formatting /data...\n");
		set_force_raw_format_enabled(1);
		if(format_volume("/data")!=0) {
			ui_print("Error formatting /data!\n");
			ui_reset_progress();
			return;
		}
		ui_reset_progress();
		set_force_raw_format_enabled(0);
		ui_print("Done.\n");

		// toggle
		dualboot_set_tdb_enabled(!enable);
	}

#ifndef PHILZ_TOUCH_RECOVERY
	ui_setMenuTextColor(MENU_TEXT_COLOR);
#endif

	return;
}
示例#10
0
int nandroid_restore_sd(const char* backup_path, int restore_sdext)
{
    ui_set_background(BACKGROUND_ICON_INSTALLING);
    ui_show_indeterminate_progress();
    yaffs_files_total = 0;

    if (ensure_path_mounted(backup_path) != 0)
        return print_and_error("Can't mount backup path\n");
    
    char tmp[PATH_MAX];
    
    int 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;
}
示例#11
0
文件: nandroid.c 项目: Fengyuan/G3MOD
int nandroid_restore_androidSecure(const char* backup_path, int restore_androidSecure)
{
	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];

    int ret;

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

    sync();
    ui_set_background(BACKGROUND_ICON_NONE);
    ui_reset_progress();
    ui_print("\nRestore complete!\n");
    return 0;
}
示例#12
0
int tarbackup_restore(const char* backup_path, int restore_system, int restore_data, int restore_cache, int restore_sdext)
{
    ui_set_background(BACKGROUND_ICON_INSTALLING);
    ui_show_indeterminate_progress();

    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=0;

    if (restore_system && 0 != (ret = tarbackup_restore_partition_extended(backup_path, "SYSTEM:", 1)))
        return ret;

    if (restore_data && 0 != (ret = tarbackup_restore_partition_extended(backup_path, "DATA:", 1)))
        return ret;

    if (restore_data && 0 != (ret = tarbackup_restore_partition_extended(backup_path, "DATADATA:", 1)))
        return ret;
/*
    if (restore_data && 0 != (ret = tarbackup_restore_partition_extended(backup_path, "SDCARD:/.android_secure", 0)))
        return ret;
*/
    if (restore_cache && 0 != (ret = tarbackup_restore_partition_extended(backup_path, "CACHE:", 0)))
        return ret;

    sync();
    ui_set_background(BACKGROUND_ICON_EBCLOCKWORK);
    ui_reset_progress();
    ui_print("\nRestore complete!\n");
    detect_root_fs();
    return 0;
}
示例#13
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)
{
    ui_set_background(BACKGROUND_ICON_INSTALLING);
    ui_show_indeterminate_progress();

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

#ifdef PHILZ_TOUCH_RECOVERY
    if (enable_md5sum)
#endif
    {
        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;

    if (backup_recovery && 0 != (ret = nandroid_restore_partition(backup_path, "/recovery")))
        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;
        }
    }

    // restore of raw efs image files (efs_time-stamp.img) is done elsewhere
    // as it needs to pass in a filename (instead of a folder) as backup_path
    // this could be done here since efs is processed alone, but must be done before md5 checksum!
    if (backup_efs == RESTORE_EFS_TAR && 0 != (ret = nandroid_restore_partition(backup_path, "/efs")))
        return ret;
        
    if (backup_modem == RAW_IMG_FILE && 0 != (ret = nandroid_restore_partition(backup_path, "/modem")))
        return ret;
    else if (backup_modem == RAW_BIN_FILE) {
        sprintf(tmp, "%s/modem.bin", backup_path);
        custom_restore_raw_handler(tmp, "/modem");
    }

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

    if (is_custom_backup && backup_preload) {
        if (0 != (ret = nandroid_restore_partition(backup_path, "/preload"))) {
            ui_print("Failed to restore /preload!\n");
            return ret;
        }
    }
    else if (!is_custom_backup
#ifdef PHILZ_TOUCH_RECOVERY
                && nandroid_add_preload
#endif
            )
    {
        if (restore_system && 0 != (ret = nandroid_restore_partition(backup_path, "/preload"))) {
            ui_print("Failed to restore preload! Try to disable it.\n");
            ui_print("Skipping /preload...\n");
            //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;
}
示例#14
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)
{
    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("挂载分区失败\n");

    char tmp[PATH_MAX];

    ui_print("检查MD5 校验值...\n");
    sprintf(tmp, "cd %s && md5sum -c nandroid.md5", backup_path);
    if (0 != __system(tmp))
        return print_and_error("MD5不合法\n");

    int ret;

    if (restore_boot)
    {
        if (NULL != volume_for_path("/boot") && 0 != (ret = nandroid_restore_partition(backup_path, "/boot")))
            return ret;

        if (NULL != volume_for_path("/uboot") && 0 != (ret = nandroid_restore_partition(backup_path, "/uboot")))
            return ret;

        if (NULL != volume_for_path("/recovery") && 0 != (ret = nandroid_restore_partition(backup_path, "/recovery")))
            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("警告: WiMAX分区存在,但是\n");
            ui_print("        不存在可恢复的WiMAX 镜像.\n");
            ui_print("        亦需要重新做一个备份 \n");
            ui_print("        来保护你的WiMAX keys.\n");
        }
        else
        {
            ui_print("恢复之前先清除WiMAX...\n");
            if (0 != (ret = format_volume("/wimax")))
                return print_and_error("抹掉wimax失败!\n");
            ui_print("恢复WiMAX 镜像...\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_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("\n恢复完成!\n");
    return 0;
}
示例#15
0
// custom raw restore handler
// used to restore efs in raw mode or modem.bin files
// for now, only called directly from outside functions (not from nandroid_restore())
// user selects an image file to restore, so backup_file_image path is already mounted
int dd_raw_restore_handler(const char* backup_file_image, const char* root) {
    ui_print("\n>> Restoring %s...\n", root);
    Volume *vol = volume_for_path(root);
    if (vol == NULL || vol->fs_type == NULL) {
        ui_print("volume not found! Skipping raw restore of %s...\n", root);
        return 0;
    }

    ui_set_background(BACKGROUND_ICON_INSTALLING);
    ui_show_indeterminate_progress();

    // make sure we  have a valid image file name
    int i = 0;
    char errmsg[PATH_MAX];
    char tmp[PATH_MAX];
    char filename[PATH_MAX];
    const char *raw_image_format[] = { ".img", ".bin", NULL };

    sprintf(filename, "%s", BaseName(backup_file_image));
    while (raw_image_format[i] != NULL) {
        if (strlen(filename) > strlen(raw_image_format[i]) &&
                    strcmp(filename + strlen(filename) - strlen(raw_image_format[i]), raw_image_format[i]) == 0 &&
                    strncmp(filename, vol->mount_point + 1, strlen(vol->mount_point)-1) == 0) {
            break;
        }
        i++;
    }

    if (raw_image_format[i] == NULL) {
        sprintf(errmsg, "invalid image file! Failed to restore %s to %s\n", filename, root);
        return print_and_error(errmsg, NANDROID_ERROR_GENERAL);
    }

    //make sure file exists
    if (!file_found(backup_file_image)) {
        sprintf(errmsg, "%s not found. Skipping restore of %s\n", backup_file_image, root);
        return print_and_error(errmsg, NANDROID_ERROR_GENERAL);
    }

    //restore raw image
    int ret = 0;
    char* device_mmcblk;

    ui_print("Restoring %s to %s\n", filename, vol->mount_point);
    if (strstr(vol->blk_device, "/dev/block/mmcblk") != NULL || strstr(vol->blk_device, "/dev/block/mtdblock") != NULL) {
        sprintf(tmp, "raw-backup.sh -r '%s' %s %s", backup_file_image, vol->blk_device, vol->mount_point);
    } else if (vol->blk_device2 != NULL &&
            (strstr(vol->blk_device2, "/dev/block/mmcblk") != NULL || strstr(vol->blk_device2, "/dev/block/mtdblock") != NULL)) {
        sprintf(tmp, "raw-backup.sh -r '%s' %s %s", backup_file_image, vol->blk_device2, vol->mount_point);
    } else if ((device_mmcblk = readlink_device_blk(root)) != NULL) {
        sprintf(tmp, "raw-backup.sh -r '%s' %s %s", backup_file_image, device_mmcblk, vol->mount_point);
        free(device_mmcblk);
    } else {
        sprintf(errmsg, "raw restore: no device found (%s)\n", root);
        return print_and_error(errmsg, NANDROID_ERROR_GENERAL);
    }

    ret = __system(tmp);
    if (0 != ret) {
        sprintf(errmsg, "failed raw restore of %s to %s\n", filename, root);
        print_and_error(errmsg, ret);
    } else {
        finish_nandroid_job();
    }

    sprintf(tmp, "%s/log.txt", DirName(backup_file_image));
    ui_print_custom_logtail(tmp, 3);
    return ret;
}
示例#16
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)
{
    ui_set_background(BACKGROUND_ICON_INSTALLING);
    ui_show_indeterminate_progress();
    yaffs_files_total = 0;

    if (ensure_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;

    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_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;
#ifdef RECOVERY_HAVE_SD_EXT
    if (restore_sdext && 0 != (ret = nandroid_restore_partition(backup_path, "/sd-ext")))
        return ret;
#endif
    sync();
    ui_set_background(BACKGROUND_ICON_NONE);
    ui_reset_progress();
    ui_print("\nRestore complete!\n");
    return 0;
}
示例#17
0
// If the package contains an update binary, extract it and run it.
static int
try_update_binary(const char *path, ZipArchive *zip) 
{
	int	custom_binary = 0;

	const ZipEntry* or_script_entry =
		      mzFindZipEntry(zip, ASSUMED_OR_UPDATE_SCRIPT_NAME);
		      
	if (or_script_entry != NULL)
	{
		ui_print("Using shell script...\n");
		return handle_or_update(path, zip);
	}

	const ZipEntry* binary_entry =
		      mzFindZipEntry(zip, ASSUMED_UPDATE_BINARY_NAME);

	if (binary_entry == NULL)
		ui_print("Using default updater...\n");
	else
		custom_binary = 1;
  
  char* binary = "/tmp/update_binary";
  unlink(binary);
  
  if (custom_binary)
  {
		int fd = creat(binary, 0755);
		if (fd < 0) 
		{
		  LOGE("Can't make %s\n", binary);
		  return 1;
		}
  
		bool ok = mzExtractZipEntryToFile(zip, binary_entry, fd);
		close(fd);

		if (!ok) 
		{
	    LOGE("Can't copy %s\n", ASSUMED_UPDATE_BINARY_NAME);
	    return 1;
		}
	}
	else
		binary = DEFAULT_UPDATE_BINARY_NAME;

	ui_show_indeterminate_progress();
  int pipefd[2];
  pipe(pipefd);

  // When executing the update binary contained in the package, the
  // arguments passed are:
  //
  //   - the version number for this interface
  //
  //   - an fd to which the program can write in order to update the
  //     progress bar.  The program can write single-line commands:
  //
  //        progress <frac> <secs>
  //            fill up the next <frac> part of of the progress bar
  //            over <secs> seconds.  If <secs> is zero, use
  //            set_progress commands to manually control the
  //            progress of this segment of the bar
  //
  //        set_progress <frac>
  //            <frac> should be between 0.0 and 1.0; sets the
  //            progress bar within the segment defined by the most
  //            recent progress command.
  //
  //        firmware <"hboot"|"radio"> <filename>
  //            arrange to install the contents of <filename> in the
  //            given partition on reboot.  (API v2: <filename> may
  //            start with "PACKAGE:" to indicate taking a file from
  //            the OTA package.)
  //
  //        ui_print <string>
  //            display <string> on the screen.
  //
  //				stasis
  //						quit the gui
  //   - the name of the package zip file.
  //

  char** args = malloc(sizeof(char*) * 5);
  args[0] = binary;
  args[1] = EXPAND(RECOVERY_API_VERSION);   // defined in Android.mk
  args[2] = malloc(10);
  sprintf(args[2], "%d", pipefd[1]);
  args[3] = (char*)path;
  args[4] = NULL;

  pid_t pid = fork();
  if (pid == 0) 
  {
    close(pipefd[0]);
    execv(binary, args);
    fprintf(stderr, "E:Can't run %s (%s)\n", binary, strerror(errno));
    _exit(-1);
  }
  close(pipefd[1]);

  char* firmware_type = NULL;
  char* firmware_filename = NULL;

  char buffer[1024];
  FILE* from_child = fdopen(pipefd[0], "r");
  
  ui_set_progress(0.0);
  
  while (fgets(buffer, sizeof(buffer), from_child) != NULL) 
  {
    char* command = strtok(buffer, " \n");
    if (command == NULL) 
    	continue;
   	else if (strcmp(command, "progress") == 0) 
   	{
      char* fraction_s = strtok(NULL, " \n");
      char* seconds_s = strtok(NULL, " \n");

      float fraction = strtof(fraction_s, NULL);
      int seconds = strtol(seconds_s, NULL, 10);

      ui_show_progress(fraction, seconds);
    } 
    else if (strcmp(command, "set_progress") == 0) 
    {
      char* fraction_s = strtok(NULL, " \n");
      float fraction = strtof(fraction_s, NULL);
      ui_set_progress(fraction);
    } 
    else if (strcmp(command, "firmware") == 0) 
    {
      char* type = strtok(NULL, " \n");
      char* filename = strtok(NULL, " \n");

      if (type != NULL && filename != NULL) 
      {
        if (firmware_type != NULL) 
            LOGE("ignoring attempt to do multiple firmware updates");
        else 
        {
          firmware_type = strdup(type);
          firmware_filename = strdup(filename);
        }
      }
    } 
    else if (strcmp(command, "ui_print") == 0) 
    {
      char* str = strtok(NULL, "\n");
      if (str) 
        ui_print(str);
      else
        ui_print("\n");       
    }
    else 
      LOGE("unknown command [%s]\n", command);   
  }
  
  fclose(from_child);

  int status;
  waitpid(pid, &status, 0);
  if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) 
  {
    LOGE("Error in %s\n(Status %d)\n", path, WEXITSTATUS(status));
    return INSTALL_ERROR;
  }

  if (firmware_type != NULL) 
    return handle_firmware_update(firmware_type, firmware_filename, zip);
  else 
    return INSTALL_SUCCESS;
  
}
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;
}
示例#19
0
int twrp_restore(const char* backup_path) {
    Backup_Size = 0; // by default, do not calculate size

    // progress bar will be of indeterminate progress
    // setting nandroid_files_total = 0 will force this in nandroid_callback()
    ui_set_background(BACKGROUND_ICON_INSTALLING);
    nandroid_files_total = 0;
    nandroid_start_msec = timenow_msec();
#ifdef PHILZ_TOUCH_RECOVERY
    // support dim screen timeout during nandroid operation
    last_key_ev = timenow_msec();
#endif
    if (ensure_path_mounted(backup_path) != 0)
        return print_and_error("Can't mount backup path\n", NANDROID_ERROR_GENERAL);

    char tmp[PATH_MAX];
    if (enable_md5sum.value) {
        if (0 != check_twrp_md5sum(backup_path))
            return print_and_error("MD5 mismatch!\n", NANDROID_ERROR_GENERAL);
    }

    ui_show_indeterminate_progress(); // call after verify_nandroid_md5sum() as it will reset the progress

    int ret;

    if (backup_boot && volume_for_path(BOOT_PARTITION_MOUNT_POINT) != NULL &&
            0 != (ret = nandroid_restore_partition(backup_path, BOOT_PARTITION_MOUNT_POINT)))
        return print_and_error(NULL, ret);

    if (backup_recovery && volume_for_path("/recovery") != NULL &&
            0 != (ret = nandroid_restore_partition(backup_path, "/recovery")))
        return print_and_error(NULL, ret);

#ifdef BOARD_USE_MTK_LAYOUT
    if ((backup_boot || backup_recovery) && volume_for_path("/uboot") != NULL &&
            0 != (ret = nandroid_restore_partition(backup_path, "/uboot")))
        return print_and_error(NULL, ret);
#endif

    Volume *vol = volume_for_path("/efs");
    if (backup_efs == RESTORE_EFS_TAR && vol != NULL) {
        if (0 != (ret = nandroid_restore_partition(backup_path, "/efs")))
            return print_and_error(NULL, ret);
    }

    vol = volume_for_path("/misc");
    if (backup_misc && vol != NULL) {
        if (0 != (ret = nandroid_restore_partition(backup_path, "/misc")))
            return print_and_error(NULL, ret);
    }

    vol = volume_for_path("/modem");
    if (backup_modem == RAW_IMG_FILE && vol != NULL) {
        if (0 != (ret = nandroid_restore_partition(backup_path, "/modem")))
            return print_and_error(NULL, ret);
    }

    vol = volume_for_path("/radio");
    if (backup_radio == RAW_IMG_FILE && vol != NULL) {
        if (0 != (ret = nandroid_restore_partition(backup_path, "/radio")))
            return print_and_error(NULL, ret);
    }

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

    vol = volume_for_path("/preload");
    if (backup_preload && vol != NULL) {
        if (0 != (ret = nandroid_restore_partition(backup_path, "/preload")))
            return print_and_error(NULL, ret);
    }

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

    // handle .android_secure on external and internal storage
    set_android_secure_path(tmp);
    if (backup_data && android_secure_ext) {
        if (0 != (ret = nandroid_restore_partition_extended(backup_path, tmp, 0)))
            return print_and_error(NULL, ret);
    }

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

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

    // handle extra partitions
    int i;
    int extra_partitions_num = get_extra_partitions_state();
    for (i = 0; i < extra_partitions_num; ++i) {
        if (extra_partition[i].backup_state && 0 != (ret = nandroid_restore_partition(backup_path, extra_partition[i].mount_point)))
            return print_and_error(NULL, ret);
    }

    finish_nandroid_job();
    show_restore_stats();
    if (reboot_after_nandroid)
        reboot_main_system(ANDROID_RB_RESTART, 0, 0);
    return 0;
}
示例#20
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);

    char* command = argv[0];
    char* stripped = strrchr(argv[0], '/');
    if (stripped)
        command = stripped + 1;

    if (strcmp(command, "recovery") != 0)
    {
        struct recovery_cmd cmd = get_command(command);
        if (cmd.name)
            return cmd.main_func(argc, argv);

#ifdef BOARD_RECOVERY_HANDLES_MOUNT
        if (!strcmp(command, "mount") && argc == 2)
        {
            load_volume_table();
            return ensure_path_mounted(argv[1]);
        }
#endif
        if (!strcmp(command, "setup_adbd")) {
            load_volume_table();
            setup_adbd();
            return 0;
        }
        if (!strcmp(command, "start")) {
            property_set("ctl.start", argv[1]);
            return 0;
        }
        if (!strcmp(command, "stop")) {
            property_set("ctl.stop", argv[1]);
            return 0;
        }
        /* Make sure stdout is not fully buffered, we don't want to
         * have issues when calling busybox commands */
        setlinebuf(stdout);
        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\n", ctime(&start));

    device_ui_init(&ui_parameters);
    ui_init();
    ui_print(EXPAND(RECOVERY_VERSION)"\n");

#ifdef BOARD_RECOVERY_SWIPE
#ifndef BOARD_TOUCH_RECOVERY
    //display directions for swipe controls
    ui_print("Swipe up/down to change selections.\n");
    ui_print("Swipe to the right for enter.\n");
    ui_print("Swipe to the left for back.\n");
#endif
#endif

    load_volume_table();
    process_volumes();
    vold_client_start(&v_callbacks, 0);
    vold_set_automount(1);
    setup_legacy_storage_paths();
    LOGI("Processing arguments.\n");
    ensure_path_mounted(LAST_LOG_FILE);
    rotate_last_logs(10);
    get_args(&argc, &argv);

    int previous_runs = 0;
    const char *send_intent = NULL;
    const char *update_package = NULL;
    const char *update_ubuntu_package = NULL;
    const char *user_data_update_package = NULL;
    int wipe_data = 0, wipe_cache = 0;
    int sideload = 0;
    int headless = 0;

    try_autodeploy(AUTODEPLOY_PACKAGE_FILE);
    try_autodeploy(AUTODEPLOY_PACKAGE_FILE_MULTI);

    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 'd': user_data_update_package = optarg; break;
        case 'w':
#ifndef BOARD_RECOVERY_ALWAYS_WIPES
        wipe_data = wipe_cache = 1;
#endif
        break;
        case 'h':
            ui_set_background(BACKGROUND_ICON_CID);
            ui_show_text(0);
            headless = 1;
            break;
        case 'c': wipe_cache = 1; break;
        case 't': ui_show_text(1); break;
        case 'l': sideload = 1; break;
        case 'v': update_ubuntu_package = UBUNTU_UPDATE_SCRIPT; break;
        case '?':
            LOGE("Invalid command argument\n");
            continue;
        }
    }

    struct selinux_opt seopts[] = {
      { SELABEL_OPT_PATH, "/file_contexts" }
    };

    sehandle = selabel_open(SELABEL_CTX_FILE, seopts, 1);

    if (!sehandle) {
        fprintf(stderr, "Warning: No file_contexts\n");
        ui_print("Warning:  No file_contexts\n");
    }

    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) {
            copy_logs();
            ui_print("Installation aborted.\n");
        }
    } else if (update_ubuntu_package != NULL) {
        LOGI("Performing Ubuntu update");
        ui_set_background(BACKGROUND_ICON_INSTALLING);
        ui_show_indeterminate_progress();
        ui_print("Installing Ubuntu update.\n");
        char tmp[PATH_MAX];
        sprintf(tmp, "%s %s", UBUNTU_UPDATE_SCRIPT, UBUNTU_COMMAND_FILE );
        __system(tmp);
        LOGI("Ubuntu update complete");
        ui_print("Ubuntu update complete.\n");
    } else if (wipe_data) {
        if (device_wipe_data()) status = INSTALL_ERROR;
        ignore_data_media_workaround(1);
        if (erase_volume("/data")) status = INSTALL_ERROR;
        ignore_data_media_workaround(0);
        if (has_datadata() && erase_volume("/datadata")) status = INSTALL_ERROR;
        if (wipe_cache && erase_volume("/cache")) status = INSTALL_ERROR;
        if (status != INSTALL_SUCCESS) {
            copy_logs();
            ui_print("Data wipe failed.\n");
        }
    } else if (wipe_cache) {
        if (wipe_cache && erase_volume("/cache")) status = INSTALL_ERROR;
        if (status != INSTALL_SUCCESS) {
            copy_logs();
            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;
        if (!headless) {
            ui_set_show_text(1);
            ui_set_background(BACKGROUND_ICON_UBUNTU);
        }

        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 (sideload) {
        signature_check_enabled = 0;
        if (!headless)
            ui_set_show_text(1);
        if (0 == apply_from_adb()) {
            status = INSTALL_SUCCESS;
            ui_set_show_text(0);
        }
    }

    if (headless) {
        headless_wait();
    }

    if (user_data_update_package != NULL) {
        status = install_package(user_data_update_package);
        if (status != INSTALL_SUCCESS) ui_print("Installation aborted.\n");
    }

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

    // We reach here when in main menu we choose reboot main system or for some wipe commands on start
    // 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);
    ui_print("Rebooting...\n");
    reboot_main_system(ANDROID_RB_RESTART, 0, 0);

    return EXIT_SUCCESS;
}
int runve(char* filename, char** argv, char** envp, int secs)
{
    int opipe[2];
    int ipipe[2];
    pipe(opipe);
    pipe(ipipe);
    pid_t pid = fork();
    int status = 0;
    if (pid == 0) {
	dup2(opipe[1],1);
	dup2(ipipe[0],0);
	close(opipe[0]);
	close(ipipe[1]);
        execve(filename,argv,envp);
	char* error_msg = calloc(strlen(filename)+20,sizeof(char));
	sprintf(error_msg,"Could not execute %s\n",filename);
	ui_print(error_msg);
	free(error_msg);
	return(9999);
    }
    close(opipe[1]);
    close(ipipe[0]);
    FILE* from = fdopen(opipe[0],"r");
    FILE* to = fdopen(ipipe[1],"w");
    char* cur_line = calloc(100,sizeof(char));
    char* tok;
    int total_lines;
    int cur_lines;
    int num_items;
    int num_headers;
    int num_chks;
    float cur_progress;
    char** items = NULL;
    char** headers = NULL;
    char** chks = NULL;
    
    int i = 0; // iterator for menu items
    int j = 0; // iterator for menu headers
    int k = 0; // iterator for check menu items
    int l = 0;  // iterator for outputting flags from check menu
    int flags = INT_MAX;
    int choice;
    
    while (fgets(cur_line,100,from)!=NULL) {
	printf(cur_line);
	tok=strtok(cur_line," \n");
	if(tok==NULL) {continue;}
	if(strcmp(tok,"*")==0) {
	    tok=strtok(NULL," \n");
	    if(tok==NULL) {continue;}
	    if(strcmp(tok,"ptotal")==0) {
		ui_set_progress(0.0);
		ui_show_progress(1.0,0);
		total_lines=atoi(strtok(NULL," "));
	    } else if (strcmp(tok,"print")==0) {
		ui_print(strtok(NULL,""));
	    } else if (strcmp(tok,"items")==0) {
		num_items=atoi(strtok(NULL," \n"));
		if(items!=NULL) free(items);
		items=calloc((num_items+1),sizeof(char*));
		items[num_items]=NULL;
		i=0;
	    } else if (strcmp(tok,"item")==0) {
		if (i < num_items) {
		    tok=strtok(NULL,"\n");
		    items[i]=calloc((strlen(tok)+1),sizeof(char));
		    strcpy(items[i],tok);
		    i++;
		}
	    } else if (strcmp(tok,"headers")==0) {
		num_headers=atoi(strtok(NULL," \n"));
		if(headers!=NULL) free(headers);
		headers=calloc((num_headers+1),sizeof(char*));
		headers[num_headers]=NULL;
		j=0;
	    } else if (strcmp(tok,"header")==0) {
		if (j < num_headers) {
		    tok=strtok(NULL,"\n");
		    if (tok) {
			headers[j]=calloc((strlen(tok)+1),sizeof(char));
			strcpy(headers[j],tok);
		    } else {
			headers[j]="";
		    }
		    j++;
		}
	    } else if (strcmp(tok,"show_menu")==0) {
		choice=get_menu_selection(headers,items,0,0);
		fprintf(to, "%d\n", choice);
		fflush(to);
	    } else if (strcmp(tok,"pcur")==0) {
		cur_lines=atoi(strtok(NULL,"\n"));
		if (cur_lines%10==0 || total_lines-cur_lines<10) {
		    cur_progress=(float)cur_lines/((float)total_lines);
		    ui_set_progress(cur_progress);
		}
		if (cur_lines==total_lines) ui_reset_progress();
	    } else if (strcmp(tok,"check_items")==0) {
		num_chks=atoi(strtok(NULL," \n"));
		if(chks!=NULL) free(chks);
		chks=calloc((num_chks+1),sizeof(char*));
		chks[num_chks]=NULL;
		k = 0;
	    } else if (strcmp(tok,"check_item")==0) {
		if (k < num_chks) {
		    tok=strtok(NULL,"\n");
		    chks[k]=calloc(strlen(tok)+1,sizeof(char));
		    strcpy(chks[k],tok);
		    k++;
		}
	    } else if (strcmp(tok,"show_check_menu")==0) {
		show_check_menu(headers,chks,&flags);
		for(l=0;l<num_chks;l++) {
		    fprintf(to, "%d\n", !!(flags&(1<<l)));
		}
		fflush(to);
	    } else if (strcmp(tok,"show_indeterminate_progress")==0) {
		ui_show_indeterminate_progress();
	    } else {ui_print("unrecognized command "); ui_print(tok); ui_print("\n");}
	}
    }

    while (waitpid(pid, &status, WNOHANG) == 0) {
	sleep(1);
    }
    ui_print("\n");
    free(cur_line);
    return status;
}
// remove static to be able to call it from ors menu
int
erase_volume(const char *volume) {
    bool is_cache = (strcmp(volume, CACHE_ROOT) == 0);

    int icon = ui_get_background_icon();
    ui_set_background(BACKGROUND_ICON_INSTALLING);
    ui_show_indeterminate_progress();

    saved_log_file* head = NULL;

    if (is_cache) {
        // If we're reformatting /cache, we load any
        // "/cache/recovery/last*" files into memory, so we can restore
        // them after the reformat.

        ensure_path_mounted(volume);

        DIR* d;
        struct dirent* de;
        d = opendir(CACHE_LOG_DIR);
        if (d) {
            char path[PATH_MAX];
            strcpy(path, CACHE_LOG_DIR);
            strcat(path, "/");
            int path_len = strlen(path);
            while ((de = readdir(d)) != NULL) {
                if (strncmp(de->d_name, "last", 4) == 0) {
                    saved_log_file* p = (saved_log_file*) malloc(sizeof(saved_log_file));
                    strcpy(path+path_len, de->d_name);
                    p->name = strdup(path);
                    if (stat(path, &(p->st)) == 0) {
                        // truncate files to 512kb
                        if (p->st.st_size > (1 << 19)) {
                            p->st.st_size = 1 << 19;
                        }
                        p->data = (unsigned char*) malloc(p->st.st_size);
                        FILE* f = fopen(path, "rb");
                        fread(p->data, 1, p->st.st_size, f);
                        fclose(f);
                        p->next = head;
                        head = p;
                    } else {
                        free(p);
                    }
                }
            }
            closedir(d);
        } else {
            if (errno != ENOENT) {
                printf("opendir failed: %s\n", strerror(errno));
            }
        }
    }

    ui_print("Formatting %s...\n", volume);

    ensure_path_unmounted(volume);
    int result = format_volume(volume);

    if (is_cache) {
        while (head) {
            FILE* f = fopen_path(head->name, "wb");
            if (f) {
                fwrite(head->data, 1, head->st.st_size, f);
                fclose(f);
                chmod(head->name, head->st.st_mode);
                chown(head->name, head->st.st_uid, head->st.st_gid);
            }
            free(head->name);
            free(head->data);
            saved_log_file* temp = head->next;
            free(head);
            head = temp;
        }

        // Any part of the log we'd copied to cache is now gone.
        // Reset the pointer so we copy from the beginning of the temp
        // log.
        tmplog_offset = 0;
        copy_logs();
    }

    ui_set_background(icon);
    ui_reset_progress();
    return result;
}
示例#23
0
int
install_package(const char *root_path)
{
	recovery_status = 0;
	int status = INSTALL_SUCCESS;
    ui_set_background(BACKGROUND_ICON_INSTALLING);
    ui_print("Finding update package...\n");
    ui_show_indeterminate_progress();

    if (ensure_root_path_mounted(root_path) != 0) {
        ui_print("Can't mount %s\n", root_path);
        status = INSTALL_CORRUPT;
		goto exit;
    }

    char path[PATH_MAX] = "";
    if (translate_root_path(root_path, path, sizeof(path)) == NULL) {
        ui_print("Bad path %s\n", root_path);
        status = INSTALL_CORRUPT;
		goto exit;
    }
	printf("package name = '%s'\t path_len= %d\n",path,strlen(path));
    ui_print("Opening update package...\n");
#if 0
    int numKeys;
    RSAPublicKey* loadedKeys = load_keys(PUBLIC_KEYS_FILE, &numKeys);
    if (loadedKeys == NULL) {
        LOGE("Failed to load keys\n");
        return INSTALL_CORRUPT;
    }
    LOGI("%d key(s) loaded from %s\n", numKeys, PUBLIC_KEYS_FILE);

    // Give verification half the progress bar...
    ui_print("Verifying update package...\n");
    ui_show_progress(
            VERIFICATION_PROGRESS_FRACTION,
            VERIFICATION_PROGRESS_TIME);

    int err;
    err = verify_file(path, loadedKeys, numKeys);
    free(loadedKeys);
    LOGI("verify_file returned %d\n", err);
    if (err != VERIFY_SUCCESS) {
        LOGE("signature verification failed\n");
        return INSTALL_CORRUPT;
    }
#endif

    /* Try to open the package.
     */
    int err;
    ZipArchive zip;
    err = mzOpenZipArchive(path, &zip);
    if (err != 0) {
        ui_print("Can't open %s\n(%s)\n", path, err != -1 ? strerror(err) : "bad");
        status = INSTALL_CORRUPT;
		goto exit;
    }

	/*
	 * Verify hw version 
	 */
	/*
	if (check_hw_version(&zip)) {
		ui_print("HW version doesn't match!!!");
		status = INSTALL_CORRUPT;
    	mzCloseZipArchive(&zip);
		goto exit;
	}
*/
    /* Verify and install the contents of the package.
     */
	ui_print("start update package file\n");
    status = handle_update_package(path, &zip);
	ui_print("install_success!!!\n");
    mzCloseZipArchive(&zip);

exit:
	ensure_root_path_unmounted(root_path);
	if (status != INSTALL_SUCCESS)
		recovery_status = 1;
	else
		recovery_status = 0;

    return status;
}