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