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

Defined functions

main defined in line 132; never used
opnttys defined in line 526; used 1 times
pokeinit defined in line 355; used 2 times
post defined in line 340; used 3 times
prefix defined in line 721; used 2 times
setmodem defined in line 603; used 7 times
settys defined in line 562; used 3 times
upcase defined in line 329; used 1 times

Defined variables

Devhome defined in line 119; used 2 times
Etcttys defined in line 113; used 15 times
Etcutmp defined in line 112; used 2 times
NEtcttys defined in line 116; used 5 times
etcutmp defined in line 125; used 7 times
nl defined in line 75; used 3 times
resetmodem defined in line 124; used 7 times
resettty defined in line 124; used 5 times
sccsid defined in line 2; never used
usage defined in line 121; used 2 times
utmp defined in line 123; used 20 times

Defined macros

CDEVSW defined in line 76; used 2 times
DH11 defined in line 70; used 1 times
DHINFO defined in line 90; used 1 times
DHOPEN defined in line 88; used 1 times
DHSCAR defined in line 94; used 1 times
DISABLE defined in line 110; used 2 times
DMF defined in line 71; used 1 times
DMFINFO defined in line 99; used 1 times
DMFOPEN defined in line 97; used 1 times
DMFSCAR defined in line 103; used 1 times
DZ11 defined in line 69; used 1 times
DZINFO defined in line 81; used 1 times
DZOPEN defined in line 79; used 1 times
DZSCAR defined in line 85; used 1 times
ENABLE defined in line 109; used 2 times
LINSIZ defined in line 130; used 1 times
NAMSIZ defined in line 129; used 6 times
NDH11 defined in line 92; used 1 times
NDHLINE defined in line 66; used 2 times
NDMF defined in line 101; used 1 times
NDMFLINE defined in line 67; used 2 times
NDZ11 defined in line 83; used 1 times
NDZLINE defined in line 65; used 2 times
NLVALUE defined in line 73; used 13 times
Last modified: 1986-02-13
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2714
Valid CSS Valid XHTML 1.0 Strict