blob: 650a0d664b8cadea394cc7290f8e14a036fcd2be [file] [log] [blame]
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001#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>
Ken Sumralle3aeeb42011-03-07 23:29:42 -08008#include <cutils/android_reboot.h>
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08009#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 */
17static 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
28static void wipe (const char *path);
29
30static 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
39int 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");
Ken Sumralle3aeeb42011-03-07 23:29:42 -080066 ret = android_reboot(ANDROID_RB_RESTART, 0, 0);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080067 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
78static char nameBuffer[PATH_MAX];
79static struct stat statBuffer;
80
81static 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}