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