2 * Copyright (c) 2008-2010 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 */
72 #endif /* HAVE_STRING_H */
75 #endif /* HAVE_STRINGS_H */
78 #endif /* HAVE_UNISTD_H */
83 # define dirent direct
84 # ifdef HAVE_SYS_NDIR_H
85 # include <sys/ndir.h>
87 # ifdef HAVE_SYS_DIR_H
99 #include "emul/glob.h"
100 #include "emul/charclass.h"
114 #define UNDERSCORE '_'
122 #define M_QUOTE 0x8000
123 #define M_PROTECT 0x4000
124 #define M_MASK 0xffff
125 #define M_ASCII 0x00ff
127 typedef unsigned short Char;
132 #define M_PROTECT 0x40
141 #define CHAR(c) ((Char)((c)&M_ASCII))
142 #define META(c) ((Char)((c)|M_QUOTE))
143 #define M_ALL META('*')
144 #define M_END META(']')
145 #define M_NOT META('!')
146 #define M_ONE META('?')
147 #define M_RNG META('-')
148 #define M_SET META('[')
149 #define M_CLASS META(':')
150 #define ismeta(c) (((c)&M_QUOTE) != 0)
153 static int compare __P((const void *, const void *));
154 static int g_Ctoc __P((const Char *, char *, unsigned int));
155 static int g_lstat __P((Char *, struct stat *, glob_t *));
156 static DIR *g_opendir __P((Char *, glob_t *));
157 static Char *g_strchr __P((const Char *, int));
158 static int g_strncmp __P((const Char *, const char *, size_t));
159 static int g_stat __P((Char *, struct stat *, glob_t *));
160 static int glob0 __P((const Char *, glob_t *));
161 static int glob1 __P((Char *, Char *, glob_t *));
162 static int glob2 __P((Char *, Char *, Char *, Char *, Char *, Char *,
164 static int glob3 __P((Char *, Char *, Char *, Char *, Char *, Char *,
165 Char *, Char *, glob_t *));
166 static int globextend __P((const Char *, glob_t *));
168 globtilde __P((const Char *, Char *, size_t, glob_t *));
169 static int globexp1 __P((const Char *, glob_t *));
170 static int globexp2 __P((const Char *, const Char *, glob_t *, int *));
171 static int match __P((Char *, Char *, Char *));
173 static void qprintf __P((const char *, Char *));
176 extern struct passwd *sudo_getpwnam __P((const char *));
177 extern struct passwd *sudo_getpwuid __P((uid_t));
180 glob(pattern, flags, errfunc, pglob)
182 int flags, (*errfunc) __P((const char *, int));
185 const unsigned char *patnext;
187 Char *bufnext, *bufend, patbuf[PATH_MAX];
189 patnext = (unsigned char *) pattern;
190 if (!(flags & GLOB_APPEND)) {
192 pglob->gl_pathv = NULL;
193 if (!(flags & GLOB_DOOFFS))
196 pglob->gl_flags = flags & ~GLOB_MAGCHAR;
197 pglob->gl_errfunc = errfunc;
198 pglob->gl_matchc = 0;
201 bufend = bufnext + PATH_MAX - 1;
202 if (flags & GLOB_NOESCAPE)
203 while (bufnext < bufend && (c = *patnext++) != EOS)
206 /* Protect the quoted characters. */
207 while (bufnext < bufend && (c = *patnext++) != EOS)
209 if ((c = *patnext++) == EOS) {
213 *bufnext++ = c | M_PROTECT;
219 if (flags & GLOB_BRACE)
220 return globexp1(patbuf, pglob);
222 return glob0(patbuf, pglob);
226 * Expand recursively a glob {} pattern. When there is no more expansion
227 * invoke the standard globbing routine to glob the rest of the magic
231 globexp1(pattern, pglob)
235 const Char* ptr = pattern;
238 /* Protect a single {}, for find(1), like csh */
239 if (pattern[0] == LBRACE && pattern[1] == RBRACE && pattern[2] == EOS)
240 return glob0(pattern, pglob);
242 while ((ptr = (const Char *) g_strchr(ptr, LBRACE)) != NULL)
243 if (!globexp2(ptr, pattern, pglob, &rv))
246 return glob0(pattern, pglob);
251 * Recursive brace globbing helper. Tries to expand a single brace.
252 * If it succeeds then it invokes globexp1 with the new pattern.
253 * If it fails then it tries to glob the rest of the pattern and returns.
256 globexp2(ptr, pattern, pglob, rv)
257 const Char *ptr, *pattern;
263 const Char *pe, *pm, *pl;
264 Char patbuf[PATH_MAX];
266 /* copy part up to the brace */
267 for (lm = patbuf, pm = pattern; pm != ptr; *lm++ = *pm++)
272 /* Find the balanced brace */
273 for (i = 0, pe = ++ptr; *pe; pe++)
274 if (*pe == LBRACKET) {
275 /* Ignore everything between [] */
276 for (pm = pe++; *pe != RBRACKET && *pe != EOS; pe++)
280 * We could not find a matching RBRACKET.
281 * Ignore and just look for RBRACE
285 } else if (*pe == LBRACE)
287 else if (*pe == RBRACE) {
293 /* Non matching braces; just glob the pattern */
294 if (i != 0 || *pe == EOS) {
295 *rv = glob0(patbuf, pglob);
299 for (i = 0, pl = pm = ptr; pm <= pe; pm++) {
302 /* Ignore everything between [] */
303 for (pl = pm++; *pm != RBRACKET && *pm != EOS; pm++)
307 * We could not find a matching RBRACKET.
308 * Ignore and just look for RBRACE
325 if (i && *pm == COMMA)
328 /* Append the current string */
329 for (lm = ls; (pl < pm); *lm++ = *pl++)
333 * Append the rest of the pattern after the
336 for (pl = pe + 1; (*lm++ = *pl++) != EOS; )
339 /* Expand the current pattern */
341 qprintf("globexp2:", patbuf);
343 *rv = globexp1(patbuf, pglob);
345 /* move after the comma, to the next string */
361 * expand tilde from the passwd file.
364 globtilde(pattern, patbuf, patbuf_len, pglob)
375 if (*pattern != TILDE || !(pglob->gl_flags & GLOB_TILDE))
378 /* Copy up to the end of the string or / */
379 eb = &patbuf[patbuf_len - 1];
380 for (p = pattern + 1, h = (char *) patbuf;
381 h < (char *)eb && *p && *p != SLASH; *h++ = *p++)
386 if (((char *) patbuf)[0] == EOS) {
388 * handle a plain ~ or ~/ by expanding $HOME
389 * first and then trying the password file
391 if ((h = getenv("HOME")) == NULL) {
392 if ((pwd = sudo_getpwuid(getuid())) == NULL)
401 if ((pwd = sudo_getpwnam((char*) patbuf)) == NULL)
407 /* Copy the home directory */
408 for (b = patbuf; b < eb && *h; *b++ = *h++)
411 /* Append the rest of the pattern */
412 while (b < eb && (*b++ = *p++) != EOS)
428 rv = *(Char *)s1 - *(const unsigned char *)s2++;
438 g_charclass(patternp, bufnextp)
439 const Char **patternp;
442 const Char *pattern = *patternp + 1;
443 Char *bufnext = *bufnextp;
448 if ((colon = g_strchr(pattern, ':')) == NULL || colon[1] != ']')
449 return 1; /* not a character class */
451 len = (size_t)(colon - pattern);
452 for (cc = cclasses; cc->name != NULL; cc++) {
453 if (!g_strncmp(pattern, cc->name, len) && cc->name[len] == '\0')
456 if (cc->name == NULL)
457 return -1; /* invalid character class */
458 *bufnext++ = M_CLASS;
459 *bufnext++ = (Char)(cc - &cclasses[0]);
461 *patternp += len + 3;
467 * The main glob() routine: compiles the pattern (optionally processing
468 * quotes), calls glob1() to do the real pattern matching, and finally
469 * sorts the list (unless unsorted operation is requested). Returns 0
470 * if things went well, nonzero if errors occurred. It is not an error
471 * to find no matches.
474 glob0(pattern, pglob)
478 const Char *qpatnext;
479 int c, err, oldpathc;
480 Char *bufnext, patbuf[PATH_MAX];
482 qpatnext = globtilde(pattern, patbuf, PATH_MAX, pglob);
483 oldpathc = pglob->gl_pathc;
486 /* We don't need to check for buffer overflow any more. */
487 while ((c = *qpatnext++) != EOS) {
493 if (*qpatnext == EOS ||
494 g_strchr(qpatnext+1, RBRACKET) == NULL) {
495 *bufnext++ = LBRACKET;
505 if (c == LBRACKET && *qpatnext == ':') {
507 err = g_charclass(&qpatnext,
512 } while (c == LBRACKET && *qpatnext == ':');
514 !(pglob->gl_flags & GLOB_NOCHECK))
519 *bufnext++ = CHAR(c);
520 if (*qpatnext == RANGE &&
521 (c = qpatnext[1]) != RBRACKET) {
523 *bufnext++ = CHAR(c);
526 } while ((c = *qpatnext++) != RBRACKET);
527 pglob->gl_flags |= GLOB_MAGCHAR;
531 pglob->gl_flags |= GLOB_MAGCHAR;
535 pglob->gl_flags |= GLOB_MAGCHAR;
536 /* collapse adjacent stars to one,
537 * to avoid exponential behavior
539 if (bufnext == patbuf || bufnext[-1] != M_ALL)
543 *bufnext++ = CHAR(c);
549 qprintf("glob0:", patbuf);
552 if ((err = glob1(patbuf, patbuf + PATH_MAX - 1, pglob)) != 0)
556 * If there was no match we are going to append the pattern
557 * if GLOB_NOCHECK was specified.
559 if (pglob->gl_pathc == oldpathc) {
560 if (pglob->gl_flags & GLOB_NOCHECK)
561 return(globextend(pattern, pglob));
563 return(GLOB_NOMATCH);
565 if (!(pglob->gl_flags & GLOB_NOSORT))
566 qsort(pglob->gl_pathv + pglob->gl_offs + oldpathc,
567 pglob->gl_pathc - oldpathc, sizeof(char *), compare);
575 return(strcmp(*(char **)p, *(char **)q));
579 glob1(pattern, pattern_last, pglob)
580 Char *pattern, *pattern_last;
583 Char pathbuf[PATH_MAX];
585 /* A null pathname is invalid -- POSIX 1003.1 sect. 2.4. */
588 return(glob2(pathbuf, pathbuf + PATH_MAX - 1,
589 pathbuf, pathbuf + PATH_MAX - 1,
590 pattern, pattern_last, pglob));
594 * The functions glob2 and glob3 are mutually recursive; there is one level
595 * of recursion for each segment in the pattern that contains one or more
599 glob2(pathbuf, pathbuf_last, pathend, pathend_last, pattern, pattern_last, pglob)
600 Char *pathbuf, *pathbuf_last;
601 Char *pathend, *pathend_last;
602 Char *pattern, *pattern_last;
610 * Loop over pattern segments until end of pattern or until
611 * segment with meta character found.
613 for (anymeta = 0;;) {
614 if (*pattern == EOS) { /* End of pattern? */
616 if (g_lstat(pathbuf, &sb, pglob))
619 if (((pglob->gl_flags & GLOB_MARK) &&
620 pathend[-1] != SEP) && (S_ISDIR(sb.st_mode) ||
621 (S_ISLNK(sb.st_mode) &&
622 (g_stat(pathbuf, &sb, pglob) == 0) &&
623 S_ISDIR(sb.st_mode)))) {
624 if (pathend+1 > pathend_last)
630 return(globextend(pathbuf, pglob));
633 /* Find end of next segment, copy tentatively to pathend. */
636 while (*p != EOS && *p != SEP) {
639 if (q+1 > pathend_last)
644 if (!anymeta) { /* No expansion, do next segment. */
647 while (*pattern == SEP) {
648 if (pathend+1 > pathend_last)
650 *pathend++ = *pattern++;
653 /* Need expansion, recurse. */
654 return(glob3(pathbuf, pathbuf_last, pathend,
655 pathend_last, pattern, pattern_last,
656 p, pattern_last, pglob));
662 glob3(pathbuf, pathbuf_last, pathend, pathend_last, pattern, pattern_last,
663 restpattern, restpattern_last, pglob)
664 Char *pathbuf, *pathbuf_last, *pathend, *pathend_last;
665 Char *pattern, *pattern_last, *restpattern, *restpattern_last;
673 if (pathend > pathend_last)
678 if ((dirp = g_opendir(pathbuf, pglob)) == NULL) {
679 /* TODO: don't call for ENOENT or ENOTDIR? */
680 if (pglob->gl_errfunc) {
681 if (g_Ctoc(pathbuf, buf, sizeof(buf)))
682 return(GLOB_ABORTED);
683 if (pglob->gl_errfunc(buf, errno) ||
684 pglob->gl_flags & GLOB_ERR)
685 return(GLOB_ABORTED);
692 /* Search directory for matching names. */
693 while ((dp = readdir(dirp))) {
697 /* Initial DOT must be matched literally. */
698 if (dp->d_name[0] == DOT && *pattern != DOT)
701 sc = (unsigned char *) dp->d_name;
702 while (dc < pathend_last && (*dc++ = *sc++) != EOS)
704 if (dc >= pathend_last) {
710 if (!match(pathend, pattern, restpattern)) {
714 err = glob2(pathbuf, pathbuf_last, --dc, pathend_last,
715 restpattern, restpattern_last, pglob);
725 * Extend the gl_pathv member of a glob_t structure to accommodate a new item,
726 * add the new item, and update gl_pathc.
728 * This assumes the BSD realloc, which only copies the block when its size
729 * crosses a power-of-two boundary; for v7 realloc, this would cause quadratic
732 * Return 0 if new item added, error code if memory couldn't be allocated.
734 * Invariant of the glob_t structure:
735 * Either gl_pathc is zero and gl_pathv is NULL; or gl_pathc > 0 and
736 * gl_pathv points to (gl_offs + gl_pathc + 1) items.
739 globextend(path, pglob)
745 unsigned int newsize, len;
749 newsize = sizeof(*pathv) * (2 + pglob->gl_pathc + pglob->gl_offs);
750 pathv = pglob->gl_pathv ?
751 (char **)realloc((char *)pglob->gl_pathv, newsize) :
752 (char **)malloc(newsize);
754 if (pglob->gl_pathv) {
755 free(pglob->gl_pathv);
756 pglob->gl_pathv = NULL;
758 return(GLOB_NOSPACE);
761 if (pglob->gl_pathv == NULL && pglob->gl_offs > 0) {
762 /* first time around -- clear initial gl_offs items */
763 pathv += pglob->gl_offs;
764 for (i = pglob->gl_offs; --i >= 0; )
767 pglob->gl_pathv = pathv;
769 for (p = path; *p++;)
771 len = (size_t)(p - path);
772 if ((copy = malloc(len)) != NULL) {
773 if (g_Ctoc(path, copy, len)) {
775 return(GLOB_NOSPACE);
777 pathv[pglob->gl_offs + pglob->gl_pathc++] = copy;
779 pathv[pglob->gl_offs + pglob->gl_pathc] = NULL;
781 return(copy == NULL ? GLOB_NOSPACE : 0);
785 * pattern matching function for filenames. Each occurrence of the *
786 * pattern causes a recursion level.
789 match(name, pat, patend)
790 Char *name, *pat, *patend;
792 int ok, negate_range;
795 while (pat < patend) {
797 switch (c & M_MASK) {
802 if (match(name, pat, patend))
804 } while (*name++ != EOS);
812 if ((k = *name++) == EOS)
814 if ((negate_range = ((*pat & M_MASK) == M_NOT)) != EOS)
816 while (((c = *pat++) & M_MASK) != M_END) {
817 if ((c & M_MASK) == M_CLASS) {
818 int idx = *pat & M_MASK;
819 if (idx < NCCLASSES &&
820 cclasses[idx].isctype(k))
824 if ((*pat & M_MASK) == M_RNG) {
825 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) ? '_' : ' ');