# 2.11BSD#431 - /usr/src/usr.bin/uucp/acucntrl.c

##### Functions

    main              X
    opnttys           X
    pokeinit          X
    post              X
    prefix            X
    setmodem          X
    settys            X
    upcase            X

##### Variables

    Devhome           X
    Etcttys           X
    Etcutmp           X
    NEtcttys          X
    etcutmp           X
    nl                X
    resetmodem        X
    resettty          X
    ttyslnbeg         X
    usage             X
    utmp              X
    utmploc           X

##### Macros

    CDEVSW            X
    DH11              X
    DHINFO            X
    DHOPEN            X
    DHSCAR            X
    DISABLE           X
    DMF               X
    DMFINFO           X
    DMFOPEN           X
    DMFSCAR           X
    DZ11              X
    DZINFO            X
    DZOPEN            X
    DZSCAR            X
    ENABLE            X
    LINSIZ            X
    NAMSIZ            X
    NDH11             X
    NDHLINE           X
    NDMF              X
    NDMFLINE          X
    NDZ11             X
    NDZLINE           X
    NLVALUE           X

       1: #if defined(DOSCCS) && !defined(lint)
       2: static char sccsid[] = "@(#)acucntrl.c	5.8.2 (2.11BSD GTE) 1996/3/22";
       3: #endif
       4:
       5: /*  acucntrl - turn around tty line between dialin and dialout
       6:  *
       7:  * Usage:	acucntrl {enable,disable} /dev/ttydX
       8:  *
       9:  * History:
      10:  *	First written by Allan Wilkes (fisher!allan)
      11:  *
      12:  *	Modified June 8,1983 by W.Sebok (astrovax!wls) to poke kernel rather
      13:  * 	than use kernel hack to turn on/off modem control, using subroutine
      14:  *	stolen from program written by Tsutomu Shimomura
      15:  *	{astrovax,escher}!tsutomu
      16:  *
      17:  *	Worked over many times by W.Sebok (i.e. hacked to death)
      18:  *
      19:  * Operation:
      20:  *   disable (i.e. setup for dialing out)
      21:  *	(1) check input arguments
      22:  *	(2) look at the utmp file that the line is not in use
      23:  *	(3) disable modem control on terminal
      24:  *	(4) check for carrier on device
      25:  *	(5) change owner of device to real id
      26:  *	(6) edit /etc/ttys,  changing the first character of the appropriate
      27:  *	    line to 0
      28:  *	(7) send a hangup to process 1 to poke init to disable getty
      29:  *	(8) post uid name in capitals in utmp to let world know device has
      30:  *	    been grabbed
      31:  *	(9) make sure that DTR is on
      32:  *
      33:  *   enable (i.e.) restore for dialin
      34:  *	(1) check input arguments
      35:  *	(2) look in utmp to check that the line is not in use by another
      36:  *	(3) make sure modem control on terminal is disabled
      37:  *	(4) turn off DTR to make sure line is hung up
      38:  *	(5) condition line: clear exclusive use and set hangup on close modes
      39:  *	(6) turn on modem control
      40:  *	(7) edit /etc/ttys,  changing the first character of the appropriate
      41:  *	    line to 1
      42:  *	(8) send a hangup to process 1 to poke init to enable getty
      43:  *	(9) clear uid name for utmp file
      44:  */
      45:
      46: /* #define SENSECARRIER */
      47:
      48: #include "uucp.h"
      49: #include <sys/buf.h>
      50: #include <signal.h>
      51: #include <sys/conf.h>
      52: #ifdef pdp11
      53: #include <pdpuba/ubavar.h>
      54: #else
      55: #ifdef BSD4_2
      56: #include <vaxuba/ubavar.h>
      57: #else
      58: #include <sys/ubavar.h>
      59: #endif
      60: #endif
      61: #include <sys/stat.h>
      62: #include <nlist.h>
      63: #include <sgtty.h>
      64: #include <utmp.h>
      65: #include <pwd.h>
      66: #include <stdio.h>
      67: #include <sys/file.h>
      68: #include <errno.h>
      69: #include <string.h>
      70:
      71: #define NDZLINE 8   /* lines/dz */
      72: #define NDHLINE 16  /* lines/dh */
      73: #define NDMFLINE 8  /* lines/dmf */
      74:
      75: #define DZ11    1
      76: #define DH11    2
      77: #define DMF 3
      78:
      79: #define NLVALUE(val)    (nl[val].n_value)
      80:
      81: struct nlist nl[] = {
      82: #define CDEVSW  0
      83:     { "_cdevsw" },
      84:
      85: #define DZOPEN  1
      86:     { "_dzopen" },
      87: #define DZINFO  2
      88:     { "_dzinfo" },
      89: #define NDZ11   3
      90:     { "_dz_cnt" },
      91: #define DZSCAR  4
      92:     { "_dzsoftCAR" },
      93:
      94: #define DHOPEN  5
      95:     { "_dhopen" },
      96: #define DHINFO  6
      97:     { "_dhinfo" },
      98: #define NDH11   7
      99:     { "_ndh11" },
     100: #define DHSCAR  8
     101:     { "_dhsoftCAR" },
     102:
     103: #define DMFOPEN 9
     104:     { "_dmfopen" },
     105: #define DMFINFO 10
     106:     { "_dmfinfo" },
     107: #define NDMF    11
     108:     { "_ndmf" },
     109: #define DMFSCAR 12
     110:     { "_dmfsoftCAR" },
     111:
     112:     { "\0" }
     113: };
     114:
     115: #define ENABLE  1
     116: #define DISABLE 0
     117:
     118: char Etcutmp[] = _PATH_UTMP;
     119: char Etcttys[] = "/etc/ttys";
     120: #ifdef BSD4_3
     121: FILE *ttysfile, *nttysfile;
     122: char NEtcttys[] = "/etc/ttys.new";
     123: extern long ftell();
     124: #endif BSD4_3
     125: char Devhome[] = "/dev";
     126:
     127: char usage[] = "Usage: acucntrl {dis|en}able ttydX\n";
     128:
     129: struct utmp utmp;
     130: char resettty, resetmodem;
     131: int etcutmp;
     132: off_t utmploc;
     133: off_t ttyslnbeg;
     134:
     135: #define NAMSIZ  sizeof(utmp.ut_name)
     136: #define LINSIZ  sizeof(utmp.ut_line)
     137:
     138: main(argc, argv)
     139: int argc; char *argv[];
     140: {
     141:     register char *p;
     142:     register int i;
     143:     char uname[NAMSIZ], Uname[NAMSIZ];
     144:     int enable ;
     145:     char *device;
     146:     int devfile;
     147:     int uid, gid;
     148:     off_t lseek();
     149:     struct passwd *getpwuid();
     150:     char *rindex();
     151:
     152:     /* check input arguments */
     153:     if (argc!=3) {
     154:         fprintf(stderr, usage);
     155:         exit(1);
     156:     }
     157:
     158:     /* interpret command type */
     159:     if (prefix(argv[1], "disable")  || strcmp(argv[1], "dialout")==0)
     160:         enable = 0;
     161:     else if (prefix(argv[1], "enable")  || strcmp(argv[1], "dialin")==0)
     162:         enable = 1;
     163:     else {
     164:         fprintf(stderr, usage);
     165:         exit(1);
     166:     }
     167:
     168:     device = rindex(argv[2], '/');
     169:     device = (device == NULL) ? argv[2]: device+1;
     170:
     171:     /* only recognize devices of the form ttydX */
     172:     if (strncmp(device, "ttyd", 4)!=0) {
     173:         fprintf(stderr, "Bad Device Name %s", device);
     174:         exit(1);
     175:     }
     176:
     177:     opnttys(device);
     178:
     179:     /* Get nlist info */
     180:     nlist("/vmunix", nl);
     181:
     182:     /* Chdir to /dev */
     183:     if(chdir(Devhome) < 0) {
     184:         fprintf(stderr, "Cannot chdir to %s: %s\r\n",
     185:             Devhome, strerror(errno));
     186:         exit(1);
     187:     }
     188:
     189:     /* Get uid information */
     190:     uid = getuid();
     191:     gid = getgid();
     192:
     193:     p = getpwuid(uid)->pw_name;
     194:     if (p==NULL) {
     195:         fprintf(stderr, "cannot get uid name\n");
     196:         exit(1);
     197:     }
     198:
     199:     /*  to upper case */
     200:     i = 0;
     201:     do {
     202:         uname[i] = *p;
     203:         Uname[i] = (*p>='a' && *p<='z') ? (*p - ('a'-'A')) : *p;
     204:         i++; p++;
     205:     } while (*p && i<NAMSIZ);
     206:
     207:
     208:     /* check to see if line is being used */
     209:     if( (etcutmp = open(Etcutmp, 2)) < 0) {
     210:         fprintf(stderr, "On open %s open: %s\n",
     211:             Etcutmp, strerror(errno));
     212:         exit(1);
     213:     }
     214:
     215:     (void)lseek(etcutmp, utmploc, 0);
     216:
     217:     i = read(etcutmp, (char *)&utmp, sizeof(struct utmp));
     218:
     219:     if(
     220:         i == sizeof(struct utmp) &&
     221:         utmp.ut_line[0] != '\0'  &&
     222:         utmp.ut_name[0] != '\0'  &&
     223:         (
     224:             !upcase(utmp.ut_name, NAMSIZ) ||
     225:             (
     226:                 uid != 0 &&
     227:                 strncmp(utmp.ut_name, Uname, NAMSIZ) != 0
     228:             )
     229:         )
     230:     ) {
     231:         fprintf(stderr, "%s in use by %s\n", device, utmp.ut_name);
     232:         exit(2);
     233:     }
     234:
     235:     /* Disable modem control */
     236:     if (setmodem(device, DISABLE) < 0) {
     237:         fprintf(stderr, "Unable to disable modem control\n");
     238:         exit(1);
     239:     }
     240:
     241:     if (enable) {
     242:         if((devfile = open(device, 1)) < 0) {
     243:             fprintf(stderr, "On open of %s: %s\n",
     244:                 device, strerror(errno));
     245:             (void)setmodem(device, resetmodem);
     246:             exit(1);
     247:         }
     248:         /* Try one last time to hang up */
     249:         if (ioctl(devfile, TIOCCDTR, (char *)0) < 0)
     250:             fprintf(stderr, "On TIOCCDTR ioctl: %s\n",
     251:                 strerror(errno));
     252:
     253:         if (ioctl(devfile, TIOCNXCL, (char *)0) < 0)
     254:             fprintf(stderr,
     255:                 "Cannot clear Exclusive Use on %s: %s\n",
     256:                 device, strerror(errno));
     257:
     258:         if (ioctl(devfile, TIOCHPCL, (char *)0) < 0)
     259:             fprintf(stderr,
     260:                 "Cannot set hangup on close on %s: %s\n",
     261:                 device, strerror(errno));
     262:
     263:         i = resetmodem;
     264:
     265:         if (setmodem(device, ENABLE) < 0) {
     266:             fprintf(stderr, "Cannot Enable modem control\n");
     267:             (void)setmodem(device, i);
     268:             exit(1);
     269:         }
     270:         resetmodem=i;
     271:
     272:         if (settys(ENABLE)) {
     273:             fprintf(stderr, "%s already enabled\n", device);
     274:         } else {
     275:             pokeinit(device, Uname, enable);
     276:         }
     277:         post(device, "");
     278:
     279:     } else {
     280: #if defined(TIOCMGET) && defined(SENSECARRIER)
     281:         if (uid!=0) {
     282:             int linestat = 0;
     283:
     284:             /* check for presence of carrier */
     285:             sleep(2); /* need time after modem control turnoff */
     286:
     287:             if((devfile = open(device, 1)) < 0) {
     288:                 fprintf(stderr, "On open of %s: %s\n",
     289:                     device, strerror(errno));
     290:                 (void)setmodem(device, resetmodem);
     291:                 exit(1);
     292:             }
     293:
     294:             (void)ioctl(devfile, TIOCMGET, &linestat);
     295:
     296:             if (linestat&TIOCM_CAR) {
     297:                 fprintf(stderr, "%s is in use (Carrier On)\n",
     298:                     device);
     299:                 (void)setmodem(device, resetmodem);
     300:                 exit(2);
     301:             }
     302:             (void)close(devfile);
     303:         }
     304: #endif TIOCMGET
     305:         /* chown device */
     306:         if(chown(device, uid, gid) < 0)
     307:             fprintf(stderr, "Cannot chown %s: %s\n",
     308:                 device, strerror(errno));
     309:
     310:
     311:         /* poke init */
     312:         if(settys(DISABLE)) {
     313:             fprintf(stderr, "%s already disabled\n", device);
     314:         } else {
     315:             pokeinit(device, Uname, enable);
     316:         }
     317:         post(device, Uname);
     318:         if((devfile = open(device, O_RDWR|O_NDELAY)) < 0) {
     319:             fprintf(stderr, "On %s open: %s\n",
     320:                 device, strerror(errno));
     321:         } else {
     322:             if(ioctl(devfile, TIOCSDTR, (char *)0) < 0)
     323:                 fprintf(stderr,
     324:                     "Cannot set DTR on %s: %s\n",
     325:                     device, strerror(errno));
     326:         }
     327:     }
     328:
     329:     exit(0);
     330: }
     331:
     332: /* return true if no lower case */
     333: upcase(str, len)
     334: register char *str;
     335: register int len;
     336: {
     337:     for (; *str, --len >= 0 ; str++)
     338:         if (*str>='a' && *str<='z')
     339:             return(0);
     340:     return(1);
     341: }
     342:
     343: /* Post name to public */
     344: post(device, name)
     345: char *device, *name;
     346: {
     347:     (void)time((time_t *)&utmp.ut_time);
     348:     strncpy(utmp.ut_line, device, LINSIZ);
     349:     strncpy(utmp.ut_name, name,  NAMSIZ);
     350:     if (lseek(etcutmp, utmploc, 0) < 0)
     351:         fprintf(stderr, "on lseek in %s: %s", Etcutmp,
     352:             strerror(errno));
     353:     if (write(etcutmp, (char *)&utmp, sizeof(utmp)) < 0)
     354:         fprintf(stderr, "on write in %s: %s", Etcutmp,
     355:             strerror(errno));
     356: }
     357:
     358: /* poke process 1 and wait for it to do its thing */
     359: pokeinit(device, uname, enable)
     360: char *uname, *device; int enable;
     361: {
     362:     struct utmp utmp;
     363:     register int i;
     364:
     365:     post(device, uname);
     366:
     367:     /* poke init */
     368:     if (kill(1, SIGHUP)) {
     369:         fprintf(stderr,
     370:             "Cannot send hangup to init process: %s\n",
     371:             strerror(errno));
     372:         (void)settys(resettty);
     373:         (void)setmodem(device, resetmodem);
     374:         exit(1);
     375:     }
     376:
     377:     if (enable)
     378:         return;
     379:
     380:     /* wait till init has responded, clearing the utmp entry */
     381:     i = 100;
     382:     do {
     383:         sleep(1);
     384:         if (lseek(etcutmp, utmploc, 0) < 0)
     385:             fprintf(stderr, "On lseek in %s: %s", Etcutmp,
     386:                 strerror(errno));
     387:         if (read(etcutmp, (char *)&utmp, sizeof utmp) < 0)
     388:             fprintf(stderr, "On read from %s: %s", Etcutmp,
     389:                 strerror(errno));
     390:     } while (utmp.ut_name[0] != '\0' && --i > 0);
     391: }
     392:
     393: #ifdef BSD4_3
     394: /* identify terminal line in ttys */
     395: opnttys(device)
     396: char *device;
     397: {
     398:     register int  ndevice;
     399:     register char *p;
     400:     char *index();
     401:     char linebuf[BUFSIZ];
     402:
     403:     ttysfile = NULL;
     404:     do {
     405:         if (ttysfile != NULL) {
     406:             fclose(ttysfile);
     407:             sleep(5);
     408:         }
     409:         ttysfile = fopen(Etcttys, "r");
     410:         if(ttysfile == NULL) {
     411:             fprintf(stderr, "Cannot open %s: %s\n", Etcttys,
     412:                 strerror(errno));
     413:             exit(1);
     414:         }
     415:     } while (flock(fileno(ttysfile), LOCK_NB|LOCK_EX) < 0);
     416:     nttysfile = fopen(NEtcttys, "w");
     417:     if(nttysfile == NULL) {
     418:         fprintf(stderr, "Cannot open %s: %s\n", Etcttys,
     419:             strerror(errno));
     420:         exit(1);
     421:     }
     422:
     423:     ndevice = strlen(device);
     424: #ifndef BRL4_2
     425:     utmploc = sizeof(utmp);
     426: #else BRL4_2
     427:     utmploc = 0;
     428: #endif BRL4_2
     429:
     430:     while(fgets(linebuf, sizeof(linebuf) - 1, ttysfile) != NULL) {
     431:         if(strncmp(device, linebuf, ndevice) == 0)
     432:             return;
     433:         ttyslnbeg += strlen(linebuf);
     434:         if (linebuf[0] != '#' && linebuf[0] != '\n')
     435:             utmploc += sizeof(utmp);
     436:         if (fputs(linebuf, nttysfile) == NULL) {
     437:             fprintf(stderr, "On %s write: %s\n",
     438:                 Etcttys, strerror(errno));
     439:             exit(1);
     440:         }
     441:
     442:     }
     443:     fprintf(stderr, "%s not found in %s\n", device, Etcttys);
     444:     exit(1);
     445: }
     446:
     447: /* modify appropriate line in /etc/ttys to turn on/off the device */
     448: settys(enable)
     449: int enable;
     450: {
     451:     register char *cp, *cp2;
     452:     char lbuf[BUFSIZ];
     453:     int i;
     454:     char c1, c2;
     455:
     456:     (void) fseek(ttysfile, ttyslnbeg, 0);
     457:     if(fgets(lbuf, BUFSIZ, ttysfile) == NULL) {
     458:         fprintf(stderr, "On %s read: %s\n",
     459:             Etcttys, strerror(errno));
     460:         exit(1);
     461:     }
     462:     /* format is now */
     463:     /* ttyd0 std.100 dialup on secure # comment */
     464:     /* except, 2nd item may have embedded spaces inside quotes, Hubert */
     465:     cp = lbuf;
     466:     for (i=0;*cp && i<3;i++) {
     467:         if (*cp == '"') {
     468:             cp++;
     469:             while (*cp && *cp != '"')
     470:                 cp++;
     471:             if (*cp != '\0')
     472:                 cp++;
     473:         }else {
     474:             while (*cp && *cp != ' ' && *cp != '\t')
     475:                 cp++;
     476:         }
     477:         while (*cp && (*cp == ' ' || *cp == '\t'))
     478:             cp++;
     479:     }
     480:     if (*cp == '\0') {
     481:         fprintf(stderr,"Badly formatted line in /etc/ttys:\n%s", lbuf);
     482:         exit(1);
     483:     }
     484:     c1 = *--cp;
     485:     *cp++ = '\0';
     486:     cp2 = cp;
     487:     while (*cp && *cp != ' ' && *cp != '\t' && *cp != '\n')
     488:         cp++;
     489:     if (*cp == '\0') {
     490:         fprintf(stderr,"Badly formatted line in /etc/ttys:\n%s", lbuf);
     491:         exit(1);
     492:     }
     493:     c2 = *cp;
     494:     *cp++ = '\0';
     495:     while (*cp && (*cp == ' ' || *cp == '\t'))
     496:         cp++;
     497:     resettty = strcmp("on", cp2) != 0;
     498:     fprintf(nttysfile,"%s%c%s%c%s", lbuf, c1, enable ? "on" : "off", c2, cp);
     499:     if (ferror(nttysfile)) {
     500:         fprintf(stderr, "On %s fprintf: %s\n",
     501:             NEtcttys, strerror(errno));
     502:         exit(1);
     503:     }
     504:     while(fgets(lbuf, sizeof(lbuf) - 1, ttysfile) != NULL) {
     505:         if (fputs(lbuf, nttysfile) == NULL) {
     506:             fprintf(stderr, "On %s write: %s\n",
     507:                 NEtcttys, strerror(errno));
     508:             exit(1);
     509:         }
     510:     }
     511:
     512:     if (enable^resettty)
     513:         (void) unlink(NEtcttys);
     514:     else {
     515:         struct stat statb;
     516:         if (stat(Etcttys, &statb) == 0) {
     517:             fchmod(fileno(nttysfile) ,statb.st_mode);
     518:             fchown(fileno(nttysfile), statb.st_uid, statb.st_gid);
     519:         }
     520:         (void) rename(NEtcttys, Etcttys);
     521:     }
     522:     (void) fclose(nttysfile);
     523:     (void) fclose(ttysfile);
     524:     return enable^resettty;
     525: }
     526:
     527: #else !BSD4_3
     528:
     529: /* identify terminal line in ttys */
     530: opnttys(device)
     531: char *device;
     532: {
     533:     register FILE *ttysfile;
     534:     register int  ndevice, lnsiz;
     535:     register char *p;
     536:     char *index();
     537:     char linebuf[BUFSIZ];
     538:
     539:     ttysfile = fopen(Etcttys, "r");
     540:     if(ttysfile == NULL) {
     541:         fprintf(stderr, "Cannot open %s: %s\n", Etcttys,
     542:             strerror(errno));
     543:         exit(1);
     544:     }
     545:
     546:     ndevice = strlen(device);
     547:     ttyslnbeg = 0;
     548:     utmploc = 0;
     549:
     550:     while(fgets(linebuf, sizeof(linebuf) - 1, ttysfile) != NULL) {
     551:         lnsiz = strlen(linebuf);
     552:         if ((p = index(linebuf, '\n')) != NULL)
     553:             *p = '\0';
     554:         if(strncmp(device, &linebuf[2], ndevice) == 0) {
     555:             (void)fclose(ttysfile);
     556:             return;
     557:         }
     558:         ttyslnbeg += lnsiz;
     559:         utmploc += sizeof(utmp);
     560:     }
     561:     fprintf(stderr, "%s not found in %s\n", device, Etcttys);
     562:     exit(1);
     563: }
     564:
     565: /* modify appropriate line in /etc/ttys to turn on/off the device */
     566: settys(enable)
     567: int enable;
     568: {
     569:     int ittysfil;
     570:     char out, in;
     571:
     572:     ittysfil = open(Etcttys, 2);
     573:     if(ittysfil < 0) {
     574:         fprintf(stderr, "Cannot open %s for output: %s\n",
     575:             Etcttys, strerror(errno));
     576:         exit(1);
     577:     }
     578:     (void)lseek(ittysfil, ttyslnbeg, 0);
     579:     if(read(ittysfil, &in, 1)<0) {
     580:         fprintf(stderr, "On %s write: %s\n",
     581:             Etcttys, strerror(errno));
     582:         exit(1);
     583:     }
     584:     resettty = (in == '1');
     585:     out = enable ? '1' : '0';
     586:     (void)lseek(ittysfil, ttyslnbeg, 0);
     587:     if(write(ittysfil, &out, 1)<0) {
     588:         fprintf(stderr, "On %s write: %s\n",
     589:             Etcttys, strerror(errno));
     590:         exit(1);
     591:     }
     592:     (void)close(ittysfil);
     593:     return(in==out);
     594: }
     595: #endif !BSD4_3
     596:
     597: /*
     598:  * Excerpted from (June 8, 1983 W.Sebok)
     599:  * > ttymodem.c - enable/disable modem control for tty lines.
     600:  * >
     601:  * > Knows about DZ11s and DH11/DM11s.
     602:  * > 23.3.83 - TS
     603:  * > modified to know about DMF's  (hasn't been tested) Nov 8, 1984 - WLS
     604:  */
     605:
     606:
     607: /*
     608:  * 2.11BSD NOTE:  2.11BSD doesn't use ui_flags.  We've included the code
     609:  * for correctness in case someone decides to change the way the 2.11BSD
     610:  * tty drivers work.  Mostly what needs to be done is have the tty drivers
     611:  * do something like:
     612:  *
     613:  *	if ((minor(dev)&0200) || (XXinfo[unit].ui_flags&(1L<<line))) {
     614:  *		XXsoftCAR[unit] |= 1L << line;
     615:  *		tp->t_state |= TS_CARR_ON;
     616:  *	}
     617:  *	else
     618:  *		XXsoftCAR[unit] &= ~(1L << line);
     619:  *
     620:  * (2.11BSD uses a bit 0200 in the minor device number of a tty /dev node
     621:  * to indicate soft carrier as opposed to compiling it into the kernel as
     622:  * 4.3BSD does.)  This code minus the check of ui_flags is already present
     623:  * in all 2.11BSD drivers.
     624:  */
     625: setmodem(ttyline, enable)
     626: char *ttyline; int enable;
     627: {
     628:     dev_t dev;
     629:     int kmem;
     630:     int unit, line, nlines;
     631:     int addr;
     632:     int devtype=0;
     633:     char cflags;
     634:     unsigned short sflags;
     635: #ifdef BSD4_2
     636:     long flags, tflags;
     637: #else
     638:     short flags, tflags;
     639: #endif
     640:     struct uba_device *ubinfo;
     641:     struct stat statb;
     642:     struct cdevsw cdevsw;
     643:
     644:     if(nl[CDEVSW].n_type == 0) {
     645:         fprintf(stderr, "No namelist.\n");
     646:         return(-1);
     647:     }
     648:
     649:     if((kmem = open("/dev/kmem", 2)) < 0) {
     650:         fprintf(stderr, "/dev/kmem open: %s\n", strerror(errno));
     651:         return(-1);
     652:     }
     653:
     654:     if(stat(ttyline, &statb) < 0) {
     655:         fprintf(stderr, "%s stat: %s\n", ttyline, strerror(errno));
     656:         return(-1);
     657:     }
     658:
     659:     if((statb.st_mode&S_IFMT) != S_IFCHR) {
     660:         fprintf(stderr, "%s is not a character device.\n",ttyline);
     661:         return(-1);
     662:     }
     663:
     664:     dev = statb.st_rdev;
     665:     (void)lseek(kmem,
     666:         (off_t) &(((struct cdevsw *)NLVALUE(CDEVSW))[major(dev)]),0);
     667:     (void)read(kmem, (char *) &cdevsw, sizeof cdevsw);
     668:
     669:     if((int)(cdevsw.d_open) == NLVALUE(DZOPEN)) {
     670:         devtype = DZ11;
     671:         unit = minor(dev) / NDZLINE;
     672:         line = minor(dev) % NDZLINE;
     673: #ifdef pdp11
     674:         ubinfo = &(((struct uba_device *)NLVALUE(DZINFO))[unit]);
     675: #else
     676:         addr = (int) &(((int *)NLVALUE(DZINFO))[unit]);
     677: #endif
     678:         (void)lseek(kmem, (off_t) NLVALUE(NDZ11), 0);
     679:     } else if((int)(cdevsw.d_open) == NLVALUE(DHOPEN)) {
     680:         devtype = DH11;
     681:         unit = minor(dev) / NDHLINE;
     682:         line = minor(dev) % NDHLINE;
     683: #ifdef pdp11
     684:         ubinfo = &(((struct uba_device *)NLVALUE(DHINFO))[unit]);
     685: #else
     686:         addr = (int) &(((int *)NLVALUE(DHINFO))[unit]);
     687: #endif
     688:         (void)lseek(kmem, (off_t) NLVALUE(NDH11), 0);
     689:     } else if((int)(cdevsw.d_open) == NLVALUE(DMFOPEN)) {
     690:         devtype = DMF;
     691:         unit = minor(dev) / NDMFLINE;
     692:         line = minor(dev) % NDMFLINE;
     693: #ifdef pdp11
     694:         ubinfo = &(((struct uba_device *)NLVALUE(DMFINFO))[unit]);
     695: #else
     696:         addr = (int) &(((int *)NLVALUE(DMFINFO))[unit]);
     697: #endif
     698:         (void)lseek(kmem, (off_t) NLVALUE(NDMF), 0);
     699:     } else {
     700:         fprintf(stderr, "Device %s (%d/%d) unknown.\n", ttyline,
     701:             major(dev), minor(dev));
     702:         return(-1);
     703:     }
     704:
     705:     (void)read(kmem, (char *) &nlines, sizeof nlines);
     706:     if(minor(dev) >= nlines) {
     707:         fprintf(stderr, "Sub-device %d does not exist (only %d).\n",
     708:             minor(dev), nlines);
     709:         return(-1);
     710:     }
     711:
     712: #ifndef pdp11
     713:     (void)lseek(kmem, (off_t)addr, 0);
     714:     (void)read(kmem, (char *) &ubinfo, sizeof ubinfo);
     715: #endif
     716:     (void)lseek(kmem, (off_t) &(ubinfo->ui_flags), 0);
     717:     (void)read(kmem, (char *) &flags, sizeof flags);
     718:
     719: #ifdef BSD4_2
     720:     tflags = 1L<<line;
     721: #else
     722:     tflags = 1<<line;
     723: #endif
     724:     resetmodem = ((flags&tflags) == 0);
     725:     flags = enable ? (flags & ~tflags) : (flags | tflags);
     726:     (void)lseek(kmem, (off_t) &(ubinfo->ui_flags), 0);
     727:     (void)write(kmem, (char *) &flags, sizeof flags);
     728: #ifndef pdp11
     729:     switch(devtype) {
     730:         case DZ11:
     731:             if((addr = NLVALUE(DZSCAR)) == 0) {
     732:                 fprintf(stderr, "No dzsoftCAR.\n");
     733:                 return(-1);
     734:             }
     735:             cflags = flags;
     736:             (void)lseek(kmem, (off_t) &(((char *)addr)[unit]), 0);
     737:             (void)write(kmem, (char *) &cflags, sizeof cflags);
     738:             break;
     739:         case DH11:
     740:             if((addr = NLVALUE(DHSCAR)) == 0) {
     741:                 fprintf(stderr, "No dhsoftCAR.\n");
     742:                 return(-1);
     743:             }
     744:             sflags = flags;
     745:             (void)lseek(kmem, (off_t) &(((short *)addr)[unit]), 0);
     746:             (void)write(kmem, (char *) &sflags, sizeof sflags);
     747:             break;
     748:         case DMF:
     749:             if((addr = NLVALUE(DMFSCAR)) == 0) {
     750:                 fprintf(stderr, "No dmfsoftCAR.\n");
     751:                 return(-1);
     752:             }
     753:             cflags = flags;
     754:             (void)lseek(kmem, (off_t) &(((char *)addr)[unit]), 0);
     755:             (void)write(kmem, (char *) &flags, sizeof cflags);
     756:             break;
     757:         default:
     758:             fprintf(stderr, "Unknown device type\n");
     759:             return(-1);
     760:     }
     761: #endif
     762:     return(0);
     763: }
     764:
     765: prefix(s1, s2)
     766:     register char *s1, *s2;
     767: {
     768:     register char c;
     769:
     770:     while ((c = *s1++) == *s2++)
     771:         if (c == '\0')
     772:             return (1);
     773:     return (c == '\0');
     774: }

#### Defined functions

main defined in line 138; never used
opnttys defined in line 530; used 1 times

- in line 177

pokeinit defined in line 359; used 2 times

- in line 275, 315

post defined in line 344; used 3 times

- in line 277, 317, 365

prefix defined in line 765; used 2 times

- in line 159-161(2)

setmodem defined in line 625; used 7 times

- in line 236, 245, 265-267(2), 290, 299, 373

settys defined in line 566; used 3 times

- in line 272, 312, 372

upcase defined in line 333; used 1 times

- in line 224

#### Defined variables

Devhome defined in line 125; used 2 times

- in line 183-185(2)

Etcttys defined in line 119; used 15 times

- in line 409-411(2), 418, 438-443(2), 459, 516-520(2), 539-541(2), 561, 572-575(2), 581, 589

Etcutmp defined in line 118; used 6 times

- in line 209-211(2), 351-354(2), 385-388(2)

NEtcttys defined in line 122; used 5 times

- in line 416, 501, 507, 513, 520

etcutmp defined in line 131; used 7 times

- in line 209, 215-217(2), 350-353(2), 384-387(2)

nl defined in line 81; used 3 times

- in line 79, 180, 644

resetmodem defined in line 130; used 7 times

- in line 245, 263, 270, 290, 299, 373, 724

resettty defined in line 130; used 5 times

- in line 372, 497, 512, 524, 584

sccsid defined in line 2; never used
ttyslnbeg defined in line 133; used 6 times

- in line 433, 456, 547, 558, 578, 586

usage defined in line 127; used 2 times

- in line 154, 164

utmp defined in line 129; used 20 times

- in line 135-136(2), 217-231(6), 347-353(5), 362, 387-390(3), 425, 435, 559

utmploc defined in line 132; used 8 times

- in line 215, 350, 384, 425-427(2), 435, 548, 559

#### Defined macros

CDEVSW defined in line 82; used 2 times

- in line 644, 666

DH11 defined in line 76; used 1 times

- in line 680

DHINFO defined in line 96; used 2 times

- in line 684-686(2)

DHOPEN defined in line 94; used 1 times

- in line 679

DHSCAR defined in line 100; used 1 times

- in line 740

DISABLE defined in line 116; used 2 times

- in line 236, 312

DMF defined in line 77; used 1 times

- in line 690

DMFINFO defined in line 105; used 2 times

- in line 694-696(2)

DMFOPEN defined in line 103; used 1 times

- in line 689

DMFSCAR defined in line 109; used 1 times

- in line 749

DZ11 defined in line 75; used 1 times

- in line 670

DZINFO defined in line 87; used 2 times

- in line 674-676(2)

DZOPEN defined in line 85; used 1 times

- in line 669

DZSCAR defined in line 91; used 1 times

- in line 731

ENABLE defined in line 115; used 2 times

- in line 265, 272

LINSIZ defined in line 136; used 1 times

- in line 348

NAMSIZ defined in line 135; used 6 times

- in line 143(2), 205, 224-227(2), 349

NDH11 defined in line 98; used 1 times

- in line 688

NDHLINE defined in line 72; used 2 times

- in line 681-682(2)

NDMF defined in line 107; used 1 times

- in line 698

NDMFLINE defined in line 73; used 2 times

- in line 691-692(2)

NDZ11 defined in line 89; used 1 times

- in line 678

NDZLINE defined in line 71; used 2 times

- in line 671-672(2)

NLVALUE defined in line 79; used 16 times

- in line 666-698(13), 731, 740, 749

Last modified: 1996-12-02 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 2370 |