summaryrefslogtreecommitdiff
path: root/cmds/idmap/idmap.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cmds/idmap/idmap.cpp')
-rw-r--r--cmds/idmap/idmap.cpp55
1 files changed, 55 insertions, 0 deletions
diff --git a/cmds/idmap/idmap.cpp b/cmds/idmap/idmap.cpp
index d388977e8e2f..3ab191553625 100644
--- a/cmds/idmap/idmap.cpp
+++ b/cmds/idmap/idmap.cpp
@@ -13,6 +13,8 @@ SYNOPSIS \n\
idmap --help \n\
idmap --fd target overlay fd \n\
idmap --path target overlay idmap \n\
+ idmap --scan target-package-name-to-look-for path-to-target-apk dir-to-hold-idmaps \\\
+ dir-to-scan [additional-dir-to-scan [additional-dir-to-scan [...]]]\n\
idmap --inspect idmap \n\
\n\
DESCRIPTION \n\
@@ -47,6 +49,11 @@ OPTIONS \n\
--path: create idmap for target package 'target' (path to apk) and overlay package \n\
'overlay' (path to apk); write results to 'idmap' (path). \n\
\n\
+ --scan: non-recursively search directory 'dir-to-scan' (path) for overlay packages with \n\
+ target package 'target-package-name-to-look-for' (package name) present at\n\
+ 'path-to-target-apk' (path to apk). For each overlay package found, create an\n\
+ idmap file in 'dir-to-hold-idmaps' (path). \n\
+\n\
--inspect: decode the binary format of 'idmap' (path) and display the contents in a \n\
debug-friendly format. \n\
\n\
@@ -90,6 +97,16 @@ EXAMPLES \n\
NOTES \n\
This tool and its expected invocation from installd is modelled on dexopt.";
+ bool verify_directory_readable(const char *path)
+ {
+ return access(path, R_OK | X_OK) == 0;
+ }
+
+ bool verify_directory_writable(const char *path)
+ {
+ return access(path, W_OK) == 0;
+ }
+
bool verify_file_readable(const char *path)
{
return access(path, R_OK) == 0;
@@ -150,6 +167,36 @@ NOTES \n\
return idmap_create_path(target_apk_path, overlay_apk_path, idmap_path);
}
+ int maybe_scan(const char *target_package_name, const char *target_apk_path,
+ const char *idmap_dir, const android::Vector<const char *> *overlay_dirs)
+ {
+ if (!verify_root_or_system()) {
+ fprintf(stderr, "error: permission denied: not user root or user system\n");
+ return -1;
+ }
+
+ if (!verify_file_readable(target_apk_path)) {
+ ALOGD("error: failed to read apk %s: %s\n", target_apk_path, strerror(errno));
+ return -1;
+ }
+
+ if (!verify_directory_writable(idmap_dir)) {
+ ALOGD("error: no write access to %s: %s\n", idmap_dir, strerror(errno));
+ return -1;
+ }
+
+ const size_t N = overlay_dirs->size();
+ for (size_t i = 0; i < N; i++) {
+ const char *dir = overlay_dirs->itemAt(i);
+ if (!verify_directory_readable(dir)) {
+ ALOGD("error: no read access to %s: %s\n", dir, strerror(errno));
+ return -1;
+ }
+ }
+
+ return idmap_scan(target_package_name, target_apk_path, idmap_dir, overlay_dirs);
+ }
+
int maybe_inspect(const char *idmap_path)
{
// anyone (not just root or system) may do --inspect
@@ -188,6 +235,14 @@ int main(int argc, char **argv)
return maybe_create_path(argv[2], argv[3], argv[4]);
}
+ if (argc >= 6 && !strcmp(argv[1], "--scan")) {
+ android::Vector<const char *> v;
+ for (int i = 5; i < argc; i++) {
+ v.push(argv[i]);
+ }
+ return maybe_scan(argv[2], argv[3], argv[4], &v);
+ }
+
if (argc == 3 && !strcmp(argv[1], "--inspect")) {
return maybe_inspect(argv[2]);
}