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