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

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

kmk: Always use our glob and fnmatch implementation to avoid trouble (debian builds ran into something, if I understood it correctly).

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