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