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