idmap.cpp revision 13221c9cffdb289851411bdc73a9a5236fcb9291
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\ 6913221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross SECTION ENTRY VALUE OFFSET COMMENT \n\ 7013221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross IDMAP HEADER magic 0x706d6469 0x0 \n\ 7113221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross base crc 0x484aa77f 0x1 \n\ 7213221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross overlay crc 0x03c66fa5 0x2 \n\ 7313221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross base path .......... 0x03-0x42 /system/app/target.apk \n\ 7413221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross overlay path .......... 0x43-0x82 /vendor/overlay/overlay.apk \n\ 7513221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross DATA HEADER types count 0x00000003 0x83 \n\ 7613221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross padding 0x00000000 0x84 \n\ 7713221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross type offset 0x00000004 0x85 absolute offset 0x87, xml \n\ 7813221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross type offset 0x00000007 0x86 absolute offset 0x8a, string \n\ 7913221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross DATA BLOCK entry count 0x00000001 0x87 \n\ 8013221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross entry offset 0x00000000 0x88 \n\ 8113221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross entry 0x7f020000 0x89 xml/integer \n\ 8213221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross DATA BLOCK entry count 0x00000002 0x8a \n\ 8313221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross entry offset 0x00000000 0x8b \n\ 8413221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross entry 0x7f030000 0x8c string/str \n\ 8513221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross entry 0x7f030001 0x8d string/str2 \n\ 8613221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross\n\ 8713221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross In this example, the overlay package provides three alternative resource values:\n\ 8813221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross xml/integer, string/str and string/str2.\n\ 8913221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross\n\ 9013221c9cffdb289851411bdc73a9a5236fcb9291Colin CrossNOTES \n\ 9113221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross This tool and its expected invocation from installd is modelled on dexopt."; 9213221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 9313221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross bool verify_directory_readable(const char *path) 9413221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross { 9513221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross return access(path, R_OK | X_OK) == 0; 9613221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 9713221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 9813221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross bool verify_directory_writable(const char *path) 9913221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross { 10013221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross return access(path, W_OK) == 0; 10113221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 10213221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 10313221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross bool verify_file_readable(const char *path) 10413221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross { 10513221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross return access(path, R_OK) == 0; 10613221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 10713221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 10813221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross bool verify_root_or_system() 10913221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross { 11013221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross uid_t uid = getuid(); 11113221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross gid_t gid = getgid(); 11213221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 11313221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross return (uid == 0 && gid == 0) || (uid == AID_SYSTEM && gid == AID_SYSTEM); 11413221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 11513221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 11613221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross int maybe_create_fd(const char *target_apk_path, const char *overlay_apk_path, 11713221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross const char *idmap_str) 11813221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross { 11913221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross // anyone (not just root or system) may do --fd -- the file has 12013221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross // already been opened by someone else on our behalf 12113221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 12213221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross char *endptr; 12313221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross int idmap_fd = strtol(idmap_str, &endptr, 10); 12413221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross if (*endptr != '\0') { 12513221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross fprintf(stderr, "error: failed to parse file descriptor argument %s\n", idmap_str); 12613221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross return -1; 12713221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 12813221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 12913221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross if (!verify_file_readable(target_apk_path)) { 13013221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross ALOGD("error: failed to read apk %s: %s\n", target_apk_path, strerror(errno)); 13113221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross return -1; 13213221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 13313221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 13413221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross if (!verify_file_readable(overlay_apk_path)) { 13513221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross ALOGD("error: failed to read apk %s: %s\n", overlay_apk_path, strerror(errno)); 13613221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross return -1; 13713221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 13813221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 13913221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross return idmap_create_fd(target_apk_path, overlay_apk_path, idmap_fd); 14013221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 14113221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 14213221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross int maybe_create_path(const char *target_apk_path, const char *overlay_apk_path, 14313221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross const char *idmap_path) 14413221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross { 14513221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross if (!verify_root_or_system()) { 14613221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross fprintf(stderr, "error: permission denied: not user root or user system\n"); 14713221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross return -1; 14813221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 14913221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 15013221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross if (!verify_file_readable(target_apk_path)) { 15113221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross ALOGD("error: failed to read apk %s: %s\n", target_apk_path, strerror(errno)); 15213221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross return -1; 15313221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 15413221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 15513221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross if (!verify_file_readable(overlay_apk_path)) { 15613221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross ALOGD("error: failed to read apk %s: %s\n", overlay_apk_path, strerror(errno)); 15713221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross return -1; 15813221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 15913221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 16013221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross return idmap_create_path(target_apk_path, overlay_apk_path, idmap_path); 16113221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 16213221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 16313221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross int maybe_scan(const char *overlay_dir, const char *target_package_name, 16413221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross const char *target_apk_path, const char *idmap_dir) 16513221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross { 16613221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross if (!verify_root_or_system()) { 16713221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross fprintf(stderr, "error: permission denied: not user root or user system\n"); 16813221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross return -1; 16913221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 17013221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 17113221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross if (!verify_directory_readable(overlay_dir)) { 17213221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross ALOGD("error: no read access to %s: %s\n", overlay_dir, strerror(errno)); 17313221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross return -1; 17413221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 17513221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 17613221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross if (!verify_file_readable(target_apk_path)) { 17713221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross ALOGD("error: failed to read apk %s: %s\n", target_apk_path, strerror(errno)); 17813221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross return -1; 17913221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 18013221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 18113221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross if (!verify_directory_writable(idmap_dir)) { 18213221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross ALOGD("error: no write access to %s: %s\n", idmap_dir, strerror(errno)); 18313221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross return -1; 18413221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 18513221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 18613221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross return idmap_scan(overlay_dir, target_package_name, target_apk_path, idmap_dir); 18713221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 18813221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 18913221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross int maybe_inspect(const char *idmap_path) 19013221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross { 19113221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross // anyone (not just root or system) may do --inspect 19213221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross if (!verify_file_readable(idmap_path)) { 19313221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross ALOGD("error: failed to read idmap %s: %s\n", idmap_path, strerror(errno)); 19413221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross return -1; 19513221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 19613221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross return idmap_inspect(idmap_path); 19713221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 19813221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross} 19913221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 20013221c9cffdb289851411bdc73a9a5236fcb9291Colin Crossint main(int argc, char **argv) 20113221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross{ 20213221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross#if 0 20313221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross { 20413221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross char buf[1024]; 20513221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross buf[0] = '\0'; 20613221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross for (int i = 0; i < argc; ++i) { 20713221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross strncat(buf, argv[i], sizeof(buf) - 1); 20813221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross strncat(buf, " ", sizeof(buf) - 1); 20913221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 21013221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross ALOGD("%s:%d: uid=%d gid=%d argv=%s\n", __FILE__, __LINE__, getuid(), getgid(), buf); 21113221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 21213221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross#endif 21313221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 21413221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross if (argc == 2 && !strcmp(argv[1], "--help")) { 21513221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross printf("%s\n", usage); 21613221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross return 0; 21713221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 21813221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 21913221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross if (argc == 5 && !strcmp(argv[1], "--fd")) { 22013221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross return maybe_create_fd(argv[2], argv[3], argv[4]); 22113221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 22213221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 22313221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross if (argc == 5 && !strcmp(argv[1], "--path")) { 22413221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross return maybe_create_path(argv[2], argv[3], argv[4]); 22513221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 22613221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 22713221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross if (argc == 6 && !strcmp(argv[1], "--scan")) { 22813221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross return maybe_scan(argv[2], argv[3], argv[4], argv[5]); 22913221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 23013221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 23113221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross if (argc == 3 && !strcmp(argv[1], "--inspect")) { 23213221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross return maybe_inspect(argv[2]); 23313221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 23413221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 23513221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross fprintf(stderr, "Usage: don't use this (cf dexopt usage).\n"); 23613221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross return EXIT_FAILURE; 23713221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross} 238