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