diff options
author | Dianne Hackborn <hackbod@google.com> | 2010-02-12 14:58:04 -0800 |
---|---|---|
committer | Dianne Hackborn <hackbod@google.com> | 2010-02-12 16:29:50 -0800 |
commit | d705fd2b0aca3f57168934f2ea8c351ef249f829 (patch) | |
tree | 1e9c2835b330f7c1a202abdc1a68cc8827424ef7 /cmds | |
parent | f5c6eff63d19a9f7a970a4f90619edac873c006d (diff) | |
download | frameworks_base-d705fd2b0aca3f57168934f2ea8c351ef249f829.zip frameworks_base-d705fd2b0aca3f57168934f2ea8c351ef249f829.tar.gz frameworks_base-d705fd2b0aca3f57168934f2ea8c351ef249f829.tar.bz2 |
Tweak updatecmds to be able to move entire directories.
Diffstat (limited to 'cmds')
-rw-r--r-- | cmds/installd/commands.c | 99 |
1 files changed, 83 insertions, 16 deletions
diff --git a/cmds/installd/commands.c b/cmds/installd/commands.c index cd0302c..a447f53 100644 --- a/cmds/installd/commands.c +++ b/cmds/installd/commands.c @@ -690,6 +690,83 @@ void mkinnerdirs(char* path, int basepos, mode_t mode, int uid, int gid) } } +int movefileordir(char* srcpath, char* dstpath, int dstuid, int dstgid, + struct stat* statbuf) +{ + DIR *d; + struct dirent *de; + int res; + + int srcend = strlen(srcpath); + int dstend = strlen(dstpath); + + if (lstat(srcpath, statbuf) < 0) { + LOGW("Unable to stat %s: %s\n", srcpath, strerror(errno)); + return 1; + } + + if ((statbuf->st_mode&S_IFDIR) == 0) { + LOGI("Renaming %s to %s (uid %d)\n", srcpath, dstpath, dstuid); + mkinnerdirs(dstpath, dstend-1, S_IRWXU|S_IRWXG|S_IXOTH, dstuid, dstgid); + if (rename(srcpath, dstpath) >= 0) { + if (chown(dstpath, dstuid, dstgid) < 0) { + LOGE("cannot chown %s: %s\n", dstpath, strerror(errno)); + unlink(dstpath); + return 1; + } + } else { + LOGW("Unable to rename %s to %s: %s\n", + srcpath, dstpath, strerror(errno)); + return 1; + } + return 0; + } + + d = opendir(srcpath); + if (d == NULL) { + LOGW("Unable to opendir %s: %s\n", srcpath, strerror(errno)); + return 1; + } + + res = 0; + + while ((de = readdir(d))) { + const char *name = de->d_name; + /* always skip "." and ".." */ + if (name[0] == '.') { + if (name[1] == 0) continue; + if ((name[1] == '.') && (name[2] == 0)) continue; + } + + if ((srcend+strlen(name)) >= (PKG_PATH_MAX-2)) { + LOGW("Source path too long; skipping: %s/%s\n", srcpath, name); + continue; + } + + if ((dstend+strlen(name)) >= (PKG_PATH_MAX-2)) { + LOGW("Destination path too long; skipping: %s/%s\n", dstpath, name); + continue; + } + + srcpath[srcend] = dstpath[dstend] = '/'; + strcpy(srcpath+srcend+1, name); + strcpy(dstpath+dstend+1, name); + + if (movefileordir(srcpath, dstpath, dstuid, dstgid, statbuf) != 0) { + res = 1; + } + + // Note: we will be leaving empty directories behind in srcpath, + // but that is okay, the package manager will be erasing all of the + // data associated with .apks that disappear. + + srcpath[srcend] = dstpath[dstend] = 0; + } + + closedir(d); + return res; +} + int movefiles() { DIR *d; @@ -703,7 +780,7 @@ int movefiles() char dstpkg[PKG_NAME_MAX]; char srcpath[PKG_PATH_MAX]; char dstpath[PKG_PATH_MAX]; - int dstuid, dstgid; + int dstuid=-1, dstgid=-1; int hasspace; d = opendir(UPDATE_COMMANDS_DIR_PREFIX); @@ -757,18 +834,7 @@ int movefiles() LOGV("Move file: %s (from %s to %s)\n", buf+bufp, srcpkg, dstpkg); if (!create_move_path(srcpath, PKG_DIR_PREFIX, srcpkg, buf+bufp) && !create_move_path(dstpath, PKG_DIR_PREFIX, dstpkg, buf+bufp)) { - LOGI("Renaming %s to %s (uid %d)\n", srcpath, dstpath, dstuid); - mkinnerdirs(dstpath, strlen(dstpath)-(bufi-bufp), - S_IRWXU|S_IRWXG|S_IXOTH, dstuid, dstgid); - if (rename(srcpath, dstpath) >= 0) { - if (chown(dstpath, dstuid, dstgid) < 0) { - LOGE("cannot chown %s: %s\n", dstpath, strerror(errno)); - unlink(dstpath); - } - } else { - LOGW("Unable to rename %s to %s: %s\n", - srcpath, dstpath, strerror(errno)); - } + movefileordir(srcpath, dstpath, dstuid, dstgid, &s); } } } else { @@ -812,10 +878,11 @@ int movefiles() dstuid = s.st_uid; dstgid = s.st_gid; } else { + // Destination package doesn't + // exist... due to original-package, + // this is normal, so don't be + // noisy about it. srcpkg[0] = 0; - LOGW("Can't stat path %s in %s%s: %s\n", - dstpath, UPDATE_COMMANDS_DIR_PREFIX, - name, strerror(errno)); } } else { srcpkg[0] = 0; |