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