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