1*9a747e4fSDavid du Colombier /* $Source: /u/mark/src/pax/RCS/buffer.c,v $
2*9a747e4fSDavid du Colombier *
3*9a747e4fSDavid du Colombier * $Revision: 1.2 $
4*9a747e4fSDavid du Colombier *
5*9a747e4fSDavid du Colombier * buffer.c - Buffer management functions
6*9a747e4fSDavid du Colombier *
7*9a747e4fSDavid du Colombier * DESCRIPTION
8*9a747e4fSDavid du Colombier *
9*9a747e4fSDavid du Colombier * These functions handle buffer manipulations for the archiving
10*9a747e4fSDavid du Colombier * formats. Functions are provided to get memory for buffers,
11*9a747e4fSDavid du Colombier * flush buffers, read and write buffers and de-allocate buffers.
12*9a747e4fSDavid du Colombier * Several housekeeping functions are provided as well to get some
13*9a747e4fSDavid du Colombier * information about how full buffers are, etc.
14*9a747e4fSDavid du Colombier *
15*9a747e4fSDavid du Colombier * AUTHOR
16*9a747e4fSDavid du Colombier *
17*9a747e4fSDavid du Colombier * Mark H. Colburn, NAPS International (mark@jhereg.mn.org)
18*9a747e4fSDavid du Colombier *
19*9a747e4fSDavid du Colombier * Sponsored by The USENIX Association for public distribution.
20*9a747e4fSDavid du Colombier *
21*9a747e4fSDavid du Colombier * Copyright (c) 1989 Mark H. Colburn.
22*9a747e4fSDavid du Colombier * All rights reserved.
23*9a747e4fSDavid du Colombier *
24*9a747e4fSDavid du Colombier * Redistribution and use in source and binary forms are permitted
25*9a747e4fSDavid du Colombier * provided that the above copyright notice is duplicated in all such
26*9a747e4fSDavid du Colombier * forms and that any documentation, advertising materials, and other
27*9a747e4fSDavid du Colombier * materials related to such distribution and use acknowledge that the
28*9a747e4fSDavid du Colombier * software was developed * by Mark H. Colburn and sponsored by The
29*9a747e4fSDavid du Colombier * USENIX Association.
30*9a747e4fSDavid du Colombier *
31*9a747e4fSDavid du Colombier * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
32*9a747e4fSDavid du Colombier * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
33*9a747e4fSDavid du Colombier * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
34*9a747e4fSDavid du Colombier *
35*9a747e4fSDavid du Colombier * $Log: buffer.c,v $
36*9a747e4fSDavid du Colombier * Revision 1.2 89/02/12 10:04:02 mark
37*9a747e4fSDavid du Colombier * 1.2 release fixes
38*9a747e4fSDavid du Colombier *
39*9a747e4fSDavid du Colombier * Revision 1.1 88/12/23 18:02:01 mark
40*9a747e4fSDavid du Colombier * Initial revision
41*9a747e4fSDavid du Colombier *
42*9a747e4fSDavid du Colombier */
43*9a747e4fSDavid du Colombier
44*9a747e4fSDavid du Colombier #ifndef lint
45*9a747e4fSDavid du Colombier static char *ident = "$Id: buffer.c,v 1.2 89/02/12 10:04:02 mark Exp $";
46*9a747e4fSDavid du Colombier static char *copyright = "Copyright (c) 1989 Mark H. Colburn.\nAll rights reserved.\n";
47*9a747e4fSDavid du Colombier #endif /* ! lint */
48*9a747e4fSDavid du Colombier
49*9a747e4fSDavid du Colombier
50*9a747e4fSDavid du Colombier /* Headers */
51*9a747e4fSDavid du Colombier
52*9a747e4fSDavid du Colombier #include "pax.h"
53*9a747e4fSDavid du Colombier
54*9a747e4fSDavid du Colombier
55*9a747e4fSDavid du Colombier /* Function Prototypes */
56*9a747e4fSDavid du Colombier
57*9a747e4fSDavid du Colombier #ifdef __STDC__
58*9a747e4fSDavid du Colombier
59*9a747e4fSDavid du Colombier static int ar_write(int, char *, uint);
60*9a747e4fSDavid du Colombier static void buf_pad(OFFSET);
61*9a747e4fSDavid du Colombier static int indata(int, OFFSET, char *);
62*9a747e4fSDavid du Colombier static void outflush(void);
63*9a747e4fSDavid du Colombier static void buf_use(uint);
64*9a747e4fSDavid du Colombier static int buf_in_avail(char **, uint *);
65*9a747e4fSDavid du Colombier static uint buf_out_avail(char **);
66*9a747e4fSDavid du Colombier
67*9a747e4fSDavid du Colombier #else /* !__STDC__ */
68*9a747e4fSDavid du Colombier
69*9a747e4fSDavid du Colombier static int ar_write();
70*9a747e4fSDavid du Colombier static void buf_pad();
71*9a747e4fSDavid du Colombier static int indata();
72*9a747e4fSDavid du Colombier static void outflush();
73*9a747e4fSDavid du Colombier static void buf_use();
74*9a747e4fSDavid du Colombier static int buf_in_avail();
75*9a747e4fSDavid du Colombier static uint buf_out_avail();
76*9a747e4fSDavid du Colombier
77*9a747e4fSDavid du Colombier #endif /* __STDC__ */
78*9a747e4fSDavid du Colombier
79*9a747e4fSDavid du Colombier
80*9a747e4fSDavid du Colombier /* inentry - install a single archive entry
81*9a747e4fSDavid du Colombier *
82*9a747e4fSDavid du Colombier * DESCRIPTION
83*9a747e4fSDavid du Colombier *
84*9a747e4fSDavid du Colombier * Inentry reads an archive entry from the archive file and writes it
85*9a747e4fSDavid du Colombier * out the the named file. If we are in PASS mode during archive
86*9a747e4fSDavid du Colombier * processing, the pass() function is called, otherwise we will
87*9a747e4fSDavid du Colombier * extract from the archive file.
88*9a747e4fSDavid du Colombier *
89*9a747e4fSDavid du Colombier * Inentry actaully calls indata to process the actual data to the
90*9a747e4fSDavid du Colombier * file.
91*9a747e4fSDavid du Colombier *
92*9a747e4fSDavid du Colombier * PARAMETERS
93*9a747e4fSDavid du Colombier *
94*9a747e4fSDavid du Colombier * char *name - name of the file to extract from the archive
95*9a747e4fSDavid du Colombier * Stat *asb - stat block of the file to be extracted from the
96*9a747e4fSDavid du Colombier * archive.
97*9a747e4fSDavid du Colombier *
98*9a747e4fSDavid du Colombier * RETURNS
99*9a747e4fSDavid du Colombier *
100*9a747e4fSDavid du Colombier * Returns zero if successful, -1 otherwise.
101*9a747e4fSDavid du Colombier */
102*9a747e4fSDavid du Colombier
103*9a747e4fSDavid du Colombier #ifdef __STDC__
104*9a747e4fSDavid du Colombier
inentry(char * name,Stat * asb)105*9a747e4fSDavid du Colombier int inentry(char *name, Stat *asb)
106*9a747e4fSDavid du Colombier
107*9a747e4fSDavid du Colombier #else
108*9a747e4fSDavid du Colombier
109*9a747e4fSDavid du Colombier int inentry(name, asb)
110*9a747e4fSDavid du Colombier char *name;
111*9a747e4fSDavid du Colombier Stat *asb;
112*9a747e4fSDavid du Colombier
113*9a747e4fSDavid du Colombier #endif
114*9a747e4fSDavid du Colombier {
115*9a747e4fSDavid du Colombier Link *linkp;
116*9a747e4fSDavid du Colombier int ifd;
117*9a747e4fSDavid du Colombier int ofd;
118*9a747e4fSDavid du Colombier time_t tstamp[2];
119*9a747e4fSDavid du Colombier
120*9a747e4fSDavid du Colombier if ((ofd = openout(name, asb, linkp = linkfrom(name, asb), 0)) > 0) {
121*9a747e4fSDavid du Colombier if (asb->sb_size || linkp == (Link *)NULL || linkp->l_size == 0) {
122*9a747e4fSDavid du Colombier close(indata(ofd, asb->sb_size, name));
123*9a747e4fSDavid du Colombier } else if ((ifd = open(linkp->l_path->p_name, O_RDONLY)) < 0) {
124*9a747e4fSDavid du Colombier warn(linkp->l_path->p_name, strerror());
125*9a747e4fSDavid du Colombier } else {
126*9a747e4fSDavid du Colombier passdata(linkp->l_path->p_name, ifd, name, ofd);
127*9a747e4fSDavid du Colombier close(ifd);
128*9a747e4fSDavid du Colombier close(ofd);
129*9a747e4fSDavid du Colombier }
130*9a747e4fSDavid du Colombier } else {
131*9a747e4fSDavid du Colombier return(buf_skip((OFFSET) asb->sb_size) >= 0);
132*9a747e4fSDavid du Colombier }
133*9a747e4fSDavid du Colombier tstamp[0] = (!f_pass && f_access_time) ? asb->sb_atime : time((time_t *) 0);
134*9a747e4fSDavid du Colombier tstamp[1] = f_mtime ? asb->sb_mtime : time((time_t *) 0);
135*9a747e4fSDavid du Colombier utime(name, tstamp);
136*9a747e4fSDavid du Colombier return (0);
137*9a747e4fSDavid du Colombier }
138*9a747e4fSDavid du Colombier
139*9a747e4fSDavid du Colombier
140*9a747e4fSDavid du Colombier /* outdata - write archive data
141*9a747e4fSDavid du Colombier *
142*9a747e4fSDavid du Colombier * DESCRIPTION
143*9a747e4fSDavid du Colombier *
144*9a747e4fSDavid du Colombier * Outdata transfers data from the named file to the archive buffer.
145*9a747e4fSDavid du Colombier * It knows about the file padding which is required by tar, but no
146*9a747e4fSDavid du Colombier * by cpio. Outdata continues after file read errors, padding with
147*9a747e4fSDavid du Colombier * null characters if neccessary. Closes the input file descriptor
148*9a747e4fSDavid du Colombier * when finished.
149*9a747e4fSDavid du Colombier *
150*9a747e4fSDavid du Colombier * PARAMETERS
151*9a747e4fSDavid du Colombier *
152*9a747e4fSDavid du Colombier * int fd - file descriptor of file to read data from
153*9a747e4fSDavid du Colombier * char *name - name of file
154*9a747e4fSDavid du Colombier * OFFSET size - size of the file
155*9a747e4fSDavid du Colombier *
156*9a747e4fSDavid du Colombier */
157*9a747e4fSDavid du Colombier
158*9a747e4fSDavid du Colombier #ifdef __STDC__
159*9a747e4fSDavid du Colombier
outdata(int fd,char * name,OFFSET size)160*9a747e4fSDavid du Colombier void outdata(int fd, char *name, OFFSET size)
161*9a747e4fSDavid du Colombier
162*9a747e4fSDavid du Colombier #else
163*9a747e4fSDavid du Colombier
164*9a747e4fSDavid du Colombier void outdata(fd, name, size)
165*9a747e4fSDavid du Colombier int fd;
166*9a747e4fSDavid du Colombier char *name;
167*9a747e4fSDavid du Colombier OFFSET size;
168*9a747e4fSDavid du Colombier
169*9a747e4fSDavid du Colombier #endif
170*9a747e4fSDavid du Colombier {
171*9a747e4fSDavid du Colombier uint chunk;
172*9a747e4fSDavid du Colombier int got;
173*9a747e4fSDavid du Colombier int oops;
174*9a747e4fSDavid du Colombier uint avail;
175*9a747e4fSDavid du Colombier int pad;
176*9a747e4fSDavid du Colombier char *buf;
177*9a747e4fSDavid du Colombier
178*9a747e4fSDavid du Colombier oops = got = 0;
179*9a747e4fSDavid du Colombier if (pad = (size % BLOCKSIZE)) {
180*9a747e4fSDavid du Colombier pad = (BLOCKSIZE - pad);
181*9a747e4fSDavid du Colombier }
182*9a747e4fSDavid du Colombier while (size) {
183*9a747e4fSDavid du Colombier avail = buf_out_avail(&buf);
184*9a747e4fSDavid du Colombier size -= (chunk = size < avail ? (uint) size : avail);
185*9a747e4fSDavid du Colombier if (oops == 0 && (got = read(fd, buf, (unsigned int) chunk)) < 0) {
186*9a747e4fSDavid du Colombier oops = -1;
187*9a747e4fSDavid du Colombier warn(name, strerror());
188*9a747e4fSDavid du Colombier got = 0;
189*9a747e4fSDavid du Colombier }
190*9a747e4fSDavid du Colombier if (got < chunk) {
191*9a747e4fSDavid du Colombier if (oops == 0) {
192*9a747e4fSDavid du Colombier oops = -1;
193*9a747e4fSDavid du Colombier }
194*9a747e4fSDavid du Colombier warn(name, "Early EOF");
195*9a747e4fSDavid du Colombier while (got < chunk) {
196*9a747e4fSDavid du Colombier buf[got++] = '\0';
197*9a747e4fSDavid du Colombier }
198*9a747e4fSDavid du Colombier }
199*9a747e4fSDavid du Colombier buf_use(chunk);
200*9a747e4fSDavid du Colombier }
201*9a747e4fSDavid du Colombier close(fd);
202*9a747e4fSDavid du Colombier if (ar_format == TAR) {
203*9a747e4fSDavid du Colombier buf_pad((OFFSET) pad);
204*9a747e4fSDavid du Colombier }
205*9a747e4fSDavid du Colombier }
206*9a747e4fSDavid du Colombier
207*9a747e4fSDavid du Colombier
208*9a747e4fSDavid du Colombier /* write_eot - write the end of archive record(s)
209*9a747e4fSDavid du Colombier *
210*9a747e4fSDavid du Colombier * DESCRIPTION
211*9a747e4fSDavid du Colombier *
212*9a747e4fSDavid du Colombier * Write out an End-Of-Tape record. We actually zero at least one
213*9a747e4fSDavid du Colombier * record, through the end of the block. Old tar writes garbage after
214*9a747e4fSDavid du Colombier * two zeroed records -- and PDtar used to.
215*9a747e4fSDavid du Colombier */
216*9a747e4fSDavid du Colombier
217*9a747e4fSDavid du Colombier #ifdef __STDC__
218*9a747e4fSDavid du Colombier
write_eot(void)219*9a747e4fSDavid du Colombier void write_eot(void)
220*9a747e4fSDavid du Colombier
221*9a747e4fSDavid du Colombier #else
222*9a747e4fSDavid du Colombier
223*9a747e4fSDavid du Colombier void write_eot()
224*9a747e4fSDavid du Colombier
225*9a747e4fSDavid du Colombier #endif
226*9a747e4fSDavid du Colombier {
227*9a747e4fSDavid du Colombier OFFSET pad;
228*9a747e4fSDavid du Colombier char header[M_STRLEN + H_STRLEN + 1];
229*9a747e4fSDavid du Colombier
230*9a747e4fSDavid du Colombier if (ar_format == TAR) {
231*9a747e4fSDavid du Colombier /* write out two zero blocks for trailer */
232*9a747e4fSDavid du Colombier pad = 2 * BLOCKSIZE;
233*9a747e4fSDavid du Colombier } else {
234*9a747e4fSDavid du Colombier if (pad = (total + M_STRLEN + H_STRLEN + TRAILZ) % BLOCKSIZE) {
235*9a747e4fSDavid du Colombier pad = BLOCKSIZE - pad;
236*9a747e4fSDavid du Colombier }
237*9a747e4fSDavid du Colombier strcpy(header, M_ASCII);
238*9a747e4fSDavid du Colombier sprintf(header + M_STRLEN, H_PRINT, 0, 0,
239*9a747e4fSDavid du Colombier 0, 0, 0, 1, 0, (time_t) 0, TRAILZ, pad);
240*9a747e4fSDavid du Colombier outwrite(header, M_STRLEN + H_STRLEN);
241*9a747e4fSDavid du Colombier outwrite(TRAILER, TRAILZ);
242*9a747e4fSDavid du Colombier }
243*9a747e4fSDavid du Colombier buf_pad((OFFSET) pad);
244*9a747e4fSDavid du Colombier outflush();
245*9a747e4fSDavid du Colombier }
246*9a747e4fSDavid du Colombier
247*9a747e4fSDavid du Colombier
248*9a747e4fSDavid du Colombier /* outwrite - write archive data
249*9a747e4fSDavid du Colombier *
250*9a747e4fSDavid du Colombier * DESCRIPTION
251*9a747e4fSDavid du Colombier *
252*9a747e4fSDavid du Colombier * Writes out data in the archive buffer to the archive file. The
253*9a747e4fSDavid du Colombier * buffer index and the total byte count are incremented by the number
254*9a747e4fSDavid du Colombier * of data bytes written.
255*9a747e4fSDavid du Colombier *
256*9a747e4fSDavid du Colombier * PARAMETERS
257*9a747e4fSDavid du Colombier *
258*9a747e4fSDavid du Colombier * char *idx - pointer to data to write
259*9a747e4fSDavid du Colombier * uint len - length of the data to write
260*9a747e4fSDavid du Colombier */
261*9a747e4fSDavid du Colombier
262*9a747e4fSDavid du Colombier #ifdef __STDC__
263*9a747e4fSDavid du Colombier
outwrite(char * idx,uint len)264*9a747e4fSDavid du Colombier void outwrite(char *idx, uint len)
265*9a747e4fSDavid du Colombier
266*9a747e4fSDavid du Colombier #else
267*9a747e4fSDavid du Colombier
268*9a747e4fSDavid du Colombier void outwrite(idx, len)
269*9a747e4fSDavid du Colombier char *idx; /* pointer to data to write */
270*9a747e4fSDavid du Colombier uint len; /* length of data to write */
271*9a747e4fSDavid du Colombier
272*9a747e4fSDavid du Colombier #endif
273*9a747e4fSDavid du Colombier {
274*9a747e4fSDavid du Colombier uint have;
275*9a747e4fSDavid du Colombier uint want;
276*9a747e4fSDavid du Colombier char *endx;
277*9a747e4fSDavid du Colombier
278*9a747e4fSDavid du Colombier endx = idx + len;
279*9a747e4fSDavid du Colombier while (want = endx - idx) {
280*9a747e4fSDavid du Colombier if (bufend - bufidx < 0) {
281*9a747e4fSDavid du Colombier fatal("Buffer overlow in out_write\n");
282*9a747e4fSDavid du Colombier }
283*9a747e4fSDavid du Colombier if ((have = bufend - bufidx) == 0) {
284*9a747e4fSDavid du Colombier outflush();
285*9a747e4fSDavid du Colombier }
286*9a747e4fSDavid du Colombier if (have > want) {
287*9a747e4fSDavid du Colombier have = want;
288*9a747e4fSDavid du Colombier }
289*9a747e4fSDavid du Colombier memcpy(bufidx, idx, (int) have);
290*9a747e4fSDavid du Colombier bufidx += have;
291*9a747e4fSDavid du Colombier idx += have;
292*9a747e4fSDavid du Colombier total += have;
293*9a747e4fSDavid du Colombier }
294*9a747e4fSDavid du Colombier }
295*9a747e4fSDavid du Colombier
296*9a747e4fSDavid du Colombier
297*9a747e4fSDavid du Colombier /* passdata - copy data to one file
298*9a747e4fSDavid du Colombier *
299*9a747e4fSDavid du Colombier * DESCRIPTION
300*9a747e4fSDavid du Colombier *
301*9a747e4fSDavid du Colombier * Copies a file from one place to another. Doesn't believe in input
302*9a747e4fSDavid du Colombier * file descriptor zero (see description of kludge in openin() comments).
303*9a747e4fSDavid du Colombier * Closes the provided output file descriptor.
304*9a747e4fSDavid du Colombier *
305*9a747e4fSDavid du Colombier * PARAMETERS
306*9a747e4fSDavid du Colombier *
307*9a747e4fSDavid du Colombier * char *from - input file name (old file)
308*9a747e4fSDavid du Colombier * int ifd - input file descriptor
309*9a747e4fSDavid du Colombier * char *to - output file name (new file)
310*9a747e4fSDavid du Colombier * int ofd - output file descriptor
311*9a747e4fSDavid du Colombier */
312*9a747e4fSDavid du Colombier
313*9a747e4fSDavid du Colombier #ifdef __STDC__
314*9a747e4fSDavid du Colombier
passdata(char * from,int ifd,char * to,int ofd)315*9a747e4fSDavid du Colombier void passdata(char *from, int ifd, char *to, int ofd)
316*9a747e4fSDavid du Colombier
317*9a747e4fSDavid du Colombier #else
318*9a747e4fSDavid du Colombier
319*9a747e4fSDavid du Colombier void passdata(from, ifd, to, ofd)
320*9a747e4fSDavid du Colombier char *from;
321*9a747e4fSDavid du Colombier int ifd;
322*9a747e4fSDavid du Colombier char *to;
323*9a747e4fSDavid du Colombier int ofd;
324*9a747e4fSDavid du Colombier
325*9a747e4fSDavid du Colombier #endif
326*9a747e4fSDavid du Colombier {
327*9a747e4fSDavid du Colombier int got;
328*9a747e4fSDavid du Colombier int sparse;
329*9a747e4fSDavid du Colombier char block[BUFSIZ];
330*9a747e4fSDavid du Colombier
331*9a747e4fSDavid du Colombier if (ifd) {
332*9a747e4fSDavid du Colombier lseek(ifd, (OFFSET) 0, 0);
333*9a747e4fSDavid du Colombier sparse = 0;
334*9a747e4fSDavid du Colombier while ((got = read(ifd, block, sizeof(block))) > 0
335*9a747e4fSDavid du Colombier && (sparse = ar_write(ofd, block, (uint) got)) >= 0) {
336*9a747e4fSDavid du Colombier total += got;
337*9a747e4fSDavid du Colombier }
338*9a747e4fSDavid du Colombier if (got) {
339*9a747e4fSDavid du Colombier warn(got < 0 ? from : to, strerror());
340*9a747e4fSDavid du Colombier } else if (sparse > 0
341*9a747e4fSDavid du Colombier && (lseek(ofd, (OFFSET)(-sparse), 1) < 0
342*9a747e4fSDavid du Colombier || write(ofd, block, (uint) sparse) != sparse)) {
343*9a747e4fSDavid du Colombier warn(to, strerror());
344*9a747e4fSDavid du Colombier }
345*9a747e4fSDavid du Colombier }
346*9a747e4fSDavid du Colombier close(ofd);
347*9a747e4fSDavid du Colombier }
348*9a747e4fSDavid du Colombier
349*9a747e4fSDavid du Colombier
350*9a747e4fSDavid du Colombier /* buf_allocate - get space for the I/O buffer
351*9a747e4fSDavid du Colombier *
352*9a747e4fSDavid du Colombier * DESCRIPTION
353*9a747e4fSDavid du Colombier *
354*9a747e4fSDavid du Colombier * buf_allocate allocates an I/O buffer using malloc. The resulting
355*9a747e4fSDavid du Colombier * buffer is used for all data buffering throughout the program.
356*9a747e4fSDavid du Colombier * Buf_allocate must be called prior to any use of the buffer or any
357*9a747e4fSDavid du Colombier * of the buffering calls.
358*9a747e4fSDavid du Colombier *
359*9a747e4fSDavid du Colombier * PARAMETERS
360*9a747e4fSDavid du Colombier *
361*9a747e4fSDavid du Colombier * int size - size of the I/O buffer to request
362*9a747e4fSDavid du Colombier *
363*9a747e4fSDavid du Colombier * ERRORS
364*9a747e4fSDavid du Colombier *
365*9a747e4fSDavid du Colombier * If an invalid size is given for a buffer or if a buffer of the
366*9a747e4fSDavid du Colombier * required size cannot be allocated, then the function prints out an
367*9a747e4fSDavid du Colombier * error message and returns a non-zero exit status to the calling
368*9a747e4fSDavid du Colombier * process, terminating the program.
369*9a747e4fSDavid du Colombier *
370*9a747e4fSDavid du Colombier */
371*9a747e4fSDavid du Colombier
372*9a747e4fSDavid du Colombier #ifdef __STDC__
373*9a747e4fSDavid du Colombier
buf_allocate(OFFSET size)374*9a747e4fSDavid du Colombier void buf_allocate(OFFSET size)
375*9a747e4fSDavid du Colombier
376*9a747e4fSDavid du Colombier #else
377*9a747e4fSDavid du Colombier
378*9a747e4fSDavid du Colombier void buf_allocate(size)
379*9a747e4fSDavid du Colombier OFFSET size;
380*9a747e4fSDavid du Colombier
381*9a747e4fSDavid du Colombier #endif
382*9a747e4fSDavid du Colombier {
383*9a747e4fSDavid du Colombier if (size <= 0) {
384*9a747e4fSDavid du Colombier fatal("invalid value for blocksize");
385*9a747e4fSDavid du Colombier }
386*9a747e4fSDavid du Colombier if ((bufstart = malloc((unsigned) size)) == (char *)NULL) {
387*9a747e4fSDavid du Colombier fatal("Cannot allocate I/O buffer");
388*9a747e4fSDavid du Colombier }
389*9a747e4fSDavid du Colombier bufend = bufidx = bufstart;
390*9a747e4fSDavid du Colombier bufend += size;
391*9a747e4fSDavid du Colombier }
392*9a747e4fSDavid du Colombier
393*9a747e4fSDavid du Colombier
394*9a747e4fSDavid du Colombier /* buf_skip - skip input archive data
395*9a747e4fSDavid du Colombier *
396*9a747e4fSDavid du Colombier * DESCRIPTION
397*9a747e4fSDavid du Colombier *
398*9a747e4fSDavid du Colombier * Buf_skip skips past archive data. It is used when the length of
399*9a747e4fSDavid du Colombier * the archive data is known, and we do not wish to process the data.
400*9a747e4fSDavid du Colombier *
401*9a747e4fSDavid du Colombier * PARAMETERS
402*9a747e4fSDavid du Colombier *
403*9a747e4fSDavid du Colombier * OFFSET len - number of bytes to skip
404*9a747e4fSDavid du Colombier *
405*9a747e4fSDavid du Colombier * RETURNS
406*9a747e4fSDavid du Colombier *
407*9a747e4fSDavid du Colombier * Returns zero under normal circumstances, -1 if unreadable data is
408*9a747e4fSDavid du Colombier * encountered.
409*9a747e4fSDavid du Colombier */
410*9a747e4fSDavid du Colombier
411*9a747e4fSDavid du Colombier #ifdef __STDC__
412*9a747e4fSDavid du Colombier
buf_skip(OFFSET len)413*9a747e4fSDavid du Colombier int buf_skip(OFFSET len)
414*9a747e4fSDavid du Colombier
415*9a747e4fSDavid du Colombier #else
416*9a747e4fSDavid du Colombier
417*9a747e4fSDavid du Colombier int buf_skip(len)
418*9a747e4fSDavid du Colombier OFFSET len;
419*9a747e4fSDavid du Colombier
420*9a747e4fSDavid du Colombier #endif
421*9a747e4fSDavid du Colombier {
422*9a747e4fSDavid du Colombier uint chunk;
423*9a747e4fSDavid du Colombier int corrupt = 0;
424*9a747e4fSDavid du Colombier
425*9a747e4fSDavid du Colombier while (len) {
426*9a747e4fSDavid du Colombier if (bufend - bufidx < 0) {
427*9a747e4fSDavid du Colombier fatal("Buffer overlow in buf_skip\n");
428*9a747e4fSDavid du Colombier }
429*9a747e4fSDavid du Colombier while ((chunk = bufend - bufidx) == 0) {
430*9a747e4fSDavid du Colombier corrupt |= ar_read();
431*9a747e4fSDavid du Colombier }
432*9a747e4fSDavid du Colombier if (chunk > len) {
433*9a747e4fSDavid du Colombier chunk = len;
434*9a747e4fSDavid du Colombier }
435*9a747e4fSDavid du Colombier bufidx += chunk;
436*9a747e4fSDavid du Colombier len -= chunk;
437*9a747e4fSDavid du Colombier total += chunk;
438*9a747e4fSDavid du Colombier }
439*9a747e4fSDavid du Colombier return (corrupt);
440*9a747e4fSDavid du Colombier }
441*9a747e4fSDavid du Colombier
442*9a747e4fSDavid du Colombier
443*9a747e4fSDavid du Colombier /* buf_read - read a given number of characters from the input archive
444*9a747e4fSDavid du Colombier *
445*9a747e4fSDavid du Colombier * DESCRIPTION
446*9a747e4fSDavid du Colombier *
447*9a747e4fSDavid du Colombier * Reads len number of characters from the input archive and
448*9a747e4fSDavid du Colombier * stores them in the buffer pointed at by dst.
449*9a747e4fSDavid du Colombier *
450*9a747e4fSDavid du Colombier * PARAMETERS
451*9a747e4fSDavid du Colombier *
452*9a747e4fSDavid du Colombier * char *dst - pointer to buffer to store data into
453*9a747e4fSDavid du Colombier * uint len - length of data to read
454*9a747e4fSDavid du Colombier *
455*9a747e4fSDavid du Colombier * RETURNS
456*9a747e4fSDavid du Colombier *
457*9a747e4fSDavid du Colombier * Returns zero with valid data, -1 if unreadable portions were
458*9a747e4fSDavid du Colombier * replaced by null characters.
459*9a747e4fSDavid du Colombier */
460*9a747e4fSDavid du Colombier
461*9a747e4fSDavid du Colombier #ifdef __STDC__
462*9a747e4fSDavid du Colombier
buf_read(char * dst,uint len)463*9a747e4fSDavid du Colombier int buf_read(char *dst, uint len)
464*9a747e4fSDavid du Colombier
465*9a747e4fSDavid du Colombier #else
466*9a747e4fSDavid du Colombier
467*9a747e4fSDavid du Colombier int buf_read(dst, len)
468*9a747e4fSDavid du Colombier char *dst;
469*9a747e4fSDavid du Colombier uint len;
470*9a747e4fSDavid du Colombier
471*9a747e4fSDavid du Colombier #endif
472*9a747e4fSDavid du Colombier {
473*9a747e4fSDavid du Colombier int have;
474*9a747e4fSDavid du Colombier int want;
475*9a747e4fSDavid du Colombier int corrupt = 0;
476*9a747e4fSDavid du Colombier char *endx = dst + len;
477*9a747e4fSDavid du Colombier
478*9a747e4fSDavid du Colombier while (want = endx - dst) {
479*9a747e4fSDavid du Colombier if (bufend - bufidx < 0) {
480*9a747e4fSDavid du Colombier fatal("Buffer overlow in buf_read\n");
481*9a747e4fSDavid du Colombier }
482*9a747e4fSDavid du Colombier while ((have = bufend - bufidx) == 0) {
483*9a747e4fSDavid du Colombier have = 0;
484*9a747e4fSDavid du Colombier corrupt |= ar_read();
485*9a747e4fSDavid du Colombier }
486*9a747e4fSDavid du Colombier if (have > want) {
487*9a747e4fSDavid du Colombier have = want;
488*9a747e4fSDavid du Colombier }
489*9a747e4fSDavid du Colombier memcpy(dst, bufidx, have);
490*9a747e4fSDavid du Colombier bufidx += have;
491*9a747e4fSDavid du Colombier dst += have;
492*9a747e4fSDavid du Colombier total += have;
493*9a747e4fSDavid du Colombier }
494*9a747e4fSDavid du Colombier return (corrupt);
495*9a747e4fSDavid du Colombier }
496*9a747e4fSDavid du Colombier
497*9a747e4fSDavid du Colombier
498*9a747e4fSDavid du Colombier /* indata - install data from an archive
499*9a747e4fSDavid du Colombier *
500*9a747e4fSDavid du Colombier * DESCRIPTION
501*9a747e4fSDavid du Colombier *
502*9a747e4fSDavid du Colombier * Indata writes size bytes of data from the archive buffer to the output
503*9a747e4fSDavid du Colombier * file specified by fd. The filename which is being written, pointed
504*9a747e4fSDavid du Colombier * to by name is provided only for diagnostics.
505*9a747e4fSDavid du Colombier *
506*9a747e4fSDavid du Colombier * PARAMETERS
507*9a747e4fSDavid du Colombier *
508*9a747e4fSDavid du Colombier * int fd - output file descriptor
509*9a747e4fSDavid du Colombier * OFFSET size - number of bytes to write to output file
510*9a747e4fSDavid du Colombier * char *name - name of file which corresponds to fd
511*9a747e4fSDavid du Colombier *
512*9a747e4fSDavid du Colombier * RETURNS
513*9a747e4fSDavid du Colombier *
514*9a747e4fSDavid du Colombier * Returns given file descriptor.
515*9a747e4fSDavid du Colombier */
516*9a747e4fSDavid du Colombier
517*9a747e4fSDavid du Colombier #ifdef __STDC__
518*9a747e4fSDavid du Colombier
indata(int fd,OFFSET size,char * name)519*9a747e4fSDavid du Colombier static int indata(int fd, OFFSET size, char *name)
520*9a747e4fSDavid du Colombier
521*9a747e4fSDavid du Colombier #else
522*9a747e4fSDavid du Colombier
523*9a747e4fSDavid du Colombier static int indata(fd, size, name)
524*9a747e4fSDavid du Colombier int fd;
525*9a747e4fSDavid du Colombier OFFSET size;
526*9a747e4fSDavid du Colombier char *name;
527*9a747e4fSDavid du Colombier
528*9a747e4fSDavid du Colombier #endif
529*9a747e4fSDavid du Colombier {
530*9a747e4fSDavid du Colombier uint chunk;
531*9a747e4fSDavid du Colombier char *oops;
532*9a747e4fSDavid du Colombier int sparse;
533*9a747e4fSDavid du Colombier int corrupt;
534*9a747e4fSDavid du Colombier char *buf;
535*9a747e4fSDavid du Colombier uint avail;
536*9a747e4fSDavid du Colombier
537*9a747e4fSDavid du Colombier corrupt = sparse = 0;
538*9a747e4fSDavid du Colombier oops = (char *)NULL;
539*9a747e4fSDavid du Colombier while (size) {
540*9a747e4fSDavid du Colombier corrupt |= buf_in_avail(&buf, &avail);
541*9a747e4fSDavid du Colombier size -= (chunk = size < avail ? (uint) size : avail);
542*9a747e4fSDavid du Colombier if (oops == (char *)NULL && (sparse = ar_write(fd, buf, chunk)) < 0) {
543*9a747e4fSDavid du Colombier oops = strerror();
544*9a747e4fSDavid du Colombier }
545*9a747e4fSDavid du Colombier buf_use(chunk);
546*9a747e4fSDavid du Colombier }
547*9a747e4fSDavid du Colombier if (corrupt) {
548*9a747e4fSDavid du Colombier warn(name, "Corrupt archive data");
549*9a747e4fSDavid du Colombier }
550*9a747e4fSDavid du Colombier if (oops) {
551*9a747e4fSDavid du Colombier warn(name, oops);
552*9a747e4fSDavid du Colombier } else if (sparse > 0 && (lseek(fd, (OFFSET) - 1, 1) < 0
553*9a747e4fSDavid du Colombier || write(fd, "", 1) != 1)) {
554*9a747e4fSDavid du Colombier warn(name, strerror());
555*9a747e4fSDavid du Colombier }
556*9a747e4fSDavid du Colombier return (fd);
557*9a747e4fSDavid du Colombier }
558*9a747e4fSDavid du Colombier
559*9a747e4fSDavid du Colombier
560*9a747e4fSDavid du Colombier /* outflush - flush the output buffer
561*9a747e4fSDavid du Colombier *
562*9a747e4fSDavid du Colombier * DESCRIPTION
563*9a747e4fSDavid du Colombier *
564*9a747e4fSDavid du Colombier * The output buffer is written, if there is anything in it, to the
565*9a747e4fSDavid du Colombier * archive file.
566*9a747e4fSDavid du Colombier */
567*9a747e4fSDavid du Colombier
568*9a747e4fSDavid du Colombier #ifdef __STDC__
569*9a747e4fSDavid du Colombier
outflush(void)570*9a747e4fSDavid du Colombier static void outflush(void)
571*9a747e4fSDavid du Colombier
572*9a747e4fSDavid du Colombier #else
573*9a747e4fSDavid du Colombier
574*9a747e4fSDavid du Colombier static void outflush()
575*9a747e4fSDavid du Colombier
576*9a747e4fSDavid du Colombier #endif
577*9a747e4fSDavid du Colombier {
578*9a747e4fSDavid du Colombier char *buf;
579*9a747e4fSDavid du Colombier int got;
580*9a747e4fSDavid du Colombier uint len;
581*9a747e4fSDavid du Colombier
582*9a747e4fSDavid du Colombier /* if (bufidx - buf > 0) */
583*9a747e4fSDavid du Colombier for (buf = bufstart; len = bufidx - buf;) {
584*9a747e4fSDavid du Colombier if ((got = write(archivefd, buf, MIN(len, blocksize))) > 0) {
585*9a747e4fSDavid du Colombier buf += got;
586*9a747e4fSDavid du Colombier } else if (got < 0) {
587*9a747e4fSDavid du Colombier next(AR_WRITE);
588*9a747e4fSDavid du Colombier }
589*9a747e4fSDavid du Colombier }
590*9a747e4fSDavid du Colombier bufend = (bufidx = bufstart) + blocksize;
591*9a747e4fSDavid du Colombier }
592*9a747e4fSDavid du Colombier
593*9a747e4fSDavid du Colombier
594*9a747e4fSDavid du Colombier /* ar_read - fill the archive buffer
595*9a747e4fSDavid du Colombier *
596*9a747e4fSDavid du Colombier * DESCRIPTION
597*9a747e4fSDavid du Colombier *
598*9a747e4fSDavid du Colombier * Remembers mid-buffer read failures and reports them the next time
599*9a747e4fSDavid du Colombier * through. Replaces unreadable data with null characters. Resets
600*9a747e4fSDavid du Colombier * the buffer pointers as appropriate.
601*9a747e4fSDavid du Colombier *
602*9a747e4fSDavid du Colombier * RETURNS
603*9a747e4fSDavid du Colombier *
604*9a747e4fSDavid du Colombier * Returns zero with valid data, -1 otherwise.
605*9a747e4fSDavid du Colombier */
606*9a747e4fSDavid du Colombier
607*9a747e4fSDavid du Colombier #ifdef __STDC__
608*9a747e4fSDavid du Colombier
ar_read(void)609*9a747e4fSDavid du Colombier int ar_read(void)
610*9a747e4fSDavid du Colombier
611*9a747e4fSDavid du Colombier #else
612*9a747e4fSDavid du Colombier
613*9a747e4fSDavid du Colombier int ar_read()
614*9a747e4fSDavid du Colombier
615*9a747e4fSDavid du Colombier #endif
616*9a747e4fSDavid du Colombier {
617*9a747e4fSDavid du Colombier int got;
618*9a747e4fSDavid du Colombier static int failed;
619*9a747e4fSDavid du Colombier
620*9a747e4fSDavid du Colombier bufend = bufidx = bufstart;
621*9a747e4fSDavid du Colombier if (!failed) {
622*9a747e4fSDavid du Colombier if (areof) {
623*9a747e4fSDavid du Colombier if (total == 0) {
624*9a747e4fSDavid du Colombier fatal("No input");
625*9a747e4fSDavid du Colombier } else {
626*9a747e4fSDavid du Colombier next(AR_READ);
627*9a747e4fSDavid du Colombier }
628*9a747e4fSDavid du Colombier }
629*9a747e4fSDavid du Colombier while (!failed && !areof && bufstart + blocksize - bufend >= blocksize) {
630*9a747e4fSDavid du Colombier if ((got = read(archivefd, bufend, (unsigned int) blocksize)) > 0) {
631*9a747e4fSDavid du Colombier bufend += got;
632*9a747e4fSDavid du Colombier } else if (got < 0) {
633*9a747e4fSDavid du Colombier failed = -1;
634*9a747e4fSDavid du Colombier warnarch(strerror(), (OFFSET) 0 - (bufend - bufidx));
635*9a747e4fSDavid du Colombier } else {
636*9a747e4fSDavid du Colombier ++areof;
637*9a747e4fSDavid du Colombier }
638*9a747e4fSDavid du Colombier }
639*9a747e4fSDavid du Colombier }
640*9a747e4fSDavid du Colombier if (failed && bufend == bufstart) {
641*9a747e4fSDavid du Colombier failed = 0;
642*9a747e4fSDavid du Colombier for (got = 0; got < blocksize; ++got) {
643*9a747e4fSDavid du Colombier *bufend++ = '\0';
644*9a747e4fSDavid du Colombier }
645*9a747e4fSDavid du Colombier return (-1);
646*9a747e4fSDavid du Colombier }
647*9a747e4fSDavid du Colombier return (0);
648*9a747e4fSDavid du Colombier }
649*9a747e4fSDavid du Colombier
650*9a747e4fSDavid du Colombier
651*9a747e4fSDavid du Colombier /* ar_write - write a filesystem block
652*9a747e4fSDavid du Colombier *
653*9a747e4fSDavid du Colombier * DESCRIPTION
654*9a747e4fSDavid du Colombier *
655*9a747e4fSDavid du Colombier * Writes len bytes of data data from the specified buffer to the
656*9a747e4fSDavid du Colombier * specified file. Seeks past sparse blocks.
657*9a747e4fSDavid du Colombier *
658*9a747e4fSDavid du Colombier * PARAMETERS
659*9a747e4fSDavid du Colombier *
660*9a747e4fSDavid du Colombier * int fd - file to write to
661*9a747e4fSDavid du Colombier * char *buf - buffer to get data from
662*9a747e4fSDavid du Colombier * uint len - number of bytes to transfer
663*9a747e4fSDavid du Colombier *
664*9a747e4fSDavid du Colombier * RETURNS
665*9a747e4fSDavid du Colombier *
666*9a747e4fSDavid du Colombier * Returns 0 if the block was written, the given length for a sparse
667*9a747e4fSDavid du Colombier * block or -1 if unsuccessful.
668*9a747e4fSDavid du Colombier */
669*9a747e4fSDavid du Colombier
670*9a747e4fSDavid du Colombier #ifdef __STDC__
671*9a747e4fSDavid du Colombier
ar_write(int fd,char * buf,uint len)672*9a747e4fSDavid du Colombier static int ar_write(int fd, char *buf, uint len)
673*9a747e4fSDavid du Colombier
674*9a747e4fSDavid du Colombier #else
675*9a747e4fSDavid du Colombier
676*9a747e4fSDavid du Colombier static int ar_write(fd, buf, len)
677*9a747e4fSDavid du Colombier int fd;
678*9a747e4fSDavid du Colombier char *buf;
679*9a747e4fSDavid du Colombier uint len;
680*9a747e4fSDavid du Colombier
681*9a747e4fSDavid du Colombier #endif
682*9a747e4fSDavid du Colombier {
683*9a747e4fSDavid du Colombier char *bidx;
684*9a747e4fSDavid du Colombier char *bend;
685*9a747e4fSDavid du Colombier
686*9a747e4fSDavid du Colombier bend = (bidx = buf) + len;
687*9a747e4fSDavid du Colombier while (bidx < bend) {
688*9a747e4fSDavid du Colombier if (*bidx++) {
689*9a747e4fSDavid du Colombier return (write(fd, buf, len) == len ? 0 : -1);
690*9a747e4fSDavid du Colombier }
691*9a747e4fSDavid du Colombier }
692*9a747e4fSDavid du Colombier return (lseek(fd, (OFFSET) len, 1) < 0 ? -1 : len);
693*9a747e4fSDavid du Colombier }
694*9a747e4fSDavid du Colombier
695*9a747e4fSDavid du Colombier
696*9a747e4fSDavid du Colombier /* buf_pad - pad the archive buffer
697*9a747e4fSDavid du Colombier *
698*9a747e4fSDavid du Colombier * DESCRIPTION
699*9a747e4fSDavid du Colombier *
700*9a747e4fSDavid du Colombier * Buf_pad writes len zero bytes to the archive buffer in order to
701*9a747e4fSDavid du Colombier * pad it.
702*9a747e4fSDavid du Colombier *
703*9a747e4fSDavid du Colombier * PARAMETERS
704*9a747e4fSDavid du Colombier *
705*9a747e4fSDavid du Colombier * OFFSET pad - number of zero bytes to pad
706*9a747e4fSDavid du Colombier *
707*9a747e4fSDavid du Colombier */
708*9a747e4fSDavid du Colombier
709*9a747e4fSDavid du Colombier #ifdef __STDC__
710*9a747e4fSDavid du Colombier
buf_pad(OFFSET pad)711*9a747e4fSDavid du Colombier static void buf_pad(OFFSET pad)
712*9a747e4fSDavid du Colombier
713*9a747e4fSDavid du Colombier #else
714*9a747e4fSDavid du Colombier
715*9a747e4fSDavid du Colombier static void buf_pad(pad)
716*9a747e4fSDavid du Colombier OFFSET pad;
717*9a747e4fSDavid du Colombier
718*9a747e4fSDavid du Colombier #endif
719*9a747e4fSDavid du Colombier {
720*9a747e4fSDavid du Colombier int idx;
721*9a747e4fSDavid du Colombier int have;
722*9a747e4fSDavid du Colombier
723*9a747e4fSDavid du Colombier while (pad) {
724*9a747e4fSDavid du Colombier if ((have = bufend - bufidx) > pad) {
725*9a747e4fSDavid du Colombier have = pad;
726*9a747e4fSDavid du Colombier }
727*9a747e4fSDavid du Colombier for (idx = 0; idx < have; ++idx) {
728*9a747e4fSDavid du Colombier *bufidx++ = '\0';
729*9a747e4fSDavid du Colombier }
730*9a747e4fSDavid du Colombier total += have;
731*9a747e4fSDavid du Colombier pad -= have;
732*9a747e4fSDavid du Colombier if (bufend - bufidx == 0) {
733*9a747e4fSDavid du Colombier outflush();
734*9a747e4fSDavid du Colombier }
735*9a747e4fSDavid du Colombier }
736*9a747e4fSDavid du Colombier }
737*9a747e4fSDavid du Colombier
738*9a747e4fSDavid du Colombier
739*9a747e4fSDavid du Colombier /* buf_use - allocate buffer space
740*9a747e4fSDavid du Colombier *
741*9a747e4fSDavid du Colombier * DESCRIPTION
742*9a747e4fSDavid du Colombier *
743*9a747e4fSDavid du Colombier * Buf_use marks space in the buffer as being used; advancing both the
744*9a747e4fSDavid du Colombier * buffer index (bufidx) and the total byte count (total).
745*9a747e4fSDavid du Colombier *
746*9a747e4fSDavid du Colombier * PARAMETERS
747*9a747e4fSDavid du Colombier *
748*9a747e4fSDavid du Colombier * uint len - Amount of space to allocate in the buffer
749*9a747e4fSDavid du Colombier */
750*9a747e4fSDavid du Colombier
751*9a747e4fSDavid du Colombier #ifdef __STDC__
752*9a747e4fSDavid du Colombier
buf_use(uint len)753*9a747e4fSDavid du Colombier static void buf_use(uint len)
754*9a747e4fSDavid du Colombier
755*9a747e4fSDavid du Colombier #else
756*9a747e4fSDavid du Colombier
757*9a747e4fSDavid du Colombier static void buf_use(len)
758*9a747e4fSDavid du Colombier uint len;
759*9a747e4fSDavid du Colombier
760*9a747e4fSDavid du Colombier #endif
761*9a747e4fSDavid du Colombier {
762*9a747e4fSDavid du Colombier bufidx += len;
763*9a747e4fSDavid du Colombier total += len;
764*9a747e4fSDavid du Colombier }
765*9a747e4fSDavid du Colombier
766*9a747e4fSDavid du Colombier
767*9a747e4fSDavid du Colombier /* buf_in_avail - index available input data within the buffer
768*9a747e4fSDavid du Colombier *
769*9a747e4fSDavid du Colombier * DESCRIPTION
770*9a747e4fSDavid du Colombier *
771*9a747e4fSDavid du Colombier * Buf_in_avail fills the archive buffer, and points the bufp
772*9a747e4fSDavid du Colombier * parameter at the start of the data. The lenp parameter is
773*9a747e4fSDavid du Colombier * modified to contain the number of bytes which were read.
774*9a747e4fSDavid du Colombier *
775*9a747e4fSDavid du Colombier * PARAMETERS
776*9a747e4fSDavid du Colombier *
777*9a747e4fSDavid du Colombier * char **bufp - pointer to the buffer to read data into
778*9a747e4fSDavid du Colombier * uint *lenp - pointer to the number of bytes which were read
779*9a747e4fSDavid du Colombier * (returned to the caller)
780*9a747e4fSDavid du Colombier *
781*9a747e4fSDavid du Colombier * RETURNS
782*9a747e4fSDavid du Colombier *
783*9a747e4fSDavid du Colombier * Stores a pointer to the data and its length in given locations.
784*9a747e4fSDavid du Colombier * Returns zero with valid data, -1 if unreadable portions were
785*9a747e4fSDavid du Colombier * replaced with nulls.
786*9a747e4fSDavid du Colombier *
787*9a747e4fSDavid du Colombier * ERRORS
788*9a747e4fSDavid du Colombier *
789*9a747e4fSDavid du Colombier * If an error occurs in ar_read, the error code is returned to the
790*9a747e4fSDavid du Colombier * calling function.
791*9a747e4fSDavid du Colombier *
792*9a747e4fSDavid du Colombier */
793*9a747e4fSDavid du Colombier
794*9a747e4fSDavid du Colombier #ifdef __STDC__
795*9a747e4fSDavid du Colombier
buf_in_avail(char ** bufp,uint * lenp)796*9a747e4fSDavid du Colombier static int buf_in_avail(char **bufp, uint *lenp)
797*9a747e4fSDavid du Colombier
798*9a747e4fSDavid du Colombier #else
799*9a747e4fSDavid du Colombier
800*9a747e4fSDavid du Colombier static int buf_in_avail(bufp, lenp)
801*9a747e4fSDavid du Colombier char **bufp;
802*9a747e4fSDavid du Colombier uint *lenp;
803*9a747e4fSDavid du Colombier
804*9a747e4fSDavid du Colombier #endif
805*9a747e4fSDavid du Colombier {
806*9a747e4fSDavid du Colombier uint have;
807*9a747e4fSDavid du Colombier int corrupt = 0;
808*9a747e4fSDavid du Colombier
809*9a747e4fSDavid du Colombier while ((have = bufend - bufidx) == 0) {
810*9a747e4fSDavid du Colombier corrupt |= ar_read();
811*9a747e4fSDavid du Colombier }
812*9a747e4fSDavid du Colombier *bufp = bufidx;
813*9a747e4fSDavid du Colombier *lenp = have;
814*9a747e4fSDavid du Colombier return (corrupt);
815*9a747e4fSDavid du Colombier }
816*9a747e4fSDavid du Colombier
817*9a747e4fSDavid du Colombier
818*9a747e4fSDavid du Colombier /* buf_out_avail - index buffer space for archive output
819*9a747e4fSDavid du Colombier *
820*9a747e4fSDavid du Colombier * DESCRIPTION
821*9a747e4fSDavid du Colombier *
822*9a747e4fSDavid du Colombier * Stores a buffer pointer at a given location. Returns the number
823*9a747e4fSDavid du Colombier * of bytes available.
824*9a747e4fSDavid du Colombier *
825*9a747e4fSDavid du Colombier * PARAMETERS
826*9a747e4fSDavid du Colombier *
827*9a747e4fSDavid du Colombier * char **bufp - pointer to the buffer which is to be stored
828*9a747e4fSDavid du Colombier *
829*9a747e4fSDavid du Colombier * RETURNS
830*9a747e4fSDavid du Colombier *
831*9a747e4fSDavid du Colombier * The number of bytes which are available in the buffer.
832*9a747e4fSDavid du Colombier *
833*9a747e4fSDavid du Colombier */
834*9a747e4fSDavid du Colombier
835*9a747e4fSDavid du Colombier #ifdef __STDC__
836*9a747e4fSDavid du Colombier
buf_out_avail(char ** bufp)837*9a747e4fSDavid du Colombier static uint buf_out_avail(char **bufp)
838*9a747e4fSDavid du Colombier
839*9a747e4fSDavid du Colombier #else
840*9a747e4fSDavid du Colombier
841*9a747e4fSDavid du Colombier static uint buf_out_avail(bufp)
842*9a747e4fSDavid du Colombier char **bufp;
843*9a747e4fSDavid du Colombier
844*9a747e4fSDavid du Colombier #endif
845*9a747e4fSDavid du Colombier {
846*9a747e4fSDavid du Colombier int have;
847*9a747e4fSDavid du Colombier
848*9a747e4fSDavid du Colombier if (bufend - bufidx < 0) {
849*9a747e4fSDavid du Colombier fatal("Buffer overlow in buf_out_avail\n");
850*9a747e4fSDavid du Colombier }
851*9a747e4fSDavid du Colombier if ((have = bufend - bufidx) == 0) {
852*9a747e4fSDavid du Colombier outflush();
853*9a747e4fSDavid du Colombier }
854*9a747e4fSDavid du Colombier *bufp = bufidx;
855*9a747e4fSDavid du Colombier return (have);
856*9a747e4fSDavid du Colombier }
857