|
|
1.1 ! root 1: /* Copyright (c) 1979 Regents of the University of California */ ! 2: #include "sh.h" ! 3: ! 4: /* ! 5: * C shell ! 6: */ ! 7: ! 8: #define ADDOP 1 ! 9: #define MULOP 2 ! 10: #define EQOP 4 ! 11: #define RELOP 8 ! 12: #define RESTOP 16 ! 13: #define ANYOP 31 ! 14: ! 15: #define EQEQ 1 ! 16: #define GTR 2 ! 17: #define LSS 4 ! 18: #define NOTEQ 6 ! 19: ! 20: exp(vp) ! 21: register char ***vp; ! 22: { ! 23: ! 24: return (exp0(vp, 0)); ! 25: } ! 26: ! 27: exp0(vp, ignore) ! 28: register char ***vp; ! 29: bool ignore; ! 30: { ! 31: register int p1 = exp1(vp, ignore); ! 32: ! 33: #ifdef EDEBUG ! 34: etraci("exp0 p1", p1, vp); ! 35: #endif ! 36: if (**vp && eq(**vp, "||")) { ! 37: register int p2; ! 38: ! 39: (*vp)++; ! 40: p2 = exp0(vp, ignore || p1); ! 41: #ifdef EDEBUG ! 42: etraci("exp0 p2", p2, vp); ! 43: #endif ! 44: return (p1 || p2); ! 45: } ! 46: return (p1); ! 47: } ! 48: ! 49: exp1(vp, ignore) ! 50: register char ***vp; ! 51: { ! 52: register int p1 = exp2(vp, ignore); ! 53: ! 54: #ifdef EDEBUG ! 55: etraci("exp1 p1", p1, vp); ! 56: #endif ! 57: if (**vp && eq(**vp, "&&")) { ! 58: register int p2; ! 59: ! 60: (*vp)++; ! 61: p2 = exp1(vp, ignore || !p1); ! 62: #ifdef EDEBUG ! 63: etraci("exp1 p2", p2, vp); ! 64: #endif ! 65: return (p1 && p2); ! 66: } ! 67: return (p1); ! 68: } ! 69: ! 70: exp2(vp, ignore) ! 71: register char ***vp; ! 72: bool ignore; ! 73: { ! 74: register int p1 = exp2a(vp, ignore); ! 75: ! 76: #ifdef EDEBUG ! 77: etraci("exp3 p1", p1, vp); ! 78: #endif ! 79: if (**vp && eq(**vp, "|")) { ! 80: register int p2; ! 81: ! 82: (*vp)++; ! 83: p2 = exp2(vp, ignore); ! 84: #ifdef EDEBUG ! 85: etraci("exp3 p2", p2, vp); ! 86: #endif ! 87: return (p1 | p2); ! 88: } ! 89: return (p1); ! 90: } ! 91: ! 92: exp2a(vp, ignore) ! 93: register char ***vp; ! 94: bool ignore; ! 95: { ! 96: register int p1 = exp2b(vp, ignore); ! 97: ! 98: #ifdef EDEBUG ! 99: etraci("exp2a p1", p1, vp); ! 100: #endif ! 101: if (**vp && eq(**vp, "^")) { ! 102: register int p2; ! 103: ! 104: (*vp)++; ! 105: p2 = exp2a(vp, ignore); ! 106: #ifdef EDEBUG ! 107: etraci("exp2a p2", p2, vp); ! 108: #endif ! 109: return (p1 ^ p2); ! 110: } ! 111: return (p1); ! 112: } ! 113: ! 114: exp2b(vp, ignore) ! 115: register char ***vp; ! 116: bool ignore; ! 117: { ! 118: register int p1 = exp2c(vp, ignore); ! 119: ! 120: #ifdef EDEBUG ! 121: etraci("exp2b p1", p1, vp); ! 122: #endif ! 123: if (**vp && eq(**vp, "&")) { ! 124: register int p2; ! 125: ! 126: (*vp)++; ! 127: p2 = exp2b(vp, ignore); ! 128: #ifdef EDEBUG ! 129: etraci("exp2b p2", p2, vp); ! 130: #endif ! 131: return (p1 & p2); ! 132: } ! 133: return (p1); ! 134: } ! 135: ! 136: exp2c(vp, ignore) ! 137: register char ***vp; ! 138: bool ignore; ! 139: { ! 140: register char *p1 = exp3(vp, ignore); ! 141: register char *p2; ! 142: register int i; ! 143: ! 144: #ifdef EDEBUG ! 145: etracc("exp2c p1", p1, vp); ! 146: #endif ! 147: if (i = isa(**vp, EQOP)) { ! 148: (*vp)++; ! 149: p2 = exp3(vp, ignore); ! 150: #ifdef EDEBUG ! 151: etracc("exp2c p2", p2, vp); ! 152: #endif ! 153: if (!ignore) switch (i) { ! 154: ! 155: case EQEQ: ! 156: i = eq(p1, p2); ! 157: break; ! 158: ! 159: case NOTEQ: ! 160: i = !eq(p1, p2); ! 161: break; ! 162: } ! 163: xfree(p1), xfree(p2); ! 164: return (i); ! 165: } ! 166: i = egetn(p1); ! 167: xfree(p1); ! 168: return (i); ! 169: } ! 170: ! 171: char * ! 172: exp3(vp, ignore) ! 173: register char ***vp; ! 174: bool ignore; ! 175: { ! 176: register char *p1, *p2; ! 177: register int i; ! 178: ! 179: p1 = exp3a(vp, ignore); ! 180: #ifdef EDEBUG ! 181: etracc("exp3 p1", p1, vp); ! 182: #endif ! 183: if (i = isa(**vp, RELOP)) { ! 184: (*vp)++; ! 185: if (**vp && eq(**vp, "=")) ! 186: i |= 1, (*vp)++; ! 187: p2 = exp3(vp, ignore); ! 188: #ifdef EDEBUG ! 189: etracc("exp3 p2", p2, vp); ! 190: #endif ! 191: if (!ignore) switch (i) { ! 192: ! 193: case GTR: ! 194: i = egetn(p1) > egetn(p2); ! 195: break; ! 196: ! 197: case GTR|1: ! 198: i = egetn(p1) >= egetn(p2); ! 199: break; ! 200: ! 201: case LSS: ! 202: i = egetn(p1) < egetn(p2); ! 203: break; ! 204: ! 205: case LSS|1: ! 206: i = egetn(p1) <= egetn(p2); ! 207: break; ! 208: } ! 209: xfree(p1), xfree(p2); ! 210: return (putn(i)); ! 211: } ! 212: return (p1); ! 213: } ! 214: ! 215: char * ! 216: exp3a(vp, ignore) ! 217: register char ***vp; ! 218: bool ignore; ! 219: { ! 220: register char *p1, *p2, *op; ! 221: register int i; ! 222: ! 223: p1 = exp4(vp, ignore); ! 224: #ifdef EDEBUG ! 225: etracc("exp3a p1", p1, vp); ! 226: #endif ! 227: op = **vp; ! 228: if (op && any(op[0], "<>") && op[0] == op[1]) { ! 229: (*vp)++; ! 230: p2 = exp3a(vp, ignore); ! 231: #ifdef EDEBUG ! 232: etracc("exp3a p2", p2, vp); ! 233: #endif ! 234: if (op[0] == '<') ! 235: i = egetn(p1) << egetn(p2); ! 236: else ! 237: i = egetn(p1) >> egetn(p2); ! 238: xfree(p1), xfree(p2); ! 239: return (putn(i)); ! 240: } ! 241: return (p1); ! 242: } ! 243: ! 244: char * ! 245: exp4(vp, ignore) ! 246: register char ***vp; ! 247: bool ignore; ! 248: { ! 249: register char *p1, *p2; ! 250: register int i = 0; ! 251: ! 252: p1 = exp5(vp, ignore); ! 253: #ifdef EDEBUG ! 254: etracc("exp4 p1", p1, vp); ! 255: #endif ! 256: if (isa(**vp, ADDOP)) { ! 257: register char *op = *(*vp)++; ! 258: ! 259: p2 = exp4(vp, ignore); ! 260: #ifdef EDEBUG ! 261: etracc("exp4 p2", p2, vp); ! 262: #endif ! 263: if (!ignore) switch (op[0]) { ! 264: ! 265: case '+': ! 266: i = egetn(p1) + egetn(p2); ! 267: break; ! 268: ! 269: case '-': ! 270: i = egetn(p1) - egetn(p2); ! 271: break; ! 272: } ! 273: xfree(p1), xfree(p2); ! 274: return (putn(i)); ! 275: } ! 276: return (p1); ! 277: } ! 278: ! 279: char * ! 280: exp5(vp, ignore) ! 281: register char ***vp; ! 282: bool ignore; ! 283: { ! 284: register char *p1, *p2; ! 285: register int i = 0; ! 286: ! 287: p1 = exp6(vp, ignore); ! 288: #ifdef EDEBUG ! 289: etracc("exp5 p1", p1, vp); ! 290: #endif ! 291: if (isa(**vp, MULOP)) { ! 292: register char *op = *(*vp)++; ! 293: ! 294: p2 = exp5(vp, ignore); ! 295: #ifdef EDEBUG ! 296: etracc("exp5 p2", p2, vp); ! 297: #endif ! 298: if (!ignore) switch (op[0]) { ! 299: ! 300: case '*': ! 301: i = egetn(p1) * egetn(p2); ! 302: break; ! 303: ! 304: case '/': ! 305: i = egetn(p2); ! 306: if (i == 0) ! 307: error("Divide by 0"); ! 308: i = egetn(p1) / i; ! 309: break; ! 310: ! 311: case '%': ! 312: i = egetn(p2); ! 313: if (i == 0) ! 314: error("Mod by 0"); ! 315: i = egetn(p1) % i; ! 316: break; ! 317: } ! 318: xfree(p1), xfree(p2); ! 319: return (putn(i)); ! 320: } ! 321: return (p1); ! 322: } ! 323: ! 324: char * ! 325: exp6(vp, ignore) ! 326: register char ***vp; ! 327: { ! 328: int ccode, i; ! 329: register char *cp, *dp, *ep; ! 330: ! 331: if (eq(**vp, "!")) { ! 332: (*vp)++; ! 333: cp = exp6(vp, ignore); ! 334: #ifdef EDEBUG ! 335: etracc("exp6 ! cp", cp, vp); ! 336: #endif ! 337: i = egetn(cp); ! 338: xfree(cp); ! 339: return (putn(!i)); ! 340: } ! 341: if (eq(**vp, "~")) { ! 342: (*vp)++; ! 343: cp = exp6(vp, ignore); ! 344: #ifdef EDEBUG ! 345: etracc("exp6 ~ cp", cp, vp); ! 346: #endif ! 347: i = egetn(cp); ! 348: xfree(cp); ! 349: return (putn(~i)); ! 350: } ! 351: if (eq(**vp, "(")) { ! 352: (*vp)++; ! 353: ccode = exp0(vp, ignore); ! 354: #ifdef EDEBUG ! 355: etraci("exp6 () ccode", ccode, vp); ! 356: #endif ! 357: if (*vp == 0 || **vp == 0 || ***vp != ')') ! 358: bferr("Expression syntax"); ! 359: (*vp)++; ! 360: return (putn(ccode)); ! 361: } ! 362: if (eq(**vp, "{")) { ! 363: int pid; ! 364: register char **v; ! 365: ! 366: (*vp)++; ! 367: v = *vp; ! 368: for (;;) { ! 369: if (!**vp) ! 370: bferr("Missing }"); ! 371: if (eq(*(*vp)++, "}")) ! 372: break; ! 373: } ! 374: if (ignore) ! 375: return (""); ! 376: pid = fork(); ! 377: if (pid < 0) ! 378: Perror("fork"); ! 379: if (pid == 0) { ! 380: if (setintr) ! 381: signal(SIGINT, SIG_DFL); ! 382: *--(*vp) = 0; ! 383: evalav(v); ! 384: exitstat(); ! 385: } ! 386: cadd(pid, "{}"); ! 387: pwait(pid); ! 388: #ifdef EDEBUG ! 389: etraci("exp6 {} status", egetn(value("status")), vp); ! 390: #endif ! 391: return (putn(egetn(value("status")) == 0)); ! 392: } ! 393: if (isa(**vp, ANYOP)) ! 394: return (""); ! 395: cp = *(*vp)++; ! 396: if (*cp == '-' && any(cp[1], "erwxfdzo")) { ! 397: struct stat stb; ! 398: ! 399: if (isa(**vp, ANYOP)) ! 400: bferr("Missing file name"); ! 401: dp = *(*vp)++; ! 402: if (ignore) ! 403: return (""); ! 404: ep = globone(dp); ! 405: switch (cp[1]) { ! 406: ! 407: case 'r': ! 408: i = !access(ep, 4); ! 409: break; ! 410: ! 411: case 'w': ! 412: i = !access(ep, 2); ! 413: break; ! 414: ! 415: case 'x': ! 416: i = !access(ep, 1); ! 417: break; ! 418: ! 419: default: ! 420: if (stat(ep, &stb)) { ! 421: xfree(ep); ! 422: return ("0"); ! 423: } ! 424: switch (cp[1]) { ! 425: ! 426: case 'f': ! 427: i = (stb.st_mode & S_IFMT) == S_IFREG; ! 428: break; ! 429: ! 430: case 'd': ! 431: i = (stb.st_mode & S_IFMT) == S_IFDIR; ! 432: break; ! 433: ! 434: case 'z': ! 435: i = stb.st_size == 0; ! 436: break; ! 437: ! 438: case 'e': ! 439: i = 1; ! 440: break; ! 441: ! 442: case 'o': ! 443: i = stb.st_uid == uid; ! 444: break; ! 445: } ! 446: } ! 447: #ifdef EDEBUG ! 448: etraci("exp6 -? i", i, vp); ! 449: #endif ! 450: xfree(ep); ! 451: return (putn(i)); ! 452: } ! 453: #ifdef EDEBUG ! 454: etracc("exp6 default", cp, vp); ! 455: #endif ! 456: return (globone(cp)); ! 457: } ! 458: ! 459: evalav(v) ! 460: register char **v; ! 461: { ! 462: struct wordent paraml; ! 463: register struct wordent *hp = ¶ml; ! 464: struct command *t; ! 465: register struct wordent *wdp = hp; ! 466: ! 467: child++; ! 468: set("status", "0"); ! 469: hp->prev = hp->next = hp; ! 470: hp->word = ""; ! 471: while (*v) { ! 472: register struct wordent *new = (struct wordent *) calloc(1, sizeof *wdp); ! 473: ! 474: new->prev = wdp; ! 475: new->next = hp; ! 476: wdp->next = new; ! 477: wdp = new; ! 478: wdp->word = savestr(*v++); ! 479: } ! 480: hp->prev = wdp; ! 481: alias(¶ml); ! 482: t = syntax(paraml.next, ¶ml); ! 483: if (err) ! 484: error(err); ! 485: execute(t); ! 486: freelex(¶ml), freesyn(t); ! 487: } ! 488: ! 489: isa(cp, what) ! 490: register char *cp; ! 491: register int what; ! 492: { ! 493: ! 494: if (cp == 0) ! 495: return ((what & RESTOP) != 0); ! 496: if (cp[1] == 0) { ! 497: if ((what & ADDOP) && any(cp[0], "+-")) ! 498: return (1); ! 499: if ((what & MULOP) && any(cp[0], "*/%")) ! 500: return (1); ! 501: if ((what & RESTOP) && any(cp[0], "()!~^")) ! 502: return (1); ! 503: } ! 504: if ((what & RESTOP) && (any(cp[0], "|&") || eq(cp, "<<") || eq(cp, ">>"))) ! 505: return (1); ! 506: if (what & EQOP) { ! 507: if (eq(cp, "==")) ! 508: return (EQEQ); ! 509: if (eq(cp, "!=")) ! 510: return (NOTEQ); ! 511: } ! 512: if (!(what & RELOP)) ! 513: return (0); ! 514: if (*cp == '<') ! 515: return (LSS); ! 516: if (*cp == '>') ! 517: return (GTR); ! 518: return (0); ! 519: } ! 520: ! 521: egetn(cp) ! 522: register char *cp; ! 523: { ! 524: ! 525: if (*cp && *cp != '-' && !digit(*cp)) ! 526: bferr("Expression syntax"); ! 527: return (getn(cp)); ! 528: } ! 529: ! 530: /* Phew! */ ! 531: ! 532: #ifdef EDEBUG ! 533: etraci(str, i, vp) ! 534: char *str; ! 535: int i; ! 536: char ***vp; ! 537: { ! 538: ! 539: printf("%s=%d\t", str, i); ! 540: blkpr(*vp); ! 541: printf("\n"); ! 542: } ! 543: ! 544: etracc(str, cp, vp) ! 545: char *str, *cp; ! 546: char ***vp; ! 547: { ! 548: ! 549: printf("%s=%s\t", str, cp); ! 550: blkpr(*vp); ! 551: printf("\n"); ! 552: } ! 553: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.