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