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