Annotation of 43BSDReno/games/atc/input.c, revision 1.1.1.1

1.1       root        1: /*-
                      2:  * Copyright (c) 1990 The Regents of the University of California.
                      3:  * All rights reserved.
                      4:  *
                      5:  * This code is derived from software contributed to Berkeley by
                      6:  * Ed James.
                      7:  *
                      8:  * Redistribution and use in source and binary forms are permitted
                      9:  * provided that: (1) source distributions retain this entire copyright
                     10:  * notice and comment, and (2) distributions including binaries display
                     11:  * the following acknowledgement:  ``This product includes software
                     12:  * developed by the University of California, Berkeley and its contributors''
                     13:  * in the documentation or other materials provided with the distribution
                     14:  * and in all advertising materials mentioning features or use of this
                     15:  * software. Neither the name of the University nor the names of its
                     16:  * contributors may be used to endorse or promote products derived
                     17:  * from this software without specific prior written permission.
                     18:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
                     19:  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
                     20:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
                     21:  */
                     22: 
                     23: /*
                     24:  * Copyright (c) 1987 by Ed James, UC Berkeley.  All rights reserved.
                     25:  *
                     26:  * Copy permission is hereby granted provided that this notice is
                     27:  * retained on all partial or complete copies.
                     28:  *
                     29:  * For more info on this and all of my stuff, mail [email protected].
                     30:  */
                     31: 
                     32: #ifndef lint
                     33: static char sccsid[] = "@(#)input.c    5.4 (Berkeley) 4/30/90";
                     34: #endif not lint
                     35: 
                     36: #include "include.h"
                     37: #include "pathnames.h"
                     38: 
                     39: #define MAXRULES       6
                     40: #define MAXDEPTH       15
                     41: 
                     42: #define RETTOKEN       '\n'
                     43: #ifdef SYSV
                     44: #define CRTOKEN                '\r'
                     45: #endif
                     46: #define REDRAWTOKEN    '\014'  /* CTRL(L) */
                     47: #define        SHELLTOKEN      '!'
                     48: #define HELPTOKEN      '?'
                     49: #define ALPHATOKEN     256
                     50: #define NUMTOKEN       257
                     51: 
                     52: typedef struct {
                     53:        int     token;
                     54:        int     to_state;
                     55:        char    *str;
                     56:        char    *(*func)();
                     57: } RULE;
                     58: 
                     59: typedef struct {
                     60:        int     num_rules;
                     61:        RULE    *rule;
                     62: } STATE;
                     63: 
                     64: typedef struct {
                     65:        char    str[20];
                     66:        int     state;
                     67:        int     rule;
                     68:        int     ch;
                     69:        int     pos;
                     70: } STACK;
                     71: 
                     72: #define T_RULE         stack[level].rule
                     73: #define T_STATE                stack[level].state
                     74: #define T_STR          stack[level].str
                     75: #define T_POS          stack[level].pos
                     76: #define        T_CH            stack[level].ch
                     77: 
                     78: #define NUMELS(a)      (sizeof (a) / sizeof (*(a)))
                     79: 
                     80: #define NUMSTATES      NUMELS(st)
                     81: 
                     82: char   *setplane(), *circle(), *left(), *right(), *Left(), *Right(), 
                     83:        *beacon(), *ex_it(), *climb(), *descend(), *setalt(), *setrelalt(), 
                     84:        *benum(), *to_dir(), *rel_dir(), *delayb(), *mark(), *unmark(),
                     85:        *airport(), *turn(), *ignore();
                     86: 
                     87: RULE   state0[] = {    { ALPHATOKEN,   1,      "%c:",          setplane},
                     88:                        { RETTOKEN,     -1,     "",             NULL    },
                     89: #ifdef SYSV
                     90:                        { CRTOKEN,      -1,     "",             NULL    },
                     91: #endif
                     92:                        { HELPTOKEN,    12,     " [a-z]<ret>",  NULL    }},
                     93:        state1[] = {    { 't',          2,      " turn",        turn    },      
                     94:                        { 'a',          3,      " altitude:",   NULL    },      
                     95:                        { 'c',          4,      " circle",      circle  },
                     96:                        { 'm',          7,      " mark",        mark    },
                     97:                        { 'u',          7,      " unmark",      unmark  },
                     98:                        { 'i',          7,      " ignore",      ignore  },
                     99:                        { HELPTOKEN,    12,     " tacmui",      NULL    }},
                    100:        state2[] = {    { 'l',          6,      " left",        left    },      
                    101:                        { 'r',          6,      " right",       right   },      
                    102:                        { 'L',          4,      " left 90",     Left    },
                    103:                        { 'R',          4,      " right 90",    Right   },      
                    104:                        { 't',          11,     " towards",     NULL    },
                    105:                        { 'w',          4,      " to 0",        to_dir  },
                    106:                        { 'e',          4,      " to 45",       to_dir  },
                    107:                        { 'd',          4,      " to 90",       to_dir  },
                    108:                        { 'c',          4,      " to 135",      to_dir  },
                    109:                        { 'x',          4,      " to 180",      to_dir  },
                    110:                        { 'z',          4,      " to 225",      to_dir  },
                    111:                        { 'a',          4,      " to 270",      to_dir  },
                    112:                        { 'q',          4,      " to 315",      to_dir  },
                    113:                        { HELPTOKEN,    12,     " lrLRt<dir>",  NULL    }},
                    114:        state3[] = {    { '+',          10,     " climb",       climb   },      
                    115:                        { 'c',          10,     " climb",       climb   },      
                    116:                        { '-',          10,     " descend",     descend },      
                    117:                        { 'd',          10,     " descend",     descend },      
                    118:                        { NUMTOKEN,     7,      " %c000 feet",  setalt  },
                    119:                        { HELPTOKEN,    12,     " +-cd[0-9]",   NULL    }},
                    120:        state4[] = {    { '@',          9,      " at",          NULL    },      
                    121:                        { 'a',          9,      " at",          NULL    },      
                    122:                        { RETTOKEN,     -1,     "",             NULL    },
                    123: #ifdef SYSV
                    124:                        { CRTOKEN,      -1,     "",             NULL    },
                    125: #endif
                    126:                        { HELPTOKEN,    12,     " @a<ret>",     NULL    }},
                    127:        state5[] = {    { NUMTOKEN,     7,      "%c",           delayb  },
                    128:                        { HELPTOKEN,    12,     " [0-9]",       NULL    }},
                    129:        state6[] = {    { '@',          9,      " at",          NULL    },
                    130:                        { 'a',          9,      " at",          NULL    },
                    131:                        { 'w',          4,      " 0",           rel_dir },
                    132:                        { 'e',          4,      " 45",          rel_dir },
                    133:                        { 'd',          4,      " 90",          rel_dir },
                    134:                        { 'c',          4,      " 135",         rel_dir },
                    135:                        { 'x',          4,      " 180",         rel_dir },
                    136:                        { 'z',          4,      " 225",         rel_dir },
                    137:                        { 'a',          4,      " 270",         rel_dir },
                    138:                        { 'q',          4,      " 315",         rel_dir },
                    139:                        { RETTOKEN,     -1,     "",             NULL    },      
                    140: #ifdef SYSV
                    141:                        { CRTOKEN,      -1,     "",             NULL    },      
                    142: #endif
                    143:                        { HELPTOKEN,    12,     " @a<dir><ret>",NULL    }},
                    144:        state7[] = {    { RETTOKEN,     -1,     "",             NULL    },
                    145: #ifdef SYSV
                    146:                        { CRTOKEN,      -1,     "",             NULL    },
                    147: #endif
                    148:                        { HELPTOKEN,    12,     " <ret>",       NULL    }},
                    149:        state8[] = {    { NUMTOKEN,     4,      "%c",           benum   },
                    150:                        { HELPTOKEN,    12,     " [0-9]",       NULL    }},
                    151:        state9[] = {    { 'b',          5,      " beacon #",    NULL    },
                    152:                        { '*',          5,      " beacon #",    NULL    },
                    153:                        { HELPTOKEN,    12,     " b*",          NULL    }},
                    154:        state10[] = {   { NUMTOKEN,     7,      " %c000 ft",    setrelalt},
                    155:                        { HELPTOKEN,    12,     " [0-9]",       NULL    }},
                    156:        state11[] = {   { 'b',          8,      " beacon #",    beacon  },      
                    157:                        { '*',          8,      " beacon #",    beacon  },
                    158:                        { 'e',          8,      " exit #",      ex_it   },
                    159:                        { 'a',          8,      " airport #",   airport },
                    160:                        { HELPTOKEN,    12,     " b*ea",        NULL    }},
                    161:        state12[] = {   { -1,           -1,     "",             NULL    }};
                    162: 
                    163: #define DEF_STATE(s)   { NUMELS(s),    (s)     }
                    164: 
                    165: STATE  st[] = {
                    166:        DEF_STATE(state0), DEF_STATE(state1), DEF_STATE(state2),
                    167:        DEF_STATE(state3), DEF_STATE(state4), DEF_STATE(state5),
                    168:        DEF_STATE(state6), DEF_STATE(state7), DEF_STATE(state8),
                    169:        DEF_STATE(state9), DEF_STATE(state10), DEF_STATE(state11),
                    170:        DEF_STATE(state12)
                    171: };
                    172: 
                    173: PLANE  p;
                    174: STACK  stack[MAXDEPTH];
                    175: int    level;
                    176: int    tval;
                    177: int    dest_type, dest_no, dir;
                    178: 
                    179: pop()
                    180: {
                    181:        if (level == 0)
                    182:                return (-1);
                    183:        level--;
                    184: 
                    185:        ioclrtoeol(T_POS);
                    186: 
                    187:        strcpy(T_STR, "");
                    188:        T_RULE = -1;
                    189:        T_CH = -1;
                    190:        return (0);
                    191: }
                    192: 
                    193: rezero()
                    194: {
                    195:        iomove(0);
                    196: 
                    197:        level = 0;
                    198:        T_STATE = 0;
                    199:        T_RULE = -1;
                    200:        T_CH = -1;
                    201:        T_POS = 0;
                    202:        strcpy(T_STR, "");
                    203: }
                    204: 
                    205: push(ruleno, ch)
                    206: {
                    207:        int     newstate, newpos;
                    208: 
                    209:        (void)sprintf(T_STR, st[T_STATE].rule[ruleno].str, tval);
                    210:        T_RULE = ruleno;
                    211:        T_CH = ch;
                    212:        newstate = st[T_STATE].rule[ruleno].to_state;
                    213:        newpos = T_POS + strlen(T_STR);
                    214: 
                    215:        ioaddstr(T_POS, T_STR);
                    216: 
                    217:        if (level == 0)
                    218:                ioclrtobot();
                    219:        level++;
                    220:        T_STATE = newstate;
                    221:        T_POS = newpos;
                    222:        T_RULE = -1;
                    223:        strcpy(T_STR, "");
                    224: }
                    225: 
                    226: getcommand()
                    227: {
                    228:        int     c, i, done;
                    229:        char    *s, *(*func)();
                    230:        PLANE   *pp;
                    231: 
                    232:        rezero();
                    233: 
                    234:        do {
                    235:                c = gettoken();
                    236:                if (c == tty_new.sg_erase) {
                    237:                        if (pop() < 0)
                    238:                                noise();
                    239:                } else if (c == tty_new.sg_kill) {
                    240:                        while (pop() >= 0)
                    241:                                ;
                    242:                } else {
                    243:                        done = 0;
                    244:                        for (i = 0; i < st[T_STATE].num_rules; i++) {
                    245:                                if (st[T_STATE].rule[i].token == c ||
                    246:                                    st[T_STATE].rule[i].token == tval) {
                    247:                                        push(i, (c >= ALPHATOKEN) ? tval : c);
                    248:                                        done = 1;
                    249:                                        break;
                    250:                                }
                    251:                        }
                    252:                        if (!done)
                    253:                                noise();
                    254:                }
                    255:        } while (T_STATE != -1);
                    256: 
                    257:        if (level == 1)
                    258:                return (1);     /* forced update */
                    259: 
                    260:        dest_type = T_NODEST;
                    261:        
                    262:        for (i = 0; i < level; i++) {
                    263:                func = st[stack[i].state].rule[stack[i].rule].func;
                    264:                if (func != NULL)
                    265:                        if ((s = (*func)(stack[i].ch)) != NULL) {
                    266:                                ioerror(stack[i].pos, strlen(stack[i].str), s);
                    267:                                return (-1);
                    268:                        }
                    269:        }
                    270: 
                    271:        pp = findplane(p.plane_no);
                    272:        if (pp->new_altitude != p.new_altitude)
                    273:                pp->new_altitude = p.new_altitude;
                    274:        else if (pp->status != p.status)
                    275:                pp->status = p.status;
                    276:        else {
                    277:                pp->new_dir = p.new_dir;
                    278:                pp->delayd = p.delayd;
                    279:                pp->delayd_no = p.delayd_no;
                    280:        }
                    281:        return (0);
                    282: }
                    283: 
                    284: noise()
                    285: {
                    286:        putchar('\07');
                    287:        fflush(stdout);
                    288: }
                    289: 
                    290: gettoken()
                    291: {
                    292:        while ((tval = getAChar()) == REDRAWTOKEN || tval == SHELLTOKEN)
                    293:        {
                    294:                if (tval == SHELLTOKEN)
                    295:                {
                    296: #ifdef BSD
                    297:                        struct itimerval        itv;
                    298:                        itv.it_value.tv_sec = 0;
                    299:                        itv.it_value.tv_usec = 0;
                    300:                        setitimer(ITIMER_REAL, &itv, NULL);
                    301: #endif
                    302: #ifdef SYSV
                    303:                        int aval;
                    304:                        aval = alarm(0);
                    305: #endif
                    306:                        if (fork() == 0)        /* child */
                    307:                        {
                    308:                                char *shell, *base, *getenv(), *strrchr();
                    309: 
                    310:                                setuid(getuid()); /* turn off setuid bit */
                    311:                                done_screen();
                    312: 
                    313:                                                 /* run user's favorite shell */
                    314:                                if ((shell = getenv("SHELL")) != NULL)
                    315:                                {
                    316:                                        base = strrchr(shell, '/');
                    317:                                        if (base == NULL)
                    318:                                                base = shell;
                    319:                                        else
                    320:                                                base++;
                    321:                                        execl(shell, base, 0);
                    322:                                }
                    323:                                else
                    324:                                        execl(_PATH_BSHELL, "sh", 0);
                    325: 
                    326:                                exit(0);        /* oops */
                    327:                        }
                    328: 
                    329:                        wait(0);
                    330: #ifdef BSD
                    331:                        ioctl(fileno(stdin), TIOCSETP, &tty_new);
                    332:                        itv.it_value.tv_sec = 0;
                    333:                        itv.it_value.tv_usec = 1;
                    334:                        itv.it_interval.tv_sec = sp->update_secs;
                    335:                        itv.it_interval.tv_usec = 0;
                    336:                        setitimer(ITIMER_REAL, &itv, NULL);
                    337: #endif
                    338: #ifdef SYSV
                    339:                        ioctl(fileno(stdin), TCSETAW, &tty_new);
                    340:                        alarm(aval);
                    341: #endif
                    342:                }
                    343:                redraw();
                    344:        }
                    345: 
                    346:        if (isdigit(tval))
                    347:                return (NUMTOKEN);
                    348:        else if (isalpha(tval))
                    349:                return (ALPHATOKEN);
                    350:        else
                    351:                return (tval);
                    352: }
                    353: 
                    354: char   *
                    355: setplane(c)
                    356: {
                    357:        PLANE   *pp;
                    358: 
                    359:        pp = findplane(number(c));
                    360:        if (pp == NULL)
                    361:                return ("Unknown Plane");
                    362:        bcopy(pp, &p, sizeof (p));
                    363:        p.delayd = 0;
                    364:        return (NULL);
                    365: }
                    366: 
                    367: char   *
                    368: turn(c)
                    369: {
                    370:        if (p.altitude == 0)
                    371:                return ("Planes at airports may not change direction");
                    372:        return (NULL);
                    373: }
                    374: 
                    375: char   *
                    376: circle(c)
                    377: {
                    378:        if (p.altitude == 0)
                    379:                return ("Planes cannot circle on the ground");
                    380:        p.new_dir = MAXDIR;
                    381:        return (NULL);
                    382: }
                    383: 
                    384: char   *
                    385: left(c)
                    386: {
                    387:        dir = D_LEFT;
                    388:        p.new_dir = p.dir - 1;
                    389:        if (p.new_dir < 0)
                    390:                p.new_dir += MAXDIR;
                    391:        return (NULL);
                    392: }
                    393: 
                    394: char   *
                    395: right(c)
                    396: {
                    397:        dir = D_RIGHT;
                    398:        p.new_dir = p.dir + 1;
                    399:        if (p.new_dir > MAXDIR)
                    400:                p.new_dir -= MAXDIR;
                    401:        return (NULL);
                    402: }
                    403: 
                    404: char   *
                    405: Left(c)
                    406: {
                    407:        p.new_dir = p.dir - 2;
                    408:        if (p.new_dir < 0)
                    409:                p.new_dir += MAXDIR;
                    410:        return (NULL);
                    411: }
                    412: 
                    413: char   *
                    414: Right(c)
                    415: {
                    416:        p.new_dir = p.dir + 2;
                    417:        if (p.new_dir > MAXDIR)
                    418:                p.new_dir -= MAXDIR;
                    419:        return (NULL);
                    420: }
                    421: 
                    422: char   *
                    423: delayb(c)
                    424: {
                    425:        int     xdiff, ydiff;
                    426: 
                    427:        c -= '0';
                    428: 
                    429:        if (c >= sp->num_beacons)
                    430:                return ("Unknown beacon");
                    431:        xdiff = sp->beacon[c].x - p.xpos;
                    432:        xdiff = SGN(xdiff);
                    433:        ydiff = sp->beacon[c].y - p.ypos;
                    434:        ydiff = SGN(ydiff);
                    435:        if (xdiff != displacement[p.dir].dx || ydiff != displacement[p.dir].dy)
                    436:                return ("Beacon is not in flight path");
                    437:        p.delayd = 1;
                    438:        p.delayd_no = c;
                    439: 
                    440:        if (dest_type != T_NODEST) {
                    441:                switch (dest_type) {
                    442:                case T_BEACON:
                    443:                        xdiff = sp->beacon[dest_no].x - sp->beacon[c].x;
                    444:                        ydiff = sp->beacon[dest_no].y - sp->beacon[c].y;
                    445:                        break;
                    446:                case T_EXIT:
                    447:                        xdiff = sp->exit[dest_no].x - sp->beacon[c].x;
                    448:                        ydiff = sp->exit[dest_no].y - sp->beacon[c].y;
                    449:                        break;
                    450:                case T_AIRPORT:
                    451:                        xdiff = sp->airport[dest_no].x - sp->beacon[c].x;
                    452:                        ydiff = sp->airport[dest_no].y - sp->beacon[c].y;
                    453:                        break;
                    454:                default:
                    455:                        return ("Bad case in delayb!  Get help!");
                    456:                        break;
                    457:                }
                    458:                if (xdiff == 0 && ydiff == 0)
                    459:                        return ("Would already be there");
                    460:                p.new_dir = DIR_FROM_DXDY(xdiff, ydiff);
                    461:                if (p.new_dir == p.dir)
                    462:                        return ("Already going in that direction");
                    463:        }
                    464:        return (NULL);
                    465: }
                    466: 
                    467: char   *
                    468: beacon(c)
                    469: {
                    470:        dest_type = T_BEACON;
                    471:        return (NULL);
                    472: }
                    473: 
                    474: char   *
                    475: ex_it(c)
                    476: {
                    477:        dest_type = T_EXIT;
                    478:        return (NULL);
                    479: }
                    480: 
                    481: char   *
                    482: airport(c)
                    483: {
                    484:        dest_type = T_AIRPORT;
                    485:        return (NULL);
                    486: }
                    487: 
                    488: char   *
                    489: climb(c)
                    490: {
                    491:        dir = D_UP;
                    492:        return (NULL);
                    493: }
                    494: 
                    495: char   *
                    496: descend(c)
                    497: {
                    498:        dir = D_DOWN;
                    499:        return (NULL);
                    500: }
                    501: 
                    502: char   *
                    503: setalt(c)
                    504: {
                    505:        if ((p.altitude == c - '0') && (p.new_altitude == p.altitude))
                    506:                return ("Already at that altitude");
                    507:        p.new_altitude = c - '0';
                    508:        return (NULL);
                    509: }
                    510: 
                    511: char   *
                    512: setrelalt(c)
                    513: {
                    514:        if (c == 0)
                    515:                return ("altitude not changed");
                    516: 
                    517:        switch (dir) {
                    518:        case D_UP:
                    519:                p.new_altitude = p.altitude + c - '0';
                    520:                break;
                    521:        case D_DOWN:
                    522:                p.new_altitude = p.altitude - (c - '0');
                    523:                break;
                    524:        default:
                    525:                return ("Unknown case in setrelalt!  Get help!");
                    526:                break;
                    527:        }
                    528:        if (p.new_altitude < 0)
                    529:                return ("Altitude would be too low");
                    530:        else if (p.new_altitude > 9)
                    531:                return ("Altitude would be too high");
                    532:        return (NULL);
                    533: }
                    534: 
                    535: char   *
                    536: benum(c)
                    537: {
                    538:        dest_no = c -= '0';
                    539: 
                    540:        switch (dest_type) {
                    541:        case T_BEACON:
                    542:                if (c >= sp->num_beacons)
                    543:                        return ("Unknown beacon");
                    544:                p.new_dir = DIR_FROM_DXDY(sp->beacon[c].x - p.xpos,
                    545:                        sp->beacon[c].y - p.ypos);
                    546:                break;
                    547:        case T_EXIT:
                    548:                if (c >= sp->num_exits)
                    549:                        return ("Unknown exit");
                    550:                p.new_dir = DIR_FROM_DXDY(sp->exit[c].x - p.xpos,
                    551:                        sp->exit[c].y - p.ypos);
                    552:                break;
                    553:        case T_AIRPORT:
                    554:                if (c >= sp->num_airports)
                    555:                        return ("Unknown airport");
                    556:                p.new_dir = DIR_FROM_DXDY(sp->airport[c].x - p.xpos,
                    557:                        sp->airport[c].y - p.ypos);
                    558:                break;
                    559:        default:
                    560:                return ("Unknown case in benum!  Get help!");
                    561:                break;
                    562:        }
                    563:        return (NULL);
                    564: }
                    565: 
                    566: char   *
                    567: to_dir(c)
                    568: {
                    569:        p.new_dir = dir_no(c);
                    570:        return (NULL);
                    571: }
                    572: 
                    573: char   *
                    574: rel_dir(c)
                    575: {
                    576:        int     angle;
                    577: 
                    578:        angle = dir_no(c);
                    579:        switch (dir) {
                    580:        case D_LEFT:
                    581:                p.new_dir = p.dir - angle;
                    582:                if (p.new_dir < 0)
                    583:                        p.new_dir += MAXDIR;
                    584:                break;
                    585:        case D_RIGHT:
                    586:                p.new_dir = p.dir + angle;
                    587:                if (p.new_dir >= MAXDIR)
                    588:                        p.new_dir -= MAXDIR;
                    589:                break;
                    590:        default:
                    591:                return ("Bizarre direction in rel_dir!  Get help!");
                    592:                break;
                    593:        }
                    594:        return (NULL);
                    595: }
                    596: 
                    597: char   *
                    598: mark(c)
                    599: {
                    600:        if (p.altitude == 0)
                    601:                return ("Cannot mark planes on the ground");
                    602:        if (p.status == S_MARKED)
                    603:                return ("Already marked");
                    604:        p.status = S_MARKED;
                    605:        return (NULL);
                    606: }
                    607: 
                    608: char   *
                    609: unmark(c)
                    610: {
                    611:        if (p.altitude == 0)
                    612:                return ("Cannot unmark planes on the ground");
                    613:        if (p.status == S_UNMARKED)
                    614:                return ("Already unmarked");
                    615:        p.status = S_UNMARKED;
                    616:        return (NULL);
                    617: }
                    618: 
                    619: char   *
                    620: ignore(c)
                    621: {
                    622:        if (p.altitude == 0)
                    623:                return ("Cannot ignore planes on the ground");
                    624:        if (p.status == S_IGNORED)
                    625:                return ("Already ignored");
                    626:        p.status = S_IGNORED;
                    627:        return (NULL);
                    628: }
                    629: 
                    630: dir_no(ch)
                    631:        char    ch;
                    632: {
                    633:        int     dir;
                    634: 
                    635:        switch (ch) {
                    636:        case 'w':       dir = 0;        break;
                    637:        case 'e':       dir = 1;        break;
                    638:        case 'd':       dir = 2;        break;
                    639:        case 'c':       dir = 3;        break;
                    640:        case 'x':       dir = 4;        break;
                    641:        case 'z':       dir = 5;        break;
                    642:        case 'a':       dir = 6;        break;
                    643:        case 'q':       dir = 7;        break;
                    644:        default:
                    645:                fprintf(stderr, "bad character in dir_no\n");
                    646:                break;
                    647:        }
                    648:        return (dir);
                    649: }

unix.superglobalmegacorp.com

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