diff options
Diffstat (limited to 'usr.bin/rdist/expand.c')
| -rw-r--r-- | usr.bin/rdist/expand.c | 677 |
1 files changed, 0 insertions, 677 deletions
diff --git a/usr.bin/rdist/expand.c b/usr.bin/rdist/expand.c deleted file mode 100644 index d5f7ed4fd8a5..000000000000 --- a/usr.bin/rdist/expand.c +++ /dev/null @@ -1,677 +0,0 @@ -/* - * Copyright (c) 1983, 1993 - * The 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. - */ - -#ifndef lint -#if 0 -static char sccsid[] = "@(#)expand.c 8.1 (Berkeley) 6/9/93"; -#endif -static const char rcsid[] = - "$FreeBSD$"; -#endif /* not lint */ - -#include "defs.h" - -#define GAVSIZ NCARGS / 6 -#define LC '{' -#define RC '}' - -static char shchars[] = "${[*?"; - -int which; /* bit mask of types to expand */ -int eargc; /* expanded arg count */ -char **eargv; /* expanded arg vectors */ -char *path; -char *pathp; -char *lastpathp; -char *tilde; /* "~user" if not expanding tilde, else "" */ -char *tpathp; -int nleft; - -int expany; /* any expansions done? */ -char *entp; -char **sortbase; - -#define sort() qsort((char *)sortbase, &eargv[eargc] - sortbase, \ - sizeof(*sortbase), argcmp), sortbase = &eargv[eargc] - -static void Cat __P((char *, char *)); -static void addpath __P((int)); -static int amatch __P((char *, char *)); -static int argcmp __P((const void *, const void *)); -static int execbrc __P((char *, char *)); -static void expsh __P((char *)); -static void expstr __P((char *)); -static int match __P((char *, char *)); -static void matchdir __P((char *)); -static int smatch __P((char *, char *)); - -/* - * Take a list of names and expand any macros, etc. - * wh = E_VARS if expanding variables. - * wh = E_SHELL if expanding shell characters. - * wh = E_TILDE if expanding `~'. - * or any of these or'ed together. - * - * Major portions of this were snarfed from csh/sh.glob.c. - */ -struct namelist * -expand(list, wh) - struct namelist *list; - int wh; -{ - register struct namelist *nl, *prev; - register int n; - char pathbuf[BUFSIZ]; - char *argvbuf[GAVSIZ]; - - if (debug) { - printf("expand(%p, %d)\nlist = ", list, wh); - prnames(list); - } - - if (wh == 0) { - register char *cp; - - for (nl = list; nl != NULL; nl = nl->n_next) - for (cp = nl->n_name; *cp; cp++) - *cp = *cp & TRIM; - return(list); - } - - which = wh; - path = tpathp = pathp = pathbuf; - *pathp = '\0'; - lastpathp = &path[sizeof pathbuf - 2]; - tilde = ""; - eargc = 0; - eargv = sortbase = argvbuf; - *eargv = 0; - nleft = NCARGS - 4; - /* - * Walk the name list and expand names into eargv[]; - */ - for (nl = list; nl != NULL; nl = nl->n_next) - expstr(nl->n_name); - /* - * Take expanded list of names from eargv[] and build a new list. - */ - list = prev = NULL; - for (n = 0; n < eargc; n++) { - nl = makenl(NULL); - nl->n_name = eargv[n]; - if (prev == NULL) - list = prev = nl; - else { - prev->n_next = nl; - prev = nl; - } - } - if (debug) { - printf("expanded list = "); - prnames(list); - } - return(list); -} - -static void -expstr(s) - char *s; -{ - register char *cp, *cp1; - register struct namelist *tp; - char *tail; - char buf[BUFSIZ]; - int savec, oeargc; - extern char homedir[]; - - if (s == NULL || *s == '\0') - return; - - if ((which & E_VARS) && (cp = index(s, '$')) != NULL) { - *cp++ = '\0'; - if (*cp == '\0') { - yyerror("no variable name after '$'"); - return; - } - if (*cp == LC) { - cp++; - if ((tail = index(cp, RC)) == NULL) { - yyerror("unmatched '{'"); - return; - } - *tail++ = savec = '\0'; - if (*cp == '\0') { - yyerror("no variable name after '$'"); - return; - } - } else { - tail = cp + 1; - savec = *tail; - *tail = '\0'; - } - tp = lookup(cp, NULL, 0); - if (savec != '\0') - *tail = savec; - if (tp != NULL) { - for (; tp != NULL; tp = tp->n_next) { - snprintf(buf, sizeof(buf), - "%s%s%s", s, tp->n_name, tail); - expstr(buf); - } - return; - } - snprintf(buf, sizeof(buf), "%s%s", s, tail); - expstr(buf); - return; - } - if ((which & ~E_VARS) == 0 || !strcmp(s, "{") || !strcmp(s, "{}")) { - Cat(s, ""); - sort(); - return; - } - if (*s == '~') { - cp = ++s; - if (*cp == '\0' || *cp == '/') { - tilde = "~"; - cp1 = homedir; - } else { - tilde = cp1 = buf; - *cp1++ = '~'; - do - *cp1++ = *cp++; - while (*cp && *cp != '/'); - *cp1 = '\0'; - if (pw == NULL || strcmp(pw->pw_name, buf+1) != 0) { - if ((pw = getpwnam(buf+1)) == NULL) { - strcat(buf, ": unknown user name"); - yyerror(buf+1); - return; - } - } - cp1 = pw->pw_dir; - s = cp; - } - for (cp = path; (*cp++ = *cp1++); ) - ; - tpathp = pathp = cp - 1; - } else { - tpathp = pathp = path; - tilde = ""; - } - *pathp = '\0'; - if (!(which & E_SHELL)) { - if (which & E_TILDE) - Cat(path, s); - else - Cat(tilde, s); - sort(); - return; - } - oeargc = eargc; - expany = 0; - expsh(s); - if (eargc == oeargc) - Cat(s, ""); /* "nonomatch" is set */ - sort(); -} - -static int -argcmp(a1, a2) - const void *a1, *a2; -{ - - return (strcmp(*(char **)a1, *(char **)a2)); -} - -/* - * If there are any Shell meta characters in the name, - * expand into a list, after searching directory - */ -static void -expsh(s) - char *s; -{ - register char *cp; - register char *spathp, *oldcp; - struct stat stb; - - spathp = pathp; - cp = s; - while (!any(*cp, shchars)) { - if (*cp == '\0') { - if (!expany || stat(path, &stb) >= 0) { - if (which & E_TILDE) - Cat(path, ""); - else - Cat(tilde, tpathp); - } - goto endit; - } - addpath(*cp++); - } - oldcp = cp; - while (cp > s && *cp != '/') - cp--, pathp--; - if (*cp == '/') - cp++, pathp++; - *pathp = '\0'; - if (*oldcp == '{') { - execbrc(cp, NULL); - return; - } - matchdir(cp); -endit: - pathp = spathp; - *pathp = '\0'; -} - -static void -matchdir(pattern) - char *pattern; -{ - struct stat stb; - register struct dirent *dp; - DIR *dirp; - - dirp = opendir(path); - if (dirp == NULL) { - if (expany) - return; - goto patherr2; - } - if (fstat(dirp->dd_fd, &stb) < 0) - goto patherr1; - if (!ISDIR(stb.st_mode)) { - errno = ENOTDIR; - goto patherr1; - } - while ((dp = readdir(dirp)) != NULL) - if (match(dp->d_name, pattern)) { - if (which & E_TILDE) - Cat(path, dp->d_name); - else { - strcpy(pathp, dp->d_name); - Cat(tilde, tpathp); - *pathp = '\0'; - } - } - closedir(dirp); - return; - -patherr1: - closedir(dirp); -patherr2: - strcat(path, ": "); - strcat(path, strerror(errno)); - yyerror(path); -} - -static int -execbrc(p, s) - char *p, *s; -{ - char restbuf[BUFSIZ + 2]; - register char *pe, *pm, *pl; - int brclev = 0; - char *lm, savec, *spathp; - - 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; - if (!*pe) - yyerror("Missing ']'"); - continue; - } -pend: - if (brclev || !*pe) { - yyerror("Missing '}'"); - return (0); - } - for (pl = pm = p; pm <= pe; pm++) - switch (*pm & (QUOTE|TRIM)) { - - case '{': - brclev++; - continue; - - case '}': - if (brclev) { - brclev--; - continue; - } - goto doit; - - case ',': - if (brclev) - continue; -doit: - savec = *pm; - *pm = 0; - strcpy(lm, pl); - strcat(restbuf, pe + 1); - *pm = savec; - if (s == 0) { - spathp = pathp; - expsh(restbuf); - pathp = spathp; - *pathp = 0; - } else if (amatch(s, restbuf)) - return (1); - sort(); - pl = pm + 1; - continue; - - case '[': - for (pm++; *pm && *pm != ']'; pm++) - continue; - if (!*pm) - yyerror("Missing ']'"); - continue; - } - return (0); -} - -static int -match(s, p) - char *s, *p; -{ - register int c; - register char *sentp; - char sexpany = expany; - - if (*s == '.' && *p != '.') - return (0); - sentp = entp; - entp = s; - c = amatch(s, p); - entp = sentp; - expany = sexpany; - return (c); -} - -static int -amatch(s, p) - register char *s, *p; -{ - register int scc; - int ok, lc; - char *spathp; - struct stat stb; - int c, cc; - - expany = 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) { - yyerror("Missing ']'"); - return (0); - } - continue; - - case '*': - if (!*p) - return (1); - if (*p == '/') { - p++; - goto slash; - } - for (s--; *s; s++) - if (amatch(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; - - case '/': - if (scc) - return (0); -slash: - s = entp; - spathp = pathp; - while (*s) - addpath(*s++); - addpath('/'); - if (stat(path, &stb) == 0 && ISDIR(stb.st_mode)) { - if (*p == '\0') { - if (which & E_TILDE) - Cat(path, ""); - else - Cat(tilde, tpathp); - } else - expsh(p); - } - pathp = spathp; - *pathp = '\0'; - return (0); - } - } -} - -static int -smatch(s, p) - register char *s, *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) { - yyerror("Missing ']'"); - return (0); - } - continue; - - case '*': - if (!*p) - return (1); - for (s--; *s; s++) - if (smatch(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 void -Cat(s1, s2) - register char *s1, *s2; -{ - int len = strlen(s1) + strlen(s2) + 1; - register char *s; - - nleft -= len; - if (nleft <= 0 || ++eargc >= GAVSIZ) - yyerror("Arguments too long"); - eargv[eargc] = 0; - eargv[eargc - 1] = s = malloc(len); - if (s == NULL) - fatal("ran out of memory\n"); - while ((*s++ = *s1++ & TRIM)) - ; - s--; - while ((*s++ = *s2++ & TRIM)) - ; -} - -static void -addpath(c) - int c; -{ - - if (pathp >= lastpathp) - yyerror("Pathname too long"); - else { - *pathp++ = c & TRIM; - *pathp = '\0'; - } -} - -/* - * Expand file names beginning with `~' into the - * user's home directory path name. Return a pointer in buf to the - * part corresponding to `file'. - */ -char * -exptilde(buf, file, maxlen) - char buf[]; - register char *file; - int maxlen; -{ - register char *s1, *s2, *s3; - extern char homedir[]; - - if (strlen(file) >= maxlen) - return(NULL); - if (*file != '~') { - strcpy(buf, file); - return(buf); - } - if (*++file == '\0') { - s2 = homedir; - s3 = NULL; - } else if (*file == '/') { - s2 = homedir; - s3 = file; - } else { - s3 = file; - while (*s3 && *s3 != '/') - s3++; - if (*s3 == '/') - *s3 = '\0'; - else - s3 = NULL; - if (pw == NULL || strcmp(pw->pw_name, file) != 0) { - if ((pw = getpwnam(file)) == NULL) { - error("%s: unknown user name\n", file); - if (s3 != NULL) - *s3 = '/'; - return(NULL); - } - } - if (s3 != NULL) - *s3 = '/'; - s2 = pw->pw_dir; - } - for (s1 = buf; (*s1++ = *s2++) && s1 < buf+maxlen; ) - ; - s2 = --s1; - if (s3 != NULL && s1 < buf+maxlen) { - s2++; - while ((*s1++ = *s3++) && s1 < buf+maxlen) - ; - } - if (s1 == buf+maxlen) - return(NULL); - return(s2); -} |
