|
|
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: sarg0 = argc>0 ? argv[0] : ""; ! 15: fakearg(0, argc, argv, envp); ! 16: if (argc>0 && argv[0][0]=='-') { ! 17: lgnflag = 1; ! 18: umask(ufmask=022); ! 19: } else if (argc>0 && argv[0][0]=='+') { ! 20: dflttrp(IBACK); /* for security, no <Ctrl-C> out of /etc/profile */ ! 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: cleanup(1, NULL); ! 40: if (set(argc, argv, 1)) ! 41: return(1); ! 42: if (cflag) { ! 43: if (sargp[0]==NULL) { ! 44: printe("No string for -c?"); ! 45: return(1); ! 46: } ! 47: --sargc; ! 48: session(SARGS, *sargp++); ! 49: } else if (!sflag && !iflag && sargc!=0) { ! 50: sarg0 = *sargp++; ! 51: --sargc; ! 52: if (scmdp == NULL) ! 53: scmdp = sarg0; ! 54: session(SFILE, scmdp); ! 55: } else { ! 56: session(SSTR, stdin); ! 57: } ! 58: cleanup(2, NULL); ! 59: return (slret); ! 60: } ! 61: ! 62: /* ! 63: * Make the arg listing of ps come out right. ! 64: * f == 0, first entry, determine buffer limits. ! 65: * f != 0, later entry, fill buffer with lies. ! 66: */ ! 67: fakearg(f, argc, argv, envp) ! 68: int f, argc; ! 69: char **argv, **envp; ! 70: { ! 71: static char *fbuf; ! 72: static int nbuf; ! 73: register int n; ! 74: ! 75: if (f == 0) { ! 76: fbuf = argv[0]; ! 77: nbuf = 0; ! 78: if (envp != NULL && envp[0] != NULL) { ! 79: while (envp[1] != NULL) ! 80: envp += 1; ! 81: nbuf = envp[0] - fbuf + strlen(envp[0]) - 1; ! 82: } else if (argc > 0) ! 83: nbuf = argv[argc-1] - fbuf + strlen(argv[argc-1]) - 1; ! 84: } else { ! 85: if (fbuf == NULL || nbuf == 0) ! 86: return; ! 87: n = 0; ! 88: fbuf[0] = 0; ! 89: while (--argc > 0) { ! 90: argv += 1; ! 91: n += strlen(argv[0]) + 1; ! 92: if (n >= nbuf) ! 93: break; ! 94: strcat(fbuf, argv[0]); ! 95: strcat(fbuf, " "); ! 96: } ! 97: strcat(fbuf, "\1"); /* non-ascii terminator */ ! 98: } ! 99: } ! 100: ! 101: /* ! 102: * Loop on input. ! 103: */ ! 104: session(t, p) ! 105: register char *p; ! 106: { ! 107: SES s; ! 108: register int rcode; ! 109: ! 110: s.s_next = sesp; ! 111: sesp = &s; ! 112: s.s_bpp = savebuf(); ! 113: ! 114: switch (s.s_type = t) { ! 115: case SARGS: ! 116: s.s_strp = p; ! 117: s.s_flag = 0; ! 118: break; ! 119: case SARGV: ! 120: s.s_argv = (char **) p; ! 121: if ((s.s_strp = s.s_argv[0]) == NULL) ! 122: return (0); ! 123: s.s_flag = 0; ! 124: break; ! 125: case SFILE: ! 126: s.s_strp = p; ! 127: if ((s.s_ifp = fopen(s.s_strp, "r")) == NULL) { ! 128: ecantopen(s.s_strp); ! 129: return (1); ! 130: } ! 131: s.s_flag = isatty(fileno(s.s_ifp)) && isatty(2); ! 132: break; ! 133: case SSTR: ! 134: s.s_strp = NULL; ! 135: s.s_ifp = (FILE *) p; ! 136: s.s_flag = isatty(fileno(s.s_ifp)) && isatty(2); ! 137: break; ! 138: } ! 139: ! 140: if (s.s_next == NULL) { /* Initial entry */ ! 141: if (iflag) ! 142: s.s_flag = iflag; ! 143: else ! 144: iflag = s.s_flag; ! 145: if (lgnflag != 2) ! 146: dflttrp(IRDY); /* allow <Ctrl-C> unless "+sh" */ ! 147: } ! 148: ! 149: /* Loop on input */ ! 150: for (;;) { ! 151: rcode = setjmp(s.s_envl); ! 152: switch (rcode) { ! 153: case RSET: /* initial setjmp call */ ! 154: switch (lgnflag) { ! 155: case 1: /* - sign invocation */ ! 156: lgnflag = 0; ! 157: if (ffind("/etc", "profile", 4)) ! 158: session(SFILE, duplstr(strt, 0)); ! 159: recover(IPROF); ! 160: if (*vhome && ffind(vhome, ".profile", 4)) ! 161: session(SFILE, duplstr(strt, 0)); ! 162: break; ! 163: case 2: /* + sign invocation */ ! 164: lgnflag = 0; ! 165: if (ffind("/etc", "profile", 4)) ! 166: session(SFILE, duplstr(strt, 0)); ! 167: recover(IPROF); ! 168: dflttrp(IRDY); /* allow <Ctrl-C> in SHELL */ ! 169: return exshell( findvar("SHELL") ); ! 170: } ! 171: checkmail(); ! 172: comflag = 1; ! 173: errflag = 0; ! 174: recover(IRDY); ! 175: freebuf(s.s_bpp); ! 176: s.s_bpp = savebuf(); ! 177: if (yyparse() != 0) ! 178: syntax(); ! 179: case REOF: ! 180: recover(IRDY); ! 181: break; ! 182: case RCMD: ! 183: recover(IRDY); ! 184: s.s_con = NULL; ! 185: command(s.s_node); ! 186: if ((tflag && tflag++ >= 2)) ! 187: break; ! 188: continue; ! 189: case RERR: ! 190: recover(IRDY); ! 191: if ( ! errflag) ! 192: syntax(); ! 193: if ( ! iflag || (tflag && tflag++ >= 2)) ! 194: break; ! 195: continue; ! 196: case RINT: ! 197: if (s.s_next != NULL) { ! 198: sesp = s.s_next; ! 199: reset(RINT); ! 200: NOTREACHED; ! 201: } ! 202: prpflag = 2; ! 203: if ( ! iflag || (tflag && tflag++ >= 2)) ! 204: break; ! 205: continue; ! 206: case RUEXITS: ! 207: case RUABORT: ! 208: if (s.s_next != NULL) { ! 209: sesp = s.s_next; ! 210: reset(rcode); ! 211: NOTREACHED; ! 212: } ! 213: if (rcode == RUEXITS || !iflag || (tflag && tflag++ >= 2)) ! 214: break; ! 215: continue; ! 216: case RNOSBRK: ! 217: case RSYSER: ! 218: case RBRKCON: ! 219: case RNOWAY: ! 220: default: ! 221: if (s.s_next!=NULL) ! 222: break; ! 223: if ( ! iflag || (tflag && tflag++ >= 2)) ! 224: break; ! 225: continue; ! 226: } ! 227: break; ! 228: } ! 229: freebuf(s.s_bpp); ! 230: if (s.s_type == SFILE) ! 231: fclose(s.s_ifp); ! 232: if (s.s_next == NULL) { ! 233: sigintr(0); ! 234: recover(IRDY); ! 235: } ! 236: sesp = s.s_next; ! 237: return (slret); ! 238: } ! 239: ! 240: reset(f) ! 241: { ! 242: longjmp(sesp->s_envl, f); ! 243: NOTREACHED; ! 244: } ! 245: ! 246: /* ! 247: * Kludge cleanup. ! 248: */ ! 249: cleanup(flag, file) ! 250: char *file; ! 251: { ! 252: static char *files[8]; ! 253: static int nfiles = 0; ! 254: register char **pp; ! 255: ! 256: if (flag) { ! 257: for (pp=files; pp<files+8; pp+=1) ! 258: if (*pp != NULL) { ! 259: if (flag==2) ! 260: unlink(*pp); ! 261: sfree(*pp); ! 262: *pp = NULL; ! 263: } ! 264: nfiles = 0; ! 265: } else { ! 266: pp = files + nfiles; ! 267: if (*pp != NULL) { ! 268: unlink(*pp); ! 269: sfree(*pp); ! 270: } ! 271: *pp = duplstr(file, 1); ! 272: nfiles = (nfiles + 1) & 7; ! 273: } ! 274: } ! 275: ! 276: /* ! 277: * Make a temp file name. ! 278: */ ! 279: char * ! 280: shtmp() ! 281: { ! 282: static char tmpfile[] = "/tmp/shXXXXXX"; ! 283: static int tmpflag = 0; ! 284: ! 285: sprintf(tmpfile+6, "%05d%c", shpid, (tmpflag++%26) + 'a'); ! 286: return (tmpfile); ! 287: } ! 288: ! 289: /* ! 290: * Print formatted. ! 291: */ ! 292: /* ! 293: printv(av) ! 294: register char **av; ! 295: { ! 296: while (*av) prints("\t%s\n", *av++); ! 297: } ! 298: */ ! 299: ! 300: prints(a1) ! 301: char *a1; ! 302: { ! 303: fprintf(stderr, "%r", &a1); ! 304: } ! 305: ! 306: /* ! 307: * Make a core dump in /tmp and longjmp back to session - ! 308: * there's a possibility we'll die horribly. ! 309: */ ! 310: panic(i) register int i; ! 311: { ! 312: #ifdef PARANOID ! 313: register int f; ! 314: ! 315: if ((f=fork())==0) { ! 316: abort(); ! 317: NOTREACHED; ! 318: } ! 319: waitc(f); ! 320: #endif ! 321: printe("Internal shell assertion %d failed", i); ! 322: reset(RNOWAY); ! 323: NOTREACHED; ! 324: } ! 325: ! 326: /* ! 327: * Print out an error message. ! 328: */ ! 329: printe(a1) ! 330: char *a1; ! 331: { ! 332: errflag += 1; ! 333: if (! noeflag) ! 334: fprintf(stderr, "%r\n", &a1); ! 335: } ! 336: ! 337: /* ! 338: * Some familiar errors. ! 339: */ ! 340: ecantopen(s) char *s; { printe("Cannot open %s", s); } ! 341: ecantfind(s) char *s; { printe("Cannot find %s", s); } ! 342: e2big(s) char *s; { printe("File to big to execute: %s", s); } ! 343: ecantmake(s) char *s; { printe("Cannot create %s", s); } ! 344: emisschar(c) { printe("Missing `%c'", c); } ! 345: ecantfdop() { printe("Fdopen failed"); } ! 346: enotdef(s) char *s; { printe("Cannot find variable %s", s); } ! 347: eillvar(s) char *s; { printe("Illegal variable name: %s", s); } ! 348: eredir() { printe("Illegal redirection"); } ! 349: etoolong() { printe("Argument too long: %.*s", STRSIZE, strt); } ! 350: ! 351: /* ! 352: * Don't print out an error message. ! 353: */ ! 354: yyerror() ! 355: { ! 356: } ! 357: ! 358: /* ! 359: * print out the prompt given the prompt to write ! 360: */ ! 361: prompt(vps) ! 362: char *vps; ! 363: { ! 364: prints("%s", vps); ! 365: #if RSX ! 366: fflush(stdout); ! 367: #endif ! 368: } ! 369: ! 370: /* ! 371: * Syntax error message - print line number and file if ! 372: * not interactive. ! 373: */ ! 374: syntax() ! 375: { ! 376: if (sesp->s_type == SFILE) { ! 377: if (feof(sesp->s_ifp)) ! 378: printe("%s: Syntax error at EOF", sesp->s_strp); ! 379: else ! 380: printe("%s: Syntax error in line %d", sesp->s_strp, yyline); ! 381: } else ! 382: printe("Syntax error"); ! 383: } ! 384: ! 385: /* end of sh/main.c */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.