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