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