diff options
author | iru <devnull@localhost> | 2011-04-14 00:35:48 -0300 |
---|---|---|
committer | iru <devnull@localhost> | 2011-04-14 00:35:48 -0300 |
commit | fd8d404d520a3f10c143f5cbe7c170606fffc75c (patch) | |
tree | fbc8bf7218eca7d6290ffb1109fcc73b5b5cda33 /sys/src/cmd/aux/unbflz.c | |
parent | dd468419f2fbaa2c3fec570a88d13e8eae8f3faf (diff) |
Promote the old installer/livecd specific tools to normal tools under /sys/src/cmd. Where similar common tools already existed, I kept them.
Diffstat (limited to 'sys/src/cmd/aux/unbflz.c')
-rw-r--r-- | sys/src/cmd/aux/unbflz.c | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/sys/src/cmd/aux/unbflz.c b/sys/src/cmd/aux/unbflz.c new file mode 100644 index 000000000..5ddb821f9 --- /dev/null +++ b/sys/src/cmd/aux/unbflz.c @@ -0,0 +1,109 @@ +#include <u.h> +#include <libc.h> +#include <bio.h> + +void +usage(void) +{ + fprint(2, "usage: unbflz [file]\n"); + exits("usage"); +} + +int +Bgetint(Biobuf *b) +{ + uchar p[4]; + + if(Bread(b, p, 4) != 4) + sysfatal("short read"); + return (p[0]<<24)|(p[1]<<16)|(p[2]<<8)|p[3]; +} + +/* + * memmove but make sure overlap works properly. + */ +void +copy(uchar *dst, uchar *src, int n) +{ + while(n-- > 0) + *dst++ = *src++; +} + +void +main(int argc, char **argv) +{ + Biobuf *b, bin; + char buf[5]; + uchar *data; + ulong *blk, l; + int nblk, mblk; + int sum; + int i, j, length, m, n, o; + + ARGBEGIN{ + default: + usage(); + }ARGEND + + switch(argc){ + default: + usage(); + case 0: + Binit(&bin, 0, OREAD); + b = &bin; + break; + case 1: + if((b = Bopen(argv[0], OREAD)) == nil) + sysfatal("open %s: %r", argv[0]); + break; + } + + if(Bread(b, buf, 4) != 4) + sysfatal("short read"); + + if(memcmp(buf, "BLZ\n", 4) != 0) + sysfatal("bad header"); + + length = Bgetint(b); + data = malloc(length); + if(data == nil) + sysfatal("out of memory"); + sum = 0; + nblk = 0; + mblk = 0; + blk = nil; + while(sum < length){ + if(nblk>=mblk){ + mblk += 16384; + blk = realloc(blk, (mblk+1)*sizeof(blk[0])); + if(blk == nil) + sysfatal("out of memory"); + } + l = Bgetint(b); + blk[nblk++] = l; + if(l&(1<<31)) + l &= ~(1<<31); + else + blk[nblk++] = Bgetint(b); + sum += l; + } + if(sum != length) + sysfatal("bad compressed data %d %d", sum, length); + i = 0; + j = 0; + while(i < length){ + assert(j < nblk); + n = blk[j++]; + if(n&(1<<31)){ + n &= ~(1<<31); + if((m=Bread(b, data+i, n)) != n) + sysfatal("short read %d %d", n, m); + }else{ + o = blk[j++]; + copy(data+i, data+o, n); + } + i += n; + } + write(1, data, length); + exits(nil); +} |