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