• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include <utils/ResourceTypes.h>
2 #include <utils/String8.h>
3 #include <utils/String16.h>
4 #include <zipfile/zipfile.h>
5 #include <stdio.h>
6 #include <fcntl.h>
7 #include <unistd.h>
8 #include <stdlib.h>
9 
10 using namespace android;
11 
12 static int
usage()13 usage()
14 {
15     fprintf(stderr,
16             "usage: apk APKFILE\n"
17             "\n"
18             "APKFILE   an android packge file produced by aapt.\n"
19             );
20     return 1;
21 }
22 
23 
24 int
main(int argc,char ** argv)25 main(int argc, char** argv)
26 {
27     const char* filename;
28     int fd;
29     ssize_t amt;
30     off_t size;
31     void* buf;
32     zipfile_t zip;
33     zipentry_t entry;
34     void* cookie;
35     void* resfile;
36     int bufsize;
37     int err;
38 
39     if (argc != 2) {
40         return usage();
41     }
42 
43     filename = argv[1];
44     fd = open(filename, O_RDONLY);
45     if (fd == -1) {
46         fprintf(stderr, "apk: couldn't open file for read: %s\n", filename);
47         return 1;
48     }
49 
50     size = lseek(fd, 0, SEEK_END);
51     amt = lseek(fd, 0, SEEK_SET);
52 
53     if (size < 0 || amt < 0) {
54         fprintf(stderr, "apk: error determining file size: %s\n", filename);
55         return 1;
56     }
57 
58     buf = malloc(size);
59     if (buf == NULL) {
60         fprintf(stderr, "apk: file too big: %s\n", filename);
61         return 1;
62     }
63 
64     amt = read(fd, buf, size);
65     if (amt != size) {
66         fprintf(stderr, "apk: error reading file: %s\n", filename);
67         return 1;
68     }
69 
70     close(fd);
71 
72     zip = init_zipfile(buf, size);
73     if (zip == NULL) {
74         fprintf(stderr, "apk: file doesn't seem to be a zip file: %s\n",
75                 filename);
76         return 1;
77     }
78 
79     printf("files:\n");
80     cookie = NULL;
81     while ((entry = iterate_zipfile(zip, &cookie))) {
82         char* name = get_zipentry_name(entry);
83         printf("  %s\n", name);
84         free(name);
85     }
86 
87     entry = lookup_zipentry(zip, "resources.arsc");
88     if (entry != NULL) {
89         size = get_zipentry_size(entry);
90         bufsize = size + (size / 1000) + 1;
91         resfile = malloc(bufsize);
92 
93         err = decompress_zipentry(entry, resfile, bufsize);
94         if (err != 0) {
95             fprintf(stderr, "apk: error decompressing resources.arsc");
96             return 1;
97         }
98 
99         ResTable res(resfile, size, resfile);
100         res.print();
101 #if 0
102         size_t tableCount = res.getTableCount();
103         printf("Tables: %d\n", (int)tableCount);
104         for (size_t tableIndex=0; tableIndex<tableCount; tableIndex++) {
105             const ResStringPool* strings = res.getTableStringBlock(tableIndex);
106             size_t stringCount = strings->size();
107             for (size_t stringIndex=0; stringIndex<stringCount; stringIndex++) {
108                 size_t len;
109                 const char16_t* ch = strings->stringAt(stringIndex, &len);
110                 String8 s(String16(ch, len));
111                 printf("  [%3d] %s\n", (int)stringIndex, s.string());
112             }
113         }
114 
115         size_t basePackageCount = res.getBasePackageCount();
116         printf("Base Packages: %d\n", (int)basePackageCount);
117         for (size_t bpIndex=0; bpIndex<basePackageCount; bpIndex++) {
118             const String16 ch = res.getBasePackageName(bpIndex);
119             String8 s = String8(ch);
120             printf("  [%3d] %s\n", (int)bpIndex, s.string());
121         }
122 #endif
123     }
124 
125 
126     return 0;
127 }
128