Tweak updatecmds to be able to move entire directories.

This commit is contained in:
Dianne Hackborn
2010-02-12 14:58:04 -08:00
parent f5c6eff63d
commit d705fd2b0a

View File

@@ -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;