static void on_bus_acquired (GDBusConnection *connection, const gchar *name, gpointer user_data) { Daemon *daemon; GError *local_error = NULL; GError **error = &local_error; if (!ensure_directory (ICONDIR, error)) { goto out; } if (!ensure_directory (USERDIR, error)) { goto out; } daemon = daemon_new (); if (daemon == NULL) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Failed to initialize daemon"); goto out; } openlog ("accounts-daemon", LOG_PID, LOG_DAEMON); syslog (LOG_INFO, "started daemon version %s", VERSION); closelog (); openlog ("accounts-daemon", 0, LOG_AUTHPRIV); out: if (local_error != NULL) { g_printerr ("%s\n", local_error->message); g_clear_error (&local_error); g_main_loop_quit (loop); } }
int nandroid_restore_partition_extended(const char* backup_path, const char* mount_point, int umount_when_finished) { int ret = 0; char* name = basename(mount_point); char tmp[PATH_MAX]; sprintf(tmp, "%s/%s.img", backup_path, name); struct stat file_info; if (0 != (ret = statfs(tmp, &file_info))) { ui_print("%s.img没有发现. 放弃还原 %s.\n", name, mount_point); return 0; } ensure_directory(mount_point); unyaffs_callback callback = NULL; if (0 != stat("/sdcard/clockworkmod/.hidenandroidprogress", &file_info)) { callback = yaffs_callback; } ui_print("还原 %s...\n", name); /* if (0 != (ret = ensure_root_path_unmounted(root))) { ui_print("Can't unmount %s!\n", mount_point); return ret; } */ if (0 != (ret = format_volume(mount_point))) { ui_print("格式化时出错 %s!\n", mount_point); return ret; } if (0 != (ret = ensure_path_mounted(mount_point))) { ui_print("不能挂载 %s!\n", mount_point); return ret; } if (0 != (ret = unyaffs(tmp, mount_point, callback))) { ui_print("还原时出错 %s!\n", mount_point); return ret; } if (umount_when_finished) { ensure_path_unmounted(mount_point); } return 0; }
int tarbackup_restore_partition_extended(const char* backup_path, const char* root, int umount_when_finished) { int ret; char mount_point[PATH_MAX]; translate_root_path(root, mount_point, PATH_MAX); char* name = basename(mount_point); char tmp[PATH_MAX]; sprintf(tmp, "%s/%s.tar", backup_path, name); struct stat file_info; if (0 != (ret = statfs(tmp, &file_info))) { ui_print("%s.tar not found. Skipping restore of %s.\n", name, mount_point); return 0; } ensure_directory(mount_point); ui_print("Restoring %s...\n", name); if (0 != (ret = ensure_root_path_unmounted(root))) { ui_print("Can't unmount %s!\n", mount_point); return ret; } if (0 != (ret = format_root_device(root))) { ui_print("Error while formatting %s!\n", root); return ret; } if (0 != (ret = ensure_root_path_mounted(root))) { ui_print("Can't mount %s!\n", mount_point); return ret; } sprintf(tmp, "tar -x -f %s/%s.tar", backup_path, name); if (0 != __system(tmp)) { ui_print("Error while restoring %s!\n", mount_point); return ret; } if (umount_when_finished) { ensure_root_path_unmounted(root); } return 0; }
static int dedupe_compress_wrapper(const char* backup_path, const char* backup_file_image, int callback) { char tmp[PATH_MAX]; char blob_dir[PATH_MAX]; strcpy(blob_dir, backup_file_image); char *d = dirname(blob_dir); strcpy(blob_dir, d); d = dirname(blob_dir); strcpy(blob_dir, d); d = dirname(blob_dir); strcpy(blob_dir, d); strcat(blob_dir, "/blobs"); ensure_directory(blob_dir); if (!(nandroid_backup_bitfield & NANDROID_FIELD_DEDUPE_CLEARED_SPACE)) { nandroid_backup_bitfield |= NANDROID_FIELD_DEDUPE_CLEARED_SPACE; nandroid_dedupe_gc(blob_dir); } sprintf(tmp, "dedupe c %s %s %s.dup %s", backup_path, blob_dir, backup_file_image, strcmp(backup_path, "/data") == 0 && is_data_media() ? "./media" : ""); FILE *fp = __popen(tmp, "r"); if (fp == NULL) { #ifndef USE_CHINESE_FONT ui_print("Unable to execute dedupe.\n"); #else ui_print("无法进行增量备份。\n"); #endif return -1; } while (fgets(tmp, PATH_MAX, fp) != NULL) { tmp[PATH_MAX - 1] = '\0'; if (callback) nandroid_callback(tmp); } return __pclose(fp); }
int nandroid_restore_partition_extended(const char* backup_path, const char* mount_point, int umount_when_finished) { int ret = 0; char* name = basename(mount_point); nandroid_restore_handler restore_handler = NULL; const char *filesystems[] = { "yaffs2", "ext2", "ext3", "ext4", "vfat", "rfs", NULL }; const char* backup_filesystem = NULL; Volume *vol = volume_for_path(mount_point); const char *device = NULL; if (vol != NULL) device = vol->device; char tmp[PATH_MAX]; sprintf(tmp, "%s/%s.img", backup_path, name); struct stat file_info; if (0 != (ret = statfs(tmp, &file_info))) { // can't find the backup, it may be the new backup format? // iterate through the backup types printf("couldn't find old .img format\n"); char *filesystem; int i = 0; while ((filesystem = filesystems[i]) != NULL) { sprintf(tmp, "%s/%s.%s.img", backup_path, name, filesystem); if (0 == (ret = statfs(tmp, &file_info))) { backup_filesystem = filesystem; restore_handler = unyaffs_wrapper; break; } sprintf(tmp, "%s/%s.%s.tar", backup_path, name, filesystem); if (0 == (ret = statfs(tmp, &file_info))) { backup_filesystem = filesystem; restore_handler = tar_extract_wrapper; break; } sprintf(tmp, "%s/%s.%s.dup", backup_path, name, filesystem); if (0 == (ret = statfs(tmp, &file_info))) { backup_filesystem = filesystem; restore_handler = dedupe_extract_wrapper; break; } i++; } if (backup_filesystem == NULL || restore_handler == NULL) { //ui_print("%s.img not found. Skipping restore of %s.\n", name, mount_point); ui_print("No %s backup found(img, tar, dup). Skipping restore of %s.\n", name, mount_point); return 0; } else { printf("Found new backup image: %s\n", tmp); } // If the fs_type of this volume is "auto" or mount_point is /data // and is_data_media, let's revert // to using a rm -rf, rather than trying to do a // ext3/ext4/whatever format. // This is because some phones (like DroidX) will freak out if you // reformat the /system or /data partitions, and not boot due to // a locked bootloader. // Other devices, like the Galaxy Nexus, XOOM, and Galaxy Tab 10.1 // have a /sdcard symlinked to /data/media. // Or of volume does not exist (.android_secure), just rm -rf. if (vol == NULL || 0 == strcmp(vol->fs_type, "auto")) backup_filesystem = NULL; if (0 == strcmp(vol->mount_point, "/data") && is_data_media()) backup_filesystem = NULL; } ensure_directory(mount_point); int callback = stat("/sdcard/clockworkmod/.hidenandroidprogress", &file_info) != 0; compute_archive_stats(tmp); ui_print("Restoring %s...\n", name); if (backup_filesystem == NULL) { if (0 != (ret = format_volume(mount_point))) { ui_print("Error while formatting %s!\n", mount_point); return ret; } } else if (0 != (ret = format_device(device, mount_point, backup_filesystem))) { ui_print("Error while formatting %s!\n", mount_point); return ret; } if (0 != (ret = ensure_path_mounted(mount_point))) { ui_print("Can't mount %s!\n", mount_point); return ret; } if (restore_handler == NULL) restore_handler = get_restore_handler(mount_point); if (restore_handler == NULL) { ui_print("Error finding an appropriate restore handler.\n"); return -2; } if (0 != (ret = restore_handler(tmp, mount_point, callback))) { ui_print("Error while restoring %s!\n", mount_point); return ret; } if (umount_when_finished) { ensure_path_unmounted(mount_point); } return 0; }
int nandroid_backup(const char* backup_path) { nandroid_backup_bitfield = 0; ui_set_background(BACKGROUND_ICON_INSTALLING); refresh_default_backup_handler(); if (ensure_path_mounted(backup_path) != 0) { return print_and_error("Can't mount backup path.\n"); } Volume* volume = volume_for_path(backup_path); if (NULL == volume) return print_and_error("Unable to find volume for backup path.\n"); if (is_data_media_volume_path(volume->mount_point)) volume = volume_for_path("/data"); int ret; struct statfs s; if (NULL != volume) { if (0 != (ret = statfs(volume->mount_point, &s))) return print_and_error("Unable to stat backup path.\n"); uint64_t bavail = s.f_bavail; uint64_t bsize = s.f_bsize; uint64_t sdcard_free = bavail * bsize; uint64_t sdcard_free_mb = sdcard_free / (uint64_t)(1024 * 1024); ui_print("SD Card space free: %lluMB\n", sdcard_free_mb); if (sdcard_free_mb < 150) ui_print("There may not be enough free space to complete backup... continuing...\n"); } char tmp[PATH_MAX]; ensure_directory(backup_path); if (backup_boot && 0 != (ret = nandroid_backup_partition(backup_path, "/boot"))) return ret; if (backup_recovery && 0 != (ret = nandroid_backup_partition(backup_path, "/recovery"))) return ret; Volume *vol = volume_for_path("/wimax"); if (backup_wimax && vol != NULL && 0 == stat(vol->device, &s)) { char serialno[PROPERTY_VALUE_MAX]; ui_print("Backing up WiMAX...\n"); serialno[0] = 0; property_get("ro.serialno", serialno, ""); sprintf(tmp, "%s/wimax.%s.img", backup_path, serialno); ret = backup_raw_partition(vol->fs_type, vol->device, tmp); if (0 != ret) return print_and_error("Error while dumping WiMAX image!\n"); } //2 copies of efs are made: tarball and raw backup if (backup_efs) { //first backup in raw format, returns 0 on success (or if skipped), else 1 if (0 != custom_backup_raw_handler(backup_path, "/efs")) { ui_print("EFS raw image backup failed! Trying tar backup...\n"); } //second backup in tar format sprintf(tmp, "%s/efs_tar", backup_path); ensure_directory(tmp); if (0 != (ret = nandroid_backup_partition(tmp, "/efs"))) return ret; } if (backup_modem) { if (0 != (ret = nandroid_backup_partition(backup_path, "/modem"))) return ret; } if (backup_system && 0 != (ret = nandroid_backup_partition(backup_path, "/system"))) return ret; if (is_custom_backup && backup_preload) { if (0 != (ret = nandroid_backup_partition(backup_path, "/preload"))) { ui_print("Failed to backup /preload!\n"); return ret; } } else if (!is_custom_backup #ifdef PHILZ_TOUCH_RECOVERY && nandroid_add_preload #endif ) { if (0 != (ret = nandroid_backup_partition(backup_path, "/preload"))) { ui_print("Failed to backup preload! Try to disable it.\n"); ui_print("Skipping /preload...\n"); //return ret; } } if (backup_data && 0 != (ret = nandroid_backup_partition(backup_path, "/data"))) return ret; if (has_datadata()) { if (backup_data && 0 != (ret = nandroid_backup_partition(backup_path, "/datadata"))) return ret; } if (is_data_media() || 0 != stat("/sdcard/.android_secure", &s)) { ui_print("No /sdcard/.android_secure found. Skipping backup of applications on external storage.\n"); } else { if (backup_data && 0 != (ret = nandroid_backup_partition_extended(backup_path, "/sdcard/.android_secure", 0))) return ret; } if (backup_cache && 0 != (ret = nandroid_backup_partition_extended(backup_path, "/cache", 0))) return ret; if (backup_sdext) { vol = volume_for_path("/sd-ext"); if (vol == NULL || 0 != stat(vol->device, &s)) { ui_print("No sd-ext found. Skipping backup of sd-ext.\n"); } else { if (0 != ensure_path_mounted("/sd-ext")) ui_print("Could not mount sd-ext. sd-ext backup may not be supported on this device. Skipping backup of sd-ext.\n"); else if (0 != (ret = nandroid_backup_partition(backup_path, "/sd-ext"))) return ret; } } #ifdef PHILZ_TOUCH_RECOVERY if (enable_md5sum) #endif { ui_print("Generating md5 sum...\n"); sprintf(tmp, "nandroid-md5.sh %s", backup_path); if (0 != (ret = __system(tmp))) { ui_print("Error while generating md5 sum!\n"); return ret; } } sprintf(tmp, "chmod -R 777 %s ; chmod -R u+r,u+w,g+r,g+w,o+r,o+w /sdcard/clockworkmod ; chmod u+x,g+x,o+x /sdcard/clockworkmod/backup ; chmod u+x,g+x,o+x /sdcard/clockworkmod/blobs", backup_path); __system(tmp); sync(); ui_set_background(BACKGROUND_ICON_NONE); ui_reset_progress(); ui_print("\nBackup complete!\n"); return 0; }
int nandroid_restore_partition_extended(const char* backup_path, const char* mount_point, int umount_when_finished) { int ret = 0; char* name = basename(mount_point); nandroid_restore_handler restore_handler = NULL; const char *filesystems[] = { "yaffs2", "ext2", "ext3", "ext4", "vfat", "rfs", NULL }; const char* backup_filesystem = NULL; Volume *vol = volume_for_path(mount_point); const char *device = NULL; if (vol != NULL) device = vol->device; char tmp[PATH_MAX]; sprintf(tmp, "%s/%s.img", backup_path, name); struct stat file_info; if (strcmp(backup_path, "-") == 0) { if (vol) backup_filesystem = vol->fs_type; restore_handler = tar_extract_wrapper; strcpy(tmp, "/proc/self/fd/0"); } else if (0 != (ret = statfs(tmp, &file_info))) { // can't find the backup, it may be the new backup format? // iterate through the backup types printf("找不到默认\n"); char *filesystem; int i = 0; while ((filesystem = filesystems[i]) != NULL) { sprintf(tmp, "%s/%s.%s.img", backup_path, name, filesystem); if (0 == (ret = statfs(tmp, &file_info))) { backup_filesystem = filesystem; restore_handler = unyaffs_wrapper; break; } sprintf(tmp, "%s/%s.%s.tar", backup_path, name, filesystem); if (0 == (ret = statfs(tmp, &file_info))) { backup_filesystem = filesystem; restore_handler = tar_extract_wrapper; break; } sprintf(tmp, "%s/%s.%s.dup", backup_path, name, filesystem); if (0 == (ret = statfs(tmp, &file_info))) { backup_filesystem = filesystem; restore_handler = dedupe_extract_wrapper; break; } i++; } if (backup_filesystem == NULL || restore_handler == NULL) { ui_print("%s.镜像没找到,因此跳过该处恢复. %s.\n", name, mount_point); return 0; } else { printf("找到新的可恢复镜像: %s\n", tmp); } } // If the fs_type of this volume is "auto" or mount_point is /data // and is_data_media, let's revert // to using a rm -rf, rather than trying to do a // ext3/ext4/whatever format. // This is because some phones (like DroidX) will freak out if you // reformat the /system or /data partitions, and not boot due to // a locked bootloader. // Other devices, like the Galaxy Nexus, XOOM, and Galaxy Tab 10.1 // have a /sdcard symlinked to /data/media. // Or of volume does not exist (.android_secure), just rm -rf. if (vol == NULL || 0 == strcmp(vol->fs_type, "auto")) backup_filesystem = NULL; if (0 == strcmp(vol->mount_point, "/data") && is_data_media()) backup_filesystem = NULL; ensure_directory(mount_point); int callback = stat("/sdcard/clockworkmod/.hidenandroidprogress", &file_info) != 0; ui_print("正在恢复 %s...\n", name); if (backup_filesystem == NULL) { if (0 != (ret = format_volume(mount_point))) { ui_print("格式化下列分区失败 %s!\n", mount_point); return ret; } } else if (0 != (ret = format_device(device, mount_point, backup_filesystem))) { ui_print("格式化下列分区失败 %s!\n", mount_point); return ret; } if (0 != (ret = ensure_path_mounted(mount_point))) { ui_print("挂载下列分区失败 %s!\n", mount_point); return ret; } if (restore_handler == NULL) restore_handler = get_restore_handler(mount_point); // override restore handler for undump if (strcmp(backup_path, "-") == 0) { restore_handler = tar_undump_wrapper; } if (restore_handler == NULL) { ui_print("找不到合适的方案\n"); return -2; } if (0 != (ret = restore_handler(tmp, mount_point, callback))) { ui_print("恢复失败: %s!\n", mount_point); return ret; } if (umount_when_finished) { ensure_path_unmounted(mount_point); } return 0; }
int nandroid_backup(const char* backup_path) { nandroid_backup_bitfield = 0; ui_set_background(BACKGROUND_ICON_INSTALLING); refresh_default_backup_handler(); if (ensure_path_mounted(backup_path) != 0) { return print_and_error("无法挂载备份时需要的存储器.\n"); } Volume* volume = volume_for_path(backup_path); if (NULL == volume) return print_and_error("找不到备份需要的存储器.\n"); if (is_data_media_volume_path(volume->mount_point)) volume = volume_for_path("/data"); int ret; struct statfs s; if (NULL != volume) { if (0 != (ret = statfs(volume->mount_point, &s))) return print_and_error("找不到备份路径,因此无法开始.\n"); uint64_t bavail = s.f_bavail; uint64_t bsize = s.f_bsize; uint64_t sdcard_free = bavail * bsize; uint64_t sdcard_free_mb = sdcard_free / (uint64_t)(1024 * 1024); ui_print("SD Card space free: %lluMB\n", sdcard_free_mb); if (sdcard_free_mb < 150) ui_print("可能是你的机器空间不足了,继续中...\n"); } char tmp[PATH_MAX]; ensure_directory(backup_path); if (0 != (ret = nandroid_backup_partition(backup_path, "/boot"))) return ret; if (0 != (ret = nandroid_backup_partition(backup_path, "/uboot"))) return ret; if (0 != (ret = nandroid_backup_partition(backup_path, "/recovery"))) return ret; Volume *vol = volume_for_path("/wimax"); if (vol != NULL && 0 == stat(vol->device, &s)) { char serialno[PROPERTY_VALUE_MAX]; ui_print("正在备份WiMAX...\n"); serialno[0] = 0; property_get("ro.serialno", serialno, ""); sprintf(tmp, "%s/wimax.%s.img", backup_path, serialno); ret = backup_raw_partition(vol->fs_type, vol->device, tmp); if (0 != ret) return print_and_error("打包或生成WiMAX镜像失败\n"); } if (0 != (ret = nandroid_backup_partition(backup_path, "/system"))) return ret; if (0 != (ret = nandroid_backup_partition(backup_path, "/data"))) return ret; if (has_datadata()) { if (0 != (ret = nandroid_backup_partition(backup_path, "/datadata"))) return ret; } if (is_data_media() || 0 != stat("/sdcard/.android_secure", &s)) { ui_print("没找到 /sdcard/.android_secure. 跳过外部程序备份.\n"); } else { if (0 != (ret = nandroid_backup_partition_extended(backup_path, "/sdcard/.android_secure", 0))) return ret; } if (0 != (ret = nandroid_backup_partition_extended(backup_path, "/cache", 0))) return ret; vol = volume_for_path("/sd-ext"); if (vol == NULL || 0 != stat(vol->device, &s)) { ui_print("没找到SD-EXT,因此跳过该处备份.\n"); } else { if (0 != ensure_path_mounted("/sd-ext")) ui_print("没法挂载SD-EXT,可能是你的机器不支持该选项,跳过该部分的备份\n"); else if (0 != (ret = nandroid_backup_partition(backup_path, "/sd-ext"))) return ret; } ui_print("生成md5 校验值...\n"); sprintf(tmp, "nandroid-md5.sh %s", backup_path); if (0 != (ret = __system(tmp))) { ui_print("MD5校验值生成失败\n"); return ret; } sprintf(tmp, "cp /tmp/recovery.log %s/recovery.log", backup_path); __system(tmp); sprintf(tmp, "chmod -R 777 %s ; chmod -R u+r,u+w,g+r,g+w,o+r,o+w /sdcard/clockworkmod ; chmod u+x,g+x,o+x /sdcard/clockworkmod/backup ; chmod u+x,g+x,o+x /sdcard/clockworkmod/blobs", backup_path); __system(tmp); sync(); ui_set_background(BACKGROUND_ICON_NONE); ui_reset_progress(); ui_print("\n备份完成!\n"); return 0; }
/* XXX Should better explicitely specify * uncomp_size and file_times instead of pfhdr! */ char *map_new_file (DWORD flags, char *filename, char *pathname_part, int size, WORD wFatDate, WORD wFatTime, NOTIFYPROC notify) { HANDLE hFile, hFileMapping; char *dst; FILETIME ft; try_again: if (!flags) flags = CREATE_NEW; hFile = CreateFile (filename, GENERIC_WRITE | GENERIC_READ, 0, NULL, flags, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) { DWORD x = GetLastError(); switch (x) { case ERROR_FILE_EXISTS: if (notify && notify (CAN_OVERWRITE, filename)) hFile = CreateFile (filename, GENERIC_WRITE | GENERIC_READ, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); else { if (notify) notify (FILE_OVERWRITTEN, filename); return NULL; } break; case ERROR_PATH_NOT_FOUND: if (ensure_directory (filename, pathname_part, notify)) goto try_again; else return FALSE; break; default: SetLastError (x); break; } } if (hFile == INVALID_HANDLE_VALUE) { if (notify) notify (SYSTEM_ERROR, "CreateFile (%s)", filename); return NULL; } if (notify) notify (FILE_CREATED, filename); DosDateTimeToFileTime (wFatDate, wFatTime, &ft); SetFileTime (hFile, &ft, &ft, &ft); if (size == 0) { /* We cannot map a zero-length file (Also it makes no sense */ CloseHandle (hFile); return NULL; } hFileMapping = CreateFileMapping (hFile, NULL, PAGE_READWRITE, 0, size, NULL); CloseHandle (hFile); if (hFileMapping == INVALID_HANDLE_VALUE) { if (notify) notify (SYSTEM_ERROR, "CreateFileMapping (%s)", filename); return NULL; } dst = MapViewOfFile (hFileMapping, FILE_MAP_WRITE, 0, 0, 0); CloseHandle (hFileMapping); if (!dst) { if (notify) notify (SYSTEM_ERROR, "MapViewOfFile (%s)", filename); return NULL; } return dst; }
int nandroid_backup(const char* backup_path) { nandroid_backup_bitfield = 0; ui_set_background(BACKGROUND_ICON_INSTALLING); refresh_default_backup_handler(); if (ensure_path_mounted(backup_path) != 0) { return print_and_error("Can't mount backup path.\n"); } Volume* volume = volume_for_path(backup_path); if (NULL == volume) return print_and_error("Unable to find volume for backup path.\n"); if (is_data_media_volume_path(volume->mount_point)) volume = volume_for_path("/data"); int ret; struct statfs s; if (NULL != volume) { if (0 != (ret = statfs(volume->mount_point, &s))) return print_and_error("Unable to stat backup path.\n"); uint64_t bavail = s.f_bavail; uint64_t bsize = s.f_bsize; uint64_t sdcard_free = bavail * bsize; uint64_t sdcard_free_mb = sdcard_free / (uint64_t)(1024 * 1024); ui_print("SD Card space free: %lluMB\n", sdcard_free_mb); if (sdcard_free_mb < 150) ui_print("There may not be enough free space to complete backup... continuing...\n"); } char tmp[PATH_MAX]; ensure_directory(backup_path); if (0 != (ret = nandroid_backup_partition(backup_path, "/boot"))) return ret; if (0 != (ret = nandroid_backup_partition(backup_path, "/recovery"))) return ret; Volume *vol = volume_for_path("/wimax"); if (vol != NULL && 0 == stat(vol->device, &s)) { char serialno[PROPERTY_VALUE_MAX]; ui_print("Backing up WiMAX...\n"); serialno[0] = 0; property_get("ro.serialno", serialno, ""); sprintf(tmp, "%s/wimax.%s.img", backup_path, serialno); ret = backup_raw_partition(vol->fs_type, vol->device, tmp); if (0 != ret) return print_and_error("Error while dumping WiMAX image!\n"); } if (0 != (ret = nandroid_backup_partition(backup_path, "/system"))) return ret; if (0 != (ret = nandroid_backup_partition(backup_path, "/preload"))) return ret; if (0 != (ret = nandroid_backup_partition(backup_path, "/data"))) return ret; if (has_datadata()) { if (0 != (ret = nandroid_backup_partition(backup_path, "/datadata"))) return ret; } if (is_data_media() || 0 != stat("/sdcard/.android_secure", &s)) { ui_print("No /sdcard/.android_secure found. Skipping backup of applications on external storage.\n"); } else { if (0 != (ret = nandroid_backup_partition_extended(backup_path, "/sdcard/.android_secure", 0))) return ret; } if (0 != (ret = nandroid_backup_partition_extended(backup_path, "/cache", 0))) return ret; vol = volume_for_path("/sd-ext"); if (vol == NULL || 0 != stat(vol->device, &s)) { ui_print("No sd-ext found. Skipping backup of sd-ext.\n"); } else { if (0 != ensure_path_mounted("/sd-ext")) ui_print("Could not mount sd-ext. sd-ext backup may not be supported on this device. Skipping backup of sd-ext.\n"); else if (0 != (ret = nandroid_backup_partition(backup_path, "/sd-ext"))) return ret; } ui_print("Generating md5 sum...\n"); sprintf(tmp, "nandroid-md5.sh %s", backup_path); if (0 != (ret = __system(tmp))) { ui_print("Error while generating md5 sum!\n"); return ret; } sprintf(tmp, "chmod -R 777 %s ; chmod -R u+r,u+w,g+r,g+w,o+r,o+w /sdcard/clockworkmod ; chmod u+x,g+x,o+x /sdcard/clockworkmod/backup ; chmod u+x,g+x,o+x /sdcard/clockworkmod/blobs", backup_path); __system(tmp); sync(); ui_set_background(BACKGROUND_ICON_NONE); ui_reset_progress(); ui_print("\nBackup complete!\n"); return 0; }
int nandroid_restore_partition_extended(const char* backup_path, const char* root, int umount_when_finished) { int ret = 0; char mount_point[PATH_MAX]; translate_root_path(root, mount_point, PATH_MAX); char* name = basename(mount_point); char tmp[PATH_MAX]; sprintf(tmp, "%s/%s.img", backup_path, name); struct stat file_info; if (0 != (ret = statfs(tmp, &file_info))) { ui_print("%s.img not found. Skipping restore of %s.\n", name, mount_point); return 0; } ensure_directory(mount_point); unyaffs_callback callback = NULL; if (0 != stat("/sdcard/clockworkmod/.hidenandroidprogress", &file_info)) { callback = yaffs_callback; } ui_print("Restoring %s...\n", name); /* if (0 != (ret = ensure_root_path_unmounted(root))) { ui_print("Can't unmount %s!\n", mount_point); return ret; } */ if (0 != (ret = format_root_device(root))) { ui_print("Error while formatting %s!\n", root); return ret; } if (0 != (ret = ensure_root_path_mounted(root))) { ui_print("Can't mount %s!\n", mount_point); return ret; } /* mumbozver if (0 != (ret = unyaffs(tmp, mount_point, callback))) { ui_print("Error while restoring %s!\n", mount_point); return ret; } */ char tmp1[PATH_MAX]; sprintf(tmp1, "%s/%s.img", backup_path, name); char tar1[PATH_MAX+35]; sprintf(tar1, "tar xpf %s -C /", tmp1); if (0 != (ret = __system (tar1))) { ui_print("Error while restoring %s!\n", mount_point); return ret; } if (umount_when_finished) { ensure_root_path_unmounted(root); } return 0; }
int nandroid_restore_partition_extended(const char* backup_path, const char* mount_point, int umount_when_finished) { int ret = 0; char* name = basename(mount_point); nandroid_restore_handler restore_handler = NULL; const char *filesystems[] = { "yaffs2", "ext2", "ext3", "ext4", "vfat", "rfs", NULL }; const char* backup_filesystem = NULL; Volume *vol = volume_for_path(mount_point); const char *device = NULL; if (vol != NULL) device = vol->device; char tmp[PATH_MAX]; sprintf(tmp, "%s/%s.img", backup_path, name); struct stat file_info; if (0 != (ret = statfs(tmp, &file_info))) { // can't find the backup, it may be the new backup format? // iterate through the backup types printf("couldn't find default\n"); char *filesystem; int i = 0; while ((filesystem = filesystems[i]) != NULL) { sprintf(tmp, "%s/%s.%s.img", backup_path, name, filesystem); if (0 == (ret = statfs(tmp, &file_info))) { backup_filesystem = filesystem; restore_handler = unyaffs_wrapper; break; } sprintf(tmp, "%s/%s.%s.tar", backup_path, name, filesystem); if (0 == (ret = statfs(tmp, &file_info))) { backup_filesystem = filesystem; restore_handler = tar_extract_wrapper; break; } i++; } if (backup_filesystem == NULL || restore_handler == NULL) { ui_print("%s.img not found. Skipping restore of %s.\n", name, mount_point); return 0; } else { printf("Found new backup image: %s\n", tmp); } // If the fs_type of this volume is "auto", let's revert to using a // rm -rf, rather than trying to do a ext3/ext4/whatever format. // This is because some phones (like DroidX) will freak out if you // reformat the /system or /data partitions, and not boot due to // a locked bootloader. // The "auto" fs type preserves the file system, and does not // trigger that lock. // Or of volume does not exist (.android_secure), just rm -rf. if (vol == NULL || 0 == strcmp(vol->fs_type, "auto")) backup_filesystem = NULL; } else { // Force legacy tar extraction to old CWM2 backup files restore_handler = tar_extract_wrapper_legacy; } ensure_directory(mount_point); int callback = stat("/sdcard/clockworkmod/.hidenandroidprogress", &file_info) != 0; ui_print("Restoring %s...\n", name); if (backup_filesystem == NULL) { if (0 != (ret = format_volume(mount_point))) { ui_print("Error while formatting %s!\n", mount_point); return ret; } } else if (0 != (ret = format_device(device, mount_point, backup_filesystem))) { ui_print("Error while formatting %s!\n", mount_point); return ret; } if (0 != (ret = ensure_path_mounted(mount_point))) { ui_print("Can't mount %s!\n", mount_point); return ret; } if (restore_handler == NULL) restore_handler = get_restore_handler(mount_point); if (restore_handler == NULL) { ui_print("Error finding an appropriate restore handler.\n"); return -2; } if (0 != (ret = restore_handler(tmp, mount_point, callback))) { ui_print("Error while restoring %s!\n", mount_point); return ret; } if (umount_when_finished) { ensure_path_unmounted(mount_point); } return 0; }
int nandroid_backup(const char* backup_path) { nandroid_backup_bitfield = 0; ui_set_background(BACKGROUND_ICON_INSTALLING); refresh_default_backup_handler(); if (ensure_path_mounted(backup_path) != 0) { #ifndef USE_CHINESE_FONT return print_and_error("Can't mount backup path.\n"); #else return print_and_error("无法挂载备份路径。\n"); #endif } Volume* volume; if (is_data_media_volume_path(backup_path)) volume = volume_for_path("/data"); else volume = volume_for_path(backup_path); if (NULL == volume) #ifndef USE_CHINESE_FONT return print_and_error("Unable to find volume for backup path.\n"); #else return print_and_error("无法找到备份路径所在卷。\n"); #endif int ret; struct statfs sfs; struct stat s; if (NULL != volume) { if (0 != (ret = statfs(volume->mount_point, &sfs))) #ifndef USE_CHINESE_FONT return print_and_error("Unable to stat backup path.\n"); #else return print_and_error("无法统计备份路径。\n"); #endif uint64_t bavail = sfs.f_bavail; uint64_t bsize = sfs.f_bsize; uint64_t sdcard_free = bavail * bsize; uint64_t sdcard_free_mb = sdcard_free / (uint64_t)(1024 * 1024); #ifndef USE_CHINESE_FONT ui_print("SD Card space free: %lluMB\n", sdcard_free_mb); #else ui_print("SD 卡剩余空间: %lluMB\n", sdcard_free_mb); #endif if (sdcard_free_mb < 150) #ifndef USE_CHINESE_FONT ui_print("There may not be enough free space to complete backup... continuing...\n"); #else ui_print("可能没有足够的空间完成备份... 继续...\n"); #endif } char tmp[PATH_MAX]; ensure_directory(backup_path); if (0 != (ret = nandroid_backup_partition(backup_path, "/boot"))) return ret; if (0 != (ret = nandroid_backup_partition(backup_path, "/recovery"))) return ret; Volume *vol = volume_for_path("/wimax"); if (vol != NULL && 0 == stat(vol->blk_device, &s)) { char serialno[PROPERTY_VALUE_MAX]; #ifndef USE_CHINESE_FONT ui_print("Backing up WiMAX...\n"); #else ui_print("正在备份 WiMAX...\n"); #endif serialno[0] = 0; property_get("ro.serialno", serialno, ""); sprintf(tmp, "%s/wimax.%s.img", backup_path, serialno); ret = backup_raw_partition(vol->fs_type, vol->blk_device, tmp); if (0 != ret) #ifndef USE_CHINESE_FONT return print_and_error("Error while dumping WiMAX image!\n"); #else return print_and_error("导出 WiMAX 镜像时出错!\n"); #endif } if (0 != (ret = nandroid_backup_partition(backup_path, "/system"))) return ret; if (0 != (ret = nandroid_backup_partition(backup_path, "/data"))) return ret; if (has_datadata()) { if (0 != (ret = nandroid_backup_partition(backup_path, "/datadata"))) return ret; } if (is_data_media() || 0 != stat(get_android_secure_path(), &s)) { #ifndef USE_CHINESE_FONT ui_print("No .android_secure found. Skipping backup of applications on external storage.\n"); #else ui_print("未找到 .android_secure。跳过备份安装在外置存储卡上的应用程序。\n"); #endif } else { if (0 != (ret = nandroid_backup_partition_extended(backup_path, get_android_secure_path(), 0))) return ret; } if (0 != (ret = nandroid_backup_partition_extended(backup_path, "/cache", 0))) return ret; vol = volume_for_path("/sd-ext"); if (vol == NULL || 0 != stat(vol->blk_device, &s)) { #ifndef USE_CHINESE_FONT LOGI("No sd-ext found. Skipping backup of sd-ext.\n"); #else LOGI("未找到 sd-ext。跳过对 sd-ext 的备份。\n"); #endif } else { if (0 != ensure_path_mounted("/sd-ext")) #ifndef USE_CHINESE_FONT LOGI("Could not mount sd-ext. sd-ext backup may not be supported on this device. Skipping backup of sd-ext.\n"); #else LOGI("无法挂载 sd-ext。此设备可能不支持对 sd-ext 进行备份,跳过对sd-ext的备份。\n"); #endif else if (0 != (ret = nandroid_backup_partition(backup_path, "/sd-ext"))) return ret; }
int twrp_backup(const char* backup_path) { // keep this for extra security and keep close to stock code // refresh_default_backup_handler() mounts /sdcard. We stat it in nandroid_backup_partition_extended() for callback nandroid_backup_bitfield = 0; refresh_default_backup_handler(); if (ensure_path_mounted(backup_path) != 0) return print_and_error("Can't mount backup path.\n", NANDROID_ERROR_GENERAL); int ret; struct statfs s; // refresh size stats for backup_path // this will also ensure volume for backup path != NULL if (0 != Get_Size_Via_statfs(backup_path)) return print_and_error("Unable to stat backup path.\n", NANDROID_ERROR_GENERAL); // estimate backup size and ensure we have enough free space available on backup_path if (check_backup_size(backup_path) < 0) return print_and_error("Not enough free space: backup cancelled.\n", NANDROID_ERROR_GENERAL); // moved after backup size check to fix pause before showing low space prompt // this is caused by friendly log view triggering on ui_set_background(BACKGROUND_ICON_INSTALLING) call // also, it is expected to have the background installing icon when we actually start backup ui_set_background(BACKGROUND_ICON_INSTALLING); nandroid_start_msec = timenow_msec(); // starts backup monitoring timer for total backup time #ifdef PHILZ_TOUCH_RECOVERY last_key_ev = nandroid_start_msec; // support dim screen timeout during nandroid operation #endif char tmp[PATH_MAX]; ensure_directory(backup_path, 0755); if (backup_boot && volume_for_path(BOOT_PARTITION_MOUNT_POINT) != NULL && 0 != (ret = nandroid_backup_partition(backup_path, BOOT_PARTITION_MOUNT_POINT))) return print_and_error(NULL, ret); if (backup_recovery && volume_for_path("/recovery") != NULL && 0 != (ret = nandroid_backup_partition(backup_path, "/recovery"))) return print_and_error(NULL, ret); #ifdef BOARD_USE_MTK_LAYOUT if ((backup_boot || backup_recovery) && volume_for_path("/uboot") != NULL && 0 != (ret = nandroid_backup_partition(backup_path, "/uboot"))) return print_and_error(NULL, ret); #endif Volume *vol = volume_for_path("/efs"); if (backup_efs && NULL != vol) { if (0 != (ret = nandroid_backup_partition(backup_path, "/efs"))) return print_and_error(NULL, ret); } vol = volume_for_path("/misc"); if (backup_misc && NULL != vol) { if (0 != (ret = nandroid_backup_partition(backup_path, "/misc"))) return print_and_error(NULL, ret); } vol = volume_for_path("/modem"); if (backup_modem && NULL != vol) { if (0 != (ret = nandroid_backup_partition(backup_path, "/modem"))) return print_and_error(NULL, ret); } vol = volume_for_path("/radio"); if (backup_radio && NULL != vol) { if (0 != (ret = nandroid_backup_partition(backup_path, "/radio"))) return print_and_error(NULL, ret); } if (backup_system && 0 != (ret = nandroid_backup_partition(backup_path, "/system"))) return print_and_error(NULL, ret); vol = volume_for_path("/preload"); if (backup_preload && NULL != vol) { if (0 != (ret = nandroid_backup_partition(backup_path, "/preload"))) return print_and_error(NULL, ret); } if (backup_data && 0 != (ret = nandroid_backup_partition(backup_path, "/data"))) return print_and_error(NULL, ret); if (has_datadata()) { if (backup_data && 0 != (ret = nandroid_backup_partition(backup_path, "/datadata"))) return print_and_error(NULL, ret); } // handle .android_secure on external and internal storage set_android_secure_path(tmp); if (backup_data && android_secure_ext) { if (0 != (ret = nandroid_backup_partition_extended(backup_path, tmp, 0))) return print_and_error(NULL, ret); } if (backup_cache && 0 != (ret = nandroid_backup_partition_extended(backup_path, "/cache", 0))) return print_and_error(NULL, ret); if (backup_sdext) { if (0 != ensure_path_mounted("/sd-ext")) { LOGI("No sd-ext found. Skipping backup of sd-ext.\n"); } else if (0 != (ret = nandroid_backup_partition(backup_path, "/sd-ext"))) { return print_and_error(NULL, ret); } } // handle extra partitions int i; int extra_partitions_num = get_extra_partitions_state(); for (i = 0; i < extra_partitions_num; ++i) { if (extra_partition[i].backup_state && 0 != (ret = nandroid_backup_partition(backup_path, extra_partition[i].mount_point))) return print_and_error(NULL, ret); } if (enable_md5sum.value) { if (0 != (ret = gen_twrp_md5sum(backup_path))) return print_and_error(NULL, ret); } sprintf(tmp, "chmod -R 777 %s", backup_path); __system(tmp); finish_nandroid_job(); show_backup_stats(backup_path); if (reboot_after_nandroid) reboot_main_system(ANDROID_RB_RESTART, 0, 0); return 0; }
// 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; }
int web_main(void * _ed, struct MHD_Connection * con, const char * url, const char * method, const char * version, const char *upload_data, size_t * upload_data_size, void ** con_cls){ UNUSED(url); UNUSED(version); UNUSED(upload_data); UNUSED(upload_data_size); UNUSED(method); UNUSED(con_cls); UNUSED(_ed); const char * file = "page.html"; bool style_loc = strcmp((char *) url + 1, "style.css") == 0; if(style_loc) file = "style.css"; else if(0 == strcmp((char *) url + 1, (char *) "favicon.png")) file = "favicon.png"; char fnamebuffer[100]; logd("'%s' %s %s %i\n", url, method, version, upload_data_size); logd("File: %s\n", file); if(url == strstr(url, "/sharesinfo")){ // Send back json code describing all the available shares. file = "shareinfo_data"; dirscan dir = scan_directories("shareinfo"); FILE * outfile = fopen(file, "w"); fprintf(outfile, "["); for(size_t i = 0; i < dir.cnt; i++){ logd("looking in: %s\n", dir.files[i]); char fnamebuffer2[100]; sprintf(fnamebuffer2, "shareinfo/%s", dir.files[i]); void * rdbuffer = read_file_to_string(fnamebuffer2); ASSERT(rdbuffer != NULL); void *ptr = rdbuffer; char * dirname = udpc_unpack_string(&ptr); char * name = udpc_unpack_string(&ptr); char * user = udpc_unpack_string(&ptr); fprintf(outfile, "{\"path\": \"%s\", \"name\":\"%s\", \"user\":\"%s\"}%s\n",dirname, name, user, (i == dir.cnt -1) ? "" : ","); dealloc(rdbuffer); } fprintf(outfile, "]"); fclose(outfile); dirscan_clean(&dir); }else if(url == strstr(url,"/shares/")){ // fetch the active shares item inside the shares folder char * shareid = (char *) url + strlen("/shares/"); logd("Shareid: %s\n", shareid); char * shareinfo_filename = fmtstr("shareinfo/%s", shareid); void * buffer = read_file_to_string(shareinfo_filename); if(buffer == NULL) goto error; void * bufptr = buffer; char * dir = udpc_unpack_string(&bufptr); char * name = udpc_unpack_string(&bufptr); char * user = udpc_unpack_string(&bufptr); service_descriptor sd; if(!udpc_get_service_descriptor(user, &sd)){ logd("Unable to parse service name: '%s'\n", user); dealloc(buffer); goto error; } logd("path: %s, name: %s, user: %s\n", dir, name, user); update_dirfile(dir, name, user); sprintf(fnamebuffer, "shares/%s.json", name); dealloc(buffer); logd("Sending: %s\n", fnamebuffer); file = fnamebuffer; } if(strcmp(url, "/add_share") == 0){ const char * path = MHD_lookup_connection_value(con, MHD_GET_ARGUMENT_KIND, "path"); const char * name = MHD_lookup_connection_value(con, MHD_GET_ARGUMENT_KIND, "name"); const char * user = MHD_lookup_connection_value(con, MHD_GET_ARGUMENT_KIND, "user"); logd("path: %s, name: %s, user: %s\n", path, name, user); if(path == NULL || name == NULL || user == NULL){ goto error; } service_descriptor sd; if(!udpc_get_service_descriptor(user, &sd)){ logd("Unable to parse service name: '%s'\n", user); goto error; } logd("Service descriptor seems ok \n"); ensure_directory("shareinfo/"); char * sharepath = fmtstr("shareinfo/%s", name); struct stat filest; stat(sharepath, &filest); dealloc(sharepath); if(S_ISREG(filest.st_mode)){ logd("File exists!\n"); }else{ struct stat dirst; stat(path, &dirst); if(!S_ISDIR(dirst.st_mode)){ logd("Dir does not exist.. creating a new one..\n"); int path_len = strlen(path); if(path[path_len] !='/'){ char * npath = fmtstr("%s/", path); ensure_directory(npath); dealloc(npath); }else{ ensure_directory(path); } } logd("Updating dirfile!\n"); update_dirfile(path, name, user); logd("Done..\n"); } const char * r = "\"OK\""; struct MHD_Response * response = MHD_create_response_from_data(strlen(r), (void *) r, 0, MHD_NO); int ret = MHD_queue_response(con, MHD_HTTP_OK, response); MHD_destroy_response(response); return ret; } size_t filesize = 0; void * pg = read_file_to_buffer(file, &filesize); struct MHD_Response * response = MHD_create_response_from_data(filesize, pg, 1, MHD_NO); int ret = MHD_queue_response(con, MHD_HTTP_OK, response); MHD_destroy_response(response); return ret; error:; const char * error_str = "<html><body>400</body></html>"; response = MHD_create_response_from_data(strlen(error_str) + 1, (void *) error_str, 0, MHD_NO); ret = MHD_queue_response(con, MHD_HTTP_BAD_REQUEST, response); MHD_destroy_response(response); return ret; }