194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood// Copyright 2009 The Android Open Source Project 294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include <stdio.h> 494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include <stdlib.h> 594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include <stdarg.h> 694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include <string.h> 794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include <unistd.h> 894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include <fcntl.h> 994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include <time.h> 1094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include <dirent.h> 1194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include <errno.h> 1294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include <assert.h> 1394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include <ctype.h> 1494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include <utime.h> 1594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include <sys/stat.h> 1694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include <sys/types.h> 1794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include <stdint.h> 1894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 1994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include <cutils/properties.h> 2094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 2194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include <private/android_filesystem_config.h> 2294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 2394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#ifndef PATH_MAX 2494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#define PATH_MAX 4096 2594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#endif 2694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 2794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood// First version. 2894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#define FILE_VERSION_1 0xffff0001 2994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 3094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood// Introduces backup all option to header. 3194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#define FILE_VERSION_2 0xffff0002 3294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 3394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#define FILE_VERSION FILE_VERSION_2 3494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 3594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodnamespace android { 3694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 3794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodstatic char nameBuffer[PATH_MAX]; 3894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodstatic struct stat statBuffer; 3994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 4094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodstatic char copyBuffer[8192]; 4194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodstatic char *backupFilePath = NULL; 4294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 4394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodstatic uint32_t inputFileVersion; 4494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 4594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodstatic int opt_backupAll; 4694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 4794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#define SPECIAL_NO_TOUCH 0 4894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#define SPECIAL_NO_BACKUP 1 4994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 5094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodstruct special_dir { 5194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood const char* path; 5294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int type; 5394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}; 5494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 5594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood/* Directory paths that we will not backup/restore */ 5694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodstatic const struct special_dir SKIP_PATHS[] = { 5794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood { "/data/misc", SPECIAL_NO_TOUCH }, 5894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood { "/data/system/batterystats.bin", SPECIAL_NO_TOUCH }, 5994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood { "/data/system/location", SPECIAL_NO_TOUCH }, 6094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood { "/data/dalvik-cache", SPECIAL_NO_BACKUP }, 6194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood { NULL, 0 }, 6294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}; 6394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 6494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood/* This is just copied from the shell's built-in wipe command. */ 6594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodstatic int wipe (const char *path) 6694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 6794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood DIR *dir; 6894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood struct dirent *de; 6994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int ret; 7094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int i; 7194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 7294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood dir = opendir(path); 7394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 7494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (dir == NULL) { 7594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fprintf (stderr, "Error opendir'ing %s: %s\n", 7694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood path, strerror(errno)); 7794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return 0; 7894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 7994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 8094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood char *filenameOffset; 8194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 8294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood strcpy(nameBuffer, path); 8394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood strcat(nameBuffer, "/"); 8494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 8594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood filenameOffset = nameBuffer + strlen(nameBuffer); 8694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 8794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood for (;;) { 8894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood de = readdir(dir); 8994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 9094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (de == NULL) { 9194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood break; 9294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 9394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 9494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (0 == strcmp(de->d_name, ".") 9594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood || 0 == strcmp(de->d_name, "..") 9694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood || 0 == strcmp(de->d_name, "lost+found") 9794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ) { 9894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood continue; 9994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 10094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 10194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood strcpy(filenameOffset, de->d_name); 10294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bool noBackup = false; 10394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 10494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood /* See if this is a path we should skip. */ 10594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood for (i = 0; SKIP_PATHS[i].path; i++) { 10694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (strcmp(SKIP_PATHS[i].path, nameBuffer) == 0) { 10794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (opt_backupAll || SKIP_PATHS[i].type == SPECIAL_NO_BACKUP) { 10894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood // In this case we didn't back up the directory -- 10994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood // we do want to wipe its contents, but not the 11094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood // directory itself, since the restore file won't 11194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood // contain the directory. 11294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood noBackup = true; 11394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 11494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood break; 11594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 11694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 11794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 11894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (!noBackup && SKIP_PATHS[i].path != NULL) { 11994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood // This is a SPECIAL_NO_TOUCH directory. 12094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood continue; 12194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 12294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 12394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ret = lstat (nameBuffer, &statBuffer); 12494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 12594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (ret != 0) { 12694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fprintf(stderr, "warning -- stat() error on '%s': %s\n", 12794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood nameBuffer, strerror(errno)); 12894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood continue; 12994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 13094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 13194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if(S_ISDIR(statBuffer.st_mode)) { 13294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int i; 13394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood char *newpath; 13494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 13594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood newpath = strdup(nameBuffer); 13694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (wipe(newpath) == 0) { 13794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood free(newpath); 13894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood closedir(dir); 13994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return 0; 14094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 14194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 14294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (!noBackup) { 14394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ret = rmdir(newpath); 14494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (ret != 0) { 14594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fprintf(stderr, "warning -- rmdir() error on '%s': %s\n", 14694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood newpath, strerror(errno)); 14794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 14894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 14994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 15094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood free(newpath); 15194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 15294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood strcpy(nameBuffer, path); 15394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood strcat(nameBuffer, "/"); 15494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 15594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } else { 15694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood // Don't delete the backup file 15794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (backupFilePath && strcmp(backupFilePath, nameBuffer) == 0) { 15894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood continue; 15994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 16094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ret = unlink(nameBuffer); 16194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 16294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (ret != 0) { 16394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fprintf(stderr, "warning -- unlink() error on '%s': %s\n", 16494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood nameBuffer, strerror(errno)); 16594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 16694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 16794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 16894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 16994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood closedir(dir); 17094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 17194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return 1; 17294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 17394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 17494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodstatic int write_int32(FILE* fh, int32_t val) 17594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 17694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int res = fwrite(&val, 1, sizeof(val), fh); 17794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (res != sizeof(val)) { 17894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fprintf(stderr, "unable to write int32 (%d bytes): %s\n", res, strerror(errno)); 17994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return 0; 18094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 18194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 18294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return 1; 18394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 18494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 18594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodstatic int write_int64(FILE* fh, int64_t val) 18694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 18794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int res = fwrite(&val, 1, sizeof(val), fh); 18894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (res != sizeof(val)) { 18994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fprintf(stderr, "unable to write int64 (%d bytes): %s\n", res, strerror(errno)); 19094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return 0; 19194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 19294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 19394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return 1; 19494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 19594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 19694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodstatic int copy_file(FILE* dest, FILE* src, off_t size, const char* destName, 19794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood const char* srcName) 19894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 19994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood errno = 0; 20094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 20194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood off_t origSize = size; 20294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 20394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood while (size > 0) { 20494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int amt = size > (off_t)sizeof(copyBuffer) ? sizeof(copyBuffer) : (int)size; 20594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int readLen = fread(copyBuffer, 1, amt, src); 20694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (readLen <= 0) { 20794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (srcName != NULL) { 20894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fprintf(stderr, "unable to read source (%d of %ld bytes) file '%s': %s\n", 20994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood amt, origSize, srcName, errno != 0 ? strerror(errno) : "unexpected EOF"); 21094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } else { 21194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fprintf(stderr, "unable to read buffer (%d of %ld bytes): %s\n", 21294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood amt, origSize, errno != 0 ? strerror(errno) : "unexpected EOF"); 21394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 21494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return 0; 21594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 21694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int writeLen = fwrite(copyBuffer, 1, readLen, dest); 21794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (writeLen != readLen) { 21894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (destName != NULL) { 21994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fprintf(stderr, "unable to write file (%d of %d bytes) '%s': '%s'\n", 22094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood writeLen, readLen, destName, strerror(errno)); 22194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } else { 22294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fprintf(stderr, "unable to write buffer (%d of %d bytes): '%s'\n", 22394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood writeLen, readLen, strerror(errno)); 22494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 22594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return 0; 22694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 22794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood size -= readLen; 22894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 22994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return 1; 23094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 23194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 23294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#define TYPE_END 0 23394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#define TYPE_DIR 1 23494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#define TYPE_FILE 2 23594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 23694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodstatic int write_header(FILE* fh, int type, const char* path, const struct stat* st) 23794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 23894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int pathLen = strlen(path); 23994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (!write_int32(fh, type)) return 0; 24094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (!write_int32(fh, pathLen)) return 0; 24194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (fwrite(path, 1, pathLen, fh) != (size_t)pathLen) { 24294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fprintf(stderr, "unable to write: %s\n", strerror(errno)); 24394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return 0; 24494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 24594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 24694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (!write_int32(fh, st->st_uid)) return 0; 24794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (!write_int32(fh, st->st_gid)) return 0; 24894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (!write_int32(fh, st->st_mode)) return 0; 24994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (!write_int64(fh, ((int64_t)st->st_atime)*1000*1000*1000)) return 0; 25094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (!write_int64(fh, ((int64_t)st->st_mtime)*1000*1000*1000)) return 0; 25194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (!write_int64(fh, ((int64_t)st->st_ctime)*1000*1000*1000)) return 0; 25294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 25394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return 1; 25494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 25594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 25694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodstatic int backup_dir(FILE* fh, const char* srcPath) 25794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 25894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood DIR *dir; 25994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood struct dirent *de; 26094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood char* fullPath = NULL; 26194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int srcLen = strlen(srcPath); 26294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int result = 1; 26394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int i; 26494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 26594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood dir = opendir(srcPath); 26694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 26794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (dir == NULL) { 26894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fprintf (stderr, "error opendir'ing '%s': %s\n", 26994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood srcPath, strerror(errno)); 27094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return 0; 27194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 27294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 27394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood for (;;) { 27494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood de = readdir(dir); 27594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 27694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (de == NULL) { 27794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood break; 27894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 27994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 28094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (0 == strcmp(de->d_name, ".") 28194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood || 0 == strcmp(de->d_name, "..") 28294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood || 0 == strcmp(de->d_name, "lost+found") 28394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ) { 28494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood continue; 28594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 28694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 28794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (fullPath != NULL) { 28894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood free(fullPath); 28994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 29094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fullPath = (char*)malloc(srcLen + strlen(de->d_name) + 2); 29194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood strcpy(fullPath, srcPath); 29294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fullPath[srcLen] = '/'; 29394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood strcpy(fullPath+srcLen+1, de->d_name); 29494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 29594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood /* See if this is a path we should skip. */ 29694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (!opt_backupAll) { 29794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood for (i = 0; SKIP_PATHS[i].path; i++) { 29894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (strcmp(SKIP_PATHS[i].path, fullPath) == 0) { 29994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood break; 30094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 30194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 30294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (SKIP_PATHS[i].path != NULL) { 30394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood continue; 30494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 30594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 30694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 30794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int ret = lstat(fullPath, &statBuffer); 30894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 30994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (ret != 0) { 31094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fprintf(stderr, "stat() error on '%s': %s\n", 31194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fullPath, strerror(errno)); 31294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood result = 0; 31394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood goto done; 31494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 31594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 31694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if(S_ISDIR(statBuffer.st_mode)) { 31794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood printf("Saving dir %s...\n", fullPath); 31894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 31994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (write_header(fh, TYPE_DIR, fullPath, &statBuffer) == 0) { 32094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood result = 0; 32194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood goto done; 32294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 32394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (backup_dir(fh, fullPath) == 0) { 32494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood result = 0; 32594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood goto done; 32694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 32794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } else if (S_ISREG(statBuffer.st_mode)) { 32894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood // Skip the backup file 32994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (backupFilePath && strcmp(fullPath, backupFilePath) == 0) { 33094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood printf("Skipping backup file %s...\n", backupFilePath); 33194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood continue; 33294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } else { 33394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood printf("Saving file %s...\n", fullPath); 33494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 33594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (write_header(fh, TYPE_FILE, fullPath, &statBuffer) == 0) { 33694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood result = 0; 33794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood goto done; 33894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 33994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 34094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood off_t size = statBuffer.st_size; 34194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (!write_int64(fh, size)) { 34294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood result = 0; 34394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood goto done; 34494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 34594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 34694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood FILE* src = fopen(fullPath, "r"); 34794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (src == NULL) { 34894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fprintf(stderr, "unable to open source file '%s': %s\n", 34994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fullPath, strerror(errno)); 35094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood result = 0; 35194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood goto done; 35294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 35394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 35494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int copyres = copy_file(fh, src, size, NULL, fullPath); 35594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fclose(src); 35694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (!copyres) { 35794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood result = 0; 35894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood goto done; 35994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 36094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 36194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 36294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 36394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwooddone: 36494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (fullPath != NULL) { 36594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood free(fullPath); 36694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 36794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 36894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood closedir(dir); 36994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 37094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return result; 37194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 37294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 37394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodstatic int backup_data(const char* destPath) 37494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 37594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int res = -1; 37694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 37794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood FILE* fh = fopen(destPath, "w"); 37894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (fh == NULL) { 37994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fprintf(stderr, "unable to open destination '%s': %s\n", 38094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood destPath, strerror(errno)); 38194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return -1; 38294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 38394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 38494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood printf("Backing up /data to %s...\n", destPath); 38594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 38694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood // The path that shouldn't be backed up 38794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood backupFilePath = strdup(destPath); 38894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 38994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (!write_int32(fh, FILE_VERSION)) goto done; 39094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (!write_int32(fh, opt_backupAll)) goto done; 39194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (!backup_dir(fh, "/data")) goto done; 39294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (!write_int32(fh, 0)) goto done; 39394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 39494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood res = 0; 39594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 39694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwooddone: 39794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (fflush(fh) != 0) { 39894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fprintf(stderr, "error flushing destination '%s': %s\n", 39994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood destPath, strerror(errno)); 40094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood res = -1; 40194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood goto donedone; 40294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 40394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (fsync(fileno(fh)) != 0) { 40494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fprintf(stderr, "error syncing destination '%s': %s\n", 40594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood destPath, strerror(errno)); 40694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood res = -1; 40794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood goto donedone; 40894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 40994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fclose(fh); 41094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood sync(); 41194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 41294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwooddonedone: 41394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return res; 41494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 41594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 41694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodstatic int32_t read_int32(FILE* fh, int32_t defVal) 41794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 41894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int32_t val; 41994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (fread(&val, 1, sizeof(val), fh) != sizeof(val)) { 42094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fprintf(stderr, "unable to read: %s\n", strerror(errno)); 42194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return defVal; 42294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 42394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 42494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return val; 42594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 42694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 42794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodstatic int64_t read_int64(FILE* fh, int64_t defVal) 42894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 42994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int64_t val; 43094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (fread(&val, 1, sizeof(val), fh) != sizeof(val)) { 43194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fprintf(stderr, "unable to read: %s\n", strerror(errno)); 43294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return defVal; 43394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 43494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 43594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return val; 43694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 43794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 43894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodstatic int read_header(FILE* fh, int* type, char** path, struct stat* st) 43994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 44094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood *type = read_int32(fh, -1); 44194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (*type == TYPE_END) { 44294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return 1; 44394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 44494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 44594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (*type < 0) { 44694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fprintf(stderr, "bad token %d in restore file\n", *type); 44794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return 0; 44894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 44994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 45094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int32_t pathLen = read_int32(fh, -1); 45194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (pathLen <= 0) { 45294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fprintf(stderr, "bad path length %d in restore file\n", pathLen); 45394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return 0; 45494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 45594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood char* readPath = (char*)malloc(pathLen+1); 45694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (fread(readPath, 1, pathLen, fh) != (size_t)pathLen) { 45794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fprintf(stderr, "truncated path in restore file\n"); 45894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood free(readPath); 45994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return 0; 46094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 46194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood readPath[pathLen] = 0; 46294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood *path = readPath; 46394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 46494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood st->st_uid = read_int32(fh, -1); 46594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (st->st_uid == (uid_t)-1) { 46694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fprintf(stderr, "bad uid in restore file at '%s'\n", readPath); 46794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return 0; 46894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 46994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood st->st_gid = read_int32(fh, -1); 47094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (st->st_gid == (gid_t)-1) { 47194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fprintf(stderr, "bad gid in restore file at '%s'\n", readPath); 47294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return 0; 47394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 47494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood st->st_mode = read_int32(fh, -1); 47594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (st->st_mode == (mode_t)-1) { 47694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fprintf(stderr, "bad mode in restore file at '%s'\n", readPath); 47794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return 0; 47894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 47994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int64_t ltime = read_int64(fh, -1); 48094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (ltime < 0) { 48194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fprintf(stderr, "bad atime in restore file at '%s'\n", readPath); 48294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return 0; 48394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 48494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood st->st_atime = (time_t)(ltime/1000/1000/1000); 48594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ltime = read_int64(fh, -1); 48694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (ltime < 0) { 48794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fprintf(stderr, "bad mtime in restore file at '%s'\n", readPath); 48894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return 0; 48994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 49094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood st->st_mtime = (time_t)(ltime/1000/1000/1000); 49194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ltime = read_int64(fh, -1); 49294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (ltime < 0) { 49394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fprintf(stderr, "bad ctime in restore file at '%s'\n", readPath); 49494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return 0; 49594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 49694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood st->st_ctime = (time_t)(ltime/1000/1000/1000); 49794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 49894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood st->st_mode &= (S_IRWXU|S_IRWXG|S_IRWXO); 49994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 50094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return 1; 50194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 50294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 50394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodstatic int restore_data(const char* srcPath) 50494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 50594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int res = -1; 50694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 50794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood FILE* fh = fopen(srcPath, "r"); 50894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (fh == NULL) { 50994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fprintf(stderr, "Unable to open source '%s': %s\n", 51094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood srcPath, strerror(errno)); 51194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return -1; 51294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 51394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 51494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood inputFileVersion = read_int32(fh, 0); 51594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (inputFileVersion < FILE_VERSION_1 || inputFileVersion > FILE_VERSION) { 51694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fprintf(stderr, "Restore file has bad version: 0x%x\n", inputFileVersion); 51794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood goto done; 51894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 51994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 52094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (inputFileVersion >= FILE_VERSION_2) { 52194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood opt_backupAll = read_int32(fh, 0); 52294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } else { 52394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood opt_backupAll = 0; 52494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 52594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 52694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood // The path that shouldn't be deleted 52794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood backupFilePath = strdup(srcPath); 52894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 52994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood printf("Wiping contents of /data...\n"); 53094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (!wipe("/data")) { 53194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood goto done; 53294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 53394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 53494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood printf("Restoring from %s to /data...\n", srcPath); 53594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 53694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood while (1) { 53794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int type; 53894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood char* path = NULL; 53994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (read_header(fh, &type, &path, &statBuffer) == 0) { 54094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood goto done; 54194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 54294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (type == 0) { 54394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood break; 54494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 54594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 54694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood const char* typeName = "?"; 54794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 54894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (type == TYPE_DIR) { 54994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood typeName = "dir"; 55094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 55194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood printf("Restoring dir %s...\n", path); 55294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 55394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (mkdir(path, statBuffer.st_mode) != 0) { 55494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (errno != EEXIST) { 55594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fprintf(stderr, "unable to create directory '%s': %s\n", 55694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood path, strerror(errno)); 55794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood free(path); 55894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood goto done; 55994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 56094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 56194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 56294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } else if (type == TYPE_FILE) { 56394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood typeName = "file"; 56494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood off_t size = read_int64(fh, -1); 56594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (size < 0) { 56694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fprintf(stderr, "bad file size %ld in restore file\n", size); 56794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood free(path); 56894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood goto done; 56994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 57094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 57194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood printf("Restoring file %s...\n", path); 57294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 57394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood FILE* dest = fopen(path, "w"); 57494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (dest == NULL) { 57594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fprintf(stderr, "unable to open destination file '%s': %s\n", 57694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood path, strerror(errno)); 57794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood free(path); 57894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood goto done; 57994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 58094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 58194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int copyres = copy_file(dest, fh, size, path, NULL); 58294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fclose(dest); 58394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (!copyres) { 58494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood free(path); 58594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood goto done; 58694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 58794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 58894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } else { 58994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fprintf(stderr, "unknown node type %d\n", type); 59094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood goto done; 59194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 59294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 59394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood // Do this even for directories, since the dir may have already existed 59494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood // so we need to make sure it gets the correct mode. 59594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (chmod(path, statBuffer.st_mode&(S_IRWXU|S_IRWXG|S_IRWXO)) != 0) { 59694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fprintf(stderr, "unable to chmod destination %s '%s' to 0x%x: %s\n", 59794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood typeName, path, statBuffer.st_mode, strerror(errno)); 59894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood free(path); 59994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood goto done; 60094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 60194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 60294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (chown(path, statBuffer.st_uid, statBuffer.st_gid) != 0) { 60394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fprintf(stderr, "unable to chown destination %s '%s' to uid %d / gid %d: %s\n", 60494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood typeName, path, (int)statBuffer.st_uid, (int)statBuffer.st_gid, strerror(errno)); 60594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood free(path); 60694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood goto done; 60794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 60894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 60994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood struct utimbuf timbuf; 61094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood timbuf.actime = statBuffer.st_atime; 61194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood timbuf.modtime = statBuffer.st_mtime; 61294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (utime(path, &timbuf) != 0) { 61394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fprintf(stderr, "unable to utime destination %s '%s': %s\n", 61494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood typeName, path, strerror(errno)); 61594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood free(path); 61694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood goto done; 61794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 61894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 61994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 62094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood free(path); 62194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 62294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 62394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood res = 0; 62494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 62594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwooddone: 62694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fclose(fh); 62794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 62894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return res; 62994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 63094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 63194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodstatic void show_help(const char *cmd) 63294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 63394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fprintf(stderr,"Usage: %s COMMAND [options] [backup-file-path]\n", cmd); 63494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 63594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fprintf(stderr, "commands are:\n" 63694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood " help Show this help text.\n" 63794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood " backup Perform a backup of /data.\n" 63894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood " restore Perform a restore of /data.\n"); 63994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fprintf(stderr, "options include:\n" 64094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood " -h Show this help text.\n" 64194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood " -a Backup all files.\n"); 642b82bf9dfc97c44852283630eac24ae92b49f85f6Amith Yamasani fprintf(stderr, "\n backup-file-path Defaults to /sdcard/backup.dat .\n" 643b82bf9dfc97c44852283630eac24ae92b49f85f6Amith Yamasani " On devices that emulate the sdcard, you will need to\n" 644b82bf9dfc97c44852283630eac24ae92b49f85f6Amith Yamasani " explicitly specify the directory it is mapped to,\n" 645b82bf9dfc97c44852283630eac24ae92b49f85f6Amith Yamasani " to avoid recursive backup or deletion of the backup file\n" 646b82bf9dfc97c44852283630eac24ae92b49f85f6Amith Yamasani " during restore.\n\n" 647b82bf9dfc97c44852283630eac24ae92b49f85f6Amith Yamasani " Eg. /data/media/0/backup.dat\n"); 64894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fprintf(stderr, "\nThe %s command allows you to perform low-level\n" 64994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood "backup and restore of the /data partition. This is\n" 65094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood "where all user data is kept, allowing for a fairly\n" 65194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood "complete restore of a device's state. Note that\n" 65294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood "because this is low-level, it will only work across\n" 65394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood "builds of the same (or very similar) device software.\n", 65494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood cmd); 65594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 65694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 65794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} /* namespace android */ 65894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 65994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodint main (int argc, char **argv) 66094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 66194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int restore = 0; 66294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 66394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (getuid() != AID_ROOT) { 66494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fprintf(stderr, "error -- %s must run as root\n", argv[0]); 66594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood exit(-1); 66694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 66794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 66894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (argc < 2) { 66994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fprintf(stderr, "No command specified.\n"); 67094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood android::show_help(argv[0]); 67194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood exit(-1); 67294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 67394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 67494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (0 == strcmp(argv[1], "restore")) { 67594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood restore = 1; 67694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } else if (0 == strcmp(argv[1], "help")) { 67794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood android::show_help(argv[0]); 67894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood exit(0); 67994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } else if (0 != strcmp(argv[1], "backup")) { 68094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fprintf(stderr, "Unknown command: %s\n", argv[1]); 68194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood android::show_help(argv[0]); 68294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood exit(-1); 68394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 68494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 68594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood android::opt_backupAll = 0; 68694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 68794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood optind = 2; 68894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 68994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood for (;;) { 69094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int ret; 69194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 69294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ret = getopt(argc, argv, "ah"); 69394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 69494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (ret < 0) { 69594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood break; 69694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 69794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 69894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood switch(ret) { 69994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood case 'a': 70094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood android::opt_backupAll = 1; 70194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (restore) fprintf(stderr, "Warning: -a option ignored on restore\n"); 70294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood break; 70394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood case 'h': 70494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood android::show_help(argv[0]); 70594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood exit(0); 70694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood break; 70794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 70894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood default: 70994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fprintf(stderr,"Unrecognized Option\n"); 71094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood android::show_help(argv[0]); 71194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood exit(-1); 71294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood break; 71394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 71494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 71594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 71694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood const char* backupFile = "/sdcard/backup.dat"; 71794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 71894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (argc > optind) { 71994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood backupFile = argv[optind]; 72094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood optind++; 72194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (argc != optind) { 72294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fprintf(stderr, "Too many arguments\n"); 72394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood android::show_help(argv[0]); 72494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood exit(-1); 72594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 72694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 72794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 72894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood printf("Stopping system...\n"); 72994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood property_set("ctl.stop", "runtime"); 73094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood property_set("ctl.stop", "zygote"); 73194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood sleep(1); 73294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 73394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int res; 73494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (restore) { 73594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood res = android::restore_data(backupFile); 73694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (res != 0) { 73794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood // Don't restart system, since the data partition is hosed. 73894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return res; 73994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 74094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood printf("Restore complete! Restarting system, cross your fingers...\n"); 74194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } else { 74294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood res = android::backup_data(backupFile); 74394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (res == 0) { 74494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood printf("Backup complete! Restarting system...\n"); 74594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } else { 74694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood printf("Restarting system...\n"); 74794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 74894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 74994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 75094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood property_set("ctl.start", "zygote"); 75194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood property_set("ctl.start", "runtime"); 75294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 753