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
main(argc,argv)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 */
upcase(str,len)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 */
post(device,name)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 */
pokeinit(device,uname,enable)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 */
opnttys(device)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 */
settys(enable)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 */
opnttys(device)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 */
settys(enable)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
setmodem(ttyline,enable)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
setmodem(ttyline,enable)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
prefix(s1,s2)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 */
main()784 main()
785 {
786 fprintf(stderr,"acucntrl is not supported on this system\n");
787 }
788 #endif /* !DIALINOUT */
789