xref: /inferno-os/utils/rcsh/main.c (revision 74a4d8c26dd3c1e9febcb717cfd6cb6512991a7a)
1*74a4d8c2SCharles.Forsyth #include "rc.h"
2*74a4d8c2SCharles.Forsyth 
3*74a4d8c2SCharles.Forsyth int	flag[256];
4*74a4d8c2SCharles.Forsyth Io	*err;
5*74a4d8c2SCharles.Forsyth char	*argv0;
6*74a4d8c2SCharles.Forsyth 
7*74a4d8c2SCharles.Forsyth Thread	*runq;
8*74a4d8c2SCharles.Forsyth int	ndot;
9*74a4d8c2SCharles.Forsyth 
10*74a4d8c2SCharles.Forsyth 
11*74a4d8c2SCharles.Forsyth void
main(int argc,char * argv[])12*74a4d8c2SCharles.Forsyth main(int argc, char *argv[])
13*74a4d8c2SCharles.Forsyth {
14*74a4d8c2SCharles.Forsyth 	int i;
15*74a4d8c2SCharles.Forsyth 	Code bootstrap[17];
16*74a4d8c2SCharles.Forsyth 	char *cflag, *cp;
17*74a4d8c2SCharles.Forsyth 	char rcmain[200];
18*74a4d8c2SCharles.Forsyth 	Var *infroot;
19*74a4d8c2SCharles.Forsyth 	char **p;
20*74a4d8c2SCharles.Forsyth 
21*74a4d8c2SCharles.Forsyth 	cflag = 0;
22*74a4d8c2SCharles.Forsyth 
23*74a4d8c2SCharles.Forsyth 	/* default to interactive mode */
24*74a4d8c2SCharles.Forsyth 	flag['i']++;
25*74a4d8c2SCharles.Forsyth 
26*74a4d8c2SCharles.Forsyth 	/* hack for DOS-style options, when rcsh started from MS-land */
27*74a4d8c2SCharles.Forsyth 	for (p = argv+1; *p && **p == '/'; p++)
28*74a4d8c2SCharles.Forsyth 		**p = '-';
29*74a4d8c2SCharles.Forsyth 
30*74a4d8c2SCharles.Forsyth 	argv0 = *argv;
31*74a4d8c2SCharles.Forsyth 	ARGBEGIN{
32*74a4d8c2SCharles.Forsyth 	default:
33*74a4d8c2SCharles.Forsyth 		fprint(2, "usage: %s: [-seiIlvxr] [-c string] [file [args]]\n", argv0);
34*74a4d8c2SCharles.Forsyth 		exits("usage");
35*74a4d8c2SCharles.Forsyth 	case 'e': flag['e']++; break;
36*74a4d8c2SCharles.Forsyth 	case 'c': cflag = ARGF(); break;
37*74a4d8c2SCharles.Forsyth 	case 'i': flag['i']++; break;
38*74a4d8c2SCharles.Forsyth 	case 'I': flag['i'] = 0; break;
39*74a4d8c2SCharles.Forsyth 	case 'l': flag['l']++; break;
40*74a4d8c2SCharles.Forsyth 	case 'r': flag['r']++; break;
41*74a4d8c2SCharles.Forsyth 	case 's': flag['s']++; break;
42*74a4d8c2SCharles.Forsyth 	case 'S': flag['S']++; break;		/* sub shell */
43*74a4d8c2SCharles.Forsyth 	case 'v': flag['v']++; break;
44*74a4d8c2SCharles.Forsyth 	case 'V': flag['V']++; break;
45*74a4d8c2SCharles.Forsyth 	case 'x': flag['x']++; break;
46*74a4d8c2SCharles.Forsyth 	}ARGEND
47*74a4d8c2SCharles.Forsyth 
48*74a4d8c2SCharles.Forsyth 	err = openfd(2);
49*74a4d8c2SCharles.Forsyth 
50*74a4d8c2SCharles.Forsyth 	kinit();
51*74a4d8c2SCharles.Forsyth 	vinit();
52*74a4d8c2SCharles.Forsyth 
53*74a4d8c2SCharles.Forsyth 	cp = ROOT;
54*74a4d8c2SCharles.Forsyth 	if(0 && strlen(argv0))
55*74a4d8c2SCharles.Forsyth 		sprint(rcmain, "%s/../lib/rcmain", argv0);
56*74a4d8c2SCharles.Forsyth 	else{
57*74a4d8c2SCharles.Forsyth 		infroot = vlook("ROOT");
58*74a4d8c2SCharles.Forsyth 		if(infroot->val)
59*74a4d8c2SCharles.Forsyth 			cp = infroot->val->word;
60*74a4d8c2SCharles.Forsyth 	}
61*74a4d8c2SCharles.Forsyth 	sprint(rcmain, "%s/utils/lib/rcmain", cp);
62*74a4d8c2SCharles.Forsyth 
63*74a4d8c2SCharles.Forsyth 	setvar("rcname", newword(argv0, 0));
64*74a4d8c2SCharles.Forsyth 	if(cflag)
65*74a4d8c2SCharles.Forsyth 		setvar("cflag", newword(cflag, 0));
66*74a4d8c2SCharles.Forsyth 	else
67*74a4d8c2SCharles.Forsyth 		setvar("cflag", 0);
68*74a4d8c2SCharles.Forsyth 
69*74a4d8c2SCharles.Forsyth 	/* bootstrap == . rcmain $* */
70*74a4d8c2SCharles.Forsyth 	i=0;
71*74a4d8c2SCharles.Forsyth 	bootstrap[i++].i=1;
72*74a4d8c2SCharles.Forsyth 	bootstrap[i++].f=Xmark;
73*74a4d8c2SCharles.Forsyth 	bootstrap[i++].f=Xword;
74*74a4d8c2SCharles.Forsyth 	bootstrap[i++].s="*";
75*74a4d8c2SCharles.Forsyth 	bootstrap[i++].f=Xassign;
76*74a4d8c2SCharles.Forsyth 	bootstrap[i++].f=Xmark;
77*74a4d8c2SCharles.Forsyth 	bootstrap[i++].f=Xmark;
78*74a4d8c2SCharles.Forsyth 	bootstrap[i++].f=Xword;
79*74a4d8c2SCharles.Forsyth 	bootstrap[i++].s="*";
80*74a4d8c2SCharles.Forsyth 	bootstrap[i++].f=Xdol;
81*74a4d8c2SCharles.Forsyth 	bootstrap[i++].f=Xword;
82*74a4d8c2SCharles.Forsyth 	bootstrap[i++].s=rcmain;
83*74a4d8c2SCharles.Forsyth 	bootstrap[i++].f=Xword;
84*74a4d8c2SCharles.Forsyth 	bootstrap[i++].s=".";
85*74a4d8c2SCharles.Forsyth 	bootstrap[i++].f=Xsimple;
86*74a4d8c2SCharles.Forsyth 	bootstrap[i++].f=Xexit;
87*74a4d8c2SCharles.Forsyth 	bootstrap[i].i=0;
88*74a4d8c2SCharles.Forsyth 	start(bootstrap, 1, 0);
89*74a4d8c2SCharles.Forsyth 	pushlist();
90*74a4d8c2SCharles.Forsyth 	for(i=argc-1;i>=0;i--)
91*74a4d8c2SCharles.Forsyth 		pushword(argv[i]);
92*74a4d8c2SCharles.Forsyth 
93*74a4d8c2SCharles.Forsyth 	for(;;){
94*74a4d8c2SCharles.Forsyth 		if(flag['r']) pfnc(err, runq);
95*74a4d8c2SCharles.Forsyth 		runq->pc++;
96*74a4d8c2SCharles.Forsyth 		(*runq->code[runq->pc-1].f)();
97*74a4d8c2SCharles.Forsyth 		if(ntrap.ref)
98*74a4d8c2SCharles.Forsyth 			dotrap();
99*74a4d8c2SCharles.Forsyth 	}
100*74a4d8c2SCharles.Forsyth }
101*74a4d8c2SCharles.Forsyth 
102*74a4d8c2SCharles.Forsyth void
panic(char * s,int n)103*74a4d8c2SCharles.Forsyth panic(char *s, int n)
104*74a4d8c2SCharles.Forsyth {
105*74a4d8c2SCharles.Forsyth 	pfmt(err, "rc: ");
106*74a4d8c2SCharles.Forsyth 	pfmt(err, s, n);
107*74a4d8c2SCharles.Forsyth 	pchr(err, '\n');
108*74a4d8c2SCharles.Forsyth 	flush(err);
109*74a4d8c2SCharles.Forsyth 	pfmt(err, "aborting\n");
110*74a4d8c2SCharles.Forsyth 	flush(err);
111*74a4d8c2SCharles.Forsyth 	exits("aborting");
112*74a4d8c2SCharles.Forsyth }
113*74a4d8c2SCharles.Forsyth 
114*74a4d8c2SCharles.Forsyth void
setstatus(char * s)115*74a4d8c2SCharles.Forsyth setstatus(char *s)
116*74a4d8c2SCharles.Forsyth {
117*74a4d8c2SCharles.Forsyth 	setvar("status", newword(s, 0));
118*74a4d8c2SCharles.Forsyth }
119*74a4d8c2SCharles.Forsyth 
120*74a4d8c2SCharles.Forsyth char *
getstatus(void)121*74a4d8c2SCharles.Forsyth getstatus(void)
122*74a4d8c2SCharles.Forsyth {
123*74a4d8c2SCharles.Forsyth 	Var *status=vlook("status");
124*74a4d8c2SCharles.Forsyth 
125*74a4d8c2SCharles.Forsyth 	return status->val?status->val->word:"";
126*74a4d8c2SCharles.Forsyth }
127*74a4d8c2SCharles.Forsyth 
128*74a4d8c2SCharles.Forsyth int
truestatus(void)129*74a4d8c2SCharles.Forsyth truestatus(void)
130*74a4d8c2SCharles.Forsyth {
131*74a4d8c2SCharles.Forsyth 	char *s;
132*74a4d8c2SCharles.Forsyth 	for(s=getstatus();*s;s++)
133*74a4d8c2SCharles.Forsyth 		if(*s!='|' && *s!='0') return 0;
134*74a4d8c2SCharles.Forsyth 	return 1;
135*74a4d8c2SCharles.Forsyth }
136*74a4d8c2SCharles.Forsyth 
137*74a4d8c2SCharles.Forsyth char *
concstatus(char * s,char * t)138*74a4d8c2SCharles.Forsyth concstatus(char *s, char *t)
139*74a4d8c2SCharles.Forsyth {
140*74a4d8c2SCharles.Forsyth 	static char v[NSTATUS+1];
141*74a4d8c2SCharles.Forsyth 	int n=strlen(s);
142*74a4d8c2SCharles.Forsyth 	strncpy(v, s, NSTATUS);
143*74a4d8c2SCharles.Forsyth 	if(n<NSTATUS){
144*74a4d8c2SCharles.Forsyth 		v[n]='|';
145*74a4d8c2SCharles.Forsyth 		strncpy(v+n+1, t, NSTATUS-n-1);
146*74a4d8c2SCharles.Forsyth 	}
147*74a4d8c2SCharles.Forsyth 	v[NSTATUS]='\0';
148*74a4d8c2SCharles.Forsyth 	return v;
149*74a4d8c2SCharles.Forsyth }
150*74a4d8c2SCharles.Forsyth 
151*74a4d8c2SCharles.Forsyth /*
152*74a4d8c2SCharles.Forsyth  * Start executing the given code at the given pc with the given redirection
153*74a4d8c2SCharles.Forsyth  */
154*74a4d8c2SCharles.Forsyth void
start(Code * c,int pc,Var * local)155*74a4d8c2SCharles.Forsyth start(Code *c, int pc, Var *local)
156*74a4d8c2SCharles.Forsyth {
157*74a4d8c2SCharles.Forsyth 	Thread *p = new(Thread);
158*74a4d8c2SCharles.Forsyth 
159*74a4d8c2SCharles.Forsyth 	memset(p, 0, sizeof(Thread));
160*74a4d8c2SCharles.Forsyth 	p->code = codecopy(c);
161*74a4d8c2SCharles.Forsyth 	p->pc = pc;
162*74a4d8c2SCharles.Forsyth 	if(runq) {
163*74a4d8c2SCharles.Forsyth 		p->redir = runq->redir;
164*74a4d8c2SCharles.Forsyth 		p->startredir = runq->redir;
165*74a4d8c2SCharles.Forsyth 	}
166*74a4d8c2SCharles.Forsyth 	p->local = local;
167*74a4d8c2SCharles.Forsyth 	p->lineno = 1;
168*74a4d8c2SCharles.Forsyth 	p->ret = runq;
169*74a4d8c2SCharles.Forsyth 	runq=p;
170*74a4d8c2SCharles.Forsyth }
171*74a4d8c2SCharles.Forsyth 
172*74a4d8c2SCharles.Forsyth void
execcmds(Io * f)173*74a4d8c2SCharles.Forsyth execcmds(Io *f)
174*74a4d8c2SCharles.Forsyth {
175*74a4d8c2SCharles.Forsyth 	static Code rdcmds[4];
176*74a4d8c2SCharles.Forsyth 	static int first=1;
177*74a4d8c2SCharles.Forsyth 
178*74a4d8c2SCharles.Forsyth 	if(first){
179*74a4d8c2SCharles.Forsyth 		rdcmds[0].i=1;
180*74a4d8c2SCharles.Forsyth 		rdcmds[1].f=Xrdcmds;
181*74a4d8c2SCharles.Forsyth 		rdcmds[2].f=Xreturn;
182*74a4d8c2SCharles.Forsyth 		first=0;
183*74a4d8c2SCharles.Forsyth 	}
184*74a4d8c2SCharles.Forsyth 	start(rdcmds, 1, runq->local);
185*74a4d8c2SCharles.Forsyth 	runq->cmdfd=f;
186*74a4d8c2SCharles.Forsyth 	runq->iflast=0;
187*74a4d8c2SCharles.Forsyth }
188*74a4d8c2SCharles.Forsyth 
189*74a4d8c2SCharles.Forsyth void
waitfor(uint pid)190*74a4d8c2SCharles.Forsyth waitfor(uint pid)
191*74a4d8c2SCharles.Forsyth {
192*74a4d8c2SCharles.Forsyth 	int e;
193*74a4d8c2SCharles.Forsyth 	char estr[64];
194*74a4d8c2SCharles.Forsyth 
195*74a4d8c2SCharles.Forsyth 	e = procwait(pid);
196*74a4d8c2SCharles.Forsyth 	if(e != 0) {
197*74a4d8c2SCharles.Forsyth 		sprint(estr, "error code %d", e);
198*74a4d8c2SCharles.Forsyth 		setstatus(estr);
199*74a4d8c2SCharles.Forsyth 	} else
200*74a4d8c2SCharles.Forsyth 		setstatus("");
201*74a4d8c2SCharles.Forsyth }
202*74a4d8c2SCharles.Forsyth 
203*74a4d8c2SCharles.Forsyth char **
procargv(char * s0,char * s1,char * s2,char * s3,Word * w)204*74a4d8c2SCharles.Forsyth procargv(char *s0, char *s1, char *s2, char *s3, Word *w)
205*74a4d8c2SCharles.Forsyth {
206*74a4d8c2SCharles.Forsyth 	int n, i;
207*74a4d8c2SCharles.Forsyth 	Word *p;
208*74a4d8c2SCharles.Forsyth 	char **argv;
209*74a4d8c2SCharles.Forsyth 
210*74a4d8c2SCharles.Forsyth 	for(p=w,n=5; p; p=p->next,n++);
211*74a4d8c2SCharles.Forsyth 		;
212*74a4d8c2SCharles.Forsyth 
213*74a4d8c2SCharles.Forsyth 	argv = malloc(n*sizeof(char*));
214*74a4d8c2SCharles.Forsyth 	i = 0;
215*74a4d8c2SCharles.Forsyth 	if(s0)
216*74a4d8c2SCharles.Forsyth 		argv[i++] = s0;
217*74a4d8c2SCharles.Forsyth 	if(s1)
218*74a4d8c2SCharles.Forsyth 		argv[i++] = s1;
219*74a4d8c2SCharles.Forsyth 	if(s2)
220*74a4d8c2SCharles.Forsyth 		argv[i++] = s2;
221*74a4d8c2SCharles.Forsyth 	if(s3)
222*74a4d8c2SCharles.Forsyth 		argv[i++] = s3;
223*74a4d8c2SCharles.Forsyth 	for(p=w; p; p=p->next)
224*74a4d8c2SCharles.Forsyth 		argv[i++] = p->word;
225*74a4d8c2SCharles.Forsyth 	argv[i] = 0;
226*74a4d8c2SCharles.Forsyth 	return argv;
227*74a4d8c2SCharles.Forsyth }
228*74a4d8c2SCharles.Forsyth 
229