|  | #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); | 
|  |  | 
|  | } |