VirtualBox

source: kBuild/branches/GNU/src/gmake/glob/glob.c@ 280

Last change on this file since 280 was 280, checked in by bird, 20 years ago

Current make snaphot, 2005-05-16.

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