Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/lib/libpz/sfdcpzip.c
1808 views
1
/***********************************************************************
2
* *
3
* This software is part of the ast package *
4
* Copyright (c) 1998-2011 AT&T Intellectual Property *
5
* and is licensed under the *
6
* Eclipse Public License, Version 1.0 *
7
* by AT&T Intellectual Property *
8
* *
9
* A copy of the License is available at *
10
* http://www.eclipse.org/org/documents/epl-v10.html *
11
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
12
* *
13
* Information and Software Systems Research *
14
* AT&T Research *
15
* Florham Park NJ *
16
* *
17
* Glenn Fowler <[email protected]> *
18
* *
19
***********************************************************************/
20
#pragma prototyped
21
22
/*
23
* sfio pzip discipline
24
*/
25
26
#include "pzlib.h"
27
28
#include <sfdcbzip.h>
29
30
#define GZ_MAGIC_1 0x1f /* 1st gzip magic char */
31
#define GZ_MAGIC_2 0x8b /* 2nd gzip magic char */
32
#define LZ_MAGIC_2 0x9d /* 2nd lzw magic char */
33
34
#define PZ_GZ_MAGOFF 10 /* compressed magic offset */
35
#define PZ_GZ_MAGIC_1 0x92 /* 1st compressed magic char */
36
#define PZ_GZ_MAGIC_2 0x17 /* 2nd compressed magic char */
37
38
typedef struct
39
{
40
Sfdisc_t sfdisc; /* sfio discipline */
41
Pzdisc_t disc; /* pzip discipline */
42
Pz_t* pz; /* pz handle */
43
Sfio_t* io; /* real pzwrite stream */
44
} Sfpzip_t;
45
46
/*
47
* pzip exception handler
48
* free on close
49
*/
50
51
static int
52
sfpzexcept(Sfio_t* sp, int op, void* val, Sfdisc_t* dp)
53
{
54
register Sfpzip_t* pz = (Sfpzip_t*)dp;
55
int r;
56
57
NoP(sp);
58
switch (op)
59
{
60
case SF_ATEXIT:
61
sfdisc(sp, SF_POPDISC);
62
return 0;
63
case SF_CLOSING:
64
case SF_DPOP:
65
case SF_FINAL:
66
if (pz->pz)
67
{
68
pz->pz->flags &= ~PZ_STREAM;
69
r = pzclose(pz->pz);
70
pz->pz = 0;
71
}
72
else
73
r = 0;
74
if (op != SF_CLOSING)
75
free(dp);
76
return r;
77
case SF_DBUFFER:
78
return 1;
79
case SF_SYNC:
80
return val ? 0 : pzsync(pz->pz);
81
case SFPZ_HANDLE:
82
return (*((Pz_t**)val) = pz->pz) ? 1 : -1;
83
}
84
return 0;
85
}
86
87
/*
88
* sfio pzip discipline read
89
*/
90
91
static ssize_t
92
sfpzread(Sfio_t* fp, Void_t* buf, size_t size, Sfdisc_t* dp)
93
{
94
register Sfpzip_t* pz = (Sfpzip_t*)dp;
95
96
return pzread(pz->pz, buf, size);
97
}
98
99
/*
100
* sfio pzip discipline write
101
*/
102
103
static ssize_t
104
sfpzwrite(Sfio_t* fp, const Void_t* buf, size_t size, Sfdisc_t* dp)
105
{
106
register Sfpzip_t* pz = (Sfpzip_t*)dp;
107
108
return pzwrite(pz->pz, pz->io, buf, size);
109
}
110
111
/*
112
* create and push the sfio pzip discipline
113
*
114
* (flags&PZ_STAT) return
115
* >0 is a pzip file
116
* 0 not a pzip file
117
* <0 error
118
* otherwise flags have pzopen() semantics and return
119
* >0 discipline pushed (one or more of { pzip gzip lzw })
120
* 0 discipline not needed
121
* <0 error
122
*/
123
124
int
125
sfdcpzip(Sfio_t* sp, const char* path, unsigned long flags, Pzdisc_t* disc)
126
{
127
Sfio_t* io;
128
Sfpzip_t* pz;
129
Pz_t* oz;
130
131
if (flags & PZ_HANDLE)
132
{
133
oz = (Pz_t*)sp;
134
sp = oz->io;
135
}
136
else
137
oz = 0;
138
if (sfset(sp, 0, 0) & SF_WRITE)
139
{
140
if (flags & PZ_STAT)
141
return -1;
142
}
143
else if (!(flags & PZ_FORCE))
144
{
145
unsigned char* s;
146
int r;
147
int m1;
148
int m2;
149
150
if (!(r = sfset(sp, 0, 0) & SF_SHARE))
151
sfset(sp, SF_SHARE, 1);
152
s = (unsigned char*)sfreserve(sp, PZ_GZ_MAGOFF + 2, 1);
153
if (!r)
154
sfset(sp, SF_SHARE, 0);
155
if (!s)
156
return -1;
157
m1 = s[0];
158
m2 = s[1];
159
r = m1 == PZ_MAGIC_1 && m2 == PZ_MAGIC_2 && s[2] > 0 && s[3] < 10 ||
160
m1 == GZ_MAGIC_1 && m2 == GZ_MAGIC_2 &&
161
s[PZ_GZ_MAGOFF] == PZ_GZ_MAGIC_1 && s[PZ_GZ_MAGOFF+1] == PZ_GZ_MAGIC_2;
162
sfread(sp, s, 0);
163
if (flags & PZ_STAT)
164
return r;
165
if (!r)
166
{
167
if (!(flags & PZ_NOGZIP))
168
{
169
if (m1 == GZ_MAGIC_1)
170
{
171
if (m2 == GZ_MAGIC_2)
172
r = sfdcgzip(sp, (flags & PZ_CRC) ? 0 : SFGZ_NOCRC);
173
else if (m2 == LZ_MAGIC_2)
174
r = sfdclzw(sp, 0);
175
}
176
else if (m1 == 'B' && m2 == 'Z' && s[2] == 'h' && s[3] >= '1' && s[3] <= '9')
177
r = sfdcbzip(sp, 0);
178
}
179
return r;
180
}
181
sfsync(sp);
182
}
183
if (!(io = sfnew(NiL, NiL, SF_UNBOUND, sffileno(sp), (sfset(sp, 0, 0) & (SF_READ|SF_WRITE)))))
184
return -1;
185
if (!(pz = newof(0, Sfpzip_t, 1, 0)))
186
{
187
io->_file = -1;
188
sfclose(io);
189
return -1;
190
}
191
pz->disc.version = PZ_VERSION;
192
flags &= ~(PZ_READ|PZ_WRITE|PZ_STAT|PZ_STREAM|PZ_INTERNAL);
193
flags |= PZ_PUSHED|PZ_STREAM|((sfset(sp, 0, 0) & SF_READ) ? PZ_READ : PZ_WRITE);
194
if (oz && (oz->flags & PZ_WRITE))
195
flags |= PZ_DELAY;
196
if (disc)
197
{
198
pz->disc.errorf = disc->errorf;
199
pz->disc.window = disc->window;
200
pz->disc.options = disc->options;
201
pz->disc.partition = disc->partition;
202
if (disc->splitf)
203
flags |= PZ_ACCEPT;
204
}
205
if (!(pz->pz = pzopen(&pz->disc, (char*)io, flags)) || (sp->_file = open("/dev/null", 0)) < 0)
206
{
207
io->_file = -1;
208
sfclose(io);
209
free(pz);
210
return -1;
211
}
212
if (path)
213
pz->pz->path = path;
214
pz->sfdisc.exceptf = sfpzexcept;
215
if (flags & PZ_WRITE)
216
{
217
pz->sfdisc.writef = sfpzwrite;
218
pz->io = io;
219
}
220
else
221
pz->sfdisc.readf = sfpzread;
222
sfset(sp, SF_SHARE|SF_PUBLIC, 0);
223
if (sfdisc(sp, &pz->sfdisc) != &pz->sfdisc)
224
{
225
close(sp->_file);
226
sp->_file = io->_file;
227
sfseek(sp, sftell(io), SEEK_SET);
228
io->_file = -1;
229
pzclose(pz->pz);
230
free(pz);
231
return -1;
232
}
233
if (oz)
234
oz->flags |= pz->pz->flags & PZ_INTERNAL;
235
return 1;
236
}
237
238