static int dump_header(const char *filename) { int fd; xar_header_t xh; if(filename == NULL) fd = 0; else { fd = open(filename, O_RDONLY); if( fd < 0 ) { perror("open"); exit(1); } } if( read(fd, &xh, sizeof(xh)) < sizeof(xh) ) { fprintf(stderr, "error reading header\n"); exit(1); } printf("magic: 0x%x ", ntohl(xh.magic)); if( ntohl(xh.magic) != XAR_HEADER_MAGIC ) printf("(BAD)\n"); else printf("(OK)\n"); printf("size: %d\n", ntohs(xh.size)); printf("version: %d\n", ntohs(xh.version)); printf("Compressed TOC length: %" PRId64 "\n", xar_ntoh64(xh.toc_length_compressed)); printf("Uncompressed TOC length: %" PRId64 "\n", xar_ntoh64(xh.toc_length_uncompressed)); printf("Checksum algorithm: %d ", ntohl(xh.cksum_alg)); switch( ntohl(xh.cksum_alg) ) { case XAR_CKSUM_NONE: printf("(none)\n"); break; case XAR_CKSUM_SHA1: printf("(SHA1)\n"); break; case XAR_CKSUM_MD5: printf("(MD5)\n"); break; default: printf("(unknown)\n"); break; }; return 0; }
int main(int argc, char *argv[]) { char *file = argv[1]; xar_t x; xar_iter_t ifile, iprop, iattr; xar_file_t f; const char *key; int fd; off_t off; xar_header_t hdr; x = xar_open(file, READ); if( !x ) { fprintf(stderr, "Error opening archive\n"); exit(1); } fd = open(file, O_RDONLY); if( fd < 0 ) { fprintf(stderr, "Error opening archive\n"); exit(1); } read(fd, &hdr, sizeof(hdr)); hdr.size = htons(hdr.size); hdr.toc_length_compressed = xar_ntoh64(hdr.toc_length_compressed); HeapOff = hdr.size + hdr.toc_length_compressed; ifile = xar_iter_new(); if( !ifile ) { fprintf(stderr, "Error creating file iterator"); exit(1); } for(f = xar_file_first(x, ifile); f; f = xar_file_next(ifile)) { prop_check(fd, x, f); } }
char *pkg_toc_extract(const char *path) { unsigned char *bufcomp = NULL, *bufuncomp = NULL; int len; int infd, outfd; int ret; ssize_t sread; struct xar_header h; z_stream zs; char *tmp = mem_alloc(PATH_MAX); if ((infd = open(path, O_RDONLY)) < 0) { Log(LOG_ERROR, "error importing pkg %s: %d:%s", path, errno, strerror(errno)); FAIL; } snprintf(tmp, PATH_MAX - 1, "%s.XXXXXX", path); if ((outfd = mkstemp(tmp)) < 0) { Log(LOG_ERROR, "error opening toc output file %s: %d:%s", path, errno, strerror(errno)); FAIL; } if (read(infd, &h, 8) < 0) { Log(LOG_ERROR, "error reading Xar header on pkg %s: %d:%s", path, errno, strerror(errno)); FAIL; } h.magic = ntohl(h.magic); h.size = ntohs(h.size); h.version = ntohs(h.version); len = sizeof(h.magic) + sizeof(h.size) + sizeof(h.version); if (read(infd, &h.toc_length_compressed, h.size - len) < 0) { Log(LOG_ERROR, "error reading Xar toc size on pkg %s: %d:%s", path, errno, strerror(errno)); FAIL; } /* * BEGIN: Voodoo lifted from toc_extract.c in xar distribution */ h.toc_length_compressed = xar_ntoh64(h.toc_length_compressed); h.toc_length_uncompressed = xar_ntoh64(h.toc_length_uncompressed); h.cksum_alg = ntohl(h.cksum_alg); bufcomp = mem_alloc(pkg_toc_zbufsize); bufuncomp = mem_alloc(pkg_toc_zbufsize); zs.zalloc = Z_NULL; zs.zfree = Z_NULL; zs.opaque = Z_NULL; if ((ret = inflateInit(&zs)) != Z_OK) { Log(LOG_ERROR, "inflateInit doesnt like us... ret=%d", ret); FAIL; } sread = 0; while (sread < h.toc_length_compressed) { int sz = pkg_toc_zbufsize; if (h.toc_length_compressed - sread < pkg_toc_zbufsize) sz = h.toc_length_compressed - sread; if ((ret = read(infd, bufcomp, sz)) < 0) { Log(LOG_ERROR, "error reading Xar toc on pkg %s: %d:%s", path, errno, strerror(errno)); FAIL; } sread += ret; zs.next_in = bufcomp; zs.avail_in = ret; do { int err; zs.avail_out = pkg_toc_zbufsize; zs.next_out = bufuncomp; if ((err = inflate(&zs, Z_SYNC_FLUSH)) != Z_OK) { switch (err) { case Z_NEED_DICT: case Z_DATA_ERROR: Log(LOG_ERROR, "invalid compressed data in toc for %s", path); inflateEnd(&zs); FAIL; case Z_MEM_ERROR: Log(LOG_ERROR, "out of memory uncompressing TOC for %s", path); inflateEnd(&zs); FAIL; } } len = pkg_toc_zbufsize - zs.avail_out; write(outfd, bufuncomp, len); } while (zs.avail_out == 0); } /* * END: Voodoo lifted from toc_extract.c in xar distribution */ /* * cleanup */ inflateEnd(&zs); close(infd); close(outfd); return tmp; }