Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/lib/libpz/pzhead.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
* pz header support
24
*/
25
26
#include "pzlib.h"
27
28
/*
29
* read the pz header from pz->io
30
*/
31
32
int
33
pzheadread(register Pz_t* pz)
34
{
35
register int i;
36
register int n;
37
register unsigned char* s;
38
size_t m;
39
Pzpart_t* pp;
40
41
if (pz->flags & PZ_HEAD)
42
return 0;
43
44
/*
45
* check the header magic
46
*/
47
48
if (s = (unsigned char*)sfreserve(pz->io, 4, 1))
49
{
50
i = s[0];
51
n = s[1];
52
}
53
else
54
i = n = 0;
55
if (pz->disc->errorf)
56
(*pz->disc->errorf)(pz, pz->disc, -1, "%s: pzheadread: f=%08x i=%02x n=%02x partition=%s%s", pz->path, pz->flags, i, n, pz->disc->partition, s ? "" : " (nil)");
57
if (i != PZ_MAGIC_1 || n != PZ_MAGIC_2 || s[2] == 0 || s[3] >= 10)
58
{
59
sfread(pz->io, s, 0);
60
if (pz->flags & PZ_SPLIT)
61
return 0;
62
if (pz->flags & PZ_DISC)
63
{
64
pz->flags &= ~PZ_POP;
65
return -1;
66
}
67
if (!(pz->flags & (PZ_READ|PZ_WRITE|PZ_STAT)) && (m = pz->prefix.count))
68
{
69
if (pz->prefix.terminator >= 0)
70
{
71
while (m-- > 0)
72
{
73
if (!sfgetr(pz->io, pz->prefix.terminator, 0))
74
{
75
if (pz->disc->errorf)
76
(*pz->disc->errorf)(pz, pz->disc, 2, "%s: cannot read %I*u prefix record%s from data", pz->path, sizeof(pz->prefix.count), pz->prefix.count, pz->prefix.count == 1 ? "" : "s");
77
return -1;
78
}
79
}
80
}
81
else if (!sfreserve(pz->io, m, 0))
82
{
83
if (pz->disc->errorf)
84
(*pz->disc->errorf)(pz, pz->disc, 2, "%s: cannot read %I*u prefix byte%s from data", pz->path, sizeof(pz->prefix.count), pz->prefix.count, pz->prefix.count == 1 ? "" : "s");
85
return -1;
86
}
87
}
88
if (!(n = pz->row))
89
{
90
if ((pz->flags & PZ_ACCEPT) || !sfsize(pz->io))
91
n = 1;
92
else if ((n = pzfixed(pz, pz->io, NiL, 0)) <= 0 && pz->disc->partition)
93
{
94
pz->flags |= PZ_ROWONLY;
95
if (!pzpartition(pz, pz->disc->partition))
96
n = pz->row;
97
pz->flags &= ~PZ_ROWONLY;
98
}
99
}
100
if (n <= 0)
101
{
102
if (!(pz->flags & PZ_DELAY) && (pz->disc->partition || !(pz->flags & PZ_FORCE)))
103
{
104
if (pz->disc->errorf)
105
(*pz->disc->errorf)(pz, pz->disc, 2, "%s: unknown input format", pz->path);
106
return -1;
107
}
108
pz->flags |= PZ_UNKNOWN;
109
n = 1;
110
}
111
if (!(pp = vmnewof(pz->vm, 0, Pzpart_t, 1, 0)))
112
return -1;
113
pz->major = PZ_MAJOR;
114
pz->minor = PZ_MINOR;
115
pp->name = "";
116
pp->row = n;
117
return pzpartinit(pz, pp, NiL);
118
}
119
sfread(pz->io, s, 2);
120
pz->flags &= ~PZ_FORCE;
121
pz->major = sfgetc(pz->io);
122
pz->minor = sfgetc(pz->io);
123
switch (pz->major)
124
{
125
case 1:
126
if (pz->minor <= 2)
127
goto noway;
128
break;
129
case 2:
130
pz->win = sfgetu(pz->io);
131
break;
132
default:
133
goto noway;
134
}
135
pz->flags |= PZ_HEAD;
136
return pzpartread(pz);
137
noway:
138
if (pz->disc->errorf)
139
(*pz->disc->errorf)(pz, pz->disc, 2, "%s: data %d.%d not supported by implementation %d.%d", pz->path, pz->major, pz->minor, PZ_MAJOR, PZ_MINOR);
140
return -1;
141
}
142
143
/*
144
* write the pz header to op
145
*/
146
147
int
148
pzheadwrite(Pz_t* pz, Sfio_t* op)
149
{
150
register size_t i;
151
register size_t m;
152
register size_t n;
153
register char* s;
154
155
if (pz->flags & PZ_HEAD)
156
return 0;
157
pz->oop = op;
158
if (!(pz->flags & PZ_NOGZIP))
159
sfdcgzip(op, 0);
160
if (pz->flags & PZ_NOPZIP)
161
return 0;
162
sfputc(op, PZ_MAGIC_1);
163
sfputc(op, PZ_MAGIC_2);
164
if (sfsync(op))
165
return -1;
166
sfputc(op, pz->major = PZ_MAJOR);
167
sfputc(op, pz->minor = PZ_MINOR);
168
sfputu(op, pz->win);
169
if (pz->disc->comment)
170
{
171
sfputc(op, PZ_HDR_comment);
172
m = strlen(pz->disc->comment) + 1;
173
sfputu(op, m);
174
sfwrite(op, pz->disc->comment, m);
175
}
176
if (pz->det && (m = sfstrtell(pz->det)))
177
{
178
sfputc(op, PZ_HDR_options);
179
if (!(s = sfstruse(pz->det)))
180
{
181
if (pz->disc->errorf)
182
(*pz->disc->errorf)(pz, pz->disc, ERROR_SYSTEM|2, "out of space");
183
return -1;
184
}
185
m++;
186
sfputu(op, m);
187
sfwrite(op, s, m);
188
}
189
if (i = pz->prefix.count)
190
{
191
sfputc(op, PZ_HDR_prefix);
192
if (pz->prefix.terminator >= 0)
193
{
194
m = 0;
195
while (i-- > 0)
196
{
197
if (!(s = sfgetr(pz->io, pz->prefix.terminator, 0)))
198
{
199
if (pz->disc->errorf)
200
(*pz->disc->errorf)(pz, pz->disc, 2, "%s: cannot read %I*u prefix record%s from data", pz->path, sizeof(pz->prefix.count), pz->prefix.count, pz->prefix.count == 1 ? "" : "s");
201
return -1;
202
}
203
m += n = sfvalue(pz->io);
204
sfwrite(pz->tmp, s, n);
205
}
206
s = sfstrseek(pz->tmp, 0, SEEK_SET);
207
}
208
else
209
{
210
m = i;
211
if (!(s = (char*)sfreserve(pz->io, m, 0)))
212
{
213
if (pz->disc->errorf)
214
(*pz->disc->errorf)(pz, pz->disc, 2, "%s: cannot read %I*u prefix byte%s from data", pz->path, sizeof(pz->prefix.count), pz->prefix.count, pz->prefix.count == 1 ? "" : "s");
215
return -1;
216
}
217
}
218
sfputu(op, m);
219
sfwrite(op, s, m);
220
}
221
pz->flags |= PZ_HEAD;
222
return pzpartwrite(pz, op);
223
}
224
225
/*
226
* pretty print header info to op
227
*/
228
229
int
230
pzheadprint(register Pz_t* pz, register Sfio_t* op, int parts)
231
{
232
register Pzpart_t* pp;
233
char t;
234
235
if (pz->flags & PZ_FORCE)
236
sfprintf(op, "# fixed record input\n");
237
else
238
{
239
sfprintf(op, "# pzip %d.%d partition\n", pz->major, pz->minor);
240
if (pz->disc->comment)
241
sfprintf(op, "# %s\n", pz->disc->comment);
242
sfprintf(op, "# window %I*u\n", sizeof(pz->win), pz->win);
243
if (pz->prefix.count)
244
{
245
sfprintf(op, "\nprefix=%I*u", sizeof(pz->prefix.count), pz->prefix.count);
246
if (pz->prefix.terminator >= 0)
247
{
248
t = pz->prefix.terminator;
249
sfprintf(op, "*%s\n", fmtquote(&t, "'", "'", 1, FMT_ALWAYS));
250
}
251
else
252
sfputc(op, '\n');
253
}
254
if (pz->headoptions || pz->det)
255
{
256
sfputc(op, '\n');
257
if (pz->headoptions)
258
sfputr(op, pz->headoptions, '\n');
259
if (pz->det)
260
{
261
sfwrite(op, sfstrbase(pz->det), sfstrtell(pz->det));
262
sfputc(op, '\n');
263
}
264
}
265
}
266
if (parts)
267
{
268
pp = pz->partdict ? (Pzpart_t*)dtfirst(pz->partdict) : pz->part;
269
while (pp)
270
{
271
if (pzpartprint(pz, pp, op))
272
return -1;
273
if (!pz->partdict)
274
break;
275
pp = (Pzpart_t*)dtnext(pz->partdict, pp);
276
}
277
}
278
return sferror(op) ? -1 : 0;
279
}
280
281
/*
282
* pzip files may be concatenated
283
* pzfile() is called to determine if EOF has been reached
284
* or if another file is concatenated
285
* return:
286
* -1 error
287
* 0 EOF
288
* 1 another file found (and initialized in pz)
289
*/
290
291
int
292
pzfile(Pz_t* pz)
293
{
294
unsigned char* s;
295
int i;
296
int j;
297
size_t n;
298
299
/*
300
* 0 or more nul's mean clean EOF
301
*/
302
303
while (!(i = sfgetc(pz->io)));
304
if (pz->disc->errorf)
305
(*pz->disc->errorf)(pz, pz->disc, -1, "%s: pzfile: i=%02x", pz->path, i);
306
if (i == -1)
307
return 0;
308
if (i == PZ_MARK_TAIL)
309
{
310
/*
311
* file trailer
312
*/
313
314
while ((n = sfgetu(pz->io)) && !sferror(pz->io) && !sfeof(pz->io) && (s = (unsigned char*)sfreserve(pz->io, n, 0)))
315
if (pz->disc->eventf && (*pz->disc->eventf)(pz, PZ_TAILREAD, s, n, pz->disc) < 0)
316
return -1;
317
if ((i = sfgetc(pz->io)) == -1)
318
return 0;
319
}
320
j = sfgetc(pz->io);
321
if (pz->disc->errorf)
322
(*pz->disc->errorf)(pz, pz->disc, -1, "%s: pzfile: i=%02x j=%02x", pz->path, i, j);
323
if (i == PZ_MAGIC_1 && j == PZ_MAGIC_2)
324
{
325
/*
326
* next file header
327
*/
328
329
sfungetc(pz->io, j);
330
sfungetc(pz->io, i);
331
return pzopen(pz->disc, (char*)pz, PZ_AGAIN) ? 1 : -1;
332
}
333
if (pz->disc->errorf)
334
(*pz->disc->errorf)(pz, pz->disc, 2, "%s: data corrupted", pz->path);
335
return -1;
336
}
337
338