113221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross#include "idmap.h" 213221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 313221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross#include <private/android_filesystem_config.h> // for AID_SYSTEM 413221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 513221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross#include <stdlib.h> 613221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross#include <string.h> 713221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 813221c9cffdb289851411bdc73a9a5236fcb9291Colin Crossnamespace { 913221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross const char *usage = "NAME\n\ 1013221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross idmap - create or display idmap files\n\ 1113221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross\n\ 1213221c9cffdb289851411bdc73a9a5236fcb9291Colin CrossSYNOPSIS \n\ 1313221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross idmap --help \n\ 1413221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross idmap --fd target overlay fd \n\ 1513221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross idmap --path target overlay idmap \n\ 1613221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross idmap --scan dir-to-scan target-to-look-for target dir-to-hold-idmaps \n\ 1713221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross idmap --inspect idmap \n\ 1813221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross\n\ 1913221c9cffdb289851411bdc73a9a5236fcb9291Colin CrossDESCRIPTION \n\ 2013221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross Idmap files play an integral part in the runtime resource overlay framework. An idmap \n\ 2113221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross file contains a mapping of resource identifiers between overlay package and its target \n\ 2213221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross package; this mapping is used during resource lookup. Idmap files also act as control \n\ 2313221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross files by their existence: if not present, the corresponding overlay package is ignored \n\ 2413221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross when the resource context is created. \n\ 2513221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross\n\ 2613221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross Idmap files are stored in /data/resource-cache. For each pair (target package, overlay \n\ 2713221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross package), there exists exactly one idmap file, or none if the overlay should not be used. \n\ 2813221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross\n\ 2913221c9cffdb289851411bdc73a9a5236fcb9291Colin CrossNOMENCLATURE \n\ 3013221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross target: the original, non-overlay, package. Each target package may be associated with \n\ 3113221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross any number of overlay packages. \n\ 3213221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross\n\ 3313221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross overlay: an overlay package. Each overlay package is associated with exactly one target \n\ 3413221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross package, specified in the overlay's manifest using the <overlay target=\"...\"/> \n\ 3513221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross tag. \n\ 3613221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross\n\ 3713221c9cffdb289851411bdc73a9a5236fcb9291Colin CrossOPTIONS \n\ 3813221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross --help: display this help \n\ 3913221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross\n\ 4013221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross --fd: create idmap for target package 'target' (path to apk) and overlay package 'overlay' \n\ 4113221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross (path to apk); write results to file descriptor 'fd' (integer). This invocation \n\ 4213221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross version is intended to be used by a parent process with higher privileges to call \n\ 4313221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross idmap in a controlled way: the parent will open a suitable file descriptor, fork, \n\ 4413221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross drop its privileges and exec. This tool will continue execution without the extra \n\ 4513221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross privileges, but still have write access to a file it could not have opened on its \n\ 4613221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross own. \n\ 4713221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross\n\ 4813221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross --path: create idmap for target package 'target' (path to apk) and overlay package \n\ 4913221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 'overlay' (path to apk); write results to 'idmap' (path). \n\ 5013221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross\n\ 5113221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross --scan: non-recursively search directory 'dir-to-scan' (path) for overlay packages with \n\ 5213221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross target package 'target-to-look-for' (package name) present at 'target' (path to \n\ 5313221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross apk). For each overlay package found, create an idmap file in 'dir-to-hold-idmaps' \n\ 5413221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross (path). \n\ 5513221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross\n\ 5613221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross --inspect: decode the binary format of 'idmap' (path) and display the contents in a \n\ 5713221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross debug-friendly format. \n\ 5813221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross\n\ 5913221c9cffdb289851411bdc73a9a5236fcb9291Colin CrossEXAMPLES \n\ 6013221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross Create an idmap file: \n\ 6113221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross\n\ 6213221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross $ adb shell idmap --path /system/app/target.apk \\ \n\ 6313221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross /vendor/overlay/overlay.apk \\ \n\ 6413221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross /data/resource-cache/vendor@overlay@overlay.apk@idmap \n\ 6513221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross\n\ 6613221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross Display an idmap file: \n\ 6713221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross\n\ 6813221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross $ adb shell idmap --inspect /data/resource-cache/vendor@overlay@overlay.apk@idmap \n\ 69f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski SECTION ENTRY VALUE COMMENT \n\ 70f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski IDMAP HEADER magic 0x706d6469 \n\ 71f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski base crc 0xb65a383f \n\ 72f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski overlay crc 0x7b9675e8 \n\ 73f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski base path .......... /path/to/target.apk \n\ 74f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski overlay path .......... /path/to/overlay.apk \n\ 75f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski DATA HEADER target pkg 0x0000007f \n\ 76f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski types count 0x00000003 \n\ 77f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski DATA BLOCK target type 0x00000002 \n\ 78f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski overlay type 0x00000002 \n\ 79f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski entry count 0x00000001 \n\ 80f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski entry offset 0x00000000 \n\ 81f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski entry 0x00000000 drawable/drawable \n\ 82f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski DATA BLOCK target type 0x00000003 \n\ 83f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski overlay type 0x00000003 \n\ 84f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski entry count 0x00000001 \n\ 85f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski entry offset 0x00000000 \n\ 86f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski entry 0x00000000 xml/integer \n\ 87f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski DATA BLOCK target type 0x00000004 \n\ 88f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski overlay type 0x00000004 \n\ 89f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski entry count 0x00000001 \n\ 90f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski entry offset 0x00000000 \n\ 91f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski entry 0x00000000 raw/lorem_ipsum \n\ 9213221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross\n\ 9313221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross In this example, the overlay package provides three alternative resource values:\n\ 94f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski drawable/drawable, xml/integer, and raw/lorem_ipsum \n\ 9513221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross\n\ 9613221c9cffdb289851411bdc73a9a5236fcb9291Colin CrossNOTES \n\ 9713221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross This tool and its expected invocation from installd is modelled on dexopt."; 9813221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 9913221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross bool verify_directory_readable(const char *path) 10013221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross { 10113221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross return access(path, R_OK | X_OK) == 0; 10213221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 10313221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 10413221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross bool verify_directory_writable(const char *path) 10513221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross { 10613221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross return access(path, W_OK) == 0; 10713221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 10813221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 10913221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross bool verify_file_readable(const char *path) 11013221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross { 11113221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross return access(path, R_OK) == 0; 11213221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 11313221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 11413221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross bool verify_root_or_system() 11513221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross { 11613221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross uid_t uid = getuid(); 11713221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross gid_t gid = getgid(); 11813221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 11913221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross return (uid == 0 && gid == 0) || (uid == AID_SYSTEM && gid == AID_SYSTEM); 12013221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 12113221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 12213221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross int maybe_create_fd(const char *target_apk_path, const char *overlay_apk_path, 12313221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross const char *idmap_str) 12413221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross { 12513221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross // anyone (not just root or system) may do --fd -- the file has 12613221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross // already been opened by someone else on our behalf 12713221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 12813221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross char *endptr; 12913221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross int idmap_fd = strtol(idmap_str, &endptr, 10); 13013221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross if (*endptr != '\0') { 13113221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross fprintf(stderr, "error: failed to parse file descriptor argument %s\n", idmap_str); 13213221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross return -1; 13313221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 13413221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 13513221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross if (!verify_file_readable(target_apk_path)) { 13613221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross ALOGD("error: failed to read apk %s: %s\n", target_apk_path, strerror(errno)); 13713221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross return -1; 13813221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 13913221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 14013221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross if (!verify_file_readable(overlay_apk_path)) { 14113221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross ALOGD("error: failed to read apk %s: %s\n", overlay_apk_path, strerror(errno)); 14213221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross return -1; 14313221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 14413221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 14513221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross return idmap_create_fd(target_apk_path, overlay_apk_path, idmap_fd); 14613221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 14713221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 14813221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross int maybe_create_path(const char *target_apk_path, const char *overlay_apk_path, 14913221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross const char *idmap_path) 15013221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross { 15113221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross if (!verify_root_or_system()) { 15213221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross fprintf(stderr, "error: permission denied: not user root or user system\n"); 15313221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross return -1; 15413221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 15513221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 15613221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross if (!verify_file_readable(target_apk_path)) { 15713221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross ALOGD("error: failed to read apk %s: %s\n", target_apk_path, strerror(errno)); 15813221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross return -1; 15913221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 16013221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 16113221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross if (!verify_file_readable(overlay_apk_path)) { 16213221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross ALOGD("error: failed to read apk %s: %s\n", overlay_apk_path, strerror(errno)); 16313221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross return -1; 16413221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 16513221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 16613221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross return idmap_create_path(target_apk_path, overlay_apk_path, idmap_path); 16713221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 16813221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 16913221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross int maybe_scan(const char *overlay_dir, const char *target_package_name, 17013221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross const char *target_apk_path, const char *idmap_dir) 17113221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross { 17213221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross if (!verify_root_or_system()) { 17313221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross fprintf(stderr, "error: permission denied: not user root or user system\n"); 17413221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross return -1; 17513221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 17613221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 17713221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross if (!verify_directory_readable(overlay_dir)) { 17813221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross ALOGD("error: no read access to %s: %s\n", overlay_dir, strerror(errno)); 17913221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross return -1; 18013221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 18113221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 18213221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross if (!verify_file_readable(target_apk_path)) { 18313221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross ALOGD("error: failed to read apk %s: %s\n", target_apk_path, strerror(errno)); 18413221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross return -1; 18513221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 18613221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 18713221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross if (!verify_directory_writable(idmap_dir)) { 18813221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross ALOGD("error: no write access to %s: %s\n", idmap_dir, strerror(errno)); 18913221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross return -1; 19013221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 19113221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 19213221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross return idmap_scan(overlay_dir, target_package_name, target_apk_path, idmap_dir); 19313221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 19413221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 19513221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross int maybe_inspect(const char *idmap_path) 19613221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross { 19713221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross // anyone (not just root or system) may do --inspect 19813221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross if (!verify_file_readable(idmap_path)) { 19913221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross ALOGD("error: failed to read idmap %s: %s\n", idmap_path, strerror(errno)); 20013221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross return -1; 20113221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 20213221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross return idmap_inspect(idmap_path); 20313221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 20413221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross} 20513221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 20613221c9cffdb289851411bdc73a9a5236fcb9291Colin Crossint main(int argc, char **argv) 20713221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross{ 20813221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross#if 0 20913221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross { 21013221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross char buf[1024]; 21113221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross buf[0] = '\0'; 21213221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross for (int i = 0; i < argc; ++i) { 21313221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross strncat(buf, argv[i], sizeof(buf) - 1); 21413221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross strncat(buf, " ", sizeof(buf) - 1); 21513221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 21613221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross ALOGD("%s:%d: uid=%d gid=%d argv=%s\n", __FILE__, __LINE__, getuid(), getgid(), buf); 21713221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 21813221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross#endif 21913221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 22013221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross if (argc == 2 && !strcmp(argv[1], "--help")) { 22113221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross printf("%s\n", usage); 22213221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross return 0; 22313221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 22413221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 22513221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross if (argc == 5 && !strcmp(argv[1], "--fd")) { 22613221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross return maybe_create_fd(argv[2], argv[3], argv[4]); 22713221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 22813221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 22913221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross if (argc == 5 && !strcmp(argv[1], "--path")) { 23013221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross return maybe_create_path(argv[2], argv[3], argv[4]); 23113221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 23213221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 23313221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross if (argc == 6 && !strcmp(argv[1], "--scan")) { 23413221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross return maybe_scan(argv[2], argv[3], argv[4], argv[5]); 23513221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 23613221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 23713221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross if (argc == 3 && !strcmp(argv[1], "--inspect")) { 23813221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross return maybe_inspect(argv[2]); 23913221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 24013221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 24113221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross fprintf(stderr, "Usage: don't use this (cf dexopt usage).\n"); 24213221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross return EXIT_FAILURE; 24313221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross} 244