1/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3
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.
8
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public
15 License along with the GNU C Library; if not, see
16 <http://www.gnu.org/licenses/>. */
17
18#ifndef _LIBC
19# include <config.h>
20#endif
21
22#include <glob.h>
23
24#include <errno.h>
25#include <sys/types.h>
26#include <sys/stat.h>
27#include <stdbool.h>
28#include <stddef.h>
29#include <stdint.h>
30#include <assert.h>
31#include <unistd.h>
32
33#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
34# define WINDOWS32
35#endif
36
37#ifndef WINDOWS32
38# include <pwd.h>
39#endif
40
41#include <errno.h>
42#ifndef __set_errno
43# define __set_errno(val) errno = (val)
44#endif
45
46#include <dirent.h>
47#include <stdlib.h>
48#include <string.h>
49#include <alloca.h>
50
51#ifdef _LIBC
52# undef strdup
53# define strdup(str) __strdup (str)
54# define sysconf(id) __sysconf (id)
55# define closedir(dir) __closedir (dir)
56# define opendir(name) __opendir (name)
57# define readdir(str) __readdir64 (str)
58# define getpwnam_r(name, bufp, buf, len, res) \
59 __getpwnam_r (name, bufp, buf, len, res)
60# ifndef __stat64
61# define __stat64(fname, buf) __xstat64 (_STAT_VER, fname, buf)
62# endif
63# define struct_stat64 struct stat64
64# define FLEXIBLE_ARRAY_MEMBER
65#else /* !_LIBC */
66# define __getlogin_r(buf, len) getlogin_r (buf, len)
67# define __stat64(fname, buf) stat (fname, buf)
68# define __fxstatat64(_, d, f, st, flag) fstatat (d, f, st, flag)
69# define struct_stat64 struct stat
70# ifndef __MVS__
71# define __alloca alloca
72# endif
73# define __readdir readdir
74# define COMPILE_GLOB64
75#endif /* _LIBC */
76
77#include <fnmatch.h>
78
79#include <flexmember.h>
80#include <glob_internal.h>
81
82#ifdef _SC_GETPW_R_SIZE_MAX
83# define GETPW_R_SIZE_MAX() sysconf (_SC_GETPW_R_SIZE_MAX)
84#else
85# define GETPW_R_SIZE_MAX() (-1)
86#endif
87#ifdef _SC_LOGIN_NAME_MAX
88# define GET_LOGIN_NAME_MAX() sysconf (_SC_LOGIN_NAME_MAX)
89#else
90# define GET_LOGIN_NAME_MAX() (-1)
91#endif
92
93static const char *next_brace_sub (const char *begin, int flags) __THROWNL;
94
95typedef uint_fast8_t dirent_type;
96
97#if !defined _LIBC && !defined HAVE_STRUCT_DIRENT_D_TYPE
98/* Any distinct values will do here.
99 Undef any existing macros out of the way. */
100# undef DT_UNKNOWN
101# undef DT_DIR
102# undef DT_LNK
103# define DT_UNKNOWN 0
104# define DT_DIR 1
105# define DT_LNK 2
106#endif
107
108/* A representation of a directory entry which does not depend on the
109 layout of struct dirent, or the size of ino_t. */
110struct readdir_result
111{
112 const char *name;
113#if defined _DIRENT_HAVE_D_TYPE || defined HAVE_STRUCT_DIRENT_D_TYPE
114 dirent_type type;
115#endif
116#if defined _LIBC || defined D_INO_IN_DIRENT
117 bool skip_entry;
118#endif
119};
120
121/* Initialize and return type member of struct readdir_result. */
122static dirent_type
123readdir_result_type (struct readdir_result d)
124{
125#if defined _DIRENT_HAVE_D_TYPE || defined HAVE_STRUCT_DIRENT_D_TYPE
126# define D_TYPE_TO_RESULT(source) (source)->d_type,
127 return d.type;
128#else
129# define D_TYPE_TO_RESULT(source)
130 return DT_UNKNOWN;
131#endif
132}
133
134/* Initialize and return skip_entry member of struct readdir_result. */
135static bool
136readdir_result_skip_entry (struct readdir_result d)
137{
138/* Initializer for skip_entry. POSIX does not require that the d_ino
139 field be present, and some systems do not provide it. */
140#if defined _LIBC || defined D_INO_IN_DIRENT
141# define D_INO_TO_RESULT(source) (source)->d_ino == 0,
142 return d.skip_entry;
143#else
144# define D_INO_TO_RESULT(source)
145 return false;
146#endif
147}
148
149/* Construct an initializer for a struct readdir_result object from a
150 struct dirent *. No copy of the name is made. */
151#define READDIR_RESULT_INITIALIZER(source) \
152 { \
153 source->d_name, \
154 D_TYPE_TO_RESULT (source) \
155 D_INO_TO_RESULT (source) \
156 }
157
158/* Call gl_readdir on STREAM. This macro can be overridden to reduce
159 type safety if an old interface version needs to be supported. */
160#ifndef GL_READDIR
161# define GL_READDIR(pglob, stream) ((pglob)->gl_readdir (stream))
162#endif
163
164/* Extract name and type from directory entry. No copy of the name is
165 made. If SOURCE is NULL, result name is NULL. Keep in sync with
166 convert_dirent64 below. */
167static struct readdir_result
168convert_dirent (const struct dirent *source)
169{
170 if (source == NULL)
171 {
172 struct readdir_result result = { NULL, };
173 return result;
174 }
175 struct readdir_result result = READDIR_RESULT_INITIALIZER (source);
176 return result;
177}
178
179#ifndef COMPILE_GLOB64
180/* Like convert_dirent, but works on struct dirent64 instead. Keep in
181 sync with convert_dirent above. */
182static struct readdir_result
183convert_dirent64 (const struct dirent64 *source)
184{
185 if (source == NULL)
186 {
187 struct readdir_result result = { NULL, };
188 return result;
189 }
190 struct readdir_result result = READDIR_RESULT_INITIALIZER (source);
191 return result;
192}
193#endif
194
195#ifndef _LIBC
196/* The results of opendir() in this file are not used with dirfd and fchdir,
197 and we do not leak fds to any single-threaded code that could use stdio,
198 therefore save some unnecessary recursion in fchdir.c and opendir_safer.c.
199 FIXME - if the kernel ever adds support for multi-thread safety for
200 avoiding standard fds, then we should use opendir_safer. */
201# ifdef GNULIB_defined_opendir
202# undef opendir
203# endif
204# ifdef GNULIB_defined_closedir
205# undef closedir
206# endif
207
208/* Just use malloc. */
209# define __libc_use_alloca(n) false
210# define alloca_account(len, avar) ((void) (len), (void) (avar), (void *) 0)
211# define extend_alloca_account(buf, len, newlen, avar) \
212 ((void) (buf), (void) (len), (void) (newlen), (void) (avar), (void *) 0)
213#endif
214
215/* Set *R = A + B. Return true if the answer is mathematically
216 incorrect due to overflow; in this case, *R is the low order
217 bits of the correct answer. */
218
219static bool
220size_add_wrapv (size_t a, size_t b, size_t *r)
221{
222#if 5 <= __GNUC__ && !defined __ICC
223 return __builtin_add_overflow (a, b, r);
224#else
225 *r = a + b;
226 return *r < a;
227#endif
228}
229
230static bool
231glob_use_alloca (size_t alloca_used, size_t len)
232{
233 size_t size;
234 return (!size_add_wrapv (alloca_used, len, &size)
235 && __libc_use_alloca (size));
236}
237
238static int glob_in_dir (const char *pattern, const char *directory,
239 int flags, int (*errfunc) (const char *, int),
240 glob_t *pglob, size_t alloca_used);
241extern int __glob_pattern_type (const char *pattern, int quote)
242 attribute_hidden;
243
244static int prefix_array (const char *prefix, char **array, size_t n) __THROWNL;
245static int collated_compare (const void *, const void *) __THROWNL;
246
247
248/* Find the end of the sub-pattern in a brace expression. */
249static const char *
250next_brace_sub (const char *cp, int flags)
251{
252 size_t depth = 0;
253 while (*cp != '\0')
254 if ((flags & GLOB_NOESCAPE) == 0 && *cp == '\\')
255 {
256 if (*++cp == '\0')
257 break;
258 ++cp;
259 }
260 else
261 {
262 if ((*cp == '}' && depth-- == 0) || (*cp == ',' && depth == 0))
263 break;
264
265 if (*cp++ == '{')
266 depth++;
267 }
268
269 return *cp != '\0' ? cp : NULL;
270}
271
272
273/* Do glob searching for PATTERN, placing results in PGLOB.
274 The bits defined above may be set in FLAGS.
275 If a directory cannot be opened or read and ERRFUNC is not nil,
276 it is called with the pathname that caused the error, and the
277 'errno' value from the failing call; if it returns non-zero
278 'glob' returns GLOB_ABORTED; if it returns zero, the error is ignored.
279 If memory cannot be allocated for PGLOB, GLOB_NOSPACE is returned.
280 Otherwise, 'glob' returns zero. */
281int
282#ifdef GLOB_ATTRIBUTE
283GLOB_ATTRIBUTE
284#endif
285glob (const char *pattern, int flags, int (*errfunc) (const char *, int),
286 glob_t *pglob)
287{
288 const char *filename;
289 char *dirname = NULL;
290 size_t dirlen;
291 int status;
292 size_t oldcount;
293 int meta;
294 int dirname_modified;
295 int malloc_dirname = 0;
296 glob_t dirs;
297 int retval = 0;
298 size_t alloca_used = 0;
299
300 if (pattern == NULL || pglob == NULL || (flags & ~__GLOB_FLAGS) != 0)
301 {
302 __set_errno (EINVAL);
303 return -1;
304 }
305
306 /* POSIX requires all slashes to be matched. This means that with
307 a trailing slash we must match only directories. */
308 if (pattern[0] && pattern[strlen (pattern) - 1] == '/')
309 flags |= GLOB_ONLYDIR;
310
311 if (!(flags & GLOB_DOOFFS))
312 /* Have to do this so 'globfree' knows where to start freeing. It
313 also makes all the code that uses gl_offs simpler. */
314 pglob->gl_offs = 0;
315
316 if (flags & GLOB_BRACE)
317 {
318 const char *begin;
319
320 if (flags & GLOB_NOESCAPE)
321 begin = strchr (pattern, '{');
322 else
323 {
324 begin = pattern;
325 while (1)
326 {
327 if (*begin == '\0')
328 {
329 begin = NULL;
330 break;
331 }
332
333 if (*begin == '\\' && begin[1] != '\0')
334 ++begin;
335 else if (*begin == '{')
336 break;
337
338 ++begin;
339 }
340 }
341
342 if (begin != NULL)
343 {
344 /* Allocate working buffer large enough for our work. Note that
345 we have at least an opening and closing brace. */
346 size_t firstc;
347 char *alt_start;
348 const char *p;
349 const char *next;
350 const char *rest;
351 size_t rest_len;
352 char *onealt;
353 size_t pattern_len = strlen (pattern) - 1;
354 int alloca_onealt = glob_use_alloca (alloca_used, pattern_len);
355 if (alloca_onealt)
356 onealt = alloca_account (pattern_len, alloca_used);
357 else
358 {
359 onealt = malloc (pattern_len);
360 if (onealt == NULL)
361 {
362 if (!(flags & GLOB_APPEND))
363 {
364 pglob->gl_pathc = 0;
365 pglob->gl_pathv = NULL;
366 }
367 return GLOB_NOSPACE;
368 }
369 }
370
371 /* We know the prefix for all sub-patterns. */
372 alt_start = mempcpy (onealt, pattern, begin - pattern);
373
374 /* Find the first sub-pattern and at the same time find the
375 rest after the closing brace. */
376 next = next_brace_sub (begin + 1, flags);
377 if (next == NULL)
378 {
379 /* It is an invalid expression. */
380 illegal_brace:
381 if (__glibc_unlikely (!alloca_onealt))
382 free (onealt);
383 return glob (pattern, flags & ~GLOB_BRACE, errfunc, pglob);
384 }
385
386 /* Now find the end of the whole brace expression. */
387 rest = next;
388 while (*rest != '}')
389 {
390 rest = next_brace_sub (rest + 1, flags);
391 if (rest == NULL)
392 /* It is an illegal expression. */
393 goto illegal_brace;
394 }
395 /* Please note that we now can be sure the brace expression
396 is well-formed. */
397 rest_len = strlen (++rest) + 1;
398
399 /* We have a brace expression. BEGIN points to the opening {,
400 NEXT points past the terminator of the first element, and END
401 points past the final }. We will accumulate result names from
402 recursive runs for each brace alternative in the buffer using
403 GLOB_APPEND. */
404
405 if (!(flags & GLOB_APPEND))
406 {
407 /* This call is to set a new vector, so clear out the
408 vector so we can append to it. */
409 pglob->gl_pathc = 0;
410 pglob->gl_pathv = NULL;
411 }
412 firstc = pglob->gl_pathc;
413
414 p = begin + 1;
415 while (1)
416 {
417 int result;
418
419 /* Construct the new glob expression. */
420 mempcpy (mempcpy (alt_start, p, next - p), rest, rest_len);
421
422 result = glob (onealt,
423 ((flags & ~(GLOB_NOCHECK | GLOB_NOMAGIC))
424 | GLOB_APPEND), errfunc, pglob);
425
426 /* If we got an error, return it. */
427 if (result && result != GLOB_NOMATCH)
428 {
429 if (__glibc_unlikely (!alloca_onealt))
430 free (onealt);
431 if (!(flags & GLOB_APPEND))
432 {
433 globfree (pglob);
434 pglob->gl_pathc = 0;
435 }
436 return result;
437 }
438
439 if (*next == '}')
440 /* We saw the last entry. */
441 break;
442
443 p = next + 1;
444 next = next_brace_sub (p, flags);
445 assert (next != NULL);
446 }
447
448 if (__glibc_unlikely (!alloca_onealt))
449 free (onealt);
450
451 if (pglob->gl_pathc != firstc)
452 /* We found some entries. */
453 return 0;
454 else if (!(flags & (GLOB_NOCHECK|GLOB_NOMAGIC)))
455 return GLOB_NOMATCH;
456 }
457 }
458
459 if (!(flags & GLOB_APPEND))
460 {
461 pglob->gl_pathc = 0;
462 if (!(flags & GLOB_DOOFFS))
463 pglob->gl_pathv = NULL;
464 else
465 {
466 size_t i;
467
468 if (pglob->gl_offs >= ~((size_t) 0) / sizeof (char *))
469 return GLOB_NOSPACE;
470
471 pglob->gl_pathv = (char **) malloc ((pglob->gl_offs + 1)
472 * sizeof (char *));
473 if (pglob->gl_pathv == NULL)
474 return GLOB_NOSPACE;
475
476 for (i = 0; i <= pglob->gl_offs; ++i)
477 pglob->gl_pathv[i] = NULL;
478 }
479 }
480
481 oldcount = pglob->gl_pathc + pglob->gl_offs;
482
483 /* Find the filename. */
484 filename = strrchr (pattern, '/');
485
486#if defined __MSDOS__ || defined WINDOWS32
487 /* The case of "d:pattern". Since ':' is not allowed in
488 file names, we can safely assume that wherever it
489 happens in pattern, it signals the filename part. This
490 is so we could some day support patterns like "[a-z]:foo". */
491 if (filename == NULL)
492 filename = strchr (pattern, ':');
493#endif /* __MSDOS__ || WINDOWS32 */
494
495 dirname_modified = 0;
496 if (filename == NULL)
497 {
498 /* This can mean two things: a simple name or "~name". The latter
499 case is nothing but a notation for a directory. */
500 if ((flags & (GLOB_TILDE|GLOB_TILDE_CHECK)) && pattern[0] == '~')
501 {
502 dirname = (char *) pattern;
503 dirlen = strlen (pattern);
504
505 /* Set FILENAME to NULL as a special flag. This is ugly but
506 other solutions would require much more code. We test for
507 this special case below. */
508 filename = NULL;
509 }
510 else
511 {
512 if (__glibc_unlikely (pattern[0] == '\0'))
513 {
514 dirs.gl_pathv = NULL;
515 goto no_matches;
516 }
517
518 filename = pattern;
519 dirname = (char *) ".";
520 dirlen = 0;
521 }
522 }
523 else if (filename == pattern
524 || (filename == pattern + 1 && pattern[0] == '\\'
525 && (flags & GLOB_NOESCAPE) == 0))
526 {
527 /* "/pattern" or "\\/pattern". */
528 dirname = (char *) "/";
529 dirlen = 1;
530 ++filename;
531 }
532 else
533 {
534 char *newp;
535 dirlen = filename - pattern;
536#if defined __MSDOS__ || defined WINDOWS32
537 if (*filename == ':'
538 || (filename > pattern + 1 && filename[-1] == ':'))
539 {
540 char *drive_spec;
541
542 ++dirlen;
543 drive_spec = __alloca (dirlen + 1);
544 *((char *) mempcpy (drive_spec, pattern, dirlen)) = '\0';
545 /* For now, disallow wildcards in the drive spec, to
546 prevent infinite recursion in glob. */
547 if (__glob_pattern_p (drive_spec, !(flags & GLOB_NOESCAPE)))
548 return GLOB_NOMATCH;
549 /* If this is "d:pattern", we need to copy ':' to DIRNAME
550 as well. If it's "d:/pattern", don't remove the slash
551 from "d:/", since "d:" and "d:/" are not the same.*/
552 }
553#endif
554
555 if (glob_use_alloca (alloca_used, dirlen + 1))
556 newp = alloca_account (dirlen + 1, alloca_used);
557 else
558 {
559 newp = malloc (dirlen + 1);
560 if (newp == NULL)
561 return GLOB_NOSPACE;
562 malloc_dirname = 1;
563 }
564 *((char *) mempcpy (newp, pattern, dirlen)) = '\0';
565 dirname = newp;
566 ++filename;
567
568#if defined __MSDOS__ || defined WINDOWS32
569 bool drive_root = (dirlen > 1
570 && (dirname[dirlen - 1] == ':'
571 || (dirlen > 2 && dirname[dirlen - 2] == ':'
572 && dirname[dirlen - 1] == '/')));
573#else
574 bool drive_root = false;
575#endif
576
577 if (filename[0] == '\0' && dirlen > 1 && !drive_root)
578 /* "pattern/". Expand "pattern", appending slashes. */
579 {
580 int orig_flags = flags;
581 if (!(flags & GLOB_NOESCAPE) && dirname[dirlen - 1] == '\\')
582 {
583 /* "pattern\\/". Remove the final backslash if it hasn't
584 been quoted. */
585 char *p = (char *) &dirname[dirlen - 1];
586
587 while (p > dirname && p[-1] == '\\') --p;
588 if ((&dirname[dirlen] - p) & 1)
589 {
590 *(char *) &dirname[--dirlen] = '\0';
591 flags &= ~(GLOB_NOCHECK | GLOB_NOMAGIC);
592 }
593 }
594 int val = glob (dirname, flags | GLOB_MARK, errfunc, pglob);
595 if (val == 0)
596 pglob->gl_flags = ((pglob->gl_flags & ~GLOB_MARK)
597 | (flags & GLOB_MARK));
598 else if (val == GLOB_NOMATCH && flags != orig_flags)
599 {
600 /* Make sure globfree (&dirs); is a nop. */
601 dirs.gl_pathv = NULL;
602 flags = orig_flags;
603 oldcount = pglob->gl_pathc + pglob->gl_offs;
604 goto no_matches;
605 }
606 retval = val;
607 goto out;
608 }
609 }
610
611 if ((flags & (GLOB_TILDE|GLOB_TILDE_CHECK)) && dirname[0] == '~')
612 {
613 if (dirname[1] == '\0' || dirname[1] == '/'
614 || (!(flags & GLOB_NOESCAPE) && dirname[1] == '\\'
615 && (dirname[2] == '\0' || dirname[2] == '/')))
616 {
617 /* Look up home directory. */
618 char *home_dir = getenv ("HOME");
619 int malloc_home_dir = 0;
620 if (home_dir == NULL || home_dir[0] == '\0')
621 {
622#ifdef WINDOWS32
623 /* Windows NT defines HOMEDRIVE and HOMEPATH. But give
624 preference to HOME, because the user can change HOME. */
625 const char *home_drive = getenv ("HOMEDRIVE");
626 const char *home_path = getenv ("HOMEPATH");
627
628 if (home_drive != NULL && home_path != NULL)
629 {
630 size_t home_drive_len = strlen (home_drive);
631 size_t home_path_len = strlen (home_path);
632 char *mem = alloca (home_drive_len + home_path_len + 1);
633
634 memcpy (mem, home_drive, home_drive_len);
635 memcpy (mem + home_drive_len, home_path, home_path_len + 1);
636 home_dir = mem;
637 }
638 else
639 home_dir = "c:/users/default"; /* poor default */
640#else
641 int success;
642 char *name;
643 int malloc_name = 0;
644 size_t buflen = GET_LOGIN_NAME_MAX () + 1;
645
646 if (buflen == 0)
647 /* 'sysconf' does not support _SC_LOGIN_NAME_MAX. Try
648 a moderate value. */
649 buflen = 20;
650 if (glob_use_alloca (alloca_used, buflen))
651 name = alloca_account (buflen, alloca_used);
652 else
653 {
654 name = malloc (buflen);
655 if (name == NULL)
656 {
657 retval = GLOB_NOSPACE;
658 goto out;
659 }
660 malloc_name = 1;
661 }
662
663 success = __getlogin_r (name, buflen) == 0;
664 if (success)
665 {
666 struct passwd *p;
667 char *malloc_pwtmpbuf = NULL;
668 char *pwtmpbuf;
669# if defined HAVE_GETPWNAM_R || defined _LIBC
670 long int pwbuflenmax = GETPW_R_SIZE_MAX ();
671 size_t pwbuflen = pwbuflenmax;
672 struct passwd pwbuf;
673 int save = errno;
674
675# ifndef _LIBC
676 if (! (0 < pwbuflenmax && pwbuflenmax <= SIZE_MAX))
677 /* 'sysconf' does not support _SC_GETPW_R_SIZE_MAX.
678 Try a moderate value. */
679 pwbuflen = 1024;
680# endif
681 if (glob_use_alloca (alloca_used, pwbuflen))
682 pwtmpbuf = alloca_account (pwbuflen, alloca_used);
683 else
684 {
685 pwtmpbuf = malloc (pwbuflen);
686 if (pwtmpbuf == NULL)
687 {
688 if (__glibc_unlikely (malloc_name))
689 free (name);
690 retval = GLOB_NOSPACE;
691 goto out;
692 }
693 malloc_pwtmpbuf = pwtmpbuf;
694 }
695
696 while (getpwnam_r (name, &pwbuf, pwtmpbuf, pwbuflen, &p)
697 != 0)
698 {
699 size_t newlen;
700 bool v;
701 if (errno != ERANGE)
702 {
703 p = NULL;
704 break;
705 }
706 v = size_add_wrapv (pwbuflen, pwbuflen, &newlen);
707 if (!v && malloc_pwtmpbuf == NULL
708 && glob_use_alloca (alloca_used, newlen))
709 pwtmpbuf = extend_alloca_account (pwtmpbuf, pwbuflen,
710 newlen, alloca_used);
711 else
712 {
713 char *newp = (v ? NULL
714 : realloc (malloc_pwtmpbuf, newlen));
715 if (newp == NULL)
716 {
717 free (malloc_pwtmpbuf);
718 if (__glibc_unlikely (malloc_name))
719 free (name);
720 retval = GLOB_NOSPACE;
721 goto out;
722 }
723 malloc_pwtmpbuf = pwtmpbuf = newp;
724 }
725 pwbuflen = newlen;
726 __set_errno (save);
727 }
728# else
729 p = getpwnam (name);
730# endif
731 if (__glibc_unlikely (malloc_name))
732 free (name);
733 if (p != NULL)
734 {
735 if (malloc_pwtmpbuf == NULL)
736 home_dir = p->pw_dir;
737 else
738 {
739 size_t home_dir_len = strlen (p->pw_dir) + 1;
740 if (glob_use_alloca (alloca_used, home_dir_len))
741 home_dir = alloca_account (home_dir_len,
742 alloca_used);
743 else
744 {
745 home_dir = malloc (home_dir_len);
746 if (home_dir == NULL)
747 {
748 free (pwtmpbuf);
749 retval = GLOB_NOSPACE;
750 goto out;
751 }
752 malloc_home_dir = 1;
753 }
754 memcpy (home_dir, p->pw_dir, home_dir_len);
755 }
756 }
757 free (malloc_pwtmpbuf);
758 }
759 else
760 {
761 if (__glibc_unlikely (malloc_name))
762 free (name);
763 }
764#endif /* WINDOWS32 */
765 }
766 if (home_dir == NULL || home_dir[0] == '\0')
767 {
768 if (__glibc_unlikely (malloc_home_dir))
769 free (home_dir);
770 if (flags & GLOB_TILDE_CHECK)
771 {
772 retval = GLOB_NOMATCH;
773 goto out;
774 }
775 else
776 {
777 home_dir = (char *) "~"; /* No luck. */
778 malloc_home_dir = 0;
779 }
780 }
781 /* Now construct the full directory. */
782 if (dirname[1] == '\0')
783 {
784 if (__glibc_unlikely (malloc_dirname))
785 free (dirname);
786
787 dirname = home_dir;
788 dirlen = strlen (dirname);
789 malloc_dirname = malloc_home_dir;
790 }
791 else
792 {
793 char *newp;
794 size_t home_len = strlen (home_dir);
795 int use_alloca = glob_use_alloca (alloca_used, home_len + dirlen);
796 if (use_alloca)
797 newp = alloca_account (home_len + dirlen, alloca_used);
798 else
799 {
800 newp = malloc (home_len + dirlen);
801 if (newp == NULL)
802 {
803 if (__glibc_unlikely (malloc_home_dir))
804 free (home_dir);
805 retval = GLOB_NOSPACE;
806 goto out;
807 }
808 }
809
810 mempcpy (mempcpy (newp, home_dir, home_len),
811 &dirname[1], dirlen);
812
813 if (__glibc_unlikely (malloc_dirname))
814 free (dirname);
815
816 dirname = newp;
817 dirlen += home_len - 1;
818 malloc_dirname = !use_alloca;
819
820 if (__glibc_unlikely (malloc_home_dir))
821 free (home_dir);
822 }
823 dirname_modified = 1;
824 }
825 else
826 {
827#ifndef WINDOWS32
828 char *end_name = strchr (dirname, '/');
829 char *user_name;
830 int malloc_user_name = 0;
831 char *unescape = NULL;
832
833 if (!(flags & GLOB_NOESCAPE))
834 {
835 if (end_name == NULL)
836 {
837 unescape = strchr (dirname, '\\');
838 if (unescape)
839 end_name = strchr (unescape, '\0');
840 }
841 else
842 unescape = memchr (dirname, '\\', end_name - dirname);
843 }
844 if (end_name == NULL)
845 user_name = dirname + 1;
846 else
847 {
848 char *newp;
849 if (glob_use_alloca (alloca_used, end_name - dirname))
850 newp = alloca_account (end_name - dirname, alloca_used);
851 else
852 {
853 newp = malloc (end_name - dirname);
854 if (newp == NULL)
855 {
856 retval = GLOB_NOSPACE;
857 goto out;
858 }
859 malloc_user_name = 1;
860 }
861 if (unescape != NULL)
862 {
863 char *p = mempcpy (newp, dirname + 1,
864 unescape - dirname - 1);
865 char *q = unescape;
866 while (q != end_name)
867 {
868 if (*q == '\\')
869 {
870 if (q + 1 == end_name)
871 {
872 /* "~fo\\o\\" unescape to user_name "foo\\",
873 but "~fo\\o\\/" unescape to user_name
874 "foo". */
875 if (filename == NULL)
876 *p++ = '\\';
877 break;
878 }
879 ++q;
880 }
881 *p++ = *q++;
882 }
883 *p = '\0';
884 }
885 else
886 *((char *) mempcpy (newp, dirname + 1, end_name - dirname - 1))
887 = '\0';
888 user_name = newp;
889 }
890
891 /* Look up specific user's home directory. */
892 {
893 struct passwd *p;
894 char *malloc_pwtmpbuf = NULL;
895# if defined HAVE_GETPWNAM_R || defined _LIBC
896 long int buflenmax = GETPW_R_SIZE_MAX ();
897 size_t buflen = buflenmax;
898 char *pwtmpbuf;
899 struct passwd pwbuf;
900 int save = errno;
901
902# ifndef _LIBC
903 if (! (0 <= buflenmax && buflenmax <= SIZE_MAX))
904 /* Perhaps 'sysconf' does not support _SC_GETPW_R_SIZE_MAX. Try a
905 moderate value. */
906 buflen = 1024;
907# endif
908 if (glob_use_alloca (alloca_used, buflen))
909 pwtmpbuf = alloca_account (buflen, alloca_used);
910 else
911 {
912 pwtmpbuf = malloc (buflen);
913 if (pwtmpbuf == NULL)
914 {
915 nomem_getpw:
916 if (__glibc_unlikely (malloc_user_name))
917 free (user_name);
918 retval = GLOB_NOSPACE;
919 goto out;
920 }
921 malloc_pwtmpbuf = pwtmpbuf;
922 }
923
924 while (getpwnam_r (user_name, &pwbuf, pwtmpbuf, buflen, &p) != 0)
925 {
926 size_t newlen;
927 bool v;
928 if (errno != ERANGE)
929 {
930 p = NULL;
931 break;
932 }
933 v = size_add_wrapv (buflen, buflen, &newlen);
934 if (!v && malloc_pwtmpbuf == NULL
935 && glob_use_alloca (alloca_used, newlen))
936 pwtmpbuf = extend_alloca_account (pwtmpbuf, buflen,
937 newlen, alloca_used);
938 else
939 {
940 char *newp = v ? NULL : realloc (malloc_pwtmpbuf, newlen);
941 if (newp == NULL)
942 {
943 free (malloc_pwtmpbuf);
944 goto nomem_getpw;
945 }
946 malloc_pwtmpbuf = pwtmpbuf = newp;
947 }
948 __set_errno (save);
949 }
950# else
951 p = getpwnam (user_name);
952# endif
953
954 if (__glibc_unlikely (malloc_user_name))
955 free (user_name);
956
957 /* If we found a home directory use this. */
958 if (p != NULL)
959 {
960 size_t home_len = strlen (p->pw_dir);
961 size_t rest_len = end_name == NULL ? 0 : strlen (end_name);
962
963 if (__glibc_unlikely (malloc_dirname))
964 free (dirname);
965 malloc_dirname = 0;
966
967 if (glob_use_alloca (alloca_used, home_len + rest_len + 1))
968 dirname = alloca_account (home_len + rest_len + 1,
969 alloca_used);
970 else
971 {
972 dirname = malloc (home_len + rest_len + 1);
973 if (dirname == NULL)
974 {
975 free (malloc_pwtmpbuf);
976 retval = GLOB_NOSPACE;
977 goto out;
978 }
979 malloc_dirname = 1;
980 }
981 *((char *) mempcpy (mempcpy (dirname, p->pw_dir, home_len),
982 end_name, rest_len)) = '\0';
983
984 dirlen = home_len + rest_len;
985 dirname_modified = 1;
986
987 free (malloc_pwtmpbuf);
988 }
989 else
990 {
991 free (malloc_pwtmpbuf);
992
993 if (flags & GLOB_TILDE_CHECK)
994 {
995 /* We have to regard it as an error if we cannot find the
996 home directory. */
997 retval = GLOB_NOMATCH;
998 goto out;
999 }
1000 }
1001 }
1002#endif /* !WINDOWS32 */
1003 }
1004 }
1005
1006 /* Now test whether we looked for "~" or "~NAME". In this case we
1007 can give the answer now. */
1008 if (filename == NULL)
1009 {
1010 struct stat st;
1011 struct_stat64 st64;
1012
1013 /* Return the directory if we don't check for error or if it exists. */
1014 if ((flags & GLOB_NOCHECK)
1015 || (((__builtin_expect (flags & GLOB_ALTDIRFUNC, 0))
1016 ? ((*pglob->gl_stat) (dirname, &st) == 0
1017 && S_ISDIR (st.st_mode))
1018 : (__stat64 (dirname, &st64) == 0 && S_ISDIR (st64.st_mode)))))
1019 {
1020 size_t newcount = pglob->gl_pathc + pglob->gl_offs;
1021 char **new_gl_pathv;
1022
1023 if (newcount > SIZE_MAX / sizeof (char *) - 2)
1024 {
1025 nospace:
1026 free (pglob->gl_pathv);
1027 pglob->gl_pathv = NULL;
1028 pglob->gl_pathc = 0;
1029 retval = GLOB_NOSPACE;
1030 goto out;
1031 }
1032
1033 new_gl_pathv = realloc (pglob->gl_pathv,
1034 (newcount + 2) * sizeof (char *));
1035 if (new_gl_pathv == NULL)
1036 goto nospace;
1037 pglob->gl_pathv = new_gl_pathv;
1038
1039 if (flags & GLOB_MARK)
1040 {
1041 char *p;
1042 pglob->gl_pathv[newcount] = malloc (dirlen + 2);
1043 if (pglob->gl_pathv[newcount] == NULL)
1044 goto nospace;
1045 p = mempcpy (pglob->gl_pathv[newcount], dirname, dirlen);
1046 p[0] = '/';
1047 p[1] = '\0';
1048 if (__glibc_unlikely (malloc_dirname))
1049 free (dirname);
1050 }
1051 else
1052 {
1053 if (__glibc_unlikely (malloc_dirname))
1054 pglob->gl_pathv[newcount] = dirname;
1055 else
1056 {
1057 pglob->gl_pathv[newcount] = strdup (dirname);
1058 if (pglob->gl_pathv[newcount] == NULL)
1059 goto nospace;
1060 }
1061 }
1062 pglob->gl_pathv[++newcount] = NULL;
1063 ++pglob->gl_pathc;
1064 pglob->gl_flags = flags;
1065
1066 return 0;
1067 }
1068
1069 /* Not found. */
1070 retval = GLOB_NOMATCH;
1071 goto out;
1072 }
1073
1074 meta = __glob_pattern_type (dirname, !(flags & GLOB_NOESCAPE));
1075 /* meta is 1 if correct glob pattern containing metacharacters.
1076 If meta has bit (1 << 2) set, it means there was an unterminated
1077 [ which we handle the same, using fnmatch. Broken unterminated
1078 pattern bracket expressions ought to be rare enough that it is
1079 not worth special casing them, fnmatch will do the right thing. */
1080 if (meta & 5)
1081 {
1082 /* The directory name contains metacharacters, so we
1083 have to glob for the directory, and then glob for
1084 the pattern in each directory found. */
1085 size_t i;
1086
1087 if (!(flags & GLOB_NOESCAPE) && dirlen > 0 && dirname[dirlen - 1] == '\\')
1088 {
1089 /* "foo\\/bar". Remove the final backslash from dirname
1090 if it has not been quoted. */
1091 char *p = (char *) &dirname[dirlen - 1];
1092
1093 while (p > dirname && p[-1] == '\\') --p;
1094 if ((&dirname[dirlen] - p) & 1)
1095 *(char *) &dirname[--dirlen] = '\0';
1096 }
1097
1098 if (__glibc_unlikely ((flags & GLOB_ALTDIRFUNC) != 0))
1099 {
1100 /* Use the alternative access functions also in the recursive
1101 call. */
1102 dirs.gl_opendir = pglob->gl_opendir;
1103 dirs.gl_readdir = pglob->gl_readdir;
1104 dirs.gl_closedir = pglob->gl_closedir;
1105 dirs.gl_stat = pglob->gl_stat;
1106 dirs.gl_lstat = pglob->gl_lstat;
1107 }
1108
1109 status = glob (dirname,
1110 ((flags & (GLOB_ERR | GLOB_NOESCAPE
1111 | GLOB_ALTDIRFUNC))
1112 | GLOB_NOSORT | GLOB_ONLYDIR),
1113 errfunc, &dirs);
1114 if (status != 0)
1115 {
1116 if ((flags & GLOB_NOCHECK) == 0 || status != GLOB_NOMATCH)
1117 {
1118 retval = status;
1119 goto out;
1120 }
1121 goto no_matches;
1122 }
1123
1124 /* We have successfully globbed the preceding directory name.
1125 For each name we found, call glob_in_dir on it and FILENAME,
1126 appending the results to PGLOB. */
1127 for (i = 0; i < dirs.gl_pathc; ++i)
1128 {
1129 size_t old_pathc;
1130
1131 old_pathc = pglob->gl_pathc;
1132 status = glob_in_dir (filename, dirs.gl_pathv[i],
1133 ((flags | GLOB_APPEND)
1134 & ~(GLOB_NOCHECK | GLOB_NOMAGIC)),
1135 errfunc, pglob, alloca_used);
1136 if (status == GLOB_NOMATCH)
1137 /* No matches in this directory. Try the next. */
1138 continue;
1139
1140 if (status != 0)
1141 {
1142 globfree (&dirs);
1143 globfree (pglob);
1144 pglob->gl_pathc = 0;
1145 retval = status;
1146 goto out;
1147 }
1148
1149 /* Stick the directory on the front of each name. */
1150 if (prefix_array (dirs.gl_pathv[i],
1151 &pglob->gl_pathv[old_pathc + pglob->gl_offs],
1152 pglob->gl_pathc - old_pathc))
1153 {
1154 globfree (&dirs);
1155 globfree (pglob);
1156 pglob->gl_pathc = 0;
1157 retval = GLOB_NOSPACE;
1158 goto out;
1159 }
1160 }
1161
1162 flags |= GLOB_MAGCHAR;
1163
1164 /* We have ignored the GLOB_NOCHECK flag in the 'glob_in_dir' calls.
1165 But if we have not found any matching entry and the GLOB_NOCHECK
1166 flag was set we must return the input pattern itself. */
1167 if (pglob->gl_pathc + pglob->gl_offs == oldcount)
1168 {
1169 no_matches:
1170 /* No matches. */
1171 if (flags & GLOB_NOCHECK)
1172 {
1173 size_t newcount = pglob->gl_pathc + pglob->gl_offs;
1174 char **new_gl_pathv;
1175
1176 if (newcount > SIZE_MAX / sizeof (char *) - 2)
1177 {
1178 nospace2:
1179 globfree (&dirs);
1180 retval = GLOB_NOSPACE;
1181 goto out;
1182 }
1183
1184 new_gl_pathv = realloc (pglob->gl_pathv,
1185 (newcount + 2) * sizeof (char *));
1186 if (new_gl_pathv == NULL)
1187 goto nospace2;
1188 pglob->gl_pathv = new_gl_pathv;
1189
1190 pglob->gl_pathv[newcount] = strdup (pattern);
1191 if (pglob->gl_pathv[newcount] == NULL)
1192 {
1193 globfree (&dirs);
1194 globfree (pglob);
1195 pglob->gl_pathc = 0;
1196 retval = GLOB_NOSPACE;
1197 goto out;
1198 }
1199
1200 ++pglob->gl_pathc;
1201 ++newcount;
1202
1203 pglob->gl_pathv[newcount] = NULL;
1204 pglob->gl_flags = flags;
1205 }
1206 else
1207 {
1208 globfree (&dirs);
1209 retval = GLOB_NOMATCH;
1210 goto out;
1211 }
1212 }
1213
1214 globfree (&dirs);
1215 }
1216 else
1217 {
1218 size_t old_pathc = pglob->gl_pathc;
1219 int orig_flags = flags;
1220
1221 if (meta & 2)
1222 {
1223 char *p = strchr (dirname, '\\'), *q;
1224 /* We need to unescape the dirname string. It is certainly
1225 allocated by alloca, as otherwise filename would be NULL
1226 or dirname wouldn't contain backslashes. */
1227 q = p;
1228 do
1229 {
1230 if (*p == '\\')
1231 {
1232 *q = *++p;
1233 --dirlen;
1234 }
1235 else
1236 *q = *p;
1237 ++q;
1238 }
1239 while (*p++ != '\0');
1240 dirname_modified = 1;
1241 }
1242 if (dirname_modified)
1243 flags &= ~(GLOB_NOCHECK | GLOB_NOMAGIC);
1244 status = glob_in_dir (filename, dirname, flags, errfunc, pglob,
1245 alloca_used);
1246 if (status != 0)
1247 {
1248 if (status == GLOB_NOMATCH && flags != orig_flags
1249 && pglob->gl_pathc + pglob->gl_offs == oldcount)
1250 {
1251 /* Make sure globfree (&dirs); is a nop. */
1252 dirs.gl_pathv = NULL;
1253 flags = orig_flags;
1254 goto no_matches;
1255 }
1256 retval = status;
1257 goto out;
1258 }
1259
1260 if (dirlen > 0)
1261 {
1262 /* Stick the directory on the front of each name. */
1263 if (prefix_array (dirname,
1264 &pglob->gl_pathv[old_pathc + pglob->gl_offs],
1265 pglob->gl_pathc - old_pathc))
1266 {
1267 globfree (pglob);
1268 pglob->gl_pathc = 0;
1269 retval = GLOB_NOSPACE;
1270 goto out;
1271 }
1272 }
1273 }
1274
1275 if (flags & GLOB_MARK)
1276 {
1277 /* Append slashes to directory names. */
1278 size_t i;
1279 struct stat st;
1280 struct_stat64 st64;
1281
1282 for (i = oldcount; i < pglob->gl_pathc + pglob->gl_offs; ++i)
1283 if ((__builtin_expect (flags & GLOB_ALTDIRFUNC, 0)
1284 ? ((*pglob->gl_stat) (pglob->gl_pathv[i], &st) == 0
1285 && S_ISDIR (st.st_mode))
1286 : (__stat64 (pglob->gl_pathv[i], &st64) == 0
1287 && S_ISDIR (st64.st_mode))))
1288 {
1289 size_t len = strlen (pglob->gl_pathv[i]) + 2;
1290 char *new = realloc (pglob->gl_pathv[i], len);
1291 if (new == NULL)
1292 {
1293 globfree (pglob);
1294 pglob->gl_pathc = 0;
1295 retval = GLOB_NOSPACE;
1296 goto out;
1297 }
1298 strcpy (&new[len - 2], "/");
1299 pglob->gl_pathv[i] = new;
1300 }
1301 }
1302
1303 if (!(flags & GLOB_NOSORT))
1304 {
1305 /* Sort the vector. */
1306 qsort (&pglob->gl_pathv[oldcount],
1307 pglob->gl_pathc + pglob->gl_offs - oldcount,
1308 sizeof (char *), collated_compare);
1309 }
1310
1311 out:
1312 if (__glibc_unlikely (malloc_dirname))
1313 free (dirname);
1314
1315 return retval;
1316}
1317#if defined _LIBC && !defined glob
1318libc_hidden_def (glob)
1319#endif
1320
1321
1322/* Do a collated comparison of A and B. */
1323static int
1324collated_compare (const void *a, const void *b)
1325{
1326 char *const *ps1 = a; char *s1 = *ps1;
1327 char *const *ps2 = b; char *s2 = *ps2;
1328
1329 if (s1 == s2)
1330 return 0;
1331 if (s1 == NULL)
1332 return 1;
1333 if (s2 == NULL)
1334 return -1;
1335 return strcoll (s1, s2);
1336}
1337
1338
1339/* Prepend DIRNAME to each of N members of ARRAY, replacing ARRAY's
1340 elements in place. Return nonzero if out of memory, zero if successful.
1341 A slash is inserted between DIRNAME and each elt of ARRAY,
1342 unless DIRNAME is just "/". Each old element of ARRAY is freed. */
1343static int
1344prefix_array (const char *dirname, char **array, size_t n)
1345{
1346 size_t i;
1347 size_t dirlen = strlen (dirname);
1348 char dirsep_char = '/';
1349
1350 if (dirlen == 1 && dirname[0] == '/')
1351 /* DIRNAME is just "/", so normal prepending would get us "//foo".
1352 We want "/foo" instead, so don't prepend any chars from DIRNAME. */
1353 dirlen = 0;
1354
1355#if defined __MSDOS__ || defined WINDOWS32
1356 if (dirlen > 1)
1357 {
1358 if (dirname[dirlen - 1] == '/' && dirname[dirlen - 2] == ':')
1359 /* DIRNAME is "d:/". Don't prepend the slash from DIRNAME. */
1360 --dirlen;
1361 else if (dirname[dirlen - 1] == ':')
1362 {
1363 /* DIRNAME is "d:". Use ':' instead of '/'. */
1364 --dirlen;
1365 dirsep_char = ':';
1366 }
1367 }
1368#endif
1369
1370 for (i = 0; i < n; ++i)
1371 {
1372 size_t eltlen = strlen (array[i]) + 1;
1373 char *new = malloc (dirlen + 1 + eltlen);
1374 if (new == NULL)
1375 {
1376 while (i > 0)
1377 free (array[--i]);
1378 return 1;
1379 }
1380
1381 {
1382 char *endp = mempcpy (new, dirname, dirlen);
1383 *endp++ = dirsep_char;
1384 mempcpy (endp, array[i], eltlen);
1385 }
1386 free (array[i]);
1387 array[i] = new;
1388 }
1389
1390 return 0;
1391}
1392
1393/* We put this in a separate function mainly to allow the memory
1394 allocated with alloca to be recycled. */
1395static int
1396__attribute_noinline__
1397link_stat (const char *dir, size_t dirlen, const char *fname,
1398 glob_t *pglob
1399# if !defined _LIBC && !HAVE_FSTATAT
1400 , int flags
1401# endif
1402 )
1403{
1404 size_t fnamelen = strlen (fname);
1405 char *fullname = __alloca (dirlen + 1 + fnamelen + 1);
1406 struct stat st;
1407
1408 mempcpy (mempcpy (mempcpy (fullname, dir, dirlen), "/", 1),
1409 fname, fnamelen + 1);
1410
1411# if !defined _LIBC && !HAVE_FSTATAT
1412 if (__builtin_expect ((flags & GLOB_ALTDIRFUNC) == 0, 1))
1413 {
1414 struct_stat64 st64;
1415 return __stat64 (fullname, &st64);
1416 }
1417# endif
1418 return (*pglob->gl_stat) (fullname, &st);
1419}
1420
1421/* Return true if DIR/FNAME exists. */
1422static int
1423link_exists_p (int dfd, const char *dir, size_t dirlen, const char *fname,
1424 glob_t *pglob, int flags)
1425{
1426 int status;
1427# if defined _LIBC || HAVE_FSTATAT
1428 if (__builtin_expect (flags & GLOB_ALTDIRFUNC, 0))
1429 status = link_stat (dir, dirlen, fname, pglob);
1430 else
1431 {
1432 /* dfd cannot be -1 here, because dirfd never returns -1 on
1433 glibc, or on hosts that have fstatat. */
1434 struct_stat64 st64;
1435 status = __fxstatat64 (_STAT_VER, dfd, fname, &st64, 0);
1436 }
1437# else
1438 status = link_stat (dir, dirlen, fname, pglob, flags);
1439# endif
1440 return status == 0 || errno == EOVERFLOW;
1441}
1442
1443/* Like 'glob', but PATTERN is a final pathname component,
1444 and matches are searched for in DIRECTORY.
1445 The GLOB_NOSORT bit in FLAGS is ignored. No sorting is ever done.
1446 The GLOB_APPEND flag is assumed to be set (always appends). */
1447static int
1448glob_in_dir (const char *pattern, const char *directory, int flags,
1449 int (*errfunc) (const char *, int),
1450 glob_t *pglob, size_t alloca_used)
1451{
1452 size_t dirlen = strlen (directory);
1453 void *stream = NULL;
1454# define GLOBNAMES_MEMBERS(nnames) \
1455 struct globnames *next; size_t count; char *name[nnames];
1456 struct globnames { GLOBNAMES_MEMBERS (FLEXIBLE_ARRAY_MEMBER) };
1457 struct { GLOBNAMES_MEMBERS (64) } init_names_buf;
1458 struct globnames *init_names = (struct globnames *) &init_names_buf;
1459 struct globnames *names = init_names;
1460 struct globnames *names_alloca = init_names;
1461 size_t nfound = 0;
1462 size_t cur = 0;
1463 int meta;
1464 int save;
1465 int result;
1466
1467 alloca_used += sizeof init_names_buf;
1468
1469 init_names->next = NULL;
1470 init_names->count = ((sizeof init_names_buf
1471 - offsetof (struct globnames, name))
1472 / sizeof init_names->name[0]);
1473
1474 meta = __glob_pattern_type (pattern, !(flags & GLOB_NOESCAPE));
1475 if (meta == 0 && (flags & (GLOB_NOCHECK|GLOB_NOMAGIC)))
1476 {
1477 /* We need not do any tests. The PATTERN contains no meta
1478 characters and we must not return an error therefore the
1479 result will always contain exactly one name. */
1480 flags |= GLOB_NOCHECK;
1481 }
1482 else if (meta == 0)
1483 {
1484 /* Since we use the normal file functions we can also use stat()
1485 to verify the file is there. */
1486 union
1487 {
1488 struct stat st;
1489 struct_stat64 st64;
1490 } ust;
1491 size_t patlen = strlen (pattern);
1492 size_t fullsize;
1493 bool alloca_fullname
1494 = (! size_add_wrapv (dirlen + 1, patlen + 1, &fullsize)
1495 && glob_use_alloca (alloca_used, fullsize));
1496 char *fullname;
1497 if (alloca_fullname)
1498 fullname = alloca_account (fullsize, alloca_used);
1499 else
1500 {
1501 fullname = malloc (fullsize);
1502 if (fullname == NULL)
1503 return GLOB_NOSPACE;
1504 }
1505
1506 mempcpy (mempcpy (mempcpy (fullname, directory, dirlen),
1507 "/", 1),
1508 pattern, patlen + 1);
1509 if (((__builtin_expect (flags & GLOB_ALTDIRFUNC, 0)
1510 ? (*pglob->gl_stat) (fullname, &ust.st)
1511 : __stat64 (fullname, &ust.st64))
1512 == 0)
1513 || errno == EOVERFLOW)
1514 /* We found this file to be existing. Now tell the rest
1515 of the function to copy this name into the result. */
1516 flags |= GLOB_NOCHECK;
1517
1518 if (__glibc_unlikely (!alloca_fullname))
1519 free (fullname);
1520 }
1521 else
1522 {
1523 stream = (__builtin_expect (flags & GLOB_ALTDIRFUNC, 0)
1524 ? (*pglob->gl_opendir) (directory)
1525 : opendir (directory));
1526 if (stream == NULL)
1527 {
1528 if (errno != ENOTDIR
1529 && ((errfunc != NULL && (*errfunc) (directory, errno))
1530 || (flags & GLOB_ERR)))
1531 return GLOB_ABORTED;
1532 }
1533 else
1534 {
1535 int dfd = (__builtin_expect (flags & GLOB_ALTDIRFUNC, 0)
1536 ? -1 : dirfd ((DIR *) stream));
1537 int fnm_flags = ((!(flags & GLOB_PERIOD) ? FNM_PERIOD : 0)
1538 | ((flags & GLOB_NOESCAPE) ? FNM_NOESCAPE : 0));
1539 flags |= GLOB_MAGCHAR;
1540
1541 while (1)
1542 {
1543 struct readdir_result d;
1544 {
1545 if (__builtin_expect (flags & GLOB_ALTDIRFUNC, 0))
1546 d = convert_dirent (GL_READDIR (pglob, stream));
1547 else
1548 {
1549#ifdef COMPILE_GLOB64
1550 d = convert_dirent (__readdir (stream));
1551#else
1552 d = convert_dirent64 (__readdir64 (stream));
1553#endif
1554 }
1555 }
1556 if (d.name == NULL)
1557 break;
1558 if (readdir_result_skip_entry (d))
1559 continue;
1560
1561 /* If we shall match only directories use the information
1562 provided by the dirent call if possible. */
1563 if (flags & GLOB_ONLYDIR)
1564 switch (readdir_result_type (d))
1565 {
1566 case DT_DIR: case DT_LNK: case DT_UNKNOWN: break;
1567 default: continue;
1568 }
1569
1570 if (fnmatch (pattern, d.name, fnm_flags) == 0)
1571 {
1572 /* If the file we found is a symlink we have to
1573 make sure the target file exists. */
1574 dirent_type type = readdir_result_type (d);
1575 if (! (type == DT_LNK || type == DT_UNKNOWN)
1576 || link_exists_p (dfd, directory, dirlen, d.name,
1577 pglob, flags))
1578 {
1579 if (cur == names->count)
1580 {
1581 struct globnames *newnames;
1582 size_t count = names->count * 2;
1583 size_t nameoff = offsetof (struct globnames, name);
1584 size_t size = FLEXSIZEOF (struct globnames, name,
1585 count * sizeof (char *));
1586 if ((SIZE_MAX - nameoff) / 2 / sizeof (char *)
1587 < names->count)
1588 goto memory_error;
1589 if (glob_use_alloca (alloca_used, size))
1590 newnames = names_alloca
1591 = alloca_account (size, alloca_used);
1592 else if ((newnames = malloc (size))
1593 == NULL)
1594 goto memory_error;
1595 newnames->count = count;
1596 newnames->next = names;
1597 names = newnames;
1598 cur = 0;
1599 }
1600 names->name[cur] = strdup (d.name);
1601 if (names->name[cur] == NULL)
1602 goto memory_error;
1603 ++cur;
1604 ++nfound;
1605 if (SIZE_MAX - pglob->gl_offs <= nfound)
1606 goto memory_error;
1607 }
1608 }
1609 }
1610 }
1611 }
1612
1613 if (nfound == 0 && (flags & GLOB_NOCHECK))
1614 {
1615 size_t len = strlen (pattern);
1616 nfound = 1;
1617 names->name[cur] = malloc (len + 1);
1618 if (names->name[cur] == NULL)
1619 goto memory_error;
1620 *((char *) mempcpy (names->name[cur++], pattern, len)) = '\0';
1621 }
1622
1623 result = GLOB_NOMATCH;
1624 if (nfound != 0)
1625 {
1626 char **new_gl_pathv;
1627 result = 0;
1628
1629 if (SIZE_MAX / sizeof (char *) - pglob->gl_pathc
1630 < pglob->gl_offs + nfound + 1)
1631 goto memory_error;
1632
1633 new_gl_pathv
1634 = realloc (pglob->gl_pathv,
1635 (pglob->gl_pathc + pglob->gl_offs + nfound + 1)
1636 * sizeof (char *));
1637
1638 if (new_gl_pathv == NULL)
1639 {
1640 memory_error:
1641 while (1)
1642 {
1643 struct globnames *old = names;
1644 for (size_t i = 0; i < cur; ++i)
1645 free (names->name[i]);
1646 names = names->next;
1647 /* NB: we will not leak memory here if we exit without
1648 freeing the current block assigned to OLD. At least
1649 the very first block is always allocated on the stack
1650 and this is the block assigned to OLD here. */
1651 if (names == NULL)
1652 {
1653 assert (old == init_names);
1654 break;
1655 }
1656 cur = names->count;
1657 if (old == names_alloca)
1658 names_alloca = names;
1659 else
1660 free (old);
1661 }
1662 result = GLOB_NOSPACE;
1663 }
1664 else
1665 {
1666 while (1)
1667 {
1668 struct globnames *old = names;
1669 for (size_t i = 0; i < cur; ++i)
1670 new_gl_pathv[pglob->gl_offs + pglob->gl_pathc++]
1671 = names->name[i];
1672 names = names->next;
1673 /* NB: we will not leak memory here if we exit without
1674 freeing the current block assigned to OLD. At least
1675 the very first block is always allocated on the stack
1676 and this is the block assigned to OLD here. */
1677 if (names == NULL)
1678 {
1679 assert (old == init_names);
1680 break;
1681 }
1682 cur = names->count;
1683 if (old == names_alloca)
1684 names_alloca = names;
1685 else
1686 free (old);
1687 }
1688
1689 pglob->gl_pathv = new_gl_pathv;
1690
1691 pglob->gl_pathv[pglob->gl_offs + pglob->gl_pathc] = NULL;
1692
1693 pglob->gl_flags = flags;
1694 }
1695 }
1696
1697 if (stream != NULL)
1698 {
1699 save = errno;
1700 if (__glibc_unlikely (flags & GLOB_ALTDIRFUNC))
1701 (*pglob->gl_closedir) (stream);
1702 else
1703 closedir (stream);
1704 __set_errno (save);
1705 }
1706
1707 return result;
1708}
1709