diff options
Diffstat (limited to 'cmds/installd')
-rw-r--r-- | cmds/installd/commands.c | 42 | ||||
-rw-r--r-- | cmds/installd/installd.c | 6 | ||||
-rw-r--r-- | cmds/installd/installd.h | 4 |
3 files changed, 52 insertions, 0 deletions
diff --git a/cmds/installd/commands.c b/cmds/installd/commands.c index dd92bbe..203d180 100644 --- a/cmds/installd/commands.c +++ b/cmds/installd/commands.c @@ -148,6 +148,48 @@ int delete_persona(uid_t persona) return delete_dir_contents(pkgdir, 1, NULL); } +int clone_persona_data(uid_t src_persona, uid_t target_persona, int copy) +{ + char src_data_dir[PKG_PATH_MAX]; + char pkg_path[PKG_PATH_MAX]; + DIR *d; + struct dirent *de; + struct stat s; + uid_t uid; + + if (create_persona_path(src_data_dir, src_persona)) { + return -1; + } + + d = opendir(src_data_dir); + if (d != NULL) { + while ((de = readdir(d))) { + const char *name = de->d_name; + + if (de->d_type == DT_DIR) { + int subfd; + /* always skip "." and ".." */ + if (name[0] == '.') { + if (name[1] == 0) continue; + if ((name[1] == '.') && (name[2] == 0)) continue; + } + /* Create the full path to the package's data dir */ + create_pkg_path(pkg_path, name, PKG_DIR_POSTFIX, src_persona); + /* Get the file stat */ + if (stat(pkg_path, &s) < 0) continue; + /* Get the uid of the package */ + ALOGI("Adding datadir for uid = %d\n", s.st_uid); + uid = (uid_t) s.st_uid % PER_USER_RANGE; + /* Create the directory for the target */ + make_user_data(name, uid + target_persona * PER_USER_RANGE, + target_persona); + } + } + closedir(d); + } + return 0; +} + int delete_cache(const char *pkgname) { char cachedir[PKG_PATH_MAX]; diff --git a/cmds/installd/installd.c b/cmds/installd/installd.c index 569b491..7f94a96 100644 --- a/cmds/installd/installd.c +++ b/cmds/installd/installd.c @@ -107,6 +107,11 @@ static int do_rm_user(char **arg, char reply[REPLY_MAX]) return delete_persona(atoi(arg[0])); /* userid */ } +static int do_clone_user_data(char **arg, char reply[REPLY_MAX]) +{ + return clone_persona_data(atoi(arg[0]), atoi(arg[1]), atoi(arg[2])); +} + static int do_movefiles(char **arg, char reply[REPLY_MAX]) { return movefiles(); @@ -146,6 +151,7 @@ struct cmdinfo cmds[] = { { "unlinklib", 1, do_unlinklib }, { "mkuserdata", 3, do_mk_user_data }, { "rmuser", 1, do_rm_user }, + { "cloneuserdata", 3, do_clone_user_data }, }; static int readx(int s, void *_buf, int count) diff --git a/cmds/installd/installd.h b/cmds/installd/installd.h index 173cabf..78342bb 100644 --- a/cmds/installd/installd.h +++ b/cmds/installd/installd.h @@ -72,6 +72,9 @@ #define PKG_NAME_MAX 128 /* largest allowed package name */ #define PKG_PATH_MAX 256 /* max size of any path we use */ +#define PER_USER_RANGE ((uid_t)100000) /* range of uids per user + uid = persona * PER_USER_RANGE + appid */ + /* data structures */ typedef struct { @@ -143,6 +146,7 @@ int renamepkg(const char *oldpkgname, const char *newpkgname); int delete_user_data(const char *pkgname, uid_t persona); int make_user_data(const char *pkgname, uid_t uid, uid_t persona); int delete_persona(uid_t persona); +int clone_persona_data(uid_t src_persona, uid_t target_persona, int copy); int delete_cache(const char *pkgname); int move_dex(const char *src, const char *dst); int rm_dex(const char *path); |