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