source: trunk/src/kmk/glob/glob.c@ 3140

Last change on this file since 3140 was 3140, checked in by bird, 7 years ago

kmk: Merged in changes from GNU make 4.2.1 (2e55f5e4abdc0e38c1d64be703b446695e70b3b6 / https://git.savannah.gnu.org/git/make.git).

  • Property svn:eol-style set to native
File size: 35.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#if !defined __GNU_LIBRARY__ && !defined __DJGPP__ && !defined ELECTRIC_HEAP && !defined __APPLE__ /* bird (last two) */
186# ifdef __GNUC__
187__inline
188# endif
189# ifndef __SASC
190# ifdef WINDOWS32
191# include <malloc.h>
192static void *
193my_realloc (void *p, unsigned int n)
194# else
195static char *
196my_realloc (p, n)
197 char *p;
198 unsigned int n;
199# endif
200{
201 /* These casts are the for sake of the broken Ultrix compiler,
202 which warns of illegal pointer combinations otherwise. */
203 if (p == NULL)
204 return (char *) malloc (n);
205 return (char *) realloc (p, n);
206}
207# define realloc my_realloc
208# endif /* __SASC */
209#endif /* __GNU_LIBRARY__ || __DJGPP__ */
210
211
212#if !defined __alloca && !defined __GNU_LIBRARY__
213
214# ifdef __GNUC__
215# undef alloca
216# define alloca(n) __builtin_alloca (n)
217# else /* Not GCC. */
218# ifdef HAVE_ALLOCA_H
219# include <alloca.h>
220# else /* Not HAVE_ALLOCA_H. */
221# ifndef _AIX
222# ifdef WINDOWS32
223# include <malloc.h>
224# else
225extern char *alloca ();
226# endif /* WINDOWS32 */
227# endif /* Not _AIX. */
228# endif /* sparc or HAVE_ALLOCA_H. */
229# endif /* GCC. */
230
231# define __alloca alloca
232
233#endif
234
235#ifndef __GNU_LIBRARY__
236# define __stat stat
237# ifdef STAT_MACROS_BROKEN
238# undef S_ISDIR
239# endif
240# ifndef S_ISDIR
241# define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
242# endif
243#endif
244
245#ifdef _LIBC
246# undef strdup
247# define strdup(str) __strdup (str)
248# define sysconf(id) __sysconf (id)
249# define closedir(dir) __closedir (dir)
250# define opendir(name) __opendir (name)
251# define readdir(str) __readdir (str)
252# define getpwnam_r(name, bufp, buf, len, res) \
253 __getpwnam_r (name, bufp, buf, len, res)
254# ifndef __stat
255# define __stat(fname, buf) __xstat (_STAT_VER, fname, buf)
256# endif
257#endif
258
259#if !(defined STDC_HEADERS || defined __GNU_LIBRARY__)
260# undef size_t
261# define size_t unsigned int
262#endif
263
264/* Some system header files erroneously define these.
265 We want our own definitions from <fnmatch.h> to take precedence. */
266#ifndef __GNU_LIBRARY__
267# undef FNM_PATHNAME
268# undef FNM_NOESCAPE
269# undef FNM_PERIOD
270#endif
271#include <fnmatch.h>
272
273/* Some system header files erroneously define these.
274 We want our own definitions from <glob.h> to take precedence. */
275#ifndef __GNU_LIBRARY__
276# undef GLOB_ERR
277# undef GLOB_MARK
278# undef GLOB_NOSORT
279# undef GLOB_DOOFFS
280# undef GLOB_NOCHECK
281# undef GLOB_APPEND
282# undef GLOB_NOESCAPE
283# undef GLOB_PERIOD
284#endif
285#include <glob.h>
286
287#ifdef HAVE_GETLOGIN_R
288extern int getlogin_r __P ((char *, size_t));
289#else
290extern char *getlogin __P ((void));
291#endif
292
293
294static
295#if __GNUC__ - 0 >= 2
296inline
297#endif
298const char *next_brace_sub __P ((const char *begin));
299static int glob_in_dir __P ((const char *pattern, const char *directory,
300 int flags,
301 int (*errfunc) (const char *, int),
302 glob_t *pglob));
303static int prefix_array __P ((const char *prefix, char **array, size_t n));
304static int collated_compare __P ((const __ptr_t, const __ptr_t));
305
306#if !defined _LIBC || !defined NO_GLOB_PATTERN_P
307int __glob_pattern_p __P ((const char *pattern, int quote));
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 __size_t oldcount; /* bird: correct type. */
375
376 if (pattern == NULL || pglob == NULL || (flags & ~__GLOB_FLAGS) != 0)
377 {
378 __set_errno (EINVAL);
379 return -1;
380 }
381
382 /* POSIX requires all slashes to be matched. This means that with
383 a trailing slash we must match only directories. */
384 if (pattern[0] && pattern[strlen (pattern) - 1] == '/')
385 flags |= GLOB_ONLYDIR;
386
387 if (flags & GLOB_BRACE)
388 {
389 const char *begin = strchr (pattern, '{');
390 if (begin != NULL)
391 {
392 /* Allocate working buffer large enough for our work. Note that
393 we have at least an opening and closing brace. */
394 size_t firstc; /* bird: correct type. */
395 char *alt_start;
396 const char *p;
397 const char *next;
398 const char *rest;
399 size_t rest_len;
400#ifdef __GNUC__
401 char onealt[strlen (pattern) - 1];
402#else
403 char *onealt = (char *) malloc (strlen (pattern) - 1);
404 if (onealt == NULL)
405 {
406 if (!(flags & GLOB_APPEND))
407 globfree (pglob);
408 return GLOB_NOSPACE;
409 }
410#endif
411
412 /* We know the prefix for all sub-patterns. */
413#ifdef HAVE_MEMPCPY
414 alt_start = mempcpy (onealt, pattern, begin - pattern);
415#else
416 memcpy (onealt, pattern, begin - pattern);
417 alt_start = &onealt[begin - pattern];
418#endif
419
420 /* Find the first sub-pattern and at the same time find the
421 rest after the closing brace. */
422 next = next_brace_sub (begin + 1);
423 if (next == NULL)
424 {
425 /* It is an illegal expression. */
426#ifndef __GNUC__
427 free (onealt);
428#endif
429 return glob (pattern, flags & ~GLOB_BRACE, errfunc, pglob);
430 }
431
432 /* Now find the end of the whole brace expression. */
433 rest = next;
434 while (*rest != '}')
435 {
436 rest = next_brace_sub (rest + 1);
437 if (rest == NULL)
438 {
439 /* It is an illegal expression. */
440#ifndef __GNUC__
441 free (onealt);
442#endif
443 return glob (pattern, flags & ~GLOB_BRACE, errfunc, pglob);
444 }
445 }
446 /* Please note that we now can be sure the brace expression
447 is well-formed. */
448 rest_len = strlen (++rest) + 1;
449
450 /* We have a brace expression. BEGIN points to the opening {,
451 NEXT points past the terminator of the first element, and END
452 points past the final }. We will accumulate result names from
453 recursive runs for each brace alternative in the buffer using
454 GLOB_APPEND. */
455
456 if (!(flags & GLOB_APPEND))
457 {
458 /* This call is to set a new vector, so clear out the
459 vector so we can append to it. */
460 pglob->gl_pathc = 0;
461 pglob->gl_pathv = NULL;
462 }
463 firstc = pglob->gl_pathc;
464
465 p = begin + 1;
466 while (1)
467 {
468 int result;
469
470 /* Construct the new glob expression. */
471#ifdef HAVE_MEMPCPY
472 mempcpy (mempcpy (alt_start, p, next - p), rest, rest_len);
473#else
474 memcpy (alt_start, p, next - p);
475 memcpy (&alt_start[next - p], rest, rest_len);
476#endif
477
478 result = glob (onealt,
479 ((flags & ~(GLOB_NOCHECK|GLOB_NOMAGIC))
480 | GLOB_APPEND), errfunc, pglob);
481
482 /* If we got an error, return it. */
483 if (result && result != GLOB_NOMATCH)
484 {
485#ifndef __GNUC__
486 free (onealt);
487#endif
488 if (!(flags & GLOB_APPEND))
489 globfree (pglob);
490 return result;
491 }
492
493 if (*next == '}')
494 /* We saw the last entry. */
495 break;
496
497 p = next + 1;
498 next = next_brace_sub (p);
499 assert (next != NULL);
500 }
501
502#ifndef __GNUC__
503 free (onealt);
504#endif
505
506 if (pglob->gl_pathc != firstc)
507 /* We found some entries. */
508 return 0;
509 else if (!(flags & (GLOB_NOCHECK|GLOB_NOMAGIC)))
510 return GLOB_NOMATCH;
511 }
512 }
513
514 /* Find the filename. */
515 filename = strrchr (pattern, '/');
516#if defined __MSDOS__ || defined WINDOWS32
517 /* The case of "d:pattern". Since `:' is not allowed in
518 file names, we can safely assume that wherever it
519 happens in pattern, it signals the filename part. This
520 is so we could some day support patterns like "[a-z]:foo". */
521 if (filename == NULL)
522 filename = strchr (pattern, ':');
523#endif /* __MSDOS__ || WINDOWS32 */
524 if (filename == NULL)
525 {
526 /* This can mean two things: a simple name or "~name". The later
527 case is nothing but a notation for a directory. */
528 if ((flags & (GLOB_TILDE|GLOB_TILDE_CHECK)) && pattern[0] == '~')
529 {
530 dirname = pattern;
531 dirlen = strlen (pattern);
532
533 /* Set FILENAME to NULL as a special flag. This is ugly but
534 other solutions would require much more code. We test for
535 this special case below. */
536 filename = NULL;
537 }
538 else
539 {
540 filename = pattern;
541#ifdef _AMIGA
542 dirname = "";
543#else
544 dirname = ".";
545#endif
546 dirlen = 0;
547 }
548 }
549 else if (filename == pattern)
550 {
551 /* "/pattern". */
552 dirname = "/";
553 dirlen = 1;
554 ++filename;
555 }
556 else
557 {
558 char *newp;
559 dirlen = filename - pattern;
560#if defined __MSDOS__ || defined WINDOWS32
561 if (*filename == ':'
562 || (filename > pattern + 1 && filename[-1] == ':'))
563 {
564 char *drive_spec;
565
566 ++dirlen;
567 drive_spec = (char *) __alloca (dirlen + 1);
568#ifdef HAVE_MEMPCPY
569 *((char *) mempcpy (drive_spec, pattern, dirlen)) = '\0';
570#else
571 memcpy (drive_spec, pattern, dirlen);
572 drive_spec[dirlen] = '\0';
573#endif
574 /* For now, disallow wildcards in the drive spec, to
575 prevent infinite recursion in glob. */
576 if (__glob_pattern_p (drive_spec, !(flags & GLOB_NOESCAPE)))
577 return GLOB_NOMATCH;
578 /* If this is "d:pattern", we need to copy `:' to DIRNAME
579 as well. If it's "d:/pattern", don't remove the slash
580 from "d:/", since "d:" and "d:/" are not the same.*/
581 }
582#endif
583 newp = (char *) __alloca (dirlen + 1);
584#ifdef HAVE_MEMPCPY
585 *((char *) mempcpy (newp, pattern, dirlen)) = '\0';
586#else
587 memcpy (newp, pattern, dirlen);
588 newp[dirlen] = '\0';
589#endif
590 dirname = newp;
591 ++filename;
592
593 if (filename[0] == '\0'
594#if defined __MSDOS__ || defined WINDOWS32
595 && dirname[dirlen - 1] != ':'
596 && (dirlen < 3 || dirname[dirlen - 2] != ':'
597 || dirname[dirlen - 1] != '/')
598#endif
599 && dirlen > 1)
600 /* "pattern/". Expand "pattern", appending slashes. */
601 {
602 int val = glob (dirname, flags | GLOB_MARK, errfunc, pglob);
603 if (val == 0)
604 pglob->gl_flags = ((pglob->gl_flags & ~GLOB_MARK)
605 | (flags & GLOB_MARK));
606 return val;
607 }
608 }
609
610 if (!(flags & GLOB_APPEND))
611 {
612 pglob->gl_pathc = 0;
613 pglob->gl_pathv = NULL;
614 }
615
616 oldcount = pglob->gl_pathc;
617
618#ifndef VMS
619 if ((flags & (GLOB_TILDE|GLOB_TILDE_CHECK)) && dirname[0] == '~')
620 {
621 if (dirname[1] == '\0' || dirname[1] == '/')
622 {
623 /* Look up home directory. */
624#ifdef VMS
625/* This isn't obvious, RTLs of DECC and VAXC know about "HOME" */
626 const char *home_dir = getenv ("SYS$LOGIN");
627#else
628 const char *home_dir = getenv ("HOME");
629#endif
630# ifdef _AMIGA
631 if (home_dir == NULL || home_dir[0] == '\0')
632 home_dir = "SYS:";
633# else
634# ifdef WINDOWS32
635 if (home_dir == NULL || home_dir[0] == '\0')
636 home_dir = "c:/users/default"; /* poor default */
637# else
638# ifdef VMS
639/* Again, this isn't obvious, if "HOME" isn't known "SYS$LOGIN" should be set */
640 if (home_dir == NULL || home_dir[0] == '\0')
641 home_dir = "SYS$DISK:[]";
642# else
643 if (home_dir == NULL || home_dir[0] == '\0')
644 {
645 int success;
646 char *name;
647# if defined HAVE_GETLOGIN_R || defined _LIBC
648 size_t buflen = sysconf (_SC_LOGIN_NAME_MAX) + 1;
649
650 if (buflen == 0)
651 /* `sysconf' does not support _SC_LOGIN_NAME_MAX. Try
652 a moderate value. */
653 buflen = 20;
654 name = (char *) __alloca (buflen);
655
656 success = getlogin_r (name, buflen) >= 0;
657# else
658 success = (name = getlogin ()) != NULL;
659# endif
660 if (success)
661 {
662 struct passwd *p;
663# if defined HAVE_GETPWNAM_R || defined _LIBC
664 size_t pwbuflen = sysconf (_SC_GETPW_R_SIZE_MAX);
665 char *pwtmpbuf;
666 struct passwd pwbuf;
667 int save = errno;
668
669 if (pwbuflen == -1)
670 /* `sysconf' does not support _SC_GETPW_R_SIZE_MAX.
671 Try a moderate value. */
672 pwbuflen = 1024;
673 pwtmpbuf = (char *) __alloca (pwbuflen);
674
675 while (getpwnam_r (name, &pwbuf, pwtmpbuf, pwbuflen, &p)
676 != 0)
677 {
678 if (errno != ERANGE)
679 {
680 p = NULL;
681 break;
682 }
683 pwbuflen *= 2;
684 pwtmpbuf = (char *) __alloca (pwbuflen);
685 __set_errno (save);
686 }
687# else
688 p = getpwnam (name);
689# endif
690 if (p != NULL)
691 home_dir = p->pw_dir;
692 }
693 }
694 if (home_dir == NULL || home_dir[0] == '\0')
695 {
696 if (flags & GLOB_TILDE_CHECK)
697 return GLOB_NOMATCH;
698 else
699 home_dir = "~"; /* No luck. */
700 }
701# endif /* VMS */
702# endif /* WINDOWS32 */
703# endif
704 /* Now construct the full directory. */
705 if (dirname[1] == '\0')
706 dirname = home_dir;
707 else
708 {
709 char *newp;
710 size_t home_len = strlen (home_dir);
711 newp = (char *) __alloca (home_len + dirlen);
712# ifdef HAVE_MEMPCPY
713 mempcpy (mempcpy (newp, home_dir, home_len),
714 &dirname[1], dirlen);
715# else
716 memcpy (newp, home_dir, home_len);
717 memcpy (&newp[home_len], &dirname[1], dirlen);
718# endif
719 dirname = newp;
720 }
721 }
722# if !defined _AMIGA && !defined WINDOWS32 && !defined VMS
723 else
724 {
725 char *end_name = strchr (dirname, '/');
726 const char *user_name;
727 const char *home_dir;
728
729 if (end_name == NULL)
730 user_name = dirname + 1;
731 else
732 {
733 char *newp;
734 newp = (char *) __alloca (end_name - dirname);
735# ifdef HAVE_MEMPCPY
736 *((char *) mempcpy (newp, dirname + 1, end_name - dirname))
737 = '\0';
738# else
739 memcpy (newp, dirname + 1, end_name - dirname);
740 newp[end_name - dirname - 1] = '\0';
741# endif
742 user_name = newp;
743 }
744
745 /* Look up specific user's home directory. */
746 {
747 struct passwd *p;
748# if defined HAVE_GETPWNAM_R || defined _LIBC
749 size_t buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
750 char *pwtmpbuf;
751 struct passwd pwbuf;
752 int save = errno;
753
754 if (buflen == -1)
755 /* `sysconf' does not support _SC_GETPW_R_SIZE_MAX. Try a
756 moderate value. */
757 buflen = 1024;
758 pwtmpbuf = (char *) __alloca (buflen);
759
760 while (getpwnam_r (user_name, &pwbuf, pwtmpbuf, buflen, &p) != 0)
761 {
762 if (errno != ERANGE)
763 {
764 p = NULL;
765 break;
766 }
767 buflen *= 2;
768 pwtmpbuf = __alloca (buflen);
769 __set_errno (save);
770 }
771# else
772 p = getpwnam (user_name);
773# endif
774 if (p != NULL)
775 home_dir = p->pw_dir;
776 else
777 home_dir = NULL;
778 }
779 /* If we found a home directory use this. */
780 if (home_dir != NULL)
781 {
782 char *newp;
783 size_t home_len = strlen (home_dir);
784 size_t rest_len = end_name == NULL ? 0 : strlen (end_name);
785 newp = (char *) __alloca (home_len + rest_len + 1);
786# ifdef HAVE_MEMPCPY
787 *((char *) mempcpy (mempcpy (newp, home_dir, home_len),
788 end_name, rest_len)) = '\0';
789# else
790 memcpy (newp, home_dir, home_len);
791 memcpy (&newp[home_len], end_name, rest_len);
792 newp[home_len + rest_len] = '\0';
793# endif
794 dirname = newp;
795 }
796 else
797 if (flags & GLOB_TILDE_CHECK)
798 /* We have to regard it as an error if we cannot find the
799 home directory. */
800 return GLOB_NOMATCH;
801 }
802# endif /* Not Amiga && not WINDOWS32 && not VMS. */
803 }
804#endif /* Not VMS. */
805
806 /* Now test whether we looked for "~" or "~NAME". In this case we
807 can give the answer now. */
808 if (filename == NULL)
809 {
810 struct stat st;
811
812 /* Return the directory if we don't check for error or if it exists. */
813 if ((flags & GLOB_NOCHECK)
814#ifdef KMK
815 || (flags & GLOB_ALTDIRFUNC
816 ? (*pglob->gl_isdir) (dirname)
817 : __stat (dirname, &st) == 0 && S_ISDIR (st.st_mode))
818#else
819 || (((flags & GLOB_ALTDIRFUNC)
820 ? (*pglob->gl_stat) (dirname, &st)
821 : __stat (dirname, &st)) == 0
822 && S_ISDIR (st.st_mode))
823#endif
824 )
825 {
826 pglob->gl_pathv
827 = (char **) realloc (pglob->gl_pathv,
828 (pglob->gl_pathc +
829 ((flags & GLOB_DOOFFS) ?
830 pglob->gl_offs : 0) +
831 1 + 1) *
832 sizeof (char *));
833 if (pglob->gl_pathv == NULL)
834 return GLOB_NOSPACE;
835
836 if (flags & GLOB_DOOFFS)
837 while (pglob->gl_pathc < pglob->gl_offs)
838 pglob->gl_pathv[pglob->gl_pathc++] = NULL;
839
840#if defined HAVE_STRDUP || defined _LIBC
841 pglob->gl_pathv[pglob->gl_pathc] = strdup (dirname);
842#else
843 {
844 size_t len = strlen (dirname) + 1;
845 char *dircopy = malloc (len);
846 if (dircopy != NULL)
847 pglob->gl_pathv[pglob->gl_pathc] = memcpy (dircopy, dirname,
848 len);
849 }
850#endif
851 if (pglob->gl_pathv[pglob->gl_pathc] == NULL)
852 {
853 free (pglob->gl_pathv);
854 return GLOB_NOSPACE;
855 }
856 pglob->gl_pathv[++pglob->gl_pathc] = NULL;
857 pglob->gl_flags = flags;
858
859 return 0;
860 }
861
862 /* Not found. */
863 return GLOB_NOMATCH;
864 }
865
866 if (__glob_pattern_p (dirname, !(flags & GLOB_NOESCAPE)))
867 {
868 /* The directory name contains metacharacters, so we
869 have to glob for the directory, and then glob for
870 the pattern in each directory found. */
871 glob_t dirs;
872 register __size_t i; /* bird: correct type. */
873
874 status = glob (dirname,
875 ((flags & (GLOB_ERR | GLOB_NOCHECK | GLOB_NOESCAPE))
876 | GLOB_NOSORT | GLOB_ONLYDIR),
877 errfunc, &dirs);
878 if (status != 0)
879 return status;
880
881 /* We have successfully globbed the preceding directory name.
882 For each name we found, call glob_in_dir on it and FILENAME,
883 appending the results to PGLOB. */
884 for (i = 0; i < dirs.gl_pathc; ++i)
885 {
886 int old_pathc;
887
888#ifdef SHELL
889 {
890 /* Make globbing interruptible in the bash shell. */
891 extern int interrupt_state;
892
893 if (interrupt_state)
894 {
895 globfree (&dirs);
896 globfree (&files);
897 return GLOB_ABORTED;
898 }
899 }
900#endif /* SHELL. */
901
902 old_pathc = pglob->gl_pathc;
903 status = glob_in_dir (filename, dirs.gl_pathv[i],
904 ((flags | GLOB_APPEND)
905 & ~(GLOB_NOCHECK | GLOB_ERR)),
906 errfunc, pglob);
907 if (status == GLOB_NOMATCH)
908 /* No matches in this directory. Try the next. */
909 continue;
910
911 if (status != 0)
912 {
913 globfree (&dirs);
914 globfree (pglob);
915 return status;
916 }
917
918 /* Stick the directory on the front of each name. */
919 if (prefix_array (dirs.gl_pathv[i],
920 &pglob->gl_pathv[old_pathc],
921 pglob->gl_pathc - old_pathc))
922 {
923 globfree (&dirs);
924 globfree (pglob);
925 return GLOB_NOSPACE;
926 }
927 }
928
929 flags |= GLOB_MAGCHAR;
930
931 /* We have ignored the GLOB_NOCHECK flag in the `glob_in_dir' calls.
932 But if we have not found any matching entry and thie GLOB_NOCHECK
933 flag was set we must return the list consisting of the disrectory
934 names followed by the filename. */
935 if (pglob->gl_pathc == oldcount)
936 {
937 /* No matches. */
938 if (flags & GLOB_NOCHECK)
939 {
940 size_t filename_len = strlen (filename) + 1;
941 char **new_pathv;
942 struct stat st;
943
944 /* This is an pessimistic guess about the size. */
945 pglob->gl_pathv
946 = (char **) realloc (pglob->gl_pathv,
947 (pglob->gl_pathc +
948 ((flags & GLOB_DOOFFS) ?
949 pglob->gl_offs : 0) +
950 dirs.gl_pathc + 1) *
951 sizeof (char *));
952 if (pglob->gl_pathv == NULL)
953 {
954 globfree (&dirs);
955 return GLOB_NOSPACE;
956 }
957
958 if (flags & GLOB_DOOFFS)
959 while (pglob->gl_pathc < pglob->gl_offs)
960 pglob->gl_pathv[pglob->gl_pathc++] = NULL;
961
962 for (i = 0; i < dirs.gl_pathc; ++i)
963 {
964 const char *dir = dirs.gl_pathv[i];
965 size_t dir_len = strlen (dir);
966
967 /* First check whether this really is a directory. */
968#ifdef KMK
969 if (flags & GLOB_ALTDIRFUNC
970 ? !pglob->gl_isdir (dir)
971 : __stat (dir, &st) != 0 || !S_ISDIR (st.st_mode))
972#else
973 if (((flags & GLOB_ALTDIRFUNC)
974 ? (*pglob->gl_stat) (dir, &st) : __stat (dir, &st)) != 0
975 || !S_ISDIR (st.st_mode))
976#endif
977 /* No directory, ignore this entry. */
978 continue;
979
980 pglob->gl_pathv[pglob->gl_pathc] = malloc (dir_len + 1
981 + filename_len);
982 if (pglob->gl_pathv[pglob->gl_pathc] == NULL)
983 {
984 globfree (&dirs);
985 globfree (pglob);
986 return GLOB_NOSPACE;
987 }
988
989#ifdef HAVE_MEMPCPY
990 mempcpy (mempcpy (mempcpy (pglob->gl_pathv[pglob->gl_pathc],
991 dir, dir_len),
992 "/", 1),
993 filename, filename_len);
994#else
995 memcpy (pglob->gl_pathv[pglob->gl_pathc], dir, dir_len);
996 pglob->gl_pathv[pglob->gl_pathc][dir_len] = '/';
997 memcpy (&pglob->gl_pathv[pglob->gl_pathc][dir_len + 1],
998 filename, filename_len);
999#endif
1000 ++pglob->gl_pathc;
1001 }
1002
1003 pglob->gl_pathv[pglob->gl_pathc] = NULL;
1004 pglob->gl_flags = flags;
1005
1006 /* Now we know how large the gl_pathv vector must be. */
1007 new_pathv = (char **) realloc (pglob->gl_pathv,
1008 ((pglob->gl_pathc + 1)
1009 * sizeof (char *)));
1010 if (new_pathv != NULL)
1011 pglob->gl_pathv = new_pathv;
1012 }
1013 else
1014 return GLOB_NOMATCH;
1015 }
1016
1017 globfree (&dirs);
1018 }
1019 else
1020 {
1021 status = glob_in_dir (filename, dirname, flags, errfunc, pglob);
1022 if (status != 0)
1023 return status;
1024
1025 if (dirlen > 0)
1026 {
1027 /* Stick the directory on the front of each name. */
1028 __size_t ignore = oldcount; /* bird: correct type. */
1029
1030 if ((flags & GLOB_DOOFFS) && ignore < pglob->gl_offs)
1031 ignore = pglob->gl_offs;
1032
1033 if (prefix_array (dirname,
1034 &pglob->gl_pathv[ignore],
1035 pglob->gl_pathc - ignore))
1036 {
1037 globfree (pglob);
1038 return GLOB_NOSPACE;
1039 }
1040 }
1041 }
1042
1043 if (flags & GLOB_MARK)
1044 {
1045 /* Append slashes to directory names. */
1046 __size_t i; /* bird: correct type. */
1047 struct stat st;
1048 for (i = oldcount; i < pglob->gl_pathc; ++i)
1049#ifdef KMK
1050 if (flags & GLOB_ALTDIRFUNC
1051 ? pglob->gl_isdir (pglob->gl_pathv[i])
1052 : __stat (pglob->gl_pathv[i], &st) == 0 && S_ISDIR (st.st_mode) )
1053#else
1054 if (((flags & GLOB_ALTDIRFUNC)
1055 ? (*pglob->gl_stat) (pglob->gl_pathv[i], &st)
1056 : __stat (pglob->gl_pathv[i], &st)) == 0
1057 && S_ISDIR (st.st_mode))
1058#endif
1059 {
1060 size_t len = strlen (pglob->gl_pathv[i]) + 2;
1061 char *new = realloc (pglob->gl_pathv[i], len);
1062 if (new == NULL)
1063 {
1064 globfree (pglob);
1065 return GLOB_NOSPACE;
1066 }
1067 strcpy (&new[len - 2], "/");
1068 pglob->gl_pathv[i] = new;
1069 }
1070 }
1071
1072 if (!(flags & GLOB_NOSORT))
1073 {
1074 /* Sort the vector. */
1075 int non_sort = oldcount;
1076
1077 if ((flags & GLOB_DOOFFS) && pglob->gl_offs > oldcount)
1078 non_sort = pglob->gl_offs;
1079
1080 qsort ((__ptr_t) &pglob->gl_pathv[non_sort],
1081 pglob->gl_pathc - non_sort,
1082 sizeof (char *), collated_compare);
1083 }
1084
1085 return 0;
1086}
1087
1088
1089/* Free storage allocated in PGLOB by a previous `glob' call. */
1090void
1091globfree (pglob)
1092 register glob_t *pglob;
1093{
1094 if (pglob->gl_pathv != NULL)
1095 {
1096 register __size_t i; /* bird: correct type */
1097 for (i = 0; i < pglob->gl_pathc; ++i)
1098 if (pglob->gl_pathv[i] != NULL)
1099 free ((__ptr_t) pglob->gl_pathv[i]);
1100 free ((__ptr_t) pglob->gl_pathv);
1101 }
1102}
1103
1104
1105/* Do a collated comparison of A and B. */
1106static int
1107collated_compare (a, b)
1108 const __ptr_t a;
1109 const __ptr_t b;
1110{
1111 const char *const s1 = *(const char *const * const) a;
1112 const char *const s2 = *(const char *const * const) b;
1113
1114 if (s1 == s2)
1115 return 0;
1116 if (s1 == NULL)
1117 return 1;
1118 if (s2 == NULL)
1119 return -1;
1120 return strcoll (s1, s2);
1121}
1122
1123
1124/* Prepend DIRNAME to each of N members of ARRAY, replacing ARRAY's
1125 elements in place. Return nonzero if out of memory, zero if successful.
1126 A slash is inserted between DIRNAME and each elt of ARRAY,
1127 unless DIRNAME is just "/". Each old element of ARRAY is freed. */
1128static int
1129prefix_array (dirname, array, n)
1130 const char *dirname;
1131 char **array;
1132 size_t n;
1133{
1134 register size_t i;
1135 size_t dirlen = strlen (dirname);
1136#if defined __MSDOS__ || defined WINDOWS32
1137 int sep_char = '/';
1138# define DIRSEP_CHAR sep_char
1139#else
1140# define DIRSEP_CHAR '/'
1141#endif
1142
1143 if (dirlen == 1 && dirname[0] == '/')
1144 /* DIRNAME is just "/", so normal prepending would get us "//foo".
1145 We want "/foo" instead, so don't prepend any chars from DIRNAME. */
1146 dirlen = 0;
1147#if defined __MSDOS__ || defined WINDOWS32
1148 else if (dirlen > 1)
1149 {
1150 if (dirname[dirlen - 1] == '/' && dirname[dirlen - 2] == ':')
1151 /* DIRNAME is "d:/". Don't prepend the slash from DIRNAME. */
1152 --dirlen;
1153 else if (dirname[dirlen - 1] == ':')
1154 {
1155 /* DIRNAME is "d:". Use `:' instead of `/'. */
1156 --dirlen;
1157 sep_char = ':';
1158 }
1159 }
1160#endif
1161
1162 for (i = 0; i < n; ++i)
1163 {
1164 size_t eltlen = strlen (array[i]) + 1;
1165 char *new = (char *) malloc (dirlen + 1 + eltlen);
1166 if (new == NULL)
1167 {
1168 while (i > 0)
1169 free ((__ptr_t) array[--i]);
1170 return 1;
1171 }
1172
1173#ifdef HAVE_MEMPCPY
1174 {
1175 char *endp = (char *) mempcpy (new, dirname, dirlen);
1176 *endp++ = DIRSEP_CHAR;
1177 mempcpy (endp, array[i], eltlen);
1178 }
1179#else
1180 memcpy (new, dirname, dirlen);
1181 new[dirlen] = DIRSEP_CHAR;
1182 memcpy (&new[dirlen + 1], array[i], eltlen);
1183#endif
1184 free ((__ptr_t) array[i]);
1185 array[i] = new;
1186 }
1187
1188 return 0;
1189}
1190
1191
1192/* We must not compile this function twice. */
1193#if !defined _LIBC || !defined NO_GLOB_PATTERN_P
1194/* Return nonzero if PATTERN contains any metacharacters.
1195 Metacharacters can be quoted with backslashes if QUOTE is nonzero. */
1196int
1197__glob_pattern_p (pattern, quote)
1198 const char *pattern;
1199 int quote;
1200{
1201 register const char *p;
1202 int open = 0;
1203
1204 for (p = pattern; *p != '\0'; ++p)
1205 switch (*p)
1206 {
1207 case '?':
1208 case '*':
1209 return 1;
1210
1211 case '\\':
1212 if (quote && p[1] != '\0')
1213 ++p;
1214 break;
1215
1216 case '[':
1217 open = 1;
1218 break;
1219
1220 case ']':
1221 if (open)
1222 return 1;
1223 break;
1224 }
1225
1226 return 0;
1227}
1228# ifdef _LIBC
1229weak_alias (__glob_pattern_p, glob_pattern_p)
1230# endif
1231#endif
1232
1233
1234/* Like `glob', but PATTERN is a final pathname component,
1235 and matches are searched for in DIRECTORY.
1236 The GLOB_NOSORT bit in FLAGS is ignored. No sorting is ever done.
1237 The GLOB_APPEND flag is assumed to be set (always appends). */
1238static int
1239glob_in_dir (pattern, directory, flags, errfunc, pglob)
1240 const char *pattern;
1241 const char *directory;
1242 int flags;
1243 int (*errfunc) __P ((const char *, int));
1244 glob_t *pglob;
1245{
1246 __ptr_t stream = NULL;
1247
1248 struct globlink
1249 {
1250 struct globlink *next;
1251 char *name;
1252 };
1253 struct globlink *names = NULL;
1254 size_t nfound;
1255 int meta;
1256 int save;
1257
1258#ifdef VMS
1259 if (*directory == 0)
1260 directory = "[]";
1261#endif
1262 meta = __glob_pattern_p (pattern, !(flags & GLOB_NOESCAPE));
1263 if (meta == 0)
1264 {
1265 if (flags & (GLOB_NOCHECK|GLOB_NOMAGIC))
1266 /* We need not do any tests. The PATTERN contains no meta
1267 characters and we must not return an error therefore the
1268 result will always contain exactly one name. */
1269 flags |= GLOB_NOCHECK;
1270 else
1271 {
1272 /* Since we use the normal file functions we can also use stat()
1273 to verify the file is there. */
1274 struct stat st;
1275 size_t patlen = strlen (pattern);
1276 size_t dirlen = strlen (directory);
1277 char *fullname = (char *) __alloca (dirlen + 1 + patlen + 1);
1278
1279# ifdef HAVE_MEMPCPY
1280 mempcpy (mempcpy (mempcpy (fullname, directory, dirlen),
1281 "/", 1),
1282 pattern, patlen + 1);
1283# else
1284 memcpy (fullname, directory, dirlen);
1285 fullname[dirlen] = '/';
1286 memcpy (&fullname[dirlen + 1], pattern, patlen + 1);
1287# endif
1288# ifdef KMK
1289 if (flags & GLOB_ALTDIRFUNC ? pglob->gl_exists (fullname) : __stat (fullname, &st) == 0)
1290# else
1291 if (((flags & GLOB_ALTDIRFUNC)
1292 ? (*pglob->gl_stat) (fullname, &st)
1293 : __stat (fullname, &st)) == 0)
1294# endif
1295 /* We found this file to be existing. Now tell the rest
1296 of the function to copy this name into the result. */
1297 flags |= GLOB_NOCHECK;
1298 }
1299
1300 nfound = 0;
1301 }
1302 else
1303 {
1304 if (pattern[0] == '\0')
1305 {
1306 /* This is a special case for matching directories like in
1307 "*a/". */
1308 names = (struct globlink *) __alloca (sizeof (struct globlink));
1309 names->name = (char *) malloc (1);
1310 if (names->name == NULL)
1311 goto memory_error;
1312 names->name[0] = '\0';
1313 names->next = NULL;
1314 nfound = 1;
1315 meta = 0;
1316 }
1317 else
1318 {
1319 stream = ((flags & GLOB_ALTDIRFUNC)
1320 ? (*pglob->gl_opendir) (directory)
1321 : (__ptr_t) opendir (directory));
1322 if (stream == NULL)
1323 {
1324 if (errno != ENOTDIR
1325 && ((errfunc != NULL && (*errfunc) (directory, errno))
1326 || (flags & GLOB_ERR)))
1327 return GLOB_ABORTED;
1328 nfound = 0;
1329 meta = 0;
1330 }
1331 else
1332 {
1333 int fnm_flags = ((!(flags & GLOB_PERIOD) ? FNM_PERIOD : 0)
1334 | ((flags & GLOB_NOESCAPE) ? FNM_NOESCAPE : 0)
1335#if defined HAVE_CASE_INSENSITIVE_FS
1336 | FNM_CASEFOLD
1337#endif
1338 );
1339 nfound = 0;
1340 flags |= GLOB_MAGCHAR;
1341
1342 while (1)
1343 {
1344 const char *name;
1345 size_t len;
1346 struct dirent *d = ((flags & GLOB_ALTDIRFUNC)
1347 ? (*pglob->gl_readdir) (stream)
1348 : readdir ((DIR *) stream));
1349 if (d == NULL)
1350 break;
1351 if (! REAL_DIR_ENTRY (d))
1352 continue;
1353
1354#ifdef HAVE_D_TYPE
1355 /* If we shall match only directories use the information
1356 provided by the dirent call if possible. */
1357 if ((flags & GLOB_ONLYDIR)
1358 && d->d_type != DT_UNKNOWN && d->d_type != DT_DIR)
1359 continue;
1360#endif
1361
1362 name = d->d_name;
1363
1364 if (fnmatch (pattern, name, fnm_flags) == 0)
1365 {
1366 struct globlink *new = (struct globlink *)
1367 __alloca (sizeof (struct globlink));
1368 len = NAMLEN (d);
1369 new->name = (char *) malloc (len + 1);
1370 if (new->name == NULL)
1371 goto memory_error;
1372#ifdef HAVE_MEMPCPY
1373 *((char *) mempcpy ((__ptr_t) new->name, name, len))
1374 = '\0';
1375#else
1376 memcpy ((__ptr_t) new->name, name, len);
1377 new->name[len] = '\0';
1378#endif
1379 new->next = names;
1380 names = new;
1381 ++nfound;
1382 }
1383 }
1384 }
1385 }
1386 }
1387
1388 if (nfound == 0 && (flags & GLOB_NOCHECK))
1389 {
1390 size_t len = strlen (pattern);
1391 nfound = 1;
1392 names = (struct globlink *) __alloca (sizeof (struct globlink));
1393 names->next = NULL;
1394 names->name = (char *) malloc (len + 1);
1395 if (names->name == NULL)
1396 goto memory_error;
1397#ifdef HAVE_MEMPCPY
1398 *((char *) mempcpy (names->name, pattern, len)) = '\0';
1399#else
1400 memcpy (names->name, pattern, len);
1401 names->name[len] = '\0';
1402#endif
1403 }
1404
1405 if (nfound != 0)
1406 {
1407 pglob->gl_pathv
1408 = (char **) realloc (pglob->gl_pathv,
1409 (pglob->gl_pathc +
1410 ((flags & GLOB_DOOFFS) ? pglob->gl_offs : 0) +
1411 nfound + 1) *
1412 sizeof (char *));
1413 if (pglob->gl_pathv == NULL)
1414 goto memory_error;
1415
1416 if (flags & GLOB_DOOFFS)
1417 while (pglob->gl_pathc < pglob->gl_offs)
1418 pglob->gl_pathv[pglob->gl_pathc++] = NULL;
1419
1420 for (; names != NULL; names = names->next)
1421 pglob->gl_pathv[pglob->gl_pathc++] = names->name;
1422 pglob->gl_pathv[pglob->gl_pathc] = NULL;
1423
1424 pglob->gl_flags = flags;
1425 }
1426
1427 save = errno;
1428 if (stream != NULL)
1429 {
1430 if (flags & GLOB_ALTDIRFUNC)
1431 (*pglob->gl_closedir) (stream);
1432 else
1433 closedir ((DIR *) stream);
1434 }
1435 __set_errno (save);
1436
1437 return nfound == 0 ? GLOB_NOMATCH : 0;
1438
1439 memory_error:
1440 {
1441 int save = errno;
1442 if (flags & GLOB_ALTDIRFUNC)
1443 (*pglob->gl_closedir) (stream);
1444 else
1445 closedir ((DIR *) stream);
1446 __set_errno (save);
1447 }
1448 while (names != NULL)
1449 {
1450 if (names->name != NULL)
1451 free ((__ptr_t) names->name);
1452 names = names->next;
1453 }
1454 return GLOB_NOSPACE;
1455}
1456
1457#endif /* Not ELIDE_CODE. */
Note: See TracBrowser for help on using the repository browser.