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

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

unix.superglobalmegacorp.com

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