Commit | Line | Data |
---|---|---|
572555ee | 1 | #ifndef lint |
c861cac9 | 2 | static char sccsid[] = "@(#)condevs.c 5.21 (Berkeley) %G%"; |
572555ee SL |
3 | #endif |
4 | ||
2af814a5 JB |
5 | extern int errno; |
6 | extern char *sys_errlist[]; | |
7 | ||
572555ee SL |
8 | /* |
9 | * Here are various dialers to establish the machine-machine connection. | |
10 | * conn.c/condevs.c was glued together by Mike Mitchell. | |
11 | * The dialers were supplied by many people, to whom we are grateful. | |
12 | * | |
13 | * --------------------------------------------------------------------- | |
14 | * NOTE: | |
15 | * There is a bug that occurs at least on PDP11s due to a limitation of | |
16 | * setjmp/longjmp. If the routine that does a setjmp is interrupted | |
17 | * and longjmp-ed to, it loses its register variables (on a pdp11). | |
18 | * What works is if the routine that does the setjmp | |
19 | * calls a routine and it is the *subroutine* that is interrupted. | |
46b15d8a | 20 | * |
572555ee SL |
21 | * Anyway, in conclusion, condevs.c is plagued with register variables |
22 | * that are used inside | |
23 | * if (setjmp(...)) { | |
24 | * .... | |
25 | * } | |
46b15d8a RC |
26 | * |
27 | * THE FIX: Don't declare variables to be register | |
572555ee | 28 | */ |
572555ee | 29 | |
46b15d8a | 30 | #include "condevs.h" |
c861cac9 | 31 | #include "pathnames.h" |
572555ee SL |
32 | |
33 | struct condev condevs[] = { | |
46b15d8a | 34 | { "DIR", "direct", diropn, nulldev, dircls }, |
572555ee | 35 | #ifdef DATAKIT |
46b15d8a RC |
36 | { "DK", "datakit", dkopn, nulldev, nulldev }, |
37 | #endif DATAKIT | |
572555ee | 38 | #ifdef PNET |
46b15d8a RC |
39 | { "PNET", "pnet", pnetopn, nulldev, nulldev }, |
40 | #endif PNET | |
41 | #ifdef UNETTCP | |
42 | { "TCP", "TCP", unetopn, nulldev, unetcls }, | |
43 | #endif UNETTCP | |
44 | #ifdef BSDTCP | |
45 | { "TCP", "TCP", bsdtcpopn, nulldev, bsdtcpcls }, | |
46 | #endif BSDTCP | |
572555ee | 47 | #ifdef MICOM |
46b15d8a | 48 | { "MICOM", "micom", micopn, nulldev, miccls }, |
572555ee SL |
49 | #endif MICOM |
50 | #ifdef DN11 | |
46b15d8a RC |
51 | { "ACU", "dn11", Acuopn, dnopn, dncls }, |
52 | #endif DN11 | |
572555ee | 53 | #ifdef HAYES |
c8a90aca JB |
54 | { "ACU", "hayes", Acuopn, hyspopn, hyscls }, |
55 | { "ACU", "hayespulse", Acuopn, hyspopn, hyscls }, | |
56 | { "ACU", "hayestone", Acuopn, hystopn, hyscls }, | |
01af9d69 | 57 | { "WATS", "hayestone", Acuopn, hystopn, hyscls }, |
572555ee | 58 | #endif HAYES |
9313cec6 JB |
59 | #ifdef HAYES2400 |
60 | { "ACU", "hayes2400", Acuopn, hyspopn24, hyscls24 }, | |
61 | { "ACU", "hayes2400pulse", Acuopn, hyspopn24, hyscls24 }, | |
62 | { "ACU", "hayes2400tone", Acuopn, hystopn24, hyscls24 }, | |
63 | #endif HAYES2400 | |
572555ee | 64 | #ifdef HAYESQ /* a version of hayes that doesn't use result codes */ |
c8a90aca JB |
65 | { "ACU", "hayesq", Acuopn, hysqpopn, hysqcls }, |
66 | { "ACU", "hayesqpulse", Acuopn, hysqpopn, hysqcls }, | |
67 | { "ACU", "hayesqtone", Acuopn, hysqtopn, hysqcls }, | |
68 | #endif HAYESQ | |
9313cec6 JB |
69 | #ifdef CDS224 |
70 | { "ACU", "cds224", Acuopn, cdsopn224, cdscls224}, | |
71 | #endif CDS224 | |
46b15d8a RC |
72 | #ifdef NOVATION |
73 | { "ACU", "novation", Acuopn, novopn, novcls}, | |
74 | #endif NOVATION | |
572555ee | 75 | #ifdef DF02 |
46b15d8a RC |
76 | { "ACU", "DF02", Acuopn, df2opn, df2cls }, |
77 | #endif DF02 | |
1a85e9d2 RC |
78 | #ifdef DF112 |
79 | { "ACU", "DF112P", Acuopn, df12popn, df12cls }, | |
80 | { "ACU", "DF112T", Acuopn, df12topn, df12cls }, | |
81 | #endif DF112 | |
572555ee | 82 | #ifdef VENTEL |
46b15d8a | 83 | { "ACU", "ventel", Acuopn, ventopn, ventcls }, |
572555ee | 84 | #endif VENTEL |
1a85e9d2 RC |
85 | #ifdef PENRIL |
86 | { "ACU", "penril", Acuopn, penopn, pencls }, | |
87 | #endif PENRIL | |
572555ee | 88 | #ifdef VADIC |
46b15d8a | 89 | { "ACU", "vadic", Acuopn, vadopn, vadcls }, |
572555ee | 90 | #endif VADIC |
46b15d8a RC |
91 | #ifdef VA212 |
92 | { "ACU", "va212", Acuopn, va212opn, va212cls }, | |
93 | #endif VA212 | |
94 | #ifdef VA811S | |
95 | { "ACU", "va811s", Acuopn, va811opn, va811cls }, | |
96 | #endif VA811S | |
97 | #ifdef VA820 | |
98 | { "ACU", "va820", Acuopn, va820opn, va820cls }, | |
99 | { "WATS", "va820", Acuopn, va820opn, va820cls }, | |
46b15d8a | 100 | #endif VA820 |
572555ee | 101 | #ifdef RVMACS |
46b15d8a | 102 | { "ACU", "rvmacs", Acuopn, rvmacsopn, rvmacscls }, |
572555ee | 103 | #endif RVMACS |
46b15d8a RC |
104 | #ifdef VMACS |
105 | { "ACU", "vmacs", Acuopn, vmacsopn, vmacscls }, | |
106 | #endif VMACS | |
107 | #ifdef SYTEK | |
108 | { "SYTEK", "sytek", sykopn, nulldev, sykcls }, | |
109 | #endif SYTEK | |
b83f9fbc JB |
110 | #ifdef ATT2224 |
111 | { "ACU", "att", Acuopn, attopn, attcls }, | |
112 | #endif ATT2224 | |
113 | ||
572555ee | 114 | |
46b15d8a RC |
115 | /* Insert new entries before this line */ |
116 | { NULL, NULL, NULL, NULL, NULL } | |
117 | }; | |
572555ee | 118 | |
46b15d8a | 119 | /* |
572555ee SL |
120 | * nulldev a null device (returns CF_DIAL) |
121 | */ | |
46b15d8a | 122 | nulldev() |
572555ee | 123 | { |
46b15d8a | 124 | return CF_DIAL; |
572555ee SL |
125 | } |
126 | ||
46b15d8a | 127 | /* |
572555ee SL |
128 | * nodev a null device (returns CF_NODEV) |
129 | */ | |
46b15d8a | 130 | nodev() |
572555ee | 131 | { |
46b15d8a | 132 | return CF_NODEV; |
572555ee SL |
133 | } |
134 | ||
572555ee | 135 | /* |
572555ee | 136 | * Generic devices look through L-devices and call the CU_open routines for |
46b15d8a RC |
137 | * appropriate devices. Some things, like the tcp/ip interface, or direct |
138 | * connect, do not use the CU_open entry. ACUs must search to find the | |
572555ee SL |
139 | * right routine to call. |
140 | */ | |
141 | ||
46b15d8a | 142 | /* |
572555ee | 143 | * diropn(flds) connect to hardware line |
572555ee SL |
144 | * |
145 | * return codes: | |
46b15d8a | 146 | * > 0 - file number - ok |
572555ee SL |
147 | * FAIL - failed |
148 | */ | |
572555ee SL |
149 | diropn(flds) |
150 | register char *flds[]; | |
151 | { | |
152 | register int dcr, status; | |
153 | struct Devices dev; | |
154 | char dcname[20]; | |
155 | FILE *dfp; | |
46b15d8a RC |
156 | #ifdef VMSDTR /* Modem control on vms(works dtr) */ |
157 | int modem_control; | |
158 | short iosb[4]; | |
159 | int sys$qiow(); /* use this for long reads on vms */ | |
160 | int ret; | |
161 | long mode[2]; | |
162 | modem_control = 0; | |
163 | #endif | |
572555ee | 164 | dfp = fopen(DEVFILE, "r"); |
b2712edb RA |
165 | if (dfp == NULL) { |
166 | syslog(LOG_ERR, "fopen(%s) failed: %m", DEVFILE); | |
167 | cleanup(FAIL); | |
168 | } | |
572555ee | 169 | while ((status = rddev(dfp, &dev)) != FAIL) { |
46b15d8a RC |
170 | #ifdef VMSDTR /* Modem control on vms(works dtr) */ |
171 | /* If we find MOD in the device type field we go into action */ | |
172 | if (strcmp(dev.D_type, "MOD") == SAME) { | |
173 | modem_control = 1; | |
174 | DEBUG(7, "Setting Modem control to %d",modem_control); | |
175 | } | |
176 | if (strcmp(flds[F_CLASS], dev.D_class) != SAME) | |
177 | continue; | |
178 | /* | |
179 | * Modem control on vms(works dtr) Take anything in MOD class. | |
180 | * It probably should work differently anyway so we can have | |
181 | * multiple hardwired lines. | |
182 | */ | |
183 | if (!modem_control&&strcmp(flds[F_PHONE], dev.D_line) != SAME) | |
184 | #else !VMSDTR | |
572555ee SL |
185 | if (strcmp(flds[F_CLASS], dev.D_class) != SAME) |
186 | continue; | |
187 | if (strcmp(flds[F_PHONE], dev.D_line) != SAME) | |
46b15d8a | 188 | #endif !VMSDTR |
572555ee SL |
189 | continue; |
190 | if (mlock(dev.D_line) != FAIL) | |
191 | break; | |
192 | } | |
193 | fclose(dfp); | |
194 | if (status == FAIL) { | |
195 | logent("DEVICE", "NO"); | |
46b15d8a | 196 | return CF_NODEV; |
572555ee SL |
197 | } |
198 | ||
c861cac9 | 199 | sprintf(dcname, "%s/%s", _PATH_DEV, dev.D_line); |
572555ee | 200 | if (setjmp(Sjbuf)) { |
2af814a5 | 201 | DEBUG(4, "Open timed out\n", CNULL); |
572555ee | 202 | delock(dev.D_line); |
46b15d8a | 203 | return CF_DIAL; |
572555ee SL |
204 | } |
205 | signal(SIGALRM, alarmtr); | |
2af814a5 JB |
206 | /* For PC Pursuit, it could take a while to call back */ |
207 | alarm( strcmp(flds[F_LINE], "PCP") ? 10 : MAXMSGTIME*4 ); | |
572555ee SL |
208 | getnextfd(); |
209 | errno = 0; | |
2af814a5 | 210 | DEBUG(4,"Opening %s\n",dcname); |
572555ee | 211 | dcr = open(dcname, 2); /* read/write */ |
46b15d8a RC |
212 | #ifdef VMSDTR /* Modem control on vms(works dtr) */ |
213 | fflush(stdout); | |
214 | if (modem_control) { /* Did we have MOD in the device type field ? */ | |
215 | /* Sense the current terminal setup and save it */ | |
216 | if ((ret = sys$qiow(_$EFN,(fd_fab_pointer[dcr]->fab).fab$l_stv, | |
217 | IO$_SENSEMODE,iosb,0,0,mode,8,0,0,0,0)) | |
218 | != SS$_NORMAL) { | |
219 | DEBUG(7, "ret status on sense failed on Modem sense=%x<", ret); | |
220 | return CF_DIAL; | |
221 | } | |
222 | mode[1] |= TT$M_MODEM; /* Or in modem control(DTR) */ | |
223 | /* Now set the new terminal characteristics */ | |
224 | /* This is temporary and will go away when we let go of it */ | |
225 | if ((ret = sys$qiow(_$EFN,(fd_fab_pointer[dcr]->fab).fab$l_stv, | |
226 | IO$_SETMODE,iosb,0,0,mode,8,0,0,0,0)) | |
227 | != SS$_NORMAL) { | |
228 | DEBUG(7, "ret status on sense failed on Modem setup=%x<", ret); | |
229 | return CF_DIAL; | |
230 | } | |
231 | } | |
232 | #endif VMSDTR | |
572555ee | 233 | next_fd = -1; |
572555ee SL |
234 | alarm(0); |
235 | if (dcr < 0) { | |
2af814a5 JB |
236 | if (errno == EACCES) |
237 | logent(dev.D_line, "CANT OPEN"); | |
238 | DEBUG(4, "OPEN FAILED: errno %d\n", errno); | |
572555ee | 239 | delock(dev.D_line); |
46b15d8a | 240 | return CF_DIAL; |
572555ee SL |
241 | } |
242 | fflush(stdout); | |
2af814a5 JB |
243 | if (fixline(dcr, dev.D_speed) == FAIL) { |
244 | DEBUG(4, "FIXLINE FAILED\n", CNULL); | |
c8a90aca | 245 | return CF_DIAL; |
2af814a5 | 246 | } |
572555ee SL |
247 | strcpy(devSel, dev.D_line); /* for latter unlock */ |
248 | CU_end = dircls; | |
46b15d8a | 249 | return dcr; |
572555ee SL |
250 | } |
251 | ||
252 | dircls(fd) | |
253 | register int fd; | |
254 | { | |
255 | if (fd > 0) { | |
256 | close(fd); | |
257 | delock(devSel); | |
572555ee | 258 | } |
572555ee SL |
259 | } |
260 | ||
1a85e9d2 RC |
261 | /* |
262 | * open an ACU and dial the number. The condevs table | |
263 | * will be searched until a dialing unit is found that is free. | |
572555ee SL |
264 | * |
265 | * return codes: >0 - file number - o.k. | |
266 | * FAIL - failed | |
267 | */ | |
572555ee SL |
268 | char devSel[20]; /* used for later unlock() */ |
269 | ||
270 | Acuopn(flds) | |
271 | register char *flds[]; | |
272 | { | |
1a85e9d2 RC |
273 | char phone[MAXPH+1]; |
274 | register struct condev *cd; | |
275 | register int fd, acustatus; | |
276 | register FILE *dfp; | |
277 | struct Devices dev; | |
278 | int retval = CF_NODEV; | |
01af9d69 | 279 | char nobrand[MAXPH], *line; |
1a85e9d2 RC |
280 | |
281 | exphone(flds[F_PHONE], phone); | |
01af9d69 JB |
282 | if (snccmp(flds[F_LINE], "LOCAL") == SAME) |
283 | line = "ACU"; | |
284 | else | |
285 | line = flds[F_LINE]; | |
1a85e9d2 | 286 | devSel[0] = '\0'; |
04503449 | 287 | nobrand[0] = '\0'; |
1a85e9d2 RC |
288 | DEBUG(4, "Dialing %s\n", phone); |
289 | dfp = fopen(DEVFILE, "r"); | |
b2712edb RA |
290 | if (dfp == NULL) { |
291 | syslog(LOG_ERR, "fopen(%s) failed: %m", DEVFILE); | |
292 | cleanup(FAIL); | |
293 | } | |
1a85e9d2 RC |
294 | |
295 | acustatus = 0; /* none found, none locked */ | |
01af9d69 JB |
296 | while (rddev(dfp, &dev) != FAIL) { |
297 | /* | |
298 | * for each ACU L.sys line, try at most twice | |
299 | * (TRYCALLS) to establish carrier. The old way tried every | |
300 | * available dialer, which on big sites takes forever! | |
301 | * Sites with a single auto-dialer get one try. | |
302 | * Sites with multiple dialers get a try on each of two | |
303 | * different dialers. | |
304 | * To try 'harder' to connect to a remote site, | |
305 | * use multiple L.sys entries. | |
306 | */ | |
307 | if (acustatus > TRYCALLS) | |
308 | break; | |
309 | if (strcmp(flds[F_CLASS], dev.D_class) != SAME) | |
310 | continue; | |
311 | if (snccmp(line, dev.D_type) != SAME) | |
312 | continue; | |
313 | if (dev.D_brand[0] == '\0') { | |
314 | logent("Acuopn","No 'brand' name on ACU"); | |
315 | continue; | |
316 | } | |
317 | for(cd = condevs; cd->CU_meth != NULL; cd++) { | |
318 | if (snccmp(line, cd->CU_meth) == SAME) { | |
b2712edb RA |
319 | if (snccmp(dev.D_brand, cd->CU_brand) == SAME) { |
320 | nobrand[0] = '\0'; | |
01af9d69 | 321 | break; |
b2712edb | 322 | } |
04503449 | 323 | strncpy(nobrand, dev.D_brand, sizeof nobrand); |
1a85e9d2 | 324 | } |
01af9d69 | 325 | } |
1a85e9d2 | 326 | |
438731a9 RA |
327 | if (acustatus < 1) |
328 | acustatus = 1; /* has been found */ | |
329 | ||
b72750d4 | 330 | if (mlock(dev.D_line) == FAIL) |
01af9d69 | 331 | continue; |
b72750d4 | 332 | |
1a85e9d2 | 333 | #ifdef DIALINOUT |
c8a90aca | 334 | #ifdef ALLACUINOUT |
01af9d69 | 335 | if (1) { |
c8a90aca | 336 | #else !ALLACUINOUT |
01af9d69 | 337 | if (snccmp("inout", dev.D_calldev) == SAME) { |
c8a90aca | 338 | #endif !ALLACUINOUT |
01af9d69 | 339 | if (disable(dev.D_line) == FAIL) { |
1a85e9d2 | 340 | delock(dev.D_line); |
01af9d69 | 341 | continue; |
1a85e9d2 | 342 | } |
01af9d69 JB |
343 | } else |
344 | reenable(); | |
345 | #endif DIALINOUT | |
346 | ||
347 | DEBUG(4, "Using %s\n", cd->CU_brand); | |
348 | acustatus++; | |
349 | fd = (*(cd->CU_open))(phone, flds, &dev); | |
350 | if (fd > 0) { | |
351 | CU_end = cd->CU_clos; /* point CU_end at close func */ | |
352 | fclose(dfp); | |
353 | strcpy(devSel, dev.D_line); /* save for later unlock() */ | |
354 | return fd; | |
355 | } else | |
356 | delock(dev.D_line); | |
357 | retval = CF_DIAL; | |
572555ee | 358 | } |
1a85e9d2 | 359 | fclose(dfp); |
04503449 JB |
360 | if (acustatus == 0) { |
361 | if (nobrand[0]) | |
362 | logent(nobrand, "unsupported ACU type"); | |
363 | else | |
364 | logent("L-devices", "No appropriate ACU"); | |
365 | } | |
1a85e9d2 RC |
366 | if (acustatus == 1) |
367 | logent("DEVICE", "NO"); | |
368 | return retval; | |
572555ee SL |
369 | } |
370 | ||
572555ee | 371 | /* |
c8a90aca | 372 | * intervaldelay: delay execution for numerator/denominator seconds. |
572555ee SL |
373 | */ |
374 | ||
375 | #ifdef INTERVALTIMER | |
62ba4a08 | 376 | #include <sys/time.h> |
c8a90aca JB |
377 | #define uucpdelay(num,denom) intervaldelay(num,denom) |
378 | intervaldelay(num,denom) | |
379 | int num, denom; | |
380 | { | |
381 | struct timeval tv; | |
382 | tv.tv_sec = num / denom; | |
383 | tv.tv_usec = (num * 1000000L / denom ) % 1000000L; | |
384 | (void) select (0, (int *)0, (int *)0, (int *)0, &tv); | |
385 | } | |
572555ee SL |
386 | #endif INTERVALTIMER |
387 | ||
388 | #ifdef FASTTIMER | |
389 | #define uucpdelay(num,denom) nap(60*num/denom) | |
390 | /* Sleep in increments of 60ths of second. */ | |
391 | nap (time) | |
1a85e9d2 | 392 | register int time; |
572555ee SL |
393 | { |
394 | static int fd; | |
395 | ||
396 | if (fd == 0) | |
397 | fd = open (FASTTIMER, 0); | |
398 | ||
399 | read (fd, 0, time); | |
400 | } | |
401 | #endif FASTTIMER | |
402 | ||
403 | #ifdef FTIME | |
404 | #define uucpdelay(num,denom) ftimedelay(1000*num/denom) | |
572555ee SL |
405 | ftimedelay(n) |
406 | { | |
407 | static struct timeb loctime; | |
46b15d8a RC |
408 | register i = loctime.millitm; |
409 | ||
572555ee | 410 | ftime(&loctime); |
46b15d8a RC |
411 | while (abs((int)(loctime.millitm - i))<n) ftime(&loctime) |
412 | ; | |
572555ee SL |
413 | } |
414 | #endif FTIME | |
415 | ||
416 | #ifdef BUSYLOOP | |
417 | #define uucpdelay(num,denom) busyloop(CPUSPEED*num/denom) | |
418 | #define CPUSPEED 1000000 /* VAX 780 is 1MIPS */ | |
419 | #define DELAY(n) { register long N = (n); while (--N > 0); } | |
420 | busyloop(n) | |
46b15d8a | 421 | { |
572555ee | 422 | DELAY(n); |
46b15d8a | 423 | } |
572555ee SL |
424 | #endif BUSYLOOP |
425 | ||
426 | slowrite(fd, str) | |
427 | register char *str; | |
428 | { | |
46b15d8a | 429 | DEBUG(6, "slowrite ", CNULL); |
572555ee SL |
430 | while (*str) { |
431 | DEBUG(6, "%c", *str); | |
2af814a5 | 432 | uucpdelay(1, 10); /* delay 1/10 second */ |
572555ee SL |
433 | write(fd, str, 1); |
434 | str++; | |
572555ee | 435 | } |
46b15d8a | 436 | DEBUG(6, "\n", CNULL); |
572555ee | 437 | } |
2af814a5 JB |
438 | |
439 | #define BSPEED B150 | |
440 | ||
441 | /* | |
442 | * send a break | |
443 | */ | |
444 | genbrk(fn, bnulls) | |
445 | register int fn, bnulls; | |
446 | { | |
447 | #ifdef USG | |
448 | if (ioctl(fn, TCSBRK, STBNULL) < 0) | |
449 | DEBUG(5, "break TCSBRK %s\n", sys_errlist[errno]); | |
450 | #else !USG | |
451 | # ifdef TIOCSBRK | |
452 | if (ioctl(fn, TIOCSBRK, STBNULL) < 0) | |
453 | DEBUG(5, "break TIOCSBRK %s\n", sys_errlist[errno]); | |
454 | # ifdef TIOCCBRK | |
455 | uucpdelay(bnulls, 10); | |
456 | if (ioctl(fn, TIOCCBRK, STBNULL) < 0) | |
457 | DEBUG(5, "break TIOCCBRK %s\n", sys_errlist[errno]); | |
458 | # endif TIOCCBRK | |
459 | DEBUG(4, "ioctl %f second break\n", (float) bnulls/10 ); | |
460 | # else !TIOCSBRK | |
461 | struct sgttyb ttbuf; | |
462 | register int sospeed; | |
463 | ||
464 | if (ioctl(fn, TIOCGETP, &ttbuf) < 0) | |
465 | DEBUG(5, "break TIOCGETP %s\n", sys_errlist[errno]); | |
466 | sospeed = ttbuf.sg_ospeed; | |
467 | ttbuf.sg_ospeed = BSPEED; | |
468 | if (ioctl(fn, TIOCSETP, &ttbuf) < 0) | |
469 | DEBUG(5, "break TIOCSETP %s\n", sys_errlist[errno]); | |
470 | if (write(fn, "\0\0\0\0\0\0\0\0\0\0\0\0", bnulls) != bnulls) { | |
471 | badbreak: | |
472 | logent(sys_errlist[errno], "BAD WRITE genbrk"); | |
473 | alarm(0); | |
474 | longjmp(Sjbuf, 3); | |
475 | } | |
476 | ttbuf.sg_ospeed = sospeed; | |
477 | if (ioctl(fn, TIOCSETP, &ttbuf) < 0) | |
478 | DEBUG(5, "break ioctl %s\n", sys_errlist[errno]); | |
479 | if (write(fn, "@", 1) != 1) | |
480 | goto badbreak; | |
481 | DEBUG(4, "sent BREAK nulls - %d\n", bnulls); | |
482 | #endif !TIOCSBRK | |
483 | #endif !USG | |
484 | } | |
485 | ||
1a85e9d2 RC |
486 | |
487 | #ifdef DIALINOUT | |
488 | /* DIALIN/OUT CODE (WLS) */ | |
489 | /* | |
490 | * disable and reenable: allow a single line to be use for dialin/dialout | |
491 | * | |
492 | */ | |
493 | ||
494 | char enbdev[16]; | |
495 | ||
496 | disable(dev) | |
497 | register char *dev; | |
498 | { | |
499 | register char *rdev; | |
500 | ||
501 | /* strip off directory prefixes */ | |
502 | rdev = dev; | |
503 | while (*rdev) | |
504 | rdev++; | |
505 | while (--rdev >= dev && *rdev != '/') | |
506 | ; | |
507 | rdev++; | |
508 | ||
509 | if (enbdev[0]) { | |
510 | if (strcmp(enbdev, rdev) == SAME) | |
511 | return SUCCESS; /* already disabled */ | |
512 | delock(enbdev); | |
513 | reenable(); /* else, reenable the old one */ | |
514 | } | |
515 | DEBUG(4, "Disable %s\n", rdev); | |
516 | if (enbcall("disable", rdev) == FAIL) | |
517 | return FAIL; | |
1a85e9d2 RC |
518 | strcpy(enbdev, rdev); |
519 | return SUCCESS; | |
520 | } | |
521 | ||
522 | reenable() | |
523 | { | |
04503449 | 524 | if (enbdev[0] == '\0') |
1a85e9d2 RC |
525 | return; |
526 | DEBUG(4, "Reenable %s\n", enbdev); | |
527 | (void) enbcall("enable", enbdev); | |
1a85e9d2 RC |
528 | enbdev[0] = '\0'; |
529 | } | |
530 | ||
531 | enbcall(type, dev) | |
532 | char *type, *dev; | |
533 | { | |
534 | int pid; | |
535 | register char *p; | |
536 | int fildes[2]; | |
537 | int status; | |
538 | FILE *fil; | |
539 | char buf[80]; | |
540 | ||
541 | fflush(stderr); | |
542 | fflush(stdout); | |
543 | pipe(fildes); | |
544 | if ((pid = fork()) == 0) { | |
545 | DEBUG(4, DIALINOUT, CNULL); | |
546 | DEBUG(4, " %s", type); | |
547 | DEBUG(4, " %s\n", dev); | |
548 | close(fildes[0]); | |
549 | close(0); close(1); close(2); | |
c861cac9 | 550 | open(_PATH_DEVNULL,0); |
1a85e9d2 RC |
551 | dup(fildes[1]); dup(fildes[1]); |
552 | setuid(geteuid()); /* for chown(uid()) in acu program */ | |
e3ef9ac3 | 553 | execl(DIALINOUT, "acu", type, dev, Rmtname, (char *)0); |
1a85e9d2 RC |
554 | exit(-1); |
555 | } | |
556 | if (pid<0) | |
557 | return FAIL; | |
558 | ||
559 | close(fildes[1]); | |
560 | fil = fdopen(fildes[0],"r"); | |
561 | if (fil!=NULL) { | |
c8a90aca | 562 | #ifdef BSD4_2 |
1a85e9d2 | 563 | setlinebuf(fil); |
c8a90aca | 564 | #endif BSD4_2 |
1a85e9d2 RC |
565 | while (fgets(buf, sizeof buf, fil) != NULL) { |
566 | p = buf + strlen(buf) - 1; | |
567 | if (*p == '\n') | |
568 | *p = '\0'; | |
b72750d4 | 569 | DEBUG(4, "ACUCNTRL: %s\n", buf); |
1a85e9d2 RC |
570 | } |
571 | } | |
572 | while(wait(&status) != pid) | |
573 | ; | |
574 | fclose(fil); | |
575 | return status ? FAIL : SUCCESS; | |
576 | } | |
577 | #endif DIALINOUT |