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