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