2 * Copyright (c) 1996, 1997, 1998 Shigio Yamaguchi. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * 3. All advertising materials mentioning features or use of this software
13 * must display the following acknowledgement:
14 * This product includes software developed by Shigio Yamaguchi.
15 * 4. Neither the name of the author nor the names of any co-contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * USEFIND use find(1) to traverse directory tree.
36 * Otherwise, use dirent(3) library.
40 #include <sys/param.h>
59 #include "locatestring.h"
67 * while (path = findread(&length)) {
73 static regex_t skip_area;
74 static regex_t *skip = &skip_area;
77 static void trim __P((char *));
80 * trim: remove blanks and '\'.
88 for (p = s; *s; s++) {
91 if (*s == '\\' && *(s + 1))
98 /*----------------------------------------------------------------------*/
99 /* find command version */
100 /*----------------------------------------------------------------------*/
106 char *findcom, *p, *q;
108 char *sufflist = NULL;
109 char *skiplist = NULL;
115 if (!getconfs("suffixes", sb))
116 die("cannot get suffixes data.");
117 sufflist = strdup(strvalue(sb));
119 die("short of memory.");
122 if (getconfs("skip", sb)) {
123 skiplist = strdup(strvalue(sb));
125 die("short of memory.");
130 strputs(sb, "find . \\( -type f -o -type l \\) \\(");
131 for (p = sufflist; p; ) {
133 if ((p = locatestring(p, ",", MATCH_FIRST)) != NULL)
135 strputs(sb, " -name '*.");
141 strputs(sb, " \\) -print");
142 findcom = strvalue(sb);
146 STRBUF *sbb = stropen();
148 * construct regular expression.
150 strputc(sbb, '('); /* ) */
151 for (p = skiplist; p; ) {
153 if ((p = locatestring(p, ",", MATCH_FIRST)) != NULL)
156 for (q = skipf; *q; q++) {
169 * compile regular expression.
171 if (regcomp(skip, reg, REG_EXTENDED|REG_NEWLINE) != 0)
172 die("cannot compile regular expression.");
177 if (!(ip = popen(findcom, "r")))
178 die("cannot execute find.");
189 static char path[MAXPATHLEN+1];
193 while (fgets(path, MAXPATHLEN, ip)) {
194 if (!skip || regexec(skip, path, 0, 0, 0) != 0) {
198 p = path + strlen(path) - 1;
200 die("output of find(1) is wrong (findread).");
217 /*----------------------------------------------------------------------*/
218 /* dirent version findxxx() */
219 /*----------------------------------------------------------------------*/
221 static char dir[MAXPATHLEN+1]; /* directory path */
224 char *dirp, *start, *end, *p;
225 } stack[STACKSIZE], *topp, *curp; /* stack */
227 static regex_t suff_area;
228 static regex_t *suff = &suff_area;
241 if ((dirp = opendir(dir)) == NULL)
243 while ((dp = readdir(dirp)) != NULL) {
245 if (dp->d_namlen == 1 && dp->d_name[0] == '.')
247 if (dp->d_namlen == 2 && dp->d_name[0] == '.' && dp->d_name[1] == '.')
249 if (dp->d_type == DT_DIR)
251 else if (dp->d_type == DT_REG)
253 else if (dp->d_type == DT_LNK)
257 strnputs(sb, dp->d_name, (int)dp->d_namlen);
259 if (stat(path, &st) < 0) {
260 fprintf(stderr, "cannot stat '%s'. (Ignored)\n", path);
263 if (S_ISDIR(st.st_mode))
265 else if (S_ISREG(st.st_mode))
267 else if (S_ISLNK(st.st_mode))
271 strputs(sb, dp->d_name);
275 (void)closedir(dirp);
281 STRBUF *sb = stropen();
282 char *sufflist = NULL;
283 char *skiplist = NULL;
292 topp = curp + STACKSIZE;
295 curp->dirp = dir + strlen(dir);
296 curp->sb = stropen();
297 if (getdirs(dir, curp->sb) < 0)
298 die("cannot open '.' directory.");
299 curp->start = curp->p = strvalue(curp->sb);
300 curp->end = curp->start + strbuflen(curp->sb);
303 * preparing regular expression.
306 if (!getconfs("suffixes", sb))
307 die("cannot get suffixes data.");
308 sufflist = strdup(strvalue(sb));
310 die("short of memory.");
313 if (getconfs("skip", sb)) {
314 skiplist = strdup(strvalue(sb));
316 die("short of memory.");
323 strputc(sb, '('); /* ) */
324 for (p = sufflist; p; ) {
326 if ((p = locatestring(p, ",", MATCH_FIRST)) != NULL)
336 * compile regular expression.
338 if (regcomp(suff, strvalue(sb), REG_EXTENDED) != 0)
339 die("cannot compile regular expression.");
344 * construct regular expression.
347 strputc(sb, '('); /* ) */
348 for (p = skiplist; p; ) {
350 if ((p = locatestring(p, ",", MATCH_FIRST)) != NULL)
353 for (q = skipf; *q; q++) {
365 * compile regular expression.
367 if (regcomp(skip, strvalue(sb), REG_EXTENDED) != 0)
368 die("cannot compile regular expression.");
382 static char val[MAXPATHLEN+1];
385 while (curp->p < curp->end) {
386 char type = *(curp->p);
387 char *unit = curp->p + 1;
389 curp->p += strlen(curp->p) + 1;
390 if (type == 'f' || type == 'l') {
391 char *path = makepath(dir, unit);
392 if (regexec(suff, path, 0, 0, 0) != 0)
394 if (skip && regexec(skip, path, 0, 0, 0) == 0)
400 STRBUF *sb = stropen();
401 char *dirp = curp->dirp;
405 if (getdirs(dir, sb) < 0) {
406 fprintf(stderr, "cannot open directory '%s'. (Ignored)\n", dir);
415 die("directory stack over flow.");
416 curp->dirp = dirp + strlen(dirp);
418 curp->start = curp->p = strvalue(sb);
419 curp->end = curp->start + strbuflen(sb);
424 if (curp == &stack[0])
438 for (curp = &stack[0]; curp < topp; curp++)
439 if (curp->sb != NULL)
445 #endif /* !USEFIND */