Update.
[platform/upstream/glibc.git] / posix / glob.c
1 /* Copyright (C) 1991, 92, 93, 94, 95, 96, 97 Free Software Foundation, Inc.
2
3    This library is free software; you can redistribute it and/or
4    modify it under the terms of the GNU Library General Public License as
5    published by the Free Software Foundation; either version 2 of the
6    License, or (at your option) any later version.
7
8    This library is distributed in the hope that it will be useful,
9    but WITHOUT ANY WARRANTY; without even the implied warranty of
10    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11    Library General Public License for more details.
12
13    You should have received a copy of the GNU Library General Public
14    License along with this library; see the file COPYING.LIB.  If not,
15    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
16    Boston, MA 02111-1307, USA.  */
17
18 /* AIX requires this to be the first thing in the file.  */
19 #if defined _AIX && !defined __GNUC__
20  #pragma alloca
21 #endif
22
23 #ifdef  HAVE_CONFIG_H
24 # include <config.h>
25 #endif
26
27 /* Enable GNU extensions in glob.h.  */
28 #ifndef _GNU_SOURCE
29 # define _GNU_SOURCE    1
30 #endif
31
32 #include <errno.h>
33 #include <sys/types.h>
34 #include <sys/stat.h>
35
36 /* Outcomment the following line for production quality code.  */
37 /* #define NDEBUG 1 */
38 #include <assert.h>
39
40 #include <stdio.h>              /* Needed on stupid SunOS for assert.  */
41
42
43 /* Comment out all this code if we are using the GNU C Library, and are not
44    actually compiling the library itself.  This code is part of the GNU C
45    Library, but also included in many other GNU distributions.  Compiling
46    and linking in this code is a waste when using the GNU C library
47    (especially if it is a shared library).  Rather than having every GNU
48    program understand `configure --with-gnu-libc' and omit the object files,
49    it is simpler to just do this in the source for each such file.  */
50
51 #define GLOB_INTERFACE_VERSION 1
52 #if !defined _LIBC && defined __GNU_LIBRARY__ && __GNU_LIBRARY__ > 1
53 # include <gnu-versions.h>
54 # if _GNU_GLOB_INTERFACE_VERSION == GLOB_INTERFACE_VERSION
55 #  define ELIDE_CODE
56 # endif
57 #endif
58
59 #ifndef ELIDE_CODE
60
61 #if defined STDC_HEADERS || defined __GNU_LIBRARY__
62 # include <stddef.h>
63 #endif
64
65 #if defined HAVE_UNISTD_H || defined _LIBC
66 # include <unistd.h>
67 # ifndef POSIX
68 #  ifdef _POSIX_VERSION
69 #   define POSIX
70 #  endif
71 # endif
72 #endif
73
74 #if !defined _AMIGA && !defined VMS && !defined WINDOWS32
75 # include <pwd.h>
76 #endif
77
78 #if !defined __GNU_LIBRARY__ && !defined STDC_HEADERS
79 extern int errno;
80 #endif
81 #ifndef __set_errno
82 # define __set_errno(val) errno = (val)
83 #endif
84
85 #ifndef NULL
86 # define NULL   0
87 #endif
88
89
90 #if defined HAVE_DIRENT_H || defined __GNU_LIBRARY__
91 # include <dirent.h>
92 # define NAMLEN(dirent) strlen((dirent)->d_name)
93 #else
94 # define dirent direct
95 # define NAMLEN(dirent) (dirent)->d_namlen
96 # ifdef HAVE_SYS_NDIR_H
97 #  include <sys/ndir.h>
98 # endif
99 # ifdef HAVE_SYS_DIR_H
100 #  include <sys/dir.h>
101 # endif
102 # ifdef HAVE_NDIR_H
103 #  include <ndir.h>
104 # endif
105 # ifdef HAVE_VMSDIR_H
106 #  include "vmsdir.h"
107 # endif /* HAVE_VMSDIR_H */
108 #endif
109
110
111 /* In GNU systems, <dirent.h> defines this macro for us.  */
112 #ifdef _D_NAMLEN
113 # undef NAMLEN
114 # define NAMLEN(d) _D_NAMLEN(d)
115 #endif
116
117
118 #if (defined POSIX || defined WINDOWS32) && !defined __GNU_LIBRARY__
119 /* Posix does not require that the d_ino field be present, and some
120    systems do not provide it. */
121 # define REAL_DIR_ENTRY(dp) 1
122 #else
123 # define REAL_DIR_ENTRY(dp) (dp->d_ino != 0)
124 #endif /* POSIX */
125
126 #if defined STDC_HEADERS || defined __GNU_LIBRARY__
127 # include <stdlib.h>
128 # include <string.h>
129 # define        ANSI_STRING
130 #else   /* No standard headers.  */
131
132 extern char *getenv ();
133
134 # ifdef HAVE_STRING_H
135 #  include <string.h>
136 #  define ANSI_STRING
137 # else
138 #  include <strings.h>
139 # endif
140 # ifdef HAVE_MEMORY_H
141 #  include <memory.h>
142 # endif
143
144 extern char *malloc (), *realloc ();
145 extern void free ();
146
147 extern void qsort ();
148 extern void abort (), exit ();
149
150 #endif  /* Standard headers.  */
151
152 #ifndef ANSI_STRING
153
154 # ifndef bzero
155 extern void bzero ();
156 # endif
157 # ifndef bcopy
158 extern void bcopy ();
159 # endif
160
161 # define memcpy(d, s, n)        bcopy ((s), (d), (n))
162 # define strrchr        rindex
163 /* memset is only used for zero here, but let's be paranoid.  */
164 # define memset(s, better_be_zero, n) \
165   ((void) ((better_be_zero) == 0 ? (bzero((s), (n)), 0) : (abort(), 0)))
166 #endif  /* Not ANSI_STRING.  */
167
168 #if !defined HAVE_STRCOLL && !defined _LIBC
169 # define strcoll        strcmp
170 #endif
171
172 #if !defined HAVE_MEMPCPY && __GLIBC__ - 0 == 2 && __GLIBC_MINOR__ >= 1
173 # define HAVE_MEMPCPY   1
174 # define mempcpy(Dest, Src, Len) __mempcpy (Dest, Src, Len)
175 #endif
176
177
178 #ifndef __GNU_LIBRARY__
179 # ifdef __GNUC__
180 __inline
181 # endif
182 # ifndef __SASC
183 #  ifdef WINDOWS32
184 static void *
185 #  else
186 static char *
187 # endif
188 my_realloc (p, n)
189      char *p;
190      unsigned int n;
191 {
192   /* These casts are the for sake of the broken Ultrix compiler,
193      which warns of illegal pointer combinations otherwise.  */
194   if (p == NULL)
195     return (char *) malloc (n);
196   return (char *) realloc (p, n);
197 }
198 # define        realloc my_realloc
199 # endif /* __SASC */
200 #endif /* __GNU_LIBRARY__ */
201
202
203 #if !defined __alloca && !defined __GNU_LIBRARY__
204
205 # ifdef __GNUC__
206 #  undef alloca
207 #  define alloca(n)     __builtin_alloca (n)
208 # else  /* Not GCC.  */
209 #  ifdef HAVE_ALLOCA_H
210 #   include <alloca.h>
211 #  else /* Not HAVE_ALLOCA_H.  */
212 #   ifndef _AIX
213 #    ifdef WINDOWS32
214 #     include <malloc.h>
215 #    else
216 extern char *alloca ();
217 #    endif /* WINDOWS32 */
218 #   endif /* Not _AIX.  */
219 #  endif /* sparc or HAVE_ALLOCA_H.  */
220 # endif /* GCC.  */
221
222 # define __alloca       alloca
223
224 #endif
225
226 #ifndef __GNU_LIBRARY__
227 # define __stat stat
228 # ifdef STAT_MACROS_BROKEN
229 #  undef S_ISDIR
230 # endif
231 # ifndef S_ISDIR
232 #  define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
233 # endif
234 #endif
235
236 #if !(defined STDC_HEADERS || defined __GNU_LIBRARY__)
237 # undef size_t
238 # define size_t unsigned int
239 #endif
240
241 /* Some system header files erroneously define these.
242    We want our own definitions from <fnmatch.h> to take precedence.  */
243 #undef  FNM_PATHNAME
244 #undef  FNM_NOESCAPE
245 #undef  FNM_PERIOD
246 #include <fnmatch.h>
247
248 /* Some system header files erroneously define these.
249    We want our own definitions from <glob.h> to take precedence.  */
250 #undef  GLOB_ERR
251 #undef  GLOB_MARK
252 #undef  GLOB_NOSORT
253 #undef  GLOB_DOOFFS
254 #undef  GLOB_NOCHECK
255 #undef  GLOB_APPEND
256 #undef  GLOB_NOESCAPE
257 #undef  GLOB_PERIOD
258 #include <glob.h>
259 \f
260 static
261 #if __GNUC__ - 0 >= 2
262 inline
263 #endif
264 const char *next_brace_sub __P ((const char *begin));
265 static int glob_in_dir __P ((const char *pattern, const char *directory,
266                              int flags,
267                              int (*errfunc) __P ((const char *, int)),
268                              glob_t *pglob));
269 static int prefix_array __P ((const char *prefix, char **array, size_t n));
270 static int collated_compare __P ((const __ptr_t, const __ptr_t));
271
272
273 /* Find the end of the sub-pattern in a brace expression.  We define
274    this as an inline function if the compiler permits.  */
275 static
276 #if __GNUC__ - 0 >= 2
277 inline
278 #endif
279 const char *
280 next_brace_sub (begin)
281      const char *begin;
282 {
283   unsigned int depth = 0;
284   const char *cp = begin;
285
286   while (1)
287     {
288       if (depth == 0)
289         {
290           if (*cp != ',' && *cp != '}' && *cp != '\0')
291             {
292               if (*cp == '{')
293                 ++depth;
294               ++cp;
295               continue;
296             }
297         }
298       else
299         {
300           while (*cp != '\0' && (*cp != '}' || depth > 0))
301             {
302               if (*cp == '}')
303                 --depth;
304               ++cp;
305             }
306           if (*cp == '\0')
307             /* An incorrectly terminated brace expression.  */
308             return NULL;
309
310           continue;
311         }
312       break;
313     }
314
315   return cp;
316 }
317
318 /* Do glob searching for PATTERN, placing results in PGLOB.
319    The bits defined above may be set in FLAGS.
320    If a directory cannot be opened or read and ERRFUNC is not nil,
321    it is called with the pathname that caused the error, and the
322    `errno' value from the failing call; if it returns non-zero
323    `glob' returns GLOB_ABORTED; if it returns zero, the error is ignored.
324    If memory cannot be allocated for PGLOB, GLOB_NOSPACE is returned.
325    Otherwise, `glob' returns zero.  */
326 int
327 glob (pattern, flags, errfunc, pglob)
328      const char *pattern;
329      int flags;
330      int (*errfunc) __P ((const char *, int));
331      glob_t *pglob;
332 {
333   const char *filename;
334   char *dirname;
335   size_t dirlen;
336   int status;
337   int oldcount;
338
339   if (pattern == NULL || pglob == NULL || (flags & ~__GLOB_FLAGS) != 0)
340     {
341       __set_errno (EINVAL);
342       return -1;
343     }
344
345   if (flags & GLOB_BRACE)
346     {
347       const char *begin = strchr (pattern, '{');
348       if (begin != NULL)
349         {
350           /* Allocate working buffer large enough for our work.  Note that
351             we have at least an opening and closing brace.  */
352           int firstc;
353           char *alt_start;
354           const char *p;
355           const char *next;
356           const char *rest;
357           size_t rest_len;
358 #ifdef __GNUC__
359           char onealt[strlen (pattern) - 1];
360 #else
361           char *onealt = (char *) malloc (strlen (pattern) - 1);
362           if (onealt == NULL)
363             {
364               if (!(flags & GLOB_APPEND))
365                 globfree (pglob);
366               return GLOB_NOSPACE;
367             }
368 #endif
369
370           /* We know the prefix for all sub-patterns.  */
371           memcpy (onealt, pattern, begin - pattern);
372           alt_start = &onealt[begin - pattern];
373
374           /* Find the first sub-pattern and at the same time find the
375              rest after the closing brace.  */
376           next = next_brace_sub (begin + 1);
377           if (next == NULL)
378             {
379               /* It is an illegal expression.  */
380 #ifndef __GNUC__
381               free (onealt);
382 #endif
383               return glob (pattern, flags & ~GLOB_BRACE, errfunc, pglob);
384             }
385
386           /* Now find the end of the whole brace expression.  */
387           rest = next;
388           while (*rest != '}')
389             {
390               rest = next_brace_sub (rest + 1);
391               if (rest == NULL)
392                 {
393                   /* It is an illegal expression.  */
394 #ifndef __GNUC__
395                   free (onealt);
396 #endif
397                   return glob (pattern, flags & ~GLOB_BRACE, errfunc, pglob);
398                 }
399             }
400           /* Please note that we now can be sure the brace expression
401              is well-formed.  */
402           rest_len = strlen (++rest) + 1;
403
404           /* We have a brace expression.  BEGIN points to the opening {,
405              NEXT points past the terminator of the first element, and END
406              points past the final }.  We will accumulate result names from
407              recursive runs for each brace alternative in the buffer using
408              GLOB_APPEND.  */
409
410           if (!(flags & GLOB_APPEND))
411             {
412               /* This call is to set a new vector, so clear out the
413                  vector so we can append to it.  */
414               pglob->gl_pathc = 0;
415               pglob->gl_pathv = NULL;
416             }
417           firstc = pglob->gl_pathc;
418
419           p = begin + 1;
420           while (1)
421             {
422               int result;
423
424               /* Construct the new glob expression.  */
425 #ifdef HAVE_MEMPCPY
426               mempcpy (mempcpy (alt_start, p, next - p), rest, rest_len);
427 #else
428               memcpy (alt_start, p, next - p);
429               memcpy (&alt_start[next - p], rest, rest_len);
430 #endif
431
432               result = glob (onealt,
433                              ((flags & ~(GLOB_NOCHECK|GLOB_NOMAGIC))
434                               | GLOB_APPEND), errfunc, pglob);
435
436               /* If we got an error, return it.  */
437               if (result && result != GLOB_NOMATCH)
438                 {
439 #ifndef __GNUC__
440                   free (onealt);
441 #endif
442                   if (!(flags & GLOB_APPEND))
443                     globfree (pglob);
444                   return result;
445                 }
446
447               if (*next == '}')
448                 /* We saw the last entry.  */
449                 break;
450
451               p = next + 1;
452               next = next_brace_sub (p);
453               assert (next != NULL);
454             }
455
456 #ifndef __GNUC__
457           free (onealt);
458 #endif
459
460           if (pglob->gl_pathc != firstc)
461             /* We found some entries.  */
462             return 0;
463           else if (!(flags & (GLOB_NOCHECK|GLOB_NOMAGIC)))
464             return GLOB_NOMATCH;
465         }
466     }
467
468   /* Find the filename.  */
469   filename = strrchr (pattern, '/');
470   if (filename == NULL)
471     {
472       filename = pattern;
473 #ifdef _AMIGA
474       dirname = (char *) "";
475 #else
476       dirname = (char *) ".";
477 #endif
478       dirlen = 0;
479     }
480   else if (filename == pattern)
481     {
482       /* "/pattern".  */
483       dirname = (char *) "/";
484       dirlen = 1;
485       ++filename;
486     }
487   else
488     {
489       dirlen = filename - pattern;
490       dirname = (char *) __alloca (dirlen + 1);
491 #ifdef HAVE_MEMPCPY
492       *((char *) mempcpy (dirname, pattern, dirlen)) = '\0';
493 #else
494       memcpy (dirname, pattern, dirlen);
495       dirname[dirlen] = '\0';
496 #endif
497       ++filename;
498     }
499
500   if (filename[0] == '\0' && dirlen > 1)
501     /* "pattern/".  Expand "pattern", appending slashes.  */
502     {
503       int val = glob (dirname, flags | GLOB_MARK, errfunc, pglob);
504       if (val == 0)
505         pglob->gl_flags = (pglob->gl_flags & ~GLOB_MARK) | (flags & GLOB_MARK);
506       return val;
507     }
508
509   if (!(flags & GLOB_APPEND))
510     {
511       pglob->gl_pathc = 0;
512       pglob->gl_pathv = NULL;
513     }
514
515   oldcount = pglob->gl_pathc;
516
517 #ifndef VMS
518   if ((flags & GLOB_TILDE) && dirname[0] == '~')
519     {
520       if (dirname[1] == '\0' || dirname[1] == '/')
521         {
522           /* Look up home directory.  */
523           char *home_dir = getenv ("HOME");
524 # ifdef _AMIGA
525           if (home_dir == NULL || home_dir[0] == '\0')
526             home_dir = "SYS:";
527 # else
528 #  ifdef WINDOWS32
529           if (home_dir == NULL || home_dir[0] == '\0')
530             home_dir = "c:/users/default"; /* poor default */
531 #  else
532           if (home_dir == NULL || home_dir[0] == '\0')
533             {
534               int success;
535 #   if defined HAVE_GETLOGIN_R || defined _LIBC
536               extern int getlogin_r __P ((char *, size_t));
537               size_t buflen = sysconf (_SC_LOGIN_NAME_MAX) + 1;
538               char *name;
539
540               if (buflen == 0)
541                 /* `sysconf' does not support _SC_LOGIN_NAME_MAX.  Try
542                    a moderate value.  */
543                 buflen = 16;
544               name = (char *) __alloca (buflen);
545
546               success = getlogin_r (name, buflen) >= 0;
547 #   else
548               extern char *getlogin __P ((void));
549               char *name;
550
551               success = (name = getlogin ()) != NULL;
552 #   endif
553               if (success)
554                 {
555 #   if defined HAVE_GETPWNAM_R || defined _LIBC
556                   size_t pwbuflen = sysconf (_SC_GETPW_R_SIZE_MAX);
557                   char *pwtmpbuf;
558                   struct passwd pwbuf, *p;
559
560                   pwtmpbuf = (char *) __alloca (pwbuflen);
561
562                   success = (__getpwnam_r (name, &pwbuf, pwtmpbuf,
563                                            pwbuflen, &p) >= 0);
564 #   else
565                   struct passwd *p = getpwnam (name);
566                   success = p != NULL;
567 #   endif
568                   if (success)
569                     home_dir = p->pw_dir;
570                 }
571             }
572           if (home_dir == NULL || home_dir[0] == '\0')
573             home_dir = (char *) "~"; /* No luck.  */
574 #  endif /* WINDOWS32 */
575 # endif
576           /* Now construct the full directory.  */
577           if (dirname[1] == '\0')
578             dirname = home_dir;
579           else
580             {
581               char *newp;
582               size_t home_len = strlen (home_dir);
583               newp = (char *) __alloca (home_len + dirlen);
584 # ifdef HAVE_MEMPCPY
585               mempcpy (mempcpy (newp, home_dir, home_len),
586                        &dirname[1], dirlen);
587 # else
588               memcpy (newp, home_dir, home_len);
589               memcpy (&newp[home_len], &dirname[1], dirlen);
590 # endif
591               dirname = newp;
592             }
593         }
594 # if !defined _AMIGA && !defined WINDOWS32
595       else
596         {
597           char *end_name = strchr (dirname, '/');
598           char *user_name;
599           char *home_dir;
600
601           if (end_name == NULL)
602             user_name = dirname + 1;
603           else
604             {
605               user_name = (char *) __alloca (end_name - dirname);
606 # ifdef HAVE_MEMPCPY
607               *((char *) mempcpy (user_name, dirname + 1, end_name - dirname))
608                 = '\0';
609 # else
610               memcpy (user_name, dirname + 1, end_name - dirname);
611               user_name[end_name - dirname - 1] = '\0';
612 # endif
613             }
614
615           /* Look up specific user's home directory.  */
616           {
617 #  if defined HAVE_GETPWNAM_R || defined _LIBC
618             size_t buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
619             char *pwtmpbuf = (char *) __alloca (buflen);
620             struct passwd pwbuf, *p;
621             if (__getpwnam_r (user_name, &pwbuf, pwtmpbuf, buflen, &p) >= 0)
622               home_dir = p->pw_dir;
623             else
624               home_dir = NULL;
625 #  else
626             struct passwd *p = getpwnam (user_name);
627             if (p != NULL)
628               home_dir = p->pw_dir;
629             else
630               home_dir = NULL;
631 #  endif
632           }
633           /* If we found a home directory use this.  */
634           if (home_dir != NULL)
635             {
636               char *newp;
637               size_t home_len = strlen (home_dir);
638               size_t rest_len = end_name == NULL ? 0 : strlen (end_name);
639               newp = (char *) __alloca (home_len + rest_len + 1);
640 #  ifdef HAVE_MEMPCPY
641               *((char *) mempcpy (mempcpy (newp, home_dir, home_len),
642                                   end_name, rest_len)) = '\0';
643 #  else
644               memcpy (newp, home_dir, home_len);
645               memcpy (&newp[home_len], end_name, rest_len);
646               newp[home_len + rest_len] = '\0';
647 #  endif
648               dirname = newp;
649             }
650         }
651 # endif /* Not Amiga && not WINDOWS32.  */
652     }
653 #endif  /* Not VMS.  */
654
655   if (__glob_pattern_p (dirname, !(flags & GLOB_NOESCAPE)))
656     {
657       /* The directory name contains metacharacters, so we
658          have to glob for the directory, and then glob for
659          the pattern in each directory found.  */
660       glob_t dirs;
661       register int i;
662
663       status = glob (dirname,
664                      ((flags & (GLOB_ERR | GLOB_NOCHECK | GLOB_NOESCAPE)) |
665                       GLOB_NOSORT),
666                      errfunc, &dirs);
667       if (status != 0)
668         return status;
669
670       /* We have successfully globbed the preceding directory name.
671          For each name we found, call glob_in_dir on it and FILENAME,
672          appending the results to PGLOB.  */
673       for (i = 0; i < dirs.gl_pathc; ++i)
674         {
675           int oldcount;
676
677 #ifdef  SHELL
678           {
679             /* Make globbing interruptible in the bash shell. */
680             extern int interrupt_state;
681
682             if (interrupt_state)
683               {
684                 globfree (&dirs);
685                 globfree (&files);
686                 return GLOB_ABORTED;
687               }
688           }
689 #endif /* SHELL.  */
690
691           oldcount = pglob->gl_pathc;
692           status = glob_in_dir (filename, dirs.gl_pathv[i],
693                                 (flags | GLOB_APPEND) & ~GLOB_NOCHECK,
694                                 errfunc, pglob);
695           if (status == GLOB_NOMATCH)
696             /* No matches in this directory.  Try the next.  */
697             continue;
698
699           if (status != 0)
700             {
701               globfree (&dirs);
702               globfree (pglob);
703               return status;
704             }
705
706           /* Stick the directory on the front of each name.  */
707           if (prefix_array (dirs.gl_pathv[i],
708                             &pglob->gl_pathv[oldcount],
709                             pglob->gl_pathc - oldcount))
710             {
711               globfree (&dirs);
712               globfree (pglob);
713               return GLOB_NOSPACE;
714             }
715         }
716
717       flags |= GLOB_MAGCHAR;
718
719       if (pglob->gl_pathc == oldcount)
720         /* No matches.  */
721         if (flags & GLOB_NOCHECK)
722           {
723             size_t len = strlen (pattern) + 1;
724             char *patcopy = (char *) malloc (len);
725             if (patcopy == NULL)
726               return GLOB_NOSPACE;
727             memcpy (patcopy, pattern, len);
728
729             pglob->gl_pathv
730               = (char **) realloc (pglob->gl_pathv,
731                                    (pglob->gl_pathc +
732                                     ((flags & GLOB_DOOFFS) ?
733                                      pglob->gl_offs : 0) +
734                                     1 + 1) *
735                                    sizeof (char *));
736             if (pglob->gl_pathv == NULL)
737               {
738                 free (patcopy);
739                 return GLOB_NOSPACE;
740               }
741
742             if (flags & GLOB_DOOFFS)
743               while (pglob->gl_pathc < pglob->gl_offs)
744                 pglob->gl_pathv[pglob->gl_pathc++] = NULL;
745
746             pglob->gl_pathv[pglob->gl_pathc++] = patcopy;
747             pglob->gl_pathv[pglob->gl_pathc] = NULL;
748             pglob->gl_flags = flags;
749           }
750         else
751           return GLOB_NOMATCH;
752     }
753   else
754     {
755       status = glob_in_dir (filename, dirname, flags, errfunc, pglob);
756       if (status != 0)
757         return status;
758
759       if (dirlen > 0)
760         {
761           /* Stick the directory on the front of each name.  */
762           if (prefix_array (dirname,
763                             &pglob->gl_pathv[oldcount],
764                             pglob->gl_pathc - oldcount))
765             {
766               globfree (pglob);
767               return GLOB_NOSPACE;
768             }
769         }
770     }
771
772   if (flags & GLOB_MARK)
773     {
774       /* Append slashes to directory names.  */
775       int i;
776       struct stat st;
777       for (i = oldcount; i < pglob->gl_pathc; ++i)
778         if (((flags & GLOB_ALTDIRFUNC) ?
779              (*pglob->gl_stat) (pglob->gl_pathv[i], &st) :
780              __stat (pglob->gl_pathv[i], &st)) == 0 &&
781             S_ISDIR (st.st_mode))
782           {
783             size_t len = strlen (pglob->gl_pathv[i]) + 2;
784             char *new = realloc (pglob->gl_pathv[i], len);
785             if (new == NULL)
786               {
787                 globfree (pglob);
788                 return GLOB_NOSPACE;
789               }
790             strcpy (&new[len - 2], "/");
791             pglob->gl_pathv[i] = new;
792           }
793     }
794
795   if (!(flags & GLOB_NOSORT))
796     /* Sort the vector.  */
797     qsort ((__ptr_t) &pglob->gl_pathv[oldcount],
798            pglob->gl_pathc - oldcount,
799            sizeof (char *), collated_compare);
800
801   return 0;
802 }
803
804
805 /* Free storage allocated in PGLOB by a previous `glob' call.  */
806 void
807 globfree (pglob)
808      register glob_t *pglob;
809 {
810   if (pglob->gl_pathv != NULL)
811     {
812       register int i;
813       for (i = 0; i < pglob->gl_pathc; ++i)
814         if (pglob->gl_pathv[i] != NULL)
815           free ((__ptr_t) pglob->gl_pathv[i]);
816       free ((__ptr_t) pglob->gl_pathv);
817     }
818 }
819
820
821 /* Do a collated comparison of A and B.  */
822 static int
823 collated_compare (a, b)
824      const __ptr_t a;
825      const __ptr_t b;
826 {
827   const char *const s1 = *(const char *const * const) a;
828   const char *const s2 = *(const char *const * const) b;
829
830   if (s1 == s2)
831     return 0;
832   if (s1 == NULL)
833     return 1;
834   if (s2 == NULL)
835     return -1;
836   return strcoll (s1, s2);
837 }
838
839
840 /* Prepend DIRNAME to each of N members of ARRAY, replacing ARRAY's
841    elements in place.  Return nonzero if out of memory, zero if successful.
842    A slash is inserted between DIRNAME and each elt of ARRAY,
843    unless DIRNAME is just "/".  Each old element of ARRAY is freed.  */
844 static int
845 prefix_array (dirname, array, n)
846      const char *dirname;
847      char **array;
848      size_t n;
849 {
850   register size_t i;
851   size_t dirlen = strlen (dirname);
852
853   if (dirlen == 1 && dirname[0] == '/')
854     /* DIRNAME is just "/", so normal prepending would get us "//foo".
855        We want "/foo" instead, so don't prepend any chars from DIRNAME.  */
856     dirlen = 0;
857
858   for (i = 0; i < n; ++i)
859     {
860       size_t eltlen = strlen (array[i]) + 1;
861       char *new = (char *) malloc (dirlen + 1 + eltlen);
862       if (new == NULL)
863         {
864           while (i > 0)
865             free ((__ptr_t) array[--i]);
866           return 1;
867         }
868
869 #ifdef HAVE_MEMPCPY
870       {
871         char *endp = (char *) mempcpy (new, dirname, dirlen);
872         *endp++ = '/';
873         mempcpy (endp, array[i], eltlen);
874       }
875 #else
876       memcpy (new, dirname, dirlen);
877       new[dirlen] = '/';
878       memcpy (&new[dirlen + 1], array[i], eltlen);
879 #endif
880       free ((__ptr_t) array[i]);
881       array[i] = new;
882     }
883
884   return 0;
885 }
886
887
888 /* Return nonzero if PATTERN contains any metacharacters.
889    Metacharacters can be quoted with backslashes if QUOTE is nonzero.  */
890 int
891 __glob_pattern_p (pattern, quote)
892      const char *pattern;
893      int quote;
894 {
895   register const char *p;
896   int open = 0;
897
898   for (p = pattern; *p != '\0'; ++p)
899     switch (*p)
900       {
901       case '?':
902       case '*':
903         return 1;
904
905       case '\\':
906         if (quote && p[1] != '\0')
907           ++p;
908         break;
909
910       case '[':
911         open = 1;
912         break;
913
914       case ']':
915         if (open)
916           return 1;
917         break;
918       }
919
920   return 0;
921 }
922 #ifdef _LIBC
923 weak_alias (__glob_pattern_p, glob_pattern_p)
924 #endif
925
926
927 /* Like `glob', but PATTERN is a final pathname component,
928    and matches are searched for in DIRECTORY.
929    The GLOB_NOSORT bit in FLAGS is ignored.  No sorting is ever done.
930    The GLOB_APPEND flag is assumed to be set (always appends).  */
931 static int
932 glob_in_dir (pattern, directory, flags, errfunc, pglob)
933      const char *pattern;
934      const char *directory;
935      int flags;
936      int (*errfunc) __P ((const char *, int));
937      glob_t *pglob;
938 {
939   __ptr_t stream;
940
941   struct globlink
942     {
943       struct globlink *next;
944       char *name;
945     };
946   struct globlink *names = NULL;
947   size_t nfound = 0;
948
949   if (!__glob_pattern_p (pattern, !(flags & GLOB_NOESCAPE)))
950     {
951       /* We must check whether the file in this directory exists.  */
952       stream = ((flags & GLOB_ALTDIRFUNC) ?
953                 (*pglob->gl_opendir) (directory) :
954                 (__ptr_t) opendir (directory));
955       if (stream == NULL)
956         {
957           if ((errfunc != NULL && (*errfunc) (directory, errno)) ||
958               (flags & GLOB_ERR))
959             return GLOB_ABORTED;
960         }
961       else if (pattern[0] == '\0')
962         {
963           /* This is a special case for matching directories like in
964              "*a/".  */
965           names = (struct globlink *) __alloca (sizeof (struct globlink));
966           names->name = (char *) malloc (1);
967           if (names->name == NULL)
968             goto memory_error;
969           names->name[0] = '\0';
970           names->next = NULL;
971           nfound = 1;
972         }
973       else
974         while (1)
975           {
976             struct dirent *d = ((flags & GLOB_ALTDIRFUNC) ?
977                                 (*pglob->gl_readdir) (stream) :
978                                 readdir ((DIR *) stream));
979             if (d == NULL)
980               break;
981             if (! REAL_DIR_ENTRY (d))
982               continue;
983
984             if (strcmp (pattern, d->d_name) == 0)
985               {
986                 size_t len = NAMLEN (d);
987                 names =
988                   (struct globlink *) __alloca (sizeof (struct globlink));
989                 names->name = (char *) malloc (len + 1);
990                 if (names->name == NULL)
991                   goto memory_error;
992 #ifdef HAVE_MEMPCPY
993                 *((char *) mempcpy ((__ptr_t) names->name, pattern, len))
994                   = '\0';
995 #else
996                 memcpy ((__ptr_t) names->name, pattern, len);
997                 names->name[len] = '\0';
998 #endif
999                 names->next = NULL;
1000                 nfound = 1;
1001                 break;
1002               }
1003           }
1004     }
1005   else
1006     {
1007       flags |= GLOB_MAGCHAR;
1008
1009       stream = ((flags & GLOB_ALTDIRFUNC) ?
1010                 (*pglob->gl_opendir) (directory) :
1011                 (__ptr_t) opendir (directory));
1012       if (stream == NULL)
1013         {
1014           if ((errfunc != NULL && (*errfunc) (directory, errno)) ||
1015               (flags & GLOB_ERR))
1016             return GLOB_ABORTED;
1017         }
1018       else
1019         while (1)
1020           {
1021             const char *name;
1022             size_t len;
1023             struct dirent *d = ((flags & GLOB_ALTDIRFUNC) ?
1024                                 (*pglob->gl_readdir) (stream) :
1025                                 readdir ((DIR *) stream));
1026             if (d == NULL)
1027               break;
1028             if (! REAL_DIR_ENTRY (d))
1029               continue;
1030
1031             name = d->d_name;
1032
1033             if (fnmatch (pattern, name,
1034                          (!(flags & GLOB_PERIOD) ? FNM_PERIOD : 0) |
1035                          ((flags & GLOB_NOESCAPE) ? FNM_NOESCAPE : 0)
1036 #ifdef _AMIGA
1037                          | FNM_CASEFOLD
1038 #endif
1039                          ) == 0)
1040               {
1041                 struct globlink *new
1042                   = (struct globlink *) __alloca (sizeof (struct globlink));
1043                 len = NAMLEN (d);
1044                 new->name
1045                   = (char *) malloc (len + 1);
1046                 if (new->name == NULL)
1047                   goto memory_error;
1048 #ifdef HAVE_MEMPCPY
1049                 *((char *) mempcpy ((__ptr_t) new->name, name, len)) = '\0';
1050 #else
1051                 memcpy ((__ptr_t) new->name, name, len);
1052                 new->name[len] = '\0';
1053 #endif
1054                 new->next = names;
1055                 names = new;
1056                 ++nfound;
1057               }
1058           }
1059     }
1060
1061   if (nfound == 0 && (flags & GLOB_NOMAGIC) &&
1062       ! __glob_pattern_p (pattern, !(flags & GLOB_NOESCAPE)))
1063     flags |= GLOB_NOCHECK;
1064
1065   if (nfound == 0 && (flags & GLOB_NOCHECK))
1066     {
1067       size_t len = strlen (pattern);
1068       nfound = 1;
1069       names = (struct globlink *) __alloca (sizeof (struct globlink));
1070       names->next = NULL;
1071       names->name = (char *) malloc (len + 1);
1072       if (names->name == NULL)
1073         goto memory_error;
1074 #ifdef HAVE_MEMPCPY
1075       *((char *) mempcpy (names->name, pattern, len)) = '\0';
1076 #else
1077       memcpy (names->name, pattern, len);
1078       names->name[len] = '\0';
1079 #endif
1080     }
1081
1082   if (nfound != 0)
1083     {
1084       pglob->gl_pathv
1085         = (char **) realloc (pglob->gl_pathv,
1086                              (pglob->gl_pathc +
1087                               ((flags & GLOB_DOOFFS) ? pglob->gl_offs : 0) +
1088                               nfound + 1) *
1089                              sizeof (char *));
1090       if (pglob->gl_pathv == NULL)
1091         goto memory_error;
1092
1093       if (flags & GLOB_DOOFFS)
1094         while (pglob->gl_pathc < pglob->gl_offs)
1095           pglob->gl_pathv[pglob->gl_pathc++] = NULL;
1096
1097       for (; names != NULL; names = names->next)
1098         pglob->gl_pathv[pglob->gl_pathc++] = names->name;
1099       pglob->gl_pathv[pglob->gl_pathc] = NULL;
1100
1101       pglob->gl_flags = flags;
1102     }
1103
1104   if (stream != NULL)
1105     {
1106       int save = errno;
1107       if (flags & GLOB_ALTDIRFUNC)
1108         (*pglob->gl_closedir) (stream);
1109       else
1110         closedir ((DIR *) stream);
1111       __set_errno (save);
1112     }
1113   return nfound == 0 ? GLOB_NOMATCH : 0;
1114
1115  memory_error:
1116   {
1117     int save = errno;
1118     if (flags & GLOB_ALTDIRFUNC)
1119       (*pglob->gl_closedir) (stream);
1120     else
1121       closedir ((DIR *) stream);
1122     __set_errno (save);
1123   }
1124   while (names != NULL)
1125     {
1126       if (names->name != NULL)
1127         free ((__ptr_t) names->name);
1128       names = names->next;
1129     }
1130   return GLOB_NOSPACE;
1131 }
1132
1133 #endif  /* Not ELIDE_CODE.  */