|
|
1.1 root 1: #ifndef lint
2: static char sccsid[] = "@(#)condevs.c 5.6 (Berkeley) 8/12/83";
3: #endif
4:
5: /*
6: * Here are various dialers to establish the machine-machine connection.
7: * conn.c/condevs.c was glued together by Mike Mitchell.
8: * The dialers were supplied by many people, to whom we are grateful.
9: *
10: * ---------------------------------------------------------------------
11: * NOTE:
12: * There is a bug that occurs at least on PDP11s due to a limitation of
13: * setjmp/longjmp. If the routine that does a setjmp is interrupted
14: * and longjmp-ed to, it loses its register variables (on a pdp11).
15: * What works is if the routine that does the setjmp
16: * calls a routine and it is the *subroutine* that is interrupted.
17: *
18: * Anyway, in conclusion, condevs.c is plagued with register variables
19: * that are used inside
20: * if (setjmp(...)) {
21: * ....
22: * }
23: *
24: * THE FIX: In dnopn(), for example, delete the 'register' Devices *dev.
25: * (That was causing a core dump; deleting register fixed it.)
26: * Also for dnopn delete 'register' int dnf... .
27: * In pkopn, delete 'register' flds... .
28: * There may be others, especially mcm's version of hysopen.
29: * You could just delete all references to register, that is safest.
30: * This problem might not occur on 4.1bsd, I am not sure.
31: * Tom Truscott
32: */
33: #include <sys/types.h>
34: #include <errno.h>
35: #include <setjmp.h>
36: #include <signal.h>
37: #include <sgtty.h>
38: #include "uucp.h"
39:
40: extern char devSel[]; /* name to pass to delock() in close */
41: extern int errno, next_fd;
42: extern jmp_buf Sjbuf;
43: extern int alarmtr();
44: int nulldev(), nodev(), Acuopn(), diropn(), dircls();
45:
46: #ifdef DATAKIT
47: int dkopn();
48: #endif
49: #ifdef DN11
50: int dnopn(), dncls();
51: #endif
52: #ifdef HAYES
53: int hysopn(), hyscls();
54: #endif
55: #ifdef HAYESQ
56: int hysqopn(), hysqcls(); /* a version of hayes that doesn't use ret codes */
57: #endif
58: #ifdef DF02
59: int df2opn(), df2cls();
60: #endif
61: #ifdef PNET
62: int pnetopn();
63: #endif
64: #ifdef VENTEL
65: int ventopn(), ventcls();
66: #endif
67: #ifdef UNET
68: #include <UNET/unetio.h>
69: #include <UNET/tcp.h>
70: int unetopn(), unetcls();
71: #endif UNET
72: #ifdef VADIC
73: int vadopn(), vadcls();
74: #endif VADIC
75: #ifdef RVMACS
76: int rvmacsopn(), rvmacscls();
77: #endif
78: #ifdef MICOM
79: int micopn(), miccls();
80: #endif MICOM
81:
82: struct condev condevs[] = {
83: { "DIR", "direct", diropn, nulldev, dircls },
84: #ifdef DATAKIT
85: { "DK", "datakit", dkopn, nulldev, nulldev },
86: #endif
87: #ifdef PNET
88: { "PNET", "pnet", pnetopn, nulldev, nulldev },
89: #endif
90: #ifdef UNET
91: { "UNET", "UNET", unetopn, nulldev, unetcls },
92: #endif UNET
93: #ifdef MICOM
94: { "MICOM", "micom", micopn, nulldev, miccls },
95: #endif MICOM
96: #ifdef DN11
97: { "ACU", "dn11", Acuopn, dnopn, dncls },
98: #endif
99: #ifdef HAYES
100: { "ACU", "hayes", Acuopn, hysopn, hyscls },
101: #endif HAYES
102: #ifdef HAYESQ /* a version of hayes that doesn't use result codes */
103: { "ACU", "hayesq", Acuopn, hysqopn, hysqcls },
104: #endif HATESQ
105: #ifdef DF02
106: { "ACU", "DF02", Acuopn, df2opn, df2cls },
107: #endif
108: #ifdef VENTEL
109: { "ACU", "ventel", Acuopn, ventopn, ventcls },
110: #endif VENTEL
111: #ifdef VADIC
112: { "ACU", "vadic", Acuopn, vadopn, vadcls },
113: #endif VADIC
114: #ifdef RVMACS
115: { "ACU", "rvmacs", Acuopn, rvmacsopn, rvmacscls },
116: #endif RVMACS
117:
118: /* Insert new entries before this line */
119: { NULL, NULL, NULL, NULL, NULL } };
120:
121: /***
122: * nulldev a null device (returns CF_DIAL)
123: */
124: int nulldev()
125: {
126: return(CF_DIAL);
127: }
128:
129: /***
130: * nodev a null device (returns CF_NODEV)
131: */
132: int nodev()
133: {
134: return(CF_NODEV);
135: }
136:
137:
138: /*
139: * The first things in this file are the generic devices.
140: * Generic devices look through L-devices and call the CU_open routines for
141: * appropriate devices. Some things, like the Unet interface, or direct
142: * connect, do not use the CU_open entry. ACUs must search to find the'
143: * right routine to call.
144: */
145:
146: /***
147: * diropn(flds) connect to hardware line
148: * char *flds[];
149: *
150: * return codes:
151: * >0 - file number - ok
152: * FAIL - failed
153: */
154:
155: diropn(flds)
156: register char *flds[];
157: {
158: register int dcr, status;
159: struct Devices dev;
160: char dcname[20];
161: FILE *dfp;
162: dfp = fopen(DEVFILE, "r");
163: ASSERT(dfp != NULL, "CAN'T OPEN", DEVFILE, 0);
164: while ((status = rddev(dfp, &dev)) != FAIL) {
165: if (strcmp(flds[F_CLASS], dev.D_class) != SAME)
166: continue;
167: if (strcmp(flds[F_PHONE], dev.D_line) != SAME)
168: continue;
169: if (mlock(dev.D_line) != FAIL)
170: break;
171: }
172: fclose(dfp);
173: if (status == FAIL) {
174: logent("DEVICE", "NO");
175: return(CF_NODEV);
176: }
177:
178: sprintf(dcname, "/dev/%s", dev.D_line);
179: if (setjmp(Sjbuf)) {
180: delock(dev.D_line);
181: return(FAIL);
182: }
183: signal(SIGALRM, alarmtr);
184: alarm(10);
185: getnextfd();
186: errno = 0;
187: dcr = open(dcname, 2); /* read/write */
188: next_fd = -1;
189: if (dcr < 0 && errno == EACCES)
190: logent(dcname, "CAN'T OPEN");
191: alarm(0);
192: if (dcr < 0) {
193: delock(dev.D_line);
194: return(FAIL);
195: }
196: fflush(stdout);
197: fixline(dcr, dev.D_speed);
198: strcpy(devSel, dev.D_line); /* for latter unlock */
199: CU_end = dircls;
200: return(dcr);
201: }
202:
203: dircls(fd)
204: register int fd;
205: {
206: if (fd > 0) {
207: close(fd);
208: delock(devSel);
209: }
210: }
211:
212: #ifdef DATAKIT
213:
214: #include <dk.h>
215: #define DKTRIES 2
216:
217: /***
218: * dkopn(flds) make datakit connection
219: *
220: * return codes:
221: * >0 - file number - ok
222: * FAIL - failed
223: */
224:
225: dkopn(flds)
226: char *flds[];
227: {
228: int dkphone;
229: register char *cp;
230: register ret, i;
231:
232: if (setjmp(Sjbuf))
233: return(FAIL);
234:
235: signal(SIGALRM, alarmtr);
236: dkphone = 0;
237: cp = flds[F_PHONE];
238: while(*cp)
239: dkphone = 10 * dkphone + (*cp++ - '0');
240: DEBUG(4, "dkphone (%d) ", dkphone);
241: for (i = 0; i < DKTRIES; i++) {
242: getnextfd();
243: ret = dkdial(D_SH, dkphone, 0);
244: next_fd = -1;
245: DEBUG(4, "dkdial (%d)\n", ret);
246: if (ret > -1)
247: break;
248: }
249: return(ret);
250: }
251: #endif
252:
253: #ifdef PNET
254: /***
255: * pnetopn(flds)
256: *
257: * call remote machine via Purdue network
258: * use dial string as host name, speed as socket number
259: * Author: Steve Bellovin
260: */
261:
262: pnetopn(flds)
263: char *flds[];
264: {
265: int fd;
266: int socket;
267: register char *cp;
268:
269: fd = pnetfile();
270: DEBUG(4, "pnet fd - %d\n", fd);
271: if (fd < 0) {
272: logent("AVAILABLE DEVICE", "NO");
273: return(CF_NODEV);
274: }
275: socket = 0;
276: for (cp = flds[F_CLASS]; *cp; cp++)
277: socket = 10*socket + (*cp - '0');
278: DEBUG(4, "socket - %d\n", socket);
279: if (setjmp(Sjbuf)) {
280: DEBUG(4, "pnet timeout - %s\n", flds[F_PHONE]);
281: return(FAIL);
282: }
283: signal(SIGALRM, alarmtr);
284: DEBUG(4, "host - %s\n", flds[F_PHONE]);
285: alarm(15);
286: if (pnetscon(fd, flds[F_PHONE], socket) < 0) {
287: DEBUG(4, "pnet connect failed - %s\n", flds[F_PHONE]);
288: return(FAIL);
289: }
290: alarm(0);
291: return(fd);
292: }
293: #endif PNET
294:
295: #ifdef UNET
296: /***
297: * unetopn -- make UNET (tcp-ip) connection
298: *
299: * return codes:
300: * >0 - file number - ok
301: * FAIL - failed
302: */
303:
304: /* Default port of uucico server */
305: #define DFLTPORT 33
306:
307: unetopn(flds)
308: register char *flds[];
309: {
310: register int ret, port;
311: int unetcls();
312:
313: port = atoi(flds[F_PHONE]);
314: if (port <= 0 || port > 255)
315: port = DFLTPORT;
316: DEBUG(4, "unetopn host %s, ", flds[F_NAME]);
317: DEBUG(4, "port %d\n", port);
318: if (setjmp(Sjbuf)) {
319: logent("tcpopen", "TIMEOUT");
320: endhnent(); /* see below */
321: return(CF_DIAL);
322: }
323: signal(SIGALRM, alarmtr);
324: alarm(30);
325: ret = tcpopen(flds[F_NAME], port, 0, TO_ACTIVE, "rw");
326: alarm(0);
327: endhnent(); /* wave magic wand at 3com and incant "eat it, bruce" */
328: if (ret < 0) {
329: DEBUG(5, "tcpopen failed: errno %d\n", errno);
330: logent("tcpopen", "FAILED");
331: return(CF_DIAL);
332: }
333: CU_end = unetcls;
334: return(ret);
335: }
336:
337: /*
338: * unetcls -- close UNET connection.
339: */
340: unetcls(fd)
341: register int fd;
342: {
343: DEBUG(4, "UNET CLOSE called\n", 0);
344: if (fd > 0) {
345: /* disable this until a timeout is put in
346: if (ioctl(fd, UIOCCLOSE, STBNULL))
347: logent("UNET CLOSE", "FAILED");
348: */
349: close(fd);
350: DEBUG(4, "closed fd %d\n", fd);
351: }
352: }
353: #endif UNET
354:
355: #ifdef MICOM
356:
357: /*
358: * micopn: establish connection through a micom.
359: * Returns descriptor open to tty for reading and writing.
360: * Negative values (-1...-7) denote errors in connmsg.
361: * Be sure to disconnect tty when done, via HUPCL or stty 0.
362: */
363: micopn(flds)
364: register char *flds[];
365: {
366: extern errno;
367: char *rindex(), *fdig(), dcname[20];
368: int dh, ok = 0, speed;
369: register struct condev *cd;
370: register FILE *dfp;
371: struct Devices dev;
372:
373: dfp = fopen(DEVFILE, "r");
374: ASSERT(dfp != NULL, "Can't open", DEVFILE, 0);
375:
376: signal(SIGALRM, alarmtr);
377: dh = -1;
378: for(cd = condevs; ((cd->CU_meth != NULL)&&(dh < 0)); cd++) {
379: if (snccmp(flds[F_LINE], cd->CU_meth) == SAME) {
380: fseek(dfp, (off_t)0, 0);
381: while(rddev(dfp, &dev) != FAIL) {
382: if (strcmp(flds[F_CLASS], dev.D_class) != SAME)
383: continue;
384: if (snccmp(flds[F_LINE], dev.D_type) != SAME)
385: continue;
386: if (mlock(dev.D_line) == FAIL)
387: continue;
388:
389: sprintf(dcname, "/dev/%s", dev.D_line);
390: getnextfd();
391: alarm(10);
392: if (setjmp(Sjbuf)) {
393: delock(dev.D_line);
394: logent(dev.D_line,"micom open TIMEOUT");
395: dh = -1;
396: break;
397: }
398: dh = open(dcname, 2);
399: alarm(0);
400: next_fd = -1;
401: if (dh > 0) {
402: break;
403: }
404: devSel[0] = '\0';
405: delock(dev.D_line);
406: }
407: }
408: }
409: fclose(dfp);
410: if (dh < 0)
411: return(CF_NODEV);
412:
413: speed = atoi(fdig(flds[F_CLASS]));
414: fixline(dh, speed);
415: sleep(1);
416:
417: /* negotiate with micom */
418: if (speed != 4800) /* damn their eyes! */
419: write(dh, "\r", 1);
420: else
421: write(dh, " ", 1);
422:
423: DEBUG(4, "wanted %s ", "NAME");
424: ok = expect("NAME", dh);
425: DEBUG(4, "got %s\n", ok ? "?" : "that");
426: if (ok == 0) {
427: write(dh, flds[F_PHONE], strlen(flds[F_PHONE]));
428: sleep(1);
429: write(dh, "\r", 1);
430: DEBUG(4, "wanted %s ", "GO");
431: ok = expect("GO", dh);
432: DEBUG(4, "got %s\n", ok ? "?" : "that");
433: }
434:
435: if (ok != 0) {
436: if (dh > 2)
437: close(dh);
438: DEBUG(4, "micom failed\n", "");
439: delock(dev.D_line);
440: return(CF_DIAL);
441: } else
442: DEBUG(4, "micom ok\n", "");
443:
444: CU_end = cd->CU_clos;
445: strcat(devSel, dev.D_line); /* for later unlock */
446: return(dh);
447:
448: }
449:
450: miccls(fd)
451: register int fd;
452: {
453:
454: if (fd > 0) {
455: close(fd);
456: delock(devSel);
457: }
458: }
459: #endif MICOM
460:
461: /***
462: * Acuopn - open an ACU and dial the number. The condevs table
463: * will be searched until a dialing unit is found that is
464: * free.
465: *
466: * return codes: >0 - file number - o.k.
467: * FAIL - failed
468: */
469:
470: char devSel[20]; /* used for later unlock() */
471:
472: Acuopn(flds)
473: register char *flds[];
474: {
475: char phone[MAXPH+1];
476: register struct condev *cd;
477: register int fd;
478: register FILE *dfp;
479: struct Devices dev;
480:
481: exphone(flds[F_PHONE], phone);
482: devSel[0] = '\0';
483: DEBUG(4, "Dialing %s\n", phone);
484: dfp = fopen(DEVFILE, "r");
485: ASSERT(dfp != NULL, "Can't open", DEVFILE, 0);
486:
487: for(cd = condevs; cd->CU_meth != NULL; cd++) {
488: if (snccmp(flds[F_LINE], cd->CU_meth) == SAME) {
489: fseek(dfp, (off_t)0, 0);
490: while(rddev(dfp, &dev) != FAIL) {
491: if (strcmp(flds[F_CLASS], dev.D_class) != SAME)
492: continue;
493: if (snccmp(flds[F_LINE], dev.D_type) != SAME)
494: continue;
495: if (dev.D_brand[0] == '\0')
496: logent("Acuopn","No 'brand' name on ACU");
497: else if (snccmp(dev.D_brand, cd->CU_brand) != SAME)
498: continue;
499: if (mlock(dev.D_line) == FAIL)
500: continue;
501:
502: DEBUG(4, "Using %s\n", cd->CU_brand);
503: fd = (*(cd->CU_open))(phone, flds, &dev);
504: if (fd > 0) {
505: CU_end = cd->CU_clos; /* point CU_end at close func */
506: fclose(dfp);
507: strcpy(devSel, dev.D_line); /* save for later unlock() */
508: return(fd);
509: }
510: delock(dev.D_line);
511: }
512: }
513: }
514: fclose(dfp);
515: return(FAIL);
516: }
517:
518: #ifdef DN11
519:
520: /***
521: * dnopn(ph, flds, dev) dial remote machine
522: * char *ph;
523: * char *flds[];
524: * struct Devices *dev;
525: *
526: * return codes:
527: * file descriptor - succeeded
528: * FAIL - failed
529: */
530:
531: dnopn(ph, flds, dev)
532: char *ph;
533: char *flds[];
534: struct Devices *dev;
535: {
536: char dcname[20], dnname[20], phone[MAXPH+2], c = 0;
537: #ifdef SYSIII
538: struct termio ttbuf;
539: #endif
540: int dnf, dcf;
541: int nw, lt, pid, status;
542: unsigned timelim;
543:
544: sprintf(dnname, "/dev/%s", dev->D_calldev);
545: errno = 0;
546:
547: if (setjmp(Sjbuf)) {
548: logent(dnname, "CAN'T OPEN");
549: DEBUG(4, "%s Open timed out\n", dnname);
550: return(CF_NODEV);
551: }
552: signal(SIGALRM, alarmtr);
553: getnextfd();
554: alarm(10);
555: dnf = open(dnname, 1);
556: alarm(0);
557: next_fd = -1;
558: if (dnf < 0 && errno == EACCES) {
559: logent(dnname, "CAN'T OPEN");
560: logent("DEVICE", "NO");
561: return(CF_NODEV);
562: }
563: /* rti!trt: avoid passing acu file descriptor to children */
564: fioclex(dnf);
565:
566: sprintf(dcname, "/dev/%s", dev->D_line);
567: sprintf(phone, "%s%s", ph, ACULAST);
568: DEBUG(4, "dc - %s, ", dcname);
569: DEBUG(4, "acu - %s\n", dnname);
570: pid = 0;
571: if (setjmp(Sjbuf)) {
572: logent("DIALUP DN write", "TIMEOUT");
573: if (pid)
574: kill(pid, 9);
575: delock(dev->D_line);
576: if (dnf)
577: close(dnf);
578: return(FAIL);
579: }
580: signal(SIGALRM, alarmtr);
581: timelim = 5 * strlen(phone);
582: alarm(timelim < 30 ? 30 : timelim);
583: if ((pid = fork()) == 0) {
584: sleep(2);
585: fclose(stdin);
586: fclose(stdout);
587: #ifdef TIOCFLUSH
588: ioctl(dnf, TIOCFLUSH, STBNULL);
589: #endif
590: nw = write(dnf, phone, lt = strlen(phone));
591: if (nw != lt) {
592: logent("DIALUP ACU write", "FAILED");
593: exit(1);
594: }
595: DEBUG(4, "ACU write ok%s\n", "");
596: exit(0);
597: }
598: /* open line - will return on carrier */
599: /* RT needs a sleep here because it returns immediately from open */
600:
601: #if RT
602: sleep(15);
603: #endif
604:
605: getnextfd();
606: errno = 0;
607: dcf = open(dcname, 2);
608: next_fd = -1;
609: if (dcf < 0 && errno == EACCES)
610: logent(dcname, "CAN'T OPEN");
611: DEBUG(4, "dcf is %d\n", dcf);
612: if (dcf < 0) {
613: logent("DIALUP LINE open", "FAILED");
614: alarm(0);
615: kill(pid, 9);
616: close(dnf);
617: delock(dev->D_line);
618: return(FAIL);
619: }
620: /* brl-bmd.351 (Doug Kingston) says the next ioctl is unneeded . */
621: /* ioctl(dcf, TIOCHPCL, STBNULL);*/
622: while ((nw = wait(<)) != pid && nw != -1)
623: ;
624: #ifdef SYSIII
625: ioctl(dcf, TCGETA, &ttbuf);
626: if(!(ttbuf.c_cflag & HUPCL)) {
627: ttbuf.c_cflag |= HUPCL;
628: ioctl(dcf, TCSETA, &ttbuf);
629: }
630: #endif
631: alarm(0);
632: fflush(stdout);
633: fixline(dcf, dev->D_speed);
634: DEBUG(4, "Fork Stat %o\n", lt);
635: if (lt != 0) {
636: close(dcf);
637: if (dnf)
638: close(dnf);
639: delock(dev->D_line);
640: return(FAIL);
641: }
642: return(dcf);
643: }
644:
645: /***
646: * dncls() close dn type call unit
647: *
648: * return codes: None
649: */
650: dncls(fd)
651: register int fd;
652: {
653: if (fd > 0) {
654: close(fd);
655: sleep(5);
656: delock(devSel);
657: }
658: }
659: #endif DN11
660:
661: #ifdef DF02
662: /***
663: * df2opn(ph, flds, dev) dial remote machine
664: * char *ph;
665: * char *flds[];
666: * struct Devices *dev;
667: *
668: * return codes:
669: * file descriptor - succeeded
670: * FAIL - failed
671: *
672: * Modified 9/28/81 by Bill Shannon (DEC)
673: * Changed to use DEC DF02 or DF03 ACU
674: */
675:
676:
677: df2opn(ph, flds, dev)
678: char *ph;
679: char *flds[];
680: struct Devices *dev;
681: {
682: char dcname[20], dnname[20], phone[MAXPH+2], c = 0;
683: #ifdef SYSIII
684: struct termio ttbuf;
685: #endif
686: int dcf, dnf;
687: int nw, lt, pid, st, status;
688: unsigned timelim;
689:
690: sprintf(dnname, "/dev/%s", dev->D_calldev);
691: if (setjmp(Sjbuf)) {
692: logent(dnname, "CAN'T OPEN");
693: DEBUG(4, "%s Open timed out\n", dnname);
694: return(CF_NODEV);
695: }
696: signal(SIGALRM, alarmtr);
697: getnextfd();
698: errno = 0;
699: alarm(10);
700: dnf = open(dnname, 2 );
701: alarm(0);
702: next_fd = -1;
703: if (dnf < 0 && errno == EACCES) {
704: logent(dnname, "CAN'T OPEN");
705: delock(dev->D_line);
706: logent("DEVICE", "NO");
707: return(CF_NODEV);
708: }
709: /* rti!trt: avoid passing acu file descriptor to children */
710: fioclex(dnf);
711:
712: sprintf(dcname, "/dev/%s", dev->D_line);
713: fixline(dnf, dev->D_speed);
714: sprintf(phone, "\02%s", ph);
715: DEBUG(4, "dc - %s, ", dcname);
716: DEBUG(4, "acu - %s\n", dnname);
717: pid = 0;
718: if (setjmp(Sjbuf)) {
719: logent("DIALUP DN write", "TIMEOUT");
720: if (pid)
721: kill(pid, 9);
722: delock(dev->D_line);
723: if (dnf)
724: close(dnf);
725: return(FAIL);
726: }
727: signal(SIGALRM, alarmtr);
728: timelim = 5 * strlen(phone);
729: alarm(timelim < 30 ? 30 : timelim);
730: if ((pid = fork()) == 0) {
731: sleep(2);
732: fclose(stdin);
733: fclose(stdout);
734: #ifdef TIOCFLUSH
735: ioctl(dnf, TIOCFLUSH, STBNULL);
736: #endif
737: write(dnf, "\01", 1);
738: sleep(1);
739: nw = write(dnf, phone, lt = strlen(phone));
740: if (nw != lt) {
741: logent("DIALUP ACU write", "FAILED");
742: exit(1);
743: }
744: DEBUG(4, "ACU write ok%s\n", "");
745: exit(0);
746: }
747: /* open line - will return on carrier */
748: /* RT needs a sleep here because it returns immediately from open */
749:
750: #if RT
751: sleep(15);
752: #endif
753:
754: if (read(dnf, &c, 1) != 1 || c != 'A')
755: dcf = -1;
756: else
757: dcf = 0;
758: DEBUG(4, "dcf is %d\n", dcf);
759: if (dcf < 0) {
760: logent("DIALUP LINE open", "FAILED");
761: alarm(0);
762: kill(pid, 9);
763: close(dnf);
764: delock(dev->D_line);
765: return(FAIL);
766: }
767: dcf = dnf;
768: dnf = 0;
769: /* brl-bmd.351 (Doug Kingston) says the next ioctl is unneeded . */
770: /* ioctl(dcf, TIOCHPCL, STBNULL);*/
771: while ((nw = wait(<)) != pid && nw != -1)
772: ;
773: #ifdef SYSIII
774: ioctl(dcf, TCGETA, &ttbuf);
775: if(!(ttbuf.c_cflag & HUPCL)) {
776: ttbuf.c_cflag |= HUPCL;
777: ioctl(dcf, TCSETA, &ttbuf);
778: }
779: #endif
780: alarm(0);
781: fflush(stdout);
782: fixline(dcf, dev->D_speed);
783: DEBUG(4, "Fork Stat %o\n", lt);
784: if (lt != 0) {
785: close(dcf);
786: if (dnf)
787: close(dnf);
788: delock(dev->D_line);
789: return(FAIL);
790: }
791: return(dcf);
792: }
793:
794: /*
795: * df2cls() close the DF02/DF03 call unit
796: *
797: * return codes: none
798: */
799:
800: df2cls(fd)
801: register int fd;
802: {
803: if (fd > 0) {
804: close(fd);
805: sleep(5);
806: delock(devSel);
807: }
808: }
809: #endif DF02
810:
811: #ifdef HAYES
812: /***
813: * hysopn(telno, flds, dev) connect to hayes smartmodem
814: * char *flds[], *dev[];
815: *
816: * return codes:
817: * >0 - file number - ok
818: * CF_DIAL,CF_DEVICE - failed
819: */
820: /*
821: * Define HAYSTONE if you have touch tone dialing.
822: */
823: /*#define HAYSTONE */
824:
825: hysopn(telno, flds, dev)
826: char *telno;
827: char *flds[];
828: struct Devices *dev;
829: {
830: int dh = -1;
831: extern errno;
832: char dcname[20];
833:
834: sprintf(dcname, "/dev/%s", dev->D_line);
835: DEBUG(4, "dc - %s\n", dcname);
836: if (setjmp(Sjbuf)) {
837: DEBUG(1, "timeout hayes open %s\n", dcname);
838: logent("hayes open", "TIMEOUT");
839: if (dh >= 0)
840: close(dh);
841: delock(dev->D_line);
842: return(CF_DIAL);
843: }
844: signal(SIGALRM, alarmtr);
845: getnextfd();
846: alarm(10);
847: dh = open(dcname, 2); /* read/write */
848: alarm(0);
849:
850: /* modem is open */
851: next_fd = -1;
852: if (dh >= 0) {
853: fixline(dh, dev->D_speed);
854: #ifdef HAYSTONE
855: write(dh, "\rATDT", 5);
856: #else
857: write(dh, "\rATDP", 5);
858: #endif
859: write(dh, telno, strlen(telno));
860: write(dh, "\r", 1);
861:
862: if (expect("CONNECT", dh) != 0) {
863: logent("HSM no carrier", "FAILED");
864: strcpy(devSel, dev->D_line);
865: hyscls(dh);
866: return(CF_DIAL);
867: }
868:
869: }
870: if (dh < 0) {
871: DEBUG(4, "hayes failed\n", "");
872: delock(dev->D_line);
873: }
874: DEBUG(4, "hayes ok\n", "");
875: return(dh);
876: }
877:
878: hyscls(fd)
879: int fd;
880: {
881: char dcname[20];
882: struct sgttyb hup, sav;
883:
884: if (fd > 0) {
885: sprintf(dcname, "/dev/%s", devSel);
886: DEBUG(4, "Hanging up fd = %d\n", fd);
887: /*
888: * code to drop DTR -- change to 0 baud then back to default.
889: */
890: gtty(fd, &hup);
891: gtty(fd, &sav);
892: hup.sg_ispeed = B0;
893: hup.sg_ospeed = B0;
894: stty(fd, &hup);
895: sleep(2);
896: stty(fd, &sav);
897: /*
898: * now raise DTR -- close the device & open it again.
899: */
900: sleep(2);
901: close(fd);
902: sleep(2);
903: fd = open(dcname, 2);
904: /*
905: * Since we have a getty sleeping on this line, when it wakes up it sends
906: * all kinds of garbage to the modem. Unfortunatly, the modem likes to
907: * execute the previous command when it sees the garbage. The previous
908: * command was to dial the phone, so let's make the last command reset
909: * the modem.
910: */
911: sleep(2);
912: write(fd, "\rATZ\r", 5);
913: close(fd);
914: delock(devSel);
915: }
916: }
917:
918: #endif HAYES
919:
920: #ifdef HAYESQ
921: /*
922: * New dialout routine to work with Hayes' SMART MODEM
923: * 13-JUL-82, Mike Mitchell
924: * Modified 23-MAR-83 to work with Tom Truscott's (rti!trt)
925: * version of UUCP (ncsu!mcm)
926: *
927: * The modem should be set to NOT send any result codes to
928: * the system (switch 3 up, 4 down). This end will figure out
929: * what is wrong.
930: *
931: * I had lots of problems with the modem sending
932: * result codes since I am using the same modem for both incomming and
933: * outgoing calls. I'd occasionally miss the result code (getty would
934: * grab it), and the connect would fail. Worse yet, the getty would
935: * think the result code was a user name, and send garbage to it while
936: * it was in the command state. I turned off ALL result codes, and hope
937: * for the best. 99% of the time the modem is in the correct state.
938: * Occassionally it doesn't connect, or the phone was busy, etc., and
939: * uucico sits there trying to log in. It eventually times out, calling
940: * clsacu() in the process, so it resets itself for the next attempt.
941: */
942:
943: /*
944: * Define HAYSTONE if touch-tone dialing is to be used. If it is not defined,
945: * Pulse dialing is assumed.
946: */
947: /*#define HAYSTONE*/
948:
949: hysqopn(telno, flds, dev)
950: char *telno, *flds[];
951: struct Devices *dev;
952: {
953: char dcname[20], phone[MAXPH+10], c = 0;
954: #ifdef SYSIII
955: struct termio ttbuf;
956: #endif
957: int status, dnf;
958: unsigned timelim;
959:
960: signal(SIGALRM, alarmtr);
961: sprintf(dcname, "/dev/%s", dev->D_line);
962:
963: getnextfd();
964: if (setjmp(Sjbuf)) {
965: delock(dev->D_line);
966: logent("DEVICE", "NO");
967: DEBUG(4, "Open timed out %s", dcname);
968: return(CF_NODEV);
969: }
970: alarm(10);
971:
972: if ((dnf = open(dcname, 2)) <= 0) {
973: delock(dev->D_line);
974: logent("DEVICE", "NO");
975: DEBUG(4, "Can't open %s", dcname);
976: return(CF_NODEV);
977: }
978:
979: alarm(0);
980: next_fd = -1;
981: fixline(dnf, dev->D_speed);
982: DEBUG(4, "Hayes port - %s, ", dcname);
983:
984: #ifdef HAYSTONE
985: sprintf(phone, "\rATDT%s\r", telno);
986: #else
987: sprintf(phone, "\rATDP%s\r", telno);
988: #endif
989:
990: write(dnf, phone, strlen(phone));
991:
992: /* calculate delay time for the other system to answer the phone.
993: * Default is 15 seconds, add 2 seconds for each comma in the phone
994: * number.
995: */
996: timelim = 150;
997: while(*telno) {
998: c = *telno++;
999: if (c == ',')
1000: timelim += 20;
1001: else {
1002: #ifdef HAYSTONE
1003: timelim += 2; /* .2 seconds per tone */
1004: }
1005: #else
1006: if (c == '0') timelim += 10; /* .1 second per digit */
1007: else if (c > '0' && c <= '9')
1008: timelim += (c - '0');
1009: }
1010: #endif
1011: }
1012: alarm(timelim/10);
1013: if (setjmp(Sjbuf) == 0) {
1014: read(dnf, &c, 1);
1015: alarm(0);
1016: }
1017:
1018: return(dnf);
1019: }
1020:
1021: hysqcls(fd)
1022: int fd;
1023: {
1024: char dcname[20];
1025: struct sgttyb hup, sav;
1026:
1027: if (fd > 0) {
1028: sprintf(dcname, "/dev/%s", devSel);
1029: DEBUG(4, "Hanging up fd = %d\n", fd);
1030: /*
1031: * code to drop DTR -- change to 0 baud then back to default.
1032: */
1033: gtty(fd, &hup);
1034: gtty(fd, &sav);
1035: hup.sg_ispeed = B0;
1036: hup.sg_ospeed = B0;
1037: stty(fd, &hup);
1038: sleep(2);
1039: stty(fd, &sav);
1040: /*
1041: * now raise DTR -- close the device & open it again.
1042: */
1043: sleep(2);
1044: close(fd);
1045: sleep(2);
1046: fd = open(dcname, 2);
1047: /*
1048: * Since we have a getty sleeping on this line, when it wakes up it sends
1049: * all kinds of garbage to the modem. Unfortunatly, the modem likes to
1050: * execute the previous command when it sees the garbage. The previous
1051: * command was to dial the phone, so let's make the last command reset
1052: * the modem.
1053: */
1054: sleep(2);
1055: write(fd, "\rATZ\r", 5);
1056: close(fd);
1057: delock(devSel);
1058: }
1059: }
1060:
1061: #endif HAYESQ
1062:
1063: #ifdef VENTEL
1064: ventopn(telno, flds, dev)
1065: char *flds[], *telno;
1066: struct Devices *dev;
1067: {
1068: int dh;
1069: int i, ok = -1;
1070: char dcname[20];
1071:
1072: sprintf(dcname, "/dev/%s", dev->D_line);
1073: if (setjmp(Sjbuf)) {
1074: DEBUG(1, "timeout ventel open\n", "");
1075: logent("ventel open", "TIMEOUT");
1076: if (dh >= 0)
1077: close(dh);
1078: delock(dev->D_line);
1079: return(CF_NODEV);
1080: }
1081: signal(SIGALRM, alarmtr);
1082: getnextfd();
1083: alarm(10);
1084: dh = open(dcname, 2);
1085: next_fd = -1;
1086: if (dh < 0) {
1087: DEBUG(4,"%s\n", errno == 4 ? "no carrier" : "can't open modem");
1088: delock(dev->D_line);
1089: return(errno == 4 ? CF_DIAL : CF_NODEV);
1090: }
1091:
1092: /* modem is open */
1093: fixline(dh, dev->D_speed);
1094:
1095: /* translate - to % and = to & for VenTel */
1096: DEBUG(4, "calling %s -> ", telno);
1097: for (i = 0; i < strlen(telno); ++i) {
1098: switch(telno[i]) {
1099: case '-': /* delay */
1100: telno[i] = '%';
1101: break;
1102: case '=': /* await dial tone */
1103: telno[i] = '&';
1104: break;
1105: case '<':
1106: telno[i] = '%';
1107: break;
1108: }
1109: }
1110: DEBUG(4, "%s\n", telno);
1111: sleep(1);
1112: for(i = 0; i < 5; ++i) { /* make up to 5 tries */
1113: slowrite(dh, "\r\r");/* awake, thou lowly VenTel! */
1114:
1115: DEBUG(4, "wanted %s ", "$");
1116: ok = expect("$", dh);
1117: DEBUG(4, "got %s\n", ok ? "?" : "that");
1118: if (ok != 0)
1119: continue;
1120: slowrite(dh, "K"); /* "K" (enter number) command */
1121: DEBUG(4, "wanted %s ", "DIAL: ");
1122: ok = expect("DIAL: ", dh);
1123: DEBUG(4, "got %s\n", ok ? "?" : "that");
1124: if (ok == 0)
1125: break;
1126: }
1127:
1128: if (ok == 0) {
1129: slowrite(dh, telno); /* send telno, send \r */
1130: slowrite(dh, "\r");
1131: DEBUG(4, "wanted %s ", "ONLINE");
1132: ok = expect("ONLINE!", dh);
1133: DEBUG(4, "got %s\n", ok ? "?" : "that");
1134: }
1135: if (ok != 0) {
1136: if (dh > 2)
1137: close(dh);
1138: DEBUG(4, "venDial failed\n", "");
1139: return(CF_DIAL);
1140: } else
1141: DEBUG(4, "venDial ok\n", "");
1142: return(dh);
1143: }
1144:
1145:
1146: /*
1147: * uucpdelay: delay execution for numerator/denominator seconds.
1148: */
1149:
1150: #ifdef INTERVALTIMER
1151: #define uucpdelay(num,denom) intervaldelay(1000000*num/denom)
1152: #include <sys/time.h>
1153: catch alarm sig
1154: SIGALRM
1155: struct itimerval itimerval;
1156: itimerval.itimer_reload =
1157: itimerval.rtime.itimer_interval =
1158: itimerval.rtime.itimer_value =
1159: settimer(ITIMER_REAL, &itimerval);
1160: pause();
1161: alarm comes in
1162: turn off timer.
1163: #endif INTERVALTIMER
1164:
1165: #ifdef FASTTIMER
1166: #define uucpdelay(num,denom) nap(60*num/denom)
1167: /* Sleep in increments of 60ths of second. */
1168: nap (time)
1169: register int time;
1170: {
1171: static int fd;
1172:
1173: if (fd == 0)
1174: fd = open (FASTTIMER, 0);
1175:
1176: read (fd, 0, time);
1177: }
1178: #endif FASTTIMER
1179:
1180: #ifdef FTIME
1181: #define uucpdelay(num,denom) ftimedelay(1000*num/denom)
1182: #include <sys/timeb.h>
1183: ftimedelay(n)
1184: {
1185: static struct timeb loctime;
1186: ftime(&loctime);
1187: {register i = loctime.millitm;
1188: while (abs((int)(loctime.millitm - i))<n) ftime(&loctime);
1189: }
1190: }
1191: #endif FTIME
1192:
1193: #ifdef BUSYLOOP
1194: #define uucpdelay(num,denom) busyloop(CPUSPEED*num/denom)
1195: #define CPUSPEED 1000000 /* VAX 780 is 1MIPS */
1196: #define DELAY(n) { register long N = (n); while (--N > 0); }
1197: busyloop(n)
1198: {
1199: DELAY(n);
1200: }
1201: #endif BUSYLOOP
1202:
1203: slowrite(fd, str)
1204: register char *str;
1205: {
1206: DEBUG(6, "slowrite ", "");
1207: while (*str) {
1208: DEBUG(6, "%c", *str);
1209: uucpdelay(1,10); /* delay 1/10 second */
1210: write(fd, str, 1);
1211: str++;
1212: }
1213: DEBUG(6, "\n", "");
1214: }
1215:
1216:
1217: ventcls(fd)
1218: int fd;
1219: {
1220:
1221: if (fd > 0) {
1222: close(fd);
1223: sleep(5);
1224: delock(devSel);
1225: }
1226: }
1227: #endif VENTEL
1228:
1229: #ifdef VADIC
1230:
1231: /*
1232: * vadopn: establish dial-out connection through a Racal-Vadic 3450.
1233: * Returns descriptor open to tty for reading and writing.
1234: * Negative values (-1...-7) denote errors in connmsg.
1235: * Be sure to disconnect tty when done, via HUPCL or stty 0.
1236: */
1237:
1238: vadopn(telno, flds, dev)
1239: char *telno;
1240: char *flds[];
1241: struct Devices *dev;
1242: {
1243: int dh = -1;
1244: int i, ok, er = 0, delay;
1245: extern errno;
1246: char dcname[20];
1247:
1248: sprintf(dcname, "/dev/%s", dev->D_line);
1249: if (setjmp(Sjbuf)) {
1250: DEBUG(1, "timeout vadic open\n", "");
1251: logent("vadic open", "TIMEOUT");
1252: if (dh >= 0)
1253: close(dh);
1254: delock(dev->D_line);
1255: return(CF_NODEV);
1256: }
1257: signal(SIGALRM, alarmtr);
1258: getnextfd();
1259: alarm(10);
1260: dh = open(dcname, 2);
1261: alarm(0);
1262:
1263: /* modem is open */
1264: next_fd = -1;
1265: if (dh < 0) {
1266: delock(dev->D_line);
1267: return(CF_NODEV);
1268: }
1269: fixline(dh, dev->D_speed);
1270:
1271: /* translate - to K for Vadic */
1272: DEBUG(4, "calling %s -> ", telno);
1273: delay = 0;
1274: for (i = 0; i < strlen(telno); ++i) {
1275: switch(telno[i]) {
1276: case '=': /* await dial tone */
1277: case '-': /* delay */
1278: case '<':
1279: telno[i] = 'K';
1280: delay += 5;
1281: break;
1282: }
1283: }
1284: DEBUG(4, "%s\n", telno);
1285: for(i = 0; i < 5; ++i) { /* make 5 tries */
1286: /* wake up Vadic */
1287: sendthem("\005\\d", dh);
1288: DEBUG(4, "wanted %s ", "*");
1289: ok = expect("*", dh);
1290: DEBUG(4, "got %s\n", ok ? "?" : "that");
1291: if (ok != 0)
1292: continue;
1293:
1294: sendthem("D\\d", dh); /* "D" (enter number) command */
1295: DEBUG(4, "wanted %s ", "NUMBER?\\r\\n");
1296: ok = expect("NUMBER?\r\n", dh);
1297: DEBUG(4, "got %s\n", ok ? "?" : "that");
1298: if (ok != 0)
1299: continue;
1300:
1301: /* send telno, send \r */
1302: sendthem(telno, dh);
1303: ok = expect(telno, dh);
1304: if (ok == 0)
1305: ok = expect("\r\n", dh);
1306: DEBUG(4, "got %s\n", ok ? "?" : "that");
1307: if (ok != 0)
1308: continue;
1309:
1310: sendthem("", dh); /* confirm number */
1311: DEBUG(4, "wanted %s ", "DIALING: ");
1312: ok = expect("DIALING: ", dh);
1313: DEBUG(4, "got %s\n", ok ? "?" : "that");
1314: if (ok == 0)
1315: break;
1316: }
1317:
1318: if (ok == 0) {
1319: sleep(10 + delay); /* give vadic some time */
1320: DEBUG(4, "wanted ON LINE\\r\\n ", 0);
1321: ok = expect("ON LINE\r\n", dh);
1322: DEBUG(4, "got %s\n", ok ? "?" : "that");
1323: }
1324:
1325: if (ok != 0) {
1326: sendthem("I\\d", dh); /* back to idle */
1327: if (dh > 2)
1328: close(dh);
1329: DEBUG(4, "vadDial failed\n", "");
1330: delock(dev->D_line);
1331: return(CF_DIAL);
1332: }
1333: DEBUG(4, "vadic ok\n", "");
1334: return(dh);
1335: }
1336:
1337: vadcls(fd) {
1338:
1339: if (fd > 0) {
1340: close(fd);
1341: sleep(5);
1342: delock(devSel);
1343: }
1344: }
1345:
1346: #endif VADIC
1347:
1348: #ifdef RVMACS
1349: /*
1350: * Racal-Vadic 'RV820' MACS system with 831 adaptor.
1351: * A typical 300 baud L-devices entry is
1352: * ACU /dev/tty10 /dev/tty11,48 300 rvmacs
1353: * where tty10 is the communication line (D_Line),
1354: * tty11 is the dialer line (D_calldev),
1355: * the '4' is the dialer address + modem type (viz. dialer 0, Bell 103),
1356: * and the '8' is the communication port (they are 1-indexed).
1357: * BUGS:
1358: * Only tested with one dialer, one modem
1359: * uses common speed for dialer and communication line.
1360: * UNTESTED
1361: */
1362:
1363: #define STX 02 /* Access Adaptor */
1364: #define ETX 03 /* Transfer to Dialer */
1365: #define SI 017 /* Buffer Empty (end of phone number) */
1366: #define SOH 01 /* Abort */
1367:
1368: rvmacsopn(ph, flds, dev)
1369: char *ph, *flds[];
1370: struct Devices *dev;
1371: {
1372: register int va, i, child;
1373: register char *p;
1374: char c, acu[20], com[20];
1375:
1376: child = -1;
1377: if ((p = index(dev->D_calldev, ',')) == NULL) {
1378: DEBUG(2, "No dialer/modem specification\n", 0);
1379: goto failret;
1380: }
1381: *p++ = '\0';
1382: if (setjmp(Sjbuf)) {
1383: logent("rvmacsopn", "TIMEOUT");
1384: i = CF_DIAL;
1385: goto ret;
1386: }
1387: DEBUG(4, "STARTING CALL\n", 0);
1388: sprintf(acu, "/dev/%s", dev->D_calldev);
1389: getnextfd();
1390: signal(SIGALRM, alarmtr);
1391: alarm(30);
1392: if ((va = open(acu, 2)) < 0) {
1393: logent(acu, "CAN'T OPEN");
1394: i = CF_NODEV;
1395: goto ret;
1396: }
1397: fixline(va, dev->D_speed);
1398:
1399: p_chwrite(va, STX); /* access adaptor */
1400: i = *p++ - '0';
1401: if (i < 0 || i > 7) {
1402: logent(p-1, "Bad dialer address/modem type\n");
1403: goto failret;
1404: }
1405: p_chwrite(va, i); /* Send Dialer Address Digit */
1406: i = *p - '0';
1407: if (i <= 0 || i > 14) {
1408: logent(p-1, "Bad modem address\n");
1409: goto failret;
1410: }
1411: p_chwrite(va, i-1); /* Send Modem Address Digit */
1412: write(va, ph, strlen(ph)); /* Send Phone Number */
1413: p_chwrite(va, SI); /* Send Buffer Empty */
1414: p_chwrite(va, ETX); /* Initiate Call */
1415: sprintf(com, "/dev/%s", dev->D_line);
1416:
1417: /* create child to open comm line */
1418: if ((child = fork()) == 0) {
1419: signal(SIGINT, SIG_DFL);
1420: open(com, 0);
1421: sleep(5);
1422: exit(1);
1423: }
1424:
1425: if (read(va, &c, 1) != 1) {
1426: logent("ACU READ", "FAILED");
1427: goto failret;
1428: }
1429: switch(c) {
1430: case 'A':
1431: /* Fine! */
1432: break;
1433: case 'B':
1434: DEBUG(2, "CALL ABORTED\n", 0);
1435: goto failret;
1436: case 'D':
1437: DEBUG(2, "Dialer format error\n", 0);
1438: goto failret;
1439: case 'E':
1440: DEBUG(2, "Dialer parity error\n", 0);
1441: goto failret;
1442: case 'F':
1443: DEBUG(2, "Phone number too long\n", 0);
1444: goto failret;
1445: case 'G':
1446: DEBUG(2, "Busy signal\n", 0);
1447: goto failret;
1448: default:
1449: DEBUG(2, "Unknown MACS return code '%c'\n", i);
1450: goto failret;
1451: }
1452: /*
1453: * open line - will return on carrier
1454: */
1455: if ((i = open(com, 2)) < 0) {
1456: if (errno == EIO)
1457: logent("carrier", "LOST");
1458: else
1459: logent("dialup open", "FAILED");
1460: goto failret;
1461: }
1462: fixline(i, dev->D_speed);
1463: goto ret;
1464: failret:
1465: i = CF_DIAL;
1466: ret:
1467: alarm(0);
1468: if (child != -1)
1469: kill(child, SIGKILL);
1470: close(va);
1471: return(i);
1472: }
1473:
1474: rvmacscls(fd)
1475: register int fd;
1476: {
1477: DEBUG(2, "MACS close %d\n", fd);
1478: p_chwrite(fd, SOH);
1479: /* ioctl(fd, TIOCCDTR, NULL);*/
1480: close(fd);
1481: }
1482: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.