/*- * Copyright (C) Caldera International Inc. 2001-2002. 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 and documentation 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 or owned by Caldera * International, Inc. * 4. Neither the name of Caldera International, Inc. nor the names of other * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA * INTERNATIONAL, INC. 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 CALDERA INTERNATIONAL, INC. 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. */ # /* global command -- glob params "*" in params matches r.e ".*" "?" in params matches r.e. "." "[...]" in params matches character class "[...a-z...]" in params matches a through z. perform command with argument list constructed as follows: if param does not contain "*", "[", or "?", use it as is if it does, find all files in current directory which match the param, sort them, and use them prepend the command name with "/bin" or "/usr/bin" as required. */ #define E2BIG 7 #define ENOEXEC 8 #define ENOENT 2 #define STRSIZ 522 char ab[STRSIZ]; /* generated characters */ char *ava[200]; /* generated arguments */ char **av &ava[1]; char *string ab; int errno; int ncoll; main(argc, argv) char *argv[]; { register char *cp; if (argc < 3) { write(2, "Arg count\n", 10); return; } argv++; *av++ = *argv; while (--argc >= 2) expand(*++argv); if (ncoll==0) { write(2, "No match\n", 9); return; } execute(ava[1], &ava[1]); cp = cat("/usr/bin/", ava[1]); execute(cp+4, &ava[1]); execute(cp, &ava[1]); write(2, "Command not found.\n", 19); } expand(as) char *as; { register char *s, *cs; register int dirf; char **oav; static struct { int ino; char name[16]; } entry; s = cs = as; while (*cs!='*' && *cs!='?' && *cs!='[') { if (*cs++ == 0) { *av++ = cat(s, ""); return; } } for (;;) { if (cs==s) { dirf = open(".", 0); s = ""; break; } if (*--cs == '/') { *cs = 0; dirf = open(s==cs? "/": s, 0); *cs++ = 0200; break; } } if (dirf<0) { write(2, "No directory\n", 13); exit(); } oav = av; while (read(dirf, &entry, 16) == 16) { if (entry.ino==0) continue; if (match(entry.name, cs)) { *av++ = cat(s, entry.name); ncoll++; } } close(dirf); sort(oav); } sort(oav) char **oav; { register char **p1, **p2, **c; p1 = oav; while (p1 < av-1) { p2 = p1; while(++p2 < av) { if (compar(*p1, *p2) > 0) { c = *p1; *p1 = *p2; *p2 = c; } } p1++; } } execute(afile, aarg) char *afile; char **aarg; { register char *file, **arg; arg = aarg; file = afile; execv(file, arg); if (errno==ENOEXEC) { arg[0] = file; *--arg = "/bin/sh"; execv(*arg, arg); } if (errno==E2BIG) toolong(); } toolong() { write(2, "Arg list too long\n", 18); exit(); } match(s, p) char *s, *p; { if (*s=='.' && *p!='.') return(0); return(amatch(s, p)); } amatch(as, ap) char *as, *ap; { register char *s, *p; register scc; int c, cc, ok, lc; s = as; p = ap; if (scc = *s++) if ((scc =& 0177) == 0) scc = 0200; switch (c = *p++) { case '[': ok = 0; lc = 077777; while (cc = *p++) { if (cc==']') { if (ok) return(amatch(s, p)); else return(0); } else if (cc=='-') { if (lc<=scc && scc<=(c = *p++)) ok++; } else if (scc == (lc=cc)) ok++; } return(0); default: if (c!=scc) return(0); case '?': if (scc) return(amatch(s, p)); return(0); case '*': return(umatch(--s, p)); case '\0': return(!scc); } } umatch(s, p) char *s, *p; { if(*p==0) return(1); while(*s) if (amatch(s++,p)) return(1); return(0); } compar(as1, as2) char *as1, *as2; { register char *s1, *s2; s1 = as1; s2 = as2; while (*s1++ == *s2) if (*s2++ == 0) return(0); return (*--s1 - *s2); } cat(as1, as2) char *as1, *as2; { register char *s1, *s2; register int c; s2 = string; s1 = as1; while (c = *s1++) { if (s2 > &ab[STRSIZ]) toolong(); c =& 0177; if (c==0) { *s2++ = '/'; break; } *s2++ = c; } s1 = as2; do { if (s2 > &ab[STRSIZ]) toolong(); *s2++ = c = *s1++; } while (c); s1 = string; string = s2; return(s1); }