xref: /onnv-gate/usr/src/cmd/tip/aculib/v831.c (revision 549:9e644232f978)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
30Sstevel@tonic-gate  * Use is subject to license terms.
40Sstevel@tonic-gate  */
5*549Smuffin 
60Sstevel@tonic-gate /*
70Sstevel@tonic-gate  * Copyright (c) 1983 Regents of the University of California.
80Sstevel@tonic-gate  * All rights reserved. The Berkeley software License Agreement
90Sstevel@tonic-gate  * specifies the terms and conditions for redistribution.
100Sstevel@tonic-gate  */
11*549Smuffin 
12*549Smuffin #pragma ident	"%Z%%M%	%I%	%E% SMI"
130Sstevel@tonic-gate 
140Sstevel@tonic-gate /*
150Sstevel@tonic-gate  * Routines for dialing up on Vadic 831
160Sstevel@tonic-gate  */
170Sstevel@tonic-gate #include <sys/time.h>
180Sstevel@tonic-gate 
190Sstevel@tonic-gate #include "tip.h"
200Sstevel@tonic-gate 
21*549Smuffin static char	dialit(char *, char *);
22*549Smuffin static char	*sanitize(char *);
23*549Smuffin static void	alarmtr(void);
240Sstevel@tonic-gate 
25*549Smuffin static sigjmp_buf	jmpbuf;
26*549Smuffin static int	child = -1;
270Sstevel@tonic-gate 
28*549Smuffin int
v831_dialer(char * num,char * acu)29*549Smuffin v831_dialer(char *num, char *acu)
300Sstevel@tonic-gate {
31*549Smuffin 	int status, pid;
32*549Smuffin 	int timelim;
330Sstevel@tonic-gate 
340Sstevel@tonic-gate 	if (boolean(value(VERBOSE)))
35*549Smuffin 		(void) printf("\nstarting call...");
360Sstevel@tonic-gate #ifdef DEBUG
37*549Smuffin 	(void) printf("(acu=%s)\n", acu);
380Sstevel@tonic-gate #endif
390Sstevel@tonic-gate 	if ((AC = open(acu, O_RDWR)) < 0) {
400Sstevel@tonic-gate 		if (errno == EBUSY)
41*549Smuffin 			(void) printf("line busy...");
420Sstevel@tonic-gate 		else
43*549Smuffin 			(void) printf("acu open error...");
440Sstevel@tonic-gate 		return (0);
450Sstevel@tonic-gate 	}
460Sstevel@tonic-gate 	if (sigsetjmp(jmpbuf, 1)) {
47*549Smuffin 		(void) kill(child, SIGKILL);
48*549Smuffin 		(void) close(AC);
490Sstevel@tonic-gate 		return (0);
500Sstevel@tonic-gate 	}
51*549Smuffin 	(void) signal(SIGALRM, (sig_handler_t)alarmtr);
520Sstevel@tonic-gate 	timelim = 5 * strlen(num);
53*549Smuffin 	(void) alarm(timelim < 30 ? 30 : timelim);
540Sstevel@tonic-gate 	if ((child = fork()) == 0) {
550Sstevel@tonic-gate 		/*
560Sstevel@tonic-gate 		 * ignore this stuff for aborts
570Sstevel@tonic-gate 		 */
58*549Smuffin 		(void) signal(SIGALRM, SIG_IGN);
59*549Smuffin 		(void) signal(SIGINT, SIG_IGN);
60*549Smuffin 		(void) signal(SIGQUIT, SIG_IGN);
61*549Smuffin 		(void) sleep(2);
620Sstevel@tonic-gate 		exit(dialit(num, acu) != 'A');
630Sstevel@tonic-gate 	}
640Sstevel@tonic-gate 	/*
650Sstevel@tonic-gate 	 * open line - will return on carrier
660Sstevel@tonic-gate 	 */
670Sstevel@tonic-gate 	if ((FD = open(DV, O_RDWR)) < 0) {
680Sstevel@tonic-gate #ifdef DEBUG
69*549Smuffin 		(void) printf("(after open, errno=%d)\n", errno);
700Sstevel@tonic-gate #endif
710Sstevel@tonic-gate 		if (errno == EIO)
72*549Smuffin 			(void) printf("lost carrier...");
730Sstevel@tonic-gate 		else
74*549Smuffin 			(void) printf("dialup line open failed...");
75*549Smuffin 		(void) alarm(0);
76*549Smuffin 		(void) kill(child, SIGKILL);
77*549Smuffin 		(void) close(AC);
780Sstevel@tonic-gate 		return (0);
790Sstevel@tonic-gate 	}
80*549Smuffin 	(void) alarm(0);
81*549Smuffin 	(void) signal(SIGALRM, SIG_DFL);
820Sstevel@tonic-gate 	while ((pid = wait(&status)) != child && pid != -1)
830Sstevel@tonic-gate 		;
840Sstevel@tonic-gate 	if (status) {
85*549Smuffin 		(void) close(AC);
860Sstevel@tonic-gate 		return (0);
870Sstevel@tonic-gate 	}
880Sstevel@tonic-gate 	return (1);
890Sstevel@tonic-gate }
900Sstevel@tonic-gate 
910Sstevel@tonic-gate static void
alarmtr(void)92*549Smuffin alarmtr(void)
930Sstevel@tonic-gate {
940Sstevel@tonic-gate 
95*549Smuffin 	(void) alarm(0);
960Sstevel@tonic-gate 	siglongjmp(jmpbuf, 1);
970Sstevel@tonic-gate }
980Sstevel@tonic-gate 
990Sstevel@tonic-gate /*
1000Sstevel@tonic-gate  * Insurance, for some reason we don't seem to be
1010Sstevel@tonic-gate  *  hanging up...
1020Sstevel@tonic-gate  */
103*549Smuffin void
v831_disconnect(void)104*549Smuffin v831_disconnect(void)
1050Sstevel@tonic-gate {
1060Sstevel@tonic-gate 	struct termios cntrl;
1070Sstevel@tonic-gate 	int dtr = TIOCM_DTR;
1080Sstevel@tonic-gate 
109*549Smuffin 	(void) sleep(2);
1100Sstevel@tonic-gate #ifdef DEBUG
1110Sstevel@tonic-gate 	printf("[disconnect: FD=%d]\n", FD);
1120Sstevel@tonic-gate #endif
1130Sstevel@tonic-gate 	if (FD > 0) {
114*549Smuffin 		(void) ioctl(FD, TIOCMBIC, &dtr);
115*549Smuffin 		(void) ioctl(FD, TCGETS, &cntrl);
116*549Smuffin 		(void) cfsetospeed(&cntrl, B0);
1170Sstevel@tonic-gate 		cntrl.c_cflag &= ~XCLUDE;
118*549Smuffin 		(void) ioctl(FD, TCSETSF, &cntrl);
1190Sstevel@tonic-gate 	}
120*549Smuffin 	(void) close(FD);
1210Sstevel@tonic-gate }
1220Sstevel@tonic-gate 
123*549Smuffin void
v831_abort(void)124*549Smuffin v831_abort(void)
1250Sstevel@tonic-gate {
1260Sstevel@tonic-gate 	int dtr = TIOCM_DTR;
1270Sstevel@tonic-gate 	struct termios buf;
1280Sstevel@tonic-gate 
1290Sstevel@tonic-gate #ifdef DEBUG
130*549Smuffin 	(void) printf("[abort: AC=%d]\n", AC);
1310Sstevel@tonic-gate #endif
132*549Smuffin 	(void) sleep(2);
1330Sstevel@tonic-gate 	if (child > 0)
134*549Smuffin 		(void) kill(child, SIGKILL);
1350Sstevel@tonic-gate 	if (AC > 0) {
136*549Smuffin 		(void) ioctl(FD, TCGETS, &buf);
1370Sstevel@tonic-gate 		buf.c_cflag &= ~XCLUDE;
138*549Smuffin 		(void) ioctl(FD, TCSETSF, &buf);
139*549Smuffin 		(void) close(AC);
1400Sstevel@tonic-gate 	}
1410Sstevel@tonic-gate 	if (FD > 0)
142*549Smuffin 		(void) ioctl(FD, TIOCMBIC, &dtr);
143*549Smuffin 	(void) close(FD);
1440Sstevel@tonic-gate }
1450Sstevel@tonic-gate 
1460Sstevel@tonic-gate /*
1470Sstevel@tonic-gate  * Sigh, this probably must be changed at each site.
1480Sstevel@tonic-gate  */
1490Sstevel@tonic-gate struct vaconfig {
1500Sstevel@tonic-gate 	char	*vc_name;
1510Sstevel@tonic-gate 	char	vc_rack;
1520Sstevel@tonic-gate 	char	vc_modem;
1530Sstevel@tonic-gate } vaconfig[] = {
1540Sstevel@tonic-gate 	{ "/dev/cua0", '4', '0' },
1550Sstevel@tonic-gate 	{ "/dev/cua1", '4', '1' },
1560Sstevel@tonic-gate 	{ 0 }
1570Sstevel@tonic-gate };
1580Sstevel@tonic-gate 
159*549Smuffin #define	pc(x)	(c = x, (void) write(AC, &c, 1))
1600Sstevel@tonic-gate #define	ABORT	01
1610Sstevel@tonic-gate #define	SI	017
1620Sstevel@tonic-gate #define	STX	02
1630Sstevel@tonic-gate #define	ETX	03
1640Sstevel@tonic-gate 
165*549Smuffin static char
dialit(char * phonenum,char * acu)166*549Smuffin dialit(char *phonenum, char *acu)
1670Sstevel@tonic-gate {
168*549Smuffin 	struct vaconfig *vp;
1690Sstevel@tonic-gate 	struct termios cntrl;
170*549Smuffin 	char c;
1710Sstevel@tonic-gate 	int i;
1720Sstevel@tonic-gate 
1730Sstevel@tonic-gate 	phonenum = sanitize(phonenum);
1740Sstevel@tonic-gate #ifdef DEBUG
175*549Smuffin 	(void) printf("(dial phonenum=%s)\n", phonenum);
1760Sstevel@tonic-gate #endif
1770Sstevel@tonic-gate 	if (*phonenum == '<' && phonenum[1] == 0)
1780Sstevel@tonic-gate 		return ('Z');
1790Sstevel@tonic-gate 	for (vp = vaconfig; vp->vc_name; vp++)
1800Sstevel@tonic-gate 		if (strcmp(vp->vc_name, acu) == 0)
1810Sstevel@tonic-gate 			break;
1820Sstevel@tonic-gate 	if (vp->vc_name == 0) {
183*549Smuffin 		(void) printf("Unable to locate dialer (%s)\n", acu);
1840Sstevel@tonic-gate 		return ('K');
1850Sstevel@tonic-gate 	}
186*549Smuffin 	(void) ioctl(AC, TCGETS, &cntrl);
187*549Smuffin 	(void) cfsetospeed(&cntrl, B0);
188*549Smuffin 	(void) cfsetispeed(&cntrl, B0);
1890Sstevel@tonic-gate 	cntrl.c_cflag &= ~(CSIZE|PARENB|PARODD);
190*549Smuffin 	(void) cfsetospeed(&cntrl, B2400);
1910Sstevel@tonic-gate 	cntrl.c_cflag |= CS8;
1920Sstevel@tonic-gate 	cntrl.c_iflag &= IXOFF|IXANY;
1930Sstevel@tonic-gate 	cntrl.c_lflag &= ~(ICANON|ISIG);
1940Sstevel@tonic-gate 	cntrl.c_oflag = 0;
1950Sstevel@tonic-gate 	cntrl.c_cc[VMIN] = cntrl.c_cc[VTIME] = 0;
196*549Smuffin 	(void) ioctl(AC, TCSETSF, &cntrl);
197*549Smuffin 	(void) ioctl(AC, TCFLSH, TCOFLUSH);
1980Sstevel@tonic-gate 	pc(STX);
1990Sstevel@tonic-gate 	pc(vp->vc_rack);
2000Sstevel@tonic-gate 	pc(vp->vc_modem);
2010Sstevel@tonic-gate 	while (*phonenum && *phonenum != '<')
2020Sstevel@tonic-gate 		pc(*phonenum++);
2030Sstevel@tonic-gate 	pc(SI);
2040Sstevel@tonic-gate 	pc(ETX);
205*549Smuffin 	(void) sleep(1);
2060Sstevel@tonic-gate 	i = read(AC, &c, 1);
2070Sstevel@tonic-gate #ifdef DEBUG
2080Sstevel@tonic-gate 	printf("read %d chars, char=%c, errno %d\n", i, c, errno);
2090Sstevel@tonic-gate #endif
2100Sstevel@tonic-gate 	if (i != 1)
2110Sstevel@tonic-gate 		c = 'M';
2120Sstevel@tonic-gate 	if (c == 'B' || c == 'G') {
2130Sstevel@tonic-gate 		char cc, oc = c;
2140Sstevel@tonic-gate 
2150Sstevel@tonic-gate 		pc(ABORT);
216*549Smuffin 		(void) read(AC, &cc, 1);
2170Sstevel@tonic-gate #ifdef DEBUG
218*549Smuffin 		(void) printf("abort response=%c\n", cc);
2190Sstevel@tonic-gate #endif
2200Sstevel@tonic-gate 		c = oc;
2210Sstevel@tonic-gate 		v831_disconnect();
2220Sstevel@tonic-gate 	}
223*549Smuffin 	(void) close(AC);
2240Sstevel@tonic-gate #ifdef DEBUG
225*549Smuffin 	(void) printf("dialit: returns %c\n", c);
2260Sstevel@tonic-gate #endif
2270Sstevel@tonic-gate 	return (c);
2280Sstevel@tonic-gate }
2290Sstevel@tonic-gate 
2300Sstevel@tonic-gate static char *
sanitize(char * s)231*549Smuffin sanitize(char *s)
2320Sstevel@tonic-gate {
2330Sstevel@tonic-gate 	static char buf[128];
234*549Smuffin 	char *cp;
2350Sstevel@tonic-gate 
2360Sstevel@tonic-gate 	for (cp = buf; *s; s++) {
2370Sstevel@tonic-gate 		if (!isdigit(*s) && *s == '<' && *s != '_')
2380Sstevel@tonic-gate 			continue;
2390Sstevel@tonic-gate 		if (*s == '_')
2400Sstevel@tonic-gate 			*s = '=';
2410Sstevel@tonic-gate 		*cp++ = *s;
2420Sstevel@tonic-gate 	}
2430Sstevel@tonic-gate 	*cp++ = 0;
2440Sstevel@tonic-gate 	return (buf);
2450Sstevel@tonic-gate }
246