|
|
1.1 root 1: /*
2: * sh/main.c
3: * The Bourne shell.
4: * Main program, initialization and miscellaneous routines.
5: */
6:
7: #include <sys/param.h>
8: #include "sh.h"
9:
10: main(argc, argv, envp)
11: char *argv[];
12: char *envp[];
13: {
14:
15: sarg0 = argc>0 ? argv[0] : "";
16: fakearg(0, argc, argv, envp);
17: if (argc>0 && argv[0][0]=='-') {
18: lgnflag = 1;
19: umask(ufmask=022);
20: } else if (argc>0 && argv[0][0]=='+') {
21: lgnflag = 2;
22: umask(ufmask=022);
23: } else {
24: umask(ufmask=umask(ufmask));
25: }
26:
27: if (setjmp(restart) != 0) {
28: /* reentry for shell command file execution */
29: fakearg(1, nargc, nargv, nenvp);
30: argc = nargc;
31: argv = nargv;
32: envp = nenvp;
33: cmdflag++;
34: nllflag = 0;
35: }
36:
37: shpid = getpid();
38: initvar(envp);
39: #if 0
40: cleanup(1, NULL);
41: #endif
42: if (set(argc, argv, 1))
43: return(1);
44: if (cflag) {
45: if (sargp[0]==NULL) {
46: printe("No string for -c?");
47: return(1);
48: }
49: --sargc;
50: session(SARGS, *sargp++);
51: } else if (!sflag && !iflag && sargc!=0) {
52: sarg0 = *sargp++;
53: --sargc;
54: if (scmdp == NULL)
55: scmdp = sarg0;
56: session(SFILE, scmdp);
57: } else {
58: session(SSTR, stdin);
59: }
60: cleanup_shell_fns ();
61: unlink_temp (capture_temp ());
62: return (slret);
63: }
64:
65: /*
66: * Make the arg listing of ps come out right.
67: * f == 0, first entry, determine buffer limits.
68: * f != 0, later entry, fill buffer with lies.
69: */
70: fakearg(f, argc, argv, envp)
71: int f, argc;
72: char **argv, **envp;
73: {
74: static char *fbuf;
75: static int nbuf;
76: register int n;
77:
78: if (f == 0) {
79: fbuf = argv[0];
80: nbuf = 0;
81: if (envp != NULL && envp[0] != NULL) {
82: while (envp[1] != NULL)
83: envp += 1;
84: nbuf = envp[0] - fbuf + strlen(envp[0]) - 1;
85: } else if (argc > 0)
86: nbuf = argv[argc-1] - fbuf + strlen(argv[argc-1]) - 1;
87: } else {
88: if (fbuf == NULL || nbuf == 0)
89: return;
90: n = 0;
91: fbuf[0] = 0;
92: while (--argc > 0) {
93: argv += 1;
94: n += strlen(argv[0]) + 1;
95: if (n >= nbuf)
96: break;
97: strcat(fbuf, argv[0]);
98: strcat(fbuf, " ");
99: }
100: strcat(fbuf, "\1"); /* non-ascii terminator */
101: }
102: }
103:
104: /*
105: * Loop on input.
106: */
107: session(t, p)
108: register char *p;
109: {
110: SES s;
111: register int rcode;
112:
113: s.s_next = sesp;
114: sesp = &s;
115: s.s_bpp = savebuf();
116:
117: switch (s.s_type = t) {
118: case SARGS:
119: s.s_strp = p;
120: s.s_flag = 0;
121: break;
122: case SARGV:
123: s.s_argv = (char **) p;
124: if ((s.s_strp = s.s_argv[0]) == NULL)
125: return (0);
126: s.s_flag = 0;
127: break;
128: case SFILE:
129: s.s_strp = p;
130: if ((s.s_ifp = fopen(s.s_strp, "r")) == NULL) {
131: ecantopen(s.s_strp);
132: return (1);
133: }
134: s.s_flag = isatty(fileno(s.s_ifp)) && isatty(2);
135: break;
136: case SSTR:
137: s.s_strp = NULL;
138: s.s_ifp = (FILE *) p;
139: s.s_flag = isatty(fileno(s.s_ifp)) && isatty(2);
140: break;
141: }
142:
143: if (s.s_next == NULL) { /* Initial entry */
144: if (iflag)
145: s.s_flag = iflag;
146: else
147: iflag = s.s_flag;
148: dflttrp(IRDY);
149: }
150:
151: /* Loop on input */
152: for (;;) {
153: unlink_temp (capture_temp ());
154:
155: rcode = setjmp(s.s_envl);
156: switch (rcode) {
157: case RSET: /* initial setjmp call */
158: switch (lgnflag) {
159: case 1: /* - sign invocation */
160: lgnflag = 0;
161: if (ffind("/etc", "profile", 4))
162: session(SFILE, duplstr(strt, 0));
163: recover(IPROF);
164: if (*vhome && ffind(vhome, ".profile", 4))
165: session(SFILE, duplstr(strt, 0));
166: break;
167: case 2: /* + sign invocation */
168: lgnflag = 0;
169: if (ffind("/etc", "profile", 4))
170: session(SFILE, duplstr(strt, 0));
171: recover(IPROF);
172: return exshell( findvar("SHELL") );
173: }
174: checkmail();
175: comflag = 1;
176: errflag = 0;
177: recover(IRDY);
178: freebuf(s.s_bpp);
179: s.s_bpp = savebuf();
180: if (yyparse() != 0)
181: syntax();
182: case REOF:
183: recover(IRDY);
184: break;
185: case RCMD:
186: recover(IRDY);
187: s.s_con = NULL;
188: command(s.s_node);
189: if ((tflag && tflag++ >= 2))
190: break;
191: continue;
192: case RERR:
193: recover(IRDY);
194: if ( ! errflag)
195: syntax();
196: if ( ! iflag || (tflag && tflag++ >= 2))
197: break;
198: continue;
199: case RINT:
200: if (s.s_next != NULL) {
201: sesp = s.s_next;
202: reset(RINT);
203: NOTREACHED;
204: }
205: prpflag = 2;
206: if ( ! iflag || (tflag && tflag++ >= 2))
207: break;
208: continue;
209: case RUEXITS:
210: case RUABORT:
211: if (s.s_next != NULL) {
212: sesp = s.s_next;
213: reset(rcode);
214: NOTREACHED;
215: }
216: if (rcode == RUEXITS || !iflag || (tflag && tflag++ >= 2))
217: break;
218: continue;
219: case RNOSBRK:
220: case RSYSER:
221: case RBRKCON:
222: case RNOWAY:
223: default:
224: if (s.s_next!=NULL)
225: break;
226: if ( ! iflag || (tflag && tflag++ >= 2))
227: break;
228: continue;
229: }
230: break;
231: }
232: freebuf(s.s_bpp);
233: if (s.s_type == SFILE)
234: fclose(s.s_ifp);
235: if (s.s_next == NULL) {
236: sigintr(0);
237: recover(IRDY);
238: }
239: sesp = s.s_next;
240: return (slret);
241: }
242:
243: reset(f)
244: {
245: longjmp(sesp->s_envl, f);
246: NOTREACHED;
247: }
248:
249:
250: /*
251: * Global head of list of temporary files.
252: */
253:
254: static TEMP_FILE * temp_list;
255:
256: ALLOC_COUNT (temp)
257:
258: /*
259: * Remember the name of a temporary file.
260: */
261:
262: void remember_temp (filename)
263: char * filename;
264: {
265: TEMP_FILE * temp = (TEMP_FILE *) salloc (sizeof (* temp));
266:
267: temp->tf_name = duplstr (filename, 1);
268: temp->tf_next = temp_list;
269: temp_list = temp;
270:
271: ALLOC_ALLOC (temp)
272: }
273:
274:
275: /*
276: * Return a pointer to the current global list of temporary files and clear
277: * the global pointer to that list.
278: */
279:
280: TEMP_FILE * capture_temp ()
281: {
282: TEMP_FILE * temp = temp_list;
283:
284: temp_list = NULL;
285: return temp;
286: }
287:
288:
289: /*
290: * Deallocate a list of temporary files.
291: */
292:
293: void forget_temp (templist)
294: TEMP_FILE * templist;
295: {
296: TEMP_FILE * temp;
297:
298: while ((temp = templist) != NULL) {
299:
300: templist = temp->tf_next;
301:
302: ALLOC_FREE (temp);
303: sfree (temp->tf_name);
304: sfree (temp);
305: }
306: }
307:
308:
309: /*
310: * Walk over a list of temporary files, unlinking the files and deallocating
311: * the list nodes.
312: */
313:
314: void unlink_temp (templist)
315: TEMP_FILE * templist;
316: {
317: TEMP_FILE * temp;
318:
319: while ((temp = templist) != NULL) {
320:
321: templist = temp->tf_next;
322: unlink (temp->tf_name);
323:
324: ALLOC_FREE (temp)
325: sfree (temp->tf_name);
326: sfree (temp);
327: }
328: }
329:
330:
331: /*
332: * Make a temp file name.
333: */
334: char *
335: shtmp()
336: {
337: static char tmpfile[] = "/tmp/shXXXXXX";
338: static int tmpflag = 0;
339:
340: sprintf(tmpfile+6, "%05d%c", shpid, (tmpflag++%26) + 'a');
341: return (tmpfile);
342: }
343:
344: /*
345: * Print formatted.
346: */
347: /*
348: printv(av)
349: register char **av;
350: {
351: while (*av) prints("\t%s\n", *av++);
352: }
353: */
354:
355: prints(a1)
356: char *a1;
357: {
358: fprintf(stderr, "%r", &a1);
359: }
360:
361: /*
362: * Make a core dump in /tmp and longjmp back to session -
363: * there's a possibility we'll die horribly.
364: */
365: panic(i) register int i;
366: {
367: #ifdef PARANOID
368: register int f;
369:
370: if ((f=fork())==0) {
371: abort();
372: NOTREACHED;
373: }
374: waitc(f);
375: #endif
376: printe("Internal shell assertion %d failed", i);
377: reset(RNOWAY);
378: NOTREACHED;
379: }
380:
381: /*
382: * Print out an error message.
383: */
384: printe(a1)
385: char *a1;
386: {
387: errflag += 1;
388: if (! noeflag)
389: fprintf(stderr, "%r\n", &a1);
390: }
391:
392: /*
393: * Some familiar errors.
394: */
395: ecantopen(s) char *s; { printe("Cannot open %s", s); }
396: ecantfind(s) char *s; { printe("Cannot find %s", s); }
397: e2big(s) char *s; { printe("File to big to execute: %s", s); }
398: ecantmake(s) char *s; { printe("Cannot create %s", s); }
399: emisschar(c) { printe("Missing `%c'", c); }
400: ecantfdop() { printe("Fdopen failed"); }
401: enotdef(s) char *s; { printe("Cannot find variable %s", s); }
402: eillvar(s) char *s; { printe("Illegal variable name: %s", s); }
403: eredir() { printe("Illegal redirection"); }
404: etoolong() { printe("Argument too long: %.*s", STRSIZE, strt); }
405: eredirundo() {
406: printe ("Unable to preserve redirection state when redirecting builtin");
407: }
408:
409: /*
410: * Don't print out an error message.
411: */
412: yyerror()
413: {
414: }
415:
416: /*
417: * print out the prompt given the prompt to write
418: */
419: prompt(vps)
420: char *vps;
421: {
422: prints("%s", vps);
423: #if RSX
424: fflush(stdout);
425: #endif
426: }
427:
428: /*
429: * Syntax error message - print line number and file if
430: * not interactive.
431: */
432: syntax()
433: {
434: if (sesp->s_type == SFILE) {
435: if (feof(sesp->s_ifp))
436: printe("%s: Syntax error at EOF", sesp->s_strp);
437: else
438: printe("%s: Syntax error in line %d", sesp->s_strp, yyline);
439: } else
440: printe("Syntax error");
441: }
442:
443: /* end of sh/main.c */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.