xref: /inferno-os/os/boot/libflate/inflatezlib.c (revision 74a4d8c26dd3c1e9febcb717cfd6cb6512991a7a)
1 #include "lib9.h"
2 #include <flate.h>
3 #include "zlib.h"
4 
5 typedef struct ZWrite	ZWrite;
6 
7 struct ZWrite
8 {
9 	ulong	adler;
10 	void	*wr;
11 	int	(*w)(void*, void*, int);
12 };
13 
14 static int
zlwrite(void * vzw,void * buf,int n)15 zlwrite(void *vzw, void *buf, int n)
16 {
17 	ZWrite *zw;
18 
19 	zw = vzw;
20 	zw->adler = adler32(zw->adler, buf, n);
21 	n = (*zw->w)(zw->wr, buf, n);
22 	if(n <= 0)
23 		return n;
24 	return n;
25 }
26 
27 int
inflatezlib(void * wr,int (* w)(void *,void *,int),void * getr,int (* get)(void *))28 inflatezlib(void *wr, int (*w)(void*, void*, int), void *getr, int (*get)(void*))
29 {
30 	ZWrite zw;
31 	ulong v;
32 	int c, i;
33 
34 	c = (*get)(getr);
35 	if(c < 0)
36 		return FlateInputFail;
37 	i = (*get)(getr);
38 	if(i < 0)
39 		return FlateInputFail;
40 
41 	if(((c << 8) | i) % 31)
42 		return FlateCorrupted;
43 	if((c & ZlibMeth) != ZlibDeflate
44 	|| (c & ZlibCInfo) > ZlibWin32k)
45 		return FlateCorrupted;
46 
47 	zw.wr = wr;
48 	zw.w = w;
49 	zw.adler = 1;
50 	i = inflate(&zw, zlwrite, getr, get);
51 	if(i != FlateOk)
52 		return i;
53 
54 	v = 0;
55 	for(i = 0; i < 4; i++){
56 		c = (*get)(getr);
57 		if(c < 0)
58 			return FlateInputFail;
59 		v = (v << 8) | c;
60 	}
61 	if(zw.adler != v)
62 		return FlateCorrupted;
63 
64 	return FlateOk;
65 }
66