Annotation of 43BSDReno/games/warp/intrp.c, revision 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.