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