*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char rcsid[] = "$OpenBSD: glob.c,v 1.4 1996/10/27 17:46:40 deraadt Exp $";
+#if 0
+static char sccsid[] = "@(#)glob.c 8.3 (Berkeley) 10/13/93";
+#else
+static char rcsid[] = "$OpenBSD: glob.c,v 1.5 1997/04/12 19:05:48 millert Exp $";
+#endif
#endif /* LIBC_SCCS and not lint */
/*
* GLOB_TILDE:
* expand ~user/foo to the /home/dir/of/user/foo
* GLOB_BRACE:
- * expand {1,2}{a,b} to 1a 1b 2a 2b
+ * expand {1,2}{a,b} to 1a 1b 2a 2b
* gl_matchc:
* Number of matches in the current invocation of glob.
*/
static int glob2 __P((Char *, Char *, Char *, glob_t *));
static int glob3 __P((Char *, Char *, Char *, Char *, glob_t *));
static int globextend __P((const Char *, glob_t *));
-static const Char * globtilde __P((const Char *, Char *, glob_t *));
+static const Char * globtilde __P((const Char *, Char *, size_t, glob_t *));
static int globexp1 __P((const Char *, glob_t *));
static int globexp2 __P((const Char *, const Char *, glob_t *, int *));
static int match __P((Char *, Char *, Char *));
bufend = bufnext + MAXPATHLEN;
if (flags & GLOB_QUOTE) {
/* Protect the quoted characters. */
- while (bufnext < bufend && (c = *patnext++) != EOS)
+ while (bufnext < bufend && (c = *patnext++) != EOS)
if (c == QUOTE) {
if ((c = *patnext++) == EOS) {
c = QUOTE;
else
*bufnext++ = c;
}
- else
- while (bufnext < bufend && (c = *patnext++) != EOS)
+ else
+ while (bufnext < bufend && (c = *patnext++) != EOS)
*bufnext++ = c;
*bufnext = EOS;
for (pm = pe++; *pe != RBRACKET && *pe != EOS; pe++)
continue;
if (*pe == EOS) {
- /*
+ /*
* We could not find a matching RBRACKET.
* Ignore and just look for RBRACE
*/
for (pl = pm++; *pm != RBRACKET && *pm != EOS; pm++)
continue;
if (*pm == EOS) {
- /*
+ /*
* We could not find a matching RBRACKET.
* Ignore and just look for RBRACE
*/
/* Append the current string */
for (lm = ls; (pl < pm); *lm++ = *pl++)
continue;
- /*
+ /*
* Append the rest of the pattern after the
* closing brace
*/
* expand tilde from the passwd file.
*/
static const Char *
-globtilde(pattern, patbuf, pglob)
+globtilde(pattern, patbuf, patbuf_len, pglob)
const Char *pattern;
Char *patbuf;
+ size_t patbuf_len;
glob_t *pglob;
{
struct passwd *pwd;
char *h;
const Char *p;
- Char *b;
+ Char *b, *eb;
if (*pattern != TILDE || !(pglob->gl_flags & GLOB_TILDE))
return pattern;
/* Copy up to the end of the string or / */
- for (p = pattern + 1, h = (char *) patbuf; *p && *p != SLASH;
- *h++ = *p++)
+ eb = &patbuf[patbuf_len - 1];
+ for (p = pattern + 1, h = (char *) patbuf;
+ h < (char *)eb && *p && *p != SLASH; *h++ = *p++)
continue;
*h = EOS;
if (((char *) patbuf)[0] == EOS) {
- /*
- * handle a plain ~ or ~/ by expanding $HOME
+ /*
+ * handle a plain ~ or ~/ by expanding $HOME
* first and then trying the password file
*/
if (issetugid() != 0 || (h = getenv("HOME")) == NULL) {
return pattern;
else
h = pwd->pw_dir;
- } else {
- if (strlen(h) >= MAXPATHLEN-1)
- return pattern;
}
}
else {
}
/* Copy the home directory */
- for (b = patbuf; *h; *b++ = *h++)
+ for (b = patbuf; b < eb && *h; *b++ = *h++)
continue;
-
+
/* Append the rest of the pattern */
- while ((*b++ = *p++) != EOS)
+ while (b < eb && (*b++ = *p++) != EOS)
continue;
+ *b = EOS;
return patbuf;
}
-
+
/*
* The main glob() routine: compiles the pattern (optionally processing
int c, err, oldpathc;
Char *bufnext, patbuf[MAXPATHLEN+1];
- qpatnext = globtilde(pattern, patbuf, pglob);
+ qpatnext = globtilde(pattern, patbuf, sizeof(patbuf) / sizeof(Char),
+ pglob);
oldpathc = pglob->gl_pathc;
bufnext = patbuf;
break;
case STAR:
pglob->gl_flags |= GLOB_MAGCHAR;
- /* collapse adjacent stars to one,
+ /* collapse adjacent stars to one,
* to avoid exponential behavior
*/
if (bufnext == patbuf || bufnext[-1] != M_ALL)
return(err);
/*
- * If there was no match we are going to append the pattern
+ * If there was no match we are going to append the pattern
* if GLOB_NOCHECK was specified or if GLOB_NOMAGIC was specified
* and the pattern did not contain any magic characters
* GLOB_NOMAGIC is there just for compatibility with csh.
*/
- if (pglob->gl_pathc == oldpathc &&
- ((pglob->gl_flags & GLOB_NOCHECK) ||
+ if (pglob->gl_pathc == oldpathc &&
+ ((pglob->gl_flags & GLOB_NOCHECK) ||
((pglob->gl_flags & GLOB_NOMAGIC) &&
!(pglob->gl_flags & GLOB_MAGCHAR))))
return(globextend(pattern, pglob));
- else if (!(pglob->gl_flags & GLOB_NOSORT))
+ else if (!(pglob->gl_flags & GLOB_NOSORT))
qsort(pglob->gl_pathv + pglob->gl_offs + oldpathc,
pglob->gl_pathc - oldpathc, sizeof(char *), compare);
return(0);
*pathend = EOS;
if (g_lstat(pathbuf, &sb, pglob))
return(0);
-
+
if (((pglob->gl_flags & GLOB_MARK) &&
pathend[-1] != SEP) && (S_ISDIR(sb.st_mode)
|| (S_ISLNK(sb.st_mode) &&
*pathend = EOS;
errno = 0;
-
+
if ((dirp = g_opendir(pathbuf, pglob)) == NULL) {
/* TODO: don't call for ENOENT or ENOTDIR? */
if (pglob->gl_errfunc) {
/* Initial DOT must be matched literally. */
if (dp->d_name[0] == DOT && *pattern != DOT)
continue;
- for (sc = (u_char *) dp->d_name, dc = pathend;
+ for (sc = (u_char *) dp->d_name, dc = pathend;
(*dc++ = *sc++) != EOS;)
continue;
if (!match(pathend, pattern, restpattern)) {
const Char *p;
newsize = sizeof(*pathv) * (2 + pglob->gl_pathc + pglob->gl_offs);
- pathv = pglob->gl_pathv ?
+ pathv = pglob->gl_pathv ?
realloc((char *)pglob->gl_pathv, newsize) :
malloc(newsize);
if (pathv == NULL)
return(copy == NULL ? GLOB_NOSPACE : 0);
}
-
/*
* pattern matching function for filenames. Each occurrence of the *
* pattern causes a recursion level.
case M_ALL:
if (pat == patend)
return(1);
- do
+ do
if (match(name, pat, patend))
return(1);
while (*name++ != EOS);
}
#ifdef DEBUG
-static void
+static void
qprintf(str, s)
const char *str;
register Char *s;