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