1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License ("CDDL"), version 1.0.
6  * You may use this file only in accordance with the terms of version
7  * 1.0 of the CDDL.
8  *
9  * A full copy of the text of the CDDL should have accompanied this
10  * source.  A copy of the CDDL is also available via the Internet at
11  * http://www.opensource.org/licenses/cddl1.txt
12  * See the License for the specific language governing permissions
13  * and limitations under the License.
14  *
15  * When distributing Covered Code, include this CDDL HEADER in each
16  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
17  * If applicable, add the following below this CDDL HEADER, with the
18  * fields enclosed by brackets "[]" replaced with your own identifying
19  * information: Portions Copyright [yyyy] [name of copyright owner]
20  *
21  * CDDL HEADER END
22  */
23 /* Copyright (c) 1988 AT&T */
24 /* All Rights Reserved */
25 /*
26  * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
27  * Use is subject to license terms.
28  */
29 /*
30  * Copyright 2006-2020 J. Schilling
31  *
32  * @(#)dofile.c	1.14 20/05/16 J. Schilling
33  */
34 #if defined(sun)
35 #pragma ident "@(#)dofile.c 1.14 20/05/16 J. Schilling"
36 #endif
37 /*
38  * @(#)dofile.c 1.12 06/12/12
39  */
40 
41 #if defined(sun)
42 #pragma ident	"@(#)dofile.c"
43 #pragma ident	"@(#)sccs:lib/comobj/dofile.c"
44 #endif
45 #include	<defines.h>
46 #include	<schily/dirent.h>
47 
48 char	had_dir;
49 char	had_standinp;
50 
51 /*
52  * Macro to skip the following names: "", ".", "..".
53  */
54 #define	dot_dotdot(n)	((n)[(n)[0] != '.' ? 0 : (n)[1] != '.' ? 1 : 2] == '\0')
55 
56 void
do_file(p,func,check_file,need_sdot,X)57 do_file(p, func, check_file, need_sdot, X)
58 	register char *p;
59 	void	(*func) __PR((char *));
60 	int	check_file;	/* Check whether file is readable */
61 	int	need_sdot;	/* Skip non s. files */
62 	Xparms	*X;		/* -X options */
63 {
64 	extern char *Ffile;
65 	int	fd;
66 	int	delim;
67 	char str[FILESIZE];
68 	char	*ibuf = NULL;
69 	size_t	isize = 0;
70 	ssize_t	llen;
71 	DIR	*dirf;
72 	struct dirent *dir[2];
73 
74 	had_standinp = 0;
75 	had_dir = 0;
76 	if (X && (X->x_opts & XO_NULLPATH))
77 		delim = '\0';
78 	else
79 		delim = '\n';
80 
81 	if ((p[0] == '-') && (!p[1])) {
82 		/*
83 		 * this is make sure that the arguements starting with
84 		 * a hyphen are handled as regular files and stdin
85 		 * is used for accepting file names when a hyphen is
86 		 * not followed by any characters.
87 		 */
88 		had_standinp = 1;
89 
90 		while ((llen = getdelim(&ibuf, &isize, delim, stdin)) > 0) {
91 			if (delim && ibuf[llen-1] == '\n')
92 				ibuf[--llen] = '\0';
93 
94 			had_dir = 0;
95 			if (exists(ibuf) &&
96 			    (Statbuf.st_mode & S_IFMT) == S_IFDIR) {
97 				had_dir = 1;
98 				Ffile = ibuf;
99 				if ((dirf = opendir(ibuf)) == NULL)
100 					return;
101 				while ((dir[0] = readdir(dirf)) != NULL) {
102 					if (dot_dotdot(dir[0]->d_name))
103 						continue;
104 #ifdef	HAVE_DIRENT_D_INO
105 					if (dir[0]->d_ino == 0)
106 						continue;
107 #endif
108 					snprintf(str, sizeof (str),
109 						"%s/%s", ibuf, dir[0]->d_name);
110 					if (!need_sdot) {
111 						Ffile = str;
112 						(*func)(str);
113 					} else if (sccsfile(str)) {
114 					    if (check_file && (fd = open(str, O_RDONLY|O_BINARY)) < 0) {
115 						errno = 0;
116 					    } else {
117 						if (check_file)
118 							close(fd);
119 						Ffile = str;
120 						(*func)(str);
121 					    }
122 					}
123 				}
124 				closedir(dirf);
125 			} else if (!need_sdot) {
126 				Ffile = ibuf;
127 				(*func)(ibuf);
128 			} else if (sccsfile(ibuf)) {
129 				if (check_file && (fd = open(ibuf, O_RDONLY|O_BINARY)) < 0) {
130 				    errno = 0;
131 				} else {
132 				    if (check_file)
133 					close(fd);
134 				    Ffile = ibuf;
135 				    (*func)(ibuf);
136 				}
137 			}
138 		}
139 		if (ibuf)
140 			free(ibuf);
141 	} else if (exists(p) && (Statbuf.st_mode & S_IFMT) == S_IFDIR) {
142 		had_dir = 1;
143 		Ffile = p;
144 		if (!check_permission_SccsDir(p)) {
145 			return;
146 		}
147 		if ((dirf = opendir(p)) == NULL)
148 			return;
149 		while ((dir[0] = readdir(dirf)) != NULL) {
150 			if (dot_dotdot(dir[0]->d_name))
151 				continue;
152 #ifdef	HAVE_DIRENT_D_INO
153 			if (dir[0]->d_ino == 0)
154 				continue;
155 #endif
156 			snprintf(str, sizeof (str),
157 				"%s/%s", p, dir[0]->d_name);
158 			if (!need_sdot) {
159 				Ffile = str;
160 				(*func)(str);
161 			} else if (sccsfile(str)) {
162 			    if (check_file && (fd = open(str, O_RDONLY|O_BINARY)) < 0) {
163 				errno = 0;
164 			    } else {
165 				if (check_file)
166 					close(fd);
167 				Ffile = str;
168 				(*func)(str);
169 			    }
170 			}
171 		}
172 		closedir(dirf);
173 	} else {
174 		strlcpy(str, p, sizeof (str));
175 		if (!check_permission_SccsDir(dname(str))) {
176 			return;
177 		}
178 		Ffile = p;
179 		(*func)(p);
180 	}
181 }
182