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