#include <stdlib.h> #include <stdio.h> #include <unistd.h> #include <dirent.h> #include <string.h> #include <errno.h> #include <sys/types.h> #include <cutils/android_reboot.h> #include <sys/stat.h> #ifndef PATH_MAX #define PATH_MAX 4096 #endif /* Directories created by init defined in system/rootdir/init.rc */ static char *INIT_DIRS[] = { "/system/etc/ppp", "/data/misc", "/data/local", "/data/local/tmp", "/data/data", "/data/app_private", "/data/app", NULL }; static void wipe (const char *path); static int usage() { fprintf(stderr, "wipe <system|data|all>\n\n" "system means '/system'\n" "data means '/data'\n"); return -1; } int wipe_main (int argc, char *argv[]) { char *whatToWipe; if (argc != 2) return usage(); whatToWipe = argv[1]; if (0 == strcmp (whatToWipe, "system")) { fprintf(stdout, "Wiping /system\n"); wipe ("/system"); fprintf(stdout, "Done wiping /android\n"); } else if (0 == strcmp (whatToWipe, "data")) { fprintf(stdout, "Wiping /data\n"); wipe ("/data"); fprintf(stdout, "Done wiping /data\n"); } else if (0 == strcmp (whatToWipe, "all")) { fprintf(stdout, "Wiping /system and /data\n"); wipe ("/system"); wipe ("/data"); fprintf(stdout, "Done wiping /system and /data\n"); } else if (0 == strcmp(whatToWipe, "nuke")) { int ret; fprintf(stdout, "Nuking the device...\n"); wipe ("/system"); wipe ("/data"); fprintf(stdout, "Device nuked! Rebooting...\n"); ret = android_reboot(ANDROID_RB_RESTART, 0, 0); if (ret < 0) { fprintf(stderr, "Reboot failed, %s\n", strerror(errno)); return 1; } } else { return usage(); } return 0; } static char nameBuffer[PATH_MAX]; static struct stat statBuffer; static void wipe (const char *path) { DIR *dir; struct dirent *de; int ret; dir = opendir(path); if (dir == NULL) { fprintf (stderr, "Error opendir'ing %s '%s'\n", path, strerror(errno)); return; } char *filenameOffset; strcpy(nameBuffer, path); strcat(nameBuffer, "/"); filenameOffset = nameBuffer + strlen(nameBuffer); for (;;) { de = readdir(dir); if (de == NULL) { break; } if (0 == strcmp(de->d_name, ".") || 0 == strcmp(de->d_name, "..") || 0 == strcmp(de->d_name, "lost+found") ) { continue; } strcpy(filenameOffset, de->d_name); ret = lstat (nameBuffer, &statBuffer); if (ret != 0) { fprintf(stderr, "stat() error on '%s' '%s'\n", nameBuffer, strerror(errno)); } if(S_ISDIR(statBuffer.st_mode)) { int i; char *newpath; #if 0 closedir(dir); #endif newpath = strdup(nameBuffer); wipe(newpath); /* Leave directories created by init, they have special permissions. */ for (i = 0; INIT_DIRS[i]; i++) { if (strcmp(INIT_DIRS[i], newpath) == 0) { break; } } if (INIT_DIRS[i] == NULL) { ret = rmdir(newpath); if (ret != 0) { fprintf(stderr, "rmdir() error on '%s' '%s'\n", newpath, strerror(errno)); } } free(newpath); #if 0 dir = opendir(path); if (dir == NULL) { fprintf (stderr, "Error opendir'ing %s '%s'\n", path, strerror(errno)); return; } #endif strcpy(nameBuffer, path); strcat(nameBuffer, "/"); } else { ret = unlink(nameBuffer); if (ret != 0) { fprintf(stderr, "unlink() error on '%s' '%s'\n", nameBuffer, strerror(errno)); } } } closedir(dir); }