static void refresh_default_backup_handler() { char fmt[5]; if (strlen(forced_backup_format) > 0) { strcpy(fmt, forced_backup_format); } else { ensure_path_mounted(get_primary_storage_path()); FILE* f = fopen(NANDROID_BACKUP_FORMAT_FILE, "r"); if (NULL == f) { default_backup_handler = tar_compress_wrapper; return; } fread(fmt, 1, sizeof(fmt), f); fclose(f); } fmt[3] = '\0'; if (0 == strcmp(fmt, "dup")) default_backup_handler = dedupe_compress_wrapper; else if (0 == strcmp(fmt, "tgz")) default_backup_handler = tar_gzip_compress_wrapper; else if (0 == strcmp(fmt, "tar")) default_backup_handler = tar_compress_wrapper; else default_backup_handler = tar_compress_wrapper; }
char* get_android_secure_path() { if (android_secure_path == NULL) { android_secure_path = malloc(sizeof("/.android_secure") + strlen(get_primary_storage_path()) + 1); sprintf(android_secure_path, "%s/.android_secure", primary_storage_path); } return android_secure_path; }
void setup_legacy_storage_paths() { char* primary_path = get_primary_storage_path(); if (!is_data_media_volume_path(primary_path)) { rmdir("/sdcard"); symlink(primary_path, "/sdcard"); } }
int nandroid_restore_datamedia(const char* backup_path) { char tmp[PATH_MAX]; ui_print("\n>> Restoring /data/media...\n"); if (is_data_media_volume_path(backup_path)) { // non fatal failure LOGE(" - can't restore folder to its self, skipping...\n"); return 0; } Volume *v = volume_for_path("/data"); if (v == NULL) return -1; sprintf(tmp, "%s/%s", get_primary_storage_path(), NANDROID_HIDE_PROGRESS_FILE); ensure_path_mounted(tmp); int callback = !file_found(tmp); struct stat s; char backup_file_image[PATH_MAX]; const char *filesystems[] = { "yaffs2", "ext2", "ext3", "ext4", "vfat", "exfat", "rfs", "f2fs", "auto", NULL }; const char *filesystem; int i = 0; nandroid_restore_handler restore_handler = NULL; while ((filesystem = filesystems[i]) != NULL) { sprintf(backup_file_image, "%s/datamedia.%s.tar", backup_path, filesystem); if (0 == stat(backup_file_image, &s)) { restore_handler = tar_extract_wrapper; sprintf(tmp, "cd / ; set -o pipefail ; cat %s* | tar -xpv ; exit $?", backup_file_image); break; } sprintf(backup_file_image, "%s/datamedia.%s.tar.gz", backup_path, filesystem); if (0 == stat(backup_file_image, &s)) { restore_handler = tar_gzip_extract_wrapper; sprintf(tmp, "cd / ; set -o pipefail ; cat %s* | pigz -d -c | tar -xpv ; exit $?", backup_file_image); break; } i++; } if (filesystem == NULL || restore_handler == NULL) { LOGE("No backup found, skipping...\n"); return 0; } if (0 != format_unknown_device(NULL, "/data/media", NULL)) return print_and_error("Error while erasing /data/media\n", NANDROID_ERROR_GENERAL); // data can be unmounted by format_unknown_device() if (0 != ensure_path_mounted("/data")) return -1; if (0 != do_tar_extract(tmp, backup_file_image, "/data", callback)) return print_and_error("Failed to restore /data/media!\n", NANDROID_ERROR_GENERAL); ui_print("Restore of /data/media completed.\n"); return 0; }
int get_num_extra_volumes() { int num = 0; int i; for (i = 0; i < get_num_volumes(); i++) { Volume* v = get_device_volumes() + i; if ((strcmp("/external_sd", v->mount_point) == 0) || ((strcmp(get_primary_storage_path(), v->mount_point) != 0) && fs_mgr_is_voldmanaged(v) && vold_is_volume_available(v->mount_point))) num++; } return num; }
int run_and_remove_extendedcommand() { char* primary_path = get_primary_storage_path(); char tmp[PATH_MAX]; sprintf(tmp, "cp %s /tmp/%s", EXTENDEDCOMMAND_SCRIPT, basename(EXTENDEDCOMMAND_SCRIPT)); __system(tmp); remove(EXTENDEDCOMMAND_SCRIPT); int i = 0; for (i = 20; i > 0; i--) { ui_print("Waiting for SD Card to mount (%ds)\n", i); if (ensure_path_mounted(primary_path) == 0) { ui_print("SD Card mounted...\n"); break; } sleep(1); } remove("/sdcard/clockworkmod/.recoverycheckpoint"); if (i == 0) { ui_print("Timed out waiting for SD card... continuing anyways."); } ui_print("Verifying SD Card marker...\n"); struct stat st; if (stat("/sdcard/clockworkmod/.salted_hash", &st) != 0) { ui_print("SD Card marker not found...\n"); if (volume_for_path("/emmc") != NULL) { ui_print("Checking Internal SD Card marker...\n"); ensure_path_unmounted(primary_path); if (ensure_path_mounted_at_mount_point("/emmc", primary_path) != 0) { ui_print("Internal SD Card marker not found... continuing anyways.\n"); // unmount everything, and remount as normal ensure_path_unmounted("/emmc"); ensure_path_unmounted(primary_path); ensure_path_mounted(primary_path); } } } sprintf(tmp, "/tmp/%s", basename(EXTENDEDCOMMAND_SCRIPT)); int ret; #ifdef I_AM_KOUSH if (0 != (ret = before_run_script(tmp))) { ui_print("Error processing ROM Manager script. Please verify that you are performing the backup, restore, or ROM installation from ROM Manager v4.4.0.0 or higher.\n"); return ret; } #endif return run_script(tmp); }
// backup /data/media support // we reach here only if backup_data_media == 1 // backup_data_media can be set to 1 only in "custom backup and restore" menu AND if is_data_media() && !twrp_backup_mode.value int nandroid_backup_datamedia(const char* backup_path) { char tmp[PATH_MAX]; ui_print("\n>> Backing up /data/media...\n"); if (is_data_media_volume_path(backup_path)) { // non fatal failure LOGE(" - can't backup folder to its self, skipping...\n"); return 0; } if (0 != ensure_path_mounted("/data")) return -1; sprintf(tmp, "%s/%s", get_primary_storage_path(), NANDROID_HIDE_PROGRESS_FILE); ensure_path_mounted(tmp); int callback = !file_found(tmp); compute_directory_stats("/data/media"); Volume *v = volume_for_path("/data"); if (v == NULL) return -1; char backup_file_image[PATH_MAX]; sprintf(backup_file_image, "%s/datamedia.%s", backup_path, v->fs_type == NULL ? "auto" : v->fs_type); int fmt; fmt = nandroid_get_default_backup_format(); if (fmt == NANDROID_BACKUP_FORMAT_TAR) { sprintf(tmp, "cd / ; touch %s.tar ; set -o pipefail ; (tar -cpv data/media | split -a 1 -b 1000000000 /proc/self/fd/0 %s.tar.) 2> /proc/self/fd/1 ; exit $?", backup_file_image, backup_file_image); } else if (fmt == NANDROID_BACKUP_FORMAT_TGZ) { sprintf(tmp, "cd / ; touch %s.tar.gz ; set -o pipefail ; (tar -cpv data/media | pigz -c -%d | split -a 1 -b 1000000000 /proc/self/fd/0 %s.tar.gz.) 2> /proc/self/fd/1 ; exit $?", backup_file_image, compression_value.value, backup_file_image); } else { // non fatal failure LOGE(" - backup format must be tar(.gz), skipping...\n"); return 0; } int ret; ret = do_tar_compress(tmp, callback, backup_file_image); ensure_path_unmounted("/data"); if (0 != ret) return print_and_error("Failed to backup /data/media!\n", ret); ui_print("Backup of /data/media completed.\n"); return 0; }
/* On recovery exit, check if there is a settings file (PHILZ_SETTINGS_FILE) if not, try to restore the copy we do on primary storage (PHILZ_SETTINGS_FILE2) * Also, if no copy is found, always create it if there is a settings file we shouldn't always copy settings file on exit to avoid loosing user config after a wipe if he just change brightness by error for exp... Function is called when rebooting After success install of a new rom, before reboot, it will preserve settings if they were wiped by installed ROM */ void verify_settings_file() { char settings_copy[PATH_MAX]; sprintf(settings_copy, "%s/%s", get_primary_storage_path(), PHILZ_SETTINGS_FILE2); // always have a copy of settings file in primary storage if (file_found(PHILZ_SETTINGS_FILE) && !file_found(settings_copy)) copy_a_file(PHILZ_SETTINGS_FILE, settings_copy); // restore settings from the copy if needed (after a wipe) if (!file_found(PHILZ_SETTINGS_FILE) && file_found(settings_copy)) { ui_SetShowText(true); if (!auto_restore_settings.value && !confirm_selection("Restore recovery settings?", "Yes - Restore from sdcard")) return; if (copy_a_file(settings_copy, PHILZ_SETTINGS_FILE) == 0) ui_print("Recovery settings restored.\n"); } }
static void build_configuration_path(char *path_buf, const char *file) { sprintf(path_buf, "%s%s%s", get_primary_storage_path(), (is_data_media() ? "/0/" : "/"), file); }
// set value of key in config file int write_config_file(const char* config_file, const char* key, const char* value) { if (ensure_path_mounted(config_file) != 0) { LOGE("Cannot mount path for settings file: %s\n", config_file); return -1; } char config_file_tmp[PATH_MAX]; char tmp[PATH_MAX]; sprintf(config_file_tmp, "%s.tmp", config_file); sprintf(tmp, "%s", DirName(config_file_tmp)); ensure_directory(tmp, 0755); delete_a_file(config_file_tmp); FILE *f_tmp = fopen(config_file_tmp, "wb"); if (f_tmp == NULL) { LOGE("failed to create temporary settings file!\n"); return -1; } FILE *fp = fopen(config_file, "rb"); if (fp == NULL) { // we need to create a new settings file: write an info header const char* header[] = { "#PhilZ Touch Settings File\n", "#Edit only in appropriate UNIX format (Notepad+++...)\n", "#Entries are in the form of:\n", "#key=value\n", "#Do not add spaces in between!\n", "\n", NULL }; int i; for(i = 0; header[i] != NULL; i++) { fwrite(header[i], 1, strlen(header[i]), f_tmp); } } else { // parse existing config file and write new temporary file. char line[PROPERTY_VALUE_MAX]; while (fgets(line, sizeof(line), fp) != NULL) { // ignore any existing line with key we want to set if (strstr(line, key) != NULL && strncmp(line, key, strlen(key)) == 0 && line[strlen(key)] == '=') continue; // ensure trailing \n, in case some one got a bad editor... if (line[strlen(line) - 1] != '\n') strcat(line, "\n"); fwrite(line, 1, strlen(line), f_tmp); } fclose(fp); } // write new key=value entry char new_entry[PROPERTY_VALUE_MAX]; sprintf(new_entry, "%s=%s\n", key, value); fwrite(new_entry, 1, strlen(new_entry), f_tmp); fclose(f_tmp); if (rename(config_file_tmp, config_file) != 0) { LOGE("failed to rename temporary settings file!\n"); return -1; } // if we are editing recovery settings file, create a second copy on primary storage if (strcmp(PHILZ_SETTINGS_FILE, config_file) == 0) { sprintf(tmp, "%s/%s", get_primary_storage_path(), PHILZ_SETTINGS_FILE2); if (copy_a_file(config_file, tmp) != 0) LOGE("failed duplicating settings file to primary storage!\n"); } LOGI("%s was set to %s\n", key, value); return 0; }