1e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn// Copyright 2009 The Android Open Source Project 2e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 3e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn#include <stdio.h> 4e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn#include <stdlib.h> 5e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn#include <stdarg.h> 6e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn#include <string.h> 7e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn#include <unistd.h> 8e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn#include <fcntl.h> 9e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn#include <time.h> 10e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn#include <dirent.h> 11e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn#include <errno.h> 12e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn#include <assert.h> 13e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn#include <ctype.h> 14e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn#include <utime.h> 15e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn#include <sys/stat.h> 16e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn#include <sys/types.h> 17d7c8672ccc8ccd1f99da60accc63d6817d41ac52Olivier Bailly#include <stdint.h> 18e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 19e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn#include <cutils/properties.h> 20e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 21e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn#include <private/android_filesystem_config.h> 22e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 23e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn#ifndef PATH_MAX 24e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn#define PATH_MAX 4096 25e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn#endif 26e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 27e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn// First version. 28e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn#define FILE_VERSION_1 0xffff0001 29e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 30e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn// Introduces backup all option to header. 31e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn#define FILE_VERSION_2 0xffff0002 32e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 33e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn#define FILE_VERSION FILE_VERSION_2 34e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 35e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackbornnamespace android { 36e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 37e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackbornstatic char nameBuffer[PATH_MAX]; 38e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackbornstatic struct stat statBuffer; 39e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 40e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackbornstatic char copyBuffer[8192]; 410ba48a5402926b23f2459ce5039d3fe75938c0f4Amith Yamasanistatic char *backupFilePath = NULL; 42e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 43e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackbornstatic uint32_t inputFileVersion; 44e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 45e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackbornstatic int opt_backupAll; 46e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 47e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn#define SPECIAL_NO_TOUCH 0 48e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn#define SPECIAL_NO_BACKUP 1 49e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 50e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackbornstruct special_dir { 51e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn const char* path; 52e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn int type; 53e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn}; 54e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 55e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn/* Directory paths that we will not backup/restore */ 56e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackbornstatic const struct special_dir SKIP_PATHS[] = { 57e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn { "/data/misc", SPECIAL_NO_TOUCH }, 58e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn { "/data/system/batterystats.bin", SPECIAL_NO_TOUCH }, 59e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn { "/data/system/location", SPECIAL_NO_TOUCH }, 60e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn { "/data/dalvik-cache", SPECIAL_NO_BACKUP }, 61e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn { NULL, 0 }, 62e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn}; 63e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 64e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn/* This is just copied from the shell's built-in wipe command. */ 65e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackbornstatic int wipe (const char *path) 66e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn{ 67e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn DIR *dir; 68e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn struct dirent *de; 69e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn int ret; 70e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn int i; 71e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 72e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn dir = opendir(path); 73e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 74e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (dir == NULL) { 75e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn fprintf (stderr, "Error opendir'ing %s: %s\n", 76e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn path, strerror(errno)); 77e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn return 0; 78e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 79e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 80e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn char *filenameOffset; 81e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 82e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn strcpy(nameBuffer, path); 83e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn strcat(nameBuffer, "/"); 84e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 85e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn filenameOffset = nameBuffer + strlen(nameBuffer); 86e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 87e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn for (;;) { 88e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn de = readdir(dir); 89e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 90e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (de == NULL) { 91e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn break; 92e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 93e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 94e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (0 == strcmp(de->d_name, ".") 95e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn || 0 == strcmp(de->d_name, "..") 96e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn || 0 == strcmp(de->d_name, "lost+found") 97e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn ) { 98e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn continue; 99e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 100e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 101e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn strcpy(filenameOffset, de->d_name); 102e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn bool noBackup = false; 103e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 104e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn /* See if this is a path we should skip. */ 105e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn for (i = 0; SKIP_PATHS[i].path; i++) { 106e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (strcmp(SKIP_PATHS[i].path, nameBuffer) == 0) { 107e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (opt_backupAll || SKIP_PATHS[i].type == SPECIAL_NO_BACKUP) { 108e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn // In this case we didn't back up the directory -- 109e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn // we do want to wipe its contents, but not the 110e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn // directory itself, since the restore file won't 111e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn // contain the directory. 112e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn noBackup = true; 113e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 114e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn break; 115e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 116e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 117e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 118e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (!noBackup && SKIP_PATHS[i].path != NULL) { 119e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn // This is a SPECIAL_NO_TOUCH directory. 120e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn continue; 121e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 122e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 123e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn ret = lstat (nameBuffer, &statBuffer); 124e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 125e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (ret != 0) { 126e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn fprintf(stderr, "warning -- stat() error on '%s': %s\n", 127e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn nameBuffer, strerror(errno)); 128e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn continue; 129e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 130e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 131e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if(S_ISDIR(statBuffer.st_mode)) { 132e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn int i; 133e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn char *newpath; 134e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 135e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn newpath = strdup(nameBuffer); 136e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (wipe(newpath) == 0) { 137e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn free(newpath); 138e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn closedir(dir); 139e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn return 0; 140e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 141e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 142e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (!noBackup) { 143e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn ret = rmdir(newpath); 144e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (ret != 0) { 145e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn fprintf(stderr, "warning -- rmdir() error on '%s': %s\n", 146e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn newpath, strerror(errno)); 147e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 148e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 149e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 150e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn free(newpath); 151e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 152e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn strcpy(nameBuffer, path); 153e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn strcat(nameBuffer, "/"); 154e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 155e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } else { 1560ba48a5402926b23f2459ce5039d3fe75938c0f4Amith Yamasani // Don't delete the backup file 1570ba48a5402926b23f2459ce5039d3fe75938c0f4Amith Yamasani if (backupFilePath && strcmp(backupFilePath, nameBuffer) == 0) { 1580ba48a5402926b23f2459ce5039d3fe75938c0f4Amith Yamasani continue; 1590ba48a5402926b23f2459ce5039d3fe75938c0f4Amith Yamasani } 160e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn ret = unlink(nameBuffer); 161e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 162e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (ret != 0) { 163e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn fprintf(stderr, "warning -- unlink() error on '%s': %s\n", 164e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn nameBuffer, strerror(errno)); 165e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 166e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 167e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 168e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 169e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn closedir(dir); 170e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 171e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn return 1; 172e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn} 173e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 174e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackbornstatic int write_int32(FILE* fh, int32_t val) 175e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn{ 176e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn int res = fwrite(&val, 1, sizeof(val), fh); 177e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (res != sizeof(val)) { 178e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn fprintf(stderr, "unable to write int32 (%d bytes): %s\n", res, strerror(errno)); 179e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn return 0; 180e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 181e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 182e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn return 1; 183e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn} 184e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 185e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackbornstatic int write_int64(FILE* fh, int64_t val) 186e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn{ 187e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn int res = fwrite(&val, 1, sizeof(val), fh); 188e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (res != sizeof(val)) { 189e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn fprintf(stderr, "unable to write int64 (%d bytes): %s\n", res, strerror(errno)); 190e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn return 0; 191e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 192e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 193e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn return 1; 194e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn} 195e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 196e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackbornstatic int copy_file(FILE* dest, FILE* src, off_t size, const char* destName, 197e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn const char* srcName) 198e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn{ 199e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn errno = 0; 200e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 201e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn off_t origSize = size; 202e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 203e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn while (size > 0) { 204e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn int amt = size > (off_t)sizeof(copyBuffer) ? sizeof(copyBuffer) : (int)size; 205e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn int readLen = fread(copyBuffer, 1, amt, src); 206e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (readLen <= 0) { 207e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (srcName != NULL) { 208e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn fprintf(stderr, "unable to read source (%d of %ld bytes) file '%s': %s\n", 209e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn amt, origSize, srcName, errno != 0 ? strerror(errno) : "unexpected EOF"); 210e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } else { 211e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn fprintf(stderr, "unable to read buffer (%d of %ld bytes): %s\n", 212e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn amt, origSize, errno != 0 ? strerror(errno) : "unexpected EOF"); 213e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 214e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn return 0; 215e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 216e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn int writeLen = fwrite(copyBuffer, 1, readLen, dest); 217e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (writeLen != readLen) { 218e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (destName != NULL) { 219e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn fprintf(stderr, "unable to write file (%d of %d bytes) '%s': '%s'\n", 220e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn writeLen, readLen, destName, strerror(errno)); 221e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } else { 222e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn fprintf(stderr, "unable to write buffer (%d of %d bytes): '%s'\n", 223e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn writeLen, readLen, strerror(errno)); 224e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 225e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn return 0; 226e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 227e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn size -= readLen; 228e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 229e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn return 1; 230e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn} 231e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 232e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn#define TYPE_END 0 233e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn#define TYPE_DIR 1 234e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn#define TYPE_FILE 2 235e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 236e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackbornstatic int write_header(FILE* fh, int type, const char* path, const struct stat* st) 237e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn{ 238e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn int pathLen = strlen(path); 239e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (!write_int32(fh, type)) return 0; 240e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (!write_int32(fh, pathLen)) return 0; 241e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (fwrite(path, 1, pathLen, fh) != (size_t)pathLen) { 242e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn fprintf(stderr, "unable to write: %s\n", strerror(errno)); 243e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn return 0; 244e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 245e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 246e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (!write_int32(fh, st->st_uid)) return 0; 247e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (!write_int32(fh, st->st_gid)) return 0; 248e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (!write_int32(fh, st->st_mode)) return 0; 249e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (!write_int64(fh, ((int64_t)st->st_atime)*1000*1000*1000)) return 0; 250e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (!write_int64(fh, ((int64_t)st->st_mtime)*1000*1000*1000)) return 0; 251e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (!write_int64(fh, ((int64_t)st->st_ctime)*1000*1000*1000)) return 0; 252e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 253e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn return 1; 254e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn} 255e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 256e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackbornstatic int backup_dir(FILE* fh, const char* srcPath) 257e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn{ 258e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn DIR *dir; 259e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn struct dirent *de; 260e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn char* fullPath = NULL; 261e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn int srcLen = strlen(srcPath); 262e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn int result = 1; 263e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn int i; 264e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 265e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn dir = opendir(srcPath); 266e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 267e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (dir == NULL) { 268e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn fprintf (stderr, "error opendir'ing '%s': %s\n", 269e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn srcPath, strerror(errno)); 270e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn return 0; 271e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 272e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 273e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn for (;;) { 274e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn de = readdir(dir); 275e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 276e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (de == NULL) { 277e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn break; 278e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 279e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 280e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (0 == strcmp(de->d_name, ".") 281e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn || 0 == strcmp(de->d_name, "..") 282e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn || 0 == strcmp(de->d_name, "lost+found") 283e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn ) { 284e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn continue; 285e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 286e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 2870ba48a5402926b23f2459ce5039d3fe75938c0f4Amith Yamasani if (fullPath != NULL) { 288e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn free(fullPath); 289e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 290e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn fullPath = (char*)malloc(srcLen + strlen(de->d_name) + 2); 291e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn strcpy(fullPath, srcPath); 292e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn fullPath[srcLen] = '/'; 293e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn strcpy(fullPath+srcLen+1, de->d_name); 294e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 295e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn /* See if this is a path we should skip. */ 296e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (!opt_backupAll) { 297e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn for (i = 0; SKIP_PATHS[i].path; i++) { 298e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (strcmp(SKIP_PATHS[i].path, fullPath) == 0) { 299e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn break; 300e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 301e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 302e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (SKIP_PATHS[i].path != NULL) { 303e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn continue; 304e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 305e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 306e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 307e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn int ret = lstat(fullPath, &statBuffer); 308e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 309e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (ret != 0) { 310e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn fprintf(stderr, "stat() error on '%s': %s\n", 311e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn fullPath, strerror(errno)); 312e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn result = 0; 313e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn goto done; 314e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 315e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 316e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if(S_ISDIR(statBuffer.st_mode)) { 317e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn printf("Saving dir %s...\n", fullPath); 318e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 319e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (write_header(fh, TYPE_DIR, fullPath, &statBuffer) == 0) { 320e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn result = 0; 321e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn goto done; 322e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 323e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (backup_dir(fh, fullPath) == 0) { 324e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn result = 0; 325e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn goto done; 326e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 327738b75864123b85c0aec2433571d74ea09df9b02Dianne Hackborn } else if (S_ISREG(statBuffer.st_mode)) { 3280ba48a5402926b23f2459ce5039d3fe75938c0f4Amith Yamasani // Skip the backup file 3290ba48a5402926b23f2459ce5039d3fe75938c0f4Amith Yamasani if (backupFilePath && strcmp(fullPath, backupFilePath) == 0) { 3300ba48a5402926b23f2459ce5039d3fe75938c0f4Amith Yamasani printf("Skipping backup file %s...\n", backupFilePath); 3310ba48a5402926b23f2459ce5039d3fe75938c0f4Amith Yamasani continue; 3320ba48a5402926b23f2459ce5039d3fe75938c0f4Amith Yamasani } else { 3330ba48a5402926b23f2459ce5039d3fe75938c0f4Amith Yamasani printf("Saving file %s...\n", fullPath); 3340ba48a5402926b23f2459ce5039d3fe75938c0f4Amith Yamasani } 335e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (write_header(fh, TYPE_FILE, fullPath, &statBuffer) == 0) { 336e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn result = 0; 337e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn goto done; 338e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 339e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 340e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn off_t size = statBuffer.st_size; 341e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (!write_int64(fh, size)) { 342e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn result = 0; 343e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn goto done; 344e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 345e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 346e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn FILE* src = fopen(fullPath, "r"); 347e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (src == NULL) { 348e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn fprintf(stderr, "unable to open source file '%s': %s\n", 349e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn fullPath, strerror(errno)); 350e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn result = 0; 351e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn goto done; 352e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 353e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 354e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn int copyres = copy_file(fh, src, size, NULL, fullPath); 355e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn fclose(src); 356e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (!copyres) { 357e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn result = 0; 358e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn goto done; 359e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 360e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 361e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 362e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 363e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborndone: 364e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (fullPath != NULL) { 365e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn free(fullPath); 366e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 367e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 368e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn closedir(dir); 369e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 370e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn return result; 371e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn} 372e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 373e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackbornstatic int backup_data(const char* destPath) 374e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn{ 375e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn int res = -1; 376e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 377e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn FILE* fh = fopen(destPath, "w"); 378e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (fh == NULL) { 379e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn fprintf(stderr, "unable to open destination '%s': %s\n", 380e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn destPath, strerror(errno)); 381e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn return -1; 382e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 383e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 384e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn printf("Backing up /data to %s...\n", destPath); 385e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 3860ba48a5402926b23f2459ce5039d3fe75938c0f4Amith Yamasani // The path that shouldn't be backed up 3870ba48a5402926b23f2459ce5039d3fe75938c0f4Amith Yamasani backupFilePath = strdup(destPath); 3880ba48a5402926b23f2459ce5039d3fe75938c0f4Amith Yamasani 389e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (!write_int32(fh, FILE_VERSION)) goto done; 390e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (!write_int32(fh, opt_backupAll)) goto done; 391e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (!backup_dir(fh, "/data")) goto done; 392e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (!write_int32(fh, 0)) goto done; 393e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 394e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn res = 0; 395e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 396e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborndone: 397e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (fflush(fh) != 0) { 398e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn fprintf(stderr, "error flushing destination '%s': %s\n", 399e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn destPath, strerror(errno)); 400e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn res = -1; 401e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn goto donedone; 402e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 403e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (fsync(fileno(fh)) != 0) { 404e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn fprintf(stderr, "error syncing destination '%s': %s\n", 405e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn destPath, strerror(errno)); 406e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn res = -1; 407e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn goto donedone; 408e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 409e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn fclose(fh); 410e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn sync(); 411e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 412e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborndonedone: 413e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn return res; 414e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn} 415e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 416e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackbornstatic int32_t read_int32(FILE* fh, int32_t defVal) 417e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn{ 418e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn int32_t val; 419e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (fread(&val, 1, sizeof(val), fh) != sizeof(val)) { 420e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn fprintf(stderr, "unable to read: %s\n", strerror(errno)); 421e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn return defVal; 422e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 423e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 424e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn return val; 425e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn} 426e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 427e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackbornstatic int64_t read_int64(FILE* fh, int64_t defVal) 428e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn{ 429e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn int64_t val; 430e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (fread(&val, 1, sizeof(val), fh) != sizeof(val)) { 431e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn fprintf(stderr, "unable to read: %s\n", strerror(errno)); 432e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn return defVal; 433e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 434e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 435e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn return val; 436e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn} 437e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 438e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackbornstatic int read_header(FILE* fh, int* type, char** path, struct stat* st) 439e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn{ 440e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn *type = read_int32(fh, -1); 441e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (*type == TYPE_END) { 442e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn return 1; 443e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 444e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 445e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (*type < 0) { 446e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn fprintf(stderr, "bad token %d in restore file\n", *type); 447e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn return 0; 448e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 449e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 450e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn int32_t pathLen = read_int32(fh, -1); 451e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (pathLen <= 0) { 452e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn fprintf(stderr, "bad path length %d in restore file\n", pathLen); 453e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn return 0; 454e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 455e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn char* readPath = (char*)malloc(pathLen+1); 456e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (fread(readPath, 1, pathLen, fh) != (size_t)pathLen) { 457e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn fprintf(stderr, "truncated path in restore file\n"); 458e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn free(readPath); 459e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn return 0; 460e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 461e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn readPath[pathLen] = 0; 462e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn *path = readPath; 463e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 464e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn st->st_uid = read_int32(fh, -1); 465e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (st->st_uid == (uid_t)-1) { 466e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn fprintf(stderr, "bad uid in restore file at '%s'\n", readPath); 467e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn return 0; 468e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 469e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn st->st_gid = read_int32(fh, -1); 470e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (st->st_gid == (gid_t)-1) { 471e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn fprintf(stderr, "bad gid in restore file at '%s'\n", readPath); 472e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn return 0; 473e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 474e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn st->st_mode = read_int32(fh, -1); 475e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (st->st_mode == (mode_t)-1) { 476e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn fprintf(stderr, "bad mode in restore file at '%s'\n", readPath); 477e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn return 0; 478e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 479e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn int64_t ltime = read_int64(fh, -1); 480e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (ltime < 0) { 481e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn fprintf(stderr, "bad atime in restore file at '%s'\n", readPath); 482e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn return 0; 483e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 484e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn st->st_atime = (time_t)(ltime/1000/1000/1000); 485e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn ltime = read_int64(fh, -1); 486e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (ltime < 0) { 487e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn fprintf(stderr, "bad mtime in restore file at '%s'\n", readPath); 488e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn return 0; 489e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 490e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn st->st_mtime = (time_t)(ltime/1000/1000/1000); 491e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn ltime = read_int64(fh, -1); 492e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (ltime < 0) { 493e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn fprintf(stderr, "bad ctime in restore file at '%s'\n", readPath); 494e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn return 0; 495e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 496e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn st->st_ctime = (time_t)(ltime/1000/1000/1000); 497e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 498e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn st->st_mode &= (S_IRWXU|S_IRWXG|S_IRWXO); 499e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 500e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn return 1; 501e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn} 502e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 503e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackbornstatic int restore_data(const char* srcPath) 504e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn{ 505e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn int res = -1; 506e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 507e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn FILE* fh = fopen(srcPath, "r"); 508e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (fh == NULL) { 509e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn fprintf(stderr, "Unable to open source '%s': %s\n", 510e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn srcPath, strerror(errno)); 511e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn return -1; 512e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 513e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 514e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn inputFileVersion = read_int32(fh, 0); 515e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (inputFileVersion < FILE_VERSION_1 || inputFileVersion > FILE_VERSION) { 516e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn fprintf(stderr, "Restore file has bad version: 0x%x\n", inputFileVersion); 517e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn goto done; 518e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 519e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 520e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (inputFileVersion >= FILE_VERSION_2) { 521e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn opt_backupAll = read_int32(fh, 0); 522e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } else { 523e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn opt_backupAll = 0; 524e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 5250ba48a5402926b23f2459ce5039d3fe75938c0f4Amith Yamasani 5260ba48a5402926b23f2459ce5039d3fe75938c0f4Amith Yamasani // The path that shouldn't be deleted 5270ba48a5402926b23f2459ce5039d3fe75938c0f4Amith Yamasani backupFilePath = strdup(srcPath); 528e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 529e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn printf("Wiping contents of /data...\n"); 530e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (!wipe("/data")) { 531e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn goto done; 532e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 533e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 534e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn printf("Restoring from %s to /data...\n", srcPath); 535e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 536e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn while (1) { 537e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn int type; 538e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn char* path = NULL; 539e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (read_header(fh, &type, &path, &statBuffer) == 0) { 540e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn goto done; 541e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 542e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (type == 0) { 543e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn break; 544e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 545e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 546e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn const char* typeName = "?"; 547e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 548e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (type == TYPE_DIR) { 549e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn typeName = "dir"; 550e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 551e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn printf("Restoring dir %s...\n", path); 552e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 553e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (mkdir(path, statBuffer.st_mode) != 0) { 554e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (errno != EEXIST) { 555e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn fprintf(stderr, "unable to create directory '%s': %s\n", 556e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn path, strerror(errno)); 557e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn free(path); 558e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn goto done; 559e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 560e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 561e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 562e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } else if (type == TYPE_FILE) { 563e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn typeName = "file"; 564e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn off_t size = read_int64(fh, -1); 565e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (size < 0) { 566e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn fprintf(stderr, "bad file size %ld in restore file\n", size); 567e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn free(path); 568e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn goto done; 569e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 570e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 571e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn printf("Restoring file %s...\n", path); 572e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 573e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn FILE* dest = fopen(path, "w"); 574e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (dest == NULL) { 575e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn fprintf(stderr, "unable to open destination file '%s': %s\n", 576e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn path, strerror(errno)); 577e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn free(path); 578e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn goto done; 579e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 580e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 581e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn int copyres = copy_file(dest, fh, size, path, NULL); 582e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn fclose(dest); 583e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (!copyres) { 584e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn free(path); 585e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn goto done; 586e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 587e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 588e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } else { 589e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn fprintf(stderr, "unknown node type %d\n", type); 590e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn goto done; 591e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 592e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 593e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn // Do this even for directories, since the dir may have already existed 594e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn // so we need to make sure it gets the correct mode. 595e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (chmod(path, statBuffer.st_mode&(S_IRWXU|S_IRWXG|S_IRWXO)) != 0) { 596e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn fprintf(stderr, "unable to chmod destination %s '%s' to 0x%x: %s\n", 597e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn typeName, path, statBuffer.st_mode, strerror(errno)); 598e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn free(path); 599e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn goto done; 600e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 601e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 602e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (chown(path, statBuffer.st_uid, statBuffer.st_gid) != 0) { 603e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn fprintf(stderr, "unable to chown destination %s '%s' to uid %d / gid %d: %s\n", 604e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn typeName, path, (int)statBuffer.st_uid, (int)statBuffer.st_gid, strerror(errno)); 605e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn free(path); 606e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn goto done; 607e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 608e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 609e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn struct utimbuf timbuf; 610e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn timbuf.actime = statBuffer.st_atime; 611e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn timbuf.modtime = statBuffer.st_mtime; 612e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (utime(path, &timbuf) != 0) { 613e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn fprintf(stderr, "unable to utime destination %s '%s': %s\n", 614e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn typeName, path, strerror(errno)); 615e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn free(path); 616e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn goto done; 617e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 618e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 619e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 620e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn free(path); 621e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 622e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 623e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn res = 0; 624e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 625e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborndone: 626e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn fclose(fh); 627e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 628e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn return res; 629e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn} 630e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 631e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackbornstatic void show_help(const char *cmd) 632e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn{ 633e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn fprintf(stderr,"Usage: %s COMMAND [options] [backup-file-path]\n", cmd); 634e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 635e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn fprintf(stderr, "commands are:\n" 636e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn " help Show this help text.\n" 637e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn " backup Perform a backup of /data.\n" 638e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn " restore Perform a restore of /data.\n"); 639e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn fprintf(stderr, "options include:\n" 640e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn " -h Show this help text.\n" 641e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn " -a Backup all files.\n"); 642e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn fprintf(stderr, "\nThe %s command allows you to perform low-level\n" 643e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn "backup and restore of the /data partition. This is\n" 644e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn "where all user data is kept, allowing for a fairly\n" 645e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn "complete restore of a device's state. Note that\n" 646e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn "because this is low-level, it will only work across\n" 647e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn "builds of the same (or very similar) device software.\n", 648e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn cmd); 649e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn} 650e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 651e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn} /* namespace android */ 652e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 653e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackbornint main (int argc, char **argv) 654e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn{ 655e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn int restore = 0; 656e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 657e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (getuid() != AID_ROOT) { 658e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn fprintf(stderr, "error -- %s must run as root\n", argv[0]); 659e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn exit(-1); 660e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 661e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 662e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (argc < 2) { 663e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn fprintf(stderr, "No command specified.\n"); 664e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn android::show_help(argv[0]); 665e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn exit(-1); 666e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 667e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 668e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (0 == strcmp(argv[1], "restore")) { 669e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn restore = 1; 670e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } else if (0 == strcmp(argv[1], "help")) { 671e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn android::show_help(argv[0]); 672e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn exit(0); 673e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } else if (0 != strcmp(argv[1], "backup")) { 674e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn fprintf(stderr, "Unknown command: %s\n", argv[1]); 675e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn android::show_help(argv[0]); 676e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn exit(-1); 677e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 678e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 679e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn android::opt_backupAll = 0; 680e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 681e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn optind = 2; 682e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 683e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn for (;;) { 684e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn int ret; 685e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 686e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn ret = getopt(argc, argv, "ah"); 687e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 688e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (ret < 0) { 689e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn break; 690e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 691e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 692e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn switch(ret) { 693e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn case 'a': 694e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn android::opt_backupAll = 1; 695e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (restore) fprintf(stderr, "Warning: -a option ignored on restore\n"); 696e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn break; 697e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn case 'h': 698e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn android::show_help(argv[0]); 699e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn exit(0); 700e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn break; 701e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 702e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn default: 703e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn fprintf(stderr,"Unrecognized Option\n"); 704e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn android::show_help(argv[0]); 705e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn exit(-1); 706e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn break; 707e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 708e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 709e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 710e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn const char* backupFile = "/sdcard/backup.dat"; 711e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 712e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (argc > optind) { 713e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn backupFile = argv[optind]; 714e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn optind++; 715e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (argc != optind) { 716e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn fprintf(stderr, "Too many arguments\n"); 717e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn android::show_help(argv[0]); 718e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn exit(-1); 719e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 720e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 721e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 722e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn printf("Stopping system...\n"); 723e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn property_set("ctl.stop", "runtime"); 724e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn property_set("ctl.stop", "zygote"); 725e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn sleep(1); 726e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 727e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn int res; 728e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (restore) { 729e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn res = android::restore_data(backupFile); 730e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (res != 0) { 731e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn // Don't restart system, since the data partition is hosed. 732e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn return res; 733e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 734e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn printf("Restore complete! Restarting system, cross your fingers...\n"); 735e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } else { 736e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn res = android::backup_data(backupFile); 737e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn if (res == 0) { 738e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn printf("Backup complete! Restarting system...\n"); 739e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } else { 740e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn printf("Restarting system...\n"); 741e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 742e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn } 743e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn 744e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn property_set("ctl.start", "zygote"); 745e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn property_set("ctl.start", "runtime"); 746e4bfb78ae3c4738d21e5016a51844429c4647639Dianne Hackborn} 747