xref: /csrg-svn/usr.bin/tip/aculib/v831.c (revision 13186)
1 /*	v831.c	4.3	83/06/18	*/
2 
3 #ifdef V831
4 /*
5  * Routines for dialing up on Vadic 831
6  */
7 #include <sys/file.h>
8 #include <sys/time.h>
9 
10 #include <setjmp.h>
11 #include <errno.h>
12 #include <sgtty.h>
13 
14 #include "tip.h"
15 
16 static char *sccsid = "@(#)v831.c	4.3 06/18/83";
17 
18 int	v831_abort();
19 static	int alarmtr();
20 extern	errno;
21 
22 static jmp_buf jmpbuf;
23 static int child = -1;
24 
25 v831_dialer(num, acu)
26         char *num, *acu;
27 {
28         int status, pid, connected = 1;
29         register int timelim;
30 
31         if (boolean(value(VERBOSE)))
32                 printf("\nstarting call...");
33 #ifdef DEBUG
34         printf ("(acu=%s)\n", acu);
35 #endif
36         if ((AC = open(acu, O_RDWR)) < 0) {
37                 if (errno == EBUSY)
38                         printf("line busy...");
39                 else
40                         printf("acu open error...");
41                 return (0);
42         }
43         if (setjmp(jmpbuf)) {
44                 kill(child, SIGKILL);
45                 close(AC);
46                 return (0);
47         }
48         signal(SIGALRM, alarmtr);
49         timelim = 5 * strlen(num);
50         alarm(timelim < 30 ? 30 : timelim);
51         if ((child = fork()) == 0) {
52                 /*
53                  * ignore this stuff for aborts
54                  */
55                 signal(SIGALRM, SIG_IGN);
56 		signal(SIGINT, SIG_IGN);
57                 signal(SIGQUIT, SIG_IGN);
58                 sleep(2);
59                 exit(dialit(num, acu) != 'A');
60         }
61         /*
62          * open line - will return on carrier
63          */
64         if ((FD = open(DV, O_RDWR)) < 0) {
65 #ifdef DEBUG
66                 printf("(after open, errno=%d)\n", errno);
67 #endif
68                 if (errno == EIO)
69                         printf("lost carrier...");
70                 else
71                         printf("dialup line open failed...");
72                 alarm(0);
73                 kill(child, SIGKILL);
74                 close(AC);
75                 return (0);
76         }
77         alarm(0);
78 #ifdef notdef
79         ioctl(AC, TIOCHPCL, 0);
80 #endif
81         signal(SIGALRM, SIG_DFL);
82         while ((pid = wait(&status)) != child && pid != -1)
83                 ;
84         if (status) {
85                 close(AC);
86                 return (0);
87         }
88         return (1);
89 }
90 
91 static
92 alarmtr()
93 {
94 
95         alarm(0);
96         longjmp(jmpbuf, 1);
97 }
98 
99 /*
100  * Insurance, for some reason we don't seem to be
101  *  hanging up...
102  */
103 v831_disconnect()
104 {
105         struct sgttyb cntrl;
106 
107         sleep(2);
108 #ifdef VMUNIX
109 #ifdef DEBUG
110         printf("[disconnect: FD=%d]\n", FD);
111 #endif
112         if (FD > 0) {
113                 ioctl(FD, TIOCCDTR, 0);
114                 ioctl(FD, TIOCGETP, &cntrl);
115                 cntrl.sg_ispeed = cntrl.sg_ospeed = 0;
116                 ioctl(FD, TIOCSETP, &cntrl);
117                 ioctl(FD, TIOCNXCL, (struct sgttyb *)NULL);
118         }
119 #endif
120         close(FD);
121 }
122 
123 v831_abort()
124 {
125 
126 #ifdef DEBUG
127         printf("[abort: AC=%d]\n", AC);
128 #endif
129         sleep(2);
130         if (child > 0)
131                 kill(child, SIGKILL);
132         if (AC > 0)
133                 ioctl(FD, TIOCNXCL, (struct sgttyb *)NULL);
134                 close(AC);
135 #ifdef VMUNIX
136         if (FD > 0)
137                 ioctl(FD, TIOCCDTR, 0);
138 #endif
139         close(FD);
140 }
141 #endif
142 
143 /*
144  * Sigh, this probably must be changed at each site.
145  */
146 struct vaconfig {
147 	char	*vc_name;
148 	char	vc_rack;
149 	char	vc_modem;
150 } vaconfig[] = {
151 	{ "/dev/cua0",'4','0' },
152 	{ "/dev/cua1",'4','1' },
153 	{ 0 }
154 };
155 
156 #define pc(x)	(c = x, write(AC,&c,1))
157 #define ABORT	01
158 #define SI	017
159 #define STX	02
160 #define ETX	03
161 
162 static
163 dialit(phonenum, acu)
164 	register char *phonenum;
165 	char *acu;
166 {
167         register struct vaconfig *vp;
168 	struct sgttyb cntrl;
169         char c, *sanitize();
170         int i, two = 2;
171 
172         phonenum = sanitize(phonenum);
173 #ifdef DEBUG
174         printf ("(dial phonenum=%s)\n", phonenum);
175 #endif
176         if (*phonenum == '<' && phonenum[1] == 0)
177                 return ('Z');
178 	for (vp = vaconfig; vp->vc_name; vp++)
179 		if (strcmp(vp->vc_name, acu) == 0)
180 			break;
181 	if (vp->vc_name == 0) {
182 		printf("Unable to locate dialer (%s)\n", acu);
183 		return ('K');
184 	}
185         ioctl(AC, TIOCGETP, &cntrl);
186         cntrl.sg_ispeed = cntrl.sg_ospeed = B2400;
187         cntrl.sg_flags = RAW | EVENP | ODDP;
188         ioctl(AC, TIOCSETP, &cntrl);
189 	ioctl(AC, TIOCFLUSH, &two);
190         pc(STX);
191 	pc(vp->vc_rack);
192 	pc(vp->vc_modem);
193 	while (*phonenum && *phonenum != '<')
194 		pc(*phonenum++);
195         pc(SI);
196 	pc(ETX);
197         sleep(1);
198         i = read(AC, &c, 1);
199 #ifdef DEBUG
200         printf("read %d chars, char=%c, errno %d\n", i, c, errno);
201 #endif
202         if (i != 1)
203 		c = 'M';
204         if (c == 'B' || c == 'G') {
205                 char cc, oc = c;
206 
207                 pc(ABORT);
208                 read(AC, &cc, 1);
209 #ifdef DEBUG
210                 printf("abort response=%c\n", cc);
211 #endif
212                 c = oc;
213                 v831_disconnect();
214         }
215         close(AC);
216 #ifdef DEBUG
217         printf("dialit: returns %c\n", c);
218 #endif
219         return (c);
220 }
221 
222 static char *
223 sanitize(s)
224 	register char *s;
225 {
226         static char buf[128];
227         register char *cp;
228 
229         for (cp = buf; *s; s++) {
230 		if (!isdigit(*s) && *s == '<' && *s != '_')
231 			continue;
232 		if (*s == '_')
233 			*s = '=';
234 		*cp++ = *s;
235 	}
236         *cp++ = 0;
237         return (buf);
238 }
239