Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include <u.h>
2
#include <libc.h>
3
#include <bio.h>
4
 
5
void
6
usage(void)
7
{
8
	fprint(2, "usage: unbflz [file]\n");
9
	exits("usage");
10
}
11
 
12
int
13
Bgetint(Biobuf *b)
14
{
15
	uchar p[4];
16
 
17
	if(Bread(b, p, 4) != 4)
18
		sysfatal("short read");
19
	return (p[0]<<24)|(p[1]<<16)|(p[2]<<8)|p[3];
20
}
21
 
22
/*
23
 * memmove but make sure overlap works properly.
24
 */
25
void
26
copy(uchar *dst, uchar *src, int n)
27
{
28
	while(n-- > 0)
29
		*dst++ = *src++;
30
}
31
 
32
void
33
main(int argc, char **argv)
34
{
35
	Biobuf *b, bin;
36
	char buf[5];
37
	uchar *data;
38
	ulong *blk, l;
39
	int nblk, mblk;
40
	int sum;
41
	int i, j, length, m, n, o;
42
 
43
	ARGBEGIN{
44
	default:
45
		usage();
46
	}ARGEND
47
 
48
	switch(argc){
49
	default:
50
		usage();
51
	case 0:
52
		Binit(&bin, 0, OREAD);
53
		b = &bin;
54
		break;
55
	case 1:
56
		if((b = Bopen(argv[0], OREAD)) == nil)
57
			sysfatal("open %s: %r", argv[0]);
58
		break;
59
	}
60
 
61
	if(Bread(b, buf, 4) != 4)
62
		sysfatal("short read");
63
 
64
	if(memcmp(buf, "BLZ\n", 4) != 0)
65
		sysfatal("bad header");
66
 
67
	length = Bgetint(b);
68
	data = malloc(length);
69
	if(data == nil)
70
		sysfatal("out of memory");
71
	sum = 0;
72
	nblk = 0;
73
	mblk = 0;
74
	blk = nil;
75
	while(sum < length){
76
		if(nblk>=mblk){
77
			mblk += 16384;
78
			blk = realloc(blk, (mblk+1)*sizeof(blk[0]));
79
			if(blk == nil)
80
				sysfatal("out of memory");
81
		}
82
		l = Bgetint(b);
83
		blk[nblk++] = l;
84
		if(l&(1<<31))
85
			l &= ~(1<<31);
86
		else
87
			blk[nblk++] = Bgetint(b);
88
		sum += l;
89
	}
90
	if(sum != length)
91
		sysfatal("bad compressed data %d %d", sum, length);
92
	i = 0;
93
	j = 0;
94
	while(i < length){
95
		assert(j < nblk);
96
		n = blk[j++];
97
		if(n&(1<<31)){
98
			n &= ~(1<<31);
99
			if((m=Bread(b, data+i, n)) != n)
100
				sysfatal("short read %d %d", n, m);
101
		}else{
102
			o = blk[j++];
103
			copy(data+i, data+o, n);
104
		}
105
		i += n;
106
	}
107
	write(1, data, length);
108
	exits(nil);
109
}