VirtualBox

source: kBuild/vendor/gnumake/2008-10-28/glob/glob.c

Last change on this file was 1989, checked in by bird, 16 years ago

Load gnumake-2008-10-28-CVS into vendor/gnumake/current.

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

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette