169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban/* $NetBSD: glob.c,v 1.35 2013/03/20 23:44:47 lukem Exp $ */ 269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban/* 469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * Copyright (c) 1989, 1993 569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * The Regents of the University of California. All rights reserved. 669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * 769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * This code is derived from software contributed to Berkeley by 869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * Guido van Rossum. 969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * 1069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * Redistribution and use in source and binary forms, with or without 1169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * modification, are permitted provided that the following conditions 1269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * are met: 1369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * 1. Redistributions of source code must retain the above copyright 1469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * notice, this list of conditions and the following disclaimer. 1569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * 2. Redistributions in binary form must reproduce the above copyright 1669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * notice, this list of conditions and the following disclaimer in the 1769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * documentation and/or other materials provided with the distribution. 1869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * 3. Neither the name of the University nor the names of its contributors 1969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * may be used to endorse or promote products derived from this software 2069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * without specific prior written permission. 2169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * 2269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * SUCH DAMAGE. 3369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban */ 3469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 3569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#include <sys/cdefs.h> 3669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#if defined(LIBC_SCCS) && !defined(lint) 3769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#if 0 3869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serbanstatic char sccsid[] = "@(#)glob.c 8.3 (Berkeley) 10/13/93"; 3969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#else 4069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban__RCSID("$NetBSD: glob.c,v 1.35 2013/03/20 23:44:47 lukem Exp $"); 4169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#endif 4269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#endif /* LIBC_SCCS and not lint */ 4369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 4469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban/* 4569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * glob(3) -- a superset of the one defined in POSIX 1003.2. 4669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * 4769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * The [!...] convention to negate a range is supported (SysV, Posix, ksh). 4869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * 4969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * Optional extra services, controlled by flags not defined by POSIX: 5069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * 5169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * GLOB_MAGCHAR: 5269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * Set in gl_flags if pattern contained a globbing character. 5369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * GLOB_NOMAGIC: 5469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * Same as GLOB_NOCHECK, but it will only append pattern if it did 5569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * not contain any magic characters. [Used in csh style globbing] 5669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * GLOB_ALTDIRFUNC: 5769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * Use alternately specified directory access functions. 5869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * GLOB_TILDE: 5969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * expand ~user/foo to the /home/dir/of/user/foo 6069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * GLOB_BRACE: 6169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * expand {1,2}{a,b} to 1a 1b 2a 2b 6269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * GLOB_PERIOD: 6369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * allow metacharacters to match leading dots in filenames. 6469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * GLOB_NO_DOTDIRS: 6569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * . and .. are hidden from wildcards, even if GLOB_PERIOD is set. 6669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * gl_matchc: 6769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * Number of matches in the current invocation of glob. 6869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban */ 6969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 7069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban//#include "namespace.h" 7169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#include <sys/param.h> 7269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#include <sys/stat.h> 7369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 7469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#include <assert.h> 7569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#include <ctype.h> 7669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#include <dirent.h> 7769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#include <errno.h> 7869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#include <glob.h> 7969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#include <pwd.h> 8069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#include <stdio.h> 8169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#include <stddef.h> 8269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#include <stdlib.h> 8369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#include <string.h> 8469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#include <unistd.h> 8569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 8669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#ifdef HAVE_NBTOOL_CONFIG_H 8769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#define NO_GETPW_R 8869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#endif 8969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 9069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#define GLOB_LIMIT_STRING 65536 /* number of readdirs */ 9169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#define GLOB_LIMIT_STAT 128 /* number of stat system calls */ 9269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#define GLOB_LIMIT_READDIR 16384 /* total buffer size of path strings */ 9369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#define GLOB_LIMIT_PATH 1024 /* number of path elements */ 9469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#define GLOB_LIMIT_BRACE 128 /* Number of brace calls */ 9569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 9669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serbanstruct glob_limit { 9769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban size_t l_string; 9869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban size_t l_stat; 9969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban size_t l_readdir; 10069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban size_t l_brace; 10169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban}; 10269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 10369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban/* 10469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * XXX: For NetBSD 1.4.x compatibility. (kill me l8r) 10569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban */ 10669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#ifndef _DIAGASSERT 10769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#define _DIAGASSERT(a) 10869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#endif 10969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 11069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#define DOLLAR '$' 11169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#define DOT '.' 11269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#define EOS '\0' 11369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#define LBRACKET '[' 11469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#define NOT '!' 11569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#define QUESTION '?' 11669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#define QUOTE '\\' 11769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#define RANGE '-' 11869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#define RBRACKET ']' 11969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#define SEP '/' 12069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#define STAR '*' 12169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#define TILDE '~' 12269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#define UNDERSCORE '_' 12369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#define LBRACE '{' 12469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#define RBRACE '}' 12569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#define SLASH '/' 12669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#define COMMA ',' 12769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 12869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#ifndef USE_8BIT_CHARS 12969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 13069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#define M_QUOTE 0x8000 13169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#define M_PROTECT 0x4000 13269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#define M_MASK 0xffff 13369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#define M_ASCII 0x00ff 13469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 13569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serbantypedef unsigned short Char; 13669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 13769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#else 13869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 13969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#define M_QUOTE (Char)0x80 14069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#define M_PROTECT (Char)0x40 14169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#define M_MASK (Char)0xff 14269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#define M_ASCII (Char)0x7f 14369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 14469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serbantypedef char Char; 14569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 14669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#endif 14769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 14869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 14969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#define CHAR(c) ((Char)((c)&M_ASCII)) 15069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#define META(c) ((Char)((c)|M_QUOTE)) 15169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#define M_ALL META('*') 15269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#define M_END META(']') 15369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#define M_NOT META('!') 15469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#define M_ONE META('?') 15569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#define M_RNG META('-') 15669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#define M_SET META('[') 15769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#define ismeta(c) (((c)&M_QUOTE) != 0) 15869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 15969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 16069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serbanstatic int compare(const void *, const void *); 16169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serbanstatic int g_Ctoc(const Char *, char *, size_t); 16269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serbanstatic int g_lstat(Char *, __gl_stat_t *, glob_t *); 16369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serbanstatic DIR *g_opendir(Char *, glob_t *); 16469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serbanstatic Char *g_strchr(const Char *, int); 16569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serbanstatic int g_stat(Char *, __gl_stat_t *, glob_t *); 16669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serbanstatic int glob0(const Char *, glob_t *, struct glob_limit *); 16769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serbanstatic int glob1(Char *, glob_t *, struct glob_limit *); 16869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serbanstatic int glob2(Char *, Char *, Char *, const Char *, glob_t *, 16969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban struct glob_limit *); 17069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serbanstatic int glob3(Char *, Char *, Char *, const Char *, const Char *, 17169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban const Char *, glob_t *, struct glob_limit *); 17269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serbanstatic int globextend(const Char *, glob_t *, struct glob_limit *); 17369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serbanstatic const Char *globtilde(const Char *, Char *, size_t, glob_t *); 17469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serbanstatic int globexp1(const Char *, glob_t *, struct glob_limit *); 17569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serbanstatic int globexp2(const Char *, const Char *, glob_t *, int *, 17669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban struct glob_limit *); 17769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serbanstatic int match(const Char *, const Char *, const Char *); 17869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#ifdef DEBUG 17969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serbanstatic void qprintf(const char *, Char *); 18069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#endif 18169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 18269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serbanint 18369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serbanglob(const char * __restrict pattern, int flags, int (*errfunc)(const char *, 18469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban int), glob_t * __restrict pglob) 18569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban{ 18669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban const unsigned char *patnext; 18769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban int c; 18869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban Char *bufnext, *bufend, patbuf[MAXPATHLEN+1]; 18969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban struct glob_limit limit = { 0, 0, 0, 0 }; 19069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 19169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban _DIAGASSERT(pattern != NULL); 19269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 19369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban patnext = (const unsigned char *) pattern; 19469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if (!(flags & GLOB_APPEND)) { 19569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban pglob->gl_pathc = 0; 19669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban pglob->gl_pathv = NULL; 19769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if (!(flags & GLOB_DOOFFS)) 19869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban pglob->gl_offs = 0; 19969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban } 20069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban pglob->gl_flags = flags & ~GLOB_MAGCHAR; 20169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban pglob->gl_errfunc = errfunc; 20269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban pglob->gl_matchc = 0; 20369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 20469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban bufnext = patbuf; 20569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban bufend = bufnext + MAXPATHLEN; 20669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if (flags & GLOB_NOESCAPE) { 20769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban while (bufnext < bufend && (c = *patnext++) != EOS) 20869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban *bufnext++ = c; 20969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban } else { 21069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban /* Protect the quoted characters. */ 21169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban while (bufnext < bufend && (c = *patnext++) != EOS) 21269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if (c == QUOTE) { 21369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if ((c = *patnext++) == EOS) { 21469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban c = QUOTE; 21569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban --patnext; 21669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban } 21769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban *bufnext++ = c | M_PROTECT; 21869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban } 21969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban else 22069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban *bufnext++ = c; 22169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban } 22269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban *bufnext = EOS; 22369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 22469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if (flags & GLOB_BRACE) 22569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban return globexp1(patbuf, pglob, &limit); 22669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban else 22769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban return glob0(patbuf, pglob, &limit); 22869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban} 22969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 23069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban/* 23169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * Expand recursively a glob {} pattern. When there is no more expansion 23269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * invoke the standard globbing routine to glob the rest of the magic 23369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * characters 23469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban */ 23569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serbanstatic int 23669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serbanglobexp1(const Char *pattern, glob_t *pglob, struct glob_limit *limit) 23769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban{ 23869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban const Char* ptr = pattern; 23969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban int rv; 24069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 24169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban _DIAGASSERT(pattern != NULL); 24269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban _DIAGASSERT(pglob != NULL); 24369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 24469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if ((pglob->gl_flags & GLOB_LIMIT) && 24569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban limit->l_brace++ >= GLOB_LIMIT_BRACE) { 24669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban errno = 0; 24769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban return GLOB_NOSPACE; 24869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban } 24969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 25069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban /* Protect a single {}, for find(1), like csh */ 25169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if (pattern[0] == LBRACE && pattern[1] == RBRACE && pattern[2] == EOS) 25269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban return glob0(pattern, pglob, limit); 25369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 25469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban while ((ptr = (const Char *) g_strchr(ptr, LBRACE)) != NULL) 25569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if (!globexp2(ptr, pattern, pglob, &rv, limit)) 25669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban return rv; 25769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 25869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban return glob0(pattern, pglob, limit); 25969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban} 26069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 26169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 26269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban/* 26369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * Recursive brace globbing helper. Tries to expand a single brace. 26469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * If it succeeds then it invokes globexp1 with the new pattern. 26569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * If it fails then it tries to glob the rest of the pattern and returns. 26669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban */ 26769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serbanstatic int 26869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serbanglobexp2(const Char *ptr, const Char *pattern, glob_t *pglob, int *rv, 26969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban struct glob_limit *limit) 27069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban{ 27169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban int i; 27269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban Char *lm, *ls; 27369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban const Char *pe, *pm, *pl; 27469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban Char patbuf[MAXPATHLEN + 1]; 27569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 27669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban _DIAGASSERT(ptr != NULL); 27769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban _DIAGASSERT(pattern != NULL); 27869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban _DIAGASSERT(pglob != NULL); 27969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban _DIAGASSERT(rv != NULL); 28069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 28169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban /* copy part up to the brace */ 28269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban for (lm = patbuf, pm = pattern; pm != ptr; *lm++ = *pm++) 28369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban continue; 28469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban ls = lm; 28569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 28669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban /* Find the balanced brace */ 28769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban for (i = 0, pe = ++ptr; *pe; pe++) 28869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if (*pe == LBRACKET) { 28969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban /* Ignore everything between [] */ 29069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban for (pm = pe++; *pe != RBRACKET && *pe != EOS; pe++) 29169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban continue; 29269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if (*pe == EOS) { 29369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban /* 29469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * We could not find a matching RBRACKET. 29569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * Ignore and just look for RBRACE 29669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban */ 29769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban pe = pm; 29869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban } 29969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban } 30069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban else if (*pe == LBRACE) 30169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban i++; 30269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban else if (*pe == RBRACE) { 30369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if (i == 0) 30469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban break; 30569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban i--; 30669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban } 30769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 30869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban /* Non matching braces; just glob the pattern */ 30969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if (i != 0 || *pe == EOS) { 31069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban /* 31169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * we use `pattern', not `patbuf' here so that that 31269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * unbalanced braces are passed to the match 31369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban */ 31469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban *rv = glob0(pattern, pglob, limit); 31569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban return 0; 31669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban } 31769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 31869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban for (i = 0, pl = pm = ptr; pm <= pe; pm++) { 31969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban switch (*pm) { 32069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban case LBRACKET: 32169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban /* Ignore everything between [] */ 32269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban for (pl = pm++; *pm != RBRACKET && *pm != EOS; pm++) 32369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban continue; 32469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if (*pm == EOS) { 32569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban /* 32669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * We could not find a matching RBRACKET. 32769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * Ignore and just look for RBRACE 32869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban */ 32969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban pm = pl; 33069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban } 33169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban break; 33269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 33369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban case LBRACE: 33469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban i++; 33569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban break; 33669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 33769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban case RBRACE: 33869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if (i) { 33969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban i--; 34069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban break; 34169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban } 34269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban /* FALLTHROUGH */ 34369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban case COMMA: 34469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if (i && *pm == COMMA) 34569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban break; 34669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban else { 34769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban /* Append the current string */ 34869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban for (lm = ls; (pl < pm); *lm++ = *pl++) 34969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban continue; 35069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban /* 35169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * Append the rest of the pattern after the 35269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * closing brace 35369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban */ 35469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban for (pl = pe + 1; (*lm++ = *pl++) != EOS;) 35569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban continue; 35669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 35769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban /* Expand the current pattern */ 35869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#ifdef DEBUG 35969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban qprintf("globexp2", patbuf); 36069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#endif 36169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban *rv = globexp1(patbuf, pglob, limit); 36269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 36369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban /* move after the comma, to the next string */ 36469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban pl = pm + 1; 36569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban } 36669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban break; 36769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 36869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban default: 36969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban break; 37069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban } 37169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban } 37269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban *rv = 0; 37369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban return 0; 37469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban} 37569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 37669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 37769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 37869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban/* 37969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * expand tilde from the passwd file. 38069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban */ 38169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serbanstatic const Char * 38269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serbanglobtilde(const Char *pattern, Char *patbuf, size_t patsize, glob_t *pglob) 38369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban{ 38469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban struct passwd *pwd; 38569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban const char *h; 38669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban const Char *p; 38769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban Char *b; 38869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban char *d; 38969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban Char *pend = &patbuf[patsize / sizeof(Char)]; 39069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#ifndef NO_GETPW_R 39169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban struct passwd pwres; 39269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban char pwbuf[1024]; 39369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#endif 39469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 39569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban pend--; 39669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 39769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban _DIAGASSERT(pattern != NULL); 39869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban _DIAGASSERT(patbuf != NULL); 39969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban _DIAGASSERT(pglob != NULL); 40069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 40169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if (*pattern != TILDE || !(pglob->gl_flags & GLOB_TILDE)) 40269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban return pattern; 40369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 40469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban /* Copy up to the end of the string or / */ 40569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban for (p = pattern + 1, d = (char *)(void *)patbuf; 40669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban d < (char *)(void *)pend && *p && *p != SLASH; 40769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban *d++ = *p++) 40869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban continue; 40969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 41069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if (d == (char *)(void *)pend) 41169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban return NULL; 41269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 41369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban *d = EOS; 41469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban d = (char *)(void *)patbuf; 41569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 41669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if (*d == EOS) { 41769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban /* 41869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * handle a plain ~ or ~/ by expanding $HOME 41969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * first and then trying the password file 42069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban */ 42169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if ((h = getenv("HOME")) == NULL) { 42269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#ifdef NO_GETPW_R 42369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if ((pwd = getpwuid(getuid())) == NULL) 42469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#else 42569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if (getpwuid_r(getuid(), &pwres, pwbuf, sizeof(pwbuf), 42669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban &pwd) != 0 || pwd == NULL) 42769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#endif 42869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban return pattern; 42969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban else 43069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban h = pwd->pw_dir; 43169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban } 43269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban } 43369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban else { 43469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban /* 43569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * Expand a ~user 43669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban */ 43769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#ifdef NO_GETPW_R 43869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if ((pwd = getpwnam(d)) == NULL) 43969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#else 44069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if (getpwnam_r(d, &pwres, pwbuf, sizeof(pwbuf), &pwd) != 0 || 44169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban pwd == NULL) 44269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#endif 44369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban return pattern; 44469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban else 44569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban h = pwd->pw_dir; 44669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban } 44769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 44869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban /* Copy the home directory */ 44969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban for (b = patbuf; b < pend && *h; *b++ = *h++) 45069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban continue; 45169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 45269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if (b == pend) 45369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban return NULL; 45469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 45569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban /* Append the rest of the pattern */ 45669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban while (b < pend && (*b++ = *p++) != EOS) 45769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban continue; 45869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 45969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if (b == pend) 46069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban return NULL; 46169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 46269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban return patbuf; 46369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban} 46469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 46569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 46669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban/* 46769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * The main glob() routine: compiles the pattern (optionally processing 46869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * quotes), calls glob1() to do the real pattern matching, and finally 46969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * sorts the list (unless unsorted operation is requested). Returns 0 47069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * if things went well, nonzero if errors occurred. It is not an error 47169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * to find no matches. 47269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban */ 47369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serbanstatic int 47469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serbanglob0(const Char *pattern, glob_t *pglob, struct glob_limit *limit) 47569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban{ 47669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban const Char *qpatnext; 47769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban int c, error; 47869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban __gl_size_t oldpathc; 47969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban Char *bufnext, patbuf[MAXPATHLEN+1]; 48069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 48169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban _DIAGASSERT(pattern != NULL); 48269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban _DIAGASSERT(pglob != NULL); 48369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 48469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if ((qpatnext = globtilde(pattern, patbuf, sizeof(patbuf), 48569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban pglob)) == NULL) 48669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban return GLOB_ABEND; 48769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban oldpathc = pglob->gl_pathc; 48869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban bufnext = patbuf; 48969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 49069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban /* We don't need to check for buffer overflow any more. */ 49169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban while ((c = *qpatnext++) != EOS) { 49269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban switch (c) { 49369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban case LBRACKET: 49469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban c = *qpatnext; 49569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if (c == NOT) 49669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban ++qpatnext; 49769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if (*qpatnext == EOS || 49869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban g_strchr(qpatnext+1, RBRACKET) == NULL) { 49969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban *bufnext++ = LBRACKET; 50069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if (c == NOT) 50169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban --qpatnext; 50269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban break; 50369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban } 50469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban *bufnext++ = M_SET; 50569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if (c == NOT) 50669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban *bufnext++ = M_NOT; 50769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban c = *qpatnext++; 50869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban do { 50969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban *bufnext++ = CHAR(c); 51069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if (*qpatnext == RANGE && 51169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban (c = qpatnext[1]) != RBRACKET) { 51269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban *bufnext++ = M_RNG; 51369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban *bufnext++ = CHAR(c); 51469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban qpatnext += 2; 51569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban } 51669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban } while ((c = *qpatnext++) != RBRACKET); 51769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban pglob->gl_flags |= GLOB_MAGCHAR; 51869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban *bufnext++ = M_END; 51969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban break; 52069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban case QUESTION: 52169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban pglob->gl_flags |= GLOB_MAGCHAR; 52269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban *bufnext++ = M_ONE; 52369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban break; 52469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban case STAR: 52569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban pglob->gl_flags |= GLOB_MAGCHAR; 52669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban /* collapse adjacent stars to one [or three if globstar] 52769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * to avoid exponential behavior 52869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban */ 52969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if (bufnext == patbuf || bufnext[-1] != M_ALL || 53069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban ((pglob->gl_flags & GLOB_STAR) != 0 && 53169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban (bufnext - 1 == patbuf || bufnext[-2] != M_ALL || 53269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban bufnext - 2 == patbuf || bufnext[-3] != M_ALL))) 53369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban *bufnext++ = M_ALL; 53469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban break; 53569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban default: 53669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban *bufnext++ = CHAR(c); 53769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban break; 53869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban } 53969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban } 54069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban *bufnext = EOS; 54169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#ifdef DEBUG 54269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban qprintf("glob0", patbuf); 54369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#endif 54469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 54569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if ((error = glob1(patbuf, pglob, limit)) != 0) 54669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban return error; 54769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 54869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if (pglob->gl_pathc == oldpathc) { 54969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban /* 55069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * If there was no match we are going to append the pattern 55169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * if GLOB_NOCHECK was specified or if GLOB_NOMAGIC was 55269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * specified and the pattern did not contain any magic 55369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * characters GLOB_NOMAGIC is there just for compatibility 55469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * with csh. 55569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban */ 55669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if ((pglob->gl_flags & GLOB_NOCHECK) || 55769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban ((pglob->gl_flags & (GLOB_NOMAGIC|GLOB_MAGCHAR)) 55869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban == GLOB_NOMAGIC)) { 55969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban return globextend(pattern, pglob, limit); 56069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban } else { 56169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban return GLOB_NOMATCH; 56269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban } 56369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban } else if (!(pglob->gl_flags & GLOB_NOSORT)) { 56469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban qsort(pglob->gl_pathv + pglob->gl_offs + oldpathc, 56569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban (size_t)pglob->gl_pathc - oldpathc, sizeof(char *), 56669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban compare); 56769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban } 56869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 56969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban return 0; 57069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban} 57169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 57269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serbanstatic int 57369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serbancompare(const void *p, const void *q) 57469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban{ 57569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 57669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban _DIAGASSERT(p != NULL); 57769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban _DIAGASSERT(q != NULL); 57869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 57969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban return strcoll(*(const char * const *)p, *(const char * const *)q); 58069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban} 58169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 58269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serbanstatic int 58369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serbanglob1(Char *pattern, glob_t *pglob, struct glob_limit *limit) 58469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban{ 58569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban Char pathbuf[MAXPATHLEN+1]; 58669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 58769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban _DIAGASSERT(pattern != NULL); 58869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban _DIAGASSERT(pglob != NULL); 58969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 59069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban /* A null pathname is invalid -- POSIX 1003.1 sect. 2.4. */ 59169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if (*pattern == EOS) 59269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban return 0; 59369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban /* 59469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * we save one character so that we can use ptr >= limit, 59569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * in the general case when we are appending non nul chars only. 59669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban */ 59769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban return glob2(pathbuf, pathbuf, 59869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban pathbuf + (sizeof(pathbuf) / sizeof(*pathbuf)) - 1, pattern, 59969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban pglob, limit); 60069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban} 60169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 60269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban/* 60369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * The functions glob2 and glob3 are mutually recursive; there is one level 60469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * of recursion for each segment in the pattern that contains one or more 60569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * meta characters. 60669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban */ 60769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serbanstatic int 60869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serbanglob2(Char *pathbuf, Char *pathend, Char *pathlim, const Char *pattern, 60969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban glob_t *pglob, struct glob_limit *limit) 61069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban{ 61169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban __gl_stat_t sb; 61269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban const Char *p; 61369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban Char *q; 61469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban int anymeta; 61569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 61669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban _DIAGASSERT(pathbuf != NULL); 61769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban _DIAGASSERT(pathend != NULL); 61869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban _DIAGASSERT(pattern != NULL); 61969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban _DIAGASSERT(pglob != NULL); 62069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 62169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#ifdef DEBUG 62269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban qprintf("glob2", pathbuf); 62369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#endif 62469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban /* 62569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * Loop over pattern segments until end of pattern or until 62669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * segment with meta character found. 62769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban */ 62869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban for (anymeta = 0;;) { 62969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if (*pattern == EOS) { /* End of pattern? */ 63069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban *pathend = EOS; 63169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if (g_lstat(pathbuf, &sb, pglob)) 63269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban return 0; 63369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 63469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if ((pglob->gl_flags & GLOB_LIMIT) && 63569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban limit->l_stat++ >= GLOB_LIMIT_STAT) { 63669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban errno = 0; 63769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban *pathend++ = SEP; 63869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban *pathend = EOS; 63969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban return GLOB_NOSPACE; 64069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban } 64169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if (((pglob->gl_flags & GLOB_MARK) && 64269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban pathend[-1] != SEP) && (S_ISDIR(sb.st_mode) || 64369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban (S_ISLNK(sb.st_mode) && 64469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban (g_stat(pathbuf, &sb, pglob) == 0) && 64569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban S_ISDIR(sb.st_mode)))) { 64669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if (pathend >= pathlim) 64769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban return GLOB_ABORTED; 64869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban *pathend++ = SEP; 64969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban *pathend = EOS; 65069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban } 65169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban ++pglob->gl_matchc; 65269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban return globextend(pathbuf, pglob, limit); 65369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban } 65469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 65569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban /* Find end of next segment, copy tentatively to pathend. */ 65669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban q = pathend; 65769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban p = pattern; 65869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban while (*p != EOS && *p != SEP) { 65969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if (ismeta(*p)) 66069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban anymeta = 1; 66169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if (q >= pathlim) 66269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban return GLOB_ABORTED; 66369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban *q++ = *p++; 66469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban } 66569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 66669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if (!anymeta) { 66769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban pathend = q; 66869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban pattern = p; 66969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban while (*pattern == SEP) { 67069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if (pathend >= pathlim) 67169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban return GLOB_ABORTED; 67269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban *pathend++ = *pattern++; 67369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban } 67469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban } else /* Need expansion, recurse. */ 67569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban return glob3(pathbuf, pathend, pathlim, pattern, p, 67669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban pattern, pglob, limit); 67769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban } 67869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban /* NOTREACHED */ 67969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban} 68069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 68169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serbanstatic int 68269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serbanglob3(Char *pathbuf, Char *pathend, Char *pathlim, const Char *pattern, 68369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban const Char *restpattern, const Char *pglobstar, glob_t *pglob, 68469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban struct glob_limit *limit) 68569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban{ 68669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban struct dirent *dp; 68769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban DIR *dirp; 68869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban __gl_stat_t sbuf; 68969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban int error; 69069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban char buf[MAXPATHLEN]; 69169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban int globstar = 0; 69269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban int chase_symlinks = 0; 69369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban const Char *termstar = NULL; 69469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 69569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban /* 69669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * The readdirfunc declaration can't be prototyped, because it is 69769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * assigned, below, to two functions which are prototyped in glob.h 69869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * and dirent.h as taking pointers to differently typed opaque 69969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * structures. 70069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban */ 70169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban struct dirent *(*readdirfunc)(void *); 70269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 70369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban _DIAGASSERT(pathbuf != NULL); 70469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban _DIAGASSERT(pathend != NULL); 70569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban _DIAGASSERT(pattern != NULL); 70669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban _DIAGASSERT(restpattern != NULL); 70769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban _DIAGASSERT(pglob != NULL); 70869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 70969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban *pathend = EOS; 71069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban errno = 0; 71169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 71269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban while (pglobstar < restpattern) { 71369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if ((pglobstar[0] & M_MASK) == M_ALL && 71469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban (pglobstar[1] & M_MASK) == M_ALL) { 71569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban globstar = 1; 71669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban chase_symlinks = (pglobstar[2] & M_MASK) == M_ALL; 71769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban termstar = pglobstar + (2 + chase_symlinks); 71869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban break; 71969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban } 72069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban pglobstar++; 72169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban } 72269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 72369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if (globstar) { 72469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban error = pglobstar == pattern && termstar == restpattern ? 72569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban *restpattern == EOS ? 72669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban glob2(pathbuf, pathend, pathlim, restpattern - 1, pglob, 72769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban limit) : 72869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban glob2(pathbuf, pathend, pathlim, restpattern + 1, pglob, 72969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban limit) : 73069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban glob3(pathbuf, pathend, pathlim, pattern, restpattern, 73169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban termstar, pglob, limit); 73269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if (error) 73369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban return error; 73469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban *pathend = EOS; 73569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban } 73669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 73769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if (*pathbuf && (g_lstat(pathbuf, &sbuf, pglob) || 73869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban !S_ISDIR(sbuf.st_mode) 73969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#ifdef S_IFLINK 74069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban && ((globstar && !chase_symlinks) || !S_ISLNK(sbuf.st_mode)) 74169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#endif 74269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban )) 74369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban return 0; 74469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 74569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if ((dirp = g_opendir(pathbuf, pglob)) == NULL) { 74669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if (pglob->gl_errfunc) { 74769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if (g_Ctoc(pathbuf, buf, sizeof(buf))) 74869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban return GLOB_ABORTED; 74969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if (pglob->gl_errfunc(buf, errno) || 75069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban pglob->gl_flags & GLOB_ERR) 75169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban return GLOB_ABORTED; 75269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban } 75369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban /* 75469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * Posix/XOpen: glob should return when it encounters a 75569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * directory that it cannot open or read 75669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * XXX: Should we ignore ENOTDIR and ENOENT though? 75769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * I think that Posix had in mind EPERM... 75869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban */ 75969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if (pglob->gl_flags & GLOB_ERR) 76069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban return GLOB_ABORTED; 76169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 76269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban return 0; 76369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban } 76469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 76569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban error = 0; 76669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 76769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban /* Search directory for matching names. */ 76869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if (pglob->gl_flags & GLOB_ALTDIRFUNC) 76969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban readdirfunc = pglob->gl_readdir; 77069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban else 77169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban readdirfunc = (struct dirent *(*)(void *)) readdir; 77269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban while ((dp = (*readdirfunc)(dirp)) != NULL) { 77369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban unsigned char *sc; 77469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban Char *dc; 77569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 77669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if ((pglob->gl_flags & GLOB_LIMIT) && 77769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban limit->l_readdir++ >= GLOB_LIMIT_READDIR) { 77869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban errno = 0; 77969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban *pathend++ = SEP; 78069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban *pathend = EOS; 78169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban error = GLOB_NOSPACE; 78269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban break; 78369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban } 78469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 78569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban /* 78669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * Initial DOT must be matched literally, unless we have 78769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * GLOB_PERIOD set. 78869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban */ 78969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if ((pglob->gl_flags & GLOB_PERIOD) == 0) 79069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if (dp->d_name[0] == DOT && *pattern != DOT) 79169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban continue; 79269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban /* 79369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * If GLOB_NO_DOTDIRS is set, . and .. vanish. 79469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban */ 79569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if ((pglob->gl_flags & GLOB_NO_DOTDIRS) && 79669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban (dp->d_name[0] == DOT) && 79769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban ((dp->d_name[1] == EOS) || 79869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban ((dp->d_name[1] == DOT) && (dp->d_name[2] == EOS)))) 79969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban continue; 80069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban /* 80169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * The resulting string contains EOS, so we can 80269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * use the pathlim character, if it is the nul 80369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban */ 80469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban for (sc = (unsigned char *) dp->d_name, dc = pathend; 80569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban dc <= pathlim && (*dc++ = *sc++) != EOS;) 80669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban continue; 80769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 80869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban /* 80969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * Have we filled the buffer without seeing EOS? 81069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban */ 81169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if (dc > pathlim && *pathlim != EOS) { 81269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban /* 81369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * Abort when requested by caller, otherwise 81469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * reset pathend back to last SEP and continue 81569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * with next dir entry. 81669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban */ 81769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if (pglob->gl_flags & GLOB_ERR) { 81869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban error = GLOB_ABORTED; 81969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban break; 82069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban } 82169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban else { 82269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban *pathend = EOS; 82369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban continue; 82469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban } 82569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban } 82669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 82769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if (globstar) { 82869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#ifdef S_IFLNK 82969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if (!chase_symlinks && 83069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban (g_lstat(pathbuf, &sbuf, pglob) || 83169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban S_ISLNK(sbuf.st_mode))) 83269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban continue; 83369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#endif 83469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 83569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if (!match(pathend, pattern, termstar)) 83669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban continue; 83769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 83869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if (--dc < pathlim - 2) 83969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban *dc++ = SEP; 84069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban *dc = EOS; 84169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban error = glob2(pathbuf, dc, pathlim, pglobstar, 84269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban pglob, limit); 84369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if (error) 84469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban break; 84569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban *pathend = EOS; 84669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban } else { 84769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if (!match(pathend, pattern, restpattern)) { 84869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban *pathend = EOS; 84969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban continue; 85069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban } 85169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban error = glob2(pathbuf, --dc, pathlim, restpattern, 85269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban pglob, limit); 85369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if (error) 85469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban break; 85569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban } 85669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban } 85769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if (pglob->gl_flags & GLOB_ALTDIRFUNC) 85869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban (*pglob->gl_closedir)(dirp); 85969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban else 86069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban closedir(dirp); 86169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 86269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban /* 86369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * Again Posix X/Open issue with regards to error handling. 86469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban */ 86569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if ((error || errno) && (pglob->gl_flags & GLOB_ERR)) 86669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban return GLOB_ABORTED; 86769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 86869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban return error; 86969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban} 87069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 87169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 87269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban/* 87369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * Extend the gl_pathv member of a glob_t structure to accommodate a new item, 87469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * add the new item, and update gl_pathc. 87569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * 87669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * This assumes the BSD realloc, which only copies the block when its size 87769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * crosses a power-of-two boundary; for v7 realloc, this would cause quadratic 87869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * behavior. 87969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * 88069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * Return 0 if new item added, error code if memory couldn't be allocated. 88169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * 88269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * Invariant of the glob_t structure: 88369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * Either gl_pathc is zero and gl_pathv is NULL; or gl_pathc > 0 and 88469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * gl_pathv points to (gl_offs + gl_pathc + 1) items. 88569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban */ 88669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serbanstatic int 88769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serbanglobextend(const Char *path, glob_t *pglob, struct glob_limit *limit) 88869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban{ 88969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban char **pathv; 89069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban size_t i, newsize, len; 89169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban char *copy; 89269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban const Char *p; 89369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 89469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban _DIAGASSERT(path != NULL); 89569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban _DIAGASSERT(pglob != NULL); 89669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 89769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban newsize = sizeof(*pathv) * (2 + pglob->gl_pathc + pglob->gl_offs); 89869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if ((pglob->gl_flags & GLOB_LIMIT) && 89969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban newsize > GLOB_LIMIT_PATH * sizeof(*pathv)) 90069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban goto nospace; 90169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban pathv = pglob->gl_pathv ? realloc(pglob->gl_pathv, newsize) : 90269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban malloc(newsize); 90369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if (pathv == NULL) 90469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban return GLOB_NOSPACE; 90569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 90669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if (pglob->gl_pathv == NULL && pglob->gl_offs > 0) { 90769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban /* first time around -- clear initial gl_offs items */ 90869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban pathv += pglob->gl_offs; 90969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban for (i = pglob->gl_offs + 1; --i > 0; ) 91069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban *--pathv = NULL; 91169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban } 91269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban pglob->gl_pathv = pathv; 91369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 91469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban for (p = path; *p++;) 91569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban continue; 91669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban len = (size_t)(p - path); 91769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban limit->l_string += len; 91869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if ((copy = malloc(len)) != NULL) { 91969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if (g_Ctoc(path, copy, len)) { 92069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban free(copy); 92169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban return GLOB_ABORTED; 92269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban } 92369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban pathv[pglob->gl_offs + pglob->gl_pathc++] = copy; 92469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban } 92569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban pathv[pglob->gl_offs + pglob->gl_pathc] = NULL; 92669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 92769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if ((pglob->gl_flags & GLOB_LIMIT) && 92869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban (newsize + limit->l_string) >= GLOB_LIMIT_STRING) 92969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban goto nospace; 93069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 93169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban return copy == NULL ? GLOB_NOSPACE : 0; 93269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serbannospace: 93369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban errno = 0; 93469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban return GLOB_NOSPACE; 93569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban} 93669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 93769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 93869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban/* 93969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * pattern matching function for filenames. Each occurrence of the * 94069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban * pattern causes a recursion level. 94169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban */ 94269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serbanstatic int 94369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serbanmatch(const Char *name, const Char *pat, const Char *patend) 94469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban{ 94569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban int ok, negate_range; 94669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban Char c, k; 94769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 94869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban _DIAGASSERT(name != NULL); 94969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban _DIAGASSERT(pat != NULL); 95069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban _DIAGASSERT(patend != NULL); 95169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 95269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban while (pat < patend) { 95369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban c = *pat++; 95469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban switch (c & M_MASK) { 95569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban case M_ALL: 95669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban while (pat < patend && (*pat & M_MASK) == M_ALL) 95769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban pat++; /* eat consecutive '*' */ 95869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if (pat == patend) 95969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban return 1; 96069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban for (; !match(name, pat, patend); name++) 96169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if (*name == EOS) 96269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban return 0; 96369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban return 1; 96469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban case M_ONE: 96569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if (*name++ == EOS) 96669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban return 0; 96769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban break; 96869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban case M_SET: 96969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban ok = 0; 97069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if ((k = *name++) == EOS) 97169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban return 0; 97269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if ((negate_range = ((*pat & M_MASK) == M_NOT)) != EOS) 97369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban ++pat; 97469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban while (((c = *pat++) & M_MASK) != M_END) 97569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if ((*pat & M_MASK) == M_RNG) { 97669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if (c <= k && k <= pat[1]) 97769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban ok = 1; 97869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban pat += 2; 97969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban } else if (c == k) 98069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban ok = 1; 98169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if (ok == negate_range) 98269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban return 0; 98369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban break; 98469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban default: 98569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if (*name++ != c) 98669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban return 0; 98769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban break; 98869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban } 98969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban } 99069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban return *name == EOS; 99169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban} 99269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 99369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban/* Free allocated data belonging to a glob_t structure. */ 99469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serbanvoid 99569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serbanglobfree(glob_t *pglob) 99669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban{ 99769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban size_t i; 99869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban char **pp; 99969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 100069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban _DIAGASSERT(pglob != NULL); 100169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 100269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if (pglob->gl_pathv != NULL) { 100369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban pp = pglob->gl_pathv + pglob->gl_offs; 100469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban for (i = pglob->gl_pathc; i--; ++pp) 100569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if (*pp) 100669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban free(*pp); 100769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban free(pglob->gl_pathv); 100869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban pglob->gl_pathv = NULL; 100969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban pglob->gl_pathc = 0; 101069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban } 101169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban} 101269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 101369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#ifndef __LIBC12_SOURCE__ 101469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serbanint 101569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serbanglob_pattern_p(const char *pattern, int quote) 101669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban{ 101769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban int range = 0; 101869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 101969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban for (; *pattern; pattern++) 102069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban switch (*pattern) { 102169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban case QUESTION: 102269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban case STAR: 102369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban return 1; 102469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 102569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban case QUOTE: 102669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if (quote && pattern[1] != EOS) 102769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban ++pattern; 102869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban break; 102969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 103069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban case LBRACKET: 103169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban range = 1; 103269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban break; 103369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 103469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban case RBRACKET: 103569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if (range) 103669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban return 1; 103769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban break; 103869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban default: 103969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban break; 104069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban } 104169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 104269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban return 0; 104369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban} 104469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#endif 104569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 104669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serbanstatic DIR * 104769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serbang_opendir(Char *str, glob_t *pglob) 104869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban{ 104969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban char buf[MAXPATHLEN]; 105069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 105169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban _DIAGASSERT(str != NULL); 105269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban _DIAGASSERT(pglob != NULL); 105369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 105469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if (!*str) 105569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban (void)strlcpy(buf, ".", sizeof(buf)); 105669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban else { 105769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if (g_Ctoc(str, buf, sizeof(buf))) 105869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban return NULL; 105969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban } 106069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 106169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if (pglob->gl_flags & GLOB_ALTDIRFUNC) 106269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban return (*pglob->gl_opendir)(buf); 106369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 106469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban return opendir(buf); 106569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban} 106669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 106769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serbanstatic int 106869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serbang_lstat(Char *fn, __gl_stat_t *sb, glob_t *pglob) 106969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban{ 107069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban char buf[MAXPATHLEN]; 107169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 107269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban _DIAGASSERT(fn != NULL); 107369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban _DIAGASSERT(sb != NULL); 107469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban _DIAGASSERT(pglob != NULL); 107569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 107669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if (g_Ctoc(fn, buf, sizeof(buf))) 107769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban return -1; 107869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if (pglob->gl_flags & GLOB_ALTDIRFUNC) 107969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban return (*pglob->gl_lstat)(buf, sb); 108069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban return lstat(buf, sb); 108169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban} 108269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 108369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serbanstatic int 108469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serbang_stat(Char *fn, __gl_stat_t *sb, glob_t *pglob) 108569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban{ 108669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban char buf[MAXPATHLEN]; 108769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 108869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban _DIAGASSERT(fn != NULL); 108969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban _DIAGASSERT(sb != NULL); 109069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban _DIAGASSERT(pglob != NULL); 109169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 109269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if (g_Ctoc(fn, buf, sizeof(buf))) 109369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban return -1; 109469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if (pglob->gl_flags & GLOB_ALTDIRFUNC) 109569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban return (*pglob->gl_stat)(buf, sb); 109669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban return stat(buf, sb); 109769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban} 109869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 109969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serbanstatic Char * 110069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serbang_strchr(const Char *str, int ch) 110169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban{ 110269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 110369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban _DIAGASSERT(str != NULL); 110469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 110569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban do { 110669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if (*str == ch) 110769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban return __UNCONST(str); 110869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban } while (*str++); 110969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban return NULL; 111069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban} 111169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 111269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serbanstatic int 111369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serbang_Ctoc(const Char *str, char *buf, size_t len) 111469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban{ 111569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban char *dc; 111669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 111769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban _DIAGASSERT(str != NULL); 111869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban _DIAGASSERT(buf != NULL); 111969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 112069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban if (len == 0) 112169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban return 1; 112269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 112369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban for (dc = buf; len && (*dc++ = *str++) != EOS; len--) 112469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban continue; 112569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 112669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban return len == 0; 112769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban} 112869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 112969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#ifdef DEBUG 113069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serbanstatic void 113169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serbanqprintf(const char *str, Char *s) 113269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban{ 113369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban Char *p; 113469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 113569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban _DIAGASSERT(str != NULL); 113669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban _DIAGASSERT(s != NULL); 113769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban 113869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban (void)printf("%s:\n", str); 113969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban for (p = s; *p; p++) 114069c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban (void)printf("%c", CHAR(*p)); 114169c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban (void)printf("\n"); 114269c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban for (p = s; *p; p++) 114369c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban (void)printf("%c", *p & M_PROTECT ? '"' : ' '); 114469c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban (void)printf("\n"); 114569c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban for (p = s; *p; p++) 114669c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban (void)printf("%c", ismeta(*p) ? '_' : ' '); 114769c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban (void)printf("\n"); 114869c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban} 114969c7a112c52c68b9b4654b94789505e7098c1fe7Mihai Serban#endif 1150