|
|
1.1 ! root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.