|
|
1.1 ! root 1: /* $Header: /usr/src/games/warp/RCS/intrp.c,v 1.2 87/07/03 00:56:37 games Exp $ ! 2: * ! 3: * Revision 7.0.1.2 86/12/12 16:59:04 lwall ! 4: * Baseline for net release. ! 5: * ! 6: * Revision 7.0.1.1 86/10/16 10:51:43 lwall ! 7: * Added Damage. Fixed random bugs. ! 8: * ! 9: * Revision 7.0 86/10/08 15:12:19 lwall ! 10: * Split into separate files. Added amoebas and pirates. ! 11: * ! 12: */ ! 13: ! 14: #include "EXTERN.h" ! 15: #include "warp.h" ! 16: #include "sig.h" ! 17: #include "util.h" ! 18: #include "term.h" ! 19: #include "INTERN.h" ! 20: #include "intrp.h" ! 21: ! 22: /* name of this host */ ! 23: char *hostname; ! 24: ! 25: #ifdef TILDENAME ! 26: static char *tildename = Nullch; ! 27: static char *tildedir = Nullch; ! 28: #endif ! 29: ! 30: char *dointerp(); ! 31: char *getrealname(); ! 32: #ifdef CONDSUB ! 33: char *skipinterp(); ! 34: #endif ! 35: ! 36: static void abort_interp(); ! 37: ! 38: void ! 39: intrp_init(tcbuf) ! 40: char *tcbuf; ! 41: { ! 42: char *getlogin(); ! 43: ! 44: /* get environmental stuff */ ! 45: ! 46: /* get home directory */ ! 47: ! 48: homedir = getenv("HOME"); ! 49: if (homedir == Nullch) ! 50: homedir = getenv("LOGDIR"); ! 51: ! 52: dotdir = getval("DOTDIR",homedir); ! 53: ! 54: /* get login name */ ! 55: ! 56: logname = getenv("USER"); ! 57: if (logname == Nullch) ! 58: logname = getenv("LOGNAME"); ! 59: #ifdef GETLOGIN ! 60: if (logname == Nullch) ! 61: logname = savestr(getlogin()); ! 62: #endif ! 63: ! 64: /* get the real name of the person (%N) */ ! 65: /* Must be done after logname is read in because BERKNAMES uses that */ ! 66: ! 67: strcpy(tcbuf,getrealname(getuid())); ! 68: realname = savestr(tcbuf); ! 69: ! 70: /* name of this host (%H) */ ! 71: ! 72: gethostname(buf,sizeof buf); ! 73: hostname = savestr(buf); ! 74: if (index(hostname,'.')) ! 75: hostname = savestr(hostname); ! 76: else { ! 77: char hname[128]; ! 78: ! 79: strcpy(hname,hostname); ! 80: strcat(hname,MYDOMAIN); ! 81: hostname=savestr(hname); ! 82: } ! 83: warplib = savestr(filexp(WARPLIB)); ! 84: ! 85: if (scorespec) /* that getwd below takes ~1/3 sec. */ ! 86: return; /* and we do not need it for -s */ ! 87: (void) getwd(tcbuf); /* find working directory name */ ! 88: origdir = savestr(tcbuf); /* and remember it */ ! 89: } ! 90: ! 91: /* expand filename via %, ~, and $ interpretation */ ! 92: /* returns pointer to static area */ ! 93: /* Note that there is a 1-deep cache of ~name interpretation */ ! 94: ! 95: char * ! 96: filexp(s) ! 97: Reg1 char *s; ! 98: { ! 99: static char filename[CBUFLEN]; ! 100: char scrbuf[CBUFLEN]; ! 101: Reg2 char *d; ! 102: ! 103: #ifdef DEBUGGING ! 104: if (debug & DEB_FILEXP) ! 105: printf("< %s\r\n",s); ! 106: #endif ! 107: interp(filename, (sizeof filename), s); /* interpret any % escapes */ ! 108: #ifdef DEBUGGING ! 109: if (debug & DEB_FILEXP) ! 110: printf("%% %s\r\n",filename); ! 111: #endif ! 112: s = filename; ! 113: if (*s == '~') { /* does destination start with ~? */ ! 114: if (!*(++s) || *s == '/') { ! 115: Sprintf(scrbuf,"%s%s",homedir,s); ! 116: /* swap $HOME for it */ ! 117: #ifdef DEBUGGING ! 118: if (debug & DEB_FILEXP) ! 119: printf("~ %s\r\n",scrbuf); ! 120: #endif ! 121: strcpy(filename,scrbuf); ! 122: } ! 123: else { ! 124: #ifdef TILDENAME ! 125: for (d=scrbuf; isalnum(*s); s++,d++) ! 126: *d = *s; ! 127: *d = '\0'; ! 128: if (tildedir && strEQ(tildename,scrbuf)) { ! 129: strcpy(scrbuf,tildedir); ! 130: strcat(scrbuf, s); ! 131: strcpy(filename, scrbuf); ! 132: #ifdef DEBUGGING ! 133: if (debug & DEB_FILEXP) ! 134: printf("r %s %s\r\n",tildename,tildedir); ! 135: #endif ! 136: } ! 137: else { ! 138: if (tildename) { ! 139: free(tildename); ! 140: free(tildedir); ! 141: } ! 142: tildedir = Nullch; ! 143: tildename = savestr(scrbuf); ! 144: { ! 145: struct passwd *getpwnam(); ! 146: struct passwd *pwd = getpwnam(tildename); ! 147: ! 148: Sprintf(scrbuf,"%s%s",pwd->pw_dir,s); ! 149: tildedir = savestr(pwd->pw_dir); ! 150: strcpy(filename,scrbuf); ! 151: endpwent(); ! 152: } ! 153: } ! 154: #else /* !TILDENAME */ ! 155: #ifdef VERBOSE ! 156: IF(verbose) ! 157: fputs("~loginname not implemented.\r\n",stdout); ! 158: ELSE ! 159: #endif ! 160: #ifdef TERSE ! 161: fputs("~login not impl.\r\n",stdout); ! 162: #endif ! 163: #endif ! 164: } ! 165: } ! 166: else if (*s == '$') { /* starts with some env variable? */ ! 167: d = scrbuf; ! 168: *d++ = '%'; ! 169: if (s[1] == '{') ! 170: strcpy(d,s+2); ! 171: else { ! 172: *d++ = '{'; ! 173: for (s++; isalnum(*s); s++) *d++ = *s; ! 174: /* skip over token */ ! 175: *d++ = '}'; ! 176: strcpy(d,s); ! 177: } ! 178: #ifdef DEBUGGING ! 179: if (debug & DEB_FILEXP) ! 180: printf("$ %s\r\n",scrbuf); ! 181: #endif ! 182: interp(filename, (sizeof filename), scrbuf); ! 183: /* this might do some extra '%'s but */ ! 184: /* that is how the Mercedes Benz */ ! 185: } ! 186: #ifdef DEBUGGING ! 187: if (debug & DEB_FILEXP) ! 188: printf("> %s\r\n",filename); ! 189: #endif ! 190: return filename; ! 191: } ! 192: ! 193: #ifdef CONDSUB ! 194: /* skip interpolations */ ! 195: ! 196: char * ! 197: skipinterp(pattern,stoppers) ! 198: Reg1 char *pattern; ! 199: char *stoppers; ! 200: { ! 201: ! 202: while (*pattern && (!stoppers || !index(stoppers,*pattern))) { ! 203: #ifdef DEBUGGING ! 204: if (debug & 8) ! 205: printf("skipinterp till %s at %s\r\n",stoppers?stoppers:"",pattern); ! 206: #endif ! 207: if (*pattern == '%' && pattern[1]) { ! 208: switch (*++pattern) { ! 209: case '{': ! 210: for (pattern++; *pattern && *pattern != '}'; pattern++) ! 211: if (*pattern == '\\') ! 212: pattern++; ! 213: break; ! 214: #ifdef CONDSUB ! 215: case '(': { ! 216: pattern = skipinterp(pattern+1,"!="); ! 217: if (!*pattern) ! 218: goto getout; ! 219: for (pattern++; *pattern && *pattern != '?'; pattern++) ! 220: if (*pattern == '\\') ! 221: pattern++; ! 222: if (!*pattern) ! 223: goto getout; ! 224: pattern = skipinterp(pattern+1,":)"); ! 225: if (*pattern == ':') ! 226: pattern = skipinterp(pattern+1,")"); ! 227: break; ! 228: } ! 229: #endif ! 230: #ifdef BACKTICK ! 231: case '`': { ! 232: pattern = skipinterp(pattern+1,"`"); ! 233: break; ! 234: } ! 235: #endif ! 236: #ifdef PROMPTTTY ! 237: case '"': ! 238: pattern = skipinterp(pattern+1,"\""); ! 239: break; ! 240: #endif ! 241: default: ! 242: break; ! 243: } ! 244: pattern++; ! 245: } ! 246: else { ! 247: if (*pattern == '^' && pattern[1]) ! 248: pattern += 2; ! 249: else if (*pattern == '\\' && pattern[1]) ! 250: pattern += 2; ! 251: else ! 252: pattern++; ! 253: } ! 254: } ! 255: getout: ! 256: return pattern; /* where we left off */ ! 257: } ! 258: #endif ! 259: ! 260: /* interpret interpolations */ ! 261: ! 262: char * ! 263: dointerp(dest,destsize,pattern,stoppers) ! 264: Reg1 char *dest; ! 265: Reg2 int destsize; ! 266: Reg3 char *pattern; ! 267: char *stoppers; ! 268: { ! 269: Reg4 char *s; ! 270: Reg5 int i; ! 271: char scrbuf[512]; ! 272: bool upper = FALSE; ! 273: bool lastcomp = FALSE; ! 274: int metabit = 0; ! 275: ! 276: while (*pattern && (!stoppers || !index(stoppers,*pattern))) { ! 277: #ifdef DEBUGGING ! 278: if (debug & 8) ! 279: printf("dointerp till %s at %s\r\n",stoppers?stoppers:"",pattern); ! 280: #endif ! 281: if (*pattern == '%' && pattern[1]) { ! 282: upper = FALSE; ! 283: lastcomp = FALSE; ! 284: for (s=Nullch; !s; ) { ! 285: switch (*++pattern) { ! 286: case '^': ! 287: upper = TRUE; ! 288: break; ! 289: case '_': ! 290: lastcomp = TRUE; ! 291: break; ! 292: case '{': ! 293: pattern = cpytill(scrbuf,pattern+1,'}'); ! 294: if (s = index(scrbuf,'-')) ! 295: *s++ = '\0'; ! 296: else ! 297: s = nullstr; ! 298: s = getval(scrbuf,s); ! 299: break; ! 300: #ifdef CONDSUB ! 301: case '(': { ! 302: char rch; ! 303: bool matched; ! 304: ! 305: pattern = dointerp(dest,destsize,pattern+1,"!="); ! 306: rch = *pattern; ! 307: if (rch == '!') ! 308: pattern++; ! 309: if (*pattern != '=') ! 310: goto getout; ! 311: pattern = cpytill(scrbuf,pattern+1,'?'); ! 312: if (!*pattern) ! 313: goto getout; ! 314: if (*scrbuf == '^' && scrbuf[strlen(scrbuf)-1] == '$') { ! 315: scrbuf[strlen(scrbuf)-1] = '\0'; ! 316: matched = strEQ(scrbuf+1,dest); ! 317: } ! 318: else ! 319: matched = instr(dest,scrbuf) != Nullch; ! 320: if (matched==(rch == '=')) { ! 321: pattern = dointerp(dest,destsize,pattern+1,":)"); ! 322: if (*pattern == ':') ! 323: pattern = skipinterp(pattern+1,")"); ! 324: } ! 325: else { ! 326: pattern = skipinterp(pattern+1,":)"); ! 327: if (*pattern == ':') ! 328: pattern++; ! 329: pattern = dointerp(dest,destsize,pattern,")"); ! 330: } ! 331: s = dest; ! 332: break; ! 333: } ! 334: #endif ! 335: #ifdef BACKTICK ! 336: case '`': { ! 337: FILE *pipefp, *popen(); ! 338: ! 339: pattern = dointerp(scrbuf,(sizeof scrbuf),pattern+1,"`"); ! 340: pipefp = popen(scrbuf,"r"); ! 341: if (pipefp != Nullfp) { ! 342: int len; ! 343: ! 344: len = fread(scrbuf,sizeof(char),(sizeof scrbuf)-1, ! 345: pipefp); ! 346: scrbuf[len] = '\0'; ! 347: pclose(pipefp); ! 348: } ! 349: else { ! 350: printf("\r\nCan't run %s\r\n",scrbuf); ! 351: *scrbuf = '\0'; ! 352: } ! 353: for (s=scrbuf; *s; s++) { ! 354: if (*s == '\n') { ! 355: if (s[1]) ! 356: *s = ' '; ! 357: else ! 358: *s = '\0'; ! 359: } ! 360: } ! 361: s = scrbuf; ! 362: break; ! 363: } ! 364: #endif ! 365: #ifdef PROMPTTTY ! 366: case '"': ! 367: pattern = dointerp(scrbuf,(sizeof scrbuf),pattern+1,"\""); ! 368: fputs(scrbuf,stdout); ! 369: resetty(); ! 370: gets(scrbuf); ! 371: crmode(); ! 372: raw(); ! 373: noecho(); ! 374: nonl(); ! 375: s = scrbuf; ! 376: break; ! 377: #endif ! 378: case '~': ! 379: s = homedir; ! 380: break; ! 381: case '.': ! 382: s = dotdir; ! 383: break; ! 384: case '$': ! 385: s = scrbuf; ! 386: Sprintf(s,"%d",getpid()); ! 387: break; ! 388: case 'H': /* host name */ ! 389: s = hostname; ! 390: break; ! 391: case 'L': /* login id */ ! 392: s = logname; ! 393: break; ! 394: case 'N': /* full name */ ! 395: s = getval("NAME",realname); ! 396: break; ! 397: case 'O': ! 398: s = origdir; ! 399: break; ! 400: case 'p': ! 401: s = cwd; ! 402: break; ! 403: case 'X': /* warp library */ ! 404: s = warplib; ! 405: break; ! 406: default: ! 407: if (--destsize <= 0) ! 408: abort_interp(); ! 409: *dest++ = *pattern | metabit; ! 410: s = nullstr; ! 411: break; ! 412: } ! 413: } ! 414: if (!s) ! 415: s = nullstr; ! 416: pattern++; ! 417: if (upper || lastcomp) { ! 418: char *t; ! 419: ! 420: if (s != scrbuf) { ! 421: Safecpy(scrbuf,s,(sizeof scrbuf)); ! 422: s = scrbuf; ! 423: } ! 424: if (upper || !(t=rindex(s,'/'))) ! 425: t = s; ! 426: while (*t && !isalpha(*t)) ! 427: t++; ! 428: if (islower(*t)) ! 429: *t = toupper(*t); ! 430: } ! 431: i = metabit; /* maybe get into register */ ! 432: if (s == dest) { ! 433: while (*dest) { ! 434: if (--destsize <= 0) ! 435: abort_interp(); ! 436: *dest++ |= i; ! 437: } ! 438: } ! 439: else { ! 440: while (*s) { ! 441: if (--destsize <= 0) ! 442: abort_interp(); ! 443: *dest++ = *s++ | i; ! 444: } ! 445: } ! 446: } ! 447: else { ! 448: if (--destsize <= 0) ! 449: abort_interp(); ! 450: if (*pattern == '^' && pattern[1]) { ! 451: ++pattern; /* skip uparrow */ ! 452: i = *pattern; /* get char into a register */ ! 453: if (i == '?') ! 454: *dest++ = '\177' | metabit; ! 455: else if (i == '(') { ! 456: metabit = 0200; ! 457: destsize++; ! 458: } ! 459: else if (i == ')') { ! 460: metabit = 0; ! 461: destsize++; ! 462: } ! 463: else ! 464: *dest++ = i & 037 | metabit; ! 465: pattern++; ! 466: } ! 467: else if (*pattern == '\\' && pattern[1]) { ! 468: ++pattern; /* skip backslash */ ! 469: i = *pattern; /* get char into a register */ ! 470: ! 471: /* this used to be a switch but the if may save space */ ! 472: ! 473: if (i >= '0' && i <= '7') { ! 474: i = 1; ! 475: while (i < 01000 && *pattern >= '0' && *pattern <= '7') { ! 476: i <<= 3; ! 477: i += *pattern++ - '0'; ! 478: } ! 479: *dest++ = i & 0377 | metabit; ! 480: --pattern; ! 481: } ! 482: else if (i == 'b') ! 483: *dest++ = '\b' | metabit; ! 484: else if (i == 'f') ! 485: *dest++ = '\f' | metabit; ! 486: else if (i == 'n') ! 487: *dest++ = '\n' | metabit; ! 488: else if (i == 'r') ! 489: *dest++ = '\r' | metabit; ! 490: else if (i == 't') ! 491: *dest++ = '\t' | metabit; ! 492: else ! 493: *dest++ = i | metabit; ! 494: pattern++; ! 495: } ! 496: else ! 497: *dest++ = *pattern++ | metabit; ! 498: } ! 499: } ! 500: *dest = '\0'; ! 501: getout: ! 502: return pattern; /* where we left off */ ! 503: } ! 504: ! 505: void ! 506: interp(dest,destsize,pattern) ! 507: char *dest; ! 508: int destsize; ! 509: char *pattern; ! 510: { ! 511: (void) dointerp(dest,destsize,pattern,Nullch); ! 512: #ifdef DEBUGGING ! 513: if (debug & DEB_FILEXP) ! 514: fputs(dest,stdout); ! 515: #endif ! 516: } ! 517: ! 518: /* get the person's real name from /etc/passwd */ ! 519: /* (string is overwritten, so it must be copied) */ ! 520: ! 521: char * ! 522: getrealname(uid) ! 523: int uid; ! 524: { ! 525: char *s, *c; ! 526: ! 527: #ifdef PASSNAMES ! 528: struct passwd *pwd = getpwuid(uid); ! 529: ! 530: s = pwd->pw_gecos; ! 531: #ifdef BERKNAMES ! 532: #ifdef BERKJUNK ! 533: while (*s && !isalnum(*s) && *s != '&') s++; ! 534: #endif ! 535: if ((c = index(s, ',')) != Nullch) ! 536: *c = '\0'; ! 537: if ((c = index(s, ';')) != Nullch) ! 538: *c = '\0'; ! 539: s = cpytill(buf,s,'&'); ! 540: if (*s == '&') { /* whoever thought this one up was */ ! 541: c = buf + strlen(buf); /* in the middle of the night */ ! 542: strcat(c,logname); /* before the morning after */ ! 543: strcat(c,s+1); ! 544: if (islower(*c)) ! 545: *c = toupper(*c); /* gack and double gack */ ! 546: } ! 547: #else ! 548: if ((c = index(s, '(')) != Nullch) ! 549: *c = '\0'; ! 550: if ((c = index(s, '-')) != Nullch) ! 551: s = c; ! 552: strcpy(buf,tmpbuf); ! 553: #endif ! 554: endpwent(); ! 555: return buf; /* return something static */ ! 556: #else ! 557: if ((tmpfp=fopen(filexp(FULLNAMEFILE),"r")) != Nullfp) { ! 558: Fgets(buf,sizeof buf,tmpfp); ! 559: Fclose(tmpfp); ! 560: } ! 561: else { ! 562: resetty(); ! 563: printf("What is your name? "); ! 564: Fgets(buf,(sizeof buf),stdin); ! 565: crmode(); ! 566: raw(); ! 567: noecho(); ! 568: nonl(); ! 569: if (fork()) ! 570: wait(0); ! 571: else { ! 572: setuid(getuid()); ! 573: if ((tmpfp = fopen(filexp(FULLNAMEFILE),"w")) == NULL) ! 574: exit(1); ! 575: fprintf(tmpfp, "%s\n", buf); ! 576: Fclose(tmpfp); ! 577: exit(0); ! 578: } ! 579: } ! 580: buf[strlen(buf)-1] = '\0'; ! 581: return buf; ! 582: #endif ! 583: } ! 584: ! 585: static void ! 586: abort_interp() ! 587: { ! 588: fputs("\r\n% interp buffer overflow!\r\n",stdout); ! 589: sig_catcher(0); ! 590: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.