~ubuntu-branches/ubuntu/utopic/gridengine/utopic

« back to all changes in this revision

Viewing changes to source/3rdparty/qmake/glob/glob.c

  • Committer: Bazaar Package Importer
  • Author(s): Mark Hymers
  • Date: 2008-06-25 22:36:13 UTC
  • Revision ID: james.westby@ubuntu.com-20080625223613-tvd9xlhuoct9kyhm
Tags: upstream-6.2~beta2
ImportĀ upstreamĀ versionĀ 6.2~beta2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (C) 1991,92,93,94,95,96,97,98,99 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
/* When used in the GNU libc the symbol _DIRENT_HAVE_D_TYPE is available
 
118
   if the `d_type' member for `struct dirent' is available.  */
 
119
#ifdef _DIRENT_HAVE_D_TYPE
 
120
# define HAVE_D_TYPE    1
 
121
#endif
 
122
 
 
123
 
 
124
#if (defined POSIX || defined WINDOWS32) && !defined __GNU_LIBRARY__
 
125
/* Posix does not require that the d_ino field be present, and some
 
126
   systems do not provide it. */
 
127
# define REAL_DIR_ENTRY(dp) 1
 
128
#else
 
129
# define REAL_DIR_ENTRY(dp) (dp->d_ino != 0)
 
130
#endif /* POSIX */
 
131
 
 
132
#if defined STDC_HEADERS || defined __GNU_LIBRARY__
 
133
# include <stdlib.h>
 
134
# include <string.h>
 
135
# define        ANSI_STRING
 
136
#else   /* No standard headers.  */
 
137
 
 
138
extern char *getenv ();
 
139
 
 
140
# ifdef HAVE_STRING_H
 
141
#  include <string.h>
 
142
#  define ANSI_STRING
 
143
# else
 
144
#  include <strings.h>
 
145
# endif
 
146
# ifdef HAVE_MEMORY_H
 
147
#  include <memory.h>
 
148
# endif
 
149
 
 
150
extern char *malloc (), *realloc ();
 
151
extern void free ();
 
152
 
 
153
extern void qsort ();
 
154
extern void abort (), exit ();
 
155
 
 
156
#endif  /* Standard headers.  */
 
157
 
 
158
#ifndef ANSI_STRING
 
159
 
 
160
# ifndef bzero
 
161
extern void bzero ();
 
162
# endif
 
163
# ifndef bcopy
 
164
extern void bcopy ();
 
165
# endif
 
166
 
 
167
# define memcpy(d, s, n)        bcopy ((s), (d), (n))
 
168
# define strrchr        rindex
 
169
/* memset is only used for zero here, but let's be paranoid.  */
 
170
# define memset(s, better_be_zero, n) \
 
171
  ((void) ((better_be_zero) == 0 ? (bzero((s), (n)), 0) : (abort(), 0)))
 
172
#endif  /* Not ANSI_STRING.  */
 
173
 
 
174
#if !defined HAVE_STRCOLL && !defined _LIBC
 
175
# define strcoll        strcmp
 
176
#endif
 
177
 
 
178
#if !defined HAVE_MEMPCPY && __GLIBC__ - 0 == 2 && __GLIBC_MINOR__ >= 1
 
179
# define HAVE_MEMPCPY   1
 
180
# undef  mempcpy
 
181
# define mempcpy(Dest, Src, Len) __mempcpy (Dest, Src, Len)
 
182
#endif
 
183
 
 
184
#ifndef __GNU_LIBRARY__
 
185
# ifdef __GNUC__
 
186
__inline
 
187
# endif
 
188
# ifndef __SASC
 
189
#  ifdef WINDOWS32
 
190
static void *
 
191
#  else
 
192
static char *
 
193
# endif
 
194
my_realloc (p, n)
 
195
     char *p;
 
196
     unsigned int n;
 
197
{
 
198
  /* These casts are the for sake of the broken Ultrix compiler,
 
199
     which warns of illegal pointer combinations otherwise.  */
 
200
  if (p == NULL)
 
201
    return (char *) malloc (n);
 
202
  return (char *) realloc (p, n);
 
203
}
 
204
# define        realloc my_realloc
 
205
# endif /* __SASC */
 
206
#endif /* __GNU_LIBRARY__ */
 
207
 
 
208
 
 
209
#if !defined __alloca && !defined __GNU_LIBRARY__
 
210
 
 
211
# ifdef __GNUC__
 
212
#  undef alloca
 
213
#  define alloca(n)     __builtin_alloca (n)
 
214
# else  /* Not GCC.  */
 
215
#  ifdef HAVE_ALLOCA_H
 
216
#   include <alloca.h>
 
217
#  else /* Not HAVE_ALLOCA_H.  */
 
218
#   ifndef _AIX
 
219
#    ifdef WINDOWS32
 
220
#     include <malloc.h>
 
221
#    else
 
222
extern char *alloca ();
 
223
#    endif /* WINDOWS32 */
 
224
#   endif /* Not _AIX.  */
 
225
#  endif /* sparc or HAVE_ALLOCA_H.  */
 
226
# endif /* GCC.  */
 
227
 
 
228
# define __alloca       alloca
 
229
 
 
230
#endif
 
231
 
 
232
#ifndef __GNU_LIBRARY__
 
233
# define __stat stat
 
234
# ifdef STAT_MACROS_BROKEN
 
235
#  undef S_ISDIR
 
236
# endif
 
237
# ifndef S_ISDIR
 
238
#  define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
 
239
# endif
 
240
#endif
 
241
 
 
242
#ifdef _LIBC
 
243
# undef strdup
 
244
# define strdup(str) __strdup (str)
 
245
# define sysconf(id) __sysconf (id)
 
246
# define closedir(dir) __closedir (dir)
 
247
# define opendir(name) __opendir (name)
 
248
# define readdir(str) __readdir (str)
 
249
# define getpwnam_r(name, bufp, buf, len, res) \
 
250
   __getpwnam_r (name, bufp, buf, len, res)
 
251
# ifndef __stat
 
252
#  define __stat(fname, buf) __xstat (_STAT_VER, fname, buf)
 
253
# endif
 
254
#endif
 
255
 
 
256
#if !(defined STDC_HEADERS || defined __GNU_LIBRARY__)
 
257
# undef size_t
 
258
# define size_t unsigned int
 
259
#endif
 
260
 
 
261
/* Some system header files erroneously define these.
 
262
   We want our own definitions from <fnmatch.h> to take precedence.  */
 
263
#ifndef __GNU_LIBRARY__
 
264
# undef FNM_PATHNAME
 
265
# undef FNM_NOESCAPE
 
266
# undef FNM_PERIOD
 
267
#endif
 
268
#include <fnmatch.h>
 
269
 
 
270
/* Some system header files erroneously define these.
 
271
   We want our own definitions from <glob.h> to take precedence.  */
 
272
#ifndef __GNU_LIBRARY__
 
273
# undef GLOB_ERR
 
274
# undef GLOB_MARK
 
275
# undef GLOB_NOSORT
 
276
# undef GLOB_DOOFFS
 
277
# undef GLOB_NOCHECK
 
278
# undef GLOB_APPEND
 
279
# undef GLOB_NOESCAPE
 
280
# undef GLOB_PERIOD
 
281
#endif
 
282
#include <glob.h>
 
283
 
 
284
#ifdef HAVE_GETLOGIN_R
 
285
extern int getlogin_r __P ((char *, size_t));
 
286
#else
 
287
extern char *getlogin __P ((void));
 
288
#endif
 
289
 
 
290
static
 
291
#if __GNUC__ - 0 >= 2
 
292
inline
 
293
#endif
 
294
const char *next_brace_sub __P ((const char *begin));
 
295
static int glob_in_dir __P ((const char *pattern, const char *directory,
 
296
                             int flags,
 
297
                             int (*errfunc) (const char *, int),
 
298
                             glob_t *pglob));
 
299
static int prefix_array __P ((const char *prefix, char **array, size_t n));
 
300
static int collated_compare __P ((const __ptr_t, const __ptr_t));
 
301
 
 
302
 
 
303
/* Find the end of the sub-pattern in a brace expression.  We define
 
304
   this as an inline function if the compiler permits.  */
 
305
static
 
306
#if __GNUC__ - 0 >= 2
 
307
inline
 
308
#endif
 
309
const char *
 
310
next_brace_sub (begin)
 
311
     const char *begin;
 
312
{
 
313
  unsigned int depth = 0;
 
314
  const char *cp = begin;
 
315
 
 
316
  while (1)
 
317
    {
 
318
      if (depth == 0)
 
319
        {
 
320
          if (*cp != ',' && *cp != '}' && *cp != '\0')
 
321
            {
 
322
              if (*cp == '{')
 
323
                ++depth;
 
324
              ++cp;
 
325
              continue;
 
326
            }
 
327
        }
 
328
      else
 
329
        {
 
330
          while (*cp != '\0' && (*cp != '}' || depth > 0))
 
331
            {
 
332
              if (*cp == '}')
 
333
                --depth;
 
334
              ++cp;
 
335
            }
 
336
          if (*cp == '\0')
 
337
            /* An incorrectly terminated brace expression.  */
 
338
            return NULL;
 
339
 
 
340
          continue;
 
341
        }
 
342
      break;
 
343
    }
 
344
 
 
345
  return cp;
 
346
}
 
347
 
 
348
/* Do glob searching for PATTERN, placing results in PGLOB.
 
349
   The bits defined above may be set in FLAGS.
 
350
   If a directory cannot be opened or read and ERRFUNC is not nil,
 
351
   it is called with the pathname that caused the error, and the
 
352
   `errno' value from the failing call; if it returns non-zero
 
353
   `glob' returns GLOB_ABORTED; if it returns zero, the error is ignored.
 
354
   If memory cannot be allocated for PGLOB, GLOB_NOSPACE is returned.
 
355
   Otherwise, `glob' returns zero.  */
 
356
int
 
357
glob (pattern, flags, errfunc, pglob)
 
358
     const char *pattern;
 
359
     int flags;
 
360
     int (*errfunc) __P ((const char *, int));
 
361
     glob_t *pglob;
 
362
{
 
363
  const char *filename;
 
364
  const char *dirname;
 
365
  size_t dirlen;
 
366
  int status;
 
367
  int oldcount;
 
368
 
 
369
  if (pattern == NULL || pglob == NULL || (flags & ~__GLOB_FLAGS) != 0)
 
370
    {
 
371
      __set_errno (EINVAL);
 
372
      return -1;
 
373
    }
 
374
 
 
375
  if (flags & GLOB_BRACE)
 
376
    {
 
377
      const char *begin = strchr (pattern, '{');
 
378
      if (begin != NULL)
 
379
        {
 
380
          /* Allocate working buffer large enough for our work.  Note that
 
381
            we have at least an opening and closing brace.  */
 
382
          int firstc;
 
383
          char *alt_start;
 
384
          const char *p;
 
385
          const char *next;
 
386
          const char *rest;
 
387
          size_t rest_len;
 
388
#ifdef __GNUC__
 
389
          char onealt[strlen (pattern) - 1];
 
390
#else
 
391
          char *onealt = (char *) malloc (strlen (pattern) - 1);
 
392
          if (onealt == NULL)
 
393
            {
 
394
              if (!(flags & GLOB_APPEND))
 
395
                globfree (pglob);
 
396
              return GLOB_NOSPACE;
 
397
            }
 
398
#endif
 
399
 
 
400
          /* We know the prefix for all sub-patterns.  */
 
401
#ifdef HAVE_MEMPCPY
 
402
          alt_start = mempcpy (onealt, pattern, begin - pattern);
 
403
#else
 
404
          memcpy (onealt, pattern, begin - pattern);
 
405
          alt_start = &onealt[begin - pattern];
 
406
#endif
 
407
 
 
408
          /* Find the first sub-pattern and at the same time find the
 
409
             rest after the closing brace.  */
 
410
          next = next_brace_sub (begin + 1);
 
411
          if (next == NULL)
 
412
            {
 
413
              /* It is an illegal expression.  */
 
414
#ifndef __GNUC__
 
415
              free (onealt);
 
416
#endif
 
417
              return glob (pattern, flags & ~GLOB_BRACE, errfunc, pglob);
 
418
            }
 
419
 
 
420
          /* Now find the end of the whole brace expression.  */
 
421
          rest = next;
 
422
          while (*rest != '}')
 
423
            {
 
424
              rest = next_brace_sub (rest + 1);
 
425
              if (rest == NULL)
 
426
                {
 
427
                  /* It is an illegal expression.  */
 
428
#ifndef __GNUC__
 
429
                  free (onealt);
 
430
#endif
 
431
                  return glob (pattern, flags & ~GLOB_BRACE, errfunc, pglob);
 
432
                }
 
433
            }
 
434
          /* Please note that we now can be sure the brace expression
 
435
             is well-formed.  */
 
436
          rest_len = strlen (++rest) + 1;
 
437
 
 
438
          /* We have a brace expression.  BEGIN points to the opening {,
 
439
             NEXT points past the terminator of the first element, and END
 
440
             points past the final }.  We will accumulate result names from
 
441
             recursive runs for each brace alternative in the buffer using
 
442
             GLOB_APPEND.  */
 
443
 
 
444
          if (!(flags & GLOB_APPEND))
 
445
            {
 
446
              /* This call is to set a new vector, so clear out the
 
447
                 vector so we can append to it.  */
 
448
              pglob->gl_pathc = 0;
 
449
              pglob->gl_pathv = NULL;
 
450
            }
 
451
          firstc = pglob->gl_pathc;
 
452
 
 
453
          p = begin + 1;
 
454
          while (1)
 
455
            {
 
456
              int result;
 
457
 
 
458
              /* Construct the new glob expression.  */
 
459
#ifdef HAVE_MEMPCPY
 
460
              mempcpy (mempcpy (alt_start, p, next - p), rest, rest_len);
 
461
#else
 
462
              memcpy (alt_start, p, next - p);
 
463
              memcpy (&alt_start[next - p], rest, rest_len);
 
464
#endif
 
465
 
 
466
              result = glob (onealt,
 
467
                             ((flags & ~(GLOB_NOCHECK|GLOB_NOMAGIC))
 
468
                              | GLOB_APPEND), errfunc, pglob);
 
469
 
 
470
              /* If we got an error, return it.  */
 
471
              if (result && result != GLOB_NOMATCH)
 
472
                {
 
473
#ifndef __GNUC__
 
474
                  free (onealt);
 
475
#endif
 
476
                  if (!(flags & GLOB_APPEND))
 
477
                    globfree (pglob);
 
478
                  return result;
 
479
                }
 
480
 
 
481
              if (*next == '}')
 
482
                /* We saw the last entry.  */
 
483
                break;
 
484
 
 
485
              p = next + 1;
 
486
              next = next_brace_sub (p);
 
487
              assert (next != NULL);
 
488
            }
 
489
 
 
490
#ifndef __GNUC__
 
491
          free (onealt);
 
492
#endif
 
493
 
 
494
          if (pglob->gl_pathc != firstc)
 
495
            /* We found some entries.  */
 
496
            return 0;
 
497
          else if (!(flags & (GLOB_NOCHECK|GLOB_NOMAGIC)))
 
498
            return GLOB_NOMATCH;
 
499
        }
 
500
    }
 
501
 
 
502
  /* Find the filename.  */
 
503
  filename = strrchr (pattern, '/');
 
504
#if defined __MSDOS__ || defined WINDOWS32
 
505
  /* The case of "d:pattern".  Since `:' is not allowed in
 
506
     file names, we can safely assume that wherever it
 
507
     happens in pattern, it signals the filename part.  This
 
508
     is so we could some day support patterns like "[a-z]:foo".  */
 
509
  if (filename == NULL)
 
510
    filename = strchr (pattern, ':');
 
511
#endif /* __MSDOS__ || WINDOWS32 */
 
512
  if (filename == NULL)
 
513
    {
 
514
      /* This can mean two things: a simple name or "~name".  The later
 
515
         case is nothing but a notation for a directory.  */
 
516
      if ((flags & (GLOB_TILDE|GLOB_TILDE_CHECK)) && pattern[0] == '~')
 
517
        {
 
518
          dirname = pattern;
 
519
          dirlen = strlen (pattern);
 
520
 
 
521
          /* Set FILENAME to NULL as a special flag.  This is ugly but
 
522
             other solutions would require much more code.  We test for
 
523
             this special case below.  */
 
524
          filename = NULL;
 
525
        }
 
526
      else
 
527
        {
 
528
          filename = pattern;
 
529
#ifdef _AMIGA
 
530
          dirname = "";
 
531
#else
 
532
          dirname = ".";
 
533
#endif
 
534
          dirlen = 0;
 
535
        }
 
536
    }
 
537
  else if (filename == pattern)
 
538
    {
 
539
      /* "/pattern".  */
 
540
      dirname = "/";
 
541
      dirlen = 1;
 
542
      ++filename;
 
543
    }
 
544
  else
 
545
    {
 
546
      char *newp;
 
547
      dirlen = filename - pattern;
 
548
#if defined __MSDOS__ || defined WINDOWS32
 
549
      if (*filename == ':'
 
550
          || (filename > pattern + 1 && filename[-1] == ':'))
 
551
        {
 
552
          char *drive_spec;
 
553
 
 
554
          ++dirlen;
 
555
          drive_spec = (char *) __alloca (dirlen + 1);
 
556
#ifdef HAVE_MEMPCPY
 
557
          *((char *) mempcpy (drive_spec, pattern, dirlen)) = '\0';
 
558
#else
 
559
          memcpy (drive_spec, pattern, dirlen);
 
560
          drive_spec[dirlen] = '\0';
 
561
#endif
 
562
          /* For now, disallow wildcards in the drive spec, to
 
563
             prevent infinite recursion in glob.  */
 
564
          if (__glob_pattern_p (drive_spec, !(flags & GLOB_NOESCAPE)))
 
565
            return GLOB_NOMATCH;
 
566
          /* If this is "d:pattern", we need to copy `:' to DIRNAME
 
567
             as well.  If it's "d:/pattern", don't remove the slash
 
568
             from "d:/", since "d:" and "d:/" are not the same.*/
 
569
        }
 
570
#endif
 
571
      newp = (char *) __alloca (dirlen + 1);
 
572
#ifdef HAVE_MEMPCPY
 
573
      *((char *) mempcpy (newp, pattern, dirlen)) = '\0';
 
574
#else
 
575
      memcpy (newp, pattern, dirlen);
 
576
      newp[dirlen] = '\0';
 
577
#endif
 
578
      dirname = newp;
 
579
      ++filename;
 
580
 
 
581
      if (filename[0] == '\0'
 
582
#if defined __MSDOS__ || defined WINDOWS32
 
583
          && dirname[dirlen - 1] != ':'
 
584
          && (dirlen < 3 || dirname[dirlen - 2] != ':'
 
585
              || dirname[dirlen - 1] != '/')
 
586
#endif
 
587
          && dirlen > 1)
 
588
        /* "pattern/".  Expand "pattern", appending slashes.  */
 
589
        {
 
590
          int val = glob (dirname, flags | GLOB_MARK, errfunc, pglob);
 
591
          if (val == 0)
 
592
            pglob->gl_flags = ((pglob->gl_flags & ~GLOB_MARK)
 
593
                               | (flags & GLOB_MARK));
 
594
          return val;
 
595
        }
 
596
    }
 
597
 
 
598
  if (!(flags & GLOB_APPEND))
 
599
    {
 
600
      pglob->gl_pathc = 0;
 
601
      pglob->gl_pathv = NULL;
 
602
    }
 
603
 
 
604
  oldcount = pglob->gl_pathc;
 
605
 
 
606
#ifndef VMS
 
607
  if ((flags & (GLOB_TILDE|GLOB_TILDE_CHECK)) && dirname[0] == '~')
 
608
    {
 
609
      if (dirname[1] == '\0' || dirname[1] == '/')
 
610
        {
 
611
          /* Look up home directory.  */
 
612
          const char *home_dir = getenv ("HOME");
 
613
# ifdef _AMIGA
 
614
          if (home_dir == NULL || home_dir[0] == '\0')
 
615
            home_dir = "SYS:";
 
616
# else
 
617
#  ifdef WINDOWS32
 
618
          if (home_dir == NULL || home_dir[0] == '\0')
 
619
            home_dir = "c:/users/default"; /* poor default */
 
620
#  else
 
621
          if (home_dir == NULL || home_dir[0] == '\0')
 
622
            {
 
623
              int success;
 
624
              char *name;
 
625
#   if defined HAVE_GETLOGIN_R || defined _LIBC
 
626
              size_t buflen = sysconf (_SC_LOGIN_NAME_MAX) + 1;
 
627
 
 
628
              if (buflen == 0)
 
629
                /* `sysconf' does not support _SC_LOGIN_NAME_MAX.  Try
 
630
                   a moderate value.  */
 
631
                buflen = 20;
 
632
              name = (char *) __alloca (buflen);
 
633
 
 
634
              success = getlogin_r (name, buflen) >= 0;
 
635
#   else
 
636
              success = (name = getlogin ()) != NULL;
 
637
#   endif
 
638
              if (success)
 
639
                {
 
640
                  struct passwd *p;
 
641
#   if defined HAVE_GETPWNAM_R || defined _LIBC
 
642
                  size_t pwbuflen = sysconf (_SC_GETPW_R_SIZE_MAX);
 
643
                  char *pwtmpbuf;
 
644
                  struct passwd pwbuf;
 
645
                  int save = errno;
 
646
 
 
647
                  if (pwbuflen == -1)
 
648
                    /* `sysconf' does not support _SC_GETPW_R_SIZE_MAX.
 
649
                       Try a moderate value.  */
 
650
                    pwbuflen = 1024;
 
651
                  pwtmpbuf = (char *) __alloca (pwbuflen);
 
652
 
 
653
                  while (getpwnam_r (name, &pwbuf, pwtmpbuf, pwbuflen, &p)
 
654
                         != 0)
 
655
                    {
 
656
                      if (errno != ERANGE)
 
657
                        {
 
658
                          p = NULL;
 
659
                          break;
 
660
                        }
 
661
                      pwbuflen *= 2;
 
662
                      pwtmpbuf = (char *) __alloca (pwbuflen);
 
663
                      __set_errno (save);
 
664
                    }
 
665
#   else
 
666
                  p = getpwnam (name);
 
667
#   endif
 
668
                  if (p != NULL)
 
669
                    home_dir = p->pw_dir;
 
670
                }
 
671
            }
 
672
          if (home_dir == NULL || home_dir[0] == '\0')
 
673
            {
 
674
              if (flags & GLOB_TILDE_CHECK)
 
675
                return GLOB_NOMATCH;
 
676
              else
 
677
                home_dir = "~"; /* No luck.  */
 
678
            }
 
679
#  endif /* WINDOWS32 */
 
680
# endif
 
681
          /* Now construct the full directory.  */
 
682
          if (dirname[1] == '\0')
 
683
            dirname = home_dir;
 
684
          else
 
685
            {
 
686
              char *newp;
 
687
              size_t home_len = strlen (home_dir);
 
688
              newp = (char *) __alloca (home_len + dirlen);
 
689
# ifdef HAVE_MEMPCPY
 
690
              mempcpy (mempcpy (newp, home_dir, home_len),
 
691
                       &dirname[1], dirlen);
 
692
# else
 
693
              memcpy (newp, home_dir, home_len);
 
694
              memcpy (&newp[home_len], &dirname[1], dirlen);
 
695
# endif
 
696
              dirname = newp;
 
697
            }
 
698
        }
 
699
# if !defined _AMIGA && !defined WINDOWS32
 
700
      else
 
701
        {
 
702
          char *end_name = strchr (dirname, '/');
 
703
          const char *user_name;
 
704
          const char *home_dir;
 
705
 
 
706
          if (end_name == NULL)
 
707
            user_name = dirname + 1;
 
708
          else
 
709
            {
 
710
              char *newp;
 
711
              newp = (char *) __alloca (end_name - dirname);
 
712
# ifdef HAVE_MEMPCPY
 
713
              *((char *) mempcpy (newp, dirname + 1, end_name - dirname))
 
714
                = '\0';
 
715
# else
 
716
              memcpy (newp, dirname + 1, end_name - dirname);
 
717
              newp[end_name - dirname - 1] = '\0';
 
718
# endif
 
719
              user_name = newp;
 
720
            }
 
721
 
 
722
          /* Look up specific user's home directory.  */
 
723
          {
 
724
            struct passwd *p;
 
725
#  if defined HAVE_GETPWNAM_R || defined _LIBC
 
726
            size_t buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
 
727
            char *pwtmpbuf;
 
728
            struct passwd pwbuf;
 
729
            int save = errno;
 
730
 
 
731
            if (buflen == -1)
 
732
              /* `sysconf' does not support _SC_GETPW_R_SIZE_MAX.  Try a
 
733
                 moderate value.  */
 
734
              buflen = 1024;
 
735
            pwtmpbuf = (char *) __alloca (buflen);
 
736
 
 
737
            while (getpwnam_r (user_name, &pwbuf, pwtmpbuf, buflen, &p) != 0)
 
738
              {
 
739
                if (errno != ERANGE)
 
740
                  {
 
741
                    p = NULL;
 
742
                    break;
 
743
                  }
 
744
                buflen *= 2;
 
745
                pwtmpbuf = __alloca (buflen);
 
746
                __set_errno (save);
 
747
              }
 
748
#  else
 
749
            p = getpwnam (user_name);
 
750
#  endif
 
751
            if (p != NULL)
 
752
              home_dir = p->pw_dir;
 
753
            else
 
754
              home_dir = NULL;
 
755
          }
 
756
          /* If we found a home directory use this.  */
 
757
          if (home_dir != NULL)
 
758
            {
 
759
              char *newp;
 
760
              size_t home_len = strlen (home_dir);
 
761
              size_t rest_len = end_name == NULL ? 0 : strlen (end_name);
 
762
              newp = (char *) __alloca (home_len + rest_len + 1);
 
763
#  ifdef HAVE_MEMPCPY
 
764
              *((char *) mempcpy (mempcpy (newp, home_dir, home_len),
 
765
                                  end_name, rest_len)) = '\0';
 
766
#  else
 
767
              memcpy (newp, home_dir, home_len);
 
768
              memcpy (&newp[home_len], end_name, rest_len);
 
769
              newp[home_len + rest_len] = '\0';
 
770
#  endif
 
771
              dirname = newp;
 
772
            }
 
773
          else
 
774
            if (flags & GLOB_TILDE_CHECK)
 
775
              /* We have to regard it as an error if we cannot find the
 
776
                 home directory.  */
 
777
              return GLOB_NOMATCH;
 
778
        }
 
779
# endif /* Not Amiga && not WINDOWS32.  */
 
780
    }
 
781
#endif  /* Not VMS.  */
 
782
 
 
783
  /* Now test whether we looked for "~" or "~NAME".  In this case we
 
784
     can give the answer now.  */
 
785
  if (filename == NULL)
 
786
    {
 
787
      struct stat st;
 
788
 
 
789
      /* Return the directory if we don't check for error or if it exists.  */
 
790
      if ((flags & GLOB_NOCHECK)
 
791
          || (((flags & GLOB_ALTDIRFUNC)
 
792
               ? (*pglob->gl_stat) (dirname, &st)
 
793
               : __stat (dirname, &st)) == 0
 
794
              && S_ISDIR (st.st_mode)))
 
795
        {
 
796
          pglob->gl_pathv
 
797
            = (char **) realloc (pglob->gl_pathv,
 
798
                                 (pglob->gl_pathc +
 
799
                                  ((flags & GLOB_DOOFFS) ?
 
800
                                   pglob->gl_offs : 0) +
 
801
                                  1 + 1) *
 
802
                                 sizeof (char *));
 
803
          if (pglob->gl_pathv == NULL)
 
804
            return GLOB_NOSPACE;
 
805
 
 
806
          if (flags & GLOB_DOOFFS)
 
807
            while (pglob->gl_pathc < pglob->gl_offs)
 
808
              pglob->gl_pathv[pglob->gl_pathc++] = NULL;
 
809
 
 
810
#if defined HAVE_STRDUP || defined _LIBC
 
811
          pglob->gl_pathv[pglob->gl_pathc] = strdup (dirname);
 
812
#else
 
813
          {
 
814
            size_t len = strlen (dirname) + 1;
 
815
            char *dircopy = malloc (len);
 
816
            if (dircopy != NULL)
 
817
              pglob->gl_pathv[pglob->gl_pathc] = memcpy (dircopy, dirname,
 
818
                                                         len);
 
819
          }
 
820
#endif
 
821
          if (pglob->gl_pathv[pglob->gl_pathc] == NULL)
 
822
            {
 
823
              free (pglob->gl_pathv);
 
824
              return GLOB_NOSPACE;
 
825
            }
 
826
          pglob->gl_pathv[++pglob->gl_pathc] = NULL;
 
827
          pglob->gl_flags = flags;
 
828
 
 
829
          return 0;
 
830
        }
 
831
 
 
832
      /* Not found.  */
 
833
      return GLOB_NOMATCH;
 
834
    }
 
835
 
 
836
  if (__glob_pattern_p (dirname, !(flags & GLOB_NOESCAPE)))
 
837
    {
 
838
      /* The directory name contains metacharacters, so we
 
839
         have to glob for the directory, and then glob for
 
840
         the pattern in each directory found.  */
 
841
      glob_t dirs;
 
842
      register int i;
 
843
 
 
844
      status = glob (dirname,
 
845
                     ((flags & (GLOB_ERR | GLOB_NOCHECK | GLOB_NOESCAPE))
 
846
                      | GLOB_NOSORT | GLOB_ONLYDIR),
 
847
                     errfunc, &dirs);
 
848
      if (status != 0)
 
849
        return status;
 
850
 
 
851
      /* We have successfully globbed the preceding directory name.
 
852
         For each name we found, call glob_in_dir on it and FILENAME,
 
853
         appending the results to PGLOB.  */
 
854
      for (i = 0; i < dirs.gl_pathc; ++i)
 
855
        {
 
856
          int old_pathc;
 
857
 
 
858
#ifdef  SHELL
 
859
          {
 
860
            /* Make globbing interruptible in the bash shell. */
 
861
            extern int interrupt_state;
 
862
 
 
863
            if (interrupt_state)
 
864
              {
 
865
                globfree (&dirs);
 
866
                globfree (&files);
 
867
                return GLOB_ABORTED;
 
868
              }
 
869
          }
 
870
#endif /* SHELL.  */
 
871
 
 
872
          old_pathc = pglob->gl_pathc;
 
873
          status = glob_in_dir (filename, dirs.gl_pathv[i],
 
874
                                ((flags | GLOB_APPEND)
 
875
                                 & ~(GLOB_NOCHECK | GLOB_ERR)),
 
876
                                errfunc, pglob);
 
877
          if (status == GLOB_NOMATCH)
 
878
            /* No matches in this directory.  Try the next.  */
 
879
            continue;
 
880
 
 
881
          if (status != 0)
 
882
            {
 
883
              globfree (&dirs);
 
884
              globfree (pglob);
 
885
              return status;
 
886
            }
 
887
 
 
888
          /* Stick the directory on the front of each name.  */
 
889
          if (prefix_array (dirs.gl_pathv[i],
 
890
                            &pglob->gl_pathv[old_pathc],
 
891
                            pglob->gl_pathc - old_pathc))
 
892
            {
 
893
              globfree (&dirs);
 
894
              globfree (pglob);
 
895
              return GLOB_NOSPACE;
 
896
            }
 
897
        }
 
898
 
 
899
      flags |= GLOB_MAGCHAR;
 
900
 
 
901
      /* We have ignored the GLOB_NOCHECK flag in the `glob_in_dir' calls.
 
902
         But if we have not found any matching entry and thie GLOB_NOCHECK
 
903
         flag was set we must return the list consisting of the disrectory
 
904
         names followed by the filename.  */
 
905
      if (pglob->gl_pathc == oldcount)
 
906
        {
 
907
          /* No matches.  */
 
908
          if (flags & GLOB_NOCHECK)
 
909
            {
 
910
              size_t filename_len = strlen (filename) + 1;
 
911
              char **new_pathv;
 
912
              struct stat st;
 
913
 
 
914
              /* This is an pessimistic guess about the size.  */
 
915
              pglob->gl_pathv
 
916
                = (char **) realloc (pglob->gl_pathv,
 
917
                                     (pglob->gl_pathc +
 
918
                                      ((flags & GLOB_DOOFFS) ?
 
919
                                       pglob->gl_offs : 0) +
 
920
                                      dirs.gl_pathc + 1) *
 
921
                                     sizeof (char *));
 
922
              if (pglob->gl_pathv == NULL)
 
923
                {
 
924
                  globfree (&dirs);
 
925
                  return GLOB_NOSPACE;
 
926
                }
 
927
 
 
928
              if (flags & GLOB_DOOFFS)
 
929
                while (pglob->gl_pathc < pglob->gl_offs)
 
930
                  pglob->gl_pathv[pglob->gl_pathc++] = NULL;
 
931
 
 
932
              for (i = 0; i < dirs.gl_pathc; ++i)
 
933
                {
 
934
                  const char *dir = dirs.gl_pathv[i];
 
935
                  size_t dir_len = strlen (dir);
 
936
 
 
937
                  /* First check whether this really is a directory.  */
 
938
                  if (((flags & GLOB_ALTDIRFUNC)
 
939
                       ? (*pglob->gl_stat) (dir, &st) : __stat (dir, &st)) != 0
 
940
                      || !S_ISDIR (st.st_mode))
 
941
                    /* No directory, ignore this entry.  */
 
942
                    continue;
 
943
 
 
944
                  pglob->gl_pathv[pglob->gl_pathc] = malloc (dir_len + 1
 
945
                                                             + filename_len);
 
946
                  if (pglob->gl_pathv[pglob->gl_pathc] == NULL)
 
947
                    {
 
948
                      globfree (&dirs);
 
949
                      globfree (pglob);
 
950
                      return GLOB_NOSPACE;
 
951
                    }
 
952
 
 
953
#ifdef HAVE_MEMPCPY
 
954
                  mempcpy (mempcpy (mempcpy (pglob->gl_pathv[pglob->gl_pathc],
 
955
                                             dir, dir_len),
 
956
                                    "/", 1),
 
957
                           filename, filename_len);
 
958
#else
 
959
                  memcpy (pglob->gl_pathv[pglob->gl_pathc], dir, dir_len);
 
960
                  pglob->gl_pathv[pglob->gl_pathc][dir_len] = '/';
 
961
                  memcpy (&pglob->gl_pathv[pglob->gl_pathc][dir_len + 1],
 
962
                          filename, filename_len);
 
963
#endif
 
964
                  ++pglob->gl_pathc;
 
965
                }
 
966
 
 
967
              pglob->gl_pathv[pglob->gl_pathc] = NULL;
 
968
              pglob->gl_flags = flags;
 
969
 
 
970
              /* Now we know how large the gl_pathv vector must be.  */
 
971
              new_pathv = (char **) realloc (pglob->gl_pathv,
 
972
                                             ((pglob->gl_pathc + 1)
 
973
                                              * sizeof (char *)));
 
974
              if (new_pathv != NULL)
 
975
                pglob->gl_pathv = new_pathv;
 
976
            }
 
977
          else
 
978
            return GLOB_NOMATCH;
 
979
        }
 
980
 
 
981
      globfree (&dirs);
 
982
    }
 
983
  else
 
984
    {
 
985
      status = glob_in_dir (filename, dirname, flags, errfunc, pglob);
 
986
      if (status != 0)
 
987
        return status;
 
988
 
 
989
      if (dirlen > 0)
 
990
        {
 
991
          /* Stick the directory on the front of each name.  */
 
992
          int ignore = oldcount;
 
993
 
 
994
          if ((flags & GLOB_DOOFFS) && ignore < pglob->gl_offs)
 
995
            ignore = pglob->gl_offs;
 
996
 
 
997
          if (prefix_array (dirname,
 
998
                            &pglob->gl_pathv[ignore],
 
999
                            pglob->gl_pathc - ignore))
 
1000
            {
 
1001
              globfree (pglob);
 
1002
              return GLOB_NOSPACE;
 
1003
            }
 
1004
        }
 
1005
    }
 
1006
 
 
1007
  if (flags & GLOB_MARK)
 
1008
    {
 
1009
      /* Append slashes to directory names.  */
 
1010
      int i;
 
1011
      struct stat st;
 
1012
      for (i = oldcount; i < pglob->gl_pathc; ++i)
 
1013
        if (((flags & GLOB_ALTDIRFUNC)
 
1014
             ? (*pglob->gl_stat) (pglob->gl_pathv[i], &st)
 
1015
             : __stat (pglob->gl_pathv[i], &st)) == 0
 
1016
            && S_ISDIR (st.st_mode))
 
1017
          {
 
1018
            size_t len = strlen (pglob->gl_pathv[i]) + 2;
 
1019
            char *new = realloc (pglob->gl_pathv[i], len);
 
1020
            if (new == NULL)
 
1021
              {
 
1022
                globfree (pglob);
 
1023
                return GLOB_NOSPACE;
 
1024
              }
 
1025
            strcpy (&new[len - 2], "/");
 
1026
            pglob->gl_pathv[i] = new;
 
1027
          }
 
1028
    }
 
1029
 
 
1030
  if (!(flags & GLOB_NOSORT))
 
1031
    {
 
1032
      /* Sort the vector.  */
 
1033
      int non_sort = oldcount;
 
1034
 
 
1035
      if ((flags & GLOB_DOOFFS) && pglob->gl_offs > oldcount)
 
1036
        non_sort = pglob->gl_offs;
 
1037
 
 
1038
      qsort ((__ptr_t) &pglob->gl_pathv[non_sort],
 
1039
             pglob->gl_pathc - non_sort,
 
1040
             sizeof (char *), collated_compare);
 
1041
    }
 
1042
 
 
1043
  return 0;
 
1044
}
 
1045
 
 
1046
 
 
1047
/* Free storage allocated in PGLOB by a previous `glob' call.  */
 
1048
void
 
1049
globfree (pglob)
 
1050
     register glob_t *pglob;
 
1051
{
 
1052
  if (pglob->gl_pathv != NULL)
 
1053
    {
 
1054
      register int i;
 
1055
      for (i = 0; i < pglob->gl_pathc; ++i)
 
1056
        if (pglob->gl_pathv[i] != NULL)
 
1057
          free ((__ptr_t) pglob->gl_pathv[i]);
 
1058
      free ((__ptr_t) pglob->gl_pathv);
 
1059
    }
 
1060
}
 
1061
 
 
1062
 
 
1063
/* Do a collated comparison of A and B.  */
 
1064
static int
 
1065
collated_compare (a, b)
 
1066
     const __ptr_t a;
 
1067
     const __ptr_t b;
 
1068
{
 
1069
  const char *const s1 = *(const char *const * const) a;
 
1070
  const char *const s2 = *(const char *const * const) b;
 
1071
 
 
1072
  if (s1 == s2)
 
1073
    return 0;
 
1074
  if (s1 == NULL)
 
1075
    return 1;
 
1076
  if (s2 == NULL)
 
1077
    return -1;
 
1078
  return strcoll (s1, s2);
 
1079
}
 
1080
 
 
1081
 
 
1082
/* Prepend DIRNAME to each of N members of ARRAY, replacing ARRAY's
 
1083
   elements in place.  Return nonzero if out of memory, zero if successful.
 
1084
   A slash is inserted between DIRNAME and each elt of ARRAY,
 
1085
   unless DIRNAME is just "/".  Each old element of ARRAY is freed.  */
 
1086
static int
 
1087
prefix_array (dirname, array, n)
 
1088
     const char *dirname;
 
1089
     char **array;
 
1090
     size_t n;
 
1091
{
 
1092
  register size_t i;
 
1093
  size_t dirlen = strlen (dirname);
 
1094
#if defined __MSDOS__ || defined WINDOWS32
 
1095
  int sep_char = '/';
 
1096
# define DIRSEP_CHAR sep_char
 
1097
#else
 
1098
# define DIRSEP_CHAR '/'
 
1099
#endif
 
1100
 
 
1101
  if (dirlen == 1 && dirname[0] == '/')
 
1102
    /* DIRNAME is just "/", so normal prepending would get us "//foo".
 
1103
       We want "/foo" instead, so don't prepend any chars from DIRNAME.  */
 
1104
    dirlen = 0;
 
1105
#if defined __MSDOS__ || defined WINDOWS32
 
1106
  else if (dirlen > 1)
 
1107
    {
 
1108
      if (dirname[dirlen - 1] == '/' && dirname[dirlen - 2] == ':')
 
1109
        /* DIRNAME is "d:/".  Don't prepend the slash from DIRNAME.  */
 
1110
        --dirlen;
 
1111
      else if (dirname[dirlen - 1] == ':')
 
1112
        {
 
1113
          /* DIRNAME is "d:".  Use `:' instead of `/'.  */
 
1114
          --dirlen;
 
1115
          sep_char = ':';
 
1116
        }
 
1117
    }
 
1118
#endif
 
1119
 
 
1120
  for (i = 0; i < n; ++i)
 
1121
    {
 
1122
      size_t eltlen = strlen (array[i]) + 1;
 
1123
      char *new = (char *) malloc (dirlen + 1 + eltlen);
 
1124
      if (new == NULL)
 
1125
        {
 
1126
          while (i > 0)
 
1127
            free ((__ptr_t) array[--i]);
 
1128
          return 1;
 
1129
        }
 
1130
 
 
1131
#ifdef HAVE_MEMPCPY
 
1132
      {
 
1133
        char *endp = (char *) mempcpy (new, dirname, dirlen);
 
1134
        *endp++ = DIRSEP_CHAR;
 
1135
        mempcpy (endp, array[i], eltlen);
 
1136
      }
 
1137
#else
 
1138
      memcpy (new, dirname, dirlen);
 
1139
      new[dirlen] = DIRSEP_CHAR;
 
1140
      memcpy (&new[dirlen + 1], array[i], eltlen);
 
1141
#endif
 
1142
      free ((__ptr_t) array[i]);
 
1143
      array[i] = new;
 
1144
    }
 
1145
 
 
1146
  return 0;
 
1147
}
 
1148
 
 
1149
 
 
1150
/* We must not compile this function twice.  */
 
1151
#if !defined _LIBC || !defined NO_GLOB_PATTERN_P
 
1152
/* Return nonzero if PATTERN contains any metacharacters.
 
1153
   Metacharacters can be quoted with backslashes if QUOTE is nonzero.  */
 
1154
int
 
1155
__glob_pattern_p (pattern, quote)
 
1156
     const char *pattern;
 
1157
     int quote;
 
1158
{
 
1159
  register const char *p;
 
1160
  int open = 0;
 
1161
 
 
1162
  for (p = pattern; *p != '\0'; ++p)
 
1163
    switch (*p)
 
1164
      {
 
1165
      case '?':
 
1166
      case '*':
 
1167
        return 1;
 
1168
 
 
1169
      case '\\':
 
1170
        if (quote && p[1] != '\0')
 
1171
          ++p;
 
1172
        break;
 
1173
 
 
1174
      case '[':
 
1175
        open = 1;
 
1176
        break;
 
1177
 
 
1178
      case ']':
 
1179
        if (open)
 
1180
          return 1;
 
1181
        break;
 
1182
      }
 
1183
 
 
1184
  return 0;
 
1185
}
 
1186
# ifdef _LIBC
 
1187
weak_alias (__glob_pattern_p, glob_pattern_p)
 
1188
# endif
 
1189
#endif
 
1190
 
 
1191
 
 
1192
/* Like `glob', but PATTERN is a final pathname component,
 
1193
   and matches are searched for in DIRECTORY.
 
1194
   The GLOB_NOSORT bit in FLAGS is ignored.  No sorting is ever done.
 
1195
   The GLOB_APPEND flag is assumed to be set (always appends).  */
 
1196
static int
 
1197
glob_in_dir (pattern, directory, flags, errfunc, pglob)
 
1198
     const char *pattern;
 
1199
     const char *directory;
 
1200
     int flags;
 
1201
     int (*errfunc) __P ((const char *, int));
 
1202
     glob_t *pglob;
 
1203
{
 
1204
  __ptr_t stream = NULL;
 
1205
 
 
1206
  struct globlink
 
1207
    {
 
1208
      struct globlink *next;
 
1209
      char *name;
 
1210
    };
 
1211
  struct globlink *names = NULL;
 
1212
  size_t nfound;
 
1213
  int meta;
 
1214
  int save;
 
1215
 
 
1216
  meta = __glob_pattern_p (pattern, !(flags & GLOB_NOESCAPE));
 
1217
  if (meta == 0)
 
1218
    {
 
1219
      if (flags & (GLOB_NOCHECK|GLOB_NOMAGIC))
 
1220
        /* We need not do any tests.  The PATTERN contains no meta
 
1221
           characters and we must not return an error therefore the
 
1222
           result will always contain exactly one name.  */
 
1223
        flags |= GLOB_NOCHECK;
 
1224
      else
 
1225
        {
 
1226
          /* Since we use the normal file functions we can also use stat()
 
1227
             to verify the file is there.  */
 
1228
          struct stat st;
 
1229
          size_t patlen = strlen (pattern);
 
1230
          size_t dirlen = strlen (directory);
 
1231
          char *fullname = (char *) __alloca (dirlen + 1 + patlen + 1);
 
1232
 
 
1233
# ifdef HAVE_MEMPCPY
 
1234
          mempcpy (mempcpy (mempcpy (fullname, directory, dirlen),
 
1235
                            "/", 1),
 
1236
                   pattern, patlen + 1);
 
1237
# else
 
1238
          memcpy (fullname, directory, dirlen);
 
1239
          fullname[dirlen] = '/';
 
1240
          memcpy (&fullname[dirlen + 1], pattern, patlen + 1);
 
1241
# endif
 
1242
          if (((flags & GLOB_ALTDIRFUNC)
 
1243
               ? (*pglob->gl_stat) (fullname, &st)
 
1244
               : __stat (fullname, &st)) == 0)
 
1245
            /* We found this file to be existing.  Now tell the rest
 
1246
               of the function to copy this name into the result.  */
 
1247
            flags |= GLOB_NOCHECK;
 
1248
        }
 
1249
 
 
1250
      nfound = 0;
 
1251
    }
 
1252
  else
 
1253
    {
 
1254
      if (pattern[0] == '\0')
 
1255
        {
 
1256
          /* This is a special case for matching directories like in
 
1257
             "*a/".  */
 
1258
          names = (struct globlink *) __alloca (sizeof (struct globlink));
 
1259
          names->name = (char *) malloc (1);
 
1260
          if (names->name == NULL)
 
1261
            goto memory_error;
 
1262
          names->name[0] = '\0';
 
1263
          names->next = NULL;
 
1264
          nfound = 1;
 
1265
          meta = 0;
 
1266
        }
 
1267
      else
 
1268
        {
 
1269
          stream = ((flags & GLOB_ALTDIRFUNC)
 
1270
                    ? (*pglob->gl_opendir) (directory)
 
1271
                    : (__ptr_t) opendir (directory));
 
1272
          if (stream == NULL)
 
1273
            {
 
1274
              if (errno != ENOTDIR
 
1275
                  && ((errfunc != NULL && (*errfunc) (directory, errno))
 
1276
                      || (flags & GLOB_ERR)))
 
1277
                return GLOB_ABORTED;
 
1278
              nfound = 0;
 
1279
              meta = 0;
 
1280
            }
 
1281
          else
 
1282
            {
 
1283
              int fnm_flags = ((!(flags & GLOB_PERIOD) ? FNM_PERIOD : 0)
 
1284
                               | ((flags & GLOB_NOESCAPE) ? FNM_NOESCAPE : 0)
 
1285
#if defined _AMIGA || defined VMS
 
1286
                                   | FNM_CASEFOLD
 
1287
#endif
 
1288
                                   );
 
1289
              nfound = 0;
 
1290
              flags |= GLOB_MAGCHAR;
 
1291
 
 
1292
              while (1)
 
1293
                {
 
1294
                  const char *name;
 
1295
                  size_t len;
 
1296
                  struct dirent *d = ((flags & GLOB_ALTDIRFUNC)
 
1297
                                      ? (*pglob->gl_readdir) (stream)
 
1298
                                      : readdir ((DIR *) stream));
 
1299
                  if (d == NULL)
 
1300
                    break;
 
1301
                  if (! REAL_DIR_ENTRY (d))
 
1302
                    continue;
 
1303
 
 
1304
#ifdef HAVE_D_TYPE
 
1305
                  /* If we shall match only directories use the information
 
1306
                     provided by the dirent call if possible.  */
 
1307
                  if ((flags & GLOB_ONLYDIR)
 
1308
                      && d->d_type != DT_UNKNOWN && d->d_type != DT_DIR)
 
1309
                    continue;
 
1310
#endif
 
1311
 
 
1312
                  name = d->d_name;
 
1313
 
 
1314
                  if (fnmatch (pattern, name, fnm_flags) == 0)
 
1315
                    {
 
1316
                      struct globlink *new = (struct globlink *)
 
1317
                        __alloca (sizeof (struct globlink));
 
1318
                      len = NAMLEN (d);
 
1319
                      new->name = (char *) malloc (len + 1);
 
1320
                      if (new->name == NULL)
 
1321
                        goto memory_error;
 
1322
#ifdef HAVE_MEMPCPY
 
1323
                      *((char *) mempcpy ((__ptr_t) new->name, name, len))
 
1324
                        = '\0';
 
1325
#else
 
1326
                      memcpy ((__ptr_t) new->name, name, len);
 
1327
                      new->name[len] = '\0';
 
1328
#endif
 
1329
                      new->next = names;
 
1330
                      names = new;
 
1331
                      ++nfound;
 
1332
                    }
 
1333
                }
 
1334
            }
 
1335
        }
 
1336
    }
 
1337
 
 
1338
  if (nfound == 0 && (flags & GLOB_NOCHECK))
 
1339
    {
 
1340
      size_t len = strlen (pattern);
 
1341
      nfound = 1;
 
1342
      names = (struct globlink *) __alloca (sizeof (struct globlink));
 
1343
      names->next = NULL;
 
1344
      names->name = (char *) malloc (len + 1);
 
1345
      if (names->name == NULL)
 
1346
        goto memory_error;
 
1347
#ifdef HAVE_MEMPCPY
 
1348
      *((char *) mempcpy (names->name, pattern, len)) = '\0';
 
1349
#else
 
1350
      memcpy (names->name, pattern, len);
 
1351
      names->name[len] = '\0';
 
1352
#endif
 
1353
    }
 
1354
 
 
1355
  if (nfound != 0)
 
1356
    {
 
1357
      pglob->gl_pathv
 
1358
        = (char **) realloc (pglob->gl_pathv,
 
1359
                             (pglob->gl_pathc +
 
1360
                              ((flags & GLOB_DOOFFS) ? pglob->gl_offs : 0) +
 
1361
                              nfound + 1) *
 
1362
                             sizeof (char *));
 
1363
      if (pglob->gl_pathv == NULL)
 
1364
        goto memory_error;
 
1365
 
 
1366
      if (flags & GLOB_DOOFFS)
 
1367
        while (pglob->gl_pathc < pglob->gl_offs)
 
1368
          pglob->gl_pathv[pglob->gl_pathc++] = NULL;
 
1369
 
 
1370
      for (; names != NULL; names = names->next)
 
1371
        pglob->gl_pathv[pglob->gl_pathc++] = names->name;
 
1372
      pglob->gl_pathv[pglob->gl_pathc] = NULL;
 
1373
 
 
1374
      pglob->gl_flags = flags;
 
1375
    }
 
1376
 
 
1377
  save = errno;
 
1378
  if (stream != NULL)
 
1379
    {
 
1380
      if (flags & GLOB_ALTDIRFUNC)
 
1381
        (*pglob->gl_closedir) (stream);
 
1382
      else
 
1383
        closedir ((DIR *) stream);
 
1384
    }
 
1385
  __set_errno (save);
 
1386
 
 
1387
  return nfound == 0 ? GLOB_NOMATCH : 0;
 
1388
 
 
1389
 memory_error:
 
1390
  {
 
1391
    int save = errno;
 
1392
    if (flags & GLOB_ALTDIRFUNC)
 
1393
      (*pglob->gl_closedir) (stream);
 
1394
    else
 
1395
      closedir ((DIR *) stream);
 
1396
    __set_errno (save);
 
1397
  }
 
1398
  while (names != NULL)
 
1399
    {
 
1400
      if (names->name != NULL)
 
1401
        free ((__ptr_t) names->name);
 
1402
      names = names->next;
 
1403
    }
 
1404
  return GLOB_NOSPACE;
 
1405
}
 
1406
 
 
1407
#endif  /* Not ELIDE_CODE.  */