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