Home | History | Annotate | Download | only in installd
      1 /*
      2 ** Copyright 2008, The Android Open Source Project
      3 **
      4 ** Licensed under the Apache License, Version 2.0 (the "License");
      5 ** you may not use this file except in compliance with the License.
      6 ** You may obtain a copy of the License at
      7 **
      8 **     http://www.apache.org/licenses/LICENSE-2.0
      9 **
     10 ** Unless required by applicable law or agreed to in writing, software
     11 ** distributed under the License is distributed on an "AS IS" BASIS,
     12 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13 ** See the License for the specific language governing permissions and
     14 ** limitations under the License.
     15 */
     16 
     17 #include "installd.h"
     18 
     19 #define CACHE_NOISY(x) //x
     20 
     21 int create_pkg_path_in_dir(char path[PKG_PATH_MAX],
     22                                 const dir_rec_t* dir,
     23                                 const char* pkgname,
     24                                 const char* postfix)
     25 {
     26      const size_t postfix_len = strlen(postfix);
     27 
     28      const size_t pkgname_len = strlen(pkgname);
     29      if (pkgname_len > PKG_NAME_MAX) {
     30          return -1;
     31      }
     32 
     33      if (is_valid_package_name(pkgname) < 0) {
     34          return -1;
     35      }
     36 
     37      if ((pkgname_len + dir->len + postfix_len) >= PKG_PATH_MAX) {
     38          return -1;
     39      }
     40 
     41      char *dst = path;
     42      size_t dst_size = PKG_PATH_MAX;
     43 
     44      if (append_and_increment(&dst, dir->path, &dst_size) < 0
     45              || append_and_increment(&dst, pkgname, &dst_size) < 0
     46              || append_and_increment(&dst, postfix, &dst_size) < 0) {
     47          ALOGE("Error building APK path");
     48          return -1;
     49      }
     50 
     51      return 0;
     52 }
     53 
     54 /**
     55  * Create the package path name for a given package name with a postfix for
     56  * a certain userid. Returns 0 on success, and -1 on failure.
     57  */
     58 int create_pkg_path(char path[PKG_PATH_MAX],
     59                     const char *pkgname,
     60                     const char *postfix,
     61                     userid_t userid)
     62 {
     63     size_t userid_len;
     64     char* userid_prefix;
     65     if (userid == 0) {
     66         userid_prefix = PRIMARY_USER_PREFIX;
     67         userid_len = 0;
     68     } else {
     69         userid_prefix = SECONDARY_USER_PREFIX;
     70         userid_len = snprintf(NULL, 0, "%d", userid);
     71     }
     72 
     73     const size_t prefix_len = android_data_dir.len + strlen(userid_prefix)
     74             + userid_len + 1 /*slash*/;
     75     char prefix[prefix_len + 1];
     76 
     77     char *dst = prefix;
     78     size_t dst_size = sizeof(prefix);
     79 
     80     if (append_and_increment(&dst, android_data_dir.path, &dst_size) < 0
     81             || append_and_increment(&dst, userid_prefix, &dst_size) < 0) {
     82         ALOGE("Error building prefix for APK path");
     83         return -1;
     84     }
     85 
     86     if (userid != 0) {
     87         int ret = snprintf(dst, dst_size, "%d/", userid);
     88         if (ret < 0 || (size_t) ret != userid_len + 1) {
     89             ALOGW("Error appending UID to APK path");
     90             return -1;
     91         }
     92     }
     93 
     94     dir_rec_t dir;
     95     dir.path = prefix;
     96     dir.len = prefix_len;
     97 
     98     return create_pkg_path_in_dir(path, &dir, pkgname, postfix);
     99 }
    100 
    101 /**
    102  * Create the path name for user data for a certain userid.
    103  * Returns 0 on success, and -1 on failure.
    104  */
    105 int create_user_path(char path[PKG_PATH_MAX],
    106                     userid_t userid)
    107 {
    108     size_t userid_len;
    109     char* userid_prefix;
    110     if (userid == 0) {
    111         userid_prefix = PRIMARY_USER_PREFIX;
    112         userid_len = 0;
    113     } else {
    114         userid_prefix = SECONDARY_USER_PREFIX;
    115         userid_len = snprintf(NULL, 0, "%d/", userid);
    116     }
    117 
    118     char *dst = path;
    119     size_t dst_size = PKG_PATH_MAX;
    120 
    121     if (append_and_increment(&dst, android_data_dir.path, &dst_size) < 0
    122             || append_and_increment(&dst, userid_prefix, &dst_size) < 0) {
    123         ALOGE("Error building prefix for user path");
    124         return -1;
    125     }
    126 
    127     if (userid != 0) {
    128         if (dst_size < userid_len + 1) {
    129             ALOGE("Error building user path");
    130             return -1;
    131         }
    132         int ret = snprintf(dst, dst_size, "%d/", userid);
    133         if (ret < 0 || (size_t) ret != userid_len) {
    134             ALOGE("Error appending userid to path");
    135             return -1;
    136         }
    137     }
    138     return 0;
    139 }
    140 
    141 /**
    142  * Create the path name for media for a certain userid.
    143  * Returns 0 on success, and -1 on failure.
    144  */
    145 int create_user_media_path(char path[PATH_MAX], userid_t userid) {
    146     if (snprintf(path, PATH_MAX, "%s%d", android_media_dir.path, userid) > PATH_MAX) {
    147         return -1;
    148     }
    149     return 0;
    150 }
    151 
    152 int create_move_path(char path[PKG_PATH_MAX],
    153     const char* pkgname,
    154     const char* leaf,
    155     userid_t userid)
    156 {
    157     if ((android_data_dir.len + strlen(PRIMARY_USER_PREFIX) + strlen(pkgname) + strlen(leaf) + 1)
    158             >= PKG_PATH_MAX) {
    159         return -1;
    160     }
    161 
    162     sprintf(path, "%s%s%s/%s", android_data_dir.path, PRIMARY_USER_PREFIX, pkgname, leaf);
    163     return 0;
    164 }
    165 
    166 /**
    167  * Checks whether the package name is valid. Returns -1 on error and
    168  * 0 on success.
    169  */
    170 int is_valid_package_name(const char* pkgname) {
    171     const char *x = pkgname;
    172     int alpha = -1;
    173 
    174     while (*x) {
    175         if (isalnum(*x) || (*x == '_')) {
    176                 /* alphanumeric or underscore are fine */
    177         } else if (*x == '.') {
    178             if ((x == pkgname) || (x[1] == '.') || (x[1] == 0)) {
    179                     /* periods must not be first, last, or doubled */
    180                 ALOGE("invalid package name '%s'\n", pkgname);
    181                 return -1;
    182             }
    183         } else if (*x == '-') {
    184             /* Suffix -X is fine to let versioning of packages.
    185                But whatever follows should be alphanumeric.*/
    186             alpha = 1;
    187         } else {
    188                 /* anything not A-Z, a-z, 0-9, _, or . is invalid */
    189             ALOGE("invalid package name '%s'\n", pkgname);
    190             return -1;
    191         }
    192 
    193         x++;
    194     }
    195 
    196     if (alpha == 1) {
    197         // Skip current character
    198         x++;
    199         while (*x) {
    200             if (!isalnum(*x)) {
    201                 ALOGE("invalid package name '%s' should include only numbers after -\n", pkgname);
    202                 return -1;
    203             }
    204             x++;
    205         }
    206     }
    207 
    208     return 0;
    209 }
    210 
    211 static int _delete_dir_contents(DIR *d, const char *ignore)
    212 {
    213     int result = 0;
    214     struct dirent *de;
    215     int dfd;
    216 
    217     dfd = dirfd(d);
    218 
    219     if (dfd < 0) return -1;
    220 
    221     while ((de = readdir(d))) {
    222         const char *name = de->d_name;
    223 
    224             /* skip the ignore name if provided */
    225         if (ignore && !strcmp(name, ignore)) continue;
    226 
    227         if (de->d_type == DT_DIR) {
    228             int r, subfd;
    229             DIR *subdir;
    230 
    231                 /* always skip "." and ".." */
    232             if (name[0] == '.') {
    233                 if (name[1] == 0) continue;
    234                 if ((name[1] == '.') && (name[2] == 0)) continue;
    235             }
    236 
    237             subfd = openat(dfd, name, O_RDONLY | O_DIRECTORY);
    238             if (subfd < 0) {
    239                 ALOGE("Couldn't openat %s: %s\n", name, strerror(errno));
    240                 result = -1;
    241                 continue;
    242             }
    243             subdir = fdopendir(subfd);
    244             if (subdir == NULL) {
    245                 ALOGE("Couldn't fdopendir %s: %s\n", name, strerror(errno));
    246                 close(subfd);
    247                 result = -1;
    248                 continue;
    249             }
    250             if (_delete_dir_contents(subdir, 0)) {
    251                 result = -1;
    252             }
    253             closedir(subdir);
    254             if (unlinkat(dfd, name, AT_REMOVEDIR) < 0) {
    255                 ALOGE("Couldn't unlinkat %s: %s\n", name, strerror(errno));
    256                 result = -1;
    257             }
    258         } else {
    259             if (unlinkat(dfd, name, 0) < 0) {
    260                 ALOGE("Couldn't unlinkat %s: %s\n", name, strerror(errno));
    261                 result = -1;
    262             }
    263         }
    264     }
    265 
    266     return result;
    267 }
    268 
    269 int delete_dir_contents(const char *pathname,
    270                         int also_delete_dir,
    271                         const char *ignore)
    272 {
    273     int res = 0;
    274     DIR *d;
    275 
    276     d = opendir(pathname);
    277     if (d == NULL) {
    278         ALOGE("Couldn't opendir %s: %s\n", pathname, strerror(errno));
    279         return -errno;
    280     }
    281     res = _delete_dir_contents(d, ignore);
    282     closedir(d);
    283     if (also_delete_dir) {
    284         if (rmdir(pathname)) {
    285             ALOGE("Couldn't rmdir %s: %s\n", pathname, strerror(errno));
    286             res = -1;
    287         }
    288     }
    289     return res;
    290 }
    291 
    292 int delete_dir_contents_fd(int dfd, const char *name)
    293 {
    294     int fd, res;
    295     DIR *d;
    296 
    297     fd = openat(dfd, name, O_RDONLY | O_DIRECTORY);
    298     if (fd < 0) {
    299         ALOGE("Couldn't openat %s: %s\n", name, strerror(errno));
    300         return -1;
    301     }
    302     d = fdopendir(fd);
    303     if (d == NULL) {
    304         ALOGE("Couldn't fdopendir %s: %s\n", name, strerror(errno));
    305         close(fd);
    306         return -1;
    307     }
    308     res = _delete_dir_contents(d, 0);
    309     closedir(d);
    310     return res;
    311 }
    312 
    313 int lookup_media_dir(char basepath[PATH_MAX], const char *dir)
    314 {
    315     DIR *d;
    316     struct dirent *de;
    317     struct stat s;
    318     char* dirpos = basepath + strlen(basepath);
    319 
    320     if ((*(dirpos-1)) != '/') {
    321         *dirpos = '/';
    322         dirpos++;
    323     }
    324 
    325     CACHE_NOISY(ALOGI("Looking up %s in %s\n", dir, basepath));
    326     // Verify the path won't extend beyond our buffer, to avoid
    327     // repeated checking later.
    328     if ((dirpos-basepath+strlen(dir)) >= (PATH_MAX-1)) {
    329         ALOGW("Path exceeds limit: %s%s", basepath, dir);
    330         return -1;
    331     }
    332 
    333     // First, can we find this directory with the case that is given?
    334     strcpy(dirpos, dir);
    335     if (stat(basepath, &s) >= 0) {
    336         CACHE_NOISY(ALOGI("Found direct: %s\n", basepath));
    337         return 0;
    338     }
    339 
    340     // Not found with that case...  search through all entries to find
    341     // one that matches regardless of case.
    342     *dirpos = 0;
    343 
    344     d = opendir(basepath);
    345     if (d == NULL) {
    346         return -1;
    347     }
    348 
    349     while ((de = readdir(d))) {
    350         if (strcasecmp(de->d_name, dir) == 0) {
    351             strcpy(dirpos, de->d_name);
    352             closedir(d);
    353             CACHE_NOISY(ALOGI("Found search: %s\n", basepath));
    354             return 0;
    355         }
    356     }
    357 
    358     ALOGW("Couldn't find %s in %s", dir, basepath);
    359     closedir(d);
    360     return -1;
    361 }
    362 
    363 int64_t data_disk_free()
    364 {
    365     struct statfs sfs;
    366     if (statfs(android_data_dir.path, &sfs) == 0) {
    367         return sfs.f_bavail * sfs.f_bsize;
    368     } else {
    369         ALOGE("Couldn't statfs %s: %s\n", android_data_dir.path, strerror(errno));
    370         return -1;
    371     }
    372 }
    373 
    374 cache_t* start_cache_collection()
    375 {
    376     cache_t* cache = (cache_t*)calloc(1, sizeof(cache_t));
    377     return cache;
    378 }
    379 
    380 #define CACHE_BLOCK_SIZE (512*1024)
    381 
    382 static void* _cache_malloc(cache_t* cache, size_t len)
    383 {
    384     len = (len+3)&~3;
    385     if (len > (CACHE_BLOCK_SIZE/2)) {
    386         // It doesn't make sense to try to put this allocation into one
    387         // of our blocks, because it is so big.  Instead, make a new dedicated
    388         // block for it.
    389         int8_t* res = (int8_t*)malloc(len+sizeof(void*));
    390         if (res == NULL) {
    391             return NULL;
    392         }
    393         CACHE_NOISY(ALOGI("Allocated large cache mem block: %p size %d", res, len));
    394         // Link it into our list of blocks, not disrupting the current one.
    395         if (cache->memBlocks == NULL) {
    396             *(void**)res = NULL;
    397             cache->memBlocks = res;
    398         } else {
    399             *(void**)res = *(void**)cache->memBlocks;
    400             *(void**)cache->memBlocks = res;
    401         }
    402         return res + sizeof(void*);
    403     }
    404     int8_t* res = cache->curMemBlockAvail;
    405     int8_t* nextPos = res + len;
    406     if (cache->memBlocks == NULL || nextPos > cache->curMemBlockEnd) {
    407         int8_t* newBlock = malloc(CACHE_BLOCK_SIZE);
    408         if (newBlock == NULL) {
    409             return NULL;
    410         }
    411         CACHE_NOISY(ALOGI("Allocated new cache mem block: %p", newBlock));
    412         *(void**)newBlock = cache->memBlocks;
    413         cache->memBlocks = newBlock;
    414         res = cache->curMemBlockAvail = newBlock + sizeof(void*);
    415         cache->curMemBlockEnd = newBlock + CACHE_BLOCK_SIZE;
    416         nextPos = res + len;
    417     }
    418     CACHE_NOISY(ALOGI("cache_malloc: ret %p size %d, block=%p, nextPos=%p",
    419             res, len, cache->memBlocks, nextPos));
    420     cache->curMemBlockAvail = nextPos;
    421     return res;
    422 }
    423 
    424 static void* _cache_realloc(cache_t* cache, void* cur, size_t origLen, size_t len)
    425 {
    426     // This isn't really a realloc, but it is good enough for our purposes here.
    427     void* alloc = _cache_malloc(cache, len);
    428     if (alloc != NULL && cur != NULL) {
    429         memcpy(alloc, cur, origLen < len ? origLen : len);
    430     }
    431     return alloc;
    432 }
    433 
    434 static void _inc_num_cache_collected(cache_t* cache)
    435 {
    436     cache->numCollected++;
    437     if ((cache->numCollected%20000) == 0) {
    438         ALOGI("Collected cache so far: %d directories, %d files",
    439             cache->numDirs, cache->numFiles);
    440     }
    441 }
    442 
    443 static cache_dir_t* _add_cache_dir_t(cache_t* cache, cache_dir_t* parent, const char *name)
    444 {
    445     size_t nameLen = strlen(name);
    446     cache_dir_t* dir = (cache_dir_t*)_cache_malloc(cache, sizeof(cache_dir_t)+nameLen+1);
    447     if (dir != NULL) {
    448         dir->parent = parent;
    449         dir->childCount = 0;
    450         dir->hiddenCount = 0;
    451         dir->deleted = 0;
    452         strcpy(dir->name, name);
    453         if (cache->numDirs >= cache->availDirs) {
    454             size_t newAvail = cache->availDirs < 1000 ? 1000 : cache->availDirs*2;
    455             cache_dir_t** newDirs = (cache_dir_t**)_cache_realloc(cache, cache->dirs,
    456                     cache->availDirs*sizeof(cache_dir_t*), newAvail*sizeof(cache_dir_t*));
    457             if (newDirs == NULL) {
    458                 ALOGE("Failure growing cache dirs array for %s\n", name);
    459                 return NULL;
    460             }
    461             cache->availDirs = newAvail;
    462             cache->dirs = newDirs;
    463         }
    464         cache->dirs[cache->numDirs] = dir;
    465         cache->numDirs++;
    466         if (parent != NULL) {
    467             parent->childCount++;
    468         }
    469         _inc_num_cache_collected(cache);
    470     } else {
    471         ALOGE("Failure allocating cache_dir_t for %s\n", name);
    472     }
    473     return dir;
    474 }
    475 
    476 static cache_file_t* _add_cache_file_t(cache_t* cache, cache_dir_t* dir, time_t modTime,
    477         const char *name)
    478 {
    479     size_t nameLen = strlen(name);
    480     cache_file_t* file = (cache_file_t*)_cache_malloc(cache, sizeof(cache_file_t)+nameLen+1);
    481     if (file != NULL) {
    482         file->dir = dir;
    483         file->modTime = modTime;
    484         strcpy(file->name, name);
    485         if (cache->numFiles >= cache->availFiles) {
    486             size_t newAvail = cache->availFiles < 1000 ? 1000 : cache->availFiles*2;
    487             cache_file_t** newFiles = (cache_file_t**)_cache_realloc(cache, cache->files,
    488                     cache->availFiles*sizeof(cache_file_t*), newAvail*sizeof(cache_file_t*));
    489             if (newFiles == NULL) {
    490                 ALOGE("Failure growing cache file array for %s\n", name);
    491                 return NULL;
    492             }
    493             cache->availFiles = newAvail;
    494             cache->files = newFiles;
    495         }
    496         CACHE_NOISY(ALOGI("Setting file %p at position %d in array %p", file,
    497                 cache->numFiles, cache->files));
    498         cache->files[cache->numFiles] = file;
    499         cache->numFiles++;
    500         dir->childCount++;
    501         _inc_num_cache_collected(cache);
    502     } else {
    503         ALOGE("Failure allocating cache_file_t for %s\n", name);
    504     }
    505     return file;
    506 }
    507 
    508 static int _add_cache_files(cache_t *cache, cache_dir_t *parentDir, const char *dirName,
    509         DIR* dir, char *pathBase, char *pathPos, size_t pathAvailLen)
    510 {
    511     struct dirent *de;
    512     cache_dir_t* cacheDir = NULL;
    513     int dfd;
    514 
    515     CACHE_NOISY(ALOGI("_add_cache_files: parent=%p dirName=%s dir=%p pathBase=%s",
    516             parentDir, dirName, dir, pathBase));
    517 
    518     dfd = dirfd(dir);
    519 
    520     if (dfd < 0) return 0;
    521 
    522     // Sub-directories always get added to the data structure, so if they
    523     // are empty we will know about them to delete them later.
    524     cacheDir = _add_cache_dir_t(cache, parentDir, dirName);
    525 
    526     while ((de = readdir(dir))) {
    527         const char *name = de->d_name;
    528 
    529         if (de->d_type == DT_DIR) {
    530             int subfd;
    531             DIR *subdir;
    532 
    533                 /* always skip "." and ".." */
    534             if (name[0] == '.') {
    535                 if (name[1] == 0) continue;
    536                 if ((name[1] == '.') && (name[2] == 0)) continue;
    537             }
    538 
    539             subfd = openat(dfd, name, O_RDONLY | O_DIRECTORY);
    540             if (subfd < 0) {
    541                 ALOGE("Couldn't openat %s: %s\n", name, strerror(errno));
    542                 continue;
    543             }
    544             subdir = fdopendir(subfd);
    545             if (subdir == NULL) {
    546                 ALOGE("Couldn't fdopendir %s: %s\n", name, strerror(errno));
    547                 close(subfd);
    548                 continue;
    549             }
    550             if (cacheDir == NULL) {
    551                 cacheDir = _add_cache_dir_t(cache, parentDir, dirName);
    552             }
    553             if (cacheDir != NULL) {
    554                 // Update pathBase for the new path...  this may change dirName
    555                 // if that is also pointing to the path, but we are done with it
    556                 // now.
    557                 size_t finallen = snprintf(pathPos, pathAvailLen, "/%s", name);
    558                 CACHE_NOISY(ALOGI("Collecting dir %s\n", pathBase));
    559                 if (finallen < pathAvailLen) {
    560                     _add_cache_files(cache, cacheDir, name, subdir, pathBase,
    561                             pathPos+finallen, pathAvailLen-finallen);
    562                 } else {
    563                     // Whoops, the final path is too long!  We'll just delete
    564                     // this directory.
    565                     ALOGW("Cache dir %s truncated in path %s; deleting dir\n",
    566                             name, pathBase);
    567                     _delete_dir_contents(subdir, NULL);
    568                     if (unlinkat(dfd, name, AT_REMOVEDIR) < 0) {
    569                         ALOGE("Couldn't unlinkat %s: %s\n", name, strerror(errno));
    570                     }
    571                 }
    572             }
    573             closedir(subdir);
    574         } else if (de->d_type == DT_REG) {
    575             // Skip files that start with '.'; they will be deleted if
    576             // their entire directory is deleted.  This allows for metadata
    577             // like ".nomedia" to remain in the directory until the entire
    578             // directory is deleted.
    579             if (cacheDir == NULL) {
    580                 cacheDir = _add_cache_dir_t(cache, parentDir, dirName);
    581             }
    582             if (name[0] == '.') {
    583                 cacheDir->hiddenCount++;
    584                 continue;
    585             }
    586             if (cacheDir != NULL) {
    587                 // Build final full path for file...  this may change dirName
    588                 // if that is also pointing to the path, but we are done with it
    589                 // now.
    590                 size_t finallen = snprintf(pathPos, pathAvailLen, "/%s", name);
    591                 CACHE_NOISY(ALOGI("Collecting file %s\n", pathBase));
    592                 if (finallen < pathAvailLen) {
    593                     struct stat s;
    594                     if (stat(pathBase, &s) >= 0) {
    595                         _add_cache_file_t(cache, cacheDir, s.st_mtime, name);
    596                     } else {
    597                         ALOGW("Unable to stat cache file %s; deleting\n", pathBase);
    598                         if (unlink(pathBase) < 0) {
    599                             ALOGE("Couldn't unlink %s: %s\n", pathBase, strerror(errno));
    600                         }
    601                     }
    602                 } else {
    603                     // Whoops, the final path is too long!  We'll just delete
    604                     // this file.
    605                     ALOGW("Cache file %s truncated in path %s; deleting\n",
    606                             name, pathBase);
    607                     if (unlinkat(dfd, name, 0) < 0) {
    608                         *pathPos = 0;
    609                         ALOGE("Couldn't unlinkat %s in %s: %s\n", name, pathBase,
    610                                 strerror(errno));
    611                     }
    612                 }
    613             }
    614         } else {
    615             cacheDir->hiddenCount++;
    616         }
    617     }
    618     return 0;
    619 }
    620 
    621 void add_cache_files(cache_t* cache, const char *basepath, const char *cachedir)
    622 {
    623     DIR *d;
    624     struct dirent *de;
    625     char dirname[PATH_MAX];
    626 
    627     CACHE_NOISY(ALOGI("add_cache_files: base=%s cachedir=%s\n", basepath, cachedir));
    628 
    629     d = opendir(basepath);
    630     if (d == NULL) {
    631         return;
    632     }
    633 
    634     while ((de = readdir(d))) {
    635         if (de->d_type == DT_DIR) {
    636             DIR* subdir;
    637             const char *name = de->d_name;
    638             char* pathpos;
    639 
    640                 /* always skip "." and ".." */
    641             if (name[0] == '.') {
    642                 if (name[1] == 0) continue;
    643                 if ((name[1] == '.') && (name[2] == 0)) continue;
    644             }
    645 
    646             strcpy(dirname, basepath);
    647             pathpos = dirname + strlen(dirname);
    648             if ((*(pathpos-1)) != '/') {
    649                 *pathpos = '/';
    650                 pathpos++;
    651                 *pathpos = 0;
    652             }
    653             if (cachedir != NULL) {
    654                 snprintf(pathpos, sizeof(dirname)-(pathpos-dirname), "%s/%s", name, cachedir);
    655             } else {
    656                 snprintf(pathpos, sizeof(dirname)-(pathpos-dirname), "%s", name);
    657             }
    658             CACHE_NOISY(ALOGI("Adding cache files from dir: %s\n", dirname));
    659             subdir = opendir(dirname);
    660             if (subdir != NULL) {
    661                 size_t dirnameLen = strlen(dirname);
    662                 _add_cache_files(cache, NULL, dirname, subdir, dirname, dirname+dirnameLen,
    663                         PATH_MAX - dirnameLen);
    664                 closedir(subdir);
    665             }
    666         }
    667     }
    668 
    669     closedir(d);
    670 }
    671 
    672 static char *create_dir_path(char path[PATH_MAX], cache_dir_t* dir)
    673 {
    674     char *pos = path;
    675     if (dir->parent != NULL) {
    676         pos = create_dir_path(path, dir->parent);
    677     }
    678     // Note that we don't need to worry about going beyond the buffer,
    679     // since when we were constructing the cache entries our maximum
    680     // buffer size for full paths was PATH_MAX.
    681     strcpy(pos, dir->name);
    682     pos += strlen(pos);
    683     *pos = '/';
    684     pos++;
    685     *pos = 0;
    686     return pos;
    687 }
    688 
    689 static void delete_cache_dir(char path[PATH_MAX], cache_dir_t* dir)
    690 {
    691     if (dir->parent != NULL) {
    692         create_dir_path(path, dir);
    693         ALOGI("DEL DIR %s\n", path);
    694         if (dir->hiddenCount <= 0) {
    695             if (rmdir(path)) {
    696                 ALOGE("Couldn't rmdir %s: %s\n", path, strerror(errno));
    697                 return;
    698             }
    699         } else {
    700             // The directory contains hidden files so we need to delete
    701             // them along with the directory itself.
    702             if (delete_dir_contents(path, 1, NULL)) {
    703                 return;
    704             }
    705         }
    706         dir->parent->childCount--;
    707         dir->deleted = 1;
    708         if (dir->parent->childCount <= 0) {
    709             delete_cache_dir(path, dir->parent);
    710         }
    711     } else if (dir->hiddenCount > 0) {
    712         // This is a root directory, but it has hidden files.  Get rid of
    713         // all of those files, but not the directory itself.
    714         create_dir_path(path, dir);
    715         ALOGI("DEL CONTENTS %s\n", path);
    716         delete_dir_contents(path, 0, NULL);
    717     }
    718 }
    719 
    720 static int cache_modtime_sort(const void *lhsP, const void *rhsP)
    721 {
    722     const cache_file_t *lhs = *(const cache_file_t**)lhsP;
    723     const cache_file_t *rhs = *(const cache_file_t**)rhsP;
    724     return lhs->modTime < rhs->modTime ? -1 : (lhs->modTime > rhs->modTime ? 1 : 0);
    725 }
    726 
    727 void clear_cache_files(cache_t* cache, int64_t free_size)
    728 {
    729     size_t i;
    730     int skip = 0;
    731     char path[PATH_MAX];
    732 
    733     ALOGI("Collected cache files: %d directories, %d files",
    734         cache->numDirs, cache->numFiles);
    735 
    736     CACHE_NOISY(ALOGI("Sorting files..."));
    737     qsort(cache->files, cache->numFiles, sizeof(cache_file_t*),
    738             cache_modtime_sort);
    739 
    740     CACHE_NOISY(ALOGI("Cleaning empty directories..."));
    741     for (i=cache->numDirs; i>0; i--) {
    742         cache_dir_t* dir = cache->dirs[i-1];
    743         if (dir->childCount <= 0 && !dir->deleted) {
    744             delete_cache_dir(path, dir);
    745         }
    746     }
    747 
    748     CACHE_NOISY(ALOGI("Trimming files..."));
    749     for (i=0; i<cache->numFiles; i++) {
    750         skip++;
    751         if (skip > 10) {
    752             if (data_disk_free() > free_size) {
    753                 return;
    754             }
    755             skip = 0;
    756         }
    757         cache_file_t* file = cache->files[i];
    758         strcpy(create_dir_path(path, file->dir), file->name);
    759         ALOGI("DEL (mod %d) %s\n", (int)file->modTime, path);
    760         if (unlink(path) < 0) {
    761             ALOGE("Couldn't unlink %s: %s\n", path, strerror(errno));
    762         }
    763         file->dir->childCount--;
    764         if (file->dir->childCount <= 0) {
    765             delete_cache_dir(path, file->dir);
    766         }
    767     }
    768 }
    769 
    770 void finish_cache_collection(cache_t* cache)
    771 {
    772     size_t i;
    773 
    774     CACHE_NOISY(ALOGI("clear_cache_files: %d dirs, %d files\n", cache->numDirs, cache->numFiles));
    775     CACHE_NOISY(
    776         for (i=0; i<cache->numDirs; i++) {
    777             cache_dir_t* dir = cache->dirs[i];
    778             ALOGI("dir #%d: %p %s parent=%p\n", i, dir, dir->name, dir->parent);
    779         })
    780     CACHE_NOISY(
    781         for (i=0; i<cache->numFiles; i++) {
    782             cache_file_t* file = cache->files[i];
    783             ALOGI("file #%d: %p %s time=%d dir=%p\n", i, file, file->name,
    784                     (int)file->modTime, file->dir);
    785         })
    786     void* block = cache->memBlocks;
    787     while (block != NULL) {
    788         void* nextBlock = *(void**)block;
    789         CACHE_NOISY(ALOGI("Freeing cache mem block: %p", block));
    790         free(block);
    791         block = nextBlock;
    792     }
    793     free(cache);
    794 }
    795 
    796 /**
    797  * Checks whether a path points to a system app (.apk file). Returns 0
    798  * if it is a system app or -1 if it is not.
    799  */
    800 int validate_system_app_path(const char* path) {
    801     size_t i;
    802 
    803     for (i = 0; i < android_system_dirs.count; i++) {
    804         const size_t dir_len = android_system_dirs.dirs[i].len;
    805         if (!strncmp(path, android_system_dirs.dirs[i].path, dir_len)) {
    806             if (path[dir_len] == '.' || strchr(path + dir_len, '/') != NULL) {
    807                 ALOGE("invalid system apk path '%s' (trickery)\n", path);
    808                 return -1;
    809             }
    810             return 0;
    811         }
    812     }
    813 
    814     return -1;
    815 }
    816 
    817 /**
    818  * Get the contents of a environment variable that contains a path. Caller
    819  * owns the string that is inserted into the directory record. Returns
    820  * 0 on success and -1 on error.
    821  */
    822 int get_path_from_env(dir_rec_t* rec, const char* var) {
    823     const char* path = getenv(var);
    824     int ret = get_path_from_string(rec, path);
    825     if (ret < 0) {
    826         ALOGW("Problem finding value for environment variable %s\n", var);
    827     }
    828     return ret;
    829 }
    830 
    831 /**
    832  * Puts the string into the record as a directory. Appends '/' to the end
    833  * of all paths. Caller owns the string that is inserted into the directory
    834  * record. A null value will result in an error.
    835  *
    836  * Returns 0 on success and -1 on error.
    837  */
    838 int get_path_from_string(dir_rec_t* rec, const char* path) {
    839     if (path == NULL) {
    840         return -1;
    841     } else {
    842         const size_t path_len = strlen(path);
    843         if (path_len <= 0) {
    844             return -1;
    845         }
    846 
    847         // Make sure path is absolute.
    848         if (path[0] != '/') {
    849             return -1;
    850         }
    851 
    852         if (path[path_len - 1] == '/') {
    853             // Path ends with a forward slash. Make our own copy.
    854 
    855             rec->path = strdup(path);
    856             if (rec->path == NULL) {
    857                 return -1;
    858             }
    859 
    860             rec->len = path_len;
    861         } else {
    862             // Path does not end with a slash. Generate a new string.
    863             char *dst;
    864 
    865             // Add space for slash and terminating null.
    866             size_t dst_size = path_len + 2;
    867 
    868             rec->path = malloc(dst_size);
    869             if (rec->path == NULL) {
    870                 return -1;
    871             }
    872 
    873             dst = rec->path;
    874 
    875             if (append_and_increment(&dst, path, &dst_size) < 0
    876                     || append_and_increment(&dst, "/", &dst_size)) {
    877                 ALOGE("Error canonicalizing path");
    878                 return -1;
    879             }
    880 
    881             rec->len = dst - rec->path;
    882         }
    883     }
    884     return 0;
    885 }
    886 
    887 int copy_and_append(dir_rec_t* dst, const dir_rec_t* src, const char* suffix) {
    888     dst->len = src->len + strlen(suffix);
    889     const size_t dstSize = dst->len + 1;
    890     dst->path = (char*) malloc(dstSize);
    891 
    892     if (dst->path == NULL
    893             || snprintf(dst->path, dstSize, "%s%s", src->path, suffix)
    894                     != (ssize_t) dst->len) {
    895         ALOGE("Could not allocate memory to hold appended path; aborting\n");
    896         return -1;
    897     }
    898 
    899     return 0;
    900 }
    901 
    902 /**
    903  * Check whether path points to a valid path for an APK file. An ASEC
    904  * directory is allowed to have one level of subdirectory names. Returns -1
    905  * when an invalid path is encountered and 0 when a valid path is encountered.
    906  */
    907 int validate_apk_path(const char *path)
    908 {
    909     int allowsubdir = 0;
    910     char *subdir = NULL;
    911     size_t dir_len;
    912     size_t path_len;
    913 
    914     if (!strncmp(path, android_app_dir.path, android_app_dir.len)) {
    915         dir_len = android_app_dir.len;
    916     } else if (!strncmp(path, android_app_private_dir.path, android_app_private_dir.len)) {
    917         dir_len = android_app_private_dir.len;
    918     } else if (!strncmp(path, android_asec_dir.path, android_asec_dir.len)) {
    919         dir_len = android_asec_dir.len;
    920         allowsubdir = 1;
    921     } else {
    922         ALOGE("invalid apk path '%s' (bad prefix)\n", path);
    923         return -1;
    924     }
    925 
    926     path_len = strlen(path);
    927 
    928     /*
    929      * Only allow the path to have a subdirectory if it's been marked as being allowed.
    930      */
    931     if ((subdir = strchr(path + dir_len, '/')) != NULL) {
    932         ++subdir;
    933         if (!allowsubdir
    934                 || (path_len > (size_t) (subdir - path) && (strchr(subdir, '/') != NULL))) {
    935             ALOGE("invalid apk path '%s' (subdir?)\n", path);
    936             return -1;
    937         }
    938     }
    939 
    940     /*
    941      *  Directories can't have a period directly after the directory markers
    942      *  to prevent ".."
    943      */
    944     if (path[dir_len] == '.'
    945             || (subdir != NULL && ((*subdir == '.') || (strchr(subdir, '/') != NULL)))) {
    946         ALOGE("invalid apk path '%s' (trickery)\n", path);
    947         return -1;
    948     }
    949 
    950     return 0;
    951 }
    952 
    953 int append_and_increment(char** dst, const char* src, size_t* dst_size) {
    954     ssize_t ret = strlcpy(*dst, src, *dst_size);
    955     if (ret < 0 || (size_t) ret >= *dst_size) {
    956         return -1;
    957     }
    958     *dst += ret;
    959     *dst_size -= ret;
    960     return 0;
    961 }
    962 
    963 char *build_string2(char *s1, char *s2) {
    964     if (s1 == NULL || s2 == NULL) return NULL;
    965 
    966     int len_s1 = strlen(s1);
    967     int len_s2 = strlen(s2);
    968     int len = len_s1 + len_s2 + 1;
    969     char *result = malloc(len);
    970     if (result == NULL) return NULL;
    971 
    972     strcpy(result, s1);
    973     strcpy(result + len_s1, s2);
    974 
    975     return result;
    976 }
    977 
    978 char *build_string3(char *s1, char *s2, char *s3) {
    979     if (s1 == NULL || s2 == NULL || s3 == NULL) return NULL;
    980 
    981     int len_s1 = strlen(s1);
    982     int len_s2 = strlen(s2);
    983     int len_s3 = strlen(s3);
    984     int len = len_s1 + len_s2 + len_s3 + 1;
    985     char *result = malloc(len);
    986     if (result == NULL) return NULL;
    987 
    988     strcpy(result, s1);
    989     strcpy(result + len_s1, s2);
    990     strcpy(result + len_s1 + len_s2, s3);
    991 
    992     return result;
    993 }
    994 
    995 /* Ensure that /data/media directories are prepared for given user. */
    996 int ensure_media_user_dirs(userid_t userid) {
    997     char media_user_path[PATH_MAX];
    998     char path[PATH_MAX];
    999 
   1000     // Ensure /data/media/<userid> exists
   1001     create_user_media_path(media_user_path, userid);
   1002     if (fs_prepare_dir(media_user_path, 0770, AID_MEDIA_RW, AID_MEDIA_RW) == -1) {
   1003         return -1;
   1004     }
   1005 
   1006     return 0;
   1007 }
   1008