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
pokeinit defined in line 359; used 2 times
post defined in line 344; used 3 times
prefix defined in line 765; used 2 times
setmodem defined in line 625; used 7 times
settys defined in line 566; used 3 times
upcase defined in line 333; used 1 times

Defined variables

Devhome defined in line 125; used 2 times
Etcttys defined in line 119; used 15 times
Etcutmp defined in line 118; used 6 times
NEtcttys defined in line 122; used 5 times
etcutmp defined in line 131; used 7 times
nl defined in line 81; used 3 times
resetmodem defined in line 130; used 7 times
resettty defined in line 130; used 5 times
sccsid defined in line 2; never used
ttyslnbeg defined in line 133; used 6 times
usage defined in line 127; used 2 times
utmp defined in line 129; used 20 times
utmploc defined in line 132; used 8 times

Defined macros

CDEVSW defined in line 82; used 2 times
DH11 defined in line 76; used 1 times
DHINFO defined in line 96; used 2 times
DHOPEN defined in line 94; used 1 times
DHSCAR defined in line 100; used 1 times
DISABLE defined in line 116; used 2 times
DMF defined in line 77; used 1 times
DMFINFO defined in line 105; used 2 times
DMFOPEN defined in line 103; used 1 times
DMFSCAR defined in line 109; used 1 times
DZ11 defined in line 75; used 1 times
DZINFO defined in line 87; used 2 times
DZOPEN defined in line 85; used 1 times
DZSCAR defined in line 91; used 1 times
ENABLE defined in line 115; used 2 times
LINSIZ defined in line 136; used 1 times
NAMSIZ defined in line 135; used 6 times
NDH11 defined in line 98; used 1 times
NDHLINE defined in line 72; used 2 times
NDMF defined in line 107; used 1 times
NDMFLINE defined in line 73; used 2 times
NDZ11 defined in line 89; used 1 times
NDZLINE defined in line 71; used 2 times
NLVALUE defined in line 79; used 16 times
Last modified: 1996-12-02
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 6532
Valid CSS Valid XHTML 1.0 Strict