summaryrefslogtreecommitdiff
path: root/sys/lib/dist.old/cmd/bzfs/unbflz.c
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@centraldogma>2011-04-11 19:47:05 +0000
committercinap_lenrek <cinap_lenrek@centraldogma>2011-04-11 19:47:05 +0000
commit45bab89362ebe122d60d5e9b1e2b949b26168db3 (patch)
treec430eb677a06d8c823fd1d2d4a9f7790c0c275d2 /sys/lib/dist.old/cmd/bzfs/unbflz.c
parent05569f6f2c54a19c1c85a7f10742913cd8904787 (diff)
livecd
Diffstat (limited to 'sys/lib/dist.old/cmd/bzfs/unbflz.c')
-rw-r--r--sys/lib/dist.old/cmd/bzfs/unbflz.c108
1 files changed, 108 insertions, 0 deletions
diff --git a/sys/lib/dist.old/cmd/bzfs/unbflz.c b/sys/lib/dist.old/cmd/bzfs/unbflz.c
new file mode 100644
index 000000000..661d65e4d
--- /dev/null
+++ b/sys/lib/dist.old/cmd/bzfs/unbflz.c
@@ -0,0 +1,108 @@
+#include <u.h>
+#include <libc.h>
+#include <bio.h>
+#include "bzfs.h"
+
+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++;
+}
+
+int
+unbflz(int in)
+{
+ int rv, out, p[2];
+ Biobuf *b, bin;
+ char buf[5];
+ uchar *data;
+ int i, j, length, n, m, o, sum;
+ ulong *blk;
+ int nblk, mblk;
+
+ if(pipe(p) < 0)
+ sysfatal("pipe: %r");
+
+ rv = p[0];
+ out = p[1];
+ switch(rfork(RFPROC|RFFDG|RFNOTEG|RFMEM)){
+ case -1:
+ sysfatal("fork: %r");
+ case 0:
+ close(rv);
+ break;
+ default:
+ close(in);
+ close(out);
+ return rv;
+ }
+
+ Binit(&bin, in, OREAD);
+ b = &bin;
+
+ 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");
+ }
+ n = Bgetint(b);
+ blk[nblk++] = n;
+ if(n&(1<<31))
+ n &= ~(1<<31);
+ else
+ blk[nblk++] = Bgetint(b);
+ sum += n;
+ }
+ 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(out, data, length);
+ close(in);
+ close(out);
+ _exits(0);
+ return -1;
+}