Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/cmd/pax/paxlib.c
1808 views
1
/***********************************************************************
2
* *
3
* This software is part of the ast package *
4
* Copyright (c) 1987-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
* Glenn Fowler
23
*
24
* pax pax external library support
25
*/
26
27
#include "pax.h"
28
29
#undef paxchecksum
30
#undef paxcorrupt
31
#undef paxdata
32
#undef paxget
33
#undef paxnext
34
#undef paxnospace
35
#undef paxpart
36
#undef paxput
37
#undef paxread
38
#undef paxseek
39
#undef paxstash
40
#undef paxsync
41
#undef paxunread
42
#undef paxwrite
43
44
static const char null[] = "";
45
static const char sep[] = ": ";
46
47
#define TXT(s,m) (s)?sep:null,(s)?(m):null
48
49
static int
50
paxdata(Pax_t* pax, Paxarchive_t* ap, Paxfile_t* f, int fd, void* b, off_t n)
51
{
52
return holewrite(fd, b, n) == n ? 0 : -1;
53
}
54
55
static void*
56
paxget(Pax_t* pax, Paxarchive_t* ap, off_t n, off_t* p)
57
{
58
return bget(ap, n, p);
59
}
60
61
static int
62
paxput(Pax_t* pax, Paxarchive_t* ap, off_t n)
63
{
64
bput(ap, n);
65
return 0;
66
}
67
68
static off_t
69
paxread(Pax_t* pax, Paxarchive_t* ap, void* b, off_t n, off_t m, int must)
70
{
71
return bread(ap, b, n, m, must);
72
}
73
74
static off_t
75
paxseek(Pax_t* pax, Paxarchive_t* ap, off_t pos, int op, int hard)
76
{
77
return bseek(ap, pos, op, hard);
78
}
79
80
static char*
81
paxstash(Pax_t* pax, Value_t* v, const char* s, size_t z)
82
{
83
return stash(v, s, z);
84
}
85
86
static int
87
paxsync(Pax_t* pax, Paxarchive_t* ap, int hard)
88
{
89
if (ap->io->mode == O_RDONLY)
90
bflushin(ap, hard);
91
else
92
bflushout(ap);
93
return 0;
94
}
95
96
static int
97
paxunread(Pax_t* pax, Paxarchive_t* ap, void* b, off_t n)
98
{
99
bunread(ap, b, n);
100
return 0;
101
}
102
103
static int
104
paxwrite(Pax_t* pax, Paxarchive_t* ap, const void* b, off_t n)
105
{
106
bwrite(ap, (void*)b, n);
107
return 0;
108
}
109
110
static int
111
paxnext(Pax_t* pax, Paxarchive_t* ap, size_t c, size_t n)
112
{
113
newio(ap, c, n);
114
return 0;
115
}
116
117
static int
118
paxcorrupt(Pax_t* pax, Paxarchive_t* ap, Paxfile_t* f, const char* msg)
119
{
120
(*pax->errorf)(NiL, pax, 2, "%s%s%s: %s archive corrupt at %I*u%s%s", ap->name, TXT(f, f->name), ap->format->name, sizeof(off_t), paxseek(pax, ap, 0, SEEK_CUR, 0), TXT(msg, msg));
121
return -1;
122
}
123
124
static int
125
paxchecksum(Pax_t* pax, Paxarchive_t* ap, Paxfile_t* f, unsigned long expected, unsigned long value)
126
{
127
int z;
128
129
if (expected != value)
130
{
131
z = ((expected | value) & 0xffff0000) ? 8 : 4;
132
(*pax->errorf)(NiL, pax, 2, "%s%s%s: %s archive checksum error -- expected %0*lx != %0*lx", ap->name, TXT(f, f->name), ap->format->name, z, expected, z, value);
133
return -1;
134
}
135
return 0;
136
}
137
138
static int
139
paxnospace(Pax_t* pax)
140
{
141
(*pax->errorf)(NiL, pax, 2, "out of space");
142
return -1;
143
}
144
145
/*
146
* archive part sfio discipline
147
*/
148
149
static ssize_t
150
part_read(Sfio_t* sp, void* buf, size_t n, Sfdisc_t* disc)
151
{
152
register Part_t* part = (Part_t*)disc;
153
ssize_t r;
154
155
if (part->n <= 0)
156
return part->n;
157
if (n > part->n)
158
n = part->n;
159
if ((r = paxread(part->pax, part->ap, buf, n, 0, 0)) > 0)
160
part->n -= r;
161
return r;
162
}
163
164
static ssize_t
165
part_write(Sfio_t* sp, const void* buf, size_t n, Sfdisc_t* disc)
166
{
167
register Part_t* part = (Part_t*)disc;
168
ssize_t r;
169
170
if ((r = paxwrite(part->pax, part->ap, buf, n)) > 0)
171
part->n += r;
172
return r;
173
}
174
175
static Sfio_t*
176
paxpart(Pax_t* pax, Paxarchive_t* ap, off_t n)
177
{
178
register Part_t* part;
179
180
static int fd = -1;
181
182
if (!(part = ap->partio))
183
{
184
if (!(part = newof(0, Part_t, 1, 0)) || !(part->sp = sfstropen()))
185
{
186
paxnospace(pax);
187
return 0;
188
}
189
part->sp->_flags &= ~(SF_READ|SF_WRITE|SF_STRING);
190
if (ap->flags & PAX_IN)
191
part->sp->_flags |= SF_READ;
192
else
193
part->sp->_flags |= SF_WRITE;
194
if (fd < 0)
195
fd = open("/dev/null", O_RDWR);
196
part->sp->_file = fd;
197
part->disc.readf = part_read;
198
part->disc.writef = part_write;
199
if (sfdisc(part->sp, &part->disc) != &part->disc)
200
{
201
sfclose(part->sp);
202
free(part);
203
return 0;
204
}
205
part->pax = pax;
206
part->ap = ap;
207
ap->partio = part;
208
}
209
part->n = n;
210
return part->sp;
211
}
212
213
/*
214
* initialize the external library callbacks
215
*/
216
217
void
218
paxinit(register Pax_t* pax, const char* id)
219
{
220
pax->id = id;
221
pax->errorf = errorf;
222
223
pax->dataf = paxdata;
224
pax->getf = paxget;
225
pax->partf = paxpart;
226
pax->putf = paxput;
227
pax->readf = paxread;
228
pax->seekf = paxseek;
229
pax->stashf = paxstash;
230
pax->syncf = paxsync;
231
pax->unreadf = paxunread;
232
pax->writef = paxwrite;
233
234
pax->corruptf = paxcorrupt;
235
pax->checksumf = paxchecksum;
236
pax->nospacef = paxnospace;
237
238
pax->nextf = paxnext;
239
}
240
241