11305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/*	$OpenBSD: glob.c,v 1.35 2011/01/12 01:53:14 djm Exp $ */
21305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/*
31305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Copyright (c) 1989, 1993
41305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *	The Regents of the University of California.  All rights reserved.
51305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *
61305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * This code is derived from software contributed to Berkeley by
71305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Guido van Rossum.
81305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *
91305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Redistribution and use in source and binary forms, with or without
101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * modification, are permitted provided that the following conditions
111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * are met:
121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 1. Redistributions of source code must retain the above copyright
131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *    notice, this list of conditions and the following disclaimer.
141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 2. Redistributions in binary form must reproduce the above copyright
151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *    notice, this list of conditions and the following disclaimer in the
161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *    documentation and/or other materials provided with the distribution.
171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 3. Neither the name of the University nor the names of its contributors
181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *    may be used to endorse or promote products derived from this software
191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *    without specific prior written permission.
201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *
211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * SUCH DAMAGE.
321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */
331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* OPENBSD ORIGINAL: lib/libc/gen/glob.c */
351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/*
371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * glob(3) -- a superset of the one defined in POSIX 1003.2.
381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *
391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * The [!...] convention to negate a range is supported (SysV, Posix, ksh).
401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *
411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Optional extra services, controlled by flags not defined by POSIX:
421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *
431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * GLOB_QUOTE:
441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *	Escaping convention: \ inhibits any special meaning the following
451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *	character might have (except \ at end of string is retained).
461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * GLOB_MAGCHAR:
471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *	Set in gl_flags if pattern contained a globbing character.
481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * GLOB_NOMAGIC:
491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *	Same as GLOB_NOCHECK, but it will only append pattern if it did
501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *	not contain any magic characters.  [Used in csh style globbing]
511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * GLOB_ALTDIRFUNC:
521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *	Use alternately specified directory access functions.
531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * GLOB_TILDE:
541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *	expand ~user/foo to the /home/dir/of/user/foo
551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * GLOB_BRACE:
561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *	expand {1,2}{a,b} to 1a 1b 2a 2b
571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * gl_matchc:
581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *	Number of matches in the current invocation of glob.
591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */
601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "includes.h"
621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <sys/types.h>
641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <sys/stat.h>
651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <dirent.h>
671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <ctype.h>
681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <errno.h>
691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <pwd.h>
701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <stdlib.h>
711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <string.h>
721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <unistd.h>
731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#if !defined(HAVE_GLOB) || !defined(GLOB_HAS_ALTDIRFUNC) || \
751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood    !defined(GLOB_HAS_GL_MATCHC) || !defined(GLOB_HAS_GL_STATV) || \
761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood    !defined(HAVE_DECL_GLOB_NOMATCH) || HAVE_DECL_GLOB_NOMATCH == 0 || \
771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood    defined(BROKEN_GLOB)
781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "charclass.h"
801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define	DOLLAR		'$'
821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define	DOT		'.'
831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define	EOS		'\0'
841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define	LBRACKET	'['
851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define	NOT		'!'
861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define	QUESTION	'?'
871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define	QUOTE		'\\'
881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define	RANGE		'-'
891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define	RBRACKET	']'
901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define	SEP		'/'
911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define	STAR		'*'
921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define	TILDE		'~'
931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define	UNDERSCORE	'_'
941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define	LBRACE		'{'
951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define	RBRACE		'}'
961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define	SLASH		'/'
971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define	COMMA		','
981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifndef DEBUG
1001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define	M_QUOTE		0x8000
1021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define	M_PROTECT	0x4000
1031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define	M_MASK		0xffff
1041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define	M_ASCII		0x00ff
1051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodtypedef u_short Char;
1071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#else
1091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define	M_QUOTE		0x80
1111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define	M_PROTECT	0x40
1121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define	M_MASK		0xff
1131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define	M_ASCII		0x7f
1141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodtypedef char Char;
1161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif
1181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define	CHAR(c)		((Char)((c)&M_ASCII))
1211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define	META(c)		((Char)((c)|M_QUOTE))
1221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define	M_ALL		META('*')
1231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define	M_END		META(']')
1241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define	M_NOT		META('!')
1251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define	M_ONE		META('?')
1261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define	M_RNG		META('-')
1271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define	M_SET		META('[')
1281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define	M_CLASS		META(':')
1291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define	ismeta(c)	(((c)&M_QUOTE) != 0)
1301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define	GLOB_LIMIT_MALLOC	65536
1321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define	GLOB_LIMIT_STAT		128
1331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define	GLOB_LIMIT_READDIR	16384
1341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstruct glob_lim {
1361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	size_t	glim_malloc;
1371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	size_t	glim_stat;
1381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	size_t	glim_readdir;
1391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood};
1401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int	 compare(const void *, const void *);
1421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int	 g_Ctoc(const Char *, char *, u_int);
1431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int	 g_lstat(Char *, struct stat *, glob_t *);
1441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic DIR	*g_opendir(Char *, glob_t *);
1451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic Char	*g_strchr(const Char *, int);
1461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int	 g_strncmp(const Char *, const char *, size_t);
1471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int	 g_stat(Char *, struct stat *, glob_t *);
1481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int	 glob0(const Char *, glob_t *, struct glob_lim *);
1491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int	 glob1(Char *, Char *, glob_t *, struct glob_lim *);
1501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int	 glob2(Char *, Char *, Char *, Char *, Char *, Char *,
1511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    glob_t *, struct glob_lim *);
1521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int	 glob3(Char *, Char *, Char *, Char *, Char *,
1531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    Char *, Char *, glob_t *, struct glob_lim *);
1541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int	 globextend(const Char *, glob_t *, struct glob_lim *,
1551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    struct stat *);
1561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic const Char *
1571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		 globtilde(const Char *, Char *, size_t, glob_t *);
1581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int	 globexp1(const Char *, glob_t *, struct glob_lim *);
1591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int	 globexp2(const Char *, const Char *, glob_t *,
1601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    struct glob_lim *);
1611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int	 match(Char *, Char *, Char *);
1621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef DEBUG
1631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void	 qprintf(const char *, Char *);
1641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif
1651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint
1671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodglob(const char *pattern, int flags, int (*errfunc)(const char *, int),
1681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood    glob_t *pglob)
1691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
1701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	const u_char *patnext;
1711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	int c;
1721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	Char *bufnext, *bufend, patbuf[MAXPATHLEN];
1731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	struct glob_lim limit = { 0, 0, 0 };
1741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	patnext = (u_char *) pattern;
1761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (!(flags & GLOB_APPEND)) {
1771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		pglob->gl_pathc = 0;
1781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		pglob->gl_pathv = NULL;
1791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		pglob->gl_statv = NULL;
1801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (!(flags & GLOB_DOOFFS))
1811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			pglob->gl_offs = 0;
1821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
1831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	pglob->gl_flags = flags & ~GLOB_MAGCHAR;
1841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	pglob->gl_errfunc = errfunc;
1851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	pglob->gl_matchc = 0;
1861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (pglob->gl_offs < 0 || pglob->gl_pathc < 0 ||
1881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    pglob->gl_offs >= INT_MAX || pglob->gl_pathc >= INT_MAX ||
1891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    pglob->gl_pathc >= INT_MAX - pglob->gl_offs - 1)
1901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		return GLOB_NOSPACE;
1911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	bufnext = patbuf;
1931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	bufend = bufnext + MAXPATHLEN - 1;
1941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (flags & GLOB_NOESCAPE)
1951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		while (bufnext < bufend && (c = *patnext++) != EOS)
1961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			*bufnext++ = c;
1971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	else {
1981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		/* Protect the quoted characters. */
1991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		while (bufnext < bufend && (c = *patnext++) != EOS)
2001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if (c == QUOTE) {
2011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				if ((c = *patnext++) == EOS) {
2021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood					c = QUOTE;
2031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood					--patnext;
2041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				}
2051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				*bufnext++ = c | M_PROTECT;
2061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			} else
2071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				*bufnext++ = c;
2081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
2091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	*bufnext = EOS;
2101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
2111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (flags & GLOB_BRACE)
2121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		return globexp1(patbuf, pglob, &limit);
2131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	else
2141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		return glob0(patbuf, pglob, &limit);
2151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
2161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
2171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/*
2181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Expand recursively a glob {} pattern. When there is no more expansion
2191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * invoke the standard globbing routine to glob the rest of the magic
2201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * characters
2211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */
2221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int
2231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodglobexp1(const Char *pattern, glob_t *pglob, struct glob_lim *limitp)
2241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
2251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	const Char* ptr = pattern;
2261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
2271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Protect a single {}, for find(1), like csh */
2281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (pattern[0] == LBRACE && pattern[1] == RBRACE && pattern[2] == EOS)
2291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		return glob0(pattern, pglob, limitp);
2301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
2311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if ((ptr = (const Char *) g_strchr(ptr, LBRACE)) != NULL)
2321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		return globexp2(ptr, pattern, pglob, limitp);
2331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
2341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	return glob0(pattern, pglob, limitp);
2351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
2361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
2371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
2381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/*
2391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Recursive brace globbing helper. Tries to expand a single brace.
2401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * If it succeeds then it invokes globexp1 with the new pattern.
2411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * If it fails then it tries to glob the rest of the pattern and returns.
2421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */
2431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int
2441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodglobexp2(const Char *ptr, const Char *pattern, glob_t *pglob,
2451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood    struct glob_lim *limitp)
2461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
2471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	int     i, rv;
2481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	Char   *lm, *ls;
2491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	const Char *pe, *pm, *pl;
2501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	Char    patbuf[MAXPATHLEN];
2511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
2521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* copy part up to the brace */
2531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	for (lm = patbuf, pm = pattern; pm != ptr; *lm++ = *pm++)
2541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		;
2551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	*lm = EOS;
2561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	ls = lm;
2571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
2581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Find the balanced brace */
2591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	for (i = 0, pe = ++ptr; *pe; pe++)
2601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (*pe == LBRACKET) {
2611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			/* Ignore everything between [] */
2621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			for (pm = pe++; *pe != RBRACKET && *pe != EOS; pe++)
2631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				;
2641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if (*pe == EOS) {
2651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				/*
2661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				 * We could not find a matching RBRACKET.
2671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				 * Ignore and just look for RBRACE
2681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				 */
2691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				pe = pm;
2701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			}
2711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		} else if (*pe == LBRACE)
2721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			i++;
2731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		else if (*pe == RBRACE) {
2741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if (i == 0)
2751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				break;
2761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			i--;
2771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		}
2781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
2791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Non matching braces; just glob the pattern */
2801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (i != 0 || *pe == EOS)
2811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		return glob0(patbuf, pglob, limitp);
2821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
2831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	for (i = 0, pl = pm = ptr; pm <= pe; pm++) {
2841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		switch (*pm) {
2851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		case LBRACKET:
2861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			/* Ignore everything between [] */
2871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			for (pl = pm++; *pm != RBRACKET && *pm != EOS; pm++)
2881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				;
2891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if (*pm == EOS) {
2901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				/*
2911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				 * We could not find a matching RBRACKET.
2921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				 * Ignore and just look for RBRACE
2931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				 */
2941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				pm = pl;
2951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			}
2961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			break;
2971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
2981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		case LBRACE:
2991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			i++;
3001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			break;
3011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
3021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		case RBRACE:
3031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if (i) {
3041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				i--;
3051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				break;
3061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			}
3071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			/* FALLTHROUGH */
3081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		case COMMA:
3091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if (i && *pm == COMMA)
3101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				break;
3111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			else {
3121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				/* Append the current string */
3131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				for (lm = ls; (pl < pm); *lm++ = *pl++)
3141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood					;
3151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
3161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				/*
3171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				 * Append the rest of the pattern after the
3181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				 * closing brace
3191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				 */
3201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				for (pl = pe + 1; (*lm++ = *pl++) != EOS; )
3211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood					;
3221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
3231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				/* Expand the current pattern */
3241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef DEBUG
3251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				qprintf("globexp2:", patbuf);
3261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif
3271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				rv = globexp1(patbuf, pglob, limitp);
3281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				if (rv && rv != GLOB_NOMATCH)
3291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood					return rv;
3301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
3311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				/* move after the comma, to the next string */
3321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				pl = pm + 1;
3331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			}
3341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			break;
3351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
3361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		default:
3371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			break;
3381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		}
3391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
3401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	return 0;
3411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
3421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
3431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
3441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
3451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/*
3461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * expand tilde from the passwd file.
3471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */
3481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic const Char *
3491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodglobtilde(const Char *pattern, Char *patbuf, size_t patbuf_len, glob_t *pglob)
3501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
3511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	struct passwd *pwd;
3521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	char *h;
3531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	const Char *p;
3541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	Char *b, *eb;
3551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
3561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (*pattern != TILDE || !(pglob->gl_flags & GLOB_TILDE))
3571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		return pattern;
3581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
3591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Copy up to the end of the string or / */
3601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	eb = &patbuf[patbuf_len - 1];
3611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	for (p = pattern + 1, h = (char *) patbuf;
3621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    h < (char *)eb && *p && *p != SLASH; *h++ = *p++)
3631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		;
3641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
3651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	*h = EOS;
3661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
3671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#if 0
3681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (h == (char *)eb)
3691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		return what;
3701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif
3711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
3721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (((char *) patbuf)[0] == EOS) {
3731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		/*
3741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		 * handle a plain ~ or ~/ by expanding $HOME
3751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		 * first and then trying the password file
3761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		 */
3771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#if 0
3781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (issetugid() != 0 || (h = getenv("HOME")) == NULL) {
3791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif
3801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if ((getuid() != geteuid()) || (h = getenv("HOME")) == NULL) {
3811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if ((pwd = getpwuid(getuid())) == NULL)
3821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				return pattern;
3831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			else
3841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				h = pwd->pw_dir;
3851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		}
3861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	} else {
3871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		/*
3881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		 * Expand a ~user
3891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		 */
3901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if ((pwd = getpwnam((char*) patbuf)) == NULL)
3911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			return pattern;
3921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		else
3931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			h = pwd->pw_dir;
3941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
3951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
3961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Copy the home directory */
3971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	for (b = patbuf; b < eb && *h; *b++ = *h++)
3981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		;
3991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
4001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Append the rest of the pattern */
4011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	while (b < eb && (*b++ = *p++) != EOS)
4021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		;
4031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	*b = EOS;
4041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
4051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	return patbuf;
4061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
4071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
4081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int
4091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodg_strncmp(const Char *s1, const char *s2, size_t n)
4101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
4111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	int rv = 0;
4121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
4131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	while (n--) {
4141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		rv = *(Char *)s1 - *(const unsigned char *)s2++;
4151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (rv)
4161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			break;
4171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (*s1++ == '\0')
4181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			break;
4191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
4201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	return rv;
4211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
4221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
4231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int
4241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodg_charclass(const Char **patternp, Char **bufnextp)
4251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
4261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	const Char *pattern = *patternp + 1;
4271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	Char *bufnext = *bufnextp;
4281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	const Char *colon;
4291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	struct cclass *cc;
4301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	size_t len;
4311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
4321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if ((colon = g_strchr(pattern, ':')) == NULL || colon[1] != ']')
4331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		return 1;	/* not a character class */
4341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
4351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	len = (size_t)(colon - pattern);
4361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	for (cc = cclasses; cc->name != NULL; cc++) {
4371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (!g_strncmp(pattern, cc->name, len) && cc->name[len] == '\0')
4381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			break;
4391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
4401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (cc->name == NULL)
4411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		return -1;	/* invalid character class */
4421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	*bufnext++ = M_CLASS;
4431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	*bufnext++ = (Char)(cc - &cclasses[0]);
4441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	*bufnextp = bufnext;
4451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	*patternp += len + 3;
4461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
4471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	return 0;
4481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
4491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
4501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/*
4511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * The main glob() routine: compiles the pattern (optionally processing
4521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * quotes), calls glob1() to do the real pattern matching, and finally
4531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * sorts the list (unless unsorted operation is requested).  Returns 0
4541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * if things went well, nonzero if errors occurred.  It is not an error
4551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * to find no matches.
4561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */
4571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int
4581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodglob0(const Char *pattern, glob_t *pglob, struct glob_lim *limitp)
4591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
4601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	const Char *qpatnext;
4611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	int c, err, oldpathc;
4621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	Char *bufnext, patbuf[MAXPATHLEN];
4631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
4641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	qpatnext = globtilde(pattern, patbuf, MAXPATHLEN, pglob);
4651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	oldpathc = pglob->gl_pathc;
4661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	bufnext = patbuf;
4671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
4681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* We don't need to check for buffer overflow any more. */
4691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	while ((c = *qpatnext++) != EOS) {
4701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		switch (c) {
4711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		case LBRACKET:
4721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			c = *qpatnext;
4731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if (c == NOT)
4741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				++qpatnext;
4751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if (*qpatnext == EOS ||
4761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			    g_strchr(qpatnext+1, RBRACKET) == NULL) {
4771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				*bufnext++ = LBRACKET;
4781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				if (c == NOT)
4791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood					--qpatnext;
4801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				break;
4811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			}
4821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			*bufnext++ = M_SET;
4831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if (c == NOT)
4841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				*bufnext++ = M_NOT;
4851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			c = *qpatnext++;
4861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			do {
4871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				if (c == LBRACKET && *qpatnext == ':') {
4881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood					do {
4891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood						err = g_charclass(&qpatnext,
4901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood						    &bufnext);
4911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood						if (err)
4921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood							break;
4931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood						c = *qpatnext++;
4941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood					} while (c == LBRACKET && *qpatnext == ':');
4951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood					if (err == -1 &&
4961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood					    !(pglob->gl_flags & GLOB_NOCHECK))
4971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood						return GLOB_NOMATCH;
4981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood					if (c == RBRACKET)
4991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood						break;
5001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				}
5011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				*bufnext++ = CHAR(c);
5021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				if (*qpatnext == RANGE &&
5031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				    (c = qpatnext[1]) != RBRACKET) {
5041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood					*bufnext++ = M_RNG;
5051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood					*bufnext++ = CHAR(c);
5061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood					qpatnext += 2;
5071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				}
5081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			} while ((c = *qpatnext++) != RBRACKET);
5091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			pglob->gl_flags |= GLOB_MAGCHAR;
5101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			*bufnext++ = M_END;
5111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			break;
5121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		case QUESTION:
5131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			pglob->gl_flags |= GLOB_MAGCHAR;
5141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			*bufnext++ = M_ONE;
5151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			break;
5161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		case STAR:
5171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			pglob->gl_flags |= GLOB_MAGCHAR;
5181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			/* collapse adjacent stars to one,
5191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			 * to avoid exponential behavior
5201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			 */
5211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if (bufnext == patbuf || bufnext[-1] != M_ALL)
5221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				*bufnext++ = M_ALL;
5231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			break;
5241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		default:
5251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			*bufnext++ = CHAR(c);
5261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			break;
5271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		}
5281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
5291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	*bufnext = EOS;
5301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef DEBUG
5311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	qprintf("glob0:", patbuf);
5321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif
5331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
5341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if ((err = glob1(patbuf, patbuf+MAXPATHLEN-1, pglob, limitp)) != 0)
5351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		return(err);
5361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
5371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/*
5381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * If there was no match we are going to append the pattern
5391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * if GLOB_NOCHECK was specified or if GLOB_NOMAGIC was specified
5401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * and the pattern did not contain any magic characters
5411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * GLOB_NOMAGIC is there just for compatibility with csh.
5421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 */
5431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (pglob->gl_pathc == oldpathc) {
5441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if ((pglob->gl_flags & GLOB_NOCHECK) ||
5451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    ((pglob->gl_flags & GLOB_NOMAGIC) &&
5461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    !(pglob->gl_flags & GLOB_MAGCHAR)))
5471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			return(globextend(pattern, pglob, limitp, NULL));
5481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		else
5491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			return(GLOB_NOMATCH);
5501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
5511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (!(pglob->gl_flags & GLOB_NOSORT))
5521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		qsort(pglob->gl_pathv + pglob->gl_offs + oldpathc,
5531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    pglob->gl_pathc - oldpathc, sizeof(char *), compare);
5541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	return(0);
5551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
5561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
5571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int
5581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodcompare(const void *p, const void *q)
5591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
5601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	return(strcmp(*(char **)p, *(char **)q));
5611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
5621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
5631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int
5641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodglob1(Char *pattern, Char *pattern_last, glob_t *pglob, struct glob_lim *limitp)
5651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
5661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	Char pathbuf[MAXPATHLEN];
5671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
5681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* A null pathname is invalid -- POSIX 1003.1 sect. 2.4. */
5691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (*pattern == EOS)
5701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		return(0);
5711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	return(glob2(pathbuf, pathbuf+MAXPATHLEN-1,
5721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    pathbuf, pathbuf+MAXPATHLEN-1,
5731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    pattern, pattern_last, pglob, limitp));
5741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
5751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
5761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/*
5771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * The functions glob2 and glob3 are mutually recursive; there is one level
5781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * of recursion for each segment in the pattern that contains one or more
5791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * meta characters.
5801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */
5811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int
5821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodglob2(Char *pathbuf, Char *pathbuf_last, Char *pathend, Char *pathend_last,
5831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood    Char *pattern, Char *pattern_last, glob_t *pglob, struct glob_lim *limitp)
5841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
5851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	struct stat sb;
5861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	Char *p, *q;
5871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	int anymeta;
5881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
5891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/*
5901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * Loop over pattern segments until end of pattern or until
5911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * segment with meta character found.
5921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 */
5931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	for (anymeta = 0;;) {
5941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (*pattern == EOS) {		/* End of pattern? */
5951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			*pathend = EOS;
5961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if (g_lstat(pathbuf, &sb, pglob))
5971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				return(0);
5981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
5991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if ((pglob->gl_flags & GLOB_LIMIT) &&
6001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			    limitp->glim_stat++ >= GLOB_LIMIT_STAT) {
6011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				errno = 0;
6021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				*pathend++ = SEP;
6031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				*pathend = EOS;
6041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				return(GLOB_NOSPACE);
6051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			}
6061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
6071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if (((pglob->gl_flags & GLOB_MARK) &&
6081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			    pathend[-1] != SEP) && (S_ISDIR(sb.st_mode) ||
6091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			    (S_ISLNK(sb.st_mode) &&
6101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			    (g_stat(pathbuf, &sb, pglob) == 0) &&
6111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			    S_ISDIR(sb.st_mode)))) {
6121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				if (pathend+1 > pathend_last)
6131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood					return (1);
6141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				*pathend++ = SEP;
6151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				*pathend = EOS;
6161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			}
6171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			++pglob->gl_matchc;
6181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			return(globextend(pathbuf, pglob, limitp, &sb));
6191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		}
6201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
6211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		/* Find end of next segment, copy tentatively to pathend. */
6221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		q = pathend;
6231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		p = pattern;
6241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		while (*p != EOS && *p != SEP) {
6251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if (ismeta(*p))
6261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				anymeta = 1;
6271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if (q+1 > pathend_last)
6281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				return (1);
6291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			*q++ = *p++;
6301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		}
6311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
6321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (!anymeta) {		/* No expansion, do next segment. */
6331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			pathend = q;
6341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			pattern = p;
6351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			while (*pattern == SEP) {
6361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				if (pathend+1 > pathend_last)
6371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood					return (1);
6381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				*pathend++ = *pattern++;
6391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			}
6401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		} else
6411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			/* Need expansion, recurse. */
6421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			return(glob3(pathbuf, pathbuf_last, pathend,
6431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			    pathend_last, pattern, p, pattern_last,
6441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			    pglob, limitp));
6451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
6461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* NOTREACHED */
6471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
6481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
6491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int
6501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodglob3(Char *pathbuf, Char *pathbuf_last, Char *pathend, Char *pathend_last,
6511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood    Char *pattern, Char *restpattern, Char *restpattern_last, glob_t *pglob,
6521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood    struct glob_lim *limitp)
6531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
6541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	struct dirent *dp;
6551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	DIR *dirp;
6561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	int err;
6571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	char buf[MAXPATHLEN];
6581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
6591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/*
6601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * The readdirfunc declaration can't be prototyped, because it is
6611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * assigned, below, to two functions which are prototyped in glob.h
6621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * and dirent.h as taking pointers to differently typed opaque
6631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * structures.
6641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 */
6651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	struct dirent *(*readdirfunc)(void *);
6661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
6671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (pathend > pathend_last)
6681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		return (1);
6691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	*pathend = EOS;
6701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	errno = 0;
6711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
6721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if ((dirp = g_opendir(pathbuf, pglob)) == NULL) {
6731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		/* TODO: don't call for ENOENT or ENOTDIR? */
6741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (pglob->gl_errfunc) {
6751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if (g_Ctoc(pathbuf, buf, sizeof(buf)))
6761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				return(GLOB_ABORTED);
6771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if (pglob->gl_errfunc(buf, errno) ||
6781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			    pglob->gl_flags & GLOB_ERR)
6791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				return(GLOB_ABORTED);
6801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		}
6811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		return(0);
6821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
6831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
6841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	err = 0;
6851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
6861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Search directory for matching names. */
6871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (pglob->gl_flags & GLOB_ALTDIRFUNC)
6881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		readdirfunc = pglob->gl_readdir;
6891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	else
6901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		readdirfunc = (struct dirent *(*)(void *))readdir;
6911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	while ((dp = (*readdirfunc)(dirp))) {
6921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		u_char *sc;
6931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		Char *dc;
6941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
6951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if ((pglob->gl_flags & GLOB_LIMIT) &&
6961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    limitp->glim_readdir++ >= GLOB_LIMIT_READDIR) {
6971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			errno = 0;
6981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			*pathend++ = SEP;
6991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			*pathend = EOS;
7001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			return(GLOB_NOSPACE);
7011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		}
7021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
7031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		/* Initial DOT must be matched literally. */
7041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (dp->d_name[0] == DOT && *pattern != DOT)
7051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			continue;
7061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		dc = pathend;
7071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		sc = (u_char *) dp->d_name;
7081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		while (dc < pathend_last && (*dc++ = *sc++) != EOS)
7091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			;
7101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (dc >= pathend_last) {
7111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			*dc = EOS;
7121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			err = 1;
7131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			break;
7141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		}
7151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
7161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (!match(pathend, pattern, restpattern)) {
7171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			*pathend = EOS;
7181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			continue;
7191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		}
7201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		err = glob2(pathbuf, pathbuf_last, --dc, pathend_last,
7211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    restpattern, restpattern_last, pglob, limitp);
7221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (err)
7231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			break;
7241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
7251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
7261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (pglob->gl_flags & GLOB_ALTDIRFUNC)
7271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		(*pglob->gl_closedir)(dirp);
7281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	else
7291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		closedir(dirp);
7301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	return(err);
7311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
7321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
7331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
7341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/*
7351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Extend the gl_pathv member of a glob_t structure to accommodate a new item,
7361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * add the new item, and update gl_pathc.
7371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *
7381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * This assumes the BSD realloc, which only copies the block when its size
7391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * crosses a power-of-two boundary; for v7 realloc, this would cause quadratic
7401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * behavior.
7411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *
7421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Return 0 if new item added, error code if memory couldn't be allocated.
7431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *
7441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Invariant of the glob_t structure:
7451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *	Either gl_pathc is zero and gl_pathv is NULL; or gl_pathc > 0 and
7461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *	gl_pathv points to (gl_offs + gl_pathc + 1) items.
7471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */
7481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int
7491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodglobextend(const Char *path, glob_t *pglob, struct glob_lim *limitp,
7501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood    struct stat *sb)
7511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
7521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	char **pathv;
7531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	ssize_t i;
7541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	size_t newn, len;
7551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	char *copy = NULL;
7561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	const Char *p;
7571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	struct stat **statv;
7581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
7591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	newn = 2 + pglob->gl_pathc + pglob->gl_offs;
7601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (pglob->gl_offs >= INT_MAX ||
7611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    pglob->gl_pathc >= INT_MAX ||
7621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    newn >= INT_MAX ||
7631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    SIZE_MAX / sizeof(*pathv) <= newn ||
7641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    SIZE_MAX / sizeof(*statv) <= newn) {
7651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood nospace:
7661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		for (i = pglob->gl_offs; i < (ssize_t)(newn - 2); i++) {
7671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if (pglob->gl_pathv && pglob->gl_pathv[i])
7681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				free(pglob->gl_pathv[i]);
7691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if ((pglob->gl_flags & GLOB_KEEPSTAT) != 0 &&
7701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			    pglob->gl_pathv && pglob->gl_pathv[i])
7711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				free(pglob->gl_statv[i]);
7721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		}
7731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (pglob->gl_pathv) {
7741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			free(pglob->gl_pathv);
7751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			pglob->gl_pathv = NULL;
7761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		}
7771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (pglob->gl_statv) {
7781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			free(pglob->gl_statv);
7791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			pglob->gl_statv = NULL;
7801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		}
7811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		return(GLOB_NOSPACE);
7821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
7831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
7841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	pathv = realloc(pglob->gl_pathv, newn * sizeof(*pathv));
7851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (pathv == NULL)
7861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		goto nospace;
7871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (pglob->gl_pathv == NULL && pglob->gl_offs > 0) {
7881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		/* first time around -- clear initial gl_offs items */
7891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		pathv += pglob->gl_offs;
7901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		for (i = pglob->gl_offs; --i >= 0; )
7911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			*--pathv = NULL;
7921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
7931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	pglob->gl_pathv = pathv;
7941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
7951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if ((pglob->gl_flags & GLOB_KEEPSTAT) != 0) {
7961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		statv = realloc(pglob->gl_statv, newn * sizeof(*statv));
7971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (statv == NULL)
7981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			goto nospace;
7991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (pglob->gl_statv == NULL && pglob->gl_offs > 0) {
8001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			/* first time around -- clear initial gl_offs items */
8011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			statv += pglob->gl_offs;
8021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			for (i = pglob->gl_offs; --i >= 0; )
8031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				*--statv = NULL;
8041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		}
8051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		pglob->gl_statv = statv;
8061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (sb == NULL)
8071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			statv[pglob->gl_offs + pglob->gl_pathc] = NULL;
8081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		else {
8091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			limitp->glim_malloc += sizeof(**statv);
8101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if ((pglob->gl_flags & GLOB_LIMIT) &&
8111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			    limitp->glim_malloc >= GLOB_LIMIT_MALLOC) {
8121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				errno = 0;
8131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				return(GLOB_NOSPACE);
8141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			}
8151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if ((statv[pglob->gl_offs + pglob->gl_pathc] =
8161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			    malloc(sizeof(**statv))) == NULL)
8171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				goto copy_error;
8181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			memcpy(statv[pglob->gl_offs + pglob->gl_pathc], sb,
8191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			    sizeof(*sb));
8201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		}
8211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		statv[pglob->gl_offs + pglob->gl_pathc + 1] = NULL;
8221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
8231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
8241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	for (p = path; *p++;)
8251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		;
8261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	len = (size_t)(p - path);
8271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	limitp->glim_malloc += len;
8281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if ((copy = malloc(len)) != NULL) {
8291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (g_Ctoc(path, copy, len)) {
8301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			free(copy);
8311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			return(GLOB_NOSPACE);
8321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		}
8331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		pathv[pglob->gl_offs + pglob->gl_pathc++] = copy;
8341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
8351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	pathv[pglob->gl_offs + pglob->gl_pathc] = NULL;
8361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
8371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if ((pglob->gl_flags & GLOB_LIMIT) &&
8381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    (newn * sizeof(*pathv)) + limitp->glim_malloc >
8391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    GLOB_LIMIT_MALLOC) {
8401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		errno = 0;
8411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		return(GLOB_NOSPACE);
8421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
8431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood copy_error:
8441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	return(copy == NULL ? GLOB_NOSPACE : 0);
8451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
8461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
8471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
8481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/*
8491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * pattern matching function for filenames.  Each occurrence of the *
8501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * pattern causes a recursion level.
8511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */
8521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int
8531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodmatch(Char *name, Char *pat, Char *patend)
8541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
8551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	int ok, negate_range;
8561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	Char c, k;
8571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
8581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	while (pat < patend) {
8591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		c = *pat++;
8601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		switch (c & M_MASK) {
8611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		case M_ALL:
8621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if (pat == patend)
8631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				return(1);
8641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			do {
8651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			    if (match(name, pat, patend))
8661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				    return(1);
8671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			} while (*name++ != EOS);
8681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			return(0);
8691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		case M_ONE:
8701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if (*name++ == EOS)
8711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				return(0);
8721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			break;
8731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		case M_SET:
8741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			ok = 0;
8751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if ((k = *name++) == EOS)
8761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				return(0);
8771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if ((negate_range = ((*pat & M_MASK) == M_NOT)) != EOS)
8781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				++pat;
8791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			while (((c = *pat++) & M_MASK) != M_END) {
8801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				if ((c & M_MASK) == M_CLASS) {
8811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood					Char idx = *pat & M_MASK;
8821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood					if (idx < NCCLASSES &&
8831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood					    cclasses[idx].isctype(k))
8841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood						ok = 1;
8851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood					++pat;
8861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				}
8871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				if ((*pat & M_MASK) == M_RNG) {
8881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood					if (c <= k && k <= pat[1])
8891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood						ok = 1;
8901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood					pat += 2;
8911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				} else if (c == k)
8921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood					ok = 1;
8931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			}
8941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if (ok == negate_range)
8951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				return(0);
8961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			break;
8971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		default:
8981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if (*name++ != c)
8991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				return(0);
9001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			break;
9011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		}
9021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
9031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	return(*name == EOS);
9041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
9051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
9061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* Free allocated data belonging to a glob_t structure. */
9071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid
9081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodglobfree(glob_t *pglob)
9091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
9101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	int i;
9111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	char **pp;
9121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
9131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (pglob->gl_pathv != NULL) {
9141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		pp = pglob->gl_pathv + pglob->gl_offs;
9151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		for (i = pglob->gl_pathc; i--; ++pp)
9161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if (*pp)
9171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				free(*pp);
9181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		free(pglob->gl_pathv);
9191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		pglob->gl_pathv = NULL;
9201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
9211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (pglob->gl_statv != NULL) {
9221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		for (i = 0; i < pglob->gl_pathc; i++) {
9231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if (pglob->gl_statv[i] != NULL)
9241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				free(pglob->gl_statv[i]);
9251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		}
9261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		free(pglob->gl_statv);
9271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		pglob->gl_statv = NULL;
9281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
9291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
9301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
9311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic DIR *
9321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodg_opendir(Char *str, glob_t *pglob)
9331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
9341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	char buf[MAXPATHLEN];
9351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
9361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (!*str)
9371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		strlcpy(buf, ".", sizeof buf);
9381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	else {
9391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (g_Ctoc(str, buf, sizeof(buf)))
9401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			return(NULL);
9411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
9421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
9431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (pglob->gl_flags & GLOB_ALTDIRFUNC)
9441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		return((*pglob->gl_opendir)(buf));
9451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
9461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	return(opendir(buf));
9471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
9481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
9491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int
9501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodg_lstat(Char *fn, struct stat *sb, glob_t *pglob)
9511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
9521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	char buf[MAXPATHLEN];
9531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
9541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (g_Ctoc(fn, buf, sizeof(buf)))
9551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		return(-1);
9561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (pglob->gl_flags & GLOB_ALTDIRFUNC)
9571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		return((*pglob->gl_lstat)(buf, sb));
9581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	return(lstat(buf, sb));
9591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
9601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
9611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int
9621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodg_stat(Char *fn, struct stat *sb, glob_t *pglob)
9631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
9641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	char buf[MAXPATHLEN];
9651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
9661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (g_Ctoc(fn, buf, sizeof(buf)))
9671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		return(-1);
9681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (pglob->gl_flags & GLOB_ALTDIRFUNC)
9691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		return((*pglob->gl_stat)(buf, sb));
9701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	return(stat(buf, sb));
9711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
9721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
9731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic Char *
9741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodg_strchr(const Char *str, int ch)
9751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
9761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	do {
9771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (*str == ch)
9781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			return ((Char *)str);
9791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	} while (*str++);
9801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	return (NULL);
9811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
9821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
9831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int
9841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodg_Ctoc(const Char *str, char *buf, u_int len)
9851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
9861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
9871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	while (len--) {
9881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if ((*buf++ = *str++) == EOS)
9891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			return (0);
9901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
9911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	return (1);
9921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
9931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
9941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef DEBUG
9951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void
9961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodqprintf(const char *str, Char *s)
9971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
9981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	Char *p;
9991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
10001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	(void)printf("%s:\n", str);
10011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	for (p = s; *p; p++)
10021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		(void)printf("%c", CHAR(*p));
10031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	(void)printf("\n");
10041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	for (p = s; *p; p++)
10051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		(void)printf("%c", *p & M_PROTECT ? '"' : ' ');
10061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	(void)printf("\n");
10071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	for (p = s; *p; p++)
10081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		(void)printf("%c", ismeta(*p) ? '_' : ' ');
10091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	(void)printf("\n");
10101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
10111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif
10121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
10131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif /* !defined(HAVE_GLOB) || !defined(GLOB_HAS_ALTDIRFUNC) ||
10141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood          !defined(GLOB_HAS_GL_MATCHC) || !defined(GLOB_HAS_GL_STATV) */
1015