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