]> git.ipfire.org Git - thirdparty/glibc.git/blame - sysdeps/generic/glob.c
[BZ #16]
[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
98d2ca3d 342static const char *next_brace_sub __P ((const char *begin, int flags));
60f0e64b
UD
343
344#endif /* GLOB_ONLY_P */
345
28f540f4
RM
346static int glob_in_dir __P ((const char *pattern, const char *directory,
347 int flags,
df777c40 348 int (*errfunc) (const char *, int),
28f540f4 349 glob_t *pglob));
60f0e64b
UD
350
351#if !defined _LIBC || !defined GLOB_ONLY_P
28f540f4
RM
352static int prefix_array __P ((const char *prefix, char **array, size_t n));
353static int collated_compare __P ((const __ptr_t, const __ptr_t));
354
5ae9d168 355
98d2ca3d
UD
356/* Find the end of the sub-pattern in a brace expression. */
357static const char *
358next_brace_sub (cp, flags)
638670cd 359 const char *cp;
98d2ca3d 360 int flags;
5ae9d168
UD
361{
362 unsigned int depth = 0;
98d2ca3d
UD
363 while (*cp != '\0')
364 if ((flags & GLOB_NOESCAPE) == 0 && *cp == '\\')
365 {
366 if (*++cp == '\0')
367 break;
368 ++cp;
369 }
370 else
371 {
372 if ((*cp == '}' && depth-- == 0) || (*cp == ',' && depth == 0))
373 break;
374
375 if (*cp++ == '{')
376 depth++;
377 }
378
638670cd 379 return *cp != '\0' ? cp : NULL;
5ae9d168
UD
380}
381
60f0e64b
UD
382#endif /* !GLOB_ONLY_P */
383
28f540f4
RM
384/* Do glob searching for PATTERN, placing results in PGLOB.
385 The bits defined above may be set in FLAGS.
386 If a directory cannot be opened or read and ERRFUNC is not nil,
387 it is called with the pathname that caused the error, and the
388 `errno' value from the failing call; if it returns non-zero
714a562f 389 `glob' returns GLOB_ABORTED; if it returns zero, the error is ignored.
28f540f4
RM
390 If memory cannot be allocated for PGLOB, GLOB_NOSPACE is returned.
391 Otherwise, `glob' returns zero. */
392int
393glob (pattern, flags, errfunc, pglob)
394 const char *pattern;
395 int flags;
396 int (*errfunc) __P ((const char *, int));
397 glob_t *pglob;
398{
399 const char *filename;
ec986e23 400 const char *dirname;
28f540f4
RM
401 size_t dirlen;
402 int status;
ec6f8477 403 size_t oldcount;
28f540f4
RM
404
405 if (pattern == NULL || pglob == NULL || (flags & ~__GLOB_FLAGS) != 0)
406 {
c4029823 407 __set_errno (EINVAL);
28f540f4
RM
408 return -1;
409 }
410
460adbb8
UD
411 if (!(flags & GLOB_DOOFFS))
412 /* Have to do this so `globfree' knows where to start freeing. It
413 also makes all the code that uses gl_offs simpler. */
414 pglob->gl_offs = 0;
415
787e4db9
RM
416 if (flags & GLOB_BRACE)
417 {
98d2ca3d
UD
418 const char *begin;
419
420 if (flags & GLOB_NOESCAPE)
421 begin = strchr (pattern, '{');
422 else
423 {
424 begin = pattern;
425 while (1)
426 {
427 if (*begin == '\0')
428 {
429 begin = NULL;
430 break;
431 }
432
433 if (*begin == '\\' && begin[1] != '\0')
434 ++begin;
435 else if (*begin == '{')
436 break;
437
438 ++begin;
439 }
440 }
441
787e4db9
RM
442 if (begin != NULL)
443 {
5ae9d168
UD
444 /* Allocate working buffer large enough for our work. Note that
445 we have at least an opening and closing brace. */
ec6f8477 446 size_t firstc;
5ae9d168
UD
447 char *alt_start;
448 const char *p;
449 const char *next;
450 const char *rest;
451 size_t rest_len;
452#ifdef __GNUC__
453 char onealt[strlen (pattern) - 1];
454#else
455 char *onealt = (char *) malloc (strlen (pattern) - 1);
456 if (onealt == NULL)
457 {
458 if (!(flags & GLOB_APPEND))
03af5793 459 {
03af5793 460 pglob->gl_pathc = 0;
98d2ca3d 461 pglob->gl_pathv = NULL;
03af5793 462 }
5ae9d168
UD
463 return GLOB_NOSPACE;
464 }
465#endif
466
467 /* We know the prefix for all sub-patterns. */
86187531
UD
468#ifdef HAVE_MEMPCPY
469 alt_start = mempcpy (onealt, pattern, begin - pattern);
470#else
5ae9d168
UD
471 memcpy (onealt, pattern, begin - pattern);
472 alt_start = &onealt[begin - pattern];
86187531 473#endif
5ae9d168
UD
474
475 /* Find the first sub-pattern and at the same time find the
476 rest after the closing brace. */
98d2ca3d 477 next = next_brace_sub (begin + 1, flags);
5ae9d168 478 if (next == NULL)
787e4db9 479 {
5ae9d168
UD
480 /* It is an illegal expression. */
481#ifndef __GNUC__
482 free (onealt);
483#endif
484 return glob (pattern, flags & ~GLOB_BRACE, errfunc, pglob);
485 }
486
487 /* Now find the end of the whole brace expression. */
488 rest = next;
489 while (*rest != '}')
490 {
98d2ca3d 491 rest = next_brace_sub (rest + 1, flags);
5ae9d168 492 if (rest == NULL)
787e4db9 493 {
5ae9d168
UD
494 /* It is an illegal expression. */
495#ifndef __GNUC__
496 free (onealt);
497#endif
498 return glob (pattern, flags & ~GLOB_BRACE, errfunc, pglob);
6025c399 499 }
6025c399 500 }
5ae9d168
UD
501 /* Please note that we now can be sure the brace expression
502 is well-formed. */
503 rest_len = strlen (++rest) + 1;
6025c399
RM
504
505 /* We have a brace expression. BEGIN points to the opening {,
506 NEXT points past the terminator of the first element, and END
507 points past the final }. We will accumulate result names from
508 recursive runs for each brace alternative in the buffer using
509 GLOB_APPEND. */
510
511 if (!(flags & GLOB_APPEND))
512 {
513 /* This call is to set a new vector, so clear out the
514 vector so we can append to it. */
515 pglob->gl_pathc = 0;
516 pglob->gl_pathv = NULL;
517 }
518 firstc = pglob->gl_pathc;
519
6025c399
RM
520 p = begin + 1;
521 while (1)
522 {
6025c399 523 int result;
5ae9d168
UD
524
525 /* Construct the new glob expression. */
dd7d45e8
UD
526#ifdef HAVE_MEMPCPY
527 mempcpy (mempcpy (alt_start, p, next - p), rest, rest_len);
528#else
5ae9d168
UD
529 memcpy (alt_start, p, next - p);
530 memcpy (&alt_start[next - p], rest, rest_len);
dd7d45e8 531#endif
5ae9d168 532
6025c399 533 result = glob (onealt,
add09583 534 ((flags & ~(GLOB_NOCHECK | GLOB_NOMAGIC))
5ae9d168 535 | GLOB_APPEND), errfunc, pglob);
6025c399
RM
536
537 /* If we got an error, return it. */
538 if (result && result != GLOB_NOMATCH)
787e4db9 539 {
5ae9d168
UD
540#ifndef __GNUC__
541 free (onealt);
542#endif
6025c399 543 if (!(flags & GLOB_APPEND))
03af5793
UD
544 {
545 globfree (pglob);
546 pglob->gl_pathc = 0;
547 }
6025c399
RM
548 return result;
549 }
550
5ae9d168
UD
551 if (*next == '}')
552 /* We saw the last entry. */
553 break;
554
555 p = next + 1;
98d2ca3d 556 next = next_brace_sub (p, flags);
5ae9d168 557 assert (next != NULL);
787e4db9 558 }
6025c399 559
5ae9d168
UD
560#ifndef __GNUC__
561 free (onealt);
562#endif
563
564 if (pglob->gl_pathc != firstc)
565 /* We found some entries. */
566 return 0;
567 else if (!(flags & (GLOB_NOCHECK|GLOB_NOMAGIC)))
6025c399 568 return GLOB_NOMATCH;
787e4db9
RM
569 }
570 }
571
28f540f4
RM
572 /* Find the filename. */
573 filename = strrchr (pattern, '/');
786a5421
UD
574#if defined __MSDOS__ || defined WINDOWS32
575 /* The case of "d:pattern". Since `:' is not allowed in
576 file names, we can safely assume that wherever it
577 happens in pattern, it signals the filename part. This
578 is so we could some day support patterns like "[a-z]:foo". */
579 if (filename == NULL)
580 filename = strchr (pattern, ':');
581#endif /* __MSDOS__ || WINDOWS32 */
28f540f4
RM
582 if (filename == NULL)
583 {
49c091e5 584 /* This can mean two things: a simple name or "~name". The latter
6c202c68 585 case is nothing but a notation for a directory. */
1bc21e7a 586 if ((flags & (GLOB_TILDE|GLOB_TILDE_CHECK)) && pattern[0] == '~')
6c202c68 587 {
7cabd57c 588 dirname = pattern;
6c202c68
UD
589 dirlen = strlen (pattern);
590
c9243dac 591 /* Set FILENAME to NULL as a special flag. This is ugly but
786a5421 592 other solutions would require much more code. We test for
c9243dac
UD
593 this special case below. */
594 filename = NULL;
6c202c68
UD
595 }
596 else
597 {
598 filename = pattern;
9fb16eea 599#ifdef _AMIGA
ec986e23 600 dirname = "";
9fb16eea 601#else
ec986e23 602 dirname = ".";
9fb16eea 603#endif
6c202c68
UD
604 dirlen = 0;
605 }
28f540f4
RM
606 }
607 else if (filename == pattern)
608 {
609 /* "/pattern". */
ec986e23 610 dirname = "/";
28f540f4
RM
611 dirlen = 1;
612 ++filename;
613 }
614 else
615 {
ec986e23 616 char *newp;
28f540f4 617 dirlen = filename - pattern;
786a5421
UD
618#if defined __MSDOS__ || defined WINDOWS32
619 if (*filename == ':'
620 || (filename > pattern + 1 && filename[-1] == ':'))
621 {
622 char *drive_spec;
623
624 ++dirlen;
625 drive_spec = (char *) __alloca (dirlen + 1);
626#ifdef HAVE_MEMPCPY
627 *((char *) mempcpy (drive_spec, pattern, dirlen)) = '\0';
628#else
629 memcpy (drive_spec, pattern, dirlen);
630 drive_spec[dirlen] = '\0';
631#endif
632 /* For now, disallow wildcards in the drive spec, to
633 prevent infinite recursion in glob. */
634 if (__glob_pattern_p (drive_spec, !(flags & GLOB_NOESCAPE)))
635 return GLOB_NOMATCH;
636 /* If this is "d:pattern", we need to copy `:' to DIRNAME
637 as well. If it's "d:/pattern", don't remove the slash
638 from "d:/", since "d:" and "d:/" are not the same.*/
639 }
640#endif
ec986e23 641 newp = (char *) __alloca (dirlen + 1);
dd7d45e8 642#ifdef HAVE_MEMPCPY
ec986e23 643 *((char *) mempcpy (newp, pattern, dirlen)) = '\0';
dd7d45e8 644#else
ec986e23
UD
645 memcpy (newp, pattern, dirlen);
646 newp[dirlen] = '\0';
dd7d45e8 647#endif
ec986e23 648 dirname = newp;
28f540f4 649 ++filename;
28f540f4 650
786a5421
UD
651 if (filename[0] == '\0'
652#if defined __MSDOS__ || defined WINDOWS32
653 && dirname[dirlen - 1] != ':'
654 && (dirlen < 3 || dirname[dirlen - 2] != ':'
655 || dirname[dirlen - 1] != '/')
656#endif
657 && dirlen > 1)
6c202c68
UD
658 /* "pattern/". Expand "pattern", appending slashes. */
659 {
660 int val = glob (dirname, flags | GLOB_MARK, errfunc, pglob);
661 if (val == 0)
662 pglob->gl_flags = ((pglob->gl_flags & ~GLOB_MARK)
663 | (flags & GLOB_MARK));
664 return val;
665 }
28f540f4
RM
666 }
667
668 if (!(flags & GLOB_APPEND))
669 {
670 pglob->gl_pathc = 0;
460adbb8
UD
671 if (!(flags & GLOB_DOOFFS))
672 pglob->gl_pathv = NULL;
673 else
674 {
ec6f8477 675 size_t i;
460adbb8
UD
676 pglob->gl_pathv = (char **) malloc ((pglob->gl_offs + 1)
677 * sizeof (char *));
678 if (pglob->gl_pathv == NULL)
679 return GLOB_NOSPACE;
680
681 for (i = 0; i <= pglob->gl_offs; ++i)
682 pglob->gl_pathv[i] = NULL;
683 }
28f540f4
RM
684 }
685
460adbb8 686 oldcount = pglob->gl_pathc + pglob->gl_offs;
28f540f4 687
0efef8fc 688#ifndef VMS
1bc21e7a 689 if ((flags & (GLOB_TILDE|GLOB_TILDE_CHECK)) && dirname[0] == '~')
787e4db9 690 {
5ae9d168 691 if (dirname[1] == '\0' || dirname[1] == '/')
787e4db9
RM
692 {
693 /* Look up home directory. */
ec986e23 694 const char *home_dir = getenv ("HOME");
61eb22d3 695# ifdef _AMIGA
5ae9d168
UD
696 if (home_dir == NULL || home_dir[0] == '\0')
697 home_dir = "SYS:";
61eb22d3
UD
698# else
699# ifdef WINDOWS32
5ae9d168
UD
700 if (home_dir == NULL || home_dir[0] == '\0')
701 home_dir = "c:/users/default"; /* poor default */
61eb22d3 702# else
5ae9d168 703 if (home_dir == NULL || home_dir[0] == '\0')
787e4db9 704 {
e4cf5070 705 int success;
ec986e23 706 char *name;
61eb22d3 707# if defined HAVE_GETLOGIN_R || defined _LIBC
e4cf5070 708 size_t buflen = sysconf (_SC_LOGIN_NAME_MAX) + 1;
e4cf5070
UD
709
710 if (buflen == 0)
711 /* `sysconf' does not support _SC_LOGIN_NAME_MAX. Try
712 a moderate value. */
ec986e23 713 buflen = 20;
ca34d7a7 714 name = (char *) __alloca (buflen);
e4cf5070
UD
715
716 success = getlogin_r (name, buflen) >= 0;
61eb22d3 717# else
e4cf5070 718 success = (name = getlogin ()) != NULL;
61eb22d3 719# endif
e4cf5070 720 if (success)
787e4db9 721 {
ec986e23 722 struct passwd *p;
61eb22d3 723# if defined HAVE_GETPWNAM_R || defined _LIBC
ec6f8477 724 long int pwbuflen = sysconf (_SC_GETPW_R_SIZE_MAX);
e4cf5070 725 char *pwtmpbuf;
ec986e23 726 struct passwd pwbuf;
13f2ac59 727 int save = errno;
e4cf5070 728
609b4783 729# ifndef _LIBC
ec986e23
UD
730 if (pwbuflen == -1)
731 /* `sysconf' does not support _SC_GETPW_R_SIZE_MAX.
732 Try a moderate value. */
733 pwbuflen = 1024;
609b4783 734# endif
ca34d7a7 735 pwtmpbuf = (char *) __alloca (pwbuflen);
e4cf5070 736
738d1a5a
UD
737 while (getpwnam_r (name, &pwbuf, pwtmpbuf, pwbuflen, &p)
738 != 0)
f6b56b55
UD
739 {
740 if (errno != ERANGE)
741 {
1d863dc0 742 p = NULL;
f6b56b55
UD
743 break;
744 }
609b4783
UD
745# ifdef _LIBC
746 pwtmpbuf = extend_alloca (pwtmpbuf, pwbuflen,
747 2 * pwbuflen);
748# else
f6b56b55
UD
749 pwbuflen *= 2;
750 pwtmpbuf = (char *) __alloca (pwbuflen);
609b4783 751# endif
13f2ac59 752 __set_errno (save);
f6b56b55 753 }
61eb22d3 754# else
ec986e23 755 p = getpwnam (name);
61eb22d3 756# endif
1d863dc0 757 if (p != NULL)
5ae9d168 758 home_dir = p->pw_dir;
787e4db9
RM
759 }
760 }
5ae9d168 761 if (home_dir == NULL || home_dir[0] == '\0')
6e4c40ba
UD
762 {
763 if (flags & GLOB_TILDE_CHECK)
764 return GLOB_NOMATCH;
765 else
766 home_dir = "~"; /* No luck. */
767 }
61eb22d3
UD
768# endif /* WINDOWS32 */
769# endif
5ae9d168
UD
770 /* Now construct the full directory. */
771 if (dirname[1] == '\0')
772 dirname = home_dir;
773 else
774 {
775 char *newp;
776 size_t home_len = strlen (home_dir);
ca34d7a7 777 newp = (char *) __alloca (home_len + dirlen);
dd7d45e8
UD
778# ifdef HAVE_MEMPCPY
779 mempcpy (mempcpy (newp, home_dir, home_len),
780 &dirname[1], dirlen);
781# else
5ae9d168
UD
782 memcpy (newp, home_dir, home_len);
783 memcpy (&newp[home_len], &dirname[1], dirlen);
dd7d45e8 784# endif
5ae9d168
UD
785 dirname = newp;
786 }
787e4db9 787 }
61eb22d3 788# if !defined _AMIGA && !defined WINDOWS32
787e4db9
RM
789 else
790 {
5ae9d168 791 char *end_name = strchr (dirname, '/');
ec986e23
UD
792 const char *user_name;
793 const char *home_dir;
5ae9d168
UD
794
795 if (end_name == NULL)
796 user_name = dirname + 1;
797 else
798 {
ec986e23
UD
799 char *newp;
800 newp = (char *) __alloca (end_name - dirname);
dd7d45e8 801# ifdef HAVE_MEMPCPY
ec986e23 802 *((char *) mempcpy (newp, dirname + 1, end_name - dirname))
dd7d45e8
UD
803 = '\0';
804# else
ec986e23
UD
805 memcpy (newp, dirname + 1, end_name - dirname);
806 newp[end_name - dirname - 1] = '\0';
dd7d45e8 807# endif
ec986e23 808 user_name = newp;
5ae9d168
UD
809 }
810
787e4db9 811 /* Look up specific user's home directory. */
5ae9d168 812 {
ec986e23 813 struct passwd *p;
61eb22d3 814# if defined HAVE_GETPWNAM_R || defined _LIBC
ec6f8477 815 long int buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
ec986e23
UD
816 char *pwtmpbuf;
817 struct passwd pwbuf;
13f2ac59 818 int save = errno;
ec986e23 819
609b4783 820# ifndef _LIBC
ec986e23
UD
821 if (buflen == -1)
822 /* `sysconf' does not support _SC_GETPW_R_SIZE_MAX. Try a
823 moderate value. */
824 buflen = 1024;
609b4783 825# endif
ec986e23
UD
826 pwtmpbuf = (char *) __alloca (buflen);
827
738d1a5a 828 while (getpwnam_r (user_name, &pwbuf, pwtmpbuf, buflen, &p) != 0)
f6b56b55
UD
829 {
830 if (errno != ERANGE)
831 {
832 p = NULL;
833 break;
834 }
609b4783
UD
835# ifdef _LIBC
836 pwtmpbuf = extend_alloca (pwtmpbuf, buflen, 2 * buflen);
837# else
13f2ac59
UD
838 buflen *= 2;
839 pwtmpbuf = __alloca (buflen);
609b4783 840# endif
13f2ac59 841 __set_errno (save);
f6b56b55 842 }
61eb22d3 843# else
ec986e23 844 p = getpwnam (user_name);
f6b56b55 845# endif
5ae9d168
UD
846 if (p != NULL)
847 home_dir = p->pw_dir;
848 else
849 home_dir = NULL;
5ae9d168
UD
850 }
851 /* If we found a home directory use this. */
852 if (home_dir != NULL)
853 {
854 char *newp;
855 size_t home_len = strlen (home_dir);
856 size_t rest_len = end_name == NULL ? 0 : strlen (end_name);
ca34d7a7 857 newp = (char *) __alloca (home_len + rest_len + 1);
dd7d45e8
UD
858# ifdef HAVE_MEMPCPY
859 *((char *) mempcpy (mempcpy (newp, home_dir, home_len),
860 end_name, rest_len)) = '\0';
861# else
5ae9d168
UD
862 memcpy (newp, home_dir, home_len);
863 memcpy (&newp[home_len], end_name, rest_len);
864 newp[home_len + rest_len] = '\0';
dd7d45e8 865# endif
5ae9d168
UD
866 dirname = newp;
867 }
1bc21e7a
UD
868 else
869 if (flags & GLOB_TILDE_CHECK)
870 /* We have to regard it as an error if we cannot find the
871 home directory. */
872 return GLOB_NOMATCH;
787e4db9 873 }
61eb22d3 874# endif /* Not Amiga && not WINDOWS32. */
787e4db9 875 }
0efef8fc 876#endif /* Not VMS. */
787e4db9 877
c9243dac
UD
878 /* Now test whether we looked for "~" or "~NAME". In this case we
879 can give the answer now. */
880 if (filename == NULL)
881 {
882 struct stat st;
460adbb8
UD
883#ifdef HAVE_STAT64
884 struct stat64 st64;
885#endif
c9243dac
UD
886
887 /* Return the directory if we don't check for error or if it exists. */
888 if ((flags & GLOB_NOCHECK)
889 || (((flags & GLOB_ALTDIRFUNC)
460adbb8
UD
890 ? ((*pglob->gl_stat) (dirname, &st) == 0
891 && S_ISDIR (st.st_mode))
892 : (__stat64 (dirname, &st64) == 0 && S_ISDIR (st64.st_mode)))))
c9243dac 893 {
460adbb8 894 int newcount = pglob->gl_pathc + pglob->gl_offs;
d1dddedf 895 char **new_gl_pathv;
460adbb8 896
d1dddedf 897 new_gl_pathv
c9243dac 898 = (char **) realloc (pglob->gl_pathv,
460adbb8 899 (newcount + 1 + 1) * sizeof (char *));
d1dddedf
UD
900 if (new_gl_pathv == NULL)
901 {
902 nospace:
903 free (pglob->gl_pathv);
904 pglob->gl_pathv = NULL;
905 pglob->gl_pathc = 0;
906 return GLOB_NOSPACE;
907 }
908 pglob->gl_pathv = new_gl_pathv;
c9243dac 909
c9243dac 910#if defined HAVE_STRDUP || defined _LIBC
460adbb8 911 pglob->gl_pathv[newcount] = strdup (dirname);
c9243dac
UD
912#else
913 {
914 size_t len = strlen (dirname) + 1;
d1dddedf 915 char *dircopy = (char *) malloc (len);
c9243dac 916 if (dircopy != NULL)
460adbb8 917 pglob->gl_pathv[newcount] = memcpy (dircopy, dirname, len);
c9243dac
UD
918 }
919#endif
460adbb8 920 if (pglob->gl_pathv[newcount] == NULL)
d1dddedf 921 goto nospace;
460adbb8
UD
922 pglob->gl_pathv[++newcount] = NULL;
923 ++pglob->gl_pathc;
c9243dac
UD
924 pglob->gl_flags = flags;
925
926 return 0;
927 }
928
929 /* Not found. */
930 return GLOB_NOMATCH;
931 }
932
e7fd8a39 933 if (__glob_pattern_p (dirname, !(flags & GLOB_NOESCAPE)))
28f540f4
RM
934 {
935 /* The directory name contains metacharacters, so we
936 have to glob for the directory, and then glob for
937 the pattern in each directory found. */
938 glob_t dirs;
ec6f8477 939 size_t i;
28f540f4 940
29332175
UD
941 if ((flags & GLOB_ALTDIRFUNC) != 0)
942 {
943 /* Use the alternative access functions also in the recursive
944 call. */
945 dirs.gl_opendir = pglob->gl_opendir;
946 dirs.gl_readdir = pglob->gl_readdir;
947 dirs.gl_closedir = pglob->gl_closedir;
948 dirs.gl_stat = pglob->gl_stat;
949 dirs.gl_lstat = pglob->gl_lstat;
950 }
951
28f540f4 952 status = glob (dirname,
29332175
UD
953 ((flags & (GLOB_ERR | GLOB_NOCHECK | GLOB_NOESCAPE
954 | GLOB_ALTDIRFUNC))
1cab5444 955 | GLOB_NOSORT | GLOB_ONLYDIR),
28f540f4
RM
956 errfunc, &dirs);
957 if (status != 0)
958 return status;
959
960 /* We have successfully globbed the preceding directory name.
961 For each name we found, call glob_in_dir on it and FILENAME,
962 appending the results to PGLOB. */
963 for (i = 0; i < dirs.gl_pathc; ++i)
964 {
cc60175e 965 int old_pathc;
28f540f4
RM
966
967#ifdef SHELL
968 {
969 /* Make globbing interruptible in the bash shell. */
970 extern int interrupt_state;
971
972 if (interrupt_state)
973 {
974 globfree (&dirs);
714a562f 975 return GLOB_ABORTED;
28f540f4
RM
976 }
977 }
978#endif /* SHELL. */
979
cc60175e 980 old_pathc = pglob->gl_pathc;
28f540f4 981 status = glob_in_dir (filename, dirs.gl_pathv[i],
add09583
UD
982 ((flags | GLOB_APPEND)
983 & ~(GLOB_NOCHECK | GLOB_NOMAGIC)),
28f540f4
RM
984 errfunc, pglob);
985 if (status == GLOB_NOMATCH)
986 /* No matches in this directory. Try the next. */
987 continue;
988
989 if (status != 0)
990 {
991 globfree (&dirs);
992 globfree (pglob);
03af5793 993 pglob->gl_pathc = 0;
28f540f4
RM
994 return status;
995 }
996
997 /* Stick the directory on the front of each name. */
998 if (prefix_array (dirs.gl_pathv[i],
460adbb8 999 &pglob->gl_pathv[old_pathc + pglob->gl_offs],
cc60175e 1000 pglob->gl_pathc - old_pathc))
28f540f4
RM
1001 {
1002 globfree (&dirs);
1003 globfree (pglob);
03af5793 1004 pglob->gl_pathc = 0;
28f540f4
RM
1005 return GLOB_NOSPACE;
1006 }
1007 }
1008
1009 flags |= GLOB_MAGCHAR;
1010
e852e889 1011 /* We have ignored the GLOB_NOCHECK flag in the `glob_in_dir' calls.
460adbb8 1012 But if we have not found any matching entry and the GLOB_NOCHECK
d1dddedf 1013 flag was set we must return the input pattern itself. */
460adbb8 1014 if (pglob->gl_pathc + pglob->gl_offs == oldcount)
6e4c40ba
UD
1015 {
1016 /* No matches. */
1017 if (flags & GLOB_NOCHECK)
1018 {
460adbb8 1019 int newcount = pglob->gl_pathc + pglob->gl_offs;
d1dddedf 1020 char **new_gl_pathv;
6e4c40ba 1021
d1dddedf
UD
1022 new_gl_pathv = (char **) realloc (pglob->gl_pathv,
1023 (newcount + 2)
1024 * sizeof (char *));
1025 if (new_gl_pathv == NULL)
6e4c40ba
UD
1026 {
1027 globfree (&dirs);
1028 return GLOB_NOSPACE;
1029 }
d1dddedf 1030 pglob->gl_pathv = new_gl_pathv;
28f540f4 1031
870a4e12
UD
1032 pglob->gl_pathv[newcount] = __strdup (pattern);
1033 if (pglob->gl_pathv[newcount] == NULL)
6e4c40ba 1034 {
870a4e12
UD
1035 globfree (&dirs);
1036 globfree (pglob);
03af5793 1037 pglob->gl_pathc = 0;
870a4e12 1038 return GLOB_NOSPACE;
6e4c40ba 1039 }
e852e889 1040
870a4e12
UD
1041 ++pglob->gl_pathc;
1042 ++newcount;
1043
460adbb8 1044 pglob->gl_pathv[newcount] = NULL;
6e4c40ba 1045 pglob->gl_flags = flags;
6e4c40ba
UD
1046 }
1047 else
1338451b
AJ
1048 {
1049 globfree (&dirs);
1050 return GLOB_NOMATCH;
1051 }
6e4c40ba 1052 }
e852e889
UD
1053
1054 globfree (&dirs);
28f540f4
RM
1055 }
1056 else
1057 {
460adbb8
UD
1058 int old_pathc = pglob->gl_pathc;
1059
28f540f4
RM
1060 status = glob_in_dir (filename, dirname, flags, errfunc, pglob);
1061 if (status != 0)
1062 return status;
1063
1064 if (dirlen > 0)
1065 {
1066 /* Stick the directory on the front of each name. */
1067 if (prefix_array (dirname,
460adbb8
UD
1068 &pglob->gl_pathv[old_pathc + pglob->gl_offs],
1069 pglob->gl_pathc - old_pathc))
28f540f4
RM
1070 {
1071 globfree (pglob);
03af5793 1072 pglob->gl_pathc = 0;
28f540f4
RM
1073 return GLOB_NOSPACE;
1074 }
1075 }
1076 }
1077
bf3ccd1a
RM
1078 if (flags & GLOB_MARK)
1079 {
c043db7a 1080 /* Append slashes to directory names. */
ec6f8477 1081 size_t i;
bf3ccd1a 1082 struct stat st;
460adbb8
UD
1083#ifdef HAVE_STAT64
1084 struct stat64 st64;
1085#endif
1086
1087 for (i = oldcount; i < pglob->gl_pathc + pglob->gl_offs; ++i)
a9ddb793 1088 if (((flags & GLOB_ALTDIRFUNC)
460adbb8
UD
1089 ? ((*pglob->gl_stat) (pglob->gl_pathv[i], &st) == 0
1090 && S_ISDIR (st.st_mode))
1091 : (__stat64 (pglob->gl_pathv[i], &st64) == 0
1092 && S_ISDIR (st64.st_mode))))
a993273c
RM
1093 {
1094 size_t len = strlen (pglob->gl_pathv[i]) + 2;
1095 char *new = realloc (pglob->gl_pathv[i], len);
1096 if (new == NULL)
1097 {
1098 globfree (pglob);
03af5793 1099 pglob->gl_pathc = 0;
a993273c
RM
1100 return GLOB_NOSPACE;
1101 }
1102 strcpy (&new[len - 2], "/");
1103 pglob->gl_pathv[i] = new;
1104 }
bf3ccd1a
RM
1105 }
1106
28f540f4 1107 if (!(flags & GLOB_NOSORT))
cc60175e
UD
1108 {
1109 /* Sort the vector. */
460adbb8
UD
1110 qsort ((__ptr_t) &pglob->gl_pathv[oldcount],
1111 pglob->gl_pathc + pglob->gl_offs - oldcount,
cc60175e
UD
1112 sizeof (char *), collated_compare);
1113 }
28f540f4
RM
1114
1115 return 0;
1116}
855efb5f 1117#if defined _LIBC && !defined glob
c41f555e
RM
1118libc_hidden_def (glob)
1119#endif
28f540f4
RM
1120
1121
60f0e64b
UD
1122#if !defined _LIBC || !defined GLOB_ONLY_P
1123
28f540f4
RM
1124/* Free storage allocated in PGLOB by a previous `glob' call. */
1125void
1126globfree (pglob)
1127 register glob_t *pglob;
1128{
1129 if (pglob->gl_pathv != NULL)
1130 {
ec6f8477 1131 size_t i;
28f540f4 1132 for (i = 0; i < pglob->gl_pathc; ++i)
460adbb8
UD
1133 if (pglob->gl_pathv[pglob->gl_offs + i] != NULL)
1134 free ((__ptr_t) pglob->gl_pathv[pglob->gl_offs + i]);
28f540f4
RM
1135 free ((__ptr_t) pglob->gl_pathv);
1136 }
1137}
855efb5f 1138#if defined _LIBC && !defined globfree
c41f555e
RM
1139libc_hidden_def (globfree)
1140#endif
28f540f4
RM
1141
1142
1143/* Do a collated comparison of A and B. */
1144static int
1145collated_compare (a, b)
1146 const __ptr_t a;
1147 const __ptr_t b;
1148{
1149 const char *const s1 = *(const char *const * const) a;
1150 const char *const s2 = *(const char *const * const) b;
1151
1152 if (s1 == s2)
1153 return 0;
1154 if (s1 == NULL)
1155 return 1;
1156 if (s2 == NULL)
1157 return -1;
1158 return strcoll (s1, s2);
1159}
1160
1161
1162/* Prepend DIRNAME to each of N members of ARRAY, replacing ARRAY's
1163 elements in place. Return nonzero if out of memory, zero if successful.
1164 A slash is inserted between DIRNAME and each elt of ARRAY,
1165 unless DIRNAME is just "/". Each old element of ARRAY is freed. */
1166static int
1167prefix_array (dirname, array, n)
1168 const char *dirname;
1169 char **array;
1170 size_t n;
1171{
1172 register size_t i;
1173 size_t dirlen = strlen (dirname);
786a5421
UD
1174#if defined __MSDOS__ || defined WINDOWS32
1175 int sep_char = '/';
1176# define DIRSEP_CHAR sep_char
1177#else
1178# define DIRSEP_CHAR '/'
1179#endif
28f540f4
RM
1180
1181 if (dirlen == 1 && dirname[0] == '/')
1182 /* DIRNAME is just "/", so normal prepending would get us "//foo".
1183 We want "/foo" instead, so don't prepend any chars from DIRNAME. */
1184 dirlen = 0;
786a5421
UD
1185#if defined __MSDOS__ || defined WINDOWS32
1186 else if (dirlen > 1)
1187 {
ea1bfb07 1188 if (dirname[dirlen - 1] == '/' && dirname[dirlen - 2] == ':')
786a5421
UD
1189 /* DIRNAME is "d:/". Don't prepend the slash from DIRNAME. */
1190 --dirlen;
1191 else if (dirname[dirlen - 1] == ':')
1192 {
1193 /* DIRNAME is "d:". Use `:' instead of `/'. */
1194 --dirlen;
1195 sep_char = ':';
1196 }
1197 }
1198#endif
28f540f4
RM
1199
1200 for (i = 0; i < n; ++i)
1201 {
1202 size_t eltlen = strlen (array[i]) + 1;
1203 char *new = (char *) malloc (dirlen + 1 + eltlen);
1204 if (new == NULL)
1205 {
1206 while (i > 0)
1207 free ((__ptr_t) array[--i]);
1208 return 1;
1209 }
1210
dd7d45e8
UD
1211#ifdef HAVE_MEMPCPY
1212 {
1213 char *endp = (char *) mempcpy (new, dirname, dirlen);
786a5421 1214 *endp++ = DIRSEP_CHAR;
dd7d45e8
UD
1215 mempcpy (endp, array[i], eltlen);
1216 }
1217#else
28f540f4 1218 memcpy (new, dirname, dirlen);
786a5421 1219 new[dirlen] = DIRSEP_CHAR;
28f540f4 1220 memcpy (&new[dirlen + 1], array[i], eltlen);
dd7d45e8 1221#endif
28f540f4
RM
1222 free ((__ptr_t) array[i]);
1223 array[i] = new;
1224 }
1225
1226 return 0;
1227}
1228
1229
a5f4e34a 1230/* We must not compile this function twice. */
1f539fd1 1231#if !defined _LIBC || !defined NO_GLOB_PATTERN_P
28f540f4
RM
1232/* Return nonzero if PATTERN contains any metacharacters.
1233 Metacharacters can be quoted with backslashes if QUOTE is nonzero. */
e7fd8a39
UD
1234int
1235__glob_pattern_p (pattern, quote)
28f540f4
RM
1236 const char *pattern;
1237 int quote;
1238{
1239 register const char *p;
1240 int open = 0;
1241
1242 for (p = pattern; *p != '\0'; ++p)
1243 switch (*p)
1244 {
1245 case '?':
1246 case '*':
1247 return 1;
1248
1249 case '\\':
299a95b9 1250 if (quote && p[1] != '\0')
28f540f4
RM
1251 ++p;
1252 break;
1253
1254 case '[':
1255 open = 1;
1256 break;
1257
1258 case ']':
1259 if (open)
1260 return 1;
1261 break;
1262 }
1263
1264 return 0;
1265}
a5f4e34a 1266# ifdef _LIBC
e7fd8a39 1267weak_alias (__glob_pattern_p, glob_pattern_p)
a5f4e34a 1268# endif
e7fd8a39 1269#endif
28f540f4 1270
60f0e64b
UD
1271#endif /* !GLOB_ONLY_P */
1272
28f540f4
RM
1273
1274/* Like `glob', but PATTERN is a final pathname component,
1275 and matches are searched for in DIRECTORY.
1276 The GLOB_NOSORT bit in FLAGS is ignored. No sorting is ever done.
1277 The GLOB_APPEND flag is assumed to be set (always appends). */
1278static int
1279glob_in_dir (pattern, directory, flags, errfunc, pglob)
1280 const char *pattern;
1281 const char *directory;
1282 int flags;
1283 int (*errfunc) __P ((const char *, int));
1284 glob_t *pglob;
1285{
a9ddb793 1286 __ptr_t stream = NULL;
28f540f4
RM
1287 struct globlink
1288 {
1289 struct globlink *next;
1290 char *name;
1291 };
1292 struct globlink *names = NULL;
86187531
UD
1293 size_t nfound;
1294 int meta;
1295 int save;
1296
a9ddb793 1297 meta = __glob_pattern_p (pattern, !(flags & GLOB_NOESCAPE));
460adbb8 1298 if (meta == 0 && (flags & (GLOB_NOCHECK|GLOB_NOMAGIC)))
28f540f4 1299 {
460adbb8
UD
1300 /* We need not do any tests. The PATTERN contains no meta
1301 characters and we must not return an error therefore the
1302 result will always contain exactly one name. */
1303 flags |= GLOB_NOCHECK;
1304 nfound = 0;
1305 }
1306 else if (meta == 0 &&
98d2ca3d 1307 ((flags & GLOB_NOESCAPE) || strchr (pattern, '\\') == NULL))
460adbb8
UD
1308 {
1309 /* Since we use the normal file functions we can also use stat()
1310 to verify the file is there. */
1311 struct stat st;
1312# ifdef HAVE_STAT64
1313 struct stat64 st64;
1314# endif
1315 size_t patlen = strlen (pattern);
1316 size_t dirlen = strlen (directory);
1317 char *fullname = (char *) __alloca (dirlen + 1 + patlen + 1);
a9ddb793
UD
1318
1319# ifdef HAVE_MEMPCPY
460adbb8
UD
1320 mempcpy (mempcpy (mempcpy (fullname, directory, dirlen),
1321 "/", 1),
1322 pattern, patlen + 1);
a9ddb793 1323# else
460adbb8
UD
1324 memcpy (fullname, directory, dirlen);
1325 fullname[dirlen] = '/';
1326 memcpy (&fullname[dirlen + 1], pattern, patlen + 1);
a9ddb793 1327# endif
460adbb8
UD
1328 if (((flags & GLOB_ALTDIRFUNC)
1329 ? (*pglob->gl_stat) (fullname, &st)
1330 : __stat64 (fullname, &st64)) == 0)
1331 /* We found this file to be existing. Now tell the rest
1332 of the function to copy this name into the result. */
1333 flags |= GLOB_NOCHECK;
a9ddb793 1334
86187531 1335 nfound = 0;
28f540f4
RM
1336 }
1337 else
1338 {
a9ddb793 1339 if (pattern[0] == '\0')
28f540f4 1340 {
a9ddb793
UD
1341 /* This is a special case for matching directories like in
1342 "*a/". */
1343 names = (struct globlink *) __alloca (sizeof (struct globlink));
1344 names->name = (char *) malloc (1);
1345 if (names->name == NULL)
1346 goto memory_error;
1347 names->name[0] = '\0';
1348 names->next = NULL;
1349 nfound = 1;
1350 meta = 0;
1351 }
1352 else
1353 {
1354 stream = ((flags & GLOB_ALTDIRFUNC)
1355 ? (*pglob->gl_opendir) (directory)
1356 : (__ptr_t) opendir (directory));
1357 if (stream == NULL)
1358 {
64736128
UD
1359 if (errno != ENOTDIR
1360 && ((errfunc != NULL && (*errfunc) (directory, errno))
1361 || (flags & GLOB_ERR)))
a9ddb793
UD
1362 return GLOB_ABORTED;
1363 nfound = 0;
1364 meta = 0;
1365 }
1366 else
1367 {
1368 int fnm_flags = ((!(flags & GLOB_PERIOD) ? FNM_PERIOD : 0)
1369 | ((flags & GLOB_NOESCAPE) ? FNM_NOESCAPE : 0)
1370#if defined _AMIGA || defined VMS
609b4783 1371 | FNM_CASEFOLD
a9ddb793 1372#endif
609b4783 1373 );
a9ddb793
UD
1374 nfound = 0;
1375 flags |= GLOB_MAGCHAR;
1376
1377 while (1)
1378 {
1379 const char *name;
1380 size_t len;
2958e6cc
UD
1381#if defined HAVE_DIRENT64 && !defined COMPILE_GLOB64
1382 struct dirent64 *d;
ffa8d2a0
RM
1383 union
1384 {
1385 struct dirent64 d64;
1386 char room [offsetof (struct dirent64, d_name[0])
1387 + NAME_MAX + 1];
1388 }
1389 d64buf;
2958e6cc
UD
1390
1391 if (flags & GLOB_ALTDIRFUNC)
1392 {
1393 struct dirent *d32 = (*pglob->gl_readdir) (stream);
1394 if (d32 != NULL)
1395 {
ffa8d2a0
RM
1396 CONVERT_DIRENT_DIRENT64 (&d64buf.d64, d32);
1397 d = &d64buf.d64;
2958e6cc
UD
1398 }
1399 else
1400 d = NULL;
1401 }
1402 else
1403 d = __readdir64 ((DIR *) stream);
1404#else
1405 struct dirent *d = ((flags & GLOB_ALTDIRFUNC)
1406 ? ((struct dirent *)
1407 (*pglob->gl_readdir) (stream))
1408 : __readdir ((DIR *) stream));
1409#endif
a9ddb793
UD
1410 if (d == NULL)
1411 break;
1412 if (! REAL_DIR_ENTRY (d))
1413 continue;
787e4db9 1414
1cab5444 1415#ifdef HAVE_D_TYPE
a9ddb793
UD
1416 /* If we shall match only directories use the information
1417 provided by the dirent call if possible. */
1418 if ((flags & GLOB_ONLYDIR)
1fb2614a
UD
1419 && d->d_type != DT_UNKNOWN
1420 && d->d_type != DT_DIR
1421 && d->d_type != DT_LNK)
a9ddb793 1422 continue;
1cab5444
UD
1423#endif
1424
a9ddb793 1425 name = d->d_name;
86187531 1426
a9ddb793
UD
1427 if (fnmatch (pattern, name, fnm_flags) == 0)
1428 {
1429 struct globlink *new = (struct globlink *)
1430 __alloca (sizeof (struct globlink));
1431 len = NAMLEN (d);
1432 new->name = (char *) malloc (len + 1);
1433 if (new->name == NULL)
1434 goto memory_error;
dd7d45e8 1435#ifdef HAVE_MEMPCPY
a9ddb793
UD
1436 *((char *) mempcpy ((__ptr_t) new->name, name, len))
1437 = '\0';
dd7d45e8 1438#else
a9ddb793
UD
1439 memcpy ((__ptr_t) new->name, name, len);
1440 new->name[len] = '\0';
dd7d45e8 1441#endif
a9ddb793
UD
1442 new->next = names;
1443 names = new;
1444 ++nfound;
1445 }
1446 }
86187531
UD
1447 }
1448 }
28f540f4
RM
1449 }
1450
1451 if (nfound == 0 && (flags & GLOB_NOCHECK))
1452 {
1453 size_t len = strlen (pattern);
1454 nfound = 1;
1455 names = (struct globlink *) __alloca (sizeof (struct globlink));
1456 names->next = NULL;
a993273c 1457 names->name = (char *) malloc (len + 1);
28f540f4
RM
1458 if (names->name == NULL)
1459 goto memory_error;
dd7d45e8
UD
1460#ifdef HAVE_MEMPCPY
1461 *((char *) mempcpy (names->name, pattern, len)) = '\0';
1462#else
28f540f4 1463 memcpy (names->name, pattern, len);
28f540f4 1464 names->name[len] = '\0';
dd7d45e8 1465#endif
28f540f4
RM
1466 }
1467
61eb22d3
UD
1468 if (nfound != 0)
1469 {
d1dddedf
UD
1470 char **new_gl_pathv;
1471
1472 new_gl_pathv
61eb22d3 1473 = (char **) realloc (pglob->gl_pathv,
460adbb8
UD
1474 (pglob->gl_pathc + pglob->gl_offs + nfound + 1)
1475 * sizeof (char *));
d1dddedf 1476 if (new_gl_pathv == NULL)
61eb22d3 1477 goto memory_error;
d1dddedf 1478 pglob->gl_pathv = new_gl_pathv;
28f540f4 1479
61eb22d3 1480 for (; names != NULL; names = names->next)
460adbb8
UD
1481 pglob->gl_pathv[pglob->gl_offs + pglob->gl_pathc++] = names->name;
1482 pglob->gl_pathv[pglob->gl_offs + pglob->gl_pathc] = NULL;
28f540f4 1483
61eb22d3
UD
1484 pglob->gl_flags = flags;
1485 }
28f540f4 1486
86187531 1487 save = errno;
a9ddb793 1488 if (stream != NULL)
6e4c40ba
UD
1489 {
1490 if (flags & GLOB_ALTDIRFUNC)
1491 (*pglob->gl_closedir) (stream);
1492 else
1493 closedir ((DIR *) stream);
1494 }
86187531
UD
1495 __set_errno (save);
1496
28f540f4
RM
1497 return nfound == 0 ? GLOB_NOMATCH : 0;
1498
1499 memory_error:
1500 {
1501 int save = errno;
787e4db9
RM
1502 if (flags & GLOB_ALTDIRFUNC)
1503 (*pglob->gl_closedir) (stream);
28f540f4 1504 else
faf92f2a 1505 closedir ((DIR *) stream);
c4029823 1506 __set_errno (save);
28f540f4
RM
1507 }
1508 while (names != NULL)
1509 {
1510 if (names->name != NULL)
1511 free ((__ptr_t) names->name);
1512 names = names->next;
1513 }
1514 return GLOB_NOSPACE;
1515}
1516
787e4db9 1517#endif /* Not ELIDE_CODE. */