summaryrefslogtreecommitdiffstats
path: root/tools/aapt/printapk.cpp
blob: def6e2e683fc53c60d6c1cdf955e07f79c6d2f41 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#include <utils/ResourceTypes.h>
#include <utils/String8.h>
#include <utils/String16.h>
#include <zipfile/zipfile.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>

using namespace android;

static int
usage()
{
    fprintf(stderr,
            "usage: apk APKFILE\n"
            "\n"
            "APKFILE   an android packge file produced by aapt.\n"
            );
    return 1;
}


int
main(int argc, char** argv)
{
    const char* filename;
    int fd;
    ssize_t amt;
    off_t size;
    void* buf;
    zipfile_t zip;
    zipentry_t entry;
    void* cookie;
    void* resfile;
    int bufsize;
    int err;

    if (argc != 2) {
        return usage();
    }

    filename = argv[1];
    fd = open(filename, O_RDONLY);
    if (fd == -1) {
        fprintf(stderr, "apk: couldn't open file for read: %s\n", filename);
        return 1;
    }

    size = lseek(fd, 0, SEEK_END);
    amt = lseek(fd, 0, SEEK_SET);

    if (size < 0 || amt < 0) {
        fprintf(stderr, "apk: error determining file size: %s\n", filename);
        return 1;
    }

    buf = malloc(size);
    if (buf == NULL) {
        fprintf(stderr, "apk: file too big: %s\n", filename);
        return 1;
    }

    amt = read(fd, buf, size);
    if (amt != size) {
        fprintf(stderr, "apk: error reading file: %s\n", filename);
        return 1;
    }

    close(fd);

    zip = init_zipfile(buf, size);
    if (zip == NULL) {
        fprintf(stderr, "apk: file doesn't seem to be a zip file: %s\n",
                filename);
        return 1;
    }

    printf("files:\n");
    cookie = NULL;
    while ((entry = iterate_zipfile(zip, &cookie))) {
        char* name = get_zipentry_name(entry);
        printf("  %s\n", name);
        free(name);
    }

    entry = lookup_zipentry(zip, "resources.arsc");
    if (entry != NULL) {
        size = get_zipentry_size(entry);
        bufsize = size + (size / 1000) + 1;
        resfile = malloc(bufsize);

        err = decompress_zipentry(entry, resfile, bufsize);
        if (err != 0) {
            fprintf(stderr, "apk: error decompressing resources.arsc");
            return 1;
        }

        ResTable res(resfile, size, resfile);
        res.print();
#if 0
        size_t tableCount = res.getTableCount();
        printf("Tables: %d\n", (int)tableCount);
        for (size_t tableIndex=0; tableIndex<tableCount; tableIndex++) {
            const ResStringPool* strings = res.getTableStringBlock(tableIndex);
            size_t stringCount = strings->size();
            for (size_t stringIndex=0; stringIndex<stringCount; stringIndex++) {
                size_t len;
                const char16_t* ch = strings->stringAt(stringIndex, &len);
                String8 s(String16(ch, len));
                printf("  [%3d] %s\n", (int)stringIndex, s.string());
            }
        }

        size_t basePackageCount = res.getBasePackageCount();
        printf("Base Packages: %d\n", (int)basePackageCount);
        for (size_t bpIndex=0; bpIndex<basePackageCount; bpIndex++) {
            const String16 ch = res.getBasePackageName(bpIndex);
            String8 s = String8(ch);
            printf("  [%3d] %s\n", (int)bpIndex, s.string());
        }
#endif
    }


    return 0;
}