1*9a747e4fSDavid du Colombier /* $Source: /u/mark/src/pax/RCS/fileio.c,v $
2*9a747e4fSDavid du Colombier *
3*9a747e4fSDavid du Colombier * $Revision: 1.2 $
4*9a747e4fSDavid du Colombier *
5*9a747e4fSDavid du Colombier * fileio.c - file I/O functions for all archive interfaces
6*9a747e4fSDavid du Colombier *
7*9a747e4fSDavid du Colombier * DESCRIPTION
8*9a747e4fSDavid du Colombier *
9*9a747e4fSDavid du Colombier * These function all do I/O of some form or another. They are
10*9a747e4fSDavid du Colombier * grouped here mainly for convienence.
11*9a747e4fSDavid du Colombier *
12*9a747e4fSDavid du Colombier * AUTHOR
13*9a747e4fSDavid du Colombier *
14*9a747e4fSDavid du Colombier * Mark H. Colburn, NAPS International (mark@jhereg.mn.org)
15*9a747e4fSDavid du Colombier *
16*9a747e4fSDavid du Colombier * Sponsored by The USENIX Association for public distribution.
17*9a747e4fSDavid du Colombier *
18*9a747e4fSDavid du Colombier * Copyright (c) 1989 Mark H. Colburn.
19*9a747e4fSDavid du Colombier * All rights reserved.
20*9a747e4fSDavid du Colombier *
21*9a747e4fSDavid du Colombier * Redistribution and use in source and binary forms are permitted
22*9a747e4fSDavid du Colombier * provided that the above copyright notice is duplicated in all such
23*9a747e4fSDavid du Colombier * forms and that any documentation, advertising materials, and other
24*9a747e4fSDavid du Colombier * materials related to such distribution and use acknowledge that the
25*9a747e4fSDavid du Colombier * software was developed * by Mark H. Colburn and sponsored by The
26*9a747e4fSDavid du Colombier * USENIX Association.
27*9a747e4fSDavid du Colombier *
28*9a747e4fSDavid du Colombier * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
29*9a747e4fSDavid du Colombier * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
30*9a747e4fSDavid du Colombier * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
31*9a747e4fSDavid du Colombier *
32*9a747e4fSDavid du Colombier * $Log: fileio.c,v $
33*9a747e4fSDavid du Colombier * Revision 1.2 89/02/12 10:04:31 mark
34*9a747e4fSDavid du Colombier * 1.2 release fixes
35*9a747e4fSDavid du Colombier *
36*9a747e4fSDavid du Colombier * Revision 1.1 88/12/23 18:02:09 mark
37*9a747e4fSDavid du Colombier * Initial revision
38*9a747e4fSDavid du Colombier *
39*9a747e4fSDavid du Colombier */
40*9a747e4fSDavid du Colombier
41*9a747e4fSDavid du Colombier #ifndef lint
42*9a747e4fSDavid du Colombier static char *ident = "$Id: fileio.c,v 1.2 89/02/12 10:04:31 mark Exp $";
43*9a747e4fSDavid du Colombier static char *copyright = "Copyright (c) 1989 Mark H. Colburn.\nAll rights reserved.\n";
44*9a747e4fSDavid du Colombier #endif /* ! lint */
45*9a747e4fSDavid du Colombier
46*9a747e4fSDavid du Colombier
47*9a747e4fSDavid du Colombier /* Headers */
48*9a747e4fSDavid du Colombier
49*9a747e4fSDavid du Colombier #include "pax.h"
50*9a747e4fSDavid du Colombier
51*9a747e4fSDavid du Colombier
52*9a747e4fSDavid du Colombier /* open_archive - open an archive file.
53*9a747e4fSDavid du Colombier *
54*9a747e4fSDavid du Colombier * DESCRIPTION
55*9a747e4fSDavid du Colombier *
56*9a747e4fSDavid du Colombier * Open_archive will open an archive file for reading or writing,
57*9a747e4fSDavid du Colombier * setting the proper file mode, depending on the "mode" passed to
58*9a747e4fSDavid du Colombier * it. All buffer pointers are reset according to the mode
59*9a747e4fSDavid du Colombier * specified.
60*9a747e4fSDavid du Colombier *
61*9a747e4fSDavid du Colombier * PARAMETERS
62*9a747e4fSDavid du Colombier *
63*9a747e4fSDavid du Colombier * int mode - specifies whether we are reading or writing.
64*9a747e4fSDavid du Colombier *
65*9a747e4fSDavid du Colombier * RETURNS
66*9a747e4fSDavid du Colombier *
67*9a747e4fSDavid du Colombier * Returns a zero if successfull, or -1 if an error occured during
68*9a747e4fSDavid du Colombier * the open.
69*9a747e4fSDavid du Colombier */
70*9a747e4fSDavid du Colombier
71*9a747e4fSDavid du Colombier #ifdef __STDC__
72*9a747e4fSDavid du Colombier
open_archive(int mode)73*9a747e4fSDavid du Colombier int open_archive(int mode)
74*9a747e4fSDavid du Colombier
75*9a747e4fSDavid du Colombier #else
76*9a747e4fSDavid du Colombier
77*9a747e4fSDavid du Colombier int open_archive(mode)
78*9a747e4fSDavid du Colombier int mode;
79*9a747e4fSDavid du Colombier
80*9a747e4fSDavid du Colombier #endif
81*9a747e4fSDavid du Colombier {
82*9a747e4fSDavid du Colombier if (ar_file[0] == '-' && ar_file[1] == '\0') {
83*9a747e4fSDavid du Colombier if (mode == AR_READ) {
84*9a747e4fSDavid du Colombier archivefd = STDIN;
85*9a747e4fSDavid du Colombier bufend = bufidx = bufstart;
86*9a747e4fSDavid du Colombier } else {
87*9a747e4fSDavid du Colombier archivefd = STDOUT;
88*9a747e4fSDavid du Colombier }
89*9a747e4fSDavid du Colombier } else if (mode == AR_READ) {
90*9a747e4fSDavid du Colombier archivefd = open(ar_file, O_RDONLY | O_BINARY);
91*9a747e4fSDavid du Colombier bufend = bufidx = bufstart; /* set up for initial read */
92*9a747e4fSDavid du Colombier } else if (mode == AR_WRITE) {
93*9a747e4fSDavid du Colombier archivefd = open(ar_file, O_WRONLY|O_TRUNC|O_CREAT|O_BINARY, 0666);
94*9a747e4fSDavid du Colombier } else if (mode == AR_APPEND) {
95*9a747e4fSDavid du Colombier archivefd = open(ar_file, O_RDWR | O_BINARY, 0666);
96*9a747e4fSDavid du Colombier bufend = bufidx = bufstart; /* set up for initial read */
97*9a747e4fSDavid du Colombier }
98*9a747e4fSDavid du Colombier
99*9a747e4fSDavid du Colombier if (archivefd < 0) {
100*9a747e4fSDavid du Colombier warnarch(strerror(), (OFFSET) 0);
101*9a747e4fSDavid du Colombier return (-1);
102*9a747e4fSDavid du Colombier }
103*9a747e4fSDavid du Colombier ++arvolume;
104*9a747e4fSDavid du Colombier return (0);
105*9a747e4fSDavid du Colombier }
106*9a747e4fSDavid du Colombier
107*9a747e4fSDavid du Colombier
108*9a747e4fSDavid du Colombier /* close_archive - close the archive file
109*9a747e4fSDavid du Colombier *
110*9a747e4fSDavid du Colombier * DESCRIPTION
111*9a747e4fSDavid du Colombier *
112*9a747e4fSDavid du Colombier * Closes the current archive and resets the archive end of file
113*9a747e4fSDavid du Colombier * marker.
114*9a747e4fSDavid du Colombier */
115*9a747e4fSDavid du Colombier
116*9a747e4fSDavid du Colombier #ifdef __STDC__
117*9a747e4fSDavid du Colombier
close_archive(void)118*9a747e4fSDavid du Colombier void close_archive(void)
119*9a747e4fSDavid du Colombier
120*9a747e4fSDavid du Colombier #else
121*9a747e4fSDavid du Colombier
122*9a747e4fSDavid du Colombier void close_archive()
123*9a747e4fSDavid du Colombier
124*9a747e4fSDavid du Colombier #endif
125*9a747e4fSDavid du Colombier {
126*9a747e4fSDavid du Colombier if (archivefd != STDIN && archivefd != STDOUT) {
127*9a747e4fSDavid du Colombier close(archivefd);
128*9a747e4fSDavid du Colombier }
129*9a747e4fSDavid du Colombier areof = 0;
130*9a747e4fSDavid du Colombier }
131*9a747e4fSDavid du Colombier
132*9a747e4fSDavid du Colombier
133*9a747e4fSDavid du Colombier /* openout - open an output file
134*9a747e4fSDavid du Colombier *
135*9a747e4fSDavid du Colombier * DESCRIPTION
136*9a747e4fSDavid du Colombier *
137*9a747e4fSDavid du Colombier * Openo opens the named file for output. The file mode and type are
138*9a747e4fSDavid du Colombier * set based on the values stored in the stat structure for the file.
139*9a747e4fSDavid du Colombier * If the file is a special file, then no data will be written, the
140*9a747e4fSDavid du Colombier * file/directory/Fifo, etc., will just be created. Appropriate
141*9a747e4fSDavid du Colombier * permission may be required to create special files.
142*9a747e4fSDavid du Colombier *
143*9a747e4fSDavid du Colombier * PARAMETERS
144*9a747e4fSDavid du Colombier *
145*9a747e4fSDavid du Colombier * char *name - The name of the file to create
146*9a747e4fSDavid du Colombier * Stat *asb - Stat structure for the file
147*9a747e4fSDavid du Colombier * Link *linkp; - pointer to link chain for this file
148*9a747e4fSDavid du Colombier * int ispass - true if we are operating in "pass" mode
149*9a747e4fSDavid du Colombier *
150*9a747e4fSDavid du Colombier * RETURNS
151*9a747e4fSDavid du Colombier *
152*9a747e4fSDavid du Colombier * Returns the output file descriptor, 0 if no data is required or -1
153*9a747e4fSDavid du Colombier * if unsuccessful. Note that UNIX open() will never return 0 because
154*9a747e4fSDavid du Colombier * the standard input is in use.
155*9a747e4fSDavid du Colombier */
156*9a747e4fSDavid du Colombier
157*9a747e4fSDavid du Colombier #ifdef __STDC__
158*9a747e4fSDavid du Colombier
openout(char * name,Stat * asb,Link * linkp,int ispass)159*9a747e4fSDavid du Colombier int openout(char *name, Stat *asb, Link *linkp, int ispass)
160*9a747e4fSDavid du Colombier
161*9a747e4fSDavid du Colombier #else
162*9a747e4fSDavid du Colombier
163*9a747e4fSDavid du Colombier int openout(name, asb, linkp, ispass)
164*9a747e4fSDavid du Colombier char *name;
165*9a747e4fSDavid du Colombier Stat *asb;
166*9a747e4fSDavid du Colombier Link *linkp;
167*9a747e4fSDavid du Colombier int ispass;
168*9a747e4fSDavid du Colombier
169*9a747e4fSDavid du Colombier #endif
170*9a747e4fSDavid du Colombier {
171*9a747e4fSDavid du Colombier int exists;
172*9a747e4fSDavid du Colombier int fd;
173*9a747e4fSDavid du Colombier ushort perm;
174*9a747e4fSDavid du Colombier ushort operm = 0;
175*9a747e4fSDavid du Colombier Stat osb;
176*9a747e4fSDavid du Colombier #ifdef S_IFLNK
177*9a747e4fSDavid du Colombier int ssize;
178*9a747e4fSDavid du Colombier char sname[PATH_MAX + 1];
179*9a747e4fSDavid du Colombier #endif /* S_IFLNK */
180*9a747e4fSDavid du Colombier
181*9a747e4fSDavid du Colombier if (exists = (LSTAT(name, &osb) == 0)) {
182*9a747e4fSDavid du Colombier if (ispass && osb.sb_ino == asb->sb_ino && osb.sb_dev == asb->sb_dev) {
183*9a747e4fSDavid du Colombier warn(name, "Same file");
184*9a747e4fSDavid du Colombier return (-1);
185*9a747e4fSDavid du Colombier } else if ((osb.sb_mode & S_IFMT) == (asb->sb_mode & S_IFMT)) {
186*9a747e4fSDavid du Colombier operm = osb.sb_mode & S_IPERM;
187*9a747e4fSDavid du Colombier } else if (REMOVE(name, &osb) < 0) {
188*9a747e4fSDavid du Colombier warn(name, strerror());
189*9a747e4fSDavid du Colombier return (-1);
190*9a747e4fSDavid du Colombier } else {
191*9a747e4fSDavid du Colombier exists = 0;
192*9a747e4fSDavid du Colombier }
193*9a747e4fSDavid du Colombier }
194*9a747e4fSDavid du Colombier if (linkp) {
195*9a747e4fSDavid du Colombier if (exists) {
196*9a747e4fSDavid du Colombier if (asb->sb_ino == osb.sb_ino && asb->sb_dev == osb.sb_dev) {
197*9a747e4fSDavid du Colombier return (0);
198*9a747e4fSDavid du Colombier } else if (unlink(name) < 0) {
199*9a747e4fSDavid du Colombier warn(name, strerror());
200*9a747e4fSDavid du Colombier return (-1);
201*9a747e4fSDavid du Colombier } else {
202*9a747e4fSDavid du Colombier exists = 0;
203*9a747e4fSDavid du Colombier }
204*9a747e4fSDavid du Colombier }
205*9a747e4fSDavid du Colombier if (link(linkp->l_name, name) != 0) {
206*9a747e4fSDavid du Colombier if (errno == ENOENT) {
207*9a747e4fSDavid du Colombier if (f_dir_create) {
208*9a747e4fSDavid du Colombier if (dirneed(name) != 0 ||
209*9a747e4fSDavid du Colombier link(linkp->l_name, name) != 0) {
210*9a747e4fSDavid du Colombier warn(name, strerror());
211*9a747e4fSDavid du Colombier return (-1);
212*9a747e4fSDavid du Colombier }
213*9a747e4fSDavid du Colombier } else {
214*9a747e4fSDavid du Colombier warn(name,
215*9a747e4fSDavid du Colombier "Directories are not being created (-d option)");
216*9a747e4fSDavid du Colombier }
217*9a747e4fSDavid du Colombier return(0);
218*9a747e4fSDavid du Colombier } else if (errno != EXDEV) {
219*9a747e4fSDavid du Colombier warn(name, strerror());
220*9a747e4fSDavid du Colombier return (-1);
221*9a747e4fSDavid du Colombier }
222*9a747e4fSDavid du Colombier } else {
223*9a747e4fSDavid du Colombier return(0);
224*9a747e4fSDavid du Colombier }
225*9a747e4fSDavid du Colombier }
226*9a747e4fSDavid du Colombier perm = asb->sb_mode & S_IPERM;
227*9a747e4fSDavid du Colombier switch (asb->sb_mode & S_IFMT) {
228*9a747e4fSDavid du Colombier case S_IFBLK:
229*9a747e4fSDavid du Colombier case S_IFCHR:
230*9a747e4fSDavid du Colombier #ifdef _POSIX_SOURCE
231*9a747e4fSDavid du Colombier warn(name, "Can't create special files");
232*9a747e4fSDavid du Colombier return (-1);
233*9a747e4fSDavid du Colombier #else
234*9a747e4fSDavid du Colombier fd = 0;
235*9a747e4fSDavid du Colombier if (exists) {
236*9a747e4fSDavid du Colombier if (asb->sb_rdev == osb.sb_rdev) {
237*9a747e4fSDavid du Colombier if (perm != operm && chmod(name, (int) perm) < 0) {
238*9a747e4fSDavid du Colombier warn(name, strerror());
239*9a747e4fSDavid du Colombier return (-1);
240*9a747e4fSDavid du Colombier } else {
241*9a747e4fSDavid du Colombier break;
242*9a747e4fSDavid du Colombier }
243*9a747e4fSDavid du Colombier } else if (REMOVE(name, &osb) < 0) {
244*9a747e4fSDavid du Colombier warn(name, strerror());
245*9a747e4fSDavid du Colombier return (-1);
246*9a747e4fSDavid du Colombier } else {
247*9a747e4fSDavid du Colombier exists = 0;
248*9a747e4fSDavid du Colombier }
249*9a747e4fSDavid du Colombier }
250*9a747e4fSDavid du Colombier if (mknod(name, (int) asb->sb_mode, (int) asb->sb_rdev) < 0) {
251*9a747e4fSDavid du Colombier if (errno == ENOENT) {
252*9a747e4fSDavid du Colombier if (f_dir_create) {
253*9a747e4fSDavid du Colombier if (dirneed(name) < 0 || mknod(name, (int) asb->sb_mode,
254*9a747e4fSDavid du Colombier (int) asb->sb_rdev) < 0) {
255*9a747e4fSDavid du Colombier warn(name, strerror());
256*9a747e4fSDavid du Colombier return (-1);
257*9a747e4fSDavid du Colombier }
258*9a747e4fSDavid du Colombier } else {
259*9a747e4fSDavid du Colombier warn(name, "Directories are not being created (-d option)");
260*9a747e4fSDavid du Colombier }
261*9a747e4fSDavid du Colombier } else {
262*9a747e4fSDavid du Colombier warn(name, strerror());
263*9a747e4fSDavid du Colombier return (-1);
264*9a747e4fSDavid du Colombier }
265*9a747e4fSDavid du Colombier }
266*9a747e4fSDavid du Colombier return(0);
267*9a747e4fSDavid du Colombier #endif /* _POSIX_SOURCE */
268*9a747e4fSDavid du Colombier break;
269*9a747e4fSDavid du Colombier case S_IFDIR:
270*9a747e4fSDavid du Colombier if (exists) {
271*9a747e4fSDavid du Colombier if (perm != operm && chmod(name, (int) perm) < 0) {
272*9a747e4fSDavid du Colombier warn(name, strerror());
273*9a747e4fSDavid du Colombier return (-1);
274*9a747e4fSDavid du Colombier }
275*9a747e4fSDavid du Colombier } else if (f_dir_create) {
276*9a747e4fSDavid du Colombier if (dirmake(name, asb) < 0 || dirneed(name) < 0) {
277*9a747e4fSDavid du Colombier warn(name, strerror());
278*9a747e4fSDavid du Colombier return (-1);
279*9a747e4fSDavid du Colombier }
280*9a747e4fSDavid du Colombier } else {
281*9a747e4fSDavid du Colombier warn(name, "Directories are not being created (-d option)");
282*9a747e4fSDavid du Colombier }
283*9a747e4fSDavid du Colombier return (0);
284*9a747e4fSDavid du Colombier #ifndef _POSIX_SOURCE
285*9a747e4fSDavid du Colombier #ifdef S_IFIFO
286*9a747e4fSDavid du Colombier case S_IFIFO:
287*9a747e4fSDavid du Colombier fd = 0;
288*9a747e4fSDavid du Colombier if (exists) {
289*9a747e4fSDavid du Colombier if (perm != operm && chmod(name, (int) perm) < 0) {
290*9a747e4fSDavid du Colombier warn(name, strerror());
291*9a747e4fSDavid du Colombier return (-1);
292*9a747e4fSDavid du Colombier }
293*9a747e4fSDavid du Colombier } else if (mknod(name, (int) asb->sb_mode, 0) < 0) {
294*9a747e4fSDavid du Colombier if (errno == ENOENT) {
295*9a747e4fSDavid du Colombier if (f_dir_create) {
296*9a747e4fSDavid du Colombier if (dirneed(name) < 0
297*9a747e4fSDavid du Colombier || mknod(name, (int) asb->sb_mode, 0) < 0) {
298*9a747e4fSDavid du Colombier warn(name, strerror());
299*9a747e4fSDavid du Colombier return (-1);
300*9a747e4fSDavid du Colombier }
301*9a747e4fSDavid du Colombier } else {
302*9a747e4fSDavid du Colombier warn(name, "Directories are not being created (-d option)");
303*9a747e4fSDavid du Colombier }
304*9a747e4fSDavid du Colombier } else {
305*9a747e4fSDavid du Colombier warn(name, strerror());
306*9a747e4fSDavid du Colombier return (-1);
307*9a747e4fSDavid du Colombier }
308*9a747e4fSDavid du Colombier }
309*9a747e4fSDavid du Colombier return(0);
310*9a747e4fSDavid du Colombier break;
311*9a747e4fSDavid du Colombier #endif /* S_IFIFO */
312*9a747e4fSDavid du Colombier #endif /* _POSIX_SOURCE */
313*9a747e4fSDavid du Colombier #ifdef S_IFLNK
314*9a747e4fSDavid du Colombier case S_IFLNK:
315*9a747e4fSDavid du Colombier if (exists) {
316*9a747e4fSDavid du Colombier if ((ssize = readlink(name, sname, sizeof(sname))) < 0) {
317*9a747e4fSDavid du Colombier warn(name, strerror());
318*9a747e4fSDavid du Colombier return (-1);
319*9a747e4fSDavid du Colombier } else if (strncmp(sname, asb->sb_link, ssize) == 0) {
320*9a747e4fSDavid du Colombier return (0);
321*9a747e4fSDavid du Colombier } else if (REMOVE(name, &osb) < 0) {
322*9a747e4fSDavid du Colombier warn(name, strerror());
323*9a747e4fSDavid du Colombier return (-1);
324*9a747e4fSDavid du Colombier } else {
325*9a747e4fSDavid du Colombier exists = 0;
326*9a747e4fSDavid du Colombier }
327*9a747e4fSDavid du Colombier }
328*9a747e4fSDavid du Colombier if (symlink(asb->sb_link, name) < 0) {
329*9a747e4fSDavid du Colombier if (errno == ENOENT) {
330*9a747e4fSDavid du Colombier if (f_dir_create) {
331*9a747e4fSDavid du Colombier if (dirneed(name) < 0 || symlink(asb->sb_link, name) < 0) {
332*9a747e4fSDavid du Colombier warn(name, strerror());
333*9a747e4fSDavid du Colombier return (-1);
334*9a747e4fSDavid du Colombier }
335*9a747e4fSDavid du Colombier } else {
336*9a747e4fSDavid du Colombier warn(name, "Directories are not being created (-d option)");
337*9a747e4fSDavid du Colombier }
338*9a747e4fSDavid du Colombier } else {
339*9a747e4fSDavid du Colombier warn(name, strerror());
340*9a747e4fSDavid du Colombier return (-1);
341*9a747e4fSDavid du Colombier }
342*9a747e4fSDavid du Colombier }
343*9a747e4fSDavid du Colombier return (0); /* Can't chown()/chmod() a symbolic link */
344*9a747e4fSDavid du Colombier #endif /* S_IFLNK */
345*9a747e4fSDavid du Colombier case S_IFREG:
346*9a747e4fSDavid du Colombier if (exists) {
347*9a747e4fSDavid du Colombier if (!f_unconditional && osb.sb_mtime > asb->sb_mtime) {
348*9a747e4fSDavid du Colombier warn(name, "Newer file exists");
349*9a747e4fSDavid du Colombier return (-1);
350*9a747e4fSDavid du Colombier } else if (unlink(name) < 0) {
351*9a747e4fSDavid du Colombier warn(name, strerror());
352*9a747e4fSDavid du Colombier return (-1);
353*9a747e4fSDavid du Colombier } else {
354*9a747e4fSDavid du Colombier exists = 0;
355*9a747e4fSDavid du Colombier }
356*9a747e4fSDavid du Colombier }
357*9a747e4fSDavid du Colombier if ((fd = creat(name, (int) perm)) < 0) {
358*9a747e4fSDavid du Colombier if (errno == ENOENT) {
359*9a747e4fSDavid du Colombier if (f_dir_create) {
360*9a747e4fSDavid du Colombier if (dirneed(name) < 0 ||
361*9a747e4fSDavid du Colombier (fd = creat(name, (int) perm)) < 0) {
362*9a747e4fSDavid du Colombier warn(name, strerror());
363*9a747e4fSDavid du Colombier return (-1);
364*9a747e4fSDavid du Colombier }
365*9a747e4fSDavid du Colombier } else {
366*9a747e4fSDavid du Colombier /*
367*9a747e4fSDavid du Colombier * the file requires a directory which does not exist
368*9a747e4fSDavid du Colombier * and which the user does not want created, so skip
369*9a747e4fSDavid du Colombier * the file...
370*9a747e4fSDavid du Colombier */
371*9a747e4fSDavid du Colombier warn(name, "Directories are not being created (-d option)");
372*9a747e4fSDavid du Colombier return(0);
373*9a747e4fSDavid du Colombier }
374*9a747e4fSDavid du Colombier } else {
375*9a747e4fSDavid du Colombier warn(name, strerror());
376*9a747e4fSDavid du Colombier return (-1);
377*9a747e4fSDavid du Colombier }
378*9a747e4fSDavid du Colombier }
379*9a747e4fSDavid du Colombier break;
380*9a747e4fSDavid du Colombier default:
381*9a747e4fSDavid du Colombier warn(name, "Unknown filetype");
382*9a747e4fSDavid du Colombier return (-1);
383*9a747e4fSDavid du Colombier }
384*9a747e4fSDavid du Colombier if (f_owner) {
385*9a747e4fSDavid du Colombier if (!exists || asb->sb_uid != osb.sb_uid || asb->sb_gid != osb.sb_gid) {
386*9a747e4fSDavid du Colombier chown(name, (int) asb->sb_uid, (int) asb->sb_gid);
387*9a747e4fSDavid du Colombier }
388*9a747e4fSDavid du Colombier }
389*9a747e4fSDavid du Colombier return (fd);
390*9a747e4fSDavid du Colombier }
391*9a747e4fSDavid du Colombier
392*9a747e4fSDavid du Colombier
393*9a747e4fSDavid du Colombier /* openin - open the next input file
394*9a747e4fSDavid du Colombier *
395*9a747e4fSDavid du Colombier * DESCRIPTION
396*9a747e4fSDavid du Colombier *
397*9a747e4fSDavid du Colombier * Openi will attempt to open the next file for input. If the file is
398*9a747e4fSDavid du Colombier * a special file, such as a directory, FIFO, link, character- or
399*9a747e4fSDavid du Colombier * block-special file, then the file size field of the stat structure
400*9a747e4fSDavid du Colombier * is zeroed to make sure that no data is written out for the file.
401*9a747e4fSDavid du Colombier * If the file is a special file, then a file descriptor of 0 is
402*9a747e4fSDavid du Colombier * returned to the caller, which is handled specially. If the file
403*9a747e4fSDavid du Colombier * is a regular file, then the file is opened and a file descriptor
404*9a747e4fSDavid du Colombier * to the open file is returned to the caller.
405*9a747e4fSDavid du Colombier *
406*9a747e4fSDavid du Colombier * PARAMETERS
407*9a747e4fSDavid du Colombier *
408*9a747e4fSDavid du Colombier * char *name - pointer to the name of the file to open
409*9a747e4fSDavid du Colombier * Stat *asb - pointer to the stat block for the file to open
410*9a747e4fSDavid du Colombier *
411*9a747e4fSDavid du Colombier * RETURNS
412*9a747e4fSDavid du Colombier *
413*9a747e4fSDavid du Colombier * Returns a file descriptor, 0 if no data exists, or -1 at EOF. This
414*9a747e4fSDavid du Colombier * kludge works because standard input is in use, preventing open() from
415*9a747e4fSDavid du Colombier * returning zero.
416*9a747e4fSDavid du Colombier */
417*9a747e4fSDavid du Colombier
418*9a747e4fSDavid du Colombier #ifdef __STDC__
419*9a747e4fSDavid du Colombier
openin(char * name,Stat * asb)420*9a747e4fSDavid du Colombier int openin(char *name, Stat *asb)
421*9a747e4fSDavid du Colombier
422*9a747e4fSDavid du Colombier #else
423*9a747e4fSDavid du Colombier
424*9a747e4fSDavid du Colombier int openin(name, asb)
425*9a747e4fSDavid du Colombier char *name; /* name of file to open */
426*9a747e4fSDavid du Colombier Stat *asb; /* pointer to stat structure for file */
427*9a747e4fSDavid du Colombier
428*9a747e4fSDavid du Colombier #endif
429*9a747e4fSDavid du Colombier {
430*9a747e4fSDavid du Colombier int fd;
431*9a747e4fSDavid du Colombier
432*9a747e4fSDavid du Colombier switch (asb->sb_mode & S_IFMT) {
433*9a747e4fSDavid du Colombier case S_IFDIR:
434*9a747e4fSDavid du Colombier asb->sb_nlink = 1;
435*9a747e4fSDavid du Colombier asb->sb_size = 0;
436*9a747e4fSDavid du Colombier return (0);
437*9a747e4fSDavid du Colombier #ifdef S_IFLNK
438*9a747e4fSDavid du Colombier case S_IFLNK:
439*9a747e4fSDavid du Colombier if ((asb->sb_size = readlink(name,
440*9a747e4fSDavid du Colombier asb->sb_link, sizeof(asb->sb_link) - 1)) < 0) {
441*9a747e4fSDavid du Colombier warn(name, strerror());
442*9a747e4fSDavid du Colombier return(0);
443*9a747e4fSDavid du Colombier }
444*9a747e4fSDavid du Colombier asb->sb_link[asb->sb_size] = '\0';
445*9a747e4fSDavid du Colombier return (0);
446*9a747e4fSDavid du Colombier #endif /* S_IFLNK */
447*9a747e4fSDavid du Colombier case S_IFREG:
448*9a747e4fSDavid du Colombier if (asb->sb_size == 0) {
449*9a747e4fSDavid du Colombier return (0);
450*9a747e4fSDavid du Colombier }
451*9a747e4fSDavid du Colombier if ((fd = open(name, O_RDONLY | O_BINARY)) < 0) {
452*9a747e4fSDavid du Colombier warn(name, strerror());
453*9a747e4fSDavid du Colombier }
454*9a747e4fSDavid du Colombier return (fd);
455*9a747e4fSDavid du Colombier default:
456*9a747e4fSDavid du Colombier asb->sb_size = 0;
457*9a747e4fSDavid du Colombier return (0);
458*9a747e4fSDavid du Colombier }
459*9a747e4fSDavid du Colombier }
460