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