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