2 * Copyright (c) 2008 Todd C. Miller <Todd.Miller@courtesan.com>
3 * Copyright (c) 1989, 1993
4 * The Regents of the University of California. All rights reserved.
6 * This code is derived from software contributed to Berkeley by
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * @(#)glob.c 8.3 (Berkeley) 10/13/93
37 * glob(3) -- a superset of the one defined in POSIX 1003.2.
39 * The [!...] convention to negate a range is supported (SysV, Posix, ksh).
41 * Optional extra services, controlled by flags not defined by POSIX:
44 * Set in gl_flags if pattern contained a globbing character.
46 * expand ~user/foo to the /home/dir/of/user/foo
48 * expand {1,2}{a,b} to 1a 1b 2a 2b
50 * Number of matches in the current invocation of glob.
55 #include <sys/param.h>
66 #endif /* STDC_HEADERS */
67 #if defined(HAVE_MALLOC_H) && !defined(STDC_HEADERS)
69 #endif /* HAVE_MALLOC_H && !STDC_HEADERS */
73 # ifdef HAVE_STRINGS_H
76 #endif /* HAVE_STRING_H */
79 #endif /* HAVE_UNISTD_H */
84 # define dirent direct
85 # ifdef HAVE_SYS_NDIR_H
86 # include <sys/ndir.h>
88 # ifdef HAVE_SYS_DIR_H
100 #include "emul/glob.h"
101 #include "emul/charclass.h"
115 #define UNDERSCORE '_'
123 #define M_QUOTE 0x8000
124 #define M_PROTECT 0x4000
125 #define M_MASK 0xffff
126 #define M_ASCII 0x00ff
128 typedef unsigned short Char;
133 #define M_PROTECT 0x40
142 #define CHAR(c) ((Char)((c)&M_ASCII))
143 #define META(c) ((Char)((c)|M_QUOTE))
144 #define M_ALL META('*')
145 #define M_END META(']')
146 #define M_NOT META('!')
147 #define M_ONE META('?')
148 #define M_RNG META('-')
149 #define M_SET META('[')
150 #define M_CLASS META(':')
151 #define ismeta(c) (((c)&M_QUOTE) != 0)
154 static int compare __P((const void *, const void *));
155 static int g_Ctoc __P((const Char *, char *, unsigned int));
156 static int g_lstat __P((Char *, struct stat *, glob_t *));
157 static DIR *g_opendir __P((Char *, glob_t *));
158 static Char *g_strchr __P((const Char *, int));
159 static int g_strncmp __P((const Char *, const char *, size_t));
160 static int g_stat __P((Char *, struct stat *, glob_t *));
161 static int glob0 __P((const Char *, glob_t *));
162 static int glob1 __P((Char *, Char *, glob_t *));
163 static int glob2 __P((Char *, Char *, Char *, Char *, Char *, Char *,
165 static int glob3 __P((Char *, Char *, Char *, Char *, Char *, Char *,
166 Char *, Char *, glob_t *));
167 static int globextend __P((const Char *, glob_t *));
169 globtilde __P((const Char *, Char *, size_t, glob_t *));
170 static int globexp1 __P((const Char *, glob_t *));
171 static int globexp2 __P((const Char *, const Char *, glob_t *, int *));
172 static int match __P((Char *, Char *, Char *));
174 static void qprintf __P((const char *, Char *));
177 extern struct passwd *sudo_getpwnam __P((const char *));
178 extern struct passwd *sudo_getpwuid __P((uid_t));
181 glob(pattern, flags, errfunc, pglob)
183 int flags, (*errfunc) __P((const char *, int));
186 const unsigned char *patnext;
188 Char *bufnext, *bufend, patbuf[PATH_MAX];
190 patnext = (unsigned char *) pattern;
191 if (!(flags & GLOB_APPEND)) {
193 pglob->gl_pathv = NULL;
194 if (!(flags & GLOB_DOOFFS))
197 pglob->gl_flags = flags & ~GLOB_MAGCHAR;
198 pglob->gl_errfunc = errfunc;
199 pglob->gl_matchc = 0;
202 bufend = bufnext + PATH_MAX - 1;
203 if (flags & GLOB_NOESCAPE)
204 while (bufnext < bufend && (c = *patnext++) != EOS)
207 /* Protect the quoted characters. */
208 while (bufnext < bufend && (c = *patnext++) != EOS)
210 if ((c = *patnext++) == EOS) {
214 *bufnext++ = c | M_PROTECT;
220 if (flags & GLOB_BRACE)
221 return globexp1(patbuf, pglob);
223 return glob0(patbuf, pglob);
227 * Expand recursively a glob {} pattern. When there is no more expansion
228 * invoke the standard globbing routine to glob the rest of the magic
232 globexp1(pattern, pglob)
236 const Char* ptr = pattern;
239 /* Protect a single {}, for find(1), like csh */
240 if (pattern[0] == LBRACE && pattern[1] == RBRACE && pattern[2] == EOS)
241 return glob0(pattern, pglob);
243 while ((ptr = (const Char *) g_strchr(ptr, LBRACE)) != NULL)
244 if (!globexp2(ptr, pattern, pglob, &rv))
247 return glob0(pattern, pglob);
252 * Recursive brace globbing helper. Tries to expand a single brace.
253 * If it succeeds then it invokes globexp1 with the new pattern.
254 * If it fails then it tries to glob the rest of the pattern and returns.
257 globexp2(ptr, pattern, pglob, rv)
258 const Char *ptr, *pattern;
264 const Char *pe, *pm, *pl;
265 Char patbuf[PATH_MAX];
267 /* copy part up to the brace */
268 for (lm = patbuf, pm = pattern; pm != ptr; *lm++ = *pm++)
273 /* Find the balanced brace */
274 for (i = 0, pe = ++ptr; *pe; pe++)
275 if (*pe == LBRACKET) {
276 /* Ignore everything between [] */
277 for (pm = pe++; *pe != RBRACKET && *pe != EOS; pe++)
281 * We could not find a matching RBRACKET.
282 * Ignore and just look for RBRACE
286 } else if (*pe == LBRACE)
288 else if (*pe == RBRACE) {
294 /* Non matching braces; just glob the pattern */
295 if (i != 0 || *pe == EOS) {
296 *rv = glob0(patbuf, pglob);
300 for (i = 0, pl = pm = ptr; pm <= pe; pm++) {
303 /* Ignore everything between [] */
304 for (pl = pm++; *pm != RBRACKET && *pm != EOS; pm++)
308 * We could not find a matching RBRACKET.
309 * Ignore and just look for RBRACE
326 if (i && *pm == COMMA)
329 /* Append the current string */
330 for (lm = ls; (pl < pm); *lm++ = *pl++)
334 * Append the rest of the pattern after the
337 for (pl = pe + 1; (*lm++ = *pl++) != EOS; )
340 /* Expand the current pattern */
342 qprintf("globexp2:", patbuf);
344 *rv = globexp1(patbuf, pglob);
346 /* move after the comma, to the next string */
362 * expand tilde from the passwd file.
365 globtilde(pattern, patbuf, patbuf_len, pglob)
376 if (*pattern != TILDE || !(pglob->gl_flags & GLOB_TILDE))
379 /* Copy up to the end of the string or / */
380 eb = &patbuf[patbuf_len - 1];
381 for (p = pattern + 1, h = (char *) patbuf;
382 h < (char *)eb && *p && *p != SLASH; *h++ = *p++)
387 if (((char *) patbuf)[0] == EOS) {
389 * handle a plain ~ or ~/ by expanding $HOME
390 * first and then trying the password file
392 if ((h = getenv("HOME")) == NULL) {
393 if ((pwd = sudo_getpwuid(getuid())) == NULL)
402 if ((pwd = sudo_getpwnam((char*) patbuf)) == NULL)
408 /* Copy the home directory */
409 for (b = patbuf; b < eb && *h; *b++ = *h++)
412 /* Append the rest of the pattern */
413 while (b < eb && (*b++ = *p++) != EOS)
429 rv = *(Char *)s1 - *(const unsigned char *)s2++;
439 g_charclass(patternp, bufnextp)
440 const Char **patternp;
443 const Char *pattern = *patternp + 1;
444 Char *bufnext = *bufnextp;
449 if ((colon = g_strchr(pattern, ':')) == NULL || colon[1] != ']')
450 return 1; /* not a character class */
452 len = (size_t)(colon - pattern);
453 for (cc = cclasses; cc->name != NULL; cc++) {
454 if (!g_strncmp(pattern, cc->name, len) && cc->name[len] == '\0')
457 if (cc->name == NULL)
458 return -1; /* invalid character class */
459 *bufnext++ = M_CLASS;
460 *bufnext++ = (Char)(cc - &cclasses[0]);
462 *patternp += len + 3;
468 * The main glob() routine: compiles the pattern (optionally processing
469 * quotes), calls glob1() to do the real pattern matching, and finally
470 * sorts the list (unless unsorted operation is requested). Returns 0
471 * if things went well, nonzero if errors occurred. It is not an error
472 * to find no matches.
475 glob0(pattern, pglob)
479 const Char *qpatnext;
480 int c, err, oldpathc;
481 Char *bufnext, patbuf[PATH_MAX];
483 qpatnext = globtilde(pattern, patbuf, PATH_MAX, pglob);
484 oldpathc = pglob->gl_pathc;
487 /* We don't need to check for buffer overflow any more. */
488 while ((c = *qpatnext++) != EOS) {
494 if (*qpatnext == EOS ||
495 g_strchr(qpatnext+1, RBRACKET) == NULL) {
496 *bufnext++ = LBRACKET;
506 if (c == LBRACKET && *qpatnext == ':') {
508 err = g_charclass(&qpatnext,
513 } while (c == LBRACKET && *qpatnext == ':');
515 !(pglob->gl_flags & GLOB_NOCHECK))
520 *bufnext++ = CHAR(c);
521 if (*qpatnext == RANGE &&
522 (c = qpatnext[1]) != RBRACKET) {
524 *bufnext++ = CHAR(c);
527 } while ((c = *qpatnext++) != RBRACKET);
528 pglob->gl_flags |= GLOB_MAGCHAR;
532 pglob->gl_flags |= GLOB_MAGCHAR;
536 pglob->gl_flags |= GLOB_MAGCHAR;
537 /* collapse adjacent stars to one,
538 * to avoid exponential behavior
540 if (bufnext == patbuf || bufnext[-1] != M_ALL)
544 *bufnext++ = CHAR(c);
550 qprintf("glob0:", patbuf);
553 if ((err = glob1(patbuf, patbuf + PATH_MAX - 1, pglob)) != 0)
557 * If there was no match we are going to append the pattern
558 * if GLOB_NOCHECK was specified.
560 if (pglob->gl_pathc == oldpathc) {
561 if (pglob->gl_flags & GLOB_NOCHECK)
562 return(globextend(pattern, pglob));
564 return(GLOB_NOMATCH);
566 if (!(pglob->gl_flags & GLOB_NOSORT))
567 qsort(pglob->gl_pathv + pglob->gl_offs + oldpathc,
568 pglob->gl_pathc - oldpathc, sizeof(char *), compare);
576 return(strcmp(*(char **)p, *(char **)q));
580 glob1(pattern, pattern_last, pglob)
581 Char *pattern, *pattern_last;
584 Char pathbuf[PATH_MAX];
586 /* A null pathname is invalid -- POSIX 1003.1 sect. 2.4. */
589 return(glob2(pathbuf, pathbuf + PATH_MAX - 1,
590 pathbuf, pathbuf + PATH_MAX - 1,
591 pattern, pattern_last, pglob));
595 * The functions glob2 and glob3 are mutually recursive; there is one level
596 * of recursion for each segment in the pattern that contains one or more
600 glob2(pathbuf, pathbuf_last, pathend, pathend_last, pattern, pattern_last, pglob)
601 Char *pathbuf, *pathbuf_last;
602 Char *pathend, *pathend_last;
603 Char *pattern, *pattern_last;
611 * Loop over pattern segments until end of pattern or until
612 * segment with meta character found.
614 for (anymeta = 0;;) {
615 if (*pattern == EOS) { /* End of pattern? */
617 if (g_lstat(pathbuf, &sb, pglob))
620 if (((pglob->gl_flags & GLOB_MARK) &&
621 pathend[-1] != SEP) && (S_ISDIR(sb.st_mode) ||
622 (S_ISLNK(sb.st_mode) &&
623 (g_stat(pathbuf, &sb, pglob) == 0) &&
624 S_ISDIR(sb.st_mode)))) {
625 if (pathend+1 > pathend_last)
631 return(globextend(pathbuf, pglob));
634 /* Find end of next segment, copy tentatively to pathend. */
637 while (*p != EOS && *p != SEP) {
640 if (q+1 > pathend_last)
645 if (!anymeta) { /* No expansion, do next segment. */
648 while (*pattern == SEP) {
649 if (pathend+1 > pathend_last)
651 *pathend++ = *pattern++;
654 /* Need expansion, recurse. */
655 return(glob3(pathbuf, pathbuf_last, pathend,
656 pathend_last, pattern, pattern_last,
657 p, pattern_last, pglob));
663 glob3(pathbuf, pathbuf_last, pathend, pathend_last, pattern, pattern_last,
664 restpattern, restpattern_last, pglob)
665 Char *pathbuf, *pathbuf_last, *pathend, *pathend_last;
666 Char *pattern, *pattern_last, *restpattern, *restpattern_last;
674 if (pathend > pathend_last)
679 if ((dirp = g_opendir(pathbuf, pglob)) == NULL) {
680 /* TODO: don't call for ENOENT or ENOTDIR? */
681 if (pglob->gl_errfunc) {
682 if (g_Ctoc(pathbuf, buf, sizeof(buf)))
683 return(GLOB_ABORTED);
684 if (pglob->gl_errfunc(buf, errno) ||
685 pglob->gl_flags & GLOB_ERR)
686 return(GLOB_ABORTED);
693 /* Search directory for matching names. */
694 while ((dp = readdir(dirp))) {
698 /* Initial DOT must be matched literally. */
699 if (dp->d_name[0] == DOT && *pattern != DOT)
702 sc = (unsigned char *) dp->d_name;
703 while (dc < pathend_last && (*dc++ = *sc++) != EOS)
705 if (dc >= pathend_last) {
711 if (!match(pathend, pattern, restpattern)) {
715 err = glob2(pathbuf, pathbuf_last, --dc, pathend_last,
716 restpattern, restpattern_last, pglob);
726 * Extend the gl_pathv member of a glob_t structure to accommodate a new item,
727 * add the new item, and update gl_pathc.
729 * This assumes the BSD realloc, which only copies the block when its size
730 * crosses a power-of-two boundary; for v7 realloc, this would cause quadratic
733 * Return 0 if new item added, error code if memory couldn't be allocated.
735 * Invariant of the glob_t structure:
736 * Either gl_pathc is zero and gl_pathv is NULL; or gl_pathc > 0 and
737 * gl_pathv points to (gl_offs + gl_pathc + 1) items.
740 globextend(path, pglob)
746 unsigned int newsize, len;
750 newsize = sizeof(*pathv) * (2 + pglob->gl_pathc + pglob->gl_offs);
751 pathv = pglob->gl_pathv ?
752 (char **)realloc((char *)pglob->gl_pathv, newsize) :
753 (char **)malloc(newsize);
755 if (pglob->gl_pathv) {
756 free(pglob->gl_pathv);
757 pglob->gl_pathv = NULL;
759 return(GLOB_NOSPACE);
762 if (pglob->gl_pathv == NULL && pglob->gl_offs > 0) {
763 /* first time around -- clear initial gl_offs items */
764 pathv += pglob->gl_offs;
765 for (i = pglob->gl_offs; --i >= 0; )
768 pglob->gl_pathv = pathv;
770 for (p = path; *p++;)
772 len = (size_t)(p - path);
773 if ((copy = malloc(len)) != NULL) {
774 if (g_Ctoc(path, copy, len)) {
776 return(GLOB_NOSPACE);
778 pathv[pglob->gl_offs + pglob->gl_pathc++] = copy;
780 pathv[pglob->gl_offs + pglob->gl_pathc] = NULL;
782 return(copy == NULL ? GLOB_NOSPACE : 0);
786 * pattern matching function for filenames. Each occurrence of the *
787 * pattern causes a recursion level.
790 match(name, pat, patend)
791 Char *name, *pat, *patend;
793 int ok, negate_range;
796 while (pat < patend) {
798 switch (c & M_MASK) {
803 if (match(name, pat, patend))
805 } while (*name++ != EOS);
813 if ((k = *name++) == EOS)
815 if ((negate_range = ((*pat & M_MASK) == M_NOT)) != EOS)
817 while (((c = *pat++) & M_MASK) != M_END)
818 if ((c & M_MASK) == M_CLASS) {
819 int idx = *pat & M_MASK;
820 if (idx < NCCLASSES &&
821 cclasses[idx].isctype(k))
825 if ((*pat & M_MASK) == M_RNG) {
826 if (c <= k && k <= pat[1])
831 if (ok == negate_range)
840 return(*name == EOS);
843 /* Free allocated data belonging to a glob_t structure. */
851 if (pglob->gl_pathv != NULL) {
852 pp = pglob->gl_pathv + pglob->gl_offs;
853 for (i = pglob->gl_pathc; i--; ++pp)
856 free(pglob->gl_pathv);
857 pglob->gl_pathv = NULL;
862 g_opendir(str, pglob)
872 if (g_Ctoc(str, buf, sizeof(buf)))
875 return(opendir(buf));
879 g_lstat(fn, sb, pglob)
886 if (g_Ctoc(fn, buf, sizeof(buf)))
888 return(lstat(buf, sb));
892 g_stat(fn, sb, pglob)
899 if (g_Ctoc(fn, buf, sizeof(buf)))
901 return(stat(buf, sb));
911 return ((Char *)str);
917 g_Ctoc(str, buf, len)
924 if ((*buf++ = *str++) == EOS)
938 (void)printf("%s:\n", str);
940 (void)printf("%c", CHAR(*p));
943 (void)printf("%c", *p & M_PROTECT ? '"' : ' ');
946 (void)printf("%c", ismeta(*p) ? '_' : ' ');