1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176
|
#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);
}
|