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