summaryrefslogtreecommitdiffstats
path: root/cmds
diff options
context:
space:
mode:
authorDianne Hackborn <hackbod@google.com>2010-02-12 14:58:04 -0800
committerDianne Hackborn <hackbod@google.com>2010-02-12 16:29:50 -0800
commitd705fd2b0aca3f57168934f2ea8c351ef249f829 (patch)
tree1e9c2835b330f7c1a202abdc1a68cc8827424ef7 /cmds
parentf5c6eff63d19a9f7a970a4f90619edac873c006d (diff)
downloadframeworks_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.c99
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;