示例#1
0
static void compute_directory_stats(const char* directory) {
    char tmp[PATH_MAX];
    char count_text[100];

    // reset file count if we ever return before setting it
    nandroid_files_count = 0;
    nandroid_files_total = 0;

    sprintf(tmp, "find %s | %s wc -l > /tmp/dircount", directory, strcmp(directory, "/data") == 0 && is_data_media() ? "grep -v /data/media |" : "");
    __system(tmp);

    FILE* f = fopen("/tmp/dircount", "r");
    if (f == NULL)
        return;

    if (fgets(count_text, sizeof(count_text), f) == NULL) {
        fclose(f);
        return;
    }

    size_t len = strlen(count_text);
    if (count_text[len - 1] == '\n')
        count_text[len - 1] = '\0';

    fclose(f);
    nandroid_files_total = atoi(count_text);
    ui_reset_progress();
    ui_show_progress(1, 0);
}
/* show_progress <fraction> <duration>
 *
 * Use <fraction> of the on-screen progress meter for the next operation,
 * automatically advancing the meter over <duration> seconds (or more rapidly
 * if the actual rate of progress can be determined).
 */
static int
cmd_show_progress(const char *name, void *cookie, int argc, const char *argv[])
{
    UNUSED(cookie);
    CHECK_WORDS();

    if (argc != 2) {
        LOGE("Command %s requires exactly two arguments\n", name);
        return 1;
    }

    char *end;
    double fraction = strtod(argv[0], &end);
    if (end[0] != '\0' || argv[0][0] == '\0' || fraction < 0 || fraction > 1) {
        LOGE("Command %s: invalid fraction \"%s\"\n", name, argv[0]);
        return 1;
    }

    int duration = strtoul(argv[1], &end, 0);
    if (end[0] != '\0' || argv[0][0] == '\0') {
        LOGE("Command %s: invalid duration \"%s\"\n", name, argv[1]);
        return 1;
    }

    // Half of the progress bar is taken by verification,
    // so everything that happens during installation is scaled.
    ui_show_progress(fraction * (1 - VERIFICATION_PROGRESS_FRACTION), duration);
    gDidShowProgress = 1;
    return 0;
}
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;
}
示例#4
0
// called only for multi-volume backups to generate stats for progress bar
// file list was gathered from mounted partition: no need to mount before stat line
static void compute_twrp_backup_stats(int index) {
    char tmp[PATH_MAX];
    char line[PATH_MAX];
    struct stat info;
    int total = 0;
    sprintf(tmp, "/tmp/list/filelist%03i", index);
    FILE *fp = fopen(tmp, "rb");
    if (fp != NULL) {
        while (fgets(line, sizeof(line), fp) != NULL) {
            line[strlen(line) - 1] = '\0';
            stat(line, &info);
            if (S_ISDIR(info.st_mode)) {
                compute_directory_stats(line);
                total += nandroid_files_total;
            } else
                total += 1;
        }
        nandroid_files_total = total;
        fclose(fp);
    } else {
        LOGE("Cannot compute backup stats for %s\n", tmp);
        LOGE("No progress will be shown during backup\n");
        nandroid_files_total = 0;
    }

    nandroid_files_count = 0;
    ui_reset_progress();
    ui_show_progress(1, 0);
}
示例#5
0
/**
 * get_menu_selection()
 *
 */
int get_menu_selection(char** headers, char** items, int menu_only,
                       int initial_selection) {
  // throw away keys pressed previously, so user doesn't
  // accidentally trigger menu items.
  ui_clear_key_queue();

  ui_start_menu(headers, items, initial_selection);
  int selected = initial_selection;
  int chosen_item = -1;

  while (chosen_item < 0) {

#ifdef BOARD_WITH_CPCAP
    int level = battery_level();
    if (level > 0) {
      if ((50 * progress_value) != level / 2) {
          progress_value = level / 100.0;
          if (level < 20)
             ui_print("Low battery ! %3d %%\n", level);
          ui_reset_progress();
          ui_show_progress(progress_value, 1);
          ui_set_progress(1.0);
      }
    }
#endif

    int key = ui_wait_key();
    int visible = ui_text_visible();
    int action = device_handle_key(key, visible);

    if (action < 0) {
        switch (action) {
          case HIGHLIGHT_UP:
            --selected;
            selected = ui_menu_select(selected);
            break;
          case HIGHLIGHT_DOWN:
            ++selected;
            selected = ui_menu_select(selected);
            break;
          case SELECT_ITEM:
            chosen_item = selected;
            break;
          case ACTION_CANCEL:
            chosen_item = GO_BACK;
            break;
          case NO_ACTION:
            break;
        }
    } else if (!menu_only) {
      chosen_item = action;
    }
  }

  ui_end_menu();

  return chosen_item;
}
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);
}
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;
    }

    int err;

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

    if (DataManager_GetIntValue(TW_SIGNED_ZIP_VERIFY_VAR)) {
        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);

        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);
}
示例#8
0
static int
lua_ui_show_progress(lua_State *L) {
   int x, y, w, h;

   x = lua_tonumber(L, 2);
   y = lua_tonumber(L, 3);
   w = lua_tonumber(L, 4);
   h = lua_tonumber(L, 5);

   ui_show_progress(x, y, w, h);
   return 0;
}
示例#9
0
static void compute_directory_stats(const char* directory) {
    char tmp[PATH_MAX];
    sprintf(tmp, "find %s | %s wc -l > /tmp/dircount", directory, strcmp(directory, "/data") == 0 && is_data_media() ? "grep -v /data/media |" : "");
    __system(tmp);
    char count_text[100];
    FILE* f = fopen("/tmp/dircount", "r");
    fread(count_text, 1, sizeof(count_text), f);
    fclose(f);
    nandroid_files_count = 0;
    nandroid_files_total = atoi(count_text);
    ui_reset_progress();
    ui_show_progress(1, 0);
}
示例#10
0
static void compute_directory_stats(const char* directory)
{
    char tmp[PATH_MAX];
    sprintf(tmp, "find %s | wc -l > /tmp/dircount", directory);
    __system(tmp);
    char count_text[100];
    FILE* f = fopen("/tmp/dircount", "r");
    fread(count_text, 1, sizeof(count_text), f);
    fclose(f);
    yaffs_files_count = 0;
    yaffs_files_total = atoi(count_text);
    ui_reset_progress();
    ui_show_progress(1, 0);
}
示例#11
0
static void compute_archive_stats(const char* archive_file)
{
    char tmp[PATH_MAX];
    sprintf(tmp, "cat %s* | tar -t | wc -l > /tmp/archivecount", archive_file);

    LOGE("Computing archive stats for %s\n", basename(archive_file));
    __system(tmp);
    char count_text[100];
    FILE* f = fopen("/tmp/archivecount", "r");
    fread(count_text, 1, sizeof(count_text), f);
    fclose(f);
    nandroid_files_count = 0;
    nandroid_files_total = atoi(count_text);
    ui_reset_progress();
    ui_show_progress(1, 0);
}
示例#12
0
static int
handle_update_package(const char *path, ZipArchive *zip)
{
    // Give verification half the progress bar...
    ui_print("Verifying update package...\n");
    ui_show_progress(
            VERIFICATION_PROGRESS_FRACTION,
            VERIFICATION_PROGRESS_TIME);

/*
    if (!verify_jar_signature(zip, keys, numKeys)) {
        LOGE("Verification failed\n");
        return INSTALL_CORRUPT;
    }
*/

    // Update should take the rest of the progress bar.
    ui_print("Installing update...\n");

    int result = try_update_binary(path, zip);
    if (result == INSTALL_SUCCESS || result == INSTALL_ERROR) {
        register_package_root(NULL, NULL);  // Unregister package root
        return result;
    }

    // if INSTALL_CORRUPT is returned, this package doesn't have an
    // update binary.  Fall back to the older mechanism of looking for
    // an update script.

    const ZipEntry *script_entry;
    script_entry = find_update_script(zip);
    if (script_entry == NULL) {
        LOGE("Can't find update script\n");
        return INSTALL_CORRUPT;
    }

    if (register_package_root(zip, path) < 0) {
        LOGE("Can't register package root\n");
        return INSTALL_ERROR;
    }

    int ret = handle_update_script(zip, script_entry);
    register_package_root(NULL, NULL);  // Unregister package root
    return ret;
}
示例#13
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("使用shell脚本...\n");
		return handle_or_update(path, zip);
	}

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

	if (binary_entry == NULL)
		ui_print("使用默认的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("无法制作%s\n", binary);
		  return 1;
		}
  
		bool ok = mzExtractZipEntryToFile(zip, binary_entry, fd);
		close(fd);

		if (!ok) 
		{
	    LOGE("无法复制%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:无法运行%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("忽略试图进行多个固件更新");
        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("未知命令[%s]\n", command);   
  }
  
  fclose(from_child);

  int status;
  waitpid(pid, &status, 0);
  if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) 
  {
    LOGE("错误!代码%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;
  
}
示例#14
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;
}
// If the package contains an update binary, extract it and run it.
static int
try_update_binary(const char *path, ZipArchive *zip) {
    const ZipEntry* binary_entry =
            mzFindZipEntry(zip, ASSUMED_UPDATE_BINARY_NAME);
    if (binary_entry == NULL) {
        const ZipEntry* update_script_entry =
                mzFindZipEntry(zip, ASSUMED_UPDATE_SCRIPT_NAME);
        if (update_script_entry != NULL) {
            ui_print("Amend 脚本 (update-script) 已不支持.\n");
            ui_print("Amend 脚本在 Android 1.5 后不再支持.\n");
            ui_print("请将升级包脚本升级到Edify脚本(updater-script 和 update-binary).\n");
            ui_print("安装已取消.\n");
            return INSTALL_UPDATE_BINARY_MISSING;
        }

        mzCloseZipArchive(zip);
        return INSTALL_UPDATE_BINARY_MISSING;
    }

    char* binary = "/tmp/update_binary";
    unlink(binary);
    int fd = creat(binary, 0755);
    if (fd < 0) {
        mzCloseZipArchive(zip);
        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);
        mzCloseZipArchive(zip);
        return 1;
    }

    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.)
    //
    //            (API v3: this command no longer exists.)
    //
    //        ui_print <string>
    //            display <string> on the screen.
    //
    //   - 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) {
        setenv("UPDATE_PACKAGE", path, 1);
        close(pipefd[0]);
        execv(binary, args);
        fprintf(stdout, "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");
    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 * (1-VERIFICATION_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("%s", 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));
        mzCloseZipArchive(zip);
        return INSTALL_ERROR;
    }

    if (firmware_type != NULL) {
        int ret = handle_firmware_update(firmware_type, firmware_filename, zip);
        mzCloseZipArchive(zip);
        return ret;
    }
    return INSTALL_SUCCESS;
}
示例#16
0
/* write_raw_image <src-image> <dest-root>
 */
static int
cmd_write_raw_image(const char *name, void *cookie,
        int argc, const char *argv[])
{
    UNUSED(cookie);
    CHECK_WORDS();

    if (argc != 2) {
        LOGE("Command %s requires exactly two arguments\n", name);
        return 1;
    }

    // Use 10% of the progress bar (20% post-verification) by default
    const char *src_root_path = argv[0];
    const char *dst_root_path = argv[1];
    ui_print("Writing %s...\n", dst_root_path);
    if (!gDidShowProgress) ui_show_progress(DEFAULT_IMAGE_PROGRESS_FRACTION, 0);

    /* Find the source image, which is probably in a package.
     */
    if (!is_package_root_path(src_root_path)) {
        LOGE("Command %s: non-package source path \"%s\" not yet supported\n",
                name, src_root_path);
        return 255;
    }

    /* Get the package.
     */
    char srcpathbuf[PATH_MAX];
    const char *src_path;
    const ZipArchive *package;
    src_path = translate_package_root_path(src_root_path,
            srcpathbuf, sizeof(srcpathbuf), &package);
    if (src_path == NULL) {
        LOGE("Command %s: bad source path \"%s\"\n", name, src_root_path);
        return 1;
    }

    /* Get the entry.
     */
    const ZipEntry *entry = mzFindZipEntry(package, src_path);
    if (entry == NULL) {
        LOGE("Missing file %s\n", src_path);
        return 1;
    }

    /* Unmount the destination root if it isn't already.
     */
    int ret = ensure_root_path_unmounted(dst_root_path);
    if (ret < 0) {
        LOGE("Can't unmount %s\n", dst_root_path);
        return 1;
    }

    /* Open the partition for writing.
     */
    const MtdPartition *partition = get_root_mtd_partition(dst_root_path);
    if (partition == NULL) {
        LOGE("Can't find %s\n", dst_root_path);
        return 1;
    }
    MtdWriteContext *context = mtd_write_partition(partition);
    if (context == NULL) {
        LOGE("Can't open %s\n", dst_root_path);
        return 1;
    }

    /* Extract and write the image.
     */
    bool ok = mzProcessZipEntryContents(package, entry,
            write_raw_image_process_fn, context);
    if (!ok) {
        LOGE("Error writing %s\n", dst_root_path);
        mtd_write_close(context);
        return 1;
    }

    if (mtd_erase_blocks(context, -1) == (off_t) -1) {
        LOGE("Error finishing %s\n", dst_root_path);
        mtd_write_close(context);
        return -1;
    }

    if (mtd_write_close(context)) {
        LOGE("Error closing %s\n", dst_root_path);
        return -1;
    }
    return 0;
}
示例#17
0
/* copy_dir <src-dir> <dst-dir> [<timestamp>]
 *
 * The contents of <src-dir> will become the contents of <dst-dir>.
 * The original contents of <dst-dir> are preserved unless something
 * in <src-dir> overwrote them.
 *
 * e.g., for "copy_dir PKG:system SYSTEM:", the file "PKG:system/a"
 * would be copied to "SYSTEM:a".
 *
 * The specified timestamp (in decimal seconds since 1970) will be used,
 * or a fixed default timestamp will be supplied otherwise.
 */
static int
cmd_copy_dir(const char *name, void *cookie, int argc, const char *argv[])
{
    UNUSED(name);
    UNUSED(cookie);
    CHECK_WORDS();

    // To create a consistent system image, never use the clock for timestamps.
    struct utimbuf timestamp = { 1217592000, 1217592000 };  // 8/1/2008 default
    if (argc == 3) {
        char *end;
        time_t value = strtoul(argv[2], &end, 0);
        if (value == 0 || end[0] != '\0') {
            LOGE("Command %s: invalid timestamp \"%s\"\n", name, argv[2]);
            return 1;
        } else if (value < timestamp.modtime) {
            LOGE("Command %s: timestamp \"%s\" too early\n", name, argv[2]);
            return 1;
        }
        timestamp.modtime = timestamp.actime = value;
    } else if (argc != 2) {
        LOGE("Command %s requires exactly two arguments\n", name);
        return 1;
    }

    // Use 40% of the progress bar (80% post-verification) by default
    ui_print("Copying files...\n");
    if (!gDidShowProgress) ui_show_progress(DEFAULT_FILES_PROGRESS_FRACTION, 0);

    /* Mount the destination volume if it isn't already.
     */
    const char *dst_root_path = argv[1];
    int ret = ensure_root_path_mounted(dst_root_path);
    if (ret < 0) {
        LOGE("Can't mount %s\n", dst_root_path);
        return 1;
    }

    /* Get the real target path.
     */
    char dstpathbuf[PATH_MAX];
    const char *dst_path;
    dst_path = translate_root_path(dst_root_path,
            dstpathbuf, sizeof(dstpathbuf));
    if (dst_path == NULL) {
        LOGE("Command %s: bad destination path \"%s\"\n", name, dst_root_path);
        return 1;
    }

    /* Try to copy the directory.  The source may be inside a package.
     */
    const char *src_root_path = argv[0];
    char srcpathbuf[PATH_MAX];
    const char *src_path;
    if (is_package_root_path(src_root_path)) {
        const ZipArchive *package;
        src_path = translate_package_root_path(src_root_path,
                srcpathbuf, sizeof(srcpathbuf), &package);
        if (src_path == NULL) {
            LOGE("Command %s: bad source path \"%s\"\n", name, src_root_path);
            return 1;
        }

        /* Extract the files.  Set MZ_EXTRACT_FILES_ONLY, because only files
         * are validated by the signature.  Do a dry run first to count how
         * many there are (and find some errors early).
         */
        ExtractContext ctx;
        ctx.num_done = 0;
        ctx.num_total = 0;

        if (!mzExtractRecursive(package, src_path, dst_path,
                    MZ_EXTRACT_FILES_ONLY | MZ_EXTRACT_DRY_RUN,
                    &timestamp, extract_count_cb, (void *) &ctx) ||
            !mzExtractRecursive(package, src_path, dst_path,
                    MZ_EXTRACT_FILES_ONLY,
                    &timestamp, extract_cb, (void *) &ctx)) {
            LOGW("Command %s: couldn't extract \"%s\" to \"%s\"\n",
                    name, src_root_path, dst_root_path);
            return 1;
        }
    } else {
        LOGE("Command %s: non-package source path \"%s\" not yet supported\n",
                name, src_root_path);
//xxx mount the src volume
//xxx
        return 255;
    }

    return 0;
}
示例#18
0
int phx_do_backup(const char* enableVar, struct dInfo* mnt, const char* image_dir, unsigned long long img_bytes, unsigned long long file_bytes, unsigned long long* img_bytes_remaining, unsigned long long* file_bytes_remaining, unsigned long* img_byte_time, unsigned long* file_byte_time)
{
    // Check if this partition is being backed up...
    if (!DataManager_GetIntValue(enableVar))    return 0;

    // Let's calculate the percentage of the bar this section is expected to take
    unsigned long int img_bps = DataManager_GetIntValue(VAR_BACKUP_AVG_IMG_RATE);
    unsigned long int file_bps;

    if (DataManager_GetIntValue(VAR_USE_COMPRESSION_VAR))    file_bps = DataManager_GetIntValue(VAR_BACKUP_AVG_FILE_COMP_RATE);
    else                                                    file_bps = DataManager_GetIntValue(VAR_BACKUP_AVG_FILE_RATE);

    if (DataManager_GetIntValue(VAR_SKIP_MD5_GENERATE_VAR) == 1)
    {
        // If we're skipping MD5 generation, our BPS is faster by about 1.65
        file_bps = (unsigned long) (file_bps * 1.65);
        img_bps = (unsigned long) (img_bps * 1.65);
    }

    // We know the speed for both, how far into the whole backup are we, based on time
    unsigned long total_time = (img_bytes / img_bps) + (file_bytes / file_bps);
    unsigned long remain_time = (*img_bytes_remaining / img_bps) + (*file_bytes_remaining / file_bps);

    float pos = (total_time - remain_time) / (float) total_time;
    ui_set_progress(pos);

    LOGI("Estimated Total time: %lu  Estimated remaining time: %lu\n", total_time, remain_time);

    // Determine how much we're about to process
    unsigned long long blocksize = get_backup_size(mnt);

    // And get the time
    unsigned long section_time;
    if (mnt->backup == image)       section_time = blocksize / img_bps;
    else                            section_time = blocksize / file_bps;

    // Set the position
    pos = section_time / (float) total_time;
    ui_show_progress(pos, section_time);

    time_t start, stop;
    time(&start);

    if (phx_backup(*mnt, image_dir) == 1) { // did the backup process return an error ? 0 = no error
        SetDataState("Backup failed", mnt->mnt, 1, 1);
        ui_print("-- Error occured, check recovery.log. Aborting.\n"); //oh noes! abort abort!
        return 1;
    }
    time(&stop);

    LOGI("Partition Backup time: %d\n", (int) difftime(stop, start));

    // Now, decrement out byte counts
    if (mnt->backup == image)
    {
        *img_bytes_remaining -= blocksize;
        *img_byte_time += (int) difftime(stop, start);
    }
    else
    {
        *file_bytes_remaining -= blocksize;
        *file_byte_time += (int) difftime(stop, start);
    }

    return 0;
}
int tw_restore(struct dInfo rMnt, char *rDir)
{
	int i;
	FILE *reFp;
	char rUppr[20];
	char rMount[30];
	char rFilesystem[10];
	char rFilename[255];
	char rCommand[255];
	char rOutput[255];
	time_t rStart, rStop;
	strcpy(rUppr,rMnt.mnt);
	for (i = 0; i < strlen(rUppr); i++) {
		rUppr[i] = toupper(rUppr[i]);
	}
	ui_print("[%s]\n",rUppr);
	ui_show_progress(1,150);
	time(&rStart);
	ui_print("...Verifying md5 hash for %s.\n",rMnt.mnt);
	if(checkMD5(rDir,rMnt.fnm) == 0) // verify md5, check if no error; 0 = no error.
	{
		strcpy(rFilename,rDir);
		strcat(rFilename,rMnt.fnm);
		sprintf(rCommand,"ls -l %s | awk -F'.' '{ print $2 }'",rFilename); // let's get the filesystem type from filename
		reFp = __popen(rCommand, "r");
		LOGI("=> Filename is: %s\n",rMnt.fnm);
		while (fscanf(reFp,"%s",rFilesystem) == 1) { // if we get a match, store filesystem type
			LOGI("=> Filesystem is: %s\n",rFilesystem); // show it off to the world!
		}
		__pclose(reFp);
		if (DataManager_GetIntValue(TW_RM_RF_VAR) == 1 && (strcmp(rMnt.mnt,"system") == 0 || strcmp(rMnt.mnt,"data") == 0 || strcmp(rMnt.mnt,"cache") == 0)) { // we'll use rm -rf instead of formatting for system, data and cache if the option is set
			ui_print("...using rm -rf to wipe %s\n", rMnt.mnt);
			tw_mount(rMnt); // mount the partition first
			sprintf(rCommand,"rm -rf %s%s/*", "/", rMnt.mnt);
			LOGI("rm rf commad: %s\n", rCommand);
			reFp = __popen(rCommand, "r");
			while (fscanf(reFp,"%s",rOutput) == 1) {
				ui_print_overwrite("%s",rOutput);
			}
			__pclose(reFp);
		} else {
			ui_print("...Formatting %s\n",rMnt.mnt);
			tw_format(rFilesystem,rMnt.blk); // let's format block, based on filesystem from filename above
		}
		ui_print("....Done.\n");
		if (strcmp(rFilesystem,"mtd") == 0) { // if filesystem is mtd, we use flash image
			sprintf(rCommand,"flash_image %s %s",rMnt.mnt,rFilename);
			strcpy(rMount,rMnt.mnt);
		} else if (strcmp(rFilesystem,"emmc") == 0) { // if filesystem is emmc, we use dd
			sprintf(rCommand,"dd bs=%s if=%s of=%s",bs_size,rFilename,rMnt.dev);
			strcpy(rMount,rMnt.mnt);
		} else {
			tw_mount(rMnt);
			strcpy(rMount,"/");
			if (strcmp(rMnt.mnt,".android_secure") == 0) { // if it's android_secure, we have add prefix
				strcat(rMount,"sdcard/");
			}
			strcat(rMount,rMnt.mnt);
			sprintf(rCommand,"cd %s && tar -xvf %s",rMount,rFilename); // formulate shell command to restore
		}
		ui_print("...Restoring %s\n",rMount);
		reFp = __popen(rCommand, "r");
		if(DataManager_GetIntValue(TW_SHOW_SPAM_VAR) == 2) { // twrp spam
			while (fgets(rOutput,sizeof(rOutput),reFp) != NULL) {
				ui_print_overwrite("%s",rOutput);
			}
		} else {
			while (fscanf(reFp,"%s",rOutput) == 1) {
				if(DataManager_GetIntValue(TW_SHOW_SPAM_VAR) == 1) ui_print_overwrite("%s",rOutput);
			}
		}
		__pclose(reFp);
		ui_print_overwrite("....Done.\n");
		if (strcmp(rMnt.mnt,".android_secure") != 0) { // any partition other than android secure,
			tw_unmount(rMnt); // let's unmount (unmountable partitions won't matter)
		}
	} else {
		ui_print("...Failed md5 check. Aborted.\n\n");
		return 1;
	}
	ui_reset_progress();
	time(&rStop);
	output_time(rUppr, "DONE", (int)difftime(rStop,rStart));
	return 0;
}
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;
}
示例#21
0
int
nandroid_rest_exe()
{
    SetDataState("", "", 0, 0);

    const char* nan_dir = DataManager_GetStrValue("phx_restore");

    if (ensure_path_mounted(SDCARD_ROOT) != 0) {
        ui_print("-- Could not mount: %s.\n-- Aborting.\n",SDCARD_ROOT);
        return 1;
    }

    int total = 0;
    total += (DataManager_GetIntValue(VAR_RESTORE_SYSTEM_VAR) == 1 ? 1 : 0);
    total += (DataManager_GetIntValue(VAR_RESTORE_DATA_VAR) == 1 ? 1 : 0);
    total += (DataManager_GetIntValue(VAR_RESTORE_CACHE_VAR) == 1 ? 1 : 0);
    total += (DataManager_GetIntValue(VAR_RESTORE_RECOVERY_VAR) == 1 ? 1 : 0);
    total += (DataManager_GetIntValue(VAR_RESTORE_SP1_VAR) == 1 ? 1 : 0);
    total += (DataManager_GetIntValue(VAR_RESTORE_SP2_VAR) == 1 ? 1 : 0);
    total += (DataManager_GetIntValue(VAR_RESTORE_SP3_VAR) == 1 ? 1 : 0);
    total += (DataManager_GetIntValue(VAR_RESTORE_BOOT_VAR) == 1 ? 1 : 0);
    total += (DataManager_GetIntValue(VAR_RESTORE_ANDSEC_VAR) == 1 ? 1 : 0);
    total += (DataManager_GetIntValue(VAR_RESTORE_SDEXT_VAR) == 1 ? 1 : 0);

    float sections = 1.0 / total;

    time_t rStart, rStop;
    time(&rStart);
    ui_print("\n[RESTORE STARTED]\n\n");
    if (DataManager_GetIntValue(VAR_RESTORE_SYSTEM_VAR) == 1) {
        ui_show_progress(sections, 150);
        if (phx_restore(sys,nan_dir) == 1) {
            ui_print("-- Error occured, check recovery.log. Aborting.\n");
            SetDataState("Restore failed", "", 1, 1);
            return 1;
        }
    }
    if (DataManager_GetIntValue(VAR_RESTORE_DATA_VAR) == 1) {
        ui_show_progress(sections, 150);
        if (phx_restore(dat,nan_dir) == 1) {
            ui_print("-- Error occured, check recovery.log. Aborting.\n");
            SetDataState("Restore failed", "", 1, 1);
            return 1;
        }
    }
    if (DataManager_GetIntValue(VAR_RESTORE_BOOT_VAR) == 1) {
        ui_show_progress(sections, 150);
        if (phx_restore(boo,nan_dir) == 1) {
            ui_print("-- Error occured, check recovery.log. Aborting.\n");
            SetDataState("Restore failed", "", 1, 1);
            return 1;
        }
    }
    if (DataManager_GetIntValue(VAR_RESTORE_RECOVERY_VAR) == 1) {
        ui_show_progress(sections, 150);
        if (phx_restore(rec,nan_dir) == 1) {
            ui_print("-- Error occured, check recovery.log. Aborting.\n");
            SetDataState("Restore failed", "", 1, 1);
            return 1;
        }
    }
    if (DataManager_GetIntValue(VAR_RESTORE_CACHE_VAR) == 1) {
        ui_show_progress(sections, 150);
        if (phx_restore(cac,nan_dir) == 1) {
            ui_print("-- Error occured, check recovery.log. Aborting.\n");
            SetDataState("Restore failed", "", 1, 1);
            return 1;
        }
    }
    if (DataManager_GetIntValue(VAR_RESTORE_SP1_VAR) == 1) {
        ui_show_progress(sections, 150);
        if (phx_restore(sp1,nan_dir) == 1) {
            ui_print("-- Error occured, check recovery.log. Aborting.\n");
            SetDataState("Restore failed", "", 1, 1);
            return 1;
        }
    }
    if (DataManager_GetIntValue(VAR_RESTORE_SP2_VAR) == 1) {
        ui_show_progress(sections, 150);
        if (phx_restore(sp2,nan_dir) == 1) {
            ui_print("-- Error occured, check recovery.log. Aborting.\n");
            SetDataState("Restore failed", "", 1, 1);
            return 1;
        }
    }
    if (DataManager_GetIntValue(VAR_RESTORE_SP3_VAR) == 1) {
        ui_show_progress(sections, 150);
        if (phx_restore(sp3,nan_dir) == 1) {
            ui_print("-- Error occured, check recovery.log. Aborting.\n");
            SetDataState("Restore failed", "", 1, 1);
            return 1;
        }
    }
    if (DataManager_GetIntValue(VAR_RESTORE_ANDSEC_VAR) == 1) {
        ui_show_progress(sections, 150);
        if (phx_restore(ase,nan_dir) == 1) {
            ui_print("-- Error occured, check recovery.log. Aborting.\n");
            SetDataState("Restore failed", "", 1, 1);
            return 1;
        }
    }
    if (DataManager_GetIntValue(VAR_RESTORE_SDEXT_VAR) == 1) {
        ui_show_progress(sections, 150);
        if (phx_restore(sde,nan_dir) == 1) {
            ui_print("-- Error occured, check recovery.log. Aborting.\n");
            SetDataState("Restore failed", "", 1, 1);
            return 1;
        }
    }
    time(&rStop);
    ui_print("[RESTORE COMPLETED IN %d SECONDS]\n\n",(int)difftime(rStop,rStart));
    __system("sync");
    LOGI("=> Let's update filesystem types.\n");
    verifyFst();
    LOGI("=> And update our fstab also.\n");
    createFstab();
    SetDataState("Restore Succeeded", "", 0, 1);
    return 0;
}
/* New backup function
** Condensed all partitions into one function
*/
int tw_backup(struct dInfo bMnt, char *bDir)
{
	if (ensure_path_mounted(SDCARD_ROOT) != 0) {
		ui_print("-- Could not mount: %s.\n-- Aborting.\n",SDCARD_ROOT);
		return 1;
	}
	int bDiv;
	char bTarArg[10];
	if (DataManager_GetIntValue(TW_USE_COMPRESSION_VAR)) { // set compression or not
		strcpy(bTarArg,"-czvf");
		bDiv = 512;
	} else {
		strcpy(bTarArg,"-cvf");
		bDiv = 2048;
	}
	FILE *bFp;
	int bPartSize;
	char *bImage = malloc(sizeof(char)*50);
	char *bMount = malloc(sizeof(char)*50);
	char *bCommand = malloc(sizeof(char)*255);
	if (strcmp(bMnt.mnt,"system") == 0 || strcmp(bMnt.mnt,"data") == 0 || 
			strcmp(bMnt.mnt,"cache") == 0 || strcmp(bMnt.mnt,"sd-ext") == 0 || 
			strcmp(bMnt.mnt,"efs") == 0 || strcmp(bMnt.mnt,".android_secure") == 0) { // detect mountable partitions
		if (strcmp(bMnt.mnt,".android_secure") == 0) { // if it's android secure, add sdcard to prefix
			strcpy(bMount,"/sdcard/");
			strcat(bMount,bMnt.mnt);
			sprintf(bImage,"and-sec.%s.win",bMnt.fst); // set image name based on filesystem, should always be vfat for android_secure
		} else {
			strcpy(bMount,"/");
			strcat(bMount,bMnt.mnt);
			sprintf(bImage,"%s.%s.win",bMnt.mnt,bMnt.fst); // anything else that is mountable, will be partition.filesystem.win
			ui_print("\n-- Mounting %s, please wait...\n",bMount);
			if (tw_mount(bMnt)) {
				ui_print("-- Could not mount: %s\n-- Aborting.\n",bMount);
				free(bCommand);
				free(bMount);
				free(bImage);
				return 1;
			}
			ui_print("-- Done.\n\n",bMount);
		}
		sprintf(bCommand,"du -sk %s | awk '{ print $1 }'",bMount); // check for partition/folder size
		bFp = __popen(bCommand, "r");
		fscanf(bFp,"%d",&bPartSize);
		__pclose(bFp);
		sprintf(bCommand,"cd %s && tar %s %s%s ./*",bMount,bTarArg,bDir,bImage); // form backup command
	} else {
		strcpy(bMount,bMnt.mnt);
		bPartSize = bMnt.sze / 1024;
		sprintf(bImage,"%s.%s.win",bMnt.mnt,bMnt.fst); // non-mountable partitions such as boot/wimax/recovery
		if (strcmp(bMnt.fst,"mtd") == 0) {
			sprintf(bCommand,"dump_image %s %s%s",bMnt.mnt,bDir,bImage); // if it's mtd, we use dump image
		} else if (strcmp(bMnt.fst,"emmc") == 0) {
			sprintf(bCommand,"dd bs=%s if=%s of=%s%s",bs_size,bMnt.blk,bDir,bImage); // if it's emmc, use dd
		}
		ui_print("\n");
	}
	LOGI("=> Filename: %s\n",bImage);
	LOGI("=> Size of %s is %d KB.\n\n",bMount,bPartSize);
	int i;
	char bUppr[20];
	strcpy(bUppr,bMnt.mnt);
	for (i = 0; i < strlen(bUppr); i++) { // make uppercase of mount name
		bUppr[i] = toupper(bUppr[i]);
	}
	ui_print("[%s (%d MB)]\n",bUppr,bPartSize/1024); // show size in MB
	int bProgTime;
	time_t bStart, bStop;
	char bOutput[512];
	if (sdSpace > bPartSize) { // Do we have enough space on sdcard?
		time(&bStart); // start timer
		bProgTime = bPartSize / bDiv; // not very accurate but better than nothing progress time for progress bar
		ui_show_progress(1,bProgTime);
		ui_print("...Backing up %s partition.\n",bMount);
		bFp = __popen(bCommand, "r"); // sending backup command formed earlier above
		if(DataManager_GetIntValue(TW_SHOW_SPAM_VAR) == 2) { // if twrp spam is on, show all lines
			while (fgets(bOutput,sizeof(bOutput),bFp) != NULL) {
				ui_print_overwrite("%s",bOutput);
			}
		} else { // else just show single line
			while (fscanf(bFp,"%s",bOutput) == 1) {
				if(DataManager_GetIntValue(TW_SHOW_SPAM_VAR) == 1) ui_print_overwrite("%s",bOutput);
			}
		}
		ui_print_overwrite("....Done.\n");
		__pclose(bFp);
		int pFileSize;
		ui_print("...Double checking backup file size.\n");
		sprintf(bCommand,"ls -l %s%s | awk '{ print $5 }'",bDir,bImage); // double checking to make sure we backed up something
		bFp = __popen(bCommand, "r");
		fscanf(bFp,"%d",&pFileSize);
		__pclose(bFp);
		ui_print("....File size: %d bytes.\n",pFileSize); // file size
		if (pFileSize > 0) { // larger than 0 bytes?
			if (strcmp(bMnt.fst,"mtd") == 0 || strcmp(bMnt.fst,"emmc") == 0) { // if it's an unmountable partition, we can make sure
				LOGI("=> Expected size: %d Got: %d\n",bMnt.sze,pFileSize); // partition size matches file image size (they should match!)
				if (pFileSize != bMnt.sze) {
					ui_print("....File size is incorrect. Aborting...\n\n"); // they dont :(
					free(bCommand);
					free(bMount);
					free(bImage);
					return 1;
				} else {
					ui_print("....File size matches partition size.\n"); // they do, yay!
				}
			}
			ui_print("...Generating %s md5...\n", bMnt.mnt);
			makeMD5(bDir,bImage); // make md5 file
			ui_print("....Done.\n");
			ui_print("...Verifying %s md5...\n", bMnt.mnt);
			checkMD5(bDir,bImage); // test the md5 we just made, just in case
			ui_print("....Done.\n");
			time(&bStop); // stop timer
			ui_reset_progress(); // stop progress bar
			output_time(bUppr, "DONE", (int)difftime(bStop,bStart));
			tw_unmount(bMnt); // unmount partition we just restored to (if it's not a mountable partition, it will just bypass)
			sdSpace -= bPartSize; // minus from sd space number (not accurate but, it's more than the real count so it will suffice)
		} else {
			ui_print("...File size is zero bytes. Aborting...\n\n"); // oh noes! file size is 0, abort! abort!
			tw_unmount(bMnt);
			free(bCommand);
			free(bMount);
			free(bImage);
			return 1;
		}
	} else {
		ui_print("...Not enough space on /sdcard. Aborting.\n"); // oh noes! no space left on sdcard, abort! abort!
		tw_unmount(bMnt);
		free(bCommand);
		free(bMount);
		free(bImage);
		return 1;
	}
	free(bCommand);
	free(bMount);
	free(bImage);
	return 0;
}
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;
}
示例#24
0
// If the package contains an update binary, extract it and run it.
static int
try_update_binary(const char *path, ZipArchive *zip, int* wipe_cache) {
    const ZipEntry* binary_entry =
            mzFindZipEntry(zip, ASSUMED_UPDATE_BINARY_NAME);
    if (binary_entry == NULL) {
        mzCloseZipArchive(zip);
        return INSTALL_CORRUPT;
    }

    const char* binary = "/tmp/update_binary";
    unlink(binary);
    int fd = creat(binary, 0755);
    if (fd < 0) {
        mzCloseZipArchive(zip);
        LOGE("Can't make %s\n", binary);
        return INSTALL_ERROR;
    }
    bool ok = mzExtractZipEntryToFile(zip, binary_entry, fd);
    close(fd);
    mzCloseZipArchive(zip);

    if (!ok) {
        LOGE("Can't copy %s\n", ASSUMED_UPDATE_BINARY_NAME);
        return INSTALL_ERROR;
    }

    /* Make sure the update binary is compatible with this recovery
     *
     * We're building this against 4.4's (or above) bionic, which
     * has a different property namespace structure. If "set_perm_"
     * is found, it's probably a regular updater instead of a custom
     * one. If "set_metadata_" isn't there, it's pre-4.4, which
     * makes it incompatible.
     *
     * Also, I hate matching strings in binary blobs */

    FILE *updaterfile = fopen(binary, "rb");
    char tmpbuf;
    char setpermmatch[9] = { 's','e','t','_','p','e','r','m','_' };
    char setmetamatch[13] = { 's','e','t','_','m','e','t','a','d','a','t','a','_' };
    size_t pos = 0;
    bool foundsetperm = false;
    bool foundsetmeta = false;

    if (updaterfile == NULL) {
        LOGE("Can't find %s for validation\n", ASSUMED_UPDATE_BINARY_NAME);
        return INSTALL_ERROR;
    }
    fseek(updaterfile, 0, SEEK_SET);
    while (!feof(updaterfile)) {
        fread(&tmpbuf, 1, 1, updaterfile);
        if (!foundsetperm && pos < sizeof(setpermmatch) && tmpbuf == setpermmatch[pos]) {
            pos++;
            if (pos == sizeof(setpermmatch)) {
                foundsetperm = true;
                pos = 0;
            }
            continue;
        }
        if (!foundsetmeta && tmpbuf == setmetamatch[pos]) {
            pos++;
            if (pos == sizeof(setmetamatch)) {
                foundsetmeta = true;
                pos = 0;
            }
            continue;
        }
        /* None of the match loops got a continuation, reset the counter */
        pos = 0;
    }
    fclose(updaterfile);

    /* Set legacy properties */
    if (foundsetperm && !foundsetmeta) {
        ui_print("Using legacy property environment for update-binary...\n");
        ui_print("Please upgrade to latest binary...\n");
        if (set_legacy_props() != 0) {
            LOGE("Legacy property environment did not init successfully. Properties may not be detected.\n");
        } else {
            LOGI("Legacy property environment initialized.\n");
        }
    }

    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.)
    //
    //            (API v3: this command no longer exists.)
    //
    //        ui_print <string>
    //            display <string> on the screen.
    //
    //   - the name of the package zip file.
    //

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

    pid_t pid = fork();
    if (pid == 0) {
        // set the env for UPDATE_PACKAGE (the source zip) for update-binary. This allows shell scripts to use the source zip.
		// https://github.com/CyanogenMod/android_bootable_recovery/commit/20b516a408adebcad06e03f12516e70b8998c38f
        setenv("UPDATE_PACKAGE", path, 1);
        close(pipefd[0]);
        execve(binary, (char* const*)args, environ);
        fprintf(stdout, "E:Can't run %s (%s)\n", binary, strerror(errno));
        _exit(-1);
    }
    close(pipefd[1]);

    *wipe_cache = 0;

    char buffer[1024];
    FILE* from_child = fdopen(pipefd[0], "r");
    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 * (1-VERIFICATION_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, "ui_print") == 0) {
            char* str = strtok(NULL, "\n");
            if (str) {
                ui_print("%s", str);
            } else {
                ui_print("\n");
            }
            fflush(stdout);
        } else if (strcmp(command, "wipe_cache") == 0) {
            *wipe_cache = 1;
        } else if (strcmp(command, "clear_display") == 0) {
            // not needed in PhilZ Touch;
        } else {
            LOGE("unknown command [%s]\n", command);
        }
    }
    fclose(from_child);

    int status;
    waitpid(pid, &status, 0);

    /* Unset legacy properties */
    if (legacy_props_path_modified) {
        if (unset_legacy_props() != 0) {
            LOGE("Legacy property environment did not disable successfully. Legacy properties may still be in use.\n");
        } else {
            LOGI("Legacy property environment disabled.\n");
        }
    }

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

    return INSTALL_SUCCESS;
}
示例#25
0
// If the package contains an update binary, extract it and run it.
static int
try_update_binary(const char *path, ZipArchive *zip, int* wipe_cache) {
    const ZipEntry* binary_entry =
            mzFindZipEntry(zip, ASSUMED_UPDATE_BINARY_NAME);
    if (binary_entry == NULL) {
        mzCloseZipArchive(zip);
        return INSTALL_CORRUPT;
    }
    fprintf(stderr, "try_update_binary(path(%s))\n",path);

    radio_diff = mzFindZipEntry(zip, RADIO_DIFF_NAME);

    if (radio_diff == NULL) {
        fprintf(stderr, "%s not found\n", RADIO_DIFF_NAME);
    }
    else
    {
        char* diff_file = RADIO_DIFF_OUTPUT;
        int fd_diff = creat(diff_file, 0777);

        fprintf(stderr, "%s found\n", RADIO_DIFF_NAME);

        if (fd_diff < 0) {
            fprintf(stderr, "Can't make %s\n", diff_file);
        }
        else
        {
            bool ok_diff = mzExtractZipEntryToFile(zip, radio_diff, fd_diff);
            close(fd_diff);

            if (!ok_diff) {
                fprintf(stderr, "Can't copy %s\n", RADIO_DIFF_NAME);
            }
        }
    }

    char* binary = "/tmp/update_binary";
    unlink(binary);
    int fd = creat(binary, 0755);
    if (fd < 0) {
        mzCloseZipArchive(zip);
        LOGE("Can't make %s\n", binary);
        return INSTALL_ERROR;
    }
    bool ok = mzExtractZipEntryToFile(zip, binary_entry, fd);
    close(fd);
    mzCloseZipArchive(zip);

    if (!ok) {
        LOGE("Can't copy %s\n", ASSUMED_UPDATE_BINARY_NAME);
        return INSTALL_ERROR;
    }

    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.)
    //
    //            (API v3: this command no longer exists.)
    //
    //        ui_print <string>
    //            display <string> on the screen.
    //
    //   - 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(stdout, "E:Can't run %s (%s)\n", binary, strerror(errno));
        _exit(-1);
    }
    close(pipefd[1]);

    *wipe_cache = 0;

    char buffer[1024];
    FILE* from_child = fdopen(pipefd[0], "r");
    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 * (1-VERIFICATION_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, "ui_print") == 0) {
            char* str = strtok(NULL, "\n");
            if (str) {
                ui_print("%s", str);
            } else {
                ui_print("\n");
            }
        } else if (strcmp(command, "wipe_cache") == 0) {
            *wipe_cache = 1;
        } 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;
    }

    return INSTALL_SUCCESS;
}
示例#26
0
void 
nandroid_back_exe()
{
	ensure_path_mounted(SDCARD_ROOT);
	FILE *fp;
	int isContinue = 1;
	int progTime;
	unsigned long sdSpace;
	unsigned long sdSpaceFinal;
	unsigned long imgSpace;
	char tmpOutput[150];
	char tmpString[15];
	char tmpChar;
	char exe[255];
	char tw_image_base[100];
	char tw_image[255];
    char timestamp[14];
    char tar_arg[5];
	struct stat st;
    struct tm * t;
    time_t seconds;
    time_t nan_ttime;
    time_t nan_ctime;
    seconds = time(0);
    t = localtime(&seconds);
    sprintf(timestamp,"%02d%02d%d%02d%02d",t->tm_mon+1,t->tm_mday,t->tm_year+1900,t->tm_hour,t->tm_min); // get timestamp for nandroid
	if (stat(backup_folder,&st) != 0) {
		if(mkdir(backup_folder,0777) == -1) {
			LOGI("=> Can not create directory: %s\n", backup_folder);
		} else {
			LOGI("=> Created directory: %s\n", backup_folder);
		}
	}
	sprintf(tw_image_base, "%s/%s/", backup_folder, device_id);
	if (stat(tw_image_base,&st) != 0) {
		if(mkdir(tw_image_base,0777) == -1) {
			LOGI("=> Can not create directory: %s\n", tw_image_base);
		} else {
			LOGI("=> Created directory: %s\n", tw_image_base);
		}
	}
	strcat(tw_image_base,timestamp);
	strcat(tw_image_base,"/");
	if(mkdir(tw_image_base,0777) == -1) {
		LOGI("=> Can not create directory: %s\n", tw_image_base);
	} else {
		LOGI("=> Created directory: %s\n", tw_image_base);
	}
	
	fp = __popen("df -k /sdcard| grep sdcard | awk '{ print $4 }'", "r");
	LOGI("=> Checking SDCARD Disk Space.\n");
	while (fgets(tmpString,15,fp) != NULL)
	{
		tmpChar = tmpString[strlen(tmpString)-2];
	}
	__pclose(fp);
	if(tmpChar == '%')
	{
		fp = __popen("df -k /sdcard| grep sdcard | awk '{ print $3 }'", "r");
		LOGI("=> Not the response we were looking for, trying again.\n");
		fgets(tmpString,15,fp);
		__pclose(fp);
	}
	sscanf(tmpString,"%lu",&sdSpace);
	sdSpaceFinal = sdSpace;
	LOGI("=> Space Left on SDCARD: %lu\n\n",sdSpaceFinal);
	
	int div;
	if (is_true(tw_use_compression_val) == 1) {
		strcpy(tar_arg,"czvpf");
		div = 500;
	} else {
		strcpy(tar_arg,"cvpf");
		div = 1000;
	}
	
	ui_print("\nStarting Backup...\n\n");
	nan_ttime = time(0);
	if (is_true(tw_nan_system_val)) {
		ensure_path_mounted("/system");
		fp = __popen("du -sk /system", "r");
		LOGI("=> Checking size of /system.\n");
	    fscanf(fp,"%lu %*s",&imgSpace);
		progTime = imgSpace / div;
		ui_print("[SYSTEM (%d MB)]\n",imgSpace/1024);
		__pclose(fp);
		if (sdSpace > imgSpace)
		{
			nan_ctime = time(0);
			strcpy(tw_image,tw_image_base);
			strcat(tw_image,tw_nan_system);
			sprintf(exe,"cd /%s && tar -%s %s ./*", sys.mnt, tar_arg, tw_image);
			ui_print("...Backing up system partition.\n");
			ui_show_progress(1,progTime);
			fp = __popen(exe, "r");
			while (fscanf(fp,"%s",tmpOutput) != EOF)
			{
				if(is_true(tw_show_spam_val))
				{
					ui_print("%s\n",tmpOutput);
				} else {
					ui_print_overwrite("%s",tmpOutput);
				}
			}
			ui_print_overwrite("....Done.\n");
			__pclose(fp);
			ui_print("...Generating %s md5...\n", sys.mnt);
			makeMD5(tw_image_base,tw_nan_system);
			ui_print("....Done.\n");
			ui_print("...Verifying %s md5...\n", sys.mnt);
			checkMD5(tw_image_base,tw_nan_system);
			ui_print("...Done.\n");
			ui_reset_progress();
			ui_print("Backed up in %d Seconds\n\n", time(0) - nan_ctime);
		} else {
			ui_print("\nNot enough space left on /sdcard... Aborting.\n\n");
			isContinue = 0;
		}
		ensure_path_unmounted("/system");
		sdSpace -= imgSpace;
	}
	if (isContinue)
	{
		if (is_true(tw_nan_data_val)) {
			ensure_path_mounted("/data");
			fp = __popen("du -sk /data", "r");
			LOGI("=> Checking size of /data.\n");
		    fscanf(fp,"%lu %*s",&imgSpace);
			progTime = imgSpace / div;
			ui_print("[DATA (%d MB)]\n",imgSpace/1024);
			__pclose(fp);
			if (sdSpace > imgSpace)
			{
				nan_ctime = time(0);
				strcpy(tw_image,tw_image_base);
				strcat(tw_image,tw_nan_data);
				sprintf(exe,"cd /%s && tar -%s %s ./*", dat.mnt, tar_arg, tw_image);
				ui_print("...Backing up data partition.\n");
				ui_show_progress(1,progTime);
				fp = __popen(exe, "r");
				while (fscanf(fp,"%s",tmpOutput) != EOF)
				{
					if(is_true(tw_show_spam_val))
					{
						ui_print("%s\n",tmpOutput);
					} else {
						ui_print_overwrite("%s",tmpOutput);
					}
				}
				ui_print_overwrite("....Done.\n");
				__pclose(fp);
				ui_print("...Generating %s md5...\n", dat.mnt);
				makeMD5(tw_image_base,tw_nan_data);
				ui_print("....Done.\n");
				ui_print("...Verifying %s md5...\n", dat.mnt);
				checkMD5(tw_image_base,tw_nan_data);
				ui_print("...Done.\n");
				ui_reset_progress();
				ui_print("Backed up in %d Seconds\n\n", time(0) - nan_ctime);
			} else {
				ui_print("\nNot enough space left on /sdcard... Aborting.\n\n");
				isContinue = 0;
			}
			ensure_path_unmounted("/data");
			sdSpace -= imgSpace;
		}
	}
	if (isContinue)
	{
		if (is_true(tw_nan_boot_val)) {
			imgSpace = boo.sze / 1024;
			ui_print("[BOOT (%i MB)]\n",imgSpace/1024);
			if (sdSpace > imgSpace)
			{
				nan_ctime = time(0);
				strcpy(tw_image,tw_image_base);
				strcat(tw_image,tw_nan_boot);
				if (strcmp(boo.fst,"mtd") == 0)
				{
					sprintf(exe,"dump_image %s %s", boo.mnt, tw_image);
				} else {
					sprintf(exe,"dd bs=%s if=%s of=%s", bs_size, boo.dev, tw_image);
				}
				ui_print("...Backing up boot partition.\n");
				ui_show_progress(1,5);
				__system(exe);
				LOGI("=> %s\n", exe);
				ui_print("....Done.\n");
				ui_print("...Generating %s md5...\n", boo.mnt);
				makeMD5(tw_image_base,tw_nan_boot);
				ui_print("....Done.\n");
				ui_print("...Verifying %s md5...\n", boo.mnt);
				checkMD5(tw_image_base,tw_nan_boot);
				ui_print("...Done.\n");
				ui_reset_progress();
				ui_print("Backed up in %d Seconds\n\n", time(0) - nan_ctime);
			} else {
				ui_print("\nNot enough space left on /sdcard... Aborting.\n\n");
				isContinue = 0;
			}
			sdSpace -= imgSpace;
		}
	}
	if (isContinue)
	{
		if (is_true(tw_nan_recovery_val)) {
			imgSpace = rec.sze / 1024;
			ui_print("[RECOVERY (%i MB)]\n",imgSpace/1024);
			if (sdSpace > imgSpace)
			{
				nan_ctime = time(0);
				strcpy(tw_image,tw_image_base);
				strcat(tw_image,tw_nan_recovery);
				if (strcmp(rec.fst,"mtd") == 0)
				{
					sprintf(exe,"dump_image %s %s", rec.mnt, tw_image);
				} else {
					sprintf(exe,"dd bs=%s if=%s of=%s", bs_size, rec.dev, tw_image);
				}
				ui_print("...Backing up recovery partition.\n");
				ui_show_progress(1,5);
				__system(exe);
				LOGI("=> %s\n", exe);
				ui_print("....Done.\n");
				ui_print("...Generating %s md5...\n", rec.mnt);
				makeMD5(tw_image_base,tw_nan_recovery);
				ui_print("....Done.\n");
				ui_print("...Verifying %s md5...\n", rec.mnt);
				checkMD5(tw_image_base,tw_nan_recovery);
				ui_print("...Done.\n");
				ui_reset_progress();
				ui_print("Backed up in %d Seconds\n\n", time(0) - nan_ctime);
			} else {
				ui_print("\nNot enough space left on /sdcard... Aborting.\n\n");
				isContinue = 0;
			}
			sdSpace -= imgSpace;
		}
	}
	if (isContinue)
	{
		if (is_true(tw_nan_cache_val)) {
			ensure_path_mounted("/cache");
			fp = __popen("du -sk /cache", "r");
			LOGI("=> Checking size of /cache.\n");
		    fscanf(fp,"%lu %*s",&imgSpace);
			progTime = imgSpace / div;
			ui_print("[CACHE (%d MB)]\n",imgSpace/1024);
			__pclose(fp);
			if (sdSpace > imgSpace)
			{
				nan_ctime = time(0);
				strcpy(tw_image,tw_image_base);
				strcat(tw_image,tw_nan_cache);
				sprintf(exe,"cd /%s && tar -%s %s ./*", cac.mnt, tar_arg, tw_image);
				ui_print("...Backing up cache partition.\n");
				ui_show_progress(1,progTime);
				fp = __popen(exe, "r");
				while (fscanf(fp,"%s",tmpOutput) != EOF)
				{
					if(is_true(tw_show_spam_val))
					{
						ui_print("%s\n",tmpOutput);
					} else {
						ui_print_overwrite("%s",tmpOutput);
					}
				}
				ui_print_overwrite("....Done.\n");
				__pclose(fp);
				ui_print("...Generating %s md5...\n", cac.mnt);
				makeMD5(tw_image_base,tw_nan_cache);
				ui_print("....Done.\n");
				ui_print("...Verifying %s md5...\n", cac.mnt);
				checkMD5(tw_image_base,tw_nan_cache);
				ui_print("...Done.\n");
				ui_reset_progress();
				ui_print("Backed up in %d Seconds\n\n", time(0) - nan_ctime);
			} else {
				ui_print("\nNot enough space left on /sdcard... Aborting.\n\n");
				isContinue = 0;
			}
			ensure_path_unmounted("/cache");
			sdSpace -= imgSpace;
		}
	}
	if (isContinue)
	{
		if (is_true(tw_nan_wimax_val)) {
			if (strcmp(wim.mnt,"wimax") == 0)
			{
				imgSpace = wim.sze / 1024;
				ui_print("[WIMAX (%d MB)]\n",imgSpace/1024);
			} else {
				__system("mount /efs");
				fp = __popen("du -sk /efs", "r");
				LOGI("=> Checking size of /efs.\n");
			    fscanf(fp,"%lu %*s",&imgSpace);
				ui_print("[EFS (%d MB)]\n",imgSpace/1024);
				__pclose(fp);
			}
			if (sdSpace > imgSpace)
			{
				nan_ctime = time(0);
				strcpy(tw_image,tw_image_base);
				strcat(tw_image,tw_nan_wimax);
				ui_print("...Backing up %s partition.\n", wim.mnt);
				ui_show_progress(1,5);
				if (strcmp(wim.mnt,"efs") == 0)
				{
					sprintf(exe,"cd /%s && tar -%s %s ./*", wim.mnt, tar_arg, tw_image);
				} else {
					if (strcmp(wim.fst,"mtd") == 0)
					{
						sprintf(exe,"dump_image %s %s", wim.mnt, tw_image);
						fp = __popen(exe, "r");
						while (fscanf(fp,"%s",tmpOutput) != EOF)
						{
							if(is_true(tw_show_spam_val))
							{
								ui_print("%s\n",tmpOutput);
							} else {
								ui_print_overwrite("%s",tmpOutput);
							}
						}
						__pclose(fp);
					} else {
						sprintf(exe,"dd bs=%s if=%s of=%s", bs_size, wim.dev, tw_image);
						__system(exe);
						LOGI("=> %s\n", exe);
					}
				}
				ui_print_overwrite("....Done.\n");
				ui_print("...Generating %s md5...\n", wim.mnt);
				makeMD5(tw_image_base,tw_nan_wimax);
				ui_print("....Done.\n");
				ui_print("...Verifying %s md5...\n", wim.mnt);
				checkMD5(tw_image_base,tw_nan_wimax);
				ui_print("...Done.\n");
				ui_reset_progress();
				ui_print("Backed up in %d Seconds\n\n", time(0) - nan_ctime);
			} else {
				ui_print("\nNot enough space left on /sdcard... Aborting.\n\n");
				isContinue = 0;
			}
			if (strcmp(wim.mnt,"efs") == 0)
			{
				__system("umount /efs");
			}
			sdSpace -= imgSpace;
		}
	}
	if (isContinue)
	{
		if (is_true(tw_nan_andsec_val)) {
			ensure_path_mounted(ase.dev);
			fp = __popen("du -sk /sdcard/.android_secure", "r");
			LOGI("=> Checking size of .android_secure.\n");
		    fscanf(fp,"%lu %*s",&imgSpace);
			progTime = imgSpace / div;
			ui_print("[ANDROID_SECURE (%d MB)]\n",imgSpace/1024);
			__pclose(fp);
			if (sdSpace > imgSpace)
			{
				nan_ctime = time(0);
				strcpy(tw_image,tw_image_base);
				strcat(tw_image,tw_nan_andsec);
				sprintf(exe,"cd %s && tar -%s %s ./*", ase.dev, tar_arg, tw_image);
				ui_print("...Backing up .android_secure.\n");
				ui_show_progress(1,progTime);
				fp = __popen(exe, "r");
				while (fscanf(fp,"%s",tmpOutput) != EOF)
				{
					if(is_true(tw_show_spam_val))
					{
						ui_print("%s\n",tmpOutput);
					} else {
						ui_print_overwrite("%s",tmpOutput);
					}
				}
				__pclose(fp);
				ui_print_overwrite("....Done.\n");
				ui_print("...Generating %s md5...\n", ase.mnt);
				makeMD5(tw_image_base,tw_nan_andsec);
				ui_print("....Done.\n");
				ui_print("...Verifying %s md5...\n", ase.mnt);
				checkMD5(tw_image_base,tw_nan_andsec);
				ui_print("...Done.\n");
				ui_reset_progress();
				ui_print("Backed up in %d Seconds\n\n", time(0) - nan_ctime);
			} else {
				ui_print("\nNot enough space left on /sdcard... Aborting.\n\n");
				isContinue = 0;
			}
			sdSpace -= imgSpace;
		}
	}
	if (isContinue)
	{
		if (is_true(tw_nan_sdext_val)) {
			__system("mount /sd-ext");
			fp = __popen("du -sk /sd-ext", "r");
			LOGI("=> Checking size of /sd-ext.\n");
		    fscanf(fp,"%lu %*s",&imgSpace);
			progTime = imgSpace / div;
			ui_print("[SD-EXT (%d MB)]\n",imgSpace/1024);
			__pclose(fp);
			if (sdSpace > imgSpace)
			{
				nan_ctime = time(0);
				strcpy(tw_image,tw_image_base);
				strcat(tw_image,tw_nan_sdext);
				sprintf(exe,"cd %s && tar -%s %s ./*", sde.mnt, tar_arg, tw_image);
				ui_print("...Backing up sd-ext partition.\n");
				ui_show_progress(1,progTime);
				fp = __popen(exe, "r");
				while (fscanf(fp,"%s",tmpOutput) != EOF)
				{
					if(is_true(tw_show_spam_val))
					{
						ui_print("%s\n",tmpOutput);
					} else {
						ui_print_overwrite("%s",tmpOutput);
					}
				}
				__pclose(fp);
				ui_print_overwrite("....Done.\n");
				ui_print("...Generating %s md5...\n", sde.mnt);
				makeMD5(tw_image_base,tw_nan_sdext);
				ui_print("....Done.\n");
				ui_print("...Verifying %s md5...\n", sde.mnt);
				checkMD5(tw_image_base,tw_nan_sdext);
				ui_print("...Done.\n");
				ui_reset_progress();
				ui_print("Backed up in %d Seconds\n\n", time(0) - nan_ctime);
			} else {
				ui_print("\nNot enough space left on /sdcard... Aborting.\n\n");
				isContinue = 0;
			}
			__system("umount /sd-ext");
			sdSpace -= imgSpace;
		}
	}
	fp = __popen("df -k /sdcard| grep sdcard | awk '{ print $4 }'", "r");
	while (fgets(tmpString,15,fp) != NULL)
	{
		tmpChar = tmpString[strlen(tmpString)-2];
	}
	__pclose(fp);
	if(tmpChar == '%')
	{
		fp = __popen("df -k /sdcard| grep sdcard | awk '{ print $3 }'", "r");
		LOGI("=> Not the response we were looking for, trying again.\n");
		fgets(tmpString,15,fp);
		__pclose(fp);
	}
	sscanf(tmpString,"%lu",&sdSpace);
    int totalBackedUp = (int)(sdSpaceFinal - sdSpace) / 1024;
	ui_print("[ %d MB TOTAL BACKED UP TO SDCARD ]\n[ BACKUP COMPLETED IN %d SECONDS ]\n\n", totalBackedUp, time(0) - nan_ttime);
}
示例#27
0
void 
nandroid_rest_exe()
{
	ensure_path_mounted(SDCARD_ROOT);
	FILE *fp;
	char tmpBuffer[1024];
	char *tmpOutput;
	int tmpSize;
	int numErrors = 0;
	char exe[255];
	char* tmp_file = (char*)malloc(255);
    time_t nan_ttime;
    time_t nan_ctime;
	ui_print("\nStarting Restore...\n\n");
	nan_ttime = time(0);
	if (tw_nan_system_x == 1) {
		ui_print("...Verifying md5 hash for %s.\n",tw_nan_system);
		ui_show_progress(1,150);
		nan_ctime = time(0);
		if(checkMD5(nan_dir,tw_nan_system))
		{
			ensure_path_mounted("/system");
			strcpy(tmp_file,nan_dir);
			strcat(tmp_file,tw_nan_system);
			ui_print("...Wiping %s.\n",sys.mnt);
			sprintf(exe,"rm -rf /%s/* && rm -rf /%s/.* ", sys.mnt, sys.mnt);
			__system(exe);
			ui_print("....Done.\n");
			sprintf(exe,"cd /%s && tar xzvpf %s", sys.mnt, tmp_file);
			ui_print("...Restoring system partition.\n");
			fp = __popen(exe, "r");
			while (fgets(tmpBuffer,sizeof(tmpBuffer),fp) != NULL)
			{
				tmpBuffer[strlen(tmpBuffer)-1] = '\0';
				tmpOutput = tmpBuffer;
				if(is_true(tw_show_spam_val))
				{
					ui_print("%s\n",tmpOutput);
				} else {
					ui_print_overwrite("%s",tmpOutput);
				}
			}
			__pclose(fp);
			ui_print_overwrite("....Done.\n");
			ui_print("Restored in %d Seconds\n\n", time(0) - nan_ctime);
			ensure_path_unmounted("/system");
		} else {
			ui_print("...Failed md5 check. Aborted.\n\n");
			numErrors++;
		}
		ui_reset_progress();
	}
	if (tw_nan_data_x == 1) {
		ui_print("...Verifying md5 hash for %s.\n",tw_nan_data);
		ui_show_progress(1,150);
		nan_ctime = time(0);
		if(checkMD5(nan_dir,tw_nan_data))
		{
			ensure_path_mounted("/data");
			strcpy(tmp_file,nan_dir);
			strcat(tmp_file,tw_nan_data);
			ui_print("...Wiping %s.\n",dat.mnt);
			sprintf(exe,"rm -rf /%s/* && rm -rf /%s/.* ", dat.mnt, dat.mnt);
			__system(exe);
			ui_print("....Done.\n");
			sprintf(exe,"cd /%s && tar xzvpf %s", dat.mnt, tmp_file);
			ui_print("...Restoring data partition.\n");
			fp = __popen(exe, "r");
			while (fgets(tmpBuffer,sizeof(tmpBuffer),fp) != NULL)
			{
				tmpBuffer[strlen(tmpBuffer)-1] = '\0';
				tmpOutput = tmpBuffer;
				if(is_true(tw_show_spam_val))
				{
					ui_print("%s\n",tmpOutput);
				} else {
					ui_print_overwrite("%s",tmpOutput);
				}
			}
			__pclose(fp);
			ui_print_overwrite("....Done.\n");
			ui_print("Restored in %d Seconds\n\n", time(0) - nan_ctime);
			ensure_path_unmounted("/data");
		} else {
			ui_print("...Failed md5 check. Aborted.\n\n");
			numErrors++;
		}
		ui_reset_progress();
	}
	if (tw_nan_boot_x == 1) {
		ui_print("...Verifying md5 hash for %s.\n",tw_nan_boot);
		ui_show_progress(1,5);
		nan_ctime = time(0);
		if(checkMD5(nan_dir,tw_nan_boot))
		{
			strcpy(tmp_file,nan_dir);
			strcat(tmp_file,tw_nan_boot);
			ui_print("...Double checking, by checking file size.\n");
			sprintf(exe,"ls -l %s",tmp_file);
			fp = __popen(exe, "r");
			fscanf(fp,"%*s %*i %*s %*s %i",&tmpSize);
			if (tmpSize == boo.sze)
			{
				ui_print("....File size matched partition size.\n");
				if (strcmp(boo.fst,"mtd") == 0)
				{
					sprintf(exe,"flash_image %s %s", boo.mnt, tmp_file);
				} else {
					sprintf(exe,"dd bs=%s if=%s of=%s", bs_size, tmp_file, boo.dev);
				}
				LOGI("=> %s\n", exe);
				ui_print("...Restoring boot partition.\n");
				__system(exe);
				ui_print("...Done.\n");
				ui_print("Restored in %d Seconds\n\n", time(0) - nan_ctime);
			} else {
				ui_print("...Failed file size check. Aborted.\n\n");
				numErrors++;
			}
			__pclose(fp);
		} else {
			ui_print("...Failed md5 check. Aborted.\n\n");
			numErrors++;
		}
		ui_reset_progress();
	}
	if (tw_nan_recovery_x == 1) {
		ui_print("...Verifying md5 hash for %s.\n",tw_nan_recovery);
		ui_show_progress(1,5);
		nan_ctime = time(0);
		if(checkMD5(nan_dir,tw_nan_recovery))
		{
			strcpy(tmp_file,nan_dir);
			strcat(tmp_file,tw_nan_recovery);
			ui_print("...Double checking, by checking file size.\n");
			sprintf(exe,"ls -l %s",tmp_file);
			fp = __popen(exe, "r");
			fscanf(fp,"%*s %*i %*s %*s %i",&tmpSize);
			if (tmpSize == rec.sze)
			{
				ui_print("....File size matched partition size.\n");
				if (strcmp(rec.fst,"mtd") == 0)
				{
					sprintf(exe,"flash_image %s %s", rec.mnt, tmp_file);
				} else {
					sprintf(exe,"dd bs=%s if=%s of=%s", bs_size, tmp_file, rec.dev);
				}
				LOGI("=> %s\n", exe);
				ui_print("...Restoring recovery partition.\n");
				__system(exe);
				ui_print("...Done.\n");
				ui_print("Restored in %d Seconds\n\n", time(0) - nan_ctime);
			} else {
				ui_print("...Failed file size check. Aborted.\n\n");
				numErrors++;
			}
			__pclose(fp);
		} else {
			ui_print("...Failed md5 check. Aborted.\n\n");
			numErrors++;
		}
		ui_reset_progress();
	}
	if (tw_nan_cache_x == 1) {
		ui_print("...Verifying md5 hash for %s.\n",tw_nan_cache);
		ui_show_progress(1,100);
		nan_ctime = time(0);
		if(checkMD5(nan_dir,tw_nan_cache))
		{
			ensure_path_mounted("/cache");
			strcpy(tmp_file,nan_dir);
			strcat(tmp_file,tw_nan_cache);
			ui_print("...Wiping %s.\n",cac.mnt);
			sprintf(exe,"rm -rf /%s/* && rm -rf /%s/.* ", cac.mnt, cac.mnt);
			__system(exe);
			ui_print("....Done.\n");
			sprintf(exe,"cd /%s && tar xzvpf %s", cac.mnt, tmp_file);
			ui_print("...Restoring cache partition.\n");
			fp = __popen(exe, "r");
			while (fgets(tmpBuffer,sizeof(tmpBuffer),fp) != NULL)
			{
				tmpBuffer[strlen(tmpBuffer)-1] = '\0';
				tmpOutput = tmpBuffer;
				if(is_true(tw_show_spam_val))
				{
					ui_print("%s\n",tmpOutput);
				} else {
					ui_print_overwrite("%s",tmpOutput);
				}
			}
			__pclose(fp);
			ui_print_overwrite("....Done.\n");
			ui_print("Restored in %d Seconds\n\n", time(0) - nan_ctime);
			ensure_path_unmounted("/cache");
		} else {
			ui_print("...Failed md5 check. Aborted.\n\n");
			numErrors++;
		}
		ui_reset_progress();
	}
	if (tw_nan_wimax_x == 1) {
		ui_print("...Verifying md5 hash for %s.\n",tw_nan_wimax);
		ui_show_progress(1,5);
		nan_ctime = time(0);
		if(checkMD5(nan_dir,tw_nan_wimax))
		{
			strcpy(tmp_file,nan_dir);
			strcat(tmp_file,tw_nan_wimax);
			if (strcmp(wim.mnt,"efs") == 0)
			{
				__system("mount /efs");
				ui_print("...Wiping %s.\n",wim.mnt);
				sprintf(exe,"rm -rf /%s/* && rm -rf /%s/.*", wim.mnt);
				__system(exe);
				ui_print("....Done.\n");
				sprintf(exe,"cd /%s && tar xzvpf %s", wim.mnt, tmp_file);
				ui_print("...Restoring efs partition.\n");
				fp = __popen(exe, "r");
				while (fgets(tmpBuffer,sizeof(tmpBuffer),fp) != NULL)
				{
					tmpBuffer[strlen(tmpBuffer)-1] = '\0';
					tmpOutput = tmpBuffer;
					if(is_true(tw_show_spam_val))
					{
						ui_print("%s\n",tmpOutput);
					} else {
						ui_print_overwrite("%s",tmpOutput);
					}
				}
				__pclose(fp);
				ui_print_overwrite("....Done.\n");
				ui_print("Restored in %d Seconds\n\n", time(0) - nan_ctime);
				__system("umount /efs");
			} else {
				ui_print("...Double checking, by checking file size.\n");
				sprintf(exe,"ls -l %s",tmp_file);
				fp = __popen(exe, "r");
				fscanf(fp,"%*s %*i %*s %*s %i",&tmpSize);
				if (tmpSize == wim.sze)
				{
					ui_print("....File size matched partition size.\n");
					if (strcmp(rec.fst,"mtd") == 0)
					{
						sprintf(exe,"flash_image %s %s", wim.mnt, tmp_file);
					} else {
						sprintf(exe,"dd bs=%s if=%s of=%s", bs_size, tmp_file, wim.dev);
					}
					LOGI("=> %s\n", exe);
					ui_print("...Restoring wimax partition.\n");
					__system(exe);
					ui_print("...Done.\n");
					ui_print("Restored in %d Seconds\n\n", time(0) - nan_ctime);
				} else {
					ui_print("...Failed file size check. Aborted.\n\n");
					numErrors++;
				}
				__pclose(fp);
			}
		} else {
			ui_print("...Failed md5 check. Aborted.\n\n");
			numErrors++;
		}
		ui_reset_progress();
	}
	if (tw_nan_andsec_x == 1) {
		ui_print("...Verifying md5 hash for %s.\n",tw_nan_andsec);
		ui_show_progress(1,25);
		nan_ctime = time(0);
		if(checkMD5(nan_dir,tw_nan_andsec))
		{
			ensure_path_mounted(ase.dev);
			strcpy(tmp_file,nan_dir);
			strcat(tmp_file,tw_nan_andsec);
			ui_print("...Wiping %s.\n",ase.dev);
			sprintf(exe,"rm -rf %s/* && rm -rf %s/.* ", ase.dev, ase.dev);
			__system(exe);
			ui_print("....Done.\n");
			sprintf(exe,"cd %s && tar xzvpf %s", ase.dev, tmp_file);
			ui_print("...Restoring .android-secure.\n");
			fp = __popen(exe, "r");
			while (fgets(tmpBuffer,sizeof(tmpBuffer),fp) != NULL)
			{
				tmpBuffer[strlen(tmpBuffer)-1] = '\0';
				tmpOutput = tmpBuffer;
				if(is_true(tw_show_spam_val))
				{
					ui_print("%s\n",tmpOutput);
				} else {
					ui_print_overwrite("%s",tmpOutput);
				}
			}
			__pclose(fp);
			ui_print_overwrite("....Done.\n");
			ui_print("Restored in %d Seconds\n\n", time(0) - nan_ctime);
		} else {
			ui_print("...Failed md5 check. Aborted.\n\n");
			numErrors++;
		}
		ui_reset_progress();
	}
	if (tw_nan_sdext_x == 1) {
		ui_print("...Verifying md5 hash for %s.\n",tw_nan_sdext);
		ui_show_progress(1,25);
		nan_ctime = time(0);
		if(checkMD5(nan_dir,tw_nan_sdext))
		{
			__system("mount /sd-ext");
			strcpy(tmp_file,nan_dir);
			strcat(tmp_file,tw_nan_sdext);
			ui_print("...Wiping %s.\n",sde.mnt);
			sprintf(exe,"rm -rf /%s/* && rm -rf /%s/.* ", sde.mnt, sde.mnt);
			__system(exe);
			ui_print("....Done.\n");
			sprintf(exe,"cd /%s && tar xzvpf %s", sde.mnt, tmp_file);
			ui_print("...Restoring sd-ext partition.\n");
			fp = __popen(exe, "r");
			while (fgets(tmpBuffer,sizeof(tmpBuffer),fp) != NULL)
			{
				tmpBuffer[strlen(tmpBuffer)-1] = '\0';
				tmpOutput = tmpBuffer;
				if(is_true(tw_show_spam_val))
				{
					ui_print("%s\n",tmpOutput);
				} else {
					ui_print_overwrite("%s",tmpOutput);
				}
			}
			__pclose(fp);
			ui_print_overwrite("....Done.\n");
			ui_print("Restored in %d Seconds\n\n", time(0) - nan_ctime);
			__system("umount /sd-ext");
		} else {
			ui_print("...Failed md5 check. Aborted.\n\n");
			numErrors++;
		}
		ui_reset_progress();
	}
	if (numErrors > 0)
	{
		ui_print("[ %d ERROR(S), PLEASE CHECK LOGS ]\n", numErrors);
	}
	ui_print("[ RESTORE COMPLETED IN %d SECONDS ]\n\n", time(0) - nan_ttime);
	__system("sync");
	free(tmp_file);
}