Add original unix v6
This commit is contained in:
@@ -0,0 +1,256 @@
|
||||
#
|
||||
/* 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);
|
||||
}
|
||||
Reference in New Issue
Block a user