Annotation of 43BSDTahoe/old/cu.c, revision 1.1.1.1

1.1       root        1: static char *sccsid = "@(#)cu.c        4.7 (Berkeley) 82/10/21";
                      2: 
                      3: #include <stdio.h>
                      4: #include <signal.h>
                      5: #include <sgtty.h>
                      6: 
                      7: /*
                      8:  * defs that come from uucp.h
                      9:  */
                     10: #define NAMESIZE 15
                     11: #define FAIL -1
                     12: #define SAME 0
                     13: #define SLCKTIME 5400  /* system/device timeout (LCK.. files) in seconds */
                     14: #define ASSERT(e, f, v) if (!(e)) {\
                     15:        fprintf(stderr, "AERROR - (%s) ", "e");\
                     16:        fprintf(stderr, f, v);\
                     17:        cleanup(FAIL);\
                     18: }
                     19: 
                     20: /*
                     21:  *     cu telno [-t] [-s speed] [-l line] [-a acu] [-p]
                     22:  *
                     23:  *     -t is for dial-out to terminal.
                     24:  *     speeds are: 110, 134, 150, 300, 1200, 2400. 300 is default.
                     25:  *
                     26:  *     -p says strip parity of characters transmitted.  (to compensate
                     27:  *     for c100's)
                     28:  *
                     29:  *     Escape with `~' at beginning of line.
                     30:  *     Ordinary diversions are ~<, ~> and ~>>.
                     31:  *     Silent output diversions are ~>: and ~>>:.
                     32:  *     Terminate output diversion with ~> alone.
                     33:  *     Quit is ~. and ~! gives local command or shell.
                     34:  *     Also ~$ for canned procedure pumping remote.
                     35:  *     ~%put from [to]  and  ~%take from [to] invoke builtins
                     36:  */
                     37: 
                     38: #define CRLF "\r\n"
                     39: #define wrc(ds) write(ds,&c,1)
                     40: 
                     41: 
                     42: char   *devcul = "/dev/cul0";
                     43: char   *devcua = "/dev/cua0";
                     44: char   *lspeed = "300";
                     45: 
                     46: int    ln;     /* fd for comm line */
                     47: char   tkill, terase;  /* current input kill & erase */
                     48: int    efk;            /* process of id of listener  */
                     49: char   c;
                     50: char   oc;
                     51: 
                     52: char   *connmsg[] = {
                     53:        "",
                     54:        "line busy",
                     55:        "call dropped",
                     56:        "no carrier",
                     57:        "can't fork",
                     58:        "acu access",
                     59:        "tty access",
                     60:        "tty hung",
                     61:        "usage: cu telno [-t] [-s speed] [-l line] [-a acu]",
                     62:        "lock failed: line busy"
                     63: };
                     64: 
                     65: rdc(ds) {
                     66: 
                     67:        ds=read(ds,&c,1); 
                     68:        oc = c;
                     69:        c &= 0177;
                     70:        return (ds);
                     71: }
                     72: 
                     73: int intr;
                     74: 
                     75: sig2()
                     76: {
                     77:        signal(SIGINT, SIG_IGN); 
                     78:        intr = 1;
                     79: }
                     80: 
                     81: int set14;
                     82: 
                     83: xsleep(n)
                     84: {
                     85:        xalarm(n);
                     86:        pause();
                     87:        xalarm(0);
                     88: }
                     89: 
                     90: xalarm(n)
                     91: {
                     92:        set14=n; 
                     93:        alarm(n);
                     94: }
                     95: 
                     96: sig14()
                     97: {
                     98:        signal(SIGALRM, sig14); 
                     99:        if (set14) alarm(1);
                    100: }
                    101: 
                    102: int    dout;
                    103: int    nhup;
                    104: int    dbflag;
                    105: int    pflag;          /* strip parity on chars sent to remote */
                    106: int    nullbrk;        /* turn breaks (nulls) into dels */
                    107: int    pipes[2] = { -1, -1 };
                    108: 
                    109: /*
                    110:  *     main: get connection, set speed for line.
                    111:  *     spawn child to invoke rd to read from line, output to fd 1
                    112:  *     main line invokes wr to read tty, write to line
                    113:  */
                    114: main(ac,av)
                    115: char *av[];
                    116: {
                    117:        int fk;
                    118:        int speed;
                    119:        char *telno;
                    120:        struct sgttyb stbuf;
                    121:        int cleanup();
                    122: 
                    123:        signal(SIGALRM, sig14);
                    124:        signal(SIGINT, cleanup);
                    125:        signal(SIGHUP, cleanup);
                    126:        signal(SIGQUIT, cleanup);
                    127:        if (ac < 2) {
                    128:                prf(connmsg[8]);
                    129:                exit(8);
                    130:        }
                    131:        for (; ac > 1; av++,ac--) {
                    132:                if (av[1][0] != '-')
                    133:                        telno = av[1];
                    134:                else switch(av[1][1]) {
                    135:                case 't':
                    136:                        dout = 1;
                    137:                        --ac;
                    138:                        continue;
                    139:                case 'b':
                    140:                        nullbrk++;
                    141:                        continue;
                    142:                case 'd':
                    143:                        dbflag++;
                    144:                        continue;
                    145:                case 'p':
                    146:                        pflag++;
                    147:                        continue;
                    148:                case 's':
                    149:                        lspeed = av[2]; ++av; --ac;
                    150:                        break;
                    151:                case 'l':
                    152:                        devcul = av[2]; ++av; --ac;
                    153:                        break;
                    154:                case 'a':
                    155:                        devcua = av[2]; ++av; --ac;
                    156:                        break;
                    157:                case '0': case '1': case '2': case '3': case '4':
                    158:                case '5': case '6': case '7': case '8': case '9':
                    159:                        devcua[strlen(devcua)-1] = av[1][1];
                    160:                        devcul[strlen(devcul)-1] = av[1][1];
                    161:                        break;
                    162:                default:
                    163:                        prf("Bad flag %s", av[1]);
                    164:                        break;
                    165:                }
                    166:        }
                    167:        if (!exists(devcua) || !exists(devcul))
                    168:                exit(9);
                    169:        ln = conn(devcul, devcua, telno);
                    170:        if (ln < 0) {
                    171:                prf("Connect failed: %s",connmsg[-ln]);
                    172:                cleanup(-ln);
                    173:        }
                    174:        switch(atoi(lspeed)) {
                    175:        case 110:
                    176:                speed = B110;break;
                    177:        case 150:
                    178:                speed = B150;break;
                    179:        default:
                    180:        case 300:
                    181:                speed = B300;break;
                    182:        case 1200:
                    183:                speed = B1200;break;
                    184:        case 2400:
                    185:                speed = B2400;break;
                    186:        }
                    187:        stbuf.sg_ispeed = speed;
                    188:        stbuf.sg_ospeed = speed;
                    189:        stbuf.sg_flags = EVENP|ODDP;
                    190:        if (!dout) {
                    191:                stbuf.sg_flags |= RAW;
                    192:                stbuf.sg_flags &= ~ECHO;
                    193:        }
                    194:        ioctl(ln, TIOCSETP, &stbuf);
                    195:        ioctl(ln, TIOCEXCL, (struct sgttyb *)NULL);
                    196:        ioctl(ln, TIOCHPCL, (struct sgttyb *)NULL);
                    197:        prf("Connected");
                    198:        pipe(pipes);
                    199:        if (dout)
                    200:                fk = -1;
                    201:        else
                    202:                fk = fork();
                    203:        nhup = (int)signal(SIGINT, SIG_IGN);
                    204:        if (fk == 0) {
                    205:                chwrsig();
                    206:                rd();
                    207:                prf("\007Lost carrier");
                    208:                cleanup(3);
                    209:        }
                    210:        mode(1);
                    211:        efk = fk;
                    212:        wr();
                    213:        mode(0);
                    214:        if (fk != -1) kill(fk, SIGKILL);
                    215:        wait((int *)NULL);
                    216:        stbuf.sg_ispeed = 0;
                    217:        stbuf.sg_ospeed = 0;
                    218:        ioctl(ln, TIOCSETP, &stbuf);
                    219:        prf("Disconnected");
                    220:        cleanup(0);
                    221: }
                    222: 
                    223: /*
                    224:  *     conn: establish dial-out connection.
                    225:  *     Example:  fd = conn("/dev/ttyh","/dev/dn1","4500");
                    226:  *     Returns descriptor open to tty for reading and writing.
                    227:  *     Negative values (-1...-7) denote errors in connmsg.
                    228:  *     Uses alarm and fork/wait; requires sig14 handler.
                    229:  *     Be sure to disconnect tty when done, via HUPCL or stty 0.
                    230:  */
                    231: 
                    232: conn(dev,acu,telno)
                    233: char *dev, *acu, *telno;
                    234: {
                    235:        struct sgttyb stbuf;
                    236:        extern errno;
                    237:        char *p, *q, b[30];
                    238:        char *ltail, *atail;
                    239:        char *rindex();
                    240:        int er, fk, dn, dh, t;
                    241:        er=0; 
                    242:        fk=(-1);
                    243:        atail = rindex(acu, '/')+1;
                    244:        if (mlock(atail) == FAIL) {
                    245:                er = 9;
                    246:                goto X;
                    247:        }
                    248:        ltail = rindex(dev, '/')+1;
                    249:        if (mlock(ltail) == FAIL) {
                    250:                er = 9;
                    251:                delock(atail);
                    252:                goto X;
                    253:        }
                    254:        if ((dn=open(acu,1))<0) {
                    255:                er=(errno == 6? 1:5); 
                    256:                goto X;
                    257:        }
                    258:        if ((fk=fork()) == (-1)) {
                    259:                er=4; 
                    260:                goto X;
                    261:        }
                    262:        if (fk == 0) {
                    263:                open(dev,2); 
                    264:                for (;;) pause();
                    265:        }
                    266:        xsleep(2);
                    267:        /*
                    268:         *      copy phone #, assure EON
                    269:         */
                    270:        p=b; 
                    271:        q=telno;
                    272:        while (*p++=(*q++))
                    273:                ;
                    274:        p--;
                    275:        if (*(p-1)!='<') {
                    276:                /*if (*(p-1)!='-') *p++='-';*/
                    277:                *p++='<';
                    278:        }
                    279:        t=p-b;
                    280:        xalarm(5*t);
                    281:        t=write(dn,b,t);
                    282:        xalarm(0);
                    283:        if (t<0) {
                    284:                er=2; 
                    285:                goto X;
                    286:        }
                    287:        /* close(dn) */
                    288:        xalarm(40);             /* was 5; sometimes missed carrier */
                    289:        dh = open(dev,2);
                    290:        xalarm(0);
                    291:        if (dh<0) {
                    292:                er=(errno == 4? 3:6); 
                    293:                goto X;
                    294:        }
                    295:        ioctl(dh, TIOCGETP, &stbuf);
                    296:        stbuf.sg_flags &= ~ECHO;
                    297:        xalarm(10);
                    298:        ioctl(dh, TIOCSETP, &stbuf);
                    299:        ioctl(dh, TIOCHPCL, (struct sgttyb *)NULL);
                    300:        xalarm(0);
                    301: X: 
                    302:        if (er) close(dn);
                    303:        delock(atail);
                    304:        if (fk!=(-1)) {
                    305:                kill(fk, SIGKILL);
                    306:                xalarm(10);
                    307:                while ((t=wait((int *)NULL))!=(-1) && t!=fk);
                    308:                xalarm(0);
                    309:        }
                    310:        return (er? -er:dh);
                    311: }
                    312: 
                    313: /*
                    314:  *     wr: write to remote: 0 -> line.
                    315:  *     ~.      terminate
                    316:  *     ~<file  send file
                    317:  *     ~!      local login-style shell
                    318:  *     ~!cmd   execute cmd locally
                    319:  *     ~$proc  execute proc locally, send output to line
                    320:  *     ~%cmd   execute builtin cmd (put and take)
                    321:  *     ~#      send 1-sec break
                    322:  *     ~^Z     suspend cu process.
                    323:  */
                    324: 
                    325: wr()
                    326: {
                    327:        int ds,fk,lcl,x;
                    328:        char *p,b[600];
                    329:        for (;;) {
                    330:                p=b;
                    331:                while (rdc(0) == 1) {
                    332:                        if (p == b) lcl=(c == '~');
                    333:                        if (p == b+1 && b[0] == '~') lcl=(c!='~');
                    334:                        if (nullbrk && c == 0) oc=c=0177; /* fake break kludge */
                    335:                        if (!lcl) {
                    336:                                if(!pflag)c = oc;
                    337:                                if (wrc(ln) == 0) {
                    338:                                        prf("line gone"); return;
                    339:                                }
                    340:                                c &= 0177;
                    341:                        }
                    342:                        if (lcl) {
                    343:                                if (c == 0177) c=tkill;
                    344:                                if (c == '\r' || c == '\n') goto A;
                    345:                                if (!dout) wrc(0);
                    346:                        }
                    347:                        *p++=c;
                    348:                        if (c == terase) {
                    349:                                p=p-2; 
                    350:                                if (p<b) p=b;
                    351:                        }
                    352:                        if (c == tkill || c == 0177 || c == '\4' || c == '\r' || c == '\n') p=b;
                    353:                }
                    354:                return;
                    355: A: 
                    356:                if (!dout) echo("");
                    357:                *p=0;
                    358:                switch (b[1]) {
                    359:                case '.':
                    360:                case '\004':
                    361:                        return;
                    362:                case '#':
                    363:                        ioctl(ln, TIOCSBRK, 0);
                    364:                        sleep(1);
                    365:                        ioctl(ln, TIOCCBRK, 0);
                    366:                        continue;
                    367:                case '!':
                    368:                case '$':
                    369:                        fk = fork();
                    370:                        if (fk == 0) {
                    371:                                char *getenv();
                    372:                                char *shell = getenv("SHELL");
                    373:                                if (shell == 0) shell = "/bin/sh";
                    374:                                close(1);
                    375:                                dup(b[1] == '$'? ln:2);
                    376:                                close(ln);
                    377:                                mode(0);
                    378:                                if (!nhup) signal(SIGINT, SIG_DFL);
                    379:                                if (b[2] == 0) execl(shell,shell,0);
                    380:                                /* if (b[2] == 0) execl(shell,"-",0); */
                    381:                                else execl(shell,"sh","-c",b+2,0);
                    382:                                prf("Can't execute shell");
                    383:                                exit(~0);
                    384:                        }
                    385:                        if (fk!=(-1)) {
                    386:                                while (wait(&x)!=fk);
                    387:                        }
                    388:                        mode(1);
                    389:                        if (b[1] == '!') echo("!");
                    390:                        else {
                    391:                                if (dout) echo("$");
                    392:                        }
                    393:                        break;
                    394:                case '<':
                    395:                        if (b[2] == 0) break;
                    396:                        if ((ds=open(b+2,0))<0) {
                    397:                                prf("Can't divert %s",b+1); 
                    398:                                break;
                    399:                        }
                    400:                        intr=x=0;
                    401:                        mode(2);
                    402:                        if (!nhup) signal(SIGINT, sig2);
                    403:                        while (!intr && rdc(ds) == 1) {
                    404:                                if (wrc(ln) == 0) {
                    405:                                        x=1; 
                    406:                                        break;
                    407:                                }
                    408:                        }
                    409:                        signal(SIGINT, SIG_IGN);
                    410:                        close(ds);
                    411:                        mode(1);
                    412:                        if (x) return;
                    413:                        if (dout) echo("<");
                    414:                        break;
                    415:                case '>':
                    416:                case ':':
                    417:                        {
                    418:                        register char *q;
                    419: 
                    420:                        if(pipes[1]==-1) {
                    421:                                prf("Can't tell other demon to divert");
                    422:                                break;
                    423:                        }
                    424:                        q = b+1;
                    425:                        if(*q=='>') q++;
                    426:                        write(pipes[1],q,strlen(q)+1);
                    427:                        if(dbflag) prf("msg to be delivered:"),prf(q);
                    428:                        if (efk != -1) kill(efk,SIGEMT);
                    429:                        }
                    430:                        break;
                    431: #ifdef SIGTSTP
                    432: #define CTRLZ  26
                    433:                case CTRLZ:
                    434:                        mode(0);
                    435:                        kill(getpid(), SIGTSTP);
                    436:                        mode(1);
                    437:                        break;
                    438: #endif
                    439:                case '%':
                    440:                        dopercen(&b[2]);
                    441:                        break;
                    442:                default:
                    443:                        prf("Use `~~' to start line with `~'");
                    444:                }
                    445:                continue;
                    446:        }
                    447: }
                    448: 
                    449: dopercen(line)
                    450: register char *line;
                    451: {
                    452:        char *args[10];
                    453:        register narg, f;
                    454:        int rcount;
                    455:        for (narg = 0; narg < 10;) {
                    456:                while(*line == ' ' || *line == '\t')
                    457:                        line++;
                    458:                if (*line == '\0')
                    459:                        break;
                    460:                args[narg++] = line;
                    461:                while(*line != '\0' && *line != ' ' && *line != '\t')
                    462:                        line++;
                    463:                if (*line == '\0')
                    464:                        break;
                    465:                *line++ = '\0';
                    466:        }
                    467:        if (equal(args[0], "take")) {
                    468:                if (narg < 2) {
                    469:                        prf("usage: ~%%take from [to]");
                    470:                        return;
                    471:                }
                    472:                if (narg < 3)
                    473:                        args[2] = args[1];
                    474:                write(pipes[1], ">:/dev/null",sizeof(">:/dev/null"));
                    475:                if(dbflag) prf("sending take message");
                    476:                if (efk != -1) kill(efk,SIGEMT);
                    477:                xsleep(5);
                    478:                wrln("echo '~>");
                    479:                wrln(args[2]);
                    480:                wrln("'; tee /dev/null <");
                    481:                wrln(args[1]);
                    482:                wrln(";echo '~>'\n");
                    483:                return;
                    484:        } else if (equal(args[0], "put")) {
                    485:                if (narg < 2) {
                    486:                        prf("usage: ~%%put from [to]");
                    487:                        return;
                    488:                }
                    489:                if (narg < 3)
                    490:                        args[2] = args[1];
                    491:                if ((f = open(args[1], 0)) < 0) {
                    492:                        prf("cannot open: %s", args[1]);
                    493:                        return;
                    494:                }
                    495:                wrln("stty -echo;cat >");
                    496:                wrln(args[2]);
                    497:                wrln(";stty echo\n");
                    498:                xsleep(5);
                    499:                intr = 0;
                    500:                if (!nhup)
                    501:                        signal(SIGINT, sig2);
                    502:                mode(2);
                    503:                rcount = 0;
                    504:                while(!intr && rdc(f) == 1) {
                    505:                        rcount++;
                    506:                        if (c == tkill || c == terase)
                    507:                                wrln("\\");
                    508:                        if (wrc(ln) != 1) {
                    509:                                xsleep(2);
                    510:                                if (wrc(ln) != 1) {
                    511:                                        prf("character missed");
                    512:                                        intr = 1;
                    513:                                        break;
                    514:                                }
                    515:                        }
                    516:                }
                    517:                signal(SIGINT, SIG_IGN);
                    518:                close(f);
                    519:                if (intr) {
                    520:                        wrln("\n");
                    521:                        prf("stopped after %d bytes", rcount);
                    522:                }
                    523:                wrln("\004");
                    524:                xsleep(5);
                    525:                mode(1);
                    526:                return;
                    527:        }
                    528:        prf("~%%%s unknown\n", args[0]);
                    529: }
                    530: 
                    531: equal(s1, s2)
                    532: register char *s1, *s2;
                    533: {
                    534:        while (*s1++ == *s2)
                    535:                if (*s2++ == '\0')
                    536:                        return(1);
                    537:        return(0);
                    538: }
                    539: 
                    540: wrln(s)
                    541: register char *s;
                    542: {
                    543:        while (*s)
                    544:                write(ln, s++, 1);
                    545: }
                    546: /*     chwrsig:  Catch orders from wr process 
                    547:  *     to instigate diversion
                    548:  */
                    549: int whoami;
                    550: chwrsig(){
                    551:        int readmsg(); 
                    552:        whoami = getpid();
                    553:        signal(SIGEMT,readmsg);
                    554: }
                    555: int ds,slnt,taking;
                    556: int justrung;
                    557: readmsg(){
                    558:        static char dobuff[128], morejunk[256];
                    559:        int n;
                    560:        justrung = 1;
                    561:        signal(SIGEMT,readmsg);
                    562:        if(dbflag) {
                    563:                prf("About to read from pipe");
                    564:        }
                    565:        n = read(pipes[0],morejunk,256);
                    566:        if(dbflag) {
                    567:                prf("diversion mesg recieved is");
                    568:                prf(morejunk);
                    569:                prf(CRLF);
                    570:        }
                    571:        dodiver(morejunk);
                    572: }
                    573: dodiver(msg)
                    574: char *msg;
                    575: {
                    576:        register char *cp = msg; 
                    577: 
                    578:        if (*cp=='>') cp++;
                    579:        if (*cp==':') {
                    580:                cp++;
                    581:                if(*cp==0) {
                    582:                        slnt ^= 1;
                    583:                        return;
                    584:                } else  {
                    585:                        slnt = 1;
                    586:                }
                    587:        }
                    588:        if (ds >= 0) close(ds);
                    589:        if (*cp==0) {
                    590:                slnt = 0;
                    591:                ds = -1;
                    592:                return;
                    593:        }
                    594:        if (*msg!='>' || (ds=open(cp,1))<0) ds=creat(cp,0644);
                    595:        lseek(ds, (long)0, 2);
                    596:        if(ds < 0) prf("Creat failed:"), prf(cp);
                    597:        if (ds<0) prf("Can't divert %s",cp+1);
                    598: }
                    599: 
                    600: 
                    601: /*
                    602:  *     rd: read from remote: line -> 1
                    603:  *     catch: diversion caught by interrupt routine
                    604:  */
                    605: 
                    606: #define ORDIN 0
                    607: #define SAWCR 1
                    608: #define EOL   2
                    609: #define SAWTL 3
                    610: #define DIVER 4
                    611: 
                    612: rd()
                    613: {
                    614:        extern int ds,slnt;
                    615:        char rb[600], lb[600], *rlim, *llim, c;
                    616:        register char *p,*q;
                    617:        int cnt, state = 0, mustecho, oldslnt;
                    618: 
                    619:        ds=(-1);
                    620:        p = lb; llim = lb+600;
                    621: agin:
                    622:        while((cnt = read(ln,rb,600)) > 0) {
                    623:                if(!slnt) write(1,rb,cnt);
                    624:                if(ds < 0) continue;
                    625:                oldslnt = slnt;
                    626:                for( q=rb, rlim = rb + cnt - 1; q <= rlim; ) {
                    627:                        c = *q++ & 0177;
                    628:                        if(p < llim) *p++ = c;
                    629:                        switch(state) {
                    630:                        case ORDIN:
                    631:                                if(c=='\r') state = SAWCR;
                    632:                                break;
                    633:                        case SAWCR:
                    634:                                if(c=='\n') {
                    635:                                        state = EOL;
                    636:                                        p--;
                    637:                                        p[-1] = '\n';
                    638:                                } else state = ORDIN;
                    639:                                break;
                    640:                        case EOL:
                    641:                                state = (c=='~' ? SAWTL : 
                    642:                                         (c=='\r' ? SAWCR : ORDIN));
                    643:                                break;
                    644:                        case SAWTL:
                    645:                                state = (c=='>' ? DIVER : 
                    646:                                         (c=='\r' ? SAWCR : ORDIN));
                    647:                                break;
                    648:                        case DIVER:
                    649:                                if(c=='\r') {
                    650:                                        p--;
                    651:                                } else if (c=='\n') {
                    652:                                        state = ORDIN;
                    653:                                        p[-1] = 0;
                    654:                                        dodiver(lb+2);
                    655:                                        c = 0; p = lb;
                    656:                                }
                    657:                        }
                    658:                        if(slnt==0 && oldslnt) {
                    659:                                if(c=='\n') {
                    660:                                        write(ln,lb,p-lb-1);
                    661:                                        write(ln,CRLF,sizeof(CRLF));
                    662:                                } else if(q==rlim) {
                    663:                                        write(ln,lb,p-lb);
                    664:                                        c = '\n';  /*force flush to file*/
                    665:                                }
                    666:                        }
                    667:                        if(c=='\n') {
                    668:                                if(ds >= 0)
                    669:                                        write(ds,lb,p-lb);
                    670:                                p = lb;
                    671:                        }
                    672:                }
                    673:        }
                    674:        if(justrung) {
                    675:                justrung = 0;
                    676:                goto agin;
                    677:        }
                    678: }
                    679: 
                    680: struct {char lobyte; char hibyte;};
                    681: mode(f)
                    682: {
                    683:        struct sgttyb stbuf;
                    684:        if (dout) return;
                    685:        ioctl(0, TIOCGETP, &stbuf);
                    686:        tkill = stbuf.sg_kill;
                    687:        terase = stbuf.sg_erase;
                    688:        if (f == 0) {
                    689:                stbuf.sg_flags &= ~RAW;
                    690:                stbuf.sg_flags |= ECHO|CRMOD;
                    691:        }
                    692:        if (f == 1) {
                    693:                stbuf.sg_flags |= RAW;
                    694:                stbuf.sg_flags &= ~(ECHO|CRMOD);
                    695:        }
                    696:        if (f == 2) {
                    697:                stbuf.sg_flags &= ~RAW;
                    698:                stbuf.sg_flags &= ~(ECHO|CRMOD);
                    699:        }
                    700:        ioctl(0, TIOCSETP, &stbuf);
                    701: }
                    702: 
                    703: echo(s)
                    704: char *s;
                    705: {
                    706:        char *p;
                    707:        for (p=s;*p;p++);
                    708:        if (p>s) write(0,s,p-s);
                    709:        write(0,CRLF, sizeof(CRLF));
                    710: }
                    711: 
                    712: prf(f, s)
                    713: char *f;
                    714: char *s;
                    715: {
                    716:        fprintf(stderr, f, s);
                    717:        fprintf(stderr, CRLF);
                    718: }
                    719: 
                    720: exists(devname)
                    721: char *devname;
                    722: {
                    723:        if (access(devname, 0)==0)
                    724:                return(1);
                    725:        prf("%s does not exist", devname);
                    726:        return(0);
                    727: }
                    728: 
                    729: cleanup(code)
                    730: {
                    731:        rmlock(NULL);
                    732:        exit(code);
                    733: }
                    734: 
                    735: /*
                    736:  * This code is taken directly from uucp and follows the same
                    737:  * conventions.  This is important since uucp and cu should
                    738:  * respect each others locks.
                    739:  */
                    740: 
                    741:        /*  ulockf 3.2  10/26/79  11:40:29  */
                    742: /* #include "uucp.h" */
                    743: #include <sys/types.h>
                    744: #include <sys/stat.h>
                    745: 
                    746: 
                    747: 
                    748: /*******
                    749:  *     ulockf(file, atime)
                    750:  *     char *file;
                    751:  *     time_t atime;
                    752:  *
                    753:  *     ulockf  -  this routine will create a lock file (file).
                    754:  *     If one already exists, the create time is checked for
                    755:  *     older than the age time (atime).
                    756:  *     If it is older, an attempt will be made to unlink it
                    757:  *     and create a new one.
                    758:  *
                    759:  *     return codes:  0  |  FAIL
                    760:  */
                    761: 
                    762: ulockf(file, atime)
                    763: char *file;
                    764: time_t atime;
                    765: {
                    766:        struct stat stbuf;
                    767:        time_t ptime;
                    768:        int ret;
                    769:        static int pid = -1;
                    770:        static char tempfile[NAMESIZE];
                    771: 
                    772:        if (pid < 0) {
                    773:                pid = getpid();
                    774:                sprintf(tempfile, "/usr/spool/uucp/LTMP.%d", pid);
                    775:        }
                    776:        if (onelock(pid, tempfile, file) == -1) {
                    777:                /* lock file exists */
                    778:                /* get status to check age of the lock file */
                    779:                ret = stat(file, &stbuf);
                    780:                if (ret != -1) {
                    781:                        time(&ptime);
                    782:                        if ((ptime - stbuf.st_ctime) < atime) {
                    783:                                /* file not old enough to delete */
                    784:                                return(FAIL);
                    785:                        }
                    786:                }
                    787:                ret = unlink(file);
                    788:                ret = onelock(pid, tempfile, file);
                    789:                if (ret != 0)
                    790:                        return(FAIL);
                    791:        }
                    792:        stlock(file);
                    793:        return(0);
                    794: }
                    795: 
                    796: 
                    797: #define MAXLOCKS 10    /* maximum number of lock files */
                    798: char *Lockfile[MAXLOCKS];
                    799: int Nlocks = 0;
                    800: 
                    801: /***
                    802:  *     stlock(name)    put name in list of lock files
                    803:  *     char *name;
                    804:  *
                    805:  *     return codes:  none
                    806:  */
                    807: 
                    808: stlock(name)
                    809: char *name;
                    810: {
                    811:        char *p;
                    812:        extern char *calloc();
                    813:        int i;
                    814: 
                    815:        for (i = 0; i < Nlocks; i++) {
                    816:                if (Lockfile[i] == NULL)
                    817:                        break;
                    818:        }
                    819:        ASSERT(i < MAXLOCKS, "TOO MANY LOCKS %d", i);
                    820:        if (i >= Nlocks)
                    821:                i = Nlocks++;
                    822:        p = calloc(strlen(name) + 1, sizeof (char));
                    823:        ASSERT(p != NULL, "CAN NOT ALLOCATE FOR %s", name);
                    824:        strcpy(p, name);
                    825:        Lockfile[i] = p;
                    826:        return;
                    827: }
                    828: 
                    829: 
                    830: /***
                    831:  *     rmlock(name)    remove all lock files in list
                    832:  *     char *name;     or name
                    833:  *
                    834:  *     return codes: none
                    835:  */
                    836: 
                    837: rmlock(name)
                    838: char *name;
                    839: {
                    840:        int i;
                    841: 
                    842:        for (i = 0; i < Nlocks; i++) {
                    843:                if (Lockfile[i] == NULL)
                    844:                        continue;
                    845:                if (name == NULL
                    846:                || strcmp(name, Lockfile[i]) == SAME) {
                    847:                        unlink(Lockfile[i]);
                    848:                        free(Lockfile[i]);
                    849:                        Lockfile[i] = NULL;
                    850:                }
                    851:        }
                    852:        return;
                    853: }
                    854: 
                    855: 
                    856: /*  this stuff from pjw  */
                    857: /*  /usr/pjw/bin/recover - check pids to remove unnecessary locks */
                    858: /*     isalock(name) returns 0 if the name is a lock */
                    859: /*     unlock(name)  unlocks name if it is a lock*/
                    860: /*     onelock(pid,tempfile,name) makes lock a name
                    861:        on behalf of pid.  Tempfile must be in the same
                    862:        file system as name. */
                    863: /*     lock(pid,tempfile,names) either locks all the
                    864:        names or none of them */
                    865: isalock(name) char *name;
                    866: {
                    867:        struct stat xstat;
                    868:        if(stat(name,&xstat)<0) return(0);
                    869:        if(xstat.st_size!=sizeof(int)) return(0);
                    870:        return(1);
                    871: }
                    872: unlock(name) char *name;
                    873: {
                    874:        if(isalock(name)) return(unlink(name));
                    875:        else return(-1);
                    876: }
                    877: onelock(pid,tempfile,name) char *tempfile,*name;
                    878: {      int fd;
                    879:        fd=creat(tempfile,0444);
                    880:        if(fd<0) return(-1);
                    881:        write(fd,(char *) &pid,sizeof(int));
                    882:        close(fd);
                    883:        if(link(tempfile,name)<0)
                    884:        {       unlink(tempfile);
                    885:                return(-1);
                    886:        }
                    887:        unlink(tempfile);
                    888:        return(0);
                    889: }
                    890: lock(pid,tempfile,names) char *tempfile,**names;
                    891: {      int i,j;
                    892:        for(i=0;names[i]!=0;i++)
                    893:        {       if(onelock(pid,tempfile,names[i])==0) continue;
                    894:                for(j=0;j<i;j++) unlink(names[j]);
                    895:                return(-1);
                    896:        }
                    897:        return(0);
                    898: }
                    899: 
                    900: #define LOCKPRE "/usr/spool/uucp/LCK."
                    901: 
                    902: /***
                    903:  *     delock(s)       remove a lock file
                    904:  *     char *s;
                    905:  *
                    906:  *     return codes:  0  |  FAIL
                    907:  */
                    908: 
                    909: delock(s)
                    910: char *s;
                    911: {
                    912:        char ln[30];
                    913: 
                    914:        sprintf(ln, "%s.%s", LOCKPRE, s);
                    915:        rmlock(ln);
                    916: }
                    917: 
                    918: 
                    919: /***
                    920:  *     mlock(sys)      create system lock
                    921:  *     char *sys;
                    922:  *
                    923:  *     return codes:  0  |  FAIL
                    924:  */
                    925: 
                    926: mlock(sys)
                    927: char *sys;
                    928: {
                    929:        char lname[30];
                    930:        sprintf(lname, "%s.%s", LOCKPRE, sys);
                    931:        return(ulockf(lname, (time_t) SLCKTIME ) < 0 ? FAIL : 0);
                    932: }
                    933: 
                    934: 
                    935: 
                    936: /***
                    937:  *     ultouch()       update access and modify times for lock files
                    938:  *
                    939:  *     return code - none
                    940:  */
                    941: 
                    942: ultouch()
                    943: {
                    944:        time_t time();
                    945:        int i;
                    946:        struct ut {
                    947:                time_t actime;
                    948:                time_t modtime;
                    949:        } ut;
                    950: 
                    951:        ut.actime = time(&ut.modtime);
                    952:        for (i = 0; i < Nlocks; i++) {
                    953:                if (Lockfile[i] == NULL)
                    954:                        continue;
                    955:                utime(Lockfile[i], &ut);
                    956:        }
                    957:        return;
                    958: }

unix.superglobalmegacorp.com

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