1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <unistd.h>
4 #include <dirent.h>
5 #include <string.h>
6 #include <errno.h>
7 #include <sys/types.h>
8 #include <sys/reboot.h>
9 #include <sys/stat.h>
10
11 #ifndef PATH_MAX
12 #define PATH_MAX 4096
13 #endif
14
15
16 /* Directories created by init defined in system/rootdir/init.rc */
17 static char *INIT_DIRS[] = {
18 "/system/etc/ppp",
19 "/data/misc",
20 "/data/local",
21 "/data/local/tmp",
22 "/data/data",
23 "/data/app_private",
24 "/data/app",
25 NULL
26 };
27
28 static void wipe (const char *path);
29
usage()30 static int usage()
31 {
32 fprintf(stderr, "wipe <system|data|all>\n\n"
33 "system means '/system'\n"
34 "data means '/data'\n");
35
36 return -1;
37 }
38
wipe_main(int argc,char * argv[])39 int wipe_main (int argc, char *argv[])
40 {
41 char *whatToWipe;
42
43 if (argc != 2) return usage();
44
45 whatToWipe = argv[1];
46
47 if (0 == strcmp (whatToWipe, "system")) {
48 fprintf(stdout, "Wiping /system\n");
49 wipe ("/system");
50 fprintf(stdout, "Done wiping /android\n");
51 } else if (0 == strcmp (whatToWipe, "data")) {
52 fprintf(stdout, "Wiping /data\n");
53 wipe ("/data");
54 fprintf(stdout, "Done wiping /data\n");
55 } else if (0 == strcmp (whatToWipe, "all")) {
56 fprintf(stdout, "Wiping /system and /data\n");
57 wipe ("/system");
58 wipe ("/data");
59 fprintf(stdout, "Done wiping /system and /data\n");
60 } else if (0 == strcmp(whatToWipe, "nuke")) {
61 int ret;
62 fprintf(stdout, "Nuking the device...\n");
63 wipe ("/system");
64 wipe ("/data");
65 fprintf(stdout, "Device nuked! Rebooting...\n");
66 ret = reboot(RB_AUTOBOOT);
67 if (ret < 0) {
68 fprintf(stderr, "Reboot failed, %s\n", strerror(errno));
69 return 1;
70 }
71 } else {
72 return usage();
73 }
74
75 return 0;
76 }
77
78 static char nameBuffer[PATH_MAX];
79 static struct stat statBuffer;
80
wipe(const char * path)81 static void wipe (const char *path)
82 {
83 DIR *dir;
84 struct dirent *de;
85 int ret;
86
87 dir = opendir(path);
88
89 if (dir == NULL) {
90 fprintf (stderr, "Error opendir'ing %s '%s'\n",
91 path, strerror(errno));
92 return;
93 }
94
95 char *filenameOffset;
96
97 strcpy(nameBuffer, path);
98 strcat(nameBuffer, "/");
99
100 filenameOffset = nameBuffer + strlen(nameBuffer);
101
102 for (;;) {
103 de = readdir(dir);
104
105 if (de == NULL) {
106 break;
107 }
108
109 if (0 == strcmp(de->d_name, ".")
110 || 0 == strcmp(de->d_name, "..")
111 || 0 == strcmp(de->d_name, "lost+found")
112 ) {
113 continue;
114 }
115
116 strcpy(filenameOffset, de->d_name);
117
118 ret = lstat (nameBuffer, &statBuffer);
119
120 if (ret != 0) {
121 fprintf(stderr, "stat() error on '%s' '%s'\n",
122 nameBuffer, strerror(errno));
123 }
124
125 if(S_ISDIR(statBuffer.st_mode)) {
126 int i;
127 char *newpath;
128
129 #if 0
130 closedir(dir);
131 #endif
132
133 newpath = strdup(nameBuffer);
134 wipe(newpath);
135
136 /* Leave directories created by init, they have special permissions. */
137 for (i = 0; INIT_DIRS[i]; i++) {
138 if (strcmp(INIT_DIRS[i], newpath) == 0) {
139 break;
140 }
141 }
142 if (INIT_DIRS[i] == NULL) {
143 ret = rmdir(newpath);
144 if (ret != 0) {
145 fprintf(stderr, "rmdir() error on '%s' '%s'\n",
146 newpath, strerror(errno));
147 }
148 }
149
150 free(newpath);
151
152 #if 0
153 dir = opendir(path);
154 if (dir == NULL) {
155 fprintf (stderr, "Error opendir'ing %s '%s'\n",
156 path, strerror(errno));
157 return;
158 }
159 #endif
160
161 strcpy(nameBuffer, path);
162 strcat(nameBuffer, "/");
163
164 } else {
165 ret = unlink(nameBuffer);
166
167 if (ret != 0) {
168 fprintf(stderr, "unlink() error on '%s' '%s'\n",
169 nameBuffer, strerror(errno));
170 }
171 }
172 }
173
174 closedir(dir);
175
176 }
177