]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/aux/unbflz.c
exec(2): fix prototypes
[plan9front.git] / sys / src / cmd / aux / unbflz.c
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 }