diff options
Diffstat (limited to 'contrib/opie/glob.c')
-rw-r--r-- | contrib/opie/glob.c | 668 |
1 files changed, 0 insertions, 668 deletions
diff --git a/contrib/opie/glob.c b/contrib/opie/glob.c deleted file mode 100644 index 8cbe7790e1a25..0000000000000 --- a/contrib/opie/glob.c +++ /dev/null @@ -1,668 +0,0 @@ -/* glob.c: The csh et al glob pattern matching routines. - -%%% copyright-cmetz-96 -This software is Copyright 1996-1998 by Craig Metz, All Rights Reserved. -The Inner Net License Version 2 applies to this software. -You should have received a copy of the license with this software. If -you didn't get a copy, you may request one from <license@inner.net>. - -Portions of this software are Copyright 1995 by Randall Atkinson and Dan -McDonald, All Rights Reserved. All Rights under this copyright are assigned -to the U.S. Naval Research Laboratory (NRL). The NRL Copyright Notice and -License Agreement applies to this software. - - History: - - Modified by cmetz for OPIE 2.32. Remove include of dirent.h here; it's - done already (and conditionally) in opie_cfg.h. - Modified by cmetz for OPIE 2.2. Use FUNCTION declaration et al. - Remove useless strings. Prototype right. - Modified at NRL for OPIE 2.0. - Originally from BSD. -*/ -/* - * Copyright (c) 1980 Regents of the University of California. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * C-shell glob for random programs. - */ - -#include "opie_cfg.h" - -#if HAVE_SYS_PARAM_H -#include <sys/param.h> -#endif /* HAVE_SYS_PARAM_H */ -#include <sys/stat.h> - -#if HAVE_PWD_H -#include <pwd.h> -#endif /* HAVE_PWD_H */ -#include <errno.h> -#include <stdio.h> -#include <string.h> -#if HAVE_LIMITS_H -#include <limits.h> -#endif /* HAVE_LIMITS_H */ - -#include "opie.h" - -#ifndef NCARGS -#define NCARGS 600 -#endif /* NCARGS */ -#define QUOTE 0200 -#define TRIM 0177 -#define eq(a,b) (strcmp((a),(b)) == (0)) -#define GAVSIZ (NCARGS/6) -#define isdir(d) (((d.st_mode) & S_IFMT) == S_IFDIR) - -static char **gargv; /* Pointer to the (stack) arglist */ -static int gargc; /* Number args in gargv */ -static int gnleft; -static short gflag; - -static int letter __P((register char)); -static int digit __P((register char)); -static int any __P((int, char *)); -static int blklen __P((register char **)); -VOIDRET blkfree __P((char **)); -static char *strspl __P((register char *, register char *)); - -static int tglob __P((register char c)); - -extern int errno; -static char *strend __P((char *)); - -static int globcnt; - -static char *globchars = "`{[*?"; -char *globerr = NULL; -char *home = NULL; - -static char *gpath, *gpathp, *lastgpathp; -static int globbed; -static char *entp; -static char **sortbas; - -static int amatch __P((char *p, char *s)); -static int execbrc __P((register char *p, register char *s)); -VOIDRET opiefatal __P((char *)); -char **copyblk __P((char **)); - -static int match FUNCTION((s, p), char *s AND char *p) -{ - register int c; - register char *sentp; - char sglobbed = globbed; - - if (*s == '.' && *p != '.') - return (0); - sentp = entp; - entp = s; - c = amatch(s, p); - entp = sentp; - globbed = sglobbed; - return (c); -} - - -static int Gmatch FUNCTION((s, p), register char *s AND register char *p) -{ - register int scc; - int ok, lc; - int c, cc; - - for (;;) { - scc = *s++ & TRIM; - switch (c = *p++) { - - case '[': - ok = 0; - lc = 077777; - while (cc = *p++) { - if (cc == ']') { - if (ok) - break; - return (0); - } - if (cc == '-') { - if (lc <= scc && scc <= *p++) - ok++; - } else - if (scc == (lc = cc)) - ok++; - } - if (cc == 0) - if (ok) - p--; - else - return 0; - continue; - - case '*': - if (!*p) - return (1); - for (s--; *s; s++) - if (Gmatch(s, p)) - return (1); - return (0); - - case 0: - return (scc == 0); - - default: - if ((c & TRIM) != scc) - return (0); - continue; - - case '?': - if (scc == 0) - return (0); - continue; - - } - } -} - -static VOIDRET Gcat FUNCTION((s1, s2), register char *s1 AND register char *s2) -{ - register int len = strlen(s1) + strlen(s2) + 1; - - if (len >= gnleft || gargc >= GAVSIZ - 1) - globerr = "Arguments too long"; - else { - gargc++; - gnleft -= len; - gargv[gargc] = 0; - gargv[gargc - 1] = strspl(s1, s2); - } -} - -static VOIDRET addpath FUNCTION((c), char c) -{ - - if (gpathp >= lastgpathp) - globerr = "Pathname too long"; - else { - *gpathp++ = c; - *gpathp = 0; - } -} - -static VOIDRET rscan FUNCTION((t, f), register char **t AND int (*f)__P((char))) -{ - register char *p, c; - - while (p = *t++) { - if (f == tglob) - if (*p == '~') - gflag |= 2; - else - if (eq(p, "{") || eq(p, "{}")) - continue; - while (c = *p++) - (*f) (c); - } -} - -static int tglob FUNCTION((c), register char c) -{ - if (any(c, globchars)) - gflag |= c == '{' ? 2 : 1; - return (c); -} - -static int letter FUNCTION((c), register char c) -{ - return (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c == '_'); -} - -static int digit FUNCTION((c), register char c) -{ - return (c >= '0' && c <= '9'); -} - -static int any FUNCTION((c, s), int c AND char *s) -{ - while (*s) - if (*s++ == c) - return (1); - return (0); -} - -static int blklen FUNCTION((av), register char **av) -{ - register int i = 0; - - while (*av++) - i++; - return (i); -} - -static char **blkcpy FUNCTION((oav, bv), char **oav AND register char **bv) -{ - register char **av = oav; - - while (*av++ = *bv++) - continue; - return (oav); -} - -VOIDRET blkfree FUNCTION((av0), char **av0) -{ - register char **av = av0; - - while (*av) - free(*av++); -} - -static char *strspl FUNCTION((cp, dp), register char *cp AND register char *dp) -{ - register char *ep = (char *) malloc((unsigned) (strlen(cp) + - strlen(dp) + 1)); - - if (ep == (char *) 0) - opiefatal("Out of memory"); - strcpy(ep, cp); - strcat(ep, dp); - return (ep); -} - -char **copyblk FUNCTION((v), char **v) -{ - register char **nv = (char **) malloc((unsigned) ((blklen(v) + 1) * - sizeof(char **))); - - if (nv == (char **) 0) - opiefatal("Out of memory"); - - return (blkcpy(nv, v)); -} - -static char *strend FUNCTION((cp), register char *cp) -{ - - while (*cp) - cp++; - return (cp); -} - -/* - * Extract a home directory from the password file - * The argument points to a buffer where the name of the - * user whose home directory is sought is currently. - * We write the home directory of the user back there. - */ -static int gethdir FUNCTION((home), char *home) -{ - register struct passwd *pp = getpwnam(home); - - if (!pp || home + strlen(pp->pw_dir) >= lastgpathp) - return (1); - strcpy(home, pp->pw_dir); - return (0); -} - -static VOIDRET ginit FUNCTION((agargv), char **agargv) -{ - agargv[0] = 0; - gargv = agargv; - sortbas = agargv; - gargc = 0; - gnleft = NCARGS - 4; -} - -static VOIDRET sort FUNCTION_NOARGS -{ - register char **p1, **p2, *c; - char **Gvp = &gargv[gargc]; - - p1 = sortbas; - while (p1 < Gvp - 1) { - p2 = p1; - while (++p2 < Gvp) - if (strcmp(*p1, *p2) > 0) - c = *p1, *p1 = *p2, *p2 = c; - p1++; - } - sortbas = Gvp; -} - -static VOIDRET matchdir FUNCTION((pattern), char *pattern) -{ - struct stat stb; - - register struct dirent *dp; - - DIR *dirp; - - dirp = opendir(*gpath == '\0' ? "." : gpath); - if (dirp == NULL) { - if (globbed) - return; - goto patherr2; - } -#if !defined(linux) - if (fstat(dirp->dd_fd, &stb) < 0) - goto patherr1; - if (!isdir(stb)) { - errno = ENOTDIR; - goto patherr1; - } -#endif /* !defined(linux) */ - while ((dp = readdir(dirp)) != NULL) { - if (dp->d_ino == 0) - continue; - if (match(dp->d_name, pattern)) { - Gcat(gpath, dp->d_name); - globcnt++; - } - } - closedir(dirp); - return; - -patherr1: - closedir(dirp); -patherr2: - globerr = "Bad directory components"; -} - -static VOIDRET expand FUNCTION((as), char *as) -{ - register char *cs; - register char *sgpathp, *oldcs; - struct stat stb; - - sgpathp = gpathp; - cs = as; - if (*cs == '~' && gpathp == gpath) { - addpath('~'); - for (cs++; letter(*cs) || digit(*cs) || *cs == '-';) - addpath(*cs++); - if (!*cs || *cs == '/') { - if (gpathp != gpath + 1) { - *gpathp = 0; - if (gethdir(gpath + 1)) - globerr = "Unknown user name after ~"; - strcpy(gpath, gpath + 1); - } else - strcpy(gpath, home); - gpathp = strend(gpath); - } - } - while (!any(*cs, globchars)) { - if (*cs == 0) { - if (!globbed) - Gcat(gpath, ""); - else - if (stat(gpath, &stb) >= 0) { - Gcat(gpath, ""); - globcnt++; - } - goto endit; - } - addpath(*cs++); - } - oldcs = cs; - while (cs > as && *cs != '/') - cs--, gpathp--; - if (*cs == '/') - cs++, gpathp++; - *gpathp = 0; - if (*oldcs == '{') { - execbrc(cs, ((char *) 0)); - return; - } - matchdir(cs); -endit: - gpathp = sgpathp; - *gpathp = 0; -} - -static int execbrc FUNCTION((p, s), char *p AND char *s) -{ - char restbuf[BUFSIZ + 2]; - register char *pe, *pm, *pl; - int brclev = 0; - char *lm, savec, *sgpathp; - - for (lm = restbuf; *p != '{'; *lm++ = *p++) - continue; - for (pe = ++p; *pe; pe++) - switch (*pe) { - - case '{': - brclev++; - continue; - - case '}': - if (brclev == 0) - goto pend; - brclev--; - continue; - - case '[': - for (pe++; *pe && *pe != ']'; pe++) - continue; - continue; - } -pend: - brclev = 0; - for (pl = pm = p; pm <= pe; pm++) - switch (*pm & (QUOTE | TRIM)) { - - case '{': - brclev++; - continue; - - case '}': - if (brclev) { - brclev--; - continue; - } - goto doit; - - case ',' | QUOTE: - case ',': - if (brclev) - continue; - doit: - savec = *pm; - *pm = 0; - strcpy(lm, pl); - strcat(restbuf, pe + 1); - *pm = savec; - if (s == 0) { - sgpathp = gpathp; - expand(restbuf); - gpathp = sgpathp; - *gpathp = 0; - } else - if (amatch(s, restbuf)) - return (1); - sort(); - pl = pm + 1; - if (brclev) - return (0); - continue; - - case '[': - for (pm++; *pm && *pm != ']'; pm++) - continue; - if (!*pm) - pm--; - continue; - } - if (brclev) - goto doit; - return (0); -} - -static VOIDRET acollect FUNCTION((as), register char *as) -{ - register int ogargc = gargc; - - gpathp = gpath; - *gpathp = 0; - globbed = 0; - expand(as); - if (gargc != ogargc) - sort(); -} - -static VOIDRET collect FUNCTION((as), register char *as) -{ - if (eq(as, "{") || eq(as, "{}")) { - Gcat(as, ""); - sort(); - } else - acollect(as); -} - -static int amatch FUNCTION((s, p), register char *s AND register char *p) -{ - register int scc; - int ok, lc; - char *sgpathp; - struct stat stb; - int c, cc; - - globbed = 1; - for (;;) { - scc = *s++ & TRIM; - switch (c = *p++) { - - case '{': - return (execbrc(p - 1, s - 1)); - - case '[': - ok = 0; - lc = 077777; - while (cc = *p++) { - if (cc == ']') { - if (ok) - break; - return (0); - } - if (cc == '-') { - if (lc <= scc && scc <= *p++) - ok++; - } else - if (scc == (lc = cc)) - ok++; - } - if (cc == 0) - if (ok) - p--; - else - return 0; - continue; - - case '*': - if (!*p) - return (1); - if (*p == '/') { - p++; - goto slash; - } - s--; - do { - if (amatch(s, p)) - return (1); - } - while (*s++); - return (0); - - case 0: - return (scc == 0); - - default: - if (c != scc) - return (0); - continue; - - case '?': - if (scc == 0) - return (0); - continue; - - case '/': - if (scc) - return (0); - slash: - s = entp; - sgpathp = gpathp; - while (*s) - addpath(*s++); - addpath('/'); - if (stat(gpath, &stb) == 0 && isdir(stb)) - if (*p == 0) { - Gcat(gpath, ""); - globcnt++; - } else - expand(p); - gpathp = sgpathp; - *gpathp = 0; - return (0); - } - } -} - - -char **ftpglob FUNCTION((v), register char *v) -{ - char agpath[BUFSIZ]; - char *agargv[GAVSIZ]; - char *vv[2]; - - vv[0] = v; - vv[1] = 0; - gflag = 0; - rscan(vv, tglob); - if (gflag == 0) { - vv[0] = strspl(v, ""); - return (copyblk(vv)); - } - globerr = 0; - gpath = agpath; - gpathp = gpath; - *gpathp = 0; - lastgpathp = &gpath[sizeof agpath - 2]; - ginit(agargv); - globcnt = 0; - collect(v); - if (globcnt == 0 && (gflag & 1)) { - blkfree(gargv), gargv = 0; - return (0); - } else - return (gargv = copyblk(gargv)); -} |