Annotation of researchv8dc/cmd/cu/cu.c, revision 1.1.1.1

1.1       root        1: #include <stdio.h>
                      2: #include <signal.h>
                      3: #include <sgtty.h>
                      4: #include <ctype.h>
                      5: /*
                      6:  *     cu telno [ class ]
                      7:  *     Escape with `~' at beginning of line.
                      8:  *     Ordinary diversions are ~<, ~> and ~>>.
                      9:  *     Silent output diversions are ~>: and ~>>:.
                     10:  *     Terminate output diversion with ~> alone.
                     11:  *     Output command requests are ~! and ~:! (silent).
                     12:  *     Quit is ~. and ~! gives local command or shell.
                     13:  *     Also ~$ for canned procedure pumping remote.
                     14:  *     ~%put from [to]  and  ~%take from [to] invoke builtins
                     15:  */
                     16: 
                     17: char   CRLF[2] = {'\r', '\n'};
                     18: #define        equal(s1,s2)    (strcmp(s1, s2)==0)
                     19: char   *cunfile;
                     20: int    ln;     /* fd for comm line */
                     21: char   tkill, terase;  /* current input kill & erase */
                     22: char   c;
                     23: int    intr;
                     24: int    nhup;
                     25: int    nflag;
                     26: int    tandm;
                     27: int    hduplx;
                     28: int    errflg;
                     29: extern int optind, opterr;
                     30: extern char *optarg;
                     31: struct sgttyb  realtty;
                     32: struct tchars  realtch;
                     33: int    sig2();
                     34: 
                     35: char   *connmsg[] = {
                     36:        "",
                     37:        "ACU busy",
                     38:        "call dropped",
                     39:        "no carrier",
                     40:        "can't fork",
                     41:        "acu access",
                     42:        "tty access",
                     43:        "tty hung",
                     44:        "usage: cu [-hnt] telno [ class ]",
                     45:        "unknown service class",
                     46: };
                     47: 
                     48: struct dial {
                     49:        char    *telno;
                     50:        char    *dialtype;
                     51:        char    *comment;
                     52: };
                     53: 
                     54: char partab[] = {
                     55:        0001,0201,0201,0001,0201,0001,0001,0201,
                     56:        0202,0004,0003,0201,0005,0206,0201,0001,
                     57:        0201,0001,0001,0201,0001,0201,0201,0001,
                     58:        0001,0201,0201,0001,0201,0001,0001,0201,
                     59:        0200,0000,0000,0200,0000,0200,0200,0000,
                     60:        0000,0200,0200,0000,0200,0000,0000,0200,
                     61:        0000,0200,0200,0000,0200,0000,0000,0200,
                     62:        0200,0000,0000,0200,0000,0200,0200,0000,
                     63:        0200,0000,0000,0200,0000,0200,0200,0000,
                     64:        0000,0200,0200,0000,0200,0000,0000,0200,
                     65:        0000,0200,0200,0000,0200,0000,0000,0200,
                     66:        0200,0000,0000,0200,0000,0200,0200,0000,
                     67:        0000,0200,0200,0000,0200,0000,0000,0200,
                     68:        0200,0000,0000,0200,0000,0200,0200,0000,
                     69:        0200,0000,0000,0200,0000,0200,0200,0000,
                     70:        0000,0200,0200,0000,0200,0000,0000,0201
                     71: };
                     72: 
                     73: /*
                     74:  *     spawn child to invoke rd to read from line, output to fd 1
                     75:  *     main line invokes wr to read tty, write to line
                     76:  */
                     77: 
                     78: main(ac, av)
                     79: char *av[];
                     80: {
                     81:        int fk;
                     82:        struct sgttyb stbuf;
                     83:        struct dial d;
                     84: 
                     85:        signal(SIGPIPE, SIG_IGN);
                     86:        d.telno = NULL;
                     87:        d.dialtype = NULL;
                     88:        d.comment = "";
                     89:        options(ac, av);
                     90:        if (optind >= ac || errflg) {
                     91:                prf(connmsg[8]);
                     92:                exit(8);
                     93:        }
                     94:        ioctl(0, TIOCGETP, &realtty);
                     95:        ioctl(0, TIOCGETC, &realtch);
                     96:        gettelno(av[optind], &d);
                     97:        if (optind+1 < ac)
                     98:                d.dialtype = av[optind+1];
                     99:        if (d.dialtype==NULL || *d.dialtype=='\0')
                    100:                d.dialtype = "D1200";
                    101:        if (equal(d.dialtype, "300"))
                    102:                d.dialtype = "D300";
                    103:        else if (equal(d.dialtype, "1200"))
                    104:                d.dialtype = "D1200";
                    105:        else if (equal(d.dialtype, "D"))
                    106:                d.dialtype = "D1200";
                    107:        else if (equal(d.dialtype, "C"))
                    108:                d.dialtype = "C1200";
                    109:        if (nflag) {
                    110:                printf("%s %s %s\n", d.telno, d.dialtype, d.comment);
                    111:                exit(0);
                    112:        }
                    113:        if (equal(d.dialtype, "direct")) {
                    114:                ln = open(d.telno, 2);
                    115:                if (ln>=0) {
                    116:                        struct tchars tcr;
                    117: 
                    118:                        ioctl(ln, TIOCGETP, &stbuf);
                    119:                        stbuf.sg_flags &= ~ECHO;
                    120:                        stbuf.sg_flags |= RAW|EVENP|ODDP;
                    121:                        stbuf.sg_ispeed = B9600;
                    122:                        stbuf.sg_ospeed = B9600;
                    123:                        tcr.t_stopc = '\027';
                    124:                        tcr.t_startc = '\031';
                    125:                        ioctl(ln, TIOCSETP, &stbuf);
                    126:                        ioctl(ln, TIOCGETC, &tcr);
                    127:                        ioctl(ln, TIOCSETC, &tcr);
                    128:                        ioctl(ln, TIOCHPCL, 0);
                    129:                        ioctl(ln, TIOCEXCL, 0);
                    130:                }
                    131:        } else
                    132:                ln = dialout(d.telno, d.dialtype);
                    133:        if (ln < 0) {
                    134:                prf("Connect failed: %s",connmsg[-ln]);
                    135:                exit(-ln);
                    136:        }
                    137:        ioctl(ln, TIOCGETP, &stbuf);
                    138:        prf("Connected");
                    139:        if (d.comment && *d.comment && *d.comment!='\n')
                    140:                prf(d.comment);
                    141:        if (tandm) {
                    142:                ioctl(ln, TIOCGETP, &stbuf);
                    143:                stbuf.sg_flags = ODDP+EVENP+TANDEM+CBREAK;
                    144:                ioctl(ln, TIOCSETN, &stbuf);
                    145:        }
                    146:        fk = fork();
                    147:        nhup = (int)signal(SIGINT, SIG_IGN);
                    148:        if (fk == 0) {
                    149:                rd();
                    150:                prf("\007Lost carrier");
                    151:                exit(3);
                    152:        }
                    153:        mode(1);
                    154:        wr();
                    155:        mode(0);
                    156:        kill(fk, SIGKILL);
                    157:        stbuf.sg_ispeed = 0;
                    158:        stbuf.sg_ospeed = 0;
                    159:        ioctl(ln, TIOCSETN, &stbuf);
                    160:        prf("Disconnected");
                    161:        exit(0);
                    162: }
                    163: 
                    164: /*
                    165:  *     wr: write to remote: 0 -> line.
                    166:  *     ~.      terminate
                    167:  *     ~<file  send file
                    168:  *     ~!      local login-style shell
                    169:  *     ~!cmd   execute cmd locally
                    170:  *     ~$proc  execute proc locally, send output to line
                    171:  *     ~%cmd   execute builtin cmd (put and take)
                    172:  */
                    173: 
                    174: wr()
                    175: {
                    176:        int ds, fk, lcl, x, nc;
                    177:        char *p, b[600];
                    178: 
                    179:        for (;;) {
                    180:                p = b;
                    181:                while (rdc(0) >= 1) {
                    182:                        if (p == b)
                    183:                                lcl=(c == '~');
                    184:                        if (p == b+1 && b[0] == '~')
                    185:                                lcl=(c!='~');
                    186:                        if (c == 0)
                    187:                                c = 0177;
                    188:                        if (!lcl) {
                    189:                                if (c==0177)
                    190:                                        ioctl(ln, TIOCFLUSH, 0);
                    191:                                if (wrc(ln, c, 1) <= 0) {
                    192:                                        prf("line gone");
                    193:                                        return;
                    194:                                }
                    195:                                if (c==0177)
                    196:                                        ioctl(0, TIOCFLUSH, 0);
                    197:                        }
                    198:                        if (lcl) {
                    199:                                if (c == 0177)
                    200:                                        c = tkill;
                    201:                                if (c == '\r' || c == '\n')
                    202:                                        goto A;
                    203:                                if (!hduplx)
                    204:                                        wrc(1, c, 1);
                    205:                        }
                    206:                        *p++ = c;
                    207:                        if (c == terase) {
                    208:                                p = p-2; 
                    209:                                if (p<b)
                    210:                                        p = b;
                    211:                        }
                    212:                        if (c == tkill || c == 0177 || c == '\r' || c == '\n')
                    213:                                p = b;
                    214:                }
                    215:                return;
                    216: A: 
                    217:                if (!hduplx || realtty.sg_flags&CRMOD)
                    218:                        echo("");
                    219:                *p = 0;
                    220:                switch (b[1]) {
                    221:                case '.':
                    222:                case '\004':
                    223:                        return;
                    224:                case 'b':
                    225:                        sendbreak();
                    226:                        break;
                    227: 
                    228:                case '!':
                    229:                case '$':
                    230:                        fk = fork();
                    231:                        if (fk == 0) {
                    232:                                close(1);
                    233:                                dup(b[1] == '$'? ln:2);
                    234:                                close(ln);
                    235:                                mode(0);
                    236:                                if (!nhup)
                    237:                                        signal(SIGINT, SIG_DFL);
                    238:                                if (b[2] == 0)
                    239:                                        execl("/bin/sh","sh",0);
                    240:                                else
                    241:                                        execl("/bin/sh","sh","-c",b+2,(char *)0);
                    242:                                prf("Can't execute shell");
                    243:                                exit(1);
                    244:                        }
                    245:                        if (fk!=(-1)) {
                    246:                                while (wait((int *)0)!=fk)
                    247:                                        ;
                    248:                        }
                    249:                        mode(1);
                    250:                        if (b[1] == '!')
                    251:                                echo("!");
                    252:                        break;
                    253:                case '<':
                    254:                        if (b[2] == 0) break;
                    255:                        if ((ds = open(b+2,0))<0) {
                    256:                                prf("Can't divert %s",b+1); 
                    257:                                break;
                    258:                        }
                    259:                        intr = x = 0;
                    260:                        mode(2);
                    261:                        if (!nhup)
                    262:                                signal(SIGINT, sig2);
                    263:                        while (!intr && (nc = rdc(ds)) >= 1) {
                    264:                                if (wrc(ln, c, nc==1) <= 0) {
                    265:                                        x = 1; 
                    266:                                        break;
                    267:                                }
                    268:                        }
                    269:                        signal(SIGINT, SIG_IGN);
                    270:                        close(ds);
                    271:                        mode(1);
                    272:                        if (x)
                    273:                                return;
                    274:                        break;
                    275:                case '%':
                    276:                        dopercen(&b[2]);
                    277:                        break;
                    278:                default:
                    279:                        prf("Use `~~' to start line with `~'");
                    280:                }
                    281:                continue;
                    282:        }
                    283: }
                    284: 
                    285: dopercen(line)
                    286: register char *line;
                    287: {
                    288:        char *args[10];
                    289:        register narg, f;
                    290:        int rcount, nc;
                    291: 
                    292:        for (narg = 0; narg < 10;) {
                    293:                while(*line == ' ' || *line == '\t')
                    294:                        line++;
                    295:                if (*line == '\0')
                    296:                        break;
                    297:                args[narg++] = line;
                    298:                while(*line != '\0' && *line != ' ' && *line != '\t')
                    299:                        line++;
                    300:                if (*line == '\0')
                    301:                        break;
                    302:                *line++ = '\0';
                    303:        }
                    304:        if (equal(args[0], "break")) {
                    305:                sendbreak();
                    306:                return;
                    307:        } else if (equal(args[0], "take")) {
                    308:                if (narg < 2) {
                    309:                        prf("usage: ~%%take from [to]");
                    310:                        return;
                    311:                }
                    312:                if (narg < 3)
                    313:                        args[2] = args[1];
                    314:                wrln("echo '~>:'");
                    315:                wrln(args[2]);
                    316:                wrln(";tee /dev/null <");
                    317:                wrln(args[1]);
                    318:                wrln(";echo '~>'\n");
                    319:                return;
                    320:        } else if (equal(args[0], "put")) {
                    321:                if (narg < 2) {
                    322:                        prf("usage: ~%%put from [to]");
                    323:                        return;
                    324:                }
                    325:                if (narg < 3)
                    326:                        args[2] = args[1];
                    327:                if ((f = open(args[1], 0)) < 0) {
                    328:                        prf("cannot open: %s", args[1]);
                    329:                        return;
                    330:                }
                    331:                wrln("stty -echo;cat >");
                    332:                wrln(args[2]);
                    333:                wrln(";stty echo\n");
                    334:                sleep(5);
                    335:                intr = 0;
                    336:                if (!nhup)
                    337:                        signal(SIGINT, sig2);
                    338:                mode(2);
                    339:                rcount = 0;
                    340:                while(!intr && (nc = rdc(f)) >= 1) {
                    341:                        rcount++;
                    342:                        if (c == tkill || c == terase)
                    343:                                wrc(ln, '\\', 0);
                    344:                        if (wrc(ln, c, nc == 1) <= 0)
                    345:                                intr = 1;
                    346:                }
                    347:                signal(SIGINT, SIG_IGN);
                    348:                close(f);
                    349:                if (intr) {
                    350:                        wrc(ln, '\n', 1);
                    351:                        prf("stopped after %d bytes", rcount);
                    352:                }
                    353:                wrc(ln, '\004', 1);
                    354:                sleep(5);
                    355:                mode(1);
                    356:                return;
                    357:        }
                    358:        prf("~%%%s unknown\n", args[0]);
                    359: }
                    360: 
                    361: wrln(s)
                    362: register char *s;
                    363: {
                    364:        register n = strlen(s);
                    365: 
                    366:        write(ln, s, n);
                    367: }
                    368: 
                    369: /*
                    370:  *     rd: read from remote: line -> 1
                    371:  *     catch:
                    372:  *     ~>[>][:][file]
                    373:  *     stuff from file...
                    374:  *     ~>      (ends diversion)
                    375:  *       ways for remote to run local command:
                    376:  *     ~!command (run command locally)
                    377:  *     ~:!command (run silently locally)
                    378:  */
                    379: 
                    380: rd()
                    381: {
                    382:        int ds, slnt, pid, hold=0, nc;
                    383:        char *p, *q, b[600];
                    384: 
                    385:        p = b;
                    386:        ds = -1;
                    387:        while ((nc = rdc(ln)) >= 1) {
                    388:                if (ds < 0 && hold==0)
                    389:                        slnt = 0;
                    390:                if (p==b && c=='~')
                    391:                        hold= ++slnt;
                    392:                if (hold && slnt && p==b+1 && c!=':') {
                    393:                        wrc(1, '~', 1);
                    394:                        slnt--;
                    395:                        hold = 0;
                    396:                }
                    397:                if (!slnt)
                    398:                        wrc(1, c, nc==1);
                    399:                *p++ = c;
                    400:                if (c!='\n' && p < &b[599])
                    401:                        continue;
                    402:                q = p; 
                    403:                p = b;
                    404:                hold = 0;
                    405:                if (strncmp(b, "~:!",3)==0||strncmp(b, "~!", 2)==0) {
                    406:                        *--q= '\0';
                    407:                        if (*--q == '\r')
                    408:                                *q= '\0';
                    409:                        mode(0);
                    410:                        if ((pid=fork())==0) {
                    411:                                p = b+2;
                    412:                                if (*p=='!')
                    413:                                        p++;
                    414:                                execl("/bin/sh", "sh", "-c", p, (char *)0);
                    415:                                exit(0);
                    416:                        }
                    417:                        while (wait((int *)0)!=pid)
                    418:                                ;
                    419:                        mode(1);
                    420:                        continue;
                    421:                }
                    422:                if (b[0]!='~' || b[1]!='>') {
                    423:                        if (*(q-2) == '\r') {
                    424:                                q--; 
                    425:                                *(q-1)=(*q);
                    426:                        }
                    427:                        if (ds>=0)
                    428:                                write(ds, b, q-b);
                    429:                        continue;
                    430:                }
                    431:                if (ds>=0)
                    432:                        close(ds);
                    433:                if (slnt) {
                    434:                        write(1, b, q - b);
                    435:                        write(1, CRLF, sizeof(CRLF));
                    436:                }
                    437:                if (*(q-2) == '\r')
                    438:                        q--;
                    439:                *(q-1) = 0;
                    440:                slnt = 0;
                    441:                q = b+2;
                    442:                if (*q == '>')
                    443:                        q++;
                    444:                if (*q == ':') {
                    445:                        slnt = 1; 
                    446:                        q++;
                    447:                }
                    448:                if (*q == 0) {
                    449:                        ds  = -1; 
                    450:                        continue;
                    451:                }
                    452:                if (b[2]!='>' || (ds = open(q,1))<0)
                    453:                        ds = creat(q, 0644);
                    454:                lseek(ds, (long)0, 2);
                    455:                if (ds<0)
                    456:                        prf("Can't divert %s",b+1);
                    457:        }
                    458: }
                    459: 
                    460: mode(f)
                    461: {
                    462:        struct sgttyb stbuf;
                    463:        static struct tchars nochars = { -1, -1, -1, -1, -1, -1};
                    464: 
                    465:        ioctl(0, TIOCGETP, &stbuf);
                    466:        tkill = stbuf.sg_kill;
                    467:        terase = stbuf.sg_erase;
                    468:        if (f == 0) {
                    469:                ioctl(0, TIOCSETP, &realtty);
                    470:                ioctl(0, TIOCSETC, &realtch);
                    471:                return;
                    472:        }
                    473:        if (f == 1) {
                    474:                stbuf.sg_flags |= CBREAK;
                    475:                stbuf.sg_flags &= ~CRMOD;
                    476:                if (!hduplx)
                    477:                        stbuf.sg_flags &= ~ECHO;
                    478:                ioctl(0, TIOCSETP, &stbuf);
                    479:                ioctl(0, TIOCSETC, &nochars);
                    480:                return;
                    481:        }
                    482:        if (f == 2) {
                    483:                stbuf.sg_flags &= ~(ECHO|CRMOD);
                    484:                ioctl(0, TIOCSETP, &stbuf);
                    485:                ioctl(0, TIOCSETC, &realtch);
                    486:                return;
                    487:        }
                    488: }
                    489: 
                    490: echo(s)
                    491: char *s;
                    492: {
                    493:        register n = strlen(s);
                    494: 
                    495:        if (n>0)
                    496:                write(1, s, n);
                    497:        write(1, CRLF, sizeof(CRLF));
                    498: }
                    499: 
                    500: /* VARARGS1 */
                    501: prf(f, s)
                    502: char *f;
                    503: char *s;
                    504: {
                    505:        printf(f, s);
                    506:        printf(CRLF);
                    507: }
                    508: 
                    509: sendbreak()
                    510: {
                    511:        struct sgttyb b;
                    512:        int olds;
                    513: 
                    514: #ifdef TIOCSBRK
                    515:        ioctl(ln, TIOCSBRK, 0);
                    516: #else TIOCSBRK
                    517:        ioctl(ln, TIOCGETP, &b);
                    518:        olds = b.sg_ispeed;
                    519:        b.sg_ispeed = B50;
                    520:        b.sg_ospeed = B50;
                    521:        ioctl(ln, TIOCSETP, &b);
                    522:        write(ln, "\0\0\0", 3);
                    523:        b.sg_ispeed = olds;
                    524:        b.sg_ospeed = olds;
                    525:        ioctl(ln, TIOCSETP, &b);
                    526: #endif TIOCSBRK
                    527: }
                    528: 
                    529: /*
                    530:  * Symbolic phone numbers
                    531:  */
                    532: gettelno(np, dp)
                    533: char *np;
                    534: register struct dial *dp;
                    535: {
                    536:        char cunumber[128];
                    537:        char *hp;
                    538:        register char *xnp;
                    539:        char *getenv();
                    540: 
                    541:        if (cunfile) {
                    542:                if (look(np, dp, cunfile))
                    543:                        return;
                    544:        } else {
                    545:                hp = getenv("HOME");
                    546:                if (hp) {
                    547:                        strcpy(cunumber, hp);
                    548:                        strcat(cunumber, "/lib/cunumber");
                    549:                        if (look(np, dp, cunumber))
                    550:                                return;
                    551:                }
                    552:                if (look(np, dp, "/usr/lib/cunumber"))
                    553:                        return;
                    554:        }
                    555:        xnp = np;
                    556:        if (*np != '/')
                    557:                while (*xnp) {
                    558:                        if (*xnp!=';' && *xnp!=':' && *xnp!='-' && *xnp!='*'
                    559:                         && *xnp!='#' && !isdigit(*xnp)) {
                    560:                                prf("Symbolic number not found");
                    561:                                exit(1);
                    562:                        }
                    563:                        xnp++;
                    564:                }
                    565:        dp->telno = np;
                    566: }
                    567: 
                    568: look(np, dp, fnp)
                    569: register char *np;
                    570: register struct dial *dp;
                    571: char *fnp;
                    572: {
                    573:        FILE *fp;
                    574:        static char line[128];
                    575:        register char *lp;
                    576:        register i;
                    577:        char *opts[8];
                    578:        register char **optp;
                    579:        char *w[4];
                    580: 
                    581:        if ((fp = fopen(fnp, "r")) == NULL)
                    582:                return(0);
                    583:        while (fgets(line, sizeof(line), fp)) {
                    584:                lp = line;
                    585:                optp = opts;
                    586:                for (i = 0; i<4; i++) {
                    587:                        while (isspace(*lp))
                    588:                                lp++;
                    589:                        if (i==1 && *lp=='-') {
                    590:                                *optp++ = lp;
                    591:                                i--;
                    592:                        } else
                    593:                                w[i] = lp;
                    594:                        while ((!isspace(*lp) || i==3) && *lp)
                    595:                                lp++;
                    596:                        if (*lp)
                    597:                                *lp++ = '\0';
                    598:                }
                    599:                if (strcmp(w[0], np))
                    600:                        continue;
                    601:                i = optind;
                    602:                optind = 0;
                    603:                options(optp-opts, opts);
                    604:                optind = i;
                    605:                dp->telno = w[1];
                    606:                dp->dialtype = w[2];
                    607:                dp->comment = w[3];
                    608:                fclose(fp);
                    609:                return(1);
                    610:        }
                    611:        fclose(fp);
                    612:        return(0);
                    613: }
                    614: 
                    615: options(ac, av)
                    616: char **av;
                    617: {
                    618:        register o;
                    619: 
                    620:        opterr = 0;
                    621:        while ((o = getopt(ac, av, "hntf:")) != EOF) {
                    622:                switch(o) {
                    623: 
                    624:                case '?':
                    625:                        errflg++;
                    626:                        continue;
                    627: 
                    628:                case 'h':
                    629:                        hduplx++;
                    630:                        continue;
                    631: 
                    632:                case 'f':
                    633:                        cunfile = optarg;
                    634:                        continue;
                    635: 
                    636:                case 't':
                    637:                        tandm++;
                    638:                        continue;
                    639: 
                    640:                case 'n':
                    641:                        nflag++;
                    642:                        continue;
                    643:                }
                    644:        }
                    645: }
                    646: 
                    647: wrc(f, c, flush)
                    648: register c;
                    649: {
                    650:        static char buf[64];
                    651:        static char *bp = buf;
                    652:        register r;
                    653: 
                    654:        c &= 0177;
                    655:        if (f==ln)
                    656:                c |= (partab[c] & 0200);
                    657:        *bp++ = c;
                    658:        r = 1;
                    659:        if (flush || bp >= &buf[64]) {
                    660:                r = write(f, buf, bp-buf);
                    661:                bp = buf;
                    662:        }
                    663:        return(r);
                    664: }
                    665: 
                    666: rdc(ds)
                    667: {
                    668:        static char buf[64];
                    669:        static nc = 0;
                    670:        static char *bp;
                    671: 
                    672:        if (nc <= 0) {
                    673:                nc = read(ds, buf, 64); 
                    674:                bp = buf;
                    675:        }
                    676:        if (nc <= 0)
                    677:                return(nc);
                    678:        nc--;
                    679:        c = *bp++ & 0177;
                    680:        return(nc+1);
                    681: }
                    682: 
                    683: sig2()
                    684: {
                    685:        signal(SIGINT, SIG_IGN); 
                    686:        intr = 1;
                    687: }
                    688: 

unix.superglobalmegacorp.com

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