#include #include #include #include #include "cram.h" void usage(void) { fprint(2, "usage: %s file offset\n", argv0); exits("usage"); } void main(int argc, char **argv) { Biobuf *disk; Dentry f; uchar cblock[2*Blocksz], dblock[Blocksz]; u32int start, end; int nblocks, block, n; ARGBEGIN { default: usage(); } ARGEND if(argc != 2) usage(); if((disk = Bopen(argv[0], OREAD)) == nil) sysfatal("open: %r"); if(readdentry(disk, &f, atoll(argv[1])) < 0) sysfatal("read dentry: %r"); if(inflateinit() < 0) sysfatal("inflateinit"); nblocks = (f.length + Blocksz-1) / Blocksz; for(block = 0, start = f.data; block < nblocks; block++, start = end) { if(Bpread(disk, cblock, 4, f.index + block*4) != 4) sysfatal("read index"); end = get32(cblock); if(end < start || end-start > sizeof cblock) sysfatal("bad index: [%#ux %#ux)", start, end); n = end - start + 2; /* why +2? */ if(Bpread(disk, cblock, n, start) != n) sysfatal("read data"); if((n = inflatezlibblock(dblock, Blocksz, cblock, n)) < 0) sysfatal("inflate: %s", flateerr(n)); if(write(1, dblock, n) != n) sysfatal("write: %r"); } exits(nil); }