file reorg, pathnames.h, paths.h
[unix-history] / usr / src / usr.bin / uucp / acucntrl / acucntrl.c
CommitLineData
e1d95021 1#ifndef lint
c861cac9 2static char sccsid[] = "@(#)acucntrl.c 5.16 (Berkeley) %G%";
e1d95021
RC
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
c861cac9 22 * (2) look in _PATH_UTMP to check that the line is not in use by another
e1d95021
RC
23 * (3) disable modem control on terminal
24 * (4) check for carrier on device
25 * (5) change owner of device to real id
c861cac9 26 * (6) edit _PATH_TTYS, changing the first character of the appropriate
e1d95021
RC
27 * line to 0
28 * (7) send a hangup to process 1 to poke init to disable getty
c861cac9
KB
29 * (8) post uid name in capitals in _PATH_UTMP to let world know device
30 * has been grabbed
e1d95021
RC
31 * (9) make sure that DTR is on
32 *
33 * enable (i.e.) restore for dialin
34 * (1) check input arguments
c861cac9 35 * (2) look in _PATH_UTMP to check that the line is not in use by another
e1d95021
RC
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
c861cac9 40 * (7) edit _PATH_TTYS, changing the first character of the appropriate
e1d95021
RC
41 * line to 1
42 * (8) send a hangup to process 1 to poke init to enable getty
c861cac9 43 * (9) clear uid name for _PATH_UTMP
e1d95021
RC
44 */
45
46/* #define SENSECARRIER */
47
48#include "uucp.h"
5ebee544 49#ifdef DIALINOUT
e1d95021 50#include <sys/buf.h>
1a85e9d2 51#include <signal.h>
e1d95021 52#include <sys/conf.h>
5ebee544
RA
53#ifdef vax
54#ifdef BSD4_2
55#include <vaxuba/ubavar.h>
56#else
57#include <sys/ubavar.h>
58#endif
59#endif /* vax */
e1d95021
RC
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>
2a735ba9 66#include <sys/file.h>
c861cac9 67#include "pathnames.h"
e1d95021
RC
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
79struct 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
c861cac9 116char Etcttys[] = _PATH_TTYS;
302c7a50 117#ifdef BSD4_3
2a735ba9 118FILE *ttysfile, *nttysfile;
c861cac9 119char NEtcttys[] = _PATH_NEWTTYS;
302c7a50
JB
120extern long ftell();
121#endif BSD4_3
c861cac9 122char Devhome[] = _PATH_DEV;
e1d95021
RC
123
124char usage[] = "Usage: acucntrl {dis|en}able ttydX\n";
125
126struct utmp utmp;
127char resettty, resetmodem;
128int etcutmp;
1a85e9d2
RC
129off_t utmploc;
130off_t ttyslnbeg;
dd0ab928
RA
131extern int errno;
132extern char *sys_errlist[];
21038734 133off_t lseek();
e1d95021
RC
134
135#define NAMSIZ sizeof(utmp.ut_name)
136#define LINSIZ sizeof(utmp.ut_line)
137
138main(argc, argv)
139int 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;
e1d95021
RC
148 struct passwd *getpwuid();
149 char *rindex();
e1d95021
RC
150
151 /* check input arguments */
dd0ab928 152 if (argc!=3 && argc != 4) {
e1d95021
RC
153 fprintf(stderr, usage);
154 exit(1);
155 }
156
157 /* interpret command type */
302c7a50 158 if (prefix(argv[1], "disable") || strcmp(argv[1], "dialout")==0)
e1d95021 159 enable = 0;
302c7a50 160 else if (prefix(argv[1], "enable") || strcmp(argv[1], "dialin")==0)
e1d95021
RC
161 enable = 1;
162 else {
163 fprintf(stderr, usage);
164 exit(1);
165 }
166
302c7a50 167 device = rindex(argv[2], '/');
e1d95021
RC
168 device = (device == NULL) ? argv[2]: device+1;
169
e1d95021
RC
170 opnttys(device);
171
5ebee544 172#ifdef vax
e1d95021 173 /* Get nlist info */
c861cac9 174 nlist(_PATH_UNIX, nl);
5ebee544 175#endif vax
e1d95021
RC
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) {
302c7a50 190 fprintf(stderr, "cannot get uid name\n");
e1d95021
RC
191 exit(1);
192 }
193
dd0ab928
RA
194 if (strcmp(p, "uucp") == 0 && argc == 4)
195 p = argv[3];
196
e1d95021
RC
197 /* to upper case */
198 i = 0;
199 do {
200 uname[i] = *p;
f5a0d14f
RA
201 Uname[i++] = (*p>='a' && *p<='z') ? (*p - ('a'-'A')) : *p;
202 } while (*p++ && i<NAMSIZ);
e1d95021
RC
203
204 /* check to see if line is being used */
c861cac9 205 if( (etcutmp = open(_PATH_UTMP, 2)) < 0) {
302c7a50 206 fprintf(stderr, "On open %s open: %s\n",
c861cac9 207 _PATH_UTMP, sys_errlist[errno]);
e1d95021
RC
208 exit(1);
209 }
210
302c7a50 211 (void)lseek(etcutmp, utmploc, 0);
e1d95021 212
302c7a50 213 i = read(etcutmp, (char *)&utmp, sizeof(struct utmp));
e1d95021
RC
214
215 if(
216 i == sizeof(struct utmp) &&
217 utmp.ut_line[0] != '\0' &&
218 utmp.ut_name[0] != '\0' &&
219 (
302c7a50 220 !upcase(utmp.ut_name, NAMSIZ) ||
e1d95021
RC
221 (
222 uid != 0 &&
302c7a50 223 strncmp(utmp.ut_name, Uname, NAMSIZ) != 0
e1d95021
RC
224 )
225 )
226 ) {
227 fprintf(stderr, "%s in use by %s\n", device, utmp.ut_name);
228 exit(2);
229 }
230
5ebee544 231#ifndef sequent
e1d95021 232 /* Disable modem control */
302c7a50
JB
233 if (setmodem(device, DISABLE) < 0) {
234 fprintf(stderr, "Unable to disable modem control\n");
e1d95021
RC
235 exit(1);
236 }
5ebee544 237#endif !sequent
e1d95021
RC
238
239 if (enable) {
5ebee544
RA
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
e1d95021 248 if((devfile = open(device, 1)) < 0) {
302c7a50 249 fprintf(stderr, "On open of %s: %s\n",
e1d95021 250 device, sys_errlist[errno]);
302c7a50 251 (void)setmodem(device, resetmodem);
e1d95021
RC
252 exit(1);
253 }
254 /* Try one last time to hang up */
302c7a50
JB
255 if (ioctl(devfile, (int)TIOCCDTR, (char *)0) < 0)
256 fprintf(stderr, "On TIOCCDTR ioctl: %s\n",
e1d95021
RC
257 sys_errlist[errno]);
258
302c7a50 259 if (ioctl(devfile, (int)TIOCNXCL, (char *)0) < 0)
e1d95021
RC
260 fprintf(stderr,
261 "Cannot clear Exclusive Use on %s: %s\n",
262 device, sys_errlist[errno]);
263
302c7a50 264 if (ioctl(devfile, (int)TIOCHPCL, (char *)0) < 0)
e1d95021
RC
265 fprintf(stderr,
266 "Cannot set hangup on close on %s: %s\n",
267 device, sys_errlist[errno]);
268
5ebee544 269#endif !sequent
e1d95021
RC
270 i = resetmodem;
271
5ebee544 272#ifndef sequent
302c7a50
JB
273 if (setmodem(device, ENABLE) < 0) {
274 fprintf(stderr, "Cannot Enable modem control\n");
275 (void)setmodem(device, i);
e1d95021
RC
276 exit(1);
277 }
5ebee544 278#endif sequent
e1d95021
RC
279 resetmodem=i;
280
1a85e9d2 281 if (settys(ENABLE)) {
302c7a50 282 fprintf(stderr, "%s already enabled\n", device);
1a85e9d2 283 } else {
302c7a50 284 pokeinit(device, Uname, enable);
1a85e9d2 285 }
302c7a50 286 post(device, "");
e1d95021
RC
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) {
302c7a50 297 fprintf(stderr, "On open of %s: %s\n",
e1d95021 298 device, sys_errlist[errno]);
302c7a50 299 (void)setmodem(device, resetmodem);
e1d95021
RC
300 exit(1);
301 }
302
302c7a50 303 (void)ioctl(devfile, TIOCMGET, &linestat);
e1d95021
RC
304
305 if (linestat&TIOCM_CAR) {
302c7a50 306 fprintf(stderr, "%s is in use (Carrier On)\n",
e1d95021 307 device);
302c7a50 308 (void)setmodem(device, resetmodem);
e1d95021
RC
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 */
1a85e9d2 321 if(settys(DISABLE)) {
302c7a50 322 fprintf(stderr, "%s already disabled\n", device);
1a85e9d2 323 } else {
302c7a50 324 pokeinit(device, Uname, enable);
1a85e9d2 325 }
302c7a50 326 post(device, Uname);
5ebee544
RA
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
2a735ba9 334 if((devfile = open(device, O_RDWR|O_NDELAY)) < 0) {
e1d95021
RC
335 fprintf(stderr, "On %s open: %s\n",
336 device, sys_errlist[errno]);
337 } else {
1a85e9d2 338 if(ioctl(devfile, (int)TIOCSDTR, (char *)0) < 0)
e1d95021
RC
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 */
302c7a50 349upcase(str, len)
e1d95021
RC
350register char *str;
351register 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 */
302c7a50 360post(device, name)
e1d95021
RC
361char *device, *name;
362{
1a85e9d2 363 (void)time((time_t *)&utmp.ut_time);
7b465ce2
JB
364 strncpy(utmp.ut_line, device, LINSIZ);
365 strncpy(utmp.ut_name, name, NAMSIZ);
2a735ba9 366 if (lseek(etcutmp, utmploc, 0) < 0)
c861cac9
KB
367 fprintf(stderr, "on lseek in %s: %s",
368 _PATH_UTMP, sys_errlist[errno]);
2a735ba9 369 if (write(etcutmp, (char *)&utmp, sizeof(utmp)) < 0)
c861cac9
KB
370 fprintf(stderr, "on write in %s: %s",
371 _PATH_UTMP, sys_errlist[errno]);
e1d95021
RC
372}
373
374/* poke process 1 and wait for it to do its thing */
302c7a50 375pokeinit(device, uname, enable)
e1d95021
RC
376char *uname, *device; int enable;
377{
378 struct utmp utmp;
1a85e9d2 379 register int i;
e1d95021
RC
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]);
1a85e9d2 388 (void)settys(resettty);
302c7a50 389 (void)setmodem(device, resetmodem);
e1d95021
RC
390 exit(1);
391 }
392
393 if (enable)
394 return;
395
396 /* wait till init has responded, clearing the utmp entry */
2a735ba9 397 i = 100;
e1d95021
RC
398 do {
399 sleep(1);
2a735ba9 400 if (lseek(etcutmp, utmploc, 0) < 0)
c861cac9
KB
401 fprintf(stderr, "On lseek in %s: %s",
402 _PATH_UTMP, sys_errlist[errno]);
2a735ba9 403 if (read(etcutmp, (char *)&utmp, sizeof utmp) < 0)
c861cac9
KB
404 fprintf(stderr, "On read from %s: %s",
405 _PATH_UTMP, sys_errlist[errno]);
1a85e9d2 406 } while (utmp.ut_name[0] != '\0' && --i > 0);
e1d95021
RC
407}
408
302c7a50
JB
409#ifdef BSD4_3
410/* identify terminal line in ttys */
411opnttys(device)
412char *device;
413{
302c7a50
JB
414 register int ndevice;
415 register char *p;
416 char *index();
417 char linebuf[BUFSIZ];
418
2a735ba9
JB
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);
302c7a50
JB
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);
9313cec6 440#ifndef BRL4_2
2a735ba9 441 utmploc = sizeof(utmp);
9313cec6
JB
442#else BRL4_2
443 utmploc = 0;
444#endif BRL4_2
302c7a50 445
302c7a50 446 while(fgets(linebuf, sizeof(linebuf) - 1, ttysfile) != NULL) {
2a735ba9 447 if(strncmp(device, linebuf, ndevice) == 0)
302c7a50 448 return;
2a735ba9 449 ttyslnbeg += strlen(linebuf);
9313cec6
JB
450 if (linebuf[0] != '#' && linebuf[0] != '\0')
451 utmploc += sizeof(utmp);
302c7a50
JB
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
c861cac9 463/* modify appropriate line in _PATH_TTYS to turn on/off the device */
302c7a50
JB
464settys(enable)
465int enable;
466{
467 register char *cp, *cp2;
302c7a50
JB
468 char lbuf[BUFSIZ];
469 int i;
470 char c1, c2;
471
2a735ba9
JB
472 (void) fseek(ttysfile, ttyslnbeg, 0);
473 if(fgets(lbuf, BUFSIZ, ttysfile) == NULL) {
302c7a50
JB
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 */
24663280 480 /* except, 2nd item may have embedded spaces inside quotes, Hubert */
302c7a50
JB
481 cp = lbuf;
482 for (i=0;*cp && i<3;i++) {
24663280 483 if (*cp == '"') {
302c7a50 484 cp++;
24663280
JB
485 while (*cp && *cp != '"')
486 cp++;
487 if (*cp != '\0')
488 cp++;
489 }else {
490 while (*cp && *cp != ' ' && *cp != '\t')
491 cp++;
492 }
302c7a50
JB
493 while (*cp && (*cp == ' ' || *cp == '\t'))
494 cp++;
495 }
496 if (*cp == '\0') {
c861cac9
KB
497 fprintf(stderr,"Badly formatted line in %s:\n%s",
498 _PATH_TTYS, lbuf);
302c7a50
JB
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') {
c861cac9
KB
507 fprintf(stderr,"Badly formatted line in %s:\n%s",
508 _PATH_TTYS, lbuf);
302c7a50
JB
509 exit(1);
510 }
511 c2 = *cp;
512 *cp++ = '\0';
513 while (*cp && (*cp == ' ' || *cp == '\t'))
514 cp++;
515 resettty = strcmp("on", cp2) != 0;
2a735ba9
JB
516 fprintf(nttysfile,"%s%c%s%c%s", lbuf, c1, enable ? "on" : "off", c2, cp);
517 if (ferror(nttysfile)) {
302c7a50
JB
518 fprintf(stderr, "On %s fprintf: %s\n",
519 NEtcttys, sys_errlist[errno]);
520 exit(1);
521 }
2a735ba9
JB
522 while(fgets(lbuf, sizeof(lbuf) - 1, ttysfile) != NULL) {
523 if (fputs(lbuf, nttysfile) == NULL) {
302c7a50
JB
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) {
2a735ba9
JB
535 fchmod(fileno(nttysfile) ,statb.st_mode);
536 fchown(fileno(nttysfile), statb.st_uid, statb.st_gid);
302c7a50
JB
537 }
538 (void) rename(NEtcttys, Etcttys);
539 }
2a735ba9
JB
540 (void) fclose(nttysfile);
541 (void) fclose(ttysfile);
302c7a50
JB
542 return enable^resettty;
543}
544
545#else !BSD4_3
546
e1d95021
RC
547/* identify terminal line in ttys */
548opnttys(device)
549char *device;
550{
551 register FILE *ttysfile;
552 register int ndevice, lnsiz;
553 register char *p;
554 char *index();
302c7a50 555 char linebuf[BUFSIZ];
e1d95021
RC
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) {
e1d95021 569 lnsiz = strlen(linebuf);
302c7a50 570 if ((p = index(linebuf, '\n')) != NULL)
e1d95021
RC
571 *p = '\0';
572 if(strncmp(device, &linebuf[2], ndevice) == 0) {
573 (void)fclose(ttysfile);
5ebee544
RA
574#ifdef sequent
575 /* Why is the sequent off by one? */
576 utmploc += sizeof(utmp);
577#endif sequent
e1d95021
RC
578 return;
579 }
580 ttyslnbeg += lnsiz;
2a735ba9 581 utmploc += sizeof(utmp);
e1d95021
RC
582 }
583 fprintf(stderr, "%s not found in %s\n", device, Etcttys);
584 exit(1);
585}
586
c861cac9 587/* modify appropriate line in _PATH_TTYS to turn on/off the device */
e1d95021
RC
588settys(enable)
589int enable;
590{
591 int ittysfil;
302c7a50 592 char out, in;
e1d95021
RC
593
594 ittysfil = open(Etcttys, 2);
302c7a50 595 if(ittysfil < 0) {
e1d95021
RC
596 fprintf(stderr, "Cannot open %s for output: %s\n",
597 Etcttys, sys_errlist[errno]);
598 exit(1);
599 }
302c7a50
JB
600 (void)lseek(ittysfil, ttyslnbeg, 0);
601 if(read(ittysfil, &in, 1)<0) {
602 fprintf(stderr, "On %s write: %s\n",
e1d95021
RC
603 Etcttys, sys_errlist[errno]);
604 exit(1);
605 }
606 resettty = (in == '1');
607 out = enable ? '1' : '0';
302c7a50
JB
608 (void)lseek(ittysfil, ttyslnbeg, 0);
609 if(write(ittysfil, &out, 1)<0) {
610 fprintf(stderr, "On %s write: %s\n",
e1d95021
RC
611 Etcttys, sys_errlist[errno]);
612 exit(1);
613 }
614 (void)close(ittysfil);
1a85e9d2 615 return(in==out);
e1d95021 616}
302c7a50 617#endif !BSD4_3
e1d95021 618
5ebee544
RA
619#ifdef sequent
620setmodem(ttyline, enable)
621char *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
e1d95021 630/*
302c7a50 631 * Excerpted from (June 8, 1983 W.Sebok)
e1d95021
RC
632 * > ttymodem.c - enable/disable modem control for tty lines.
633 * >
634 * > Knows about DZ11s and DH11/DM11s.
635 * > 23.3.83 - TS
302c7a50 636 * > modified to know about DMF's (hasn't been tested) Nov 8, 1984 - WLS
e1d95021
RC
637 */
638
639
302c7a50 640setmodem(ttyline, enable)
e1d95021
RC
641char *ttyline; int enable;
642{
643 dev_t dev;
644 int kmem;
302c7a50 645 int unit, line, nlines, addr, tflags;
1a85e9d2
RC
646 int devtype=0;
647 char cflags; short sflags;
648#ifdef BSD4_2
649 int flags;
650#else
651 short flags;
652#endif
e1d95021
RC
653 struct uba_device *ubinfo;
654 struct stat statb;
e1d95021
RC
655 struct cdevsw cdevsw;
656
657 if(nl[CDEVSW].n_type == 0) {
302c7a50 658 fprintf(stderr, "No namelist.\n");
e1d95021
RC
659 return(-1);
660 }
661
c861cac9
KB
662 if((kmem = open(_PATH_KMEM, 2)) < 0) {
663 fprintf(stderr, "%s open: %s\n", _PATH_KMEM,
664 sys_errlist[errno]);
e1d95021
RC
665 return(-1);
666 }
667
302c7a50
JB
668 if(stat(ttyline, &statb) < 0) {
669 fprintf(stderr, "%s stat: %s\n", ttyline, sys_errlist[errno]);
e1d95021
RC
670 return(-1);
671 }
672
1a85e9d2 673 if((statb.st_mode&S_IFMT) != S_IFCHR) {
302c7a50 674 fprintf(stderr, "%s is not a character device.\n",ttyline);
e1d95021
RC
675 return(-1);
676 }
677
678 dev = statb.st_rdev;
679 (void)lseek(kmem,
1a85e9d2 680 (off_t) &(((struct cdevsw *)NLVALUE(CDEVSW))[major(dev)]),0);
302c7a50 681 (void)read(kmem, (char *) &cdevsw, sizeof cdevsw);
e1d95021
RC
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]);
302c7a50 688 (void)lseek(kmem, (off_t) NLVALUE(NDZ11), 0);
e1d95021
RC
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]);
302c7a50 694 (void)lseek(kmem, (off_t) NLVALUE(NDH11), 0);
e1d95021
RC
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]);
302c7a50 700 (void)lseek(kmem, (off_t) NLVALUE(NDMF), 0);
e1d95021 701 } else {
302c7a50
JB
702 fprintf(stderr, "Device %s (%d/%d) unknown.\n", ttyline,
703 major(dev), minor(dev));
e1d95021
RC
704 return(-1);
705 }
706
302c7a50 707 (void)read(kmem, (char *) &nlines, sizeof nlines);
e1d95021 708 if(minor(dev) >= nlines) {
302c7a50
JB
709 fprintf(stderr, "Sub-device %d does not exist (only %d).\n",
710 minor(dev), nlines);
e1d95021
RC
711 return(-1);
712 }
713
302c7a50
JB
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);
e1d95021
RC
718
719 tflags = 1<<line;
720 resetmodem = ((flags&tflags) == 0);
721 flags = enable ? (flags & ~tflags) : (flags | tflags);
302c7a50
JB
722 (void)lseek(kmem, (off_t) &(ubinfo->ui_flags), 0);
723 (void)write(kmem, (char *) &flags, sizeof flags);
e1d95021
RC
724 switch(devtype) {
725 case DZ11:
726 if((addr = NLVALUE(DZSCAR)) == 0) {
302c7a50 727 fprintf(stderr, "No dzsoftCAR.\n");
e1d95021
RC
728 return(-1);
729 }
1a85e9d2 730 cflags = flags;
302c7a50
JB
731 (void)lseek(kmem, (off_t) &(((char *)addr)[unit]), 0);
732 (void)write(kmem, (char *) &cflags, sizeof cflags);
e1d95021
RC
733 break;
734 case DH11:
735 if((addr = NLVALUE(DHSCAR)) == 0) {
302c7a50 736 fprintf(stderr, "No dhsoftCAR.\n");
e1d95021
RC
737 return(-1);
738 }
1a85e9d2 739 sflags = flags;
302c7a50
JB
740 (void)lseek(kmem, (off_t) &(((short *)addr)[unit]), 0);
741 (void)write(kmem, (char *) &sflags, sizeof sflags);
e1d95021
RC
742 break;
743 case DMF:
744 if((addr = NLVALUE(DMFSCAR)) == 0) {
302c7a50 745 fprintf(stderr, "No dmfsoftCAR.\n");
e1d95021
RC
746 return(-1);
747 }
1a85e9d2 748 cflags = flags;
302c7a50 749 (void)lseek(kmem, (off_t) &(((char *)addr)[unit]), 0);
52dc7fd2 750 (void)write(kmem, (char *) &cflags, sizeof cflags);
e1d95021
RC
751 break;
752 default:
302c7a50 753 fprintf(stderr, "Unknown device type\n");
e1d95021
RC
754 return(-1);
755 }
756 return(0);
757}
5ebee544 758#endif /* vax */
e1d95021
RC
759
760prefix(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}
df58faa4
RA
770#else /* !DIALINOUT */
771main()
772{
773 fprintf(stderr,"acucntrl is not supported on this system\n");
774}
775#endif /* !DIALINOUT */