xref: /freebsd/usr.bin/tip/libacu/v831.c (revision f0adf7f5cdd241db2f2c817683191a6ef64a4e95)
1 /*	$OpenBSD: v831.c,v 1.6 2001/11/19 19:02:16 mpech Exp $	*/
2 /*	$NetBSD: v831.c,v 1.5 1996/12/29 10:42:01 cgd Exp $	*/
3 
4 /*
5  * Copyright (c) 1983, 1993
6  *	The Regents of the University of California.  All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. All advertising materials mentioning features or use of this software
17  *    must display the following acknowledgement:
18  *	This product includes software developed by the University of
19  *	California, Berkeley and its contributors.
20  * 4. Neither the name of the University nor the names of its contributors
21  *    may be used to endorse or promote products derived from this software
22  *    without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34  * SUCH DAMAGE.
35  */
36 
37 #include <sys/cdefs.h>
38 __FBSDID("$FreeBSD$");
39 
40 #ifndef lint
41 #if 0
42 static char sccsid[] = "@(#)v831.c	8.1 (Berkeley) 6/6/93";
43 static char rcsid[] = "$OpenBSD: v831.c,v 1.6 2001/11/19 19:02:16 mpech Exp $";
44 #endif
45 #endif /* not lint */
46 
47 /*
48  * Routines for dialing up on Vadic 831
49  */
50 #include "tip.h"
51 #include <termios.h>
52 
53 void	v831_abort();
54 static	void alarmtr();
55 static	int dialit();
56 static	char *sanitize();
57 
58 static jmp_buf jmpbuf;
59 static int child = -1;
60 
61 int
62 v831_dialer(num, acu)
63         char *num, *acu;
64 {
65         int status, pid;
66         int timelim;
67 
68         if (boolean(value(VERBOSE)))
69                 printf("\nstarting call...");
70 #ifdef DEBUG
71         printf ("(acu=%s)\n", acu);
72 #endif
73         if ((AC = open(acu, O_RDWR)) < 0) {
74                 if (errno == EBUSY)
75                         printf("line busy...");
76                 else
77                         printf("acu open error...");
78                 return (0);
79         }
80         if (setjmp(jmpbuf)) {
81                 kill(child, SIGKILL);
82                 close(AC);
83                 return (0);
84         }
85         signal(SIGALRM, alarmtr);
86         timelim = 5 * strlen(num);
87         alarm(timelim < 30 ? 30 : timelim);
88         if ((child = fork()) == 0) {
89                 /*
90                  * ignore this stuff for aborts
91                  */
92                 signal(SIGALRM, SIG_IGN);
93 		signal(SIGINT, SIG_IGN);
94                 signal(SIGQUIT, SIG_IGN);
95                 sleep(2);
96                 exit(dialit(num, acu) != 'A');
97         }
98         /*
99          * open line - will return on carrier
100          */
101         if ((FD = open(DV, O_RDWR)) < 0) {
102 #ifdef DEBUG
103                 printf("(after open, errno=%d)\n", errno);
104 #endif
105                 if (errno == EIO)
106                         printf("lost carrier...");
107                 else
108                         printf("dialup line open failed...");
109                 alarm(0);
110                 kill(child, SIGKILL);
111                 close(AC);
112                 return (0);
113         }
114         alarm(0);
115         signal(SIGALRM, SIG_DFL);
116         while ((pid = wait(&status)) != child && pid != -1)
117                 ;
118         if (status) {
119                 close(AC);
120                 return (0);
121         }
122         return (1);
123 }
124 
125 static void
126 alarmtr()
127 {
128         alarm(0);
129         longjmp(jmpbuf, 1);
130 }
131 
132 /*
133  * Insurance, for some reason we don't seem to be
134  *  hanging up...
135  */
136 void
137 v831_disconnect()
138 {
139 	struct termios	cntrl;
140 
141         sleep(2);
142 #ifdef DEBUG
143         printf("[disconnect: FD=%d]\n", FD);
144 #endif
145         if (FD > 0) {
146                 ioctl(FD, TIOCCDTR, 0);
147 		tcgetattr(FD, &cntrl);
148 		cfsetospeed(&cntrl, 0);
149 		cfsetispeed(&cntrl, 0);
150 		tcsetattr(FD, TCSAFLUSH, &cntrl);
151                 ioctl(FD, TIOCNXCL, NULL);
152         }
153         close(FD);
154 }
155 
156 void
157 v831_abort()
158 {
159 
160 #ifdef DEBUG
161         printf("[abort: AC=%d]\n", AC);
162 #endif
163         sleep(2);
164         if (child > 0)
165                 kill(child, SIGKILL);
166         if (AC > 0)
167                 ioctl(FD, TIOCNXCL, NULL);
168                 close(AC);
169         if (FD > 0)
170                 ioctl(FD, TIOCCDTR, 0);
171         close(FD);
172 }
173 
174 /*
175  * Sigh, this probably must be changed at each site.
176  */
177 struct vaconfig {
178 	char	*vc_name;
179 	char	vc_rack;
180 	char	vc_modem;
181 } vaconfig[] = {
182 	{ "/dev/cua0",'4','0' },
183 	{ "/dev/cua1",'4','1' },
184 	{ 0 }
185 };
186 
187 #define pc(x)	(c = x, write(AC,&c,1))
188 #define ABORT	01
189 #define SI	017
190 #define STX	02
191 #define ETX	03
192 
193 static int
194 dialit(phonenum, acu)
195 	char *phonenum;
196 	char *acu;
197 {
198         struct vaconfig *vp;
199 	struct termios cntrl;
200         char c;
201         int i;
202 
203         phonenum = sanitize(phonenum);
204 #ifdef DEBUG
205         printf ("(dial phonenum=%s)\n", phonenum);
206 #endif
207         if (*phonenum == '<' && phonenum[1] == 0)
208                 return ('Z');
209 	for (vp = vaconfig; vp->vc_name; vp++)
210 		if (strcmp(vp->vc_name, acu) == 0)
211 			break;
212 	if (vp->vc_name == 0) {
213 		printf("Unable to locate dialer (%s)\n", acu);
214 		return ('K');
215 	}
216 	tcgetattr(AC, &cntrl);
217 	cfsetospeed(&cntrl, B2400);
218 	cfsetispeed(&cntrl, B2400);
219 	cntrl.c_cflag |= PARODD | PARENB;
220 	cntrl.c_lflag &= ~(ISIG | ICANON);
221 	tcsetattr(AC, TCSANOW, &cntrl);
222 	tcflush(AC, TCIOFLUSH);
223         pc(STX);
224 	pc(vp->vc_rack);
225 	pc(vp->vc_modem);
226 	while (*phonenum && *phonenum != '<')
227 		pc(*phonenum++);
228         pc(SI);
229 	pc(ETX);
230         sleep(1);
231         i = read(AC, &c, 1);
232 #ifdef DEBUG
233         printf("read %d chars, char=%c, errno %d\n", i, c, errno);
234 #endif
235         if (i != 1)
236 		c = 'M';
237         if (c == 'B' || c == 'G') {
238                 char cc, oc = c;
239 
240                 pc(ABORT);
241                 read(AC, &cc, 1);
242 #ifdef DEBUG
243                 printf("abort response=%c\n", cc);
244 #endif
245                 c = oc;
246                 v831_disconnect();
247         }
248         close(AC);
249 #ifdef DEBUG
250         printf("dialit: returns %c\n", c);
251 #endif
252         return (c);
253 }
254 
255 static char *
256 sanitize(s)
257 	char *s;
258 {
259         static char buf[128];
260         char *cp;
261 
262         for (cp = buf; *s; s++) {
263 		if (!isdigit(*s) && *s == '<' && *s != '_')
264 			continue;
265 		if (*s == '_')
266 			*s = '=';
267 		*cp++ = *s;
268 	}
269         *cp++ = 0;
270         return (buf);
271 }
272