glob.c revision 1.1.1.1 1 1.1 christos /* Copyright (C) 1991-2002,2003,2004,2005 Free Software Foundation, Inc.
2 1.1 christos This file is part of the GNU C Library.
3 1.1 christos
4 1.1 christos The GNU C Library is free software; you can redistribute it and/or
5 1.1 christos modify it under the terms of the GNU Lesser General Public
6 1.1 christos License as published by the Free Software Foundation; either
7 1.1 christos version 2.1 of the License, or (at your option) any later version.
8 1.1 christos
9 1.1 christos The GNU C Library is distributed in the hope that it will be useful,
10 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of
11 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 1.1 christos Lesser General Public License for more details.
13 1.1 christos
14 1.1 christos You should have received a copy of the GNU Lesser General Public
15 1.1 christos License along with the GNU C Library; if not, write to the Free
16 1.1 christos Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
17 1.1 christos 02111-1307 USA. */
18 1.1 christos
19 1.1 christos #ifdef HAVE_CONFIG_H
20 1.1 christos # include <config.h>
21 1.1 christos #endif
22 1.1 christos
23 1.1 christos #include <glob.h>
24 1.1 christos
25 1.1 christos #include <errno.h>
26 1.1 christos #include <sys/types.h>
27 1.1 christos #include <sys/stat.h>
28 1.1 christos #include <stddef.h>
29 1.1 christos
30 1.1 christos /* Outcomment the following line for production quality code. */
31 1.1 christos /* #define NDEBUG 1 */
32 1.1 christos #include <assert.h>
33 1.1 christos
34 1.1 christos #include <stdio.h> /* Needed on stupid SunOS for assert. */
35 1.1 christos
36 1.1 christos #if !defined _LIBC || !defined GLOB_ONLY_P
37 1.1 christos #if defined HAVE_UNISTD_H || defined _LIBC
38 1.1 christos # include <unistd.h>
39 1.1 christos # ifndef POSIX
40 1.1 christos # ifdef _POSIX_VERSION
41 1.1 christos # define POSIX
42 1.1 christos # endif
43 1.1 christos # endif
44 1.1 christos #endif
45 1.1 christos
46 1.1 christos #include <pwd.h>
47 1.1 christos
48 1.1 christos #include <errno.h>
49 1.1 christos #ifndef __set_errno
50 1.1 christos # define __set_errno(val) errno = (val)
51 1.1 christos #endif
52 1.1 christos
53 1.1 christos #if defined HAVE_DIRENT_H || defined __GNU_LIBRARY__
54 1.1 christos # include <dirent.h>
55 1.1 christos # define NAMLEN(dirent) strlen((dirent)->d_name)
56 1.1 christos #else
57 1.1 christos # define dirent direct
58 1.1 christos # define NAMLEN(dirent) (dirent)->d_namlen
59 1.1 christos # ifdef HAVE_SYS_NDIR_H
60 1.1 christos # include <sys/ndir.h>
61 1.1 christos # endif
62 1.1 christos # ifdef HAVE_SYS_DIR_H
63 1.1 christos # include <sys/dir.h>
64 1.1 christos # endif
65 1.1 christos # ifdef HAVE_NDIR_H
66 1.1 christos # include <ndir.h>
67 1.1 christos # endif
68 1.1 christos # ifdef HAVE_VMSDIR_H
69 1.1 christos # include "vmsdir.h"
70 1.1 christos # endif /* HAVE_VMSDIR_H */
71 1.1 christos #endif
72 1.1 christos
73 1.1 christos
74 1.1 christos /* In GNU systems, <dirent.h> defines this macro for us. */
75 1.1 christos #ifdef _D_NAMLEN
76 1.1 christos # undef NAMLEN
77 1.1 christos # define NAMLEN(d) _D_NAMLEN(d)
78 1.1 christos #endif
79 1.1 christos
80 1.1 christos /* When used in the GNU libc the symbol _DIRENT_HAVE_D_TYPE is available
81 1.1 christos if the `d_type' member for `struct dirent' is available.
82 1.1 christos HAVE_STRUCT_DIRENT_D_TYPE plays the same role in GNULIB. */
83 1.1 christos #if defined _DIRENT_HAVE_D_TYPE || defined HAVE_STRUCT_DIRENT_D_TYPE
84 1.1 christos /* True if the directory entry D must be of type T. */
85 1.1 christos # define DIRENT_MUST_BE(d, t) ((d)->d_type == (t))
86 1.1 christos
87 1.1 christos /* True if the directory entry D might be a symbolic link. */
88 1.1 christos # define DIRENT_MIGHT_BE_SYMLINK(d) \
89 1.1 christos ((d)->d_type == DT_UNKNOWN || (d)->d_type == DT_LNK)
90 1.1 christos
91 1.1 christos /* True if the directory entry D might be a directory. */
92 1.1 christos # define DIRENT_MIGHT_BE_DIR(d) \
93 1.1 christos ((d)->d_type == DT_DIR || DIRENT_MIGHT_BE_SYMLINK (d))
94 1.1 christos
95 1.1 christos #else /* !HAVE_D_TYPE */
96 1.1 christos # define DIRENT_MUST_BE(d, t) false
97 1.1 christos # define DIRENT_MIGHT_BE_SYMLINK(d) true
98 1.1 christos # define DIRENT_MIGHT_BE_DIR(d) true
99 1.1 christos #endif /* HAVE_D_TYPE */
100 1.1 christos
101 1.1 christos /* If the system has the `struct dirent64' type we use it internally. */
102 1.1 christos #if defined _LIBC && !defined COMPILE_GLOB64
103 1.1 christos # if defined HAVE_DIRENT_H || defined __GNU_LIBRARY__
104 1.1 christos # define CONVERT_D_NAMLEN(d64, d32)
105 1.1 christos # else
106 1.1 christos # define CONVERT_D_NAMLEN(d64, d32) \
107 1.1 christos (d64)->d_namlen = (d32)->d_namlen;
108 1.1 christos # endif
109 1.1 christos
110 1.1 christos # if (defined POSIX || defined WINDOWS32) && !defined __GNU_LIBRARY__
111 1.1 christos # define CONVERT_D_INO(d64, d32)
112 1.1 christos # else
113 1.1 christos # define CONVERT_D_INO(d64, d32) \
114 1.1 christos (d64)->d_ino = (d32)->d_ino;
115 1.1 christos # endif
116 1.1 christos
117 1.1 christos # ifdef _DIRENT_HAVE_D_TYPE
118 1.1 christos # define CONVERT_D_TYPE(d64, d32) \
119 1.1 christos (d64)->d_type = (d32)->d_type;
120 1.1 christos # else
121 1.1 christos # define CONVERT_D_TYPE(d64, d32)
122 1.1 christos # endif
123 1.1 christos
124 1.1 christos # define CONVERT_DIRENT_DIRENT64(d64, d32) \
125 1.1 christos memcpy ((d64)->d_name, (d32)->d_name, NAMLEN (d32) + 1); \
126 1.1 christos CONVERT_D_NAMLEN (d64, d32) \
127 1.1 christos CONVERT_D_INO (d64, d32) \
128 1.1 christos CONVERT_D_TYPE (d64, d32)
129 1.1 christos #endif
130 1.1 christos
131 1.1 christos
132 1.1 christos #if (defined POSIX || defined WINDOWS32) && !defined __GNU_LIBRARY__
133 1.1 christos /* Posix does not require that the d_ino field be present, and some
134 1.1 christos systems do not provide it. */
135 1.1 christos # define REAL_DIR_ENTRY(dp) 1
136 1.1 christos #else
137 1.1 christos # define REAL_DIR_ENTRY(dp) (dp->d_ino != 0)
138 1.1 christos #endif /* POSIX */
139 1.1 christos
140 1.1 christos #include <stdlib.h>
141 1.1 christos #include <string.h>
142 1.1 christos
143 1.1 christos /* NAME_MAX is usually defined in <dirent.h> or <limits.h>. */
144 1.1 christos #include <limits.h>
145 1.1 christos #ifndef NAME_MAX
146 1.1 christos # define NAME_MAX (sizeof (((struct dirent *) 0)->d_name))
147 1.1 christos #endif
148 1.1 christos
149 1.1 christos #include <alloca.h>
150 1.1 christos
151 1.1 christos #ifdef _LIBC
152 1.1 christos # undef strdup
153 1.1 christos # define strdup(str) __strdup (str)
154 1.1 christos # define sysconf(id) __sysconf (id)
155 1.1 christos # define closedir(dir) __closedir (dir)
156 1.1 christos # define opendir(name) __opendir (name)
157 1.1 christos # define readdir(str) __readdir64 (str)
158 1.1 christos # define getpwnam_r(name, bufp, buf, len, res) \
159 1.1 christos __getpwnam_r (name, bufp, buf, len, res)
160 1.1 christos # ifndef __stat64
161 1.1 christos # define __stat64(fname, buf) __xstat64 (_STAT_VER, fname, buf)
162 1.1 christos # endif
163 1.1 christos # define struct_stat64 struct stat64
164 1.1 christos #else /* !_LIBC */
165 1.1 christos # include "getlogin_r.h"
166 1.1 christos # include "mempcpy.h"
167 1.1 christos # include "stat-macros.h"
168 1.1 christos # include "strdup.h"
169 1.1 christos # define __stat64(fname, buf) stat (fname, buf)
170 1.1 christos # define struct_stat64 struct stat
171 1.1 christos # define __stat(fname, buf) stat (fname, buf)
172 1.1 christos # define __alloca alloca
173 1.1 christos # define __readdir readdir
174 1.1 christos # define __readdir64 readdir64
175 1.1 christos # define __glob_pattern_p glob_pattern_p
176 1.1 christos #endif /* _LIBC */
177 1.1 christos
178 1.1 christos #include <stdbool.h>
179 1.1 christos #include <fnmatch.h>
180 1.1 christos
181 1.1 christos #ifdef _SC_GETPW_R_SIZE_MAX
182 1.1 christos # define GETPW_R_SIZE_MAX() sysconf (_SC_GETPW_R_SIZE_MAX)
183 1.1 christos #else
184 1.1 christos # define GETPW_R_SIZE_MAX() (-1)
185 1.1 christos #endif
186 1.1 christos #ifdef _SC_LOGIN_NAME_MAX
187 1.1 christos # define GET_LOGIN_NAME_MAX() sysconf (_SC_LOGIN_NAME_MAX)
188 1.1 christos #else
189 1.1 christos # define GET_LOGIN_NAME_MAX() (-1)
190 1.1 christos #endif
191 1.1 christos
192 1.1 christos static const char *next_brace_sub (const char *begin, int flags) __THROW;
194 1.1 christos
195 1.1 christos #endif /* !defined _LIBC || !defined GLOB_ONLY_P */
196 1.1 christos
197 1.1 christos static int glob_in_dir (const char *pattern, const char *directory,
198 1.1 christos int flags, int (*errfunc) (const char *, int),
199 1.1 christos glob_t *pglob);
200 1.1 christos
201 1.1 christos #if !defined _LIBC || !defined GLOB_ONLY_P
202 1.1 christos static int prefix_array (const char *prefix, char **array, size_t n) __THROW;
203 1.1 christos static int collated_compare (const void *, const void *) __THROW;
204 1.1 christos
205 1.1 christos
206 1.1 christos /* Find the end of the sub-pattern in a brace expression. */
207 1.1 christos static const char *
208 1.1 christos next_brace_sub (const char *cp, int flags)
209 1.1 christos {
210 1.1 christos unsigned int depth = 0;
211 1.1 christos while (*cp != '\0')
212 1.1 christos if ((flags & GLOB_NOESCAPE) == 0 && *cp == '\\')
213 1.1 christos {
214 1.1 christos if (*++cp == '\0')
215 1.1 christos break;
216 1.1 christos ++cp;
217 1.1 christos }
218 1.1 christos else
219 1.1 christos {
220 1.1 christos if ((*cp == '}' && depth-- == 0) || (*cp == ',' && depth == 0))
221 1.1 christos break;
222 1.1 christos
223 1.1 christos if (*cp++ == '{')
224 1.1 christos depth++;
225 1.1 christos }
226 1.1 christos
227 1.1 christos return *cp != '\0' ? cp : NULL;
228 1.1 christos }
229 1.1 christos
230 1.1 christos #endif /* !defined _LIBC || !defined GLOB_ONLY_P */
231 1.1 christos
232 1.1 christos /* Do glob searching for PATTERN, placing results in PGLOB.
233 1.1 christos The bits defined above may be set in FLAGS.
234 1.1 christos If a directory cannot be opened or read and ERRFUNC is not nil,
235 1.1 christos it is called with the pathname that caused the error, and the
236 1.1 christos `errno' value from the failing call; if it returns non-zero
237 1.1 christos `glob' returns GLOB_ABORTED; if it returns zero, the error is ignored.
238 1.1 christos If memory cannot be allocated for PGLOB, GLOB_NOSPACE is returned.
239 1.1 christos Otherwise, `glob' returns zero. */
240 1.1 christos int
241 1.1 christos #ifdef GLOB_ATTRIBUTE
242 1.1 christos GLOB_ATTRIBUTE
243 1.1 christos #endif
244 1.1 christos glob (pattern, flags, errfunc, pglob)
245 1.1 christos const char *pattern;
246 1.1 christos int flags;
247 1.1 christos int (*errfunc) (const char *, int);
248 1.1 christos glob_t *pglob;
249 1.1 christos {
250 1.1 christos const char *filename;
251 1.1 christos const char *dirname;
252 1.1 christos size_t dirlen;
253 1.1 christos int status;
254 1.1 christos size_t oldcount;
255 1.1 christos
256 1.1 christos if (pattern == NULL || pglob == NULL || (flags & ~__GLOB_FLAGS) != 0)
257 1.1 christos {
258 1.1 christos __set_errno (EINVAL);
259 1.1 christos return -1;
260 1.1 christos }
261 1.1 christos
262 1.1 christos if (!(flags & GLOB_DOOFFS))
263 1.1 christos /* Have to do this so `globfree' knows where to start freeing. It
264 1.1 christos also makes all the code that uses gl_offs simpler. */
265 1.1 christos pglob->gl_offs = 0;
266 1.1 christos
267 1.1 christos if (flags & GLOB_BRACE)
268 1.1 christos {
269 1.1 christos const char *begin;
270 1.1 christos
271 1.1 christos if (flags & GLOB_NOESCAPE)
272 1.1 christos begin = strchr (pattern, '{');
273 1.1 christos else
274 1.1 christos {
275 1.1 christos begin = pattern;
276 1.1 christos while (1)
277 1.1 christos {
278 1.1 christos if (*begin == '\0')
279 1.1 christos {
280 1.1 christos begin = NULL;
281 1.1 christos break;
282 1.1 christos }
283 1.1 christos
284 1.1 christos if (*begin == '\\' && begin[1] != '\0')
285 1.1 christos ++begin;
286 1.1 christos else if (*begin == '{')
287 1.1 christos break;
288 1.1 christos
289 1.1 christos ++begin;
290 1.1 christos }
291 1.1 christos }
292 1.1 christos
293 1.1 christos if (begin != NULL)
294 1.1 christos {
295 1.1 christos /* Allocate working buffer large enough for our work. Note that
296 1.1 christos we have at least an opening and closing brace. */
297 1.1 christos size_t firstc;
298 1.1 christos char *alt_start;
299 1.1 christos const char *p;
300 1.1 christos const char *next;
301 1.1 christos const char *rest;
302 1.1 christos size_t rest_len;
303 1.1 christos #ifdef __GNUC__
304 1.1 christos char onealt[strlen (pattern) - 1];
305 1.1 christos #else
306 1.1 christos char *onealt = malloc (strlen (pattern) - 1);
307 1.1 christos if (onealt == NULL)
308 1.1 christos {
309 1.1 christos if (!(flags & GLOB_APPEND))
310 1.1 christos {
311 1.1 christos pglob->gl_pathc = 0;
312 1.1 christos pglob->gl_pathv = NULL;
313 1.1 christos }
314 1.1 christos return GLOB_NOSPACE;
315 1.1 christos }
316 1.1 christos #endif
317 1.1 christos
318 1.1 christos /* We know the prefix for all sub-patterns. */
319 1.1 christos alt_start = mempcpy (onealt, pattern, begin - pattern);
320 1.1 christos
321 1.1 christos /* Find the first sub-pattern and at the same time find the
322 1.1 christos rest after the closing brace. */
323 1.1 christos next = next_brace_sub (begin + 1, flags);
324 1.1 christos if (next == NULL)
325 1.1 christos {
326 1.1 christos /* It is an illegal expression. */
327 1.1 christos #ifndef __GNUC__
328 1.1 christos free (onealt);
329 1.1 christos #endif
330 1.1 christos return glob (pattern, flags & ~GLOB_BRACE, errfunc, pglob);
331 1.1 christos }
332 1.1 christos
333 1.1 christos /* Now find the end of the whole brace expression. */
334 1.1 christos rest = next;
335 1.1 christos while (*rest != '}')
336 1.1 christos {
337 1.1 christos rest = next_brace_sub (rest + 1, flags);
338 1.1 christos if (rest == NULL)
339 1.1 christos {
340 1.1 christos /* It is an illegal expression. */
341 1.1 christos #ifndef __GNUC__
342 1.1 christos free (onealt);
343 1.1 christos #endif
344 1.1 christos return glob (pattern, flags & ~GLOB_BRACE, errfunc, pglob);
345 1.1 christos }
346 1.1 christos }
347 1.1 christos /* Please note that we now can be sure the brace expression
348 1.1 christos is well-formed. */
349 1.1 christos rest_len = strlen (++rest) + 1;
350 1.1 christos
351 1.1 christos /* We have a brace expression. BEGIN points to the opening {,
352 1.1 christos NEXT points past the terminator of the first element, and END
353 1.1 christos points past the final }. We will accumulate result names from
354 1.1 christos recursive runs for each brace alternative in the buffer using
355 1.1 christos GLOB_APPEND. */
356 1.1 christos
357 1.1 christos if (!(flags & GLOB_APPEND))
358 1.1 christos {
359 1.1 christos /* This call is to set a new vector, so clear out the
360 1.1 christos vector so we can append to it. */
361 1.1 christos pglob->gl_pathc = 0;
362 1.1 christos pglob->gl_pathv = NULL;
363 1.1 christos }
364 1.1 christos firstc = pglob->gl_pathc;
365 1.1 christos
366 1.1 christos p = begin + 1;
367 1.1 christos while (1)
368 1.1 christos {
369 1.1 christos int result;
370 1.1 christos
371 1.1 christos /* Construct the new glob expression. */
372 1.1 christos mempcpy (mempcpy (alt_start, p, next - p), rest, rest_len);
373 1.1 christos
374 1.1 christos result = glob (onealt,
375 1.1 christos ((flags & ~(GLOB_NOCHECK | GLOB_NOMAGIC))
376 1.1 christos | GLOB_APPEND), errfunc, pglob);
377 1.1 christos
378 1.1 christos /* If we got an error, return it. */
379 1.1 christos if (result && result != GLOB_NOMATCH)
380 1.1 christos {
381 1.1 christos #ifndef __GNUC__
382 1.1 christos free (onealt);
383 1.1 christos #endif
384 1.1 christos if (!(flags & GLOB_APPEND))
385 1.1 christos {
386 1.1 christos globfree (pglob);
387 1.1 christos pglob->gl_pathc = 0;
388 1.1 christos }
389 1.1 christos return result;
390 1.1 christos }
391 1.1 christos
392 1.1 christos if (*next == '}')
393 1.1 christos /* We saw the last entry. */
394 1.1 christos break;
395 1.1 christos
396 1.1 christos p = next + 1;
397 1.1 christos next = next_brace_sub (p, flags);
398 1.1 christos assert (next != NULL);
399 1.1 christos }
400 1.1 christos
401 1.1 christos #ifndef __GNUC__
402 1.1 christos free (onealt);
403 1.1 christos #endif
404 1.1 christos
405 1.1 christos if (pglob->gl_pathc != firstc)
406 1.1 christos /* We found some entries. */
407 1.1 christos return 0;
408 1.1 christos else if (!(flags & (GLOB_NOCHECK|GLOB_NOMAGIC)))
409 1.1 christos return GLOB_NOMATCH;
410 1.1 christos }
411 1.1 christos }
412 1.1 christos
413 1.1 christos /* Find the filename. */
414 1.1 christos filename = strrchr (pattern, '/');
415 1.1 christos #if defined __MSDOS__ || defined WINDOWS32
416 1.1 christos /* The case of "d:pattern". Since `:' is not allowed in
417 1.1 christos file names, we can safely assume that wherever it
418 1.1 christos happens in pattern, it signals the filename part. This
419 1.1 christos is so we could some day support patterns like "[a-z]:foo". */
420 1.1 christos if (filename == NULL)
421 1.1 christos filename = strchr (pattern, ':');
422 1.1 christos #endif /* __MSDOS__ || WINDOWS32 */
423 1.1 christos if (filename == NULL)
424 1.1 christos {
425 1.1 christos /* This can mean two things: a simple name or "~name". The latter
426 1.1 christos case is nothing but a notation for a directory. */
427 1.1 christos if ((flags & (GLOB_TILDE|GLOB_TILDE_CHECK)) && pattern[0] == '~')
428 1.1 christos {
429 1.1 christos dirname = pattern;
430 1.1 christos dirlen = strlen (pattern);
431 1.1 christos
432 1.1 christos /* Set FILENAME to NULL as a special flag. This is ugly but
433 1.1 christos other solutions would require much more code. We test for
434 1.1 christos this special case below. */
435 1.1 christos filename = NULL;
436 1.1 christos }
437 1.1 christos else
438 1.1 christos {
439 1.1 christos filename = pattern;
440 1.1 christos #ifdef _AMIGA
441 1.1 christos dirname = "";
442 1.1 christos #else
443 1.1 christos dirname = ".";
444 1.1 christos #endif
445 1.1 christos dirlen = 0;
446 1.1 christos }
447 1.1 christos }
448 1.1 christos else if (filename == pattern)
449 1.1 christos {
450 1.1 christos /* "/pattern". */
451 1.1 christos dirname = "/";
452 1.1 christos dirlen = 1;
453 1.1 christos ++filename;
454 1.1 christos }
455 1.1 christos else
456 1.1 christos {
457 1.1 christos char *newp;
458 1.1 christos dirlen = filename - pattern;
459 1.1 christos #if defined __MSDOS__ || defined WINDOWS32
460 1.1 christos if (*filename == ':'
461 1.1 christos || (filename > pattern + 1 && filename[-1] == ':'))
462 1.1 christos {
463 1.1 christos char *drive_spec;
464 1.1 christos
465 1.1 christos ++dirlen;
466 1.1 christos drive_spec = __alloca (dirlen + 1);
467 1.1 christos *((char *) mempcpy (drive_spec, pattern, dirlen)) = '\0';
468 1.1 christos /* For now, disallow wildcards in the drive spec, to
469 1.1 christos prevent infinite recursion in glob. */
470 1.1 christos if (__glob_pattern_p (drive_spec, !(flags & GLOB_NOESCAPE)))
471 1.1 christos return GLOB_NOMATCH;
472 1.1 christos /* If this is "d:pattern", we need to copy `:' to DIRNAME
473 1.1 christos as well. If it's "d:/pattern", don't remove the slash
474 1.1 christos from "d:/", since "d:" and "d:/" are not the same.*/
475 1.1 christos }
476 1.1 christos #endif
477 1.1 christos newp = __alloca (dirlen + 1);
478 1.1 christos *((char *) mempcpy (newp, pattern, dirlen)) = '\0';
479 1.1 christos dirname = newp;
480 1.1 christos ++filename;
481 1.1 christos
482 1.1 christos if (filename[0] == '\0'
483 1.1 christos #if defined __MSDOS__ || defined WINDOWS32
484 1.1 christos && dirname[dirlen - 1] != ':'
485 1.1 christos && (dirlen < 3 || dirname[dirlen - 2] != ':'
486 1.1 christos || dirname[dirlen - 1] != '/')
487 1.1 christos #endif
488 1.1 christos && dirlen > 1)
489 1.1 christos /* "pattern/". Expand "pattern", appending slashes. */
490 1.1 christos {
491 1.1 christos int val = glob (dirname, flags | GLOB_MARK, errfunc, pglob);
492 1.1 christos if (val == 0)
493 1.1 christos pglob->gl_flags = ((pglob->gl_flags & ~GLOB_MARK)
494 1.1 christos | (flags & GLOB_MARK));
495 1.1 christos return val;
496 1.1 christos }
497 1.1 christos }
498 1.1 christos
499 1.1 christos if (!(flags & GLOB_APPEND))
500 1.1 christos {
501 1.1 christos pglob->gl_pathc = 0;
502 1.1 christos if (!(flags & GLOB_DOOFFS))
503 1.1 christos pglob->gl_pathv = NULL;
504 1.1 christos else
505 1.1 christos {
506 1.1 christos size_t i;
507 1.1 christos pglob->gl_pathv = malloc ((pglob->gl_offs + 1) * sizeof (char *));
508 1.1 christos if (pglob->gl_pathv == NULL)
509 1.1 christos return GLOB_NOSPACE;
510 1.1 christos
511 1.1 christos for (i = 0; i <= pglob->gl_offs; ++i)
512 1.1 christos pglob->gl_pathv[i] = NULL;
513 1.1 christos }
514 1.1 christos }
515 1.1 christos
516 1.1 christos oldcount = pglob->gl_pathc + pglob->gl_offs;
517 1.1 christos
518 1.1 christos #ifndef VMS
519 1.1 christos if ((flags & (GLOB_TILDE|GLOB_TILDE_CHECK)) && dirname[0] == '~')
520 1.1 christos {
521 1.1 christos if (dirname[1] == '\0' || dirname[1] == '/')
522 1.1 christos {
523 1.1 christos /* Look up home directory. */
524 1.1 christos const char *home_dir = getenv ("HOME");
525 1.1 christos # ifdef _AMIGA
526 1.1 christos if (home_dir == NULL || home_dir[0] == '\0')
527 1.1 christos home_dir = "SYS:";
528 1.1 christos # else
529 1.1 christos # ifdef WINDOWS32
530 1.1 christos if (home_dir == NULL || home_dir[0] == '\0')
531 1.1 christos home_dir = "c:/users/default"; /* poor default */
532 1.1 christos # else
533 1.1 christos if (home_dir == NULL || home_dir[0] == '\0')
534 1.1 christos {
535 1.1 christos int success;
536 1.1 christos char *name;
537 1.1 christos size_t buflen = GET_LOGIN_NAME_MAX () + 1;
538 1.1 christos
539 1.1 christos if (buflen == 0)
540 1.1 christos /* `sysconf' does not support _SC_LOGIN_NAME_MAX. Try
541 1.1 christos a moderate value. */
542 1.1 christos buflen = 20;
543 1.1 christos name = __alloca (buflen);
544 1.1 christos
545 1.1 christos success = getlogin_r (name, buflen) == 0;
546 1.1 christos if (success)
547 1.1 christos {
548 1.1 christos struct passwd *p;
549 1.1 christos # if defined HAVE_GETPWNAM_R || defined _LIBC
550 1.1 christos long int pwbuflen = GETPW_R_SIZE_MAX ();
551 1.1 christos char *pwtmpbuf;
552 1.1 christos struct passwd pwbuf;
553 1.1 christos int save = errno;
554 1.1 christos
555 1.1 christos # ifndef _LIBC
556 1.1 christos if (pwbuflen == -1)
557 1.1 christos /* `sysconf' does not support _SC_GETPW_R_SIZE_MAX.
558 1.1 christos Try a moderate value. */
559 1.1 christos pwbuflen = 1024;
560 1.1 christos # endif
561 1.1 christos pwtmpbuf = __alloca (pwbuflen);
562 1.1 christos
563 1.1 christos while (getpwnam_r (name, &pwbuf, pwtmpbuf, pwbuflen, &p)
564 1.1 christos != 0)
565 1.1 christos {
566 1.1 christos if (errno != ERANGE)
567 1.1 christos {
568 1.1 christos p = NULL;
569 1.1 christos break;
570 1.1 christos }
571 1.1 christos # ifdef _LIBC
572 1.1 christos pwtmpbuf = extend_alloca (pwtmpbuf, pwbuflen,
573 1.1 christos 2 * pwbuflen);
574 1.1 christos # else
575 1.1 christos pwbuflen *= 2;
576 1.1 christos pwtmpbuf = __alloca (pwbuflen);
577 1.1 christos # endif
578 1.1 christos __set_errno (save);
579 1.1 christos }
580 1.1 christos # else
581 1.1 christos p = getpwnam (name);
582 1.1 christos # endif
583 1.1 christos if (p != NULL)
584 1.1 christos home_dir = p->pw_dir;
585 1.1 christos }
586 1.1 christos }
587 1.1 christos if (home_dir == NULL || home_dir[0] == '\0')
588 1.1 christos {
589 1.1 christos if (flags & GLOB_TILDE_CHECK)
590 1.1 christos return GLOB_NOMATCH;
591 1.1 christos else
592 1.1 christos home_dir = "~"; /* No luck. */
593 1.1 christos }
594 1.1 christos # endif /* WINDOWS32 */
595 1.1 christos # endif
596 1.1 christos /* Now construct the full directory. */
597 1.1 christos if (dirname[1] == '\0')
598 1.1 christos dirname = home_dir;
599 1.1 christos else
600 1.1 christos {
601 1.1 christos char *newp;
602 1.1 christos size_t home_len = strlen (home_dir);
603 1.1 christos newp = __alloca (home_len + dirlen);
604 1.1 christos mempcpy (mempcpy (newp, home_dir, home_len),
605 1.1 christos &dirname[1], dirlen);
606 1.1 christos dirname = newp;
607 1.1 christos }
608 1.1 christos }
609 1.1 christos # if !defined _AMIGA && !defined WINDOWS32
610 1.1 christos else
611 1.1 christos {
612 1.1 christos char *end_name = strchr (dirname, '/');
613 1.1 christos const char *user_name;
614 1.1 christos const char *home_dir;
615 1.1 christos
616 1.1 christos if (end_name == NULL)
617 1.1 christos user_name = dirname + 1;
618 1.1 christos else
619 1.1 christos {
620 1.1 christos char *newp;
621 1.1 christos newp = __alloca (end_name - dirname);
622 1.1 christos *((char *) mempcpy (newp, dirname + 1, end_name - dirname))
623 1.1 christos = '\0';
624 1.1 christos user_name = newp;
625 1.1 christos }
626 1.1 christos
627 1.1 christos /* Look up specific user's home directory. */
628 1.1 christos {
629 1.1 christos struct passwd *p;
630 1.1 christos # if defined HAVE_GETPWNAM_R || defined _LIBC
631 1.1 christos long int buflen = GETPW_R_SIZE_MAX ();
632 1.1 christos char *pwtmpbuf;
633 1.1 christos struct passwd pwbuf;
634 1.1 christos int save = errno;
635 1.1 christos
636 1.1 christos # ifndef _LIBC
637 1.1 christos if (buflen == -1)
638 1.1 christos /* `sysconf' does not support _SC_GETPW_R_SIZE_MAX. Try a
639 1.1 christos moderate value. */
640 1.1 christos buflen = 1024;
641 1.1 christos # endif
642 1.1 christos pwtmpbuf = __alloca (buflen);
643 1.1 christos
644 1.1 christos while (getpwnam_r (user_name, &pwbuf, pwtmpbuf, buflen, &p) != 0)
645 1.1 christos {
646 1.1 christos if (errno != ERANGE)
647 1.1 christos {
648 1.1 christos p = NULL;
649 1.1 christos break;
650 1.1 christos }
651 1.1 christos # ifdef _LIBC
652 1.1 christos pwtmpbuf = extend_alloca (pwtmpbuf, buflen, 2 * buflen);
653 1.1 christos # else
654 1.1 christos buflen *= 2;
655 1.1 christos pwtmpbuf = __alloca (buflen);
656 1.1 christos # endif
657 1.1 christos __set_errno (save);
658 1.1 christos }
659 1.1 christos # else
660 1.1 christos p = getpwnam (user_name);
661 1.1 christos # endif
662 1.1 christos if (p != NULL)
663 1.1 christos home_dir = p->pw_dir;
664 1.1 christos else
665 1.1 christos home_dir = NULL;
666 1.1 christos }
667 1.1 christos /* If we found a home directory use this. */
668 1.1 christos if (home_dir != NULL)
669 1.1 christos {
670 1.1 christos char *newp;
671 1.1 christos size_t home_len = strlen (home_dir);
672 1.1 christos size_t rest_len = end_name == NULL ? 0 : strlen (end_name);
673 1.1 christos newp = __alloca (home_len + rest_len + 1);
674 1.1 christos *((char *) mempcpy (mempcpy (newp, home_dir, home_len),
675 1.1 christos end_name, rest_len)) = '\0';
676 1.1 christos dirname = newp;
677 1.1 christos }
678 1.1 christos else
679 1.1 christos if (flags & GLOB_TILDE_CHECK)
680 1.1 christos /* We have to regard it as an error if we cannot find the
681 1.1 christos home directory. */
682 1.1 christos return GLOB_NOMATCH;
683 1.1 christos }
684 1.1 christos # endif /* Not Amiga && not WINDOWS32. */
685 1.1 christos }
686 1.1 christos #endif /* Not VMS. */
687 1.1 christos
688 1.1 christos /* Now test whether we looked for "~" or "~NAME". In this case we
689 1.1 christos can give the answer now. */
690 1.1 christos if (filename == NULL)
691 1.1 christos {
692 1.1 christos struct stat st;
693 1.1 christos struct_stat64 st64;
694 1.1 christos
695 1.1 christos /* Return the directory if we don't check for error or if it exists. */
696 1.1 christos if ((flags & GLOB_NOCHECK)
697 1.1 christos || (((flags & GLOB_ALTDIRFUNC)
698 1.1 christos ? ((*pglob->gl_stat) (dirname, &st) == 0
699 1.1 christos && S_ISDIR (st.st_mode))
700 1.1 christos : (__stat64 (dirname, &st64) == 0 && S_ISDIR (st64.st_mode)))))
701 1.1 christos {
702 1.1 christos int newcount = pglob->gl_pathc + pglob->gl_offs;
703 1.1 christos char **new_gl_pathv;
704 1.1 christos
705 1.1 christos new_gl_pathv
706 1.1 christos = realloc (pglob->gl_pathv, (newcount + 1 + 1) * sizeof (char *));
707 1.1 christos if (new_gl_pathv == NULL)
708 1.1 christos {
709 1.1 christos nospace:
710 1.1 christos free (pglob->gl_pathv);
711 1.1 christos pglob->gl_pathv = NULL;
712 1.1 christos pglob->gl_pathc = 0;
713 1.1 christos return GLOB_NOSPACE;
714 1.1 christos }
715 1.1 christos pglob->gl_pathv = new_gl_pathv;
716 1.1 christos
717 1.1 christos pglob->gl_pathv[newcount] = strdup (dirname);
718 1.1 christos if (pglob->gl_pathv[newcount] == NULL)
719 1.1 christos goto nospace;
720 1.1 christos pglob->gl_pathv[++newcount] = NULL;
721 1.1 christos ++pglob->gl_pathc;
722 1.1 christos pglob->gl_flags = flags;
723 1.1 christos
724 1.1 christos return 0;
725 1.1 christos }
726 1.1 christos
727 1.1 christos /* Not found. */
728 1.1 christos return GLOB_NOMATCH;
729 1.1 christos }
730 1.1 christos
731 1.1 christos if (__glob_pattern_p (dirname, !(flags & GLOB_NOESCAPE)))
732 1.1 christos {
733 1.1 christos /* The directory name contains metacharacters, so we
734 1.1 christos have to glob for the directory, and then glob for
735 1.1 christos the pattern in each directory found. */
736 1.1 christos glob_t dirs;
737 1.1 christos size_t i;
738 1.1 christos
739 1.1 christos if ((flags & GLOB_ALTDIRFUNC) != 0)
740 1.1 christos {
741 1.1 christos /* Use the alternative access functions also in the recursive
742 1.1 christos call. */
743 1.1 christos dirs.gl_opendir = pglob->gl_opendir;
744 1.1 christos dirs.gl_readdir = pglob->gl_readdir;
745 1.1 christos dirs.gl_closedir = pglob->gl_closedir;
746 1.1 christos dirs.gl_stat = pglob->gl_stat;
747 1.1 christos dirs.gl_lstat = pglob->gl_lstat;
748 1.1 christos }
749 1.1 christos
750 1.1 christos status = glob (dirname,
751 1.1 christos ((flags & (GLOB_ERR | GLOB_NOCHECK | GLOB_NOESCAPE
752 1.1 christos | GLOB_ALTDIRFUNC))
753 1.1 christos | GLOB_NOSORT | GLOB_ONLYDIR),
754 1.1 christos errfunc, &dirs);
755 1.1 christos if (status != 0)
756 1.1 christos return status;
757 1.1 christos
758 1.1 christos /* We have successfully globbed the preceding directory name.
759 1.1 christos For each name we found, call glob_in_dir on it and FILENAME,
760 1.1 christos appending the results to PGLOB. */
761 1.1 christos for (i = 0; i < dirs.gl_pathc; ++i)
762 1.1 christos {
763 1.1 christos int old_pathc;
764 1.1 christos
765 1.1 christos #ifdef SHELL
766 1.1 christos {
767 1.1 christos /* Make globbing interruptible in the bash shell. */
768 1.1 christos extern int interrupt_state;
769 1.1 christos
770 1.1 christos if (interrupt_state)
771 1.1 christos {
772 1.1 christos globfree (&dirs);
773 1.1 christos return GLOB_ABORTED;
774 1.1 christos }
775 1.1 christos }
776 1.1 christos #endif /* SHELL. */
777 1.1 christos
778 1.1 christos old_pathc = pglob->gl_pathc;
779 1.1 christos status = glob_in_dir (filename, dirs.gl_pathv[i],
780 1.1 christos ((flags | GLOB_APPEND)
781 1.1 christos & ~(GLOB_NOCHECK | GLOB_NOMAGIC)),
782 1.1 christos errfunc, pglob);
783 1.1 christos if (status == GLOB_NOMATCH)
784 1.1 christos /* No matches in this directory. Try the next. */
785 1.1 christos continue;
786 1.1 christos
787 1.1 christos if (status != 0)
788 1.1 christos {
789 1.1 christos globfree (&dirs);
790 1.1 christos globfree (pglob);
791 1.1 christos pglob->gl_pathc = 0;
792 1.1 christos return status;
793 1.1 christos }
794 1.1 christos
795 1.1 christos /* Stick the directory on the front of each name. */
796 1.1 christos if (prefix_array (dirs.gl_pathv[i],
797 1.1 christos &pglob->gl_pathv[old_pathc + pglob->gl_offs],
798 1.1 christos pglob->gl_pathc - old_pathc))
799 1.1 christos {
800 1.1 christos globfree (&dirs);
801 1.1 christos globfree (pglob);
802 1.1 christos pglob->gl_pathc = 0;
803 1.1 christos return GLOB_NOSPACE;
804 1.1 christos }
805 1.1 christos }
806 1.1 christos
807 1.1 christos flags |= GLOB_MAGCHAR;
808 1.1 christos
809 1.1 christos /* We have ignored the GLOB_NOCHECK flag in the `glob_in_dir' calls.
810 1.1 christos But if we have not found any matching entry and the GLOB_NOCHECK
811 1.1 christos flag was set we must return the input pattern itself. */
812 1.1 christos if (pglob->gl_pathc + pglob->gl_offs == oldcount)
813 1.1 christos {
814 1.1 christos /* No matches. */
815 1.1 christos if (flags & GLOB_NOCHECK)
816 1.1 christos {
817 1.1 christos int newcount = pglob->gl_pathc + pglob->gl_offs;
818 1.1 christos char **new_gl_pathv;
819 1.1 christos
820 1.1 christos new_gl_pathv = realloc (pglob->gl_pathv,
821 1.1 christos (newcount + 2) * sizeof (char *));
822 1.1 christos if (new_gl_pathv == NULL)
823 1.1 christos {
824 1.1 christos globfree (&dirs);
825 1.1 christos return GLOB_NOSPACE;
826 1.1 christos }
827 1.1 christos pglob->gl_pathv = new_gl_pathv;
828 1.1 christos
829 1.1 christos pglob->gl_pathv[newcount] = strdup (pattern);
830 1.1 christos if (pglob->gl_pathv[newcount] == NULL)
831 1.1 christos {
832 1.1 christos globfree (&dirs);
833 1.1 christos globfree (pglob);
834 1.1 christos pglob->gl_pathc = 0;
835 1.1 christos return GLOB_NOSPACE;
836 1.1 christos }
837 1.1 christos
838 1.1 christos ++pglob->gl_pathc;
839 1.1 christos ++newcount;
840 1.1 christos
841 1.1 christos pglob->gl_pathv[newcount] = NULL;
842 1.1 christos pglob->gl_flags = flags;
843 1.1 christos }
844 1.1 christos else
845 1.1 christos {
846 1.1 christos globfree (&dirs);
847 1.1 christos return GLOB_NOMATCH;
848 1.1 christos }
849 1.1 christos }
850 1.1 christos
851 1.1 christos globfree (&dirs);
852 1.1 christos }
853 1.1 christos else
854 1.1 christos {
855 1.1 christos int old_pathc = pglob->gl_pathc;
856 1.1 christos
857 1.1 christos status = glob_in_dir (filename, dirname, flags, errfunc, pglob);
858 1.1 christos if (status != 0)
859 1.1 christos return status;
860 1.1 christos
861 1.1 christos if (dirlen > 0)
862 1.1 christos {
863 1.1 christos /* Stick the directory on the front of each name. */
864 1.1 christos if (prefix_array (dirname,
865 1.1 christos &pglob->gl_pathv[old_pathc + pglob->gl_offs],
866 1.1 christos pglob->gl_pathc - old_pathc))
867 1.1 christos {
868 1.1 christos globfree (pglob);
869 1.1 christos pglob->gl_pathc = 0;
870 1.1 christos return GLOB_NOSPACE;
871 1.1 christos }
872 1.1 christos }
873 1.1 christos }
874 1.1 christos
875 1.1 christos if (!(flags & GLOB_NOSORT))
876 1.1 christos {
877 1.1 christos /* Sort the vector. */
878 1.1 christos qsort (&pglob->gl_pathv[oldcount],
879 1.1 christos pglob->gl_pathc + pglob->gl_offs - oldcount,
880 1.1 christos sizeof (char *), collated_compare);
881 1.1 christos }
882 1.1 christos
883 1.1 christos return 0;
884 1.1 christos }
885 1.1 christos #if defined _LIBC && !defined glob
886 1.1 christos libc_hidden_def (glob)
887 1.1 christos #endif
888 1.1 christos
889 1.1 christos
890 1.1 christos #if !defined _LIBC || !defined GLOB_ONLY_P
891 1.1 christos
892 1.1 christos /* Free storage allocated in PGLOB by a previous `glob' call. */
893 1.1 christos void
894 1.1 christos globfree (pglob)
895 1.1 christos register glob_t *pglob;
896 1.1 christos {
897 1.1 christos if (pglob->gl_pathv != NULL)
898 1.1 christos {
899 1.1 christos size_t i;
900 1.1 christos for (i = 0; i < pglob->gl_pathc; ++i)
901 1.1 christos if (pglob->gl_pathv[pglob->gl_offs + i] != NULL)
902 1.1 christos free (pglob->gl_pathv[pglob->gl_offs + i]);
903 1.1 christos free (pglob->gl_pathv);
904 1.1 christos pglob->gl_pathv = NULL;
905 1.1 christos }
906 1.1 christos }
907 1.1 christos #if defined _LIBC && !defined globfree
908 1.1 christos libc_hidden_def (globfree)
909 1.1 christos #endif
910 1.1 christos
911 1.1 christos
912 1.1 christos /* Do a collated comparison of A and B. */
913 1.1 christos static int
914 1.1 christos collated_compare (const void *a, const void *b)
915 1.1 christos {
916 1.1 christos const char *const s1 = *(const char *const * const) a;
917 1.1 christos const char *const s2 = *(const char *const * const) b;
918 1.1 christos
919 1.1 christos if (s1 == s2)
920 1.1 christos return 0;
921 1.1 christos if (s1 == NULL)
922 1.1 christos return 1;
923 1.1 christos if (s2 == NULL)
924 1.1 christos return -1;
925 1.1 christos return strcoll (s1, s2);
926 1.1 christos }
927 1.1 christos
928 1.1 christos
929 1.1 christos /* Prepend DIRNAME to each of N members of ARRAY, replacing ARRAY's
930 1.1 christos elements in place. Return nonzero if out of memory, zero if successful.
931 1.1 christos A slash is inserted between DIRNAME and each elt of ARRAY,
932 1.1 christos unless DIRNAME is just "/". Each old element of ARRAY is freed. */
933 1.1 christos static int
934 1.1 christos prefix_array (const char *dirname, char **array, size_t n)
935 1.1 christos {
936 1.1 christos register size_t i;
937 1.1 christos size_t dirlen = strlen (dirname);
938 1.1 christos #if defined __MSDOS__ || defined WINDOWS32
939 1.1 christos int sep_char = '/';
940 1.1 christos # define DIRSEP_CHAR sep_char
941 1.1 christos #else
942 1.1 christos # define DIRSEP_CHAR '/'
943 1.1 christos #endif
944 1.1 christos
945 1.1 christos if (dirlen == 1 && dirname[0] == '/')
946 1.1 christos /* DIRNAME is just "/", so normal prepending would get us "//foo".
947 1.1 christos We want "/foo" instead, so don't prepend any chars from DIRNAME. */
948 1.1 christos dirlen = 0;
949 1.1 christos #if defined __MSDOS__ || defined WINDOWS32
950 1.1 christos else if (dirlen > 1)
951 1.1 christos {
952 1.1 christos if (dirname[dirlen - 1] == '/' && dirname[dirlen - 2] == ':')
953 1.1 christos /* DIRNAME is "d:/". Don't prepend the slash from DIRNAME. */
954 1.1 christos --dirlen;
955 1.1 christos else if (dirname[dirlen - 1] == ':')
956 1.1 christos {
957 1.1 christos /* DIRNAME is "d:". Use `:' instead of `/'. */
958 1.1 christos --dirlen;
959 1.1 christos sep_char = ':';
960 1.1 christos }
961 1.1 christos }
962 1.1 christos #endif
963 1.1 christos
964 1.1 christos for (i = 0; i < n; ++i)
965 1.1 christos {
966 1.1 christos size_t eltlen = strlen (array[i]) + 1;
967 1.1 christos char *new = malloc (dirlen + 1 + eltlen);
968 1.1 christos if (new == NULL)
969 1.1 christos {
970 1.1 christos while (i > 0)
971 1.1 christos free (array[--i]);
972 1.1 christos return 1;
973 1.1 christos }
974 1.1 christos
975 1.1 christos {
976 1.1 christos char *endp = mempcpy (new, dirname, dirlen);
977 1.1 christos *endp++ = DIRSEP_CHAR;
978 1.1 christos mempcpy (endp, array[i], eltlen);
979 1.1 christos }
980 1.1 christos free (array[i]);
981 1.1 christos array[i] = new;
982 1.1 christos }
983 1.1 christos
984 1.1 christos return 0;
985 1.1 christos }
986 1.1 christos
987 1.1 christos
988 1.1 christos /* We must not compile this function twice. */
989 1.1 christos #if !defined _LIBC || !defined NO_GLOB_PATTERN_P
990 1.1 christos /* Return nonzero if PATTERN contains any metacharacters.
991 1.1 christos Metacharacters can be quoted with backslashes if QUOTE is nonzero. */
992 1.1 christos int
993 1.1 christos __glob_pattern_p (pattern, quote)
994 1.1 christos const char *pattern;
995 1.1 christos int quote;
996 1.1 christos {
997 1.1 christos register const char *p;
998 1.1 christos int open = 0;
999 1.1 christos
1000 1.1 christos for (p = pattern; *p != '\0'; ++p)
1001 1.1 christos switch (*p)
1002 1.1 christos {
1003 1.1 christos case '?':
1004 1.1 christos case '*':
1005 1.1 christos return 1;
1006 1.1 christos
1007 1.1 christos case '\\':
1008 1.1 christos if (quote && p[1] != '\0')
1009 1.1 christos ++p;
1010 1.1 christos break;
1011 1.1 christos
1012 1.1 christos case '[':
1013 1.1 christos open = 1;
1014 1.1 christos break;
1015 1.1 christos
1016 1.1 christos case ']':
1017 1.1 christos if (open)
1018 1.1 christos return 1;
1019 1.1 christos break;
1020 1.1 christos }
1021 1.1 christos
1022 1.1 christos return 0;
1023 1.1 christos }
1024 1.1 christos # ifdef _LIBC
1025 1.1 christos weak_alias (__glob_pattern_p, glob_pattern_p)
1026 1.1 christos # endif
1027 1.1 christos #endif
1028 1.1 christos
1029 1.1 christos #endif /* !GLOB_ONLY_P */
1030 1.1 christos
1031 1.1 christos
1032 1.1 christos /* We put this in a separate function mainly to allow the memory
1033 1.1 christos allocated with alloca to be recycled. */
1034 1.1 christos #if !defined _LIBC || !defined GLOB_ONLY_P
1035 1.1 christos static bool
1036 1.1 christos is_dir_p (const char *dir, size_t dirlen, const char *fname,
1037 1.1 christos glob_t *pglob, int flags)
1038 1.1 christos {
1039 1.1 christos size_t fnamelen = strlen (fname);
1040 1.1 christos char *fullname = __alloca (dirlen + 1 + fnamelen + 1);
1041 1.1 christos struct stat st;
1042 1.1 christos struct_stat64 st64;
1043 1.1 christos
1044 1.1 christos mempcpy (mempcpy (mempcpy (fullname, dir, dirlen), "/", 1),
1045 1.1 christos fname, fnamelen + 1);
1046 1.1 christos
1047 1.1 christos return ((flags & GLOB_ALTDIRFUNC)
1048 1.1 christos ? (*pglob->gl_stat) (fullname, &st) == 0 && S_ISDIR (st.st_mode)
1049 1.1 christos : __stat64 (fullname, &st64) == 0 && S_ISDIR (st64.st_mode));
1050 1.1 christos }
1051 1.1 christos #endif
1052 1.1 christos
1053 1.1 christos
1054 1.1 christos /* Like `glob', but PATTERN is a final pathname component,
1055 1.1 christos and matches are searched for in DIRECTORY.
1056 1.1 christos The GLOB_NOSORT bit in FLAGS is ignored. No sorting is ever done.
1057 1.1 christos The GLOB_APPEND flag is assumed to be set (always appends). */
1058 1.1 christos static int
1059 1.1 christos glob_in_dir (const char *pattern, const char *directory, int flags,
1060 1.1 christos int (*errfunc) (const char *, int),
1061 1.1 christos glob_t *pglob)
1062 1.1 christos {
1063 1.1 christos size_t dirlen = strlen (directory);
1064 1.1 christos void *stream = NULL;
1065 1.1 christos struct globlink
1066 1.1 christos {
1067 1.1 christos struct globlink *next;
1068 1.1 christos char *name;
1069 1.1 christos };
1070 1.1 christos struct globlink *names = NULL;
1071 1.1 christos size_t nfound;
1072 1.1 christos int meta;
1073 1.1 christos int save;
1074 1.1 christos
1075 1.1 christos meta = __glob_pattern_p (pattern, !(flags & GLOB_NOESCAPE));
1076 1.1 christos if (meta == 0 && (flags & (GLOB_NOCHECK|GLOB_NOMAGIC)))
1077 1.1 christos {
1078 1.1 christos /* We need not do any tests. The PATTERN contains no meta
1079 1.1 christos characters and we must not return an error therefore the
1080 1.1 christos result will always contain exactly one name. */
1081 1.1 christos flags |= GLOB_NOCHECK;
1082 1.1 christos nfound = 0;
1083 1.1 christos }
1084 1.1 christos else if (meta == 0 &&
1085 1.1 christos ((flags & GLOB_NOESCAPE) || strchr (pattern, '\\') == NULL))
1086 1.1 christos {
1087 1.1 christos /* Since we use the normal file functions we can also use stat()
1088 1.1 christos to verify the file is there. */
1089 1.1 christos struct stat st;
1090 1.1 christos struct_stat64 st64;
1091 1.1 christos size_t patlen = strlen (pattern);
1092 1.1 christos char *fullname = __alloca (dirlen + 1 + patlen + 1);
1093 1.1 christos
1094 1.1 christos mempcpy (mempcpy (mempcpy (fullname, directory, dirlen),
1095 1.1 christos "/", 1),
1096 1.1 christos pattern, patlen + 1);
1097 1.1 christos if (((flags & GLOB_ALTDIRFUNC)
1098 1.1 christos ? (*pglob->gl_stat) (fullname, &st)
1099 1.1 christos : __stat64 (fullname, &st64)) == 0)
1100 1.1 christos /* We found this file to be existing. Now tell the rest
1101 1.1 christos of the function to copy this name into the result. */
1102 1.1 christos flags |= GLOB_NOCHECK;
1103 1.1 christos
1104 1.1 christos nfound = 0;
1105 1.1 christos }
1106 1.1 christos else
1107 1.1 christos {
1108 1.1 christos if (pattern[0] == '\0')
1109 1.1 christos {
1110 1.1 christos /* This is a special case for matching directories like in
1111 1.1 christos "*a/". */
1112 1.1 christos names = __alloca (sizeof (struct globlink));
1113 1.1 christos names->name = malloc (1);
1114 1.1 christos if (names->name == NULL)
1115 1.1 christos goto memory_error;
1116 1.1 christos names->name[0] = '\0';
1117 1.1 christos names->next = NULL;
1118 1.1 christos nfound = 1;
1119 1.1 christos meta = 0;
1120 1.1 christos }
1121 1.1 christos else
1122 1.1 christos {
1123 1.1 christos stream = ((flags & GLOB_ALTDIRFUNC)
1124 1.1 christos ? (*pglob->gl_opendir) (directory)
1125 1.1 christos : opendir (directory));
1126 1.1 christos if (stream == NULL)
1127 1.1 christos {
1128 1.1 christos if (errno != ENOTDIR
1129 1.1 christos && ((errfunc != NULL && (*errfunc) (directory, errno))
1130 1.1 christos || (flags & GLOB_ERR)))
1131 1.1 christos return GLOB_ABORTED;
1132 1.1 christos nfound = 0;
1133 1.1 christos meta = 0;
1134 1.1 christos }
1135 1.1 christos else
1136 1.1 christos {
1137 1.1 christos int fnm_flags = ((!(flags & GLOB_PERIOD) ? FNM_PERIOD : 0)
1138 1.1 christos | ((flags & GLOB_NOESCAPE) ? FNM_NOESCAPE : 0)
1139 1.1 christos #if defined _AMIGA || defined VMS
1140 1.1 christos | FNM_CASEFOLD
1141 1.1 christos #endif
1142 1.1 christos );
1143 1.1 christos nfound = 0;
1144 1.1 christos flags |= GLOB_MAGCHAR;
1145 1.1 christos
1146 1.1 christos while (1)
1147 1.1 christos {
1148 1.1 christos const char *name;
1149 1.1 christos size_t len;
1150 1.1 christos #if defined _LIBC && !defined COMPILE_GLOB64
1151 1.1 christos struct dirent64 *d;
1152 1.1 christos union
1153 1.1 christos {
1154 1.1 christos struct dirent64 d64;
1155 1.1 christos char room [offsetof (struct dirent64, d_name[0])
1156 1.1 christos + NAME_MAX + 1];
1157 1.1 christos }
1158 1.1 christos d64buf;
1159 1.1 christos
1160 1.1 christos if (flags & GLOB_ALTDIRFUNC)
1161 1.1 christos {
1162 1.1 christos struct dirent *d32 = (*pglob->gl_readdir) (stream);
1163 1.1 christos if (d32 != NULL)
1164 1.1 christos {
1165 1.1 christos CONVERT_DIRENT_DIRENT64 (&d64buf.d64, d32);
1166 1.1 christos d = &d64buf.d64;
1167 1.1 christos }
1168 1.1 christos else
1169 1.1 christos d = NULL;
1170 1.1 christos }
1171 1.1 christos else
1172 1.1 christos d = __readdir64 (stream);
1173 1.1 christos #else
1174 1.1 christos struct dirent *d = ((flags & GLOB_ALTDIRFUNC)
1175 1.1 christos ? ((*pglob->gl_readdir) (stream))
1176 1.1 christos : __readdir (stream));
1177 1.1 christos #endif
1178 1.1 christos if (d == NULL)
1179 1.1 christos break;
1180 1.1 christos if (! REAL_DIR_ENTRY (d))
1181 1.1 christos continue;
1182 1.1 christos
1183 1.1 christos /* If we shall match only directories use the information
1184 1.1 christos provided by the dirent call if possible. */
1185 1.1 christos if ((flags & GLOB_ONLYDIR) && !DIRENT_MIGHT_BE_DIR (d))
1186 1.1 christos continue;
1187 1.1 christos
1188 1.1 christos name = d->d_name;
1189 1.1 christos
1190 1.1 christos if (fnmatch (pattern, name, fnm_flags) == 0)
1191 1.1 christos {
1192 1.1 christos /* ISDIR will often be incorrectly set to false
1193 1.1 christos when not in GLOB_ONLYDIR || GLOB_MARK mode, but we
1194 1.1 christos don't care. It won't be used and we save the
1195 1.1 christos expensive call to stat. */
1196 1.1 christos int need_dir_test =
1197 1.1 christos (GLOB_MARK | (DIRENT_MIGHT_BE_SYMLINK (d)
1198 1.1 christos ? GLOB_ONLYDIR : 0));
1199 1.1 christos bool isdir = (DIRENT_MUST_BE (d, DT_DIR)
1200 1.1 christos || ((flags & need_dir_test)
1201 1.1 christos && is_dir_p (directory, dirlen, name,
1202 1.1 christos pglob, flags)));
1203 1.1 christos
1204 1.1 christos /* In GLOB_ONLYDIR mode, skip non-dirs. */
1205 1.1 christos if ((flags & GLOB_ONLYDIR) && !isdir)
1206 1.1 christos continue;
1207 1.1 christos
1208 1.1 christos {
1209 1.1 christos struct globlink *new =
1210 1.1 christos __alloca (sizeof (struct globlink));
1211 1.1 christos char *p;
1212 1.1 christos len = NAMLEN (d);
1213 1.1 christos new->name =
1214 1.1 christos malloc (len + 1 + ((flags & GLOB_MARK) && isdir));
1215 1.1 christos if (new->name == NULL)
1216 1.1 christos goto memory_error;
1217 1.1 christos p = mempcpy (new->name, name, len);
1218 1.1 christos if ((flags & GLOB_MARK) && isdir)
1219 1.1 christos *p++ = '/';
1220 1.1 christos *p = '\0';
1221 1.1 christos new->next = names;
1222 1.1 christos names = new;
1223 1.1 christos ++nfound;
1224 1.1 christos }
1225 1.1 christos }
1226 1.1 christos }
1227 1.1 christos }
1228 1.1 christos }
1229 1.1 christos }
1230 1.1 christos
1231 1.1 christos if (nfound == 0 && (flags & GLOB_NOCHECK))
1232 1.1 christos {
1233 1.1 christos size_t len = strlen (pattern);
1234 1.1 christos nfound = 1;
1235 1.1 christos names = __alloca (sizeof (struct globlink));
1236 1.1 christos names->next = NULL;
1237 1.1 christos names->name = malloc (len + 1);
1238 1.1 christos if (names->name == NULL)
1239 1.1 christos goto memory_error;
1240 1.1 christos *((char *) mempcpy (names->name, pattern, len)) = '\0';
1241 1.1 christos }
1242 1.1 christos
1243 1.1 christos if (nfound != 0)
1244 1.1 christos {
1245 1.1 christos char **new_gl_pathv;
1246 1.1 christos
1247 1.1 christos new_gl_pathv
1248 1.1 christos = realloc (pglob->gl_pathv,
1249 1.1 christos (pglob->gl_pathc + pglob->gl_offs + nfound + 1)
1250 1.1 christos * sizeof (char *));
1251 1.1 christos if (new_gl_pathv == NULL)
1252 1.1 christos goto memory_error;
1253 1.1 christos pglob->gl_pathv = new_gl_pathv;
1254 1.1 christos
1255 1.1 christos for (; names != NULL; names = names->next)
1256 1.1 christos pglob->gl_pathv[pglob->gl_offs + pglob->gl_pathc++] = names->name;
1257 1.1 christos pglob->gl_pathv[pglob->gl_offs + pglob->gl_pathc] = NULL;
1258 1.1 christos
1259 1.1 christos pglob->gl_flags = flags;
1260 1.1 christos }
1261 1.1 christos
1262 1.1 christos save = errno;
1263 1.1 christos if (stream != NULL)
1264 1.1 christos {
1265 1.1 christos if (flags & GLOB_ALTDIRFUNC)
1266 1.1 christos (*pglob->gl_closedir) (stream);
1267 1.1 christos else
1268 1.1 christos closedir (stream);
1269 1.1 christos }
1270 1.1 christos __set_errno (save);
1271 1.1 christos
1272 1.1 christos return nfound == 0 ? GLOB_NOMATCH : 0;
1273 1.1 christos
1274 1.1 christos memory_error:
1275 1.1 christos {
1276 1.1 christos int save = errno;
1277 1.1 christos if (flags & GLOB_ALTDIRFUNC)
1278 1.1 christos (*pglob->gl_closedir) (stream);
1279 1.1 christos else
1280 1.1 christos closedir (stream);
1281 1.1 christos __set_errno (save);
1282 1.1 christos }
1283 1.1 christos while (names != NULL)
1284 1.1 christos {
1285 1.1 christos if (names->name != NULL)
1286 1.1 christos free (names->name);
1287 1.1 christos names = names->next;
1288 1.1 christos }
1289 1.1 christos return GLOB_NOSPACE;
1290 }
1291