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