diff options
| author | Kenny Root <kroot@google.com> | 2010-10-07 17:41:05 -0700 |
|---|---|---|
| committer | Android Git Automerger <android-git-automerger@android.com> | 2010-10-07 17:41:05 -0700 |
| commit | 0689b60b8644d7c4c76e5cdf7e6ce5cc4c5be124 (patch) | |
| tree | cb3522b7577d684c0e61148a7fa2278a90ac740f /cmds | |
| parent | ea445758efba6b728d5e597402e9d9538f3ef451 (diff) | |
| parent | 54e01e0f980cfb78153d5481f7e67cef90416174 (diff) | |
| download | frameworks_base-0689b60b8644d7c4c76e5cdf7e6ce5cc4c5be124.zip frameworks_base-0689b60b8644d7c4c76e5cdf7e6ce5cc4c5be124.tar.gz frameworks_base-0689b60b8644d7c4c76e5cdf7e6ce5cc4c5be124.tar.bz2 | |
am 54e01e0f: Merge "Symlink application lib directory when on SD card" into gingerbread
Merge commit '54e01e0f980cfb78153d5481f7e67cef90416174' into gingerbread-plus-aosp
* commit '54e01e0f980cfb78153d5481f7e67cef90416174':
Symlink application lib directory when on SD card
Diffstat (limited to 'cmds')
| -rw-r--r-- | cmds/installd/commands.c | 154 | ||||
| -rw-r--r-- | cmds/installd/installd.c | 12 | ||||
| -rw-r--r-- | cmds/installd/installd.h | 2 |
3 files changed, 168 insertions, 0 deletions
diff --git a/cmds/installd/commands.c b/cmds/installd/commands.c index f6f80d1..a5b3e0e 100644 --- a/cmds/installd/commands.c +++ b/cmds/installd/commands.c @@ -936,3 +936,157 @@ int movefiles() done: return 0; } + +int linklib(const char* dataDir, const char* asecLibDir) +{ + char libdir[PKG_PATH_MAX]; + struct stat s, libStat; + int rc = 0; + + const size_t libdirLen = strlen(dataDir) + strlen(PKG_LIB_POSTFIX); + if (libdirLen >= PKG_PATH_MAX) { + LOGE("library dir len too large"); + rc = -1; + goto out; + } + + if (snprintf(libdir, sizeof(libdir), "%s%s", dataDir, PKG_LIB_POSTFIX) != (ssize_t)libdirLen) { + LOGE("library dir not written successfully: %s\n", strerror(errno)); + rc = -1; + goto out; + } + + if (stat(dataDir, &s) < 0) return -1; + + if (chown(dataDir, 0, 0) < 0) { + LOGE("failed to chown '%s': %s\n", dataDir, strerror(errno)); + return -1; + } + + if (chmod(dataDir, 0700) < 0) { + LOGE("failed to chmod '%s': %s\n", dataDir, strerror(errno)); + rc = -1; + goto out; + } + + if (lstat(libdir, &libStat) < 0) { + LOGE("couldn't stat lib dir: %s\n", strerror(errno)); + rc = -1; + goto out; + } + + if (S_ISDIR(libStat.st_mode)) { + if (delete_dir_contents(libdir, 1, 0) < 0) { + rc = -1; + goto out; + } + } else if (S_ISLNK(libStat.st_mode)) { + if (unlink(libdir) < 0) { + rc = -1; + goto out; + } + } + + if (symlink(asecLibDir, libdir) < 0) { + LOGE("couldn't symlink directory '%s' -> '%s': %s\n", libdir, asecLibDir, strerror(errno)); + rc = -errno; + goto out; + } + + if (lchown(libdir, AID_SYSTEM, AID_SYSTEM) < 0) { + LOGE("cannot chown dir '%s': %s\n", libdir, strerror(errno)); + unlink(libdir); + rc = -errno; + goto out; + } + +out: + if (chmod(dataDir, s.st_mode) < 0) { + LOGE("failed to chmod '%s': %s\n", dataDir, strerror(errno)); + return -errno; + } + + if (chown(dataDir, s.st_uid, s.st_gid) < 0) { + LOGE("failed to chown '%s' : %s\n", dataDir, strerror(errno)); + return -errno; + } + + return rc; +} + +int unlinklib(const char* dataDir) +{ + char libdir[PKG_PATH_MAX]; + struct stat s, libStat; + int rc = 0; + + const size_t libdirLen = strlen(dataDir) + strlen(PKG_LIB_POSTFIX); + if (libdirLen >= PKG_PATH_MAX) { + return -1; + } + + if (snprintf(libdir, sizeof(libdir), "%s%s", dataDir, PKG_LIB_POSTFIX) != (ssize_t)libdirLen) { + LOGE("library dir not written successfully: %s\n", strerror(errno)); + return -1; + } + + if (stat(dataDir, &s) < 0) { + LOGE("couldn't state data dir"); + return -1; + } + + if (chown(dataDir, 0, 0) < 0) { + LOGE("failed to chown '%s': %s\n", dataDir, strerror(errno)); + return -1; + } + + if (chmod(dataDir, 0700) < 0) { + LOGE("failed to chmod '%s': %s\n", dataDir, strerror(errno)); + rc = -1; + goto out; + } + + if (lstat(libdir, &libStat) < 0) { + LOGE("couldn't stat lib dir: %s\n", strerror(errno)); + rc = -1; + goto out; + } + + if (S_ISDIR(libStat.st_mode)) { + if (delete_dir_contents(libdir, 1, 0) < 0) { + rc = -1; + goto out; + } + } else if (S_ISLNK(libStat.st_mode)) { + if (unlink(libdir) < 0) { + rc = -1; + goto out; + } + } + + if (mkdir(libdir, 0755) < 0) { + LOGE("cannot create dir '%s': %s\n", libdir, strerror(errno)); + rc = -errno; + goto out; + } + + if (chown(libdir, AID_SYSTEM, AID_SYSTEM) < 0) { + LOGE("cannot chown dir '%s': %s\n", libdir, strerror(errno)); + unlink(libdir); + rc = -errno; + goto out; + } + +out: + if (chmod(dataDir, s.st_mode) < 0) { + LOGE("failed to chmod '%s': %s\n", dataDir, strerror(errno)); + return -1; + } + + if (chown(dataDir, s.st_uid, s.st_gid) < 0) { + LOGE("failed to chown '%s' : %s\n", dataDir, strerror(errno)); + return -1; + } + + return rc; +} diff --git a/cmds/installd/installd.c b/cmds/installd/installd.c index c991845..9ba6402 100644 --- a/cmds/installd/installd.c +++ b/cmds/installd/installd.c @@ -101,6 +101,16 @@ static int do_movefiles(char **arg, char reply[REPLY_MAX]) return movefiles(); } +static int do_linklib(char **arg, char reply[REPLY_MAX]) +{ + return linklib(arg[0], arg[1]); +} + +static int do_unlinklib(char **arg, char reply[REPLY_MAX]) +{ + return unlinklib(arg[0]); +} + struct cmdinfo { const char *name; unsigned numargs; @@ -121,6 +131,8 @@ struct cmdinfo cmds[] = { { "getsize", 4, do_get_size }, { "rmuserdata", 2, do_rm_user_data }, { "movefiles", 0, do_movefiles }, + { "linklib", 2, do_linklib }, + { "unlinklib", 1, do_unlinklib }, }; static int readx(int s, void *_buf, int count) diff --git a/cmds/installd/installd.h b/cmds/installd/installd.h index 479e4b2..59475e9 100644 --- a/cmds/installd/installd.h +++ b/cmds/installd/installd.h @@ -111,3 +111,5 @@ int get_size(const char *pkgname, const char *apkpath, const char *fwdlock_apkpa int free_cache(int64_t free_size); int dexopt(const char *apk_path, uid_t uid, int is_public); int movefiles(); +int linklib(const char* target, const char* source); +int unlinklib(const char* libPath); |
