19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/ResourceTypes.h> 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/String8.h> 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/String16.h> 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <zipfile/zipfile.h> 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdio.h> 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <fcntl.h> 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <unistd.h> 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdlib.h> 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectusing namespace android; 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectusage() 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "usage: apk APKFILE\n" 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "\n" 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "APKFILE an android packge file produced by aapt.\n" 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ); 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 1; 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectmain(int argc, char** argv) 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char* filename; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int fd; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ssize_t amt; 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project off_t size; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void* buf; 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project zipfile_t zip; 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project zipentry_t entry; 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void* cookie; 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void* resfile; 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int bufsize; 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int err; 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (argc != 2) { 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return usage(); 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project filename = argv[1]; 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fd = open(filename, O_RDONLY); 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fd == -1) { 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "apk: couldn't open file for read: %s\n", filename); 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 1; 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size = lseek(fd, 0, SEEK_END); 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project amt = lseek(fd, 0, SEEK_SET); 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (size < 0 || amt < 0) { 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "apk: error determining file size: %s\n", filename); 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 1; 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project buf = malloc(size); 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (buf == NULL) { 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "apk: file too big: %s\n", filename); 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 1; 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project amt = read(fd, buf, size); 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (amt != size) { 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "apk: error reading file: %s\n", filename); 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 1; 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project close(fd); 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project zip = init_zipfile(buf, size); 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (zip == NULL) { 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "apk: file doesn't seem to be a zip file: %s\n", 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project filename); 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 1; 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("files:\n"); 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project cookie = NULL; 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while ((entry = iterate_zipfile(zip, &cookie))) { 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char* name = get_zipentry_name(entry); 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf(" %s\n", name); 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project free(name); 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project entry = lookup_zipentry(zip, "resources.arsc"); 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (entry != NULL) { 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size = get_zipentry_size(entry); 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bufsize = size + (size / 1000) + 1; 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project resfile = malloc(bufsize); 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project err = decompress_zipentry(entry, resfile, bufsize); 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (err != 0) { 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "apk: error decompressing resources.arsc"); 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 1; 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ResTable res(resfile, size, resfile); 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project res.print(); 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if 0 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t tableCount = res.getTableCount(); 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("Tables: %d\n", (int)tableCount); 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t tableIndex=0; tableIndex<tableCount; tableIndex++) { 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResStringPool* strings = res.getTableStringBlock(tableIndex); 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t stringCount = strings->size(); 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t stringIndex=0; stringIndex<stringCount; stringIndex++) { 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t len; 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char16_t* ch = strings->stringAt(stringIndex, &len); 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8 s(String16(ch, len)); 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf(" [%3d] %s\n", (int)stringIndex, s.string()); 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t basePackageCount = res.getBasePackageCount(); 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("Base Packages: %d\n", (int)basePackageCount); 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t bpIndex=0; bpIndex<basePackageCount; bpIndex++) { 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char16_t* ch = res.getBasePackageName(bpIndex); 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8 s = String8(String16(ch)); 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf(" [%3d] %s\n", (int)bpIndex, s.string()); 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 128