home *** CD-ROM | disk | FTP | other *** search
- #
- /* 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);
- }
-