Annotation of 43BSDReno/games/warp/intrp.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.