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