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