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