# 2.11BSD#431 - /usr/src/old/cu/cu.c

##### Functions

    chwrsig           X
    cleanup           X
    conn              X
    delock            X
    dodiver           X
    dopercen          X
    echo              X
    equal             X
    exists            X
    isalock           X
    lock              X
    main              X
    mlock             X
    mode              X
    onelock           X
    prf               X
    rd                X
    rdc               X
    readmsg           X
    rmlock            X
    sig14             X
    sig2              X
    stlock            X
    ulockf            X
    ultouch           X
    unlock            X
    wr                X
    wrln              X
    xalarm            X
    xsleep            X

##### Variables

    Lockfile          X
    Nlocks            X
    c                 X
    connmsg           X
    dbflag            X
    devcua            X
    devcul            X
    dout              X
    ds                X
    efk               X
    intr              X
    justrung          X
    ln                X
    lspeed            X
    nhup              X
    nullbrk           X
    oc                X
    pflag             X
    pipes             X
    set14             X
    slnt              X
    taking            X
    terase            X
    tkill             X
    whoami            X

##### Macros

    ASSERT            X
    CRLF              X
    CTRLZ             X
    DIVER             X
    EOL               X
    FAIL              X
    LOCKPRE           X
    MAXLOCKS          X
    NAMESIZE          X
    ORDIN             X
    SAME              X
    SAWCR             X
    SAWTL             X
    SLCKTIME          X
    wrc               X

##### struct's

    ut                X

       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: }

#### Defined functions

chwrsig defined in line 550; used 1 times

- in line 205

cleanup defined in line 729; used 8 times

- in line 17, 121-126(4), 172, 208, 220

conn defined in line 232; used 1 times

- in line 169

delock defined in line 909; used 2 times

- in line 251, 303

dodiver defined in line 573; used 2 times

- in line 571, 654

dopercen defined in line 449; used 1 times

- in line 440

echo defined in line 703; used 4 times

- in line 356, 389-391(2), 413

equal defined in line 531; used 2 times

- in line 467, 484

exists defined in line 720; used 2 times

- in line 167(2)

isalock defined in line 865; used 1 times

- in line 874

lock defined in line 890; never used
main defined in line 114; never used
mlock defined in line 926; used 2 times

- in line 244-249(2)

mode defined in line 681; used 10 times

- in line 210-213(2), 377, 388, 401, 411, 434-436(2), 502, 525

onelock defined in line 877; used 3 times

- in line 776, 788, 893

prf defined in line 712; used 28 times

- in line 128, 163, 171, 197, 207, 219, 338, 382, 397, 421, 427(2), 443, 469, 475, 486, 492, 511, 521, 528, 563-569(4), 596-597(3), 725

rd defined in line 612; used 1 times

- in line 206

rdc defined in line 65; used 3 times

- in line 331, 403, 504

readmsg defined in line 557; used 3 times

- in line 551-553(2), 561

rmlock defined in line 837; used 2 times

- in line 731, 915

sig14 defined in line 96; used 2 times

- in line 98, 123

sig2 defined in line 75; used 2 times

- in line 402, 501

stlock defined in line 808; used 1 times

- in line 792

ulockf defined in line 762; used 1 times

- in line 931

ultouch defined in line 942; never used
unlock defined in line 872; never used
wr defined in line 325; used 1 times

- in line 212

wrln defined in line 540; used 11 times

- in line 478-482(5), 495-497(3), 507, 520-523(2)

xalarm defined in line 90; used 10 times

- in line 85-87(2), 280-282(2), 288-290(2), 297-300(2), 306-308(2)

xsleep defined in line 83; used 5 times

- in line 266, 477, 498, 509, 524

#### Defined variables

Lockfile defined in line 798; used 9 times

- in line 816, 825, 843-849(5), 953-955(2)

Nlocks defined in line 799; used 5 times

- in line 815-821(3), 842, 952

c defined in line 49; used 38 times

- in line 39, 67-69(3), 332-352(17), 506(2), 615, 627-634(4), 641-667(10)

connmsg defined in line 52; used 2 times

- in line 128, 171

dbflag defined in line 104; used 5 times

- in line 143, 427, 475, 562-566(2)

devcua defined in line 43; used 5 times

- in line 155-159(3), 167-169(2)

devcul defined in line 42; used 5 times

- in line 152, 160(2), 167-169(2)

dout defined in line 102; used 8 times

- in line 136, 190, 199, 345, 356, 391, 413, 684

ds defined in line 555; used 23 times

- in line 39(2), 65-70(4), 327, 396, 403, 410, 588-597(8), 614-624(3), 668-669(2)

efk defined in line 48; used 5 times

- in line 211, 428(2), 476(2)

intr defined in line 73; used 7 times

- in line 78, 400-403(2), 499-504(2), 512, 519

justrung defined in line 556; used 3 times

- in line 560, 674-675(2)

ln defined in line 46; used 24 times

- in line 169-172(4), 194-196(3), 218, 337, 363-365(2), 375-376(2), 404, 508-510(2), 544, 622, 660-663(3), 912-915(3)

lspeed defined in line 44; used 2 times

- in line 149, 174

nhup defined in line 103; used 4 times

- in line 203, 378, 402, 500

nullbrk defined in line 106; used 2 times

- in line 140, 334

oc defined in line 50; used 3 times

- in line 68, 334-336(2)

pflag defined in line 105; used 2 times

- in line 146, 336

pipes defined in line 107; used 5 times

- in line 198, 420, 426, 474, 565

sccsid defined in line 1; never used
set14 defined in line 81; used 2 times

- in line 92, 99

slnt defined in line 555; used 7 times

- in line 582-590(3), 614, 623-625(2), 658

taking defined in line 555; never used
terase defined in line 47; used 3 times

- in line 348, 506, 687

tkill defined in line 47; used 4 times

- in line 343, 352, 506, 686

whoami defined in line 549; used 1 times

- in line 552

#### Defined struct's

ut defined in line 946; never used

#### Defined macros

ASSERT defined in line 14; used 2 times

- in line 819-823(2)

CRLF defined in line 38; used 6 times

- in line 569, 661(2), 709(2), 717

CTRLZ defined in line 432; never used
DIVER defined in line 610; used 1 times

- in line 645

EOL defined in line 608; used 1 times

- in line 635

FAIL defined in line 11; used 6 times

- in line 17, 244-249(2), 784, 790, 931

LOCKPRE defined in line 900; used 2 times

- in line 914, 930

MAXLOCKS defined in line 797; used 2 times

- in line 798, 819

NAMESIZE defined in line 10; used 1 times

- in line 770

ORDIN defined in line 606; used 4 times

- in line 638-646(3), 652

SAME defined in line 12; used 1 times

- in line 846

SAWCR defined in line 607; used 3 times

- in line 631, 642-646(2)

SAWTL defined in line 609; used 1 times

- in line 641

SLCKTIME defined in line 13; used 1 times

- in line 931

wrc defined in line 39; used 5 times

- in line 337, 345, 404, 508-510(2)

Last modified: 1982-10-22 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 3552 |