Home | History | Annotate | Download | only in toolbox
      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 <cutils/android_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 
     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 
     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 = android_reboot(ANDROID_RB_RESTART, 0, 0);
     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 
     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