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