xref: /illumos-gate/usr/src/cmd/tip/aculib/v831.c (revision bc1f688b4872ace323eaddbb1a6365d054e7bf56)
1 /*
2  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
3  * Use is subject to license terms.
4  */
5 
6 /*
7  * Copyright (c) 1983 Regents of the University of California.
8  * All rights reserved. The Berkeley software License Agreement
9  * specifies the terms and conditions for redistribution.
10  */
11 
12 #pragma ident	"%Z%%M%	%I%	%E% SMI"
13 
14 /*
15  * Routines for dialing up on Vadic 831
16  */
17 #include <sys/time.h>
18 
19 #include "tip.h"
20 
21 static char	dialit(char *, char *);
22 static char	*sanitize(char *);
23 static void	alarmtr(void);
24 
25 static sigjmp_buf	jmpbuf;
26 static int	child = -1;
27 
28 int
29 v831_dialer(char *num, char *acu)
30 {
31 	int status, pid;
32 	int timelim;
33 
34 	if (boolean(value(VERBOSE)))
35 		(void) printf("\nstarting call...");
36 #ifdef DEBUG
37 	(void) printf("(acu=%s)\n", acu);
38 #endif
39 	if ((AC = open(acu, O_RDWR)) < 0) {
40 		if (errno == EBUSY)
41 			(void) printf("line busy...");
42 		else
43 			(void) printf("acu open error...");
44 		return (0);
45 	}
46 	if (sigsetjmp(jmpbuf, 1)) {
47 		(void) kill(child, SIGKILL);
48 		(void) close(AC);
49 		return (0);
50 	}
51 	(void) signal(SIGALRM, (sig_handler_t)alarmtr);
52 	timelim = 5 * strlen(num);
53 	(void) alarm(timelim < 30 ? 30 : timelim);
54 	if ((child = fork()) == 0) {
55 		/*
56 		 * ignore this stuff for aborts
57 		 */
58 		(void) signal(SIGALRM, SIG_IGN);
59 		(void) signal(SIGINT, SIG_IGN);
60 		(void) signal(SIGQUIT, SIG_IGN);
61 		(void) sleep(2);
62 		exit(dialit(num, acu) != 'A');
63 	}
64 	/*
65 	 * open line - will return on carrier
66 	 */
67 	if ((FD = open(DV, O_RDWR)) < 0) {
68 #ifdef DEBUG
69 		(void) printf("(after open, errno=%d)\n", errno);
70 #endif
71 		if (errno == EIO)
72 			(void) printf("lost carrier...");
73 		else
74 			(void) printf("dialup line open failed...");
75 		(void) alarm(0);
76 		(void) kill(child, SIGKILL);
77 		(void) close(AC);
78 		return (0);
79 	}
80 	(void) alarm(0);
81 	(void) signal(SIGALRM, SIG_DFL);
82 	while ((pid = wait(&status)) != child && pid != -1)
83 		;
84 	if (status) {
85 		(void) close(AC);
86 		return (0);
87 	}
88 	return (1);
89 }
90 
91 static void
92 alarmtr(void)
93 {
94 
95 	(void) alarm(0);
96 	siglongjmp(jmpbuf, 1);
97 }
98 
99 /*
100  * Insurance, for some reason we don't seem to be
101  *  hanging up...
102  */
103 void
104 v831_disconnect(void)
105 {
106 	struct termios cntrl;
107 	int dtr = TIOCM_DTR;
108 
109 	(void) sleep(2);
110 #ifdef DEBUG
111 	printf("[disconnect: FD=%d]\n", FD);
112 #endif
113 	if (FD > 0) {
114 		(void) ioctl(FD, TIOCMBIC, &dtr);
115 		(void) ioctl(FD, TCGETS, &cntrl);
116 		(void) cfsetospeed(&cntrl, B0);
117 		cntrl.c_cflag &= ~XCLUDE;
118 		(void) ioctl(FD, TCSETSF, &cntrl);
119 	}
120 	(void) close(FD);
121 }
122 
123 void
124 v831_abort(void)
125 {
126 	int dtr = TIOCM_DTR;
127 	struct termios buf;
128 
129 #ifdef DEBUG
130 	(void) printf("[abort: AC=%d]\n", AC);
131 #endif
132 	(void) sleep(2);
133 	if (child > 0)
134 		(void) kill(child, SIGKILL);
135 	if (AC > 0) {
136 		(void) ioctl(FD, TCGETS, &buf);
137 		buf.c_cflag &= ~XCLUDE;
138 		(void) ioctl(FD, TCSETSF, &buf);
139 		(void) close(AC);
140 	}
141 	if (FD > 0)
142 		(void) ioctl(FD, TIOCMBIC, &dtr);
143 	(void) close(FD);
144 }
145 
146 /*
147  * Sigh, this probably must be changed at each site.
148  */
149 struct vaconfig {
150 	char	*vc_name;
151 	char	vc_rack;
152 	char	vc_modem;
153 } vaconfig[] = {
154 	{ "/dev/cua0", '4', '0' },
155 	{ "/dev/cua1", '4', '1' },
156 	{ 0 }
157 };
158 
159 #define	pc(x)	(c = x, (void) write(AC, &c, 1))
160 #define	ABORT	01
161 #define	SI	017
162 #define	STX	02
163 #define	ETX	03
164 
165 static char
166 dialit(char *phonenum, char *acu)
167 {
168 	struct vaconfig *vp;
169 	struct termios cntrl;
170 	char c;
171 	int i;
172 
173 	phonenum = sanitize(phonenum);
174 #ifdef DEBUG
175 	(void) printf("(dial phonenum=%s)\n", phonenum);
176 #endif
177 	if (*phonenum == '<' && phonenum[1] == 0)
178 		return ('Z');
179 	for (vp = vaconfig; vp->vc_name; vp++)
180 		if (strcmp(vp->vc_name, acu) == 0)
181 			break;
182 	if (vp->vc_name == 0) {
183 		(void) printf("Unable to locate dialer (%s)\n", acu);
184 		return ('K');
185 	}
186 	(void) ioctl(AC, TCGETS, &cntrl);
187 	(void) cfsetospeed(&cntrl, B0);
188 	(void) cfsetispeed(&cntrl, B0);
189 	cntrl.c_cflag &= ~(CSIZE|PARENB|PARODD);
190 	(void) cfsetospeed(&cntrl, B2400);
191 	cntrl.c_cflag |= CS8;
192 	cntrl.c_iflag &= IXOFF|IXANY;
193 	cntrl.c_lflag &= ~(ICANON|ISIG);
194 	cntrl.c_oflag = 0;
195 	cntrl.c_cc[VMIN] = cntrl.c_cc[VTIME] = 0;
196 	(void) ioctl(AC, TCSETSF, &cntrl);
197 	(void) ioctl(AC, TCFLSH, TCOFLUSH);
198 	pc(STX);
199 	pc(vp->vc_rack);
200 	pc(vp->vc_modem);
201 	while (*phonenum && *phonenum != '<')
202 		pc(*phonenum++);
203 	pc(SI);
204 	pc(ETX);
205 	(void) sleep(1);
206 	i = read(AC, &c, 1);
207 #ifdef DEBUG
208 	printf("read %d chars, char=%c, errno %d\n", i, c, errno);
209 #endif
210 	if (i != 1)
211 		c = 'M';
212 	if (c == 'B' || c == 'G') {
213 		char cc, oc = c;
214 
215 		pc(ABORT);
216 		(void) read(AC, &cc, 1);
217 #ifdef DEBUG
218 		(void) printf("abort response=%c\n", cc);
219 #endif
220 		c = oc;
221 		v831_disconnect();
222 	}
223 	(void) close(AC);
224 #ifdef DEBUG
225 	(void) printf("dialit: returns %c\n", c);
226 #endif
227 	return (c);
228 }
229 
230 static char *
231 sanitize(char *s)
232 {
233 	static char buf[128];
234 	char *cp;
235 
236 	for (cp = buf; *s; s++) {
237 		if (!isdigit(*s) && *s == '<' && *s != '_')
238 			continue;
239 		if (*s == '_')
240 			*s = '=';
241 		*cp++ = *s;
242 	}
243 	*cp++ = 0;
244 	return (buf);
245 }
246