Commit | Line | Data |
---|---|---|
e1d95021 | 1 | #ifndef lint |
c861cac9 | 2 | static 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 | ||
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 | ||
c861cac9 | 116 | char Etcttys[] = _PATH_TTYS; |
302c7a50 | 117 | #ifdef BSD4_3 |
2a735ba9 | 118 | FILE *ttysfile, *nttysfile; |
c861cac9 | 119 | char NEtcttys[] = _PATH_NEWTTYS; |
302c7a50 JB |
120 | extern long ftell(); |
121 | #endif BSD4_3 | |
c861cac9 | 122 | char Devhome[] = _PATH_DEV; |
e1d95021 RC |
123 | |
124 | char usage[] = "Usage: acucntrl {dis|en}able ttydX\n"; | |
125 | ||
126 | struct utmp utmp; | |
127 | char resettty, resetmodem; | |
128 | int etcutmp; | |
1a85e9d2 RC |
129 | off_t utmploc; |
130 | off_t ttyslnbeg; | |
dd0ab928 RA |
131 | extern int errno; |
132 | extern char *sys_errlist[]; | |
21038734 | 133 | off_t lseek(); |
e1d95021 RC |
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; | |
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 | 349 | upcase(str, len) |
e1d95021 RC |
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 */ | |
302c7a50 | 360 | post(device, name) |
e1d95021 RC |
361 | char *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 | 375 | pokeinit(device, uname, enable) |
e1d95021 RC |
376 | char *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 */ | |
411 | opnttys(device) | |
412 | char *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 |
464 | settys(enable) |
465 | int 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 */ |
548 | opnttys(device) | |
549 | char *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 |
588 | settys(enable) |
589 | int 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 |
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 | |
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 | 640 | setmodem(ttyline, enable) |
e1d95021 RC |
641 | char *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 | |
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 | } | |
df58faa4 RA |
770 | #else /* !DIALINOUT */ |
771 | main() | |
772 | { | |
773 | fprintf(stderr,"acucntrl is not supported on this system\n"); | |
774 | } | |
775 | #endif /* !DIALINOUT */ |