⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sh.c

📁 Version 6 Unix 核心源代码 Version 6 Unix 核心源代码
💻 C
字号:
#/* */#define	INTR	2#define	QUIT	3#define LINSIZ 1000#define ARGSIZ 50#define TRESIZ 100#define QUOTE 0200#define FAND 1#define FCAT 2#define FPIN 4#define FPOU 8#define FPAR 16#define FINT 32#define FPRS 64#define TCOM 1#define TPAR 2#define TFIL 3#define TLST 4#define DTYP 0#define DLEF 1#define DRIT 2#define DFLG 3#define DSPR 4#define DCOM 5#define	ENOMEM	12#define	ENOEXEC 8char	*dolp;char	pidp[6];int	ldivr;char	**dolv;int	dolc;char	*promp;char	*linep;char	*elinep;char	**argp;char	**eargp;int	*treep;int	*treeend;char	peekc;char	gflg;char	error;char	acctf;char	uid;char	setintr;char	*arginp;int	onelflg;char	*mesg[] {	0,	"Hangup",	0,	"Quit",	"Illegal instruction",	"Trace/BPT trap",	"IOT trap",	"EMT trap",	"Floating exception",	"Killed",	"Bus error",	"Memory fault",	"Bad system call",	0,	"Sig 14",	"Sig 15",	"Sig 16",	"Sig 17",	"Sig 18",	"Sig 19",};struct stime {	int proct[2];	int cputim[2];	int systim[2];} timeb;char	line[LINSIZ];char	*args[ARGSIZ];int	trebuf[TRESIZ];main(c, av)int c;char **av;{	register f;	register char *acname, **v;	for(f=2; f<15; f++)		close(f);	if((f=dup(1)) != 2)		close(f);	dolc = getpid();	for(f=4; f>=0; f--) {		dolc = ldiv(0, dolc, 10);		pidp[f] = ldivr+'0';	}	v = av;	acname = "/usr/adm/sha";	promp = "% ";	if(((uid = getuid())&0377) == 0)		promp = "# ";	acctf = open(acname, 1);	if(c > 1) {		promp = 0;		if (*v[1]=='-') {			**v = '-';			if (v[1][1]=='c' && c>2)				arginp = v[2];			else if (v[1][1]=='t')				onelflg = 2;		} else {			close(0);			f = open(v[1], 0);			if(f < 0) {				prs(v[1]);				err(": cannot open");			}		}	}	if(**v == '-') {		setintr++;		signal(QUIT, 1);		signal(INTR, 1);	}	dolv = v+1;	dolc = c-1;loop:	if(promp != 0)		prs(promp);	peekc = getc();	main1();	goto loop;}main1(){	register char c, *cp;	register *t;	argp = args;	eargp = args+ARGSIZ-5;	linep = line;	elinep = line+LINSIZ-5;	error = 0;	gflg = 0;	do {		cp = linep;		word();	} while(*cp != '\n');	treep = trebuf;	treeend = &trebuf[TRESIZ];	if(gflg == 0) {		if(error == 0) {			setexit();			if (error)				return;			t = syntax(args, argp);		}		if(error != 0)			err("syntax error"); else			execute(t);	}}word(){	register char c, c1;	*argp++ = linep;loop:	switch(c = getc()) {	case ' ':	case '\t':		goto loop;	case '\'':	case '"':		c1 = c;		while((c=readc()) != c1) {			if(c == '\n') {				error++;				peekc = c;				return;			}			*linep++ = c|QUOTE;		}		goto pack;	case '&':	case ';':	case '<':	case '>':	case '(':	case ')':	case '|':	case '^':	case '\n':		*linep++ = c;		*linep++ = '\0';		return;	}	peekc = c;pack:	for(;;) {		c = getc();		if(any(c, " '\"\t;&<>()|^\n")) {			peekc = c;			if(any(c, "\"'"))				goto loop;			*linep++ = '\0';			return;		}		*linep++ = c;	}}tree(n)int n;{	register *t;	t = treep;	treep =+ n;	if (treep>treeend) {		prs("Command line overflow\n");		error++;		reset();	}	return(t);}getc(){	register char c;	if(peekc) {		c = peekc;		peekc = 0;		return(c);	}	if(argp > eargp) {		argp =- 10;		while((c=getc()) != '\n');		argp =+ 10;		err("Too many args");		gflg++;		return(c);	}	if(linep > elinep) {		linep =- 10;		while((c=getc()) != '\n');		linep =+ 10;		err("Too many characters");		gflg++;		return(c);	}getd:	if(dolp) {		c = *dolp++;		if(c != '\0')			return(c);		dolp = 0;	}	c = readc();	if(c == '\\') {		c = readc();		if(c == '\n')			return(' ');		return(c|QUOTE);	}	if(c == '$') {		c = readc();		if(c>='0' && c<='9') {			if(c-'0' < dolc)				dolp = dolv[c-'0'];			goto getd;		}		if(c == '$') {			dolp = pidp;			goto getd;		}	}	return(c&0177);}readc(){	char cc;	register c;	if (arginp) {		if (arginp == 1)			exit();		if ((c = *arginp++) == 0) {			arginp = 1;			c = '\n';		}		return(c);	}	if (onelflg==1)		exit();	if(read(0, &cc, 1) != 1)		exit();	if (cc=='\n' && onelflg)		onelflg--;	return(cc);}/* * syntax *	empty *	syn1 */syntax(p1, p2)char **p1, **p2;{	while(p1 != p2) {		if(any(**p1, ";&\n"))			p1++; else			return(syn1(p1, p2));	}	return(0);}/* * syn1 *	syn2 *	syn2 & syntax *	syn2 ; syntax */syn1(p1, p2)char **p1, **p2;{	register char **p;	register *t, *t1;	int l;	l = 0;	for(p=p1; p!=p2; p++)	switch(**p) {	case '(':		l++;		continue;	case ')':		l--;		if(l < 0)			error++;		continue;	case '&':	case ';':	case '\n':		if(l == 0) {			l = **p;			t = tree(4);			t[DTYP] = TLST;			t[DLEF] = syn2(p1, p);			t[DFLG] = 0;			if(l == '&') {				t1 = t[DLEF];				t1[DFLG] =| FAND|FPRS|FINT;			}			t[DRIT] = syntax(p+1, p2);			return(t);		}	}	if(l == 0)		return(syn2(p1, p2));	error++;}/* * syn2 *	syn3 *	syn3 | syn2 */syn2(p1, p2)char **p1, **p2;{	register char **p;	register int l, *t;	l = 0;	for(p=p1; p!=p2; p++)	switch(**p) {	case '(':		l++;		continue;	case ')':		l--;		continue;	case '|':	case '^':		if(l == 0) {			t = tree(4);			t[DTYP] = TFIL;			t[DLEF] = syn3(p1, p);			t[DRIT] = syn2(p+1, p2);			t[DFLG] = 0;			return(t);		}	}	return(syn3(p1, p2));}/* * syn3 *	( syn1 ) [ < in  ] [ > out ] *	word word* [ < in ] [ > out ] */syn3(p1, p2)char **p1, **p2;{	register char **p;	char **lp, **rp;	register *t;	int n, l, i, o, c, flg;	flg = 0;	if(**p2 == ')')		flg =| FPAR;	lp = 0;	rp = 0;	i = 0;	o = 0;	n = 0;	l = 0;	for(p=p1; p!=p2; p++)	switch(c = **p) {	case '(':		if(l == 0) {			if(lp != 0)				error++;			lp = p+1;		}		l++;		continue;	case ')':		l--;		if(l == 0)			rp = p;		continue;	case '>':		p++;		if(p!=p2 && **p=='>')			flg =| FCAT; else			p--;	case '<':		if(l == 0) {			p++;			if(p == p2) {				error++;				p--;			}			if(any(**p, "<>("))				error++;			if(c == '<') {				if(i != 0)					error++;				i = *p;				continue;			}			if(o != 0)				error++;			o = *p;		}		continue;	default:		if(l == 0)			p1[n++] = *p;	}	if(lp != 0) {		if(n != 0)			error++;		t = tree(5);		t[DTYP] = TPAR;		t[DSPR] = syn1(lp, rp);		goto out;	}	if(n == 0)		error++;	p1[n++] = 0;	t = tree(n+5);	t[DTYP] = TCOM;	for(l=0; l<n; l++)		t[l+DCOM] = p1[l];out:	t[DFLG] = flg;	t[DLEF] = i;	t[DRIT] = o;	return(t);}scan(at, f)int *at;int (*f)();{	register char *p, c;	register *t;	t = at+DCOM;	while(p = *t++)		while(c = *p)			*p++ = (*f)(c);}tglob(c)int c;{	if(any(c, "[?*"))		gflg = 1;	return(c);}trim(c)int c;{	return(c&0177);}execute(t, pf1, pf2)int *t, *pf1, *pf2;{	int i, f, pv[2];	register *t1;	register char *cp1, *cp2;	extern errno;	if(t != 0)	switch(t[DTYP]) {	case TCOM:		cp1 = t[DCOM];		if(equal(cp1, "chdir")) {			if(t[DCOM+1] != 0) {				if(chdir(t[DCOM+1]) < 0)					err("chdir: bad directory");			} else				err("chdir: arg count");			return;		}		if(equal(cp1, "shift")) {			if(dolc < 1) {				prs("shift: no args\n");				return;			}			dolv[1] = dolv[0];			dolv++;			dolc--;			return;		}		if(equal(cp1, "login")) {			if(promp != 0) {				close(acctf);				execv("/bin/login", t+DCOM);			}			prs("login: cannot execute\n");			return;		}		if(equal(cp1, "newgrp")) {			if(promp != 0) {				close(acctf);				execv("/bin/newgrp", t+DCOM);			}			prs("newgrp: cannot execute\n");			return;		}		if(equal(cp1, "wait")) {			pwait(-1, 0);			return;		}		if(equal(cp1, ":"))			return;	case TPAR:		f = t[DFLG];		i = 0;		if((f&FPAR) == 0)			i = fork();		if(i == -1) {			err("try again");			return;		}		if(i != 0) {			if((f&FPIN) != 0) {				close(pf1[0]);				close(pf1[1]);			}			if((f&FPRS) != 0) {				prn(i);				prs("\n");			}			if((f&FAND) != 0)				return;			if((f&FPOU) == 0)				pwait(i, t);			return;		}		if(t[DLEF] != 0) {			close(0);			i = open(t[DLEF], 0);			if(i < 0) {				prs(t[DLEF]);				err(": cannot open");				exit();			}		}		if(t[DRIT] != 0) {			if((f&FCAT) != 0) {				i = open(t[DRIT], 1);				if(i >= 0) {					seek(i, 0, 2);					goto f1;				}			}			i = creat(t[DRIT], 0666);			if(i < 0) {				prs(t[DRIT]);				err(": cannot create");				exit();			}		f1:			close(1);			dup(i);			close(i);		}		if((f&FPIN) != 0) {			close(0);			dup(pf1[0]);			close(pf1[0]);			close(pf1[1]);		}		if((f&FPOU) != 0) {			close(1);			dup(pf2[1]);			close(pf2[0]);			close(pf2[1]);		}		if((f&FINT)!=0 && t[DLEF]==0 && (f&FPIN)==0) {			close(0);			open("/dev/null", 0);		}		if((f&FINT) == 0 && setintr) {			signal(INTR, 0);			signal(QUIT, 0);		}		if(t[DTYP] == TPAR) {			if(t1 = t[DSPR])				t1[DFLG] =| f&FINT;			execute(t1);			exit();		}		close(acctf);		gflg = 0;		scan(t, &tglob);		if(gflg) {			t[DSPR] = "/etc/glob";			execv(t[DSPR], t+DSPR);			prs("glob: cannot execute\n");			exit();		}		scan(t, &trim);		*linep = 0;		texec(t[DCOM], t);		cp1 = linep;		cp2 = "/usr/bin/";		while(*cp1 = *cp2++)			cp1++;		cp2 = t[DCOM];		while(*cp1++ = *cp2++);		texec(linep+4, t);		texec(linep, t);		prs(t[DCOM]);		err(": not found");		exit();	case TFIL:		f = t[DFLG];		pipe(pv);		t1 = t[DLEF];		t1[DFLG] =| FPOU | (f&(FPIN|FINT|FPRS));		execute(t1, pf1, pv);		t1 = t[DRIT];		t1[DFLG] =| FPIN | (f&(FPOU|FINT|FAND|FPRS));		execute(t1, pv, pf2);		return;	case TLST:		f = t[DFLG]&FINT;		if(t1 = t[DLEF])			t1[DFLG] =| f;		execute(t1);		if(t1 = t[DRIT])			t1[DFLG] =| f;		execute(t1);		return;	}}texec(f, at)int *at;{	extern errno;	register int *t;	t = at;	execv(f, t+DCOM);	if (errno==ENOEXEC) {		if (*linep)			t[DCOM] = linep;		t[DSPR] = "/bin/sh";		execv(t[DSPR], t+DSPR);		prs("No shell!\n");		exit();	}	if (errno==ENOMEM) {		prs(t[DCOM]);		err(": too large");		exit();	}}err(s)char *s;{	prs(s);	prs("\n");	if(promp == 0) {		seek(0, 0, 2);		exit();	}}prs(as)char *as;{	register char *s;	s = as;	while(*s)		putc(*s++);}putc(c){	write(2, &c, 1);}prn(n)int n;{	register a;	if(a=ldiv(0,n,10))		prn(a);	putc(lrem(0,n,10)+'0');}any(c, as)int c;char *as;{	register char *s;	s = as;	while(*s)		if(*s++ == c)			return(1);	return(0);}equal(as1, as2)char *as1, *as2;{	register char *s1, *s2;	s1 = as1;	s2 = as2;	while(*s1++ == *s2)		if(*s2++ == '\0')			return(1);	return(0);}pwait(i, t)int i, *t;{	register p, e;	int s;	if(i != 0)	for(;;) {		times(&timeb);		time(timeb.proct);		p = wait(&s);		if(p == -1)			break;		e = s&0177;		if(mesg[e] != 0) {			if(p != i) {				prn(p);				prs(": ");			}			prs(mesg[e]);			if(s&0200)				prs(" -- Core dumped");		}		if(e != 0)			err("");		if(i == p) {			acct(t);			break;		} else			acct(0);	}}acct(t)int *t;{	if(t == 0)		enacct("**gok"); else	if(*t == TPAR)		enacct("()"); else	enacct(t[DCOM]);}enacct(as)char *as;{	struct stime timbuf;	struct {		char cname[14];		char shf;		char uid;		int datet[2];		int realt[2];		int bcput[2];		int bsyst[2];	} tbuf;	register i;	register char *np, *s;	s = as;	times(&timbuf);	time(timbuf.proct);	lsub(tbuf.realt, timbuf.proct, timeb.proct);	lsub(tbuf.bcput, timbuf.cputim, timeb.cputim);	lsub(tbuf.bsyst, timbuf.systim, timeb.systim);	do {		np = s;		while (*s != '\0' && *s != '/')			s++;	} while (*s++ != '\0');	for (i=0; i<14; i++) {		tbuf.cname[i] = *np;		if (*np)			np++;	}	tbuf.datet[0] = timbuf.proct[0];	tbuf.datet[1] = timbuf.proct[1];	tbuf.uid = uid;	tbuf.shf = 0;	if (promp==0)		tbuf.shf = 1;	seek(acctf, 0, 2);	write(acctf, &tbuf, sizeof(tbuf));}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -