]> git.lizzy.rs Git - plan9front.git/blob - sys/src/boot/bitsy/inflate.c
kernel: avoid selecting the boot process in killbig()
[plan9front.git] / sys / src / boot / bitsy / inflate.c
1 #include "u.h"
2 #include "lib.h"
3 #include "mem.h"
4 #include "dat.h"
5 #include "fns.h"
6 #include "io.h"
7 #include <flate.h>
8
9 typedef struct Biobuf   Biobuf;
10
11 struct Biobuf
12 {
13         uchar *bp;
14         uchar *p;
15         uchar *ep;
16 };
17
18 static int      header(Biobuf*);
19 static int      trailer(Biobuf*, Biobuf*);
20 static int      getc(void*);
21 static ulong    offset(Biobuf*);
22 static int      crcwrite(void *out, void *buf, int n);
23 static ulong    get4(Biobuf *b);
24 static ulong    Boffset(Biobuf *bp);
25
26 /* GZIP flags */
27 enum {
28         Ftext=          (1<<0),
29         Fhcrc=          (1<<1),
30         Fextra=         (1<<2),
31         Fname=          (1<<3),
32         Fcomment=       (1<<4),
33
34         GZCRCPOLY       = 0xedb88320UL,
35 };
36
37 static ulong    *crctab;
38 static ulong    crc;
39
40 int
41 gunzip(uchar *out, int outn, uchar *in, int inn)
42 {
43         Biobuf bin, bout;
44         int err;
45
46         crc = 0;
47         crctab = mkcrctab(GZCRCPOLY);
48         err = inflateinit();
49         if(err != FlateOk)
50                 print("inflateinit failed: %s\n", flateerr(err));
51
52         bin.bp = bin.p = in;
53         bin.ep = in+inn;
54         bout.bp = bout.p = out;
55         bout.ep = out+outn;
56
57         err = header(&bin);
58         if(err != FlateOk)
59                 return err;
60
61         err = inflate(&bout, crcwrite, &bin, getc);
62         if(err != FlateOk)
63                 print("inflate failed: %s\n", flateerr(err));
64
65         err = trailer(&bout, &bin);
66         if(err != FlateOk)
67                 return err;
68
69         return Boffset(&bout);
70 }
71
72 static int
73 header(Biobuf *bin)
74 {
75         int i, flag;
76
77         if(getc(bin) != 0x1f || getc(bin) != 0x8b){
78                 print("bad magic\n");
79                 return FlateCorrupted;
80         }
81         if(getc(bin) != 8){
82                 print("unknown compression type\n");
83                 return FlateCorrupted;
84         }
85         
86         flag = getc(bin);
87         
88         /* mod time */
89         get4(bin);
90         
91         /* extra flags */
92         getc(bin);
93         
94         /* OS type */
95         getc(bin);
96
97         if(flag & Fextra)
98                 for(i=getc(bin); i>0; i--)
99                         getc(bin);
100         
101         /* name */
102         if(flag&Fname)
103                 while(getc(bin) != 0)
104                         ;
105
106         /* comment */
107         if(flag&Fcomment)
108                 while(getc(bin) != 0)
109                         ;
110
111         /* crc16 */
112         if(flag&Fhcrc) {
113                 getc(bin);
114                 getc(bin);
115         }
116                 
117         return FlateOk;
118 }
119
120 static int
121 trailer(Biobuf *bout, Biobuf *bin)
122 {
123         /* crc32 */
124         ulong x;
125
126         x = get4(bin);
127         if(crc != x){
128                 print("crc mismatch %lux %lux\n", crc, x);
129                 return FlateCorrupted;
130         }
131
132         /* length */
133         if(get4(bin) != Boffset(bout)){
134                 print("bad output len\n");
135                 return FlateCorrupted;
136         }
137         return FlateOk;
138 }
139
140 static ulong
141 get4(Biobuf *b)
142 {
143         ulong v;
144         int i, c;
145
146         v = 0;
147         for(i = 0; i < 4; i++){
148                 c = getc(b);
149                 v |= c << (i * 8);
150         }
151         return v;
152 }
153
154 static int
155 getc(void *in)
156 {
157         Biobuf *bp = in;
158
159         if((bp->p - bp->bp) % 10000 == 0)
160                 print(".");
161         if(bp->p >= bp->ep)
162                 return -1;
163         return *bp->p++;
164 }
165
166 static ulong
167 Boffset(Biobuf *bp)
168 {
169         return bp->p - bp->bp;
170 }
171
172 static int
173 crcwrite(void *out, void *buf, int n)
174 {
175         Biobuf *bp;
176
177         crc = blockcrc(crctab, crc, buf, n);
178         bp = out;
179         if(n > bp->ep-bp->p)
180                 n = bp->ep-bp->p;
181         memmove(bp->p, buf, n);
182         bp->p += n;
183         return n;
184 }
185
186 #undef malloc
187 #undef free
188
189 static ulong ibrkp = ~0;
190
191 void *
192 malloc(ulong n)
193 {
194         ulong rv;
195
196         if(ibrkp == ~0)
197                 ibrkp = ((ulong)end)+1024*1024;
198         n = (n+3)>>2;
199         n <<= 2;
200         rv = ibrkp;
201         ibrkp += n;
202         return (void*)rv;
203 }
204
205 void
206 free(void *)
207 {
208 }