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