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