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