|
|
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.