auto import from //depot/cupcake/@135843
diff --git a/toolbox/wipe.c b/toolbox/wipe.c
new file mode 100644
index 0000000..7e263fd
--- /dev/null
+++ b/toolbox/wipe.c
@@ -0,0 +1,176 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/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 = reboot(RB_AUTOBOOT);
+ 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);
+
+}