xref: /titanic_51/usr/src/cmd/tip/aculib/v831.c (revision 8d489c7a815fcac696803219572e95aa01532b0f)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
37c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
47c478bd9Sstevel@tonic-gate  */
5*8d489c7aSmuffin 
67c478bd9Sstevel@tonic-gate /*
77c478bd9Sstevel@tonic-gate  * Copyright (c) 1983 Regents of the University of California.
87c478bd9Sstevel@tonic-gate  * All rights reserved. The Berkeley software License Agreement
97c478bd9Sstevel@tonic-gate  * specifies the terms and conditions for redistribution.
107c478bd9Sstevel@tonic-gate  */
11*8d489c7aSmuffin 
12*8d489c7aSmuffin #pragma ident	"%Z%%M%	%I%	%E% SMI"
137c478bd9Sstevel@tonic-gate 
147c478bd9Sstevel@tonic-gate /*
157c478bd9Sstevel@tonic-gate  * Routines for dialing up on Vadic 831
167c478bd9Sstevel@tonic-gate  */
177c478bd9Sstevel@tonic-gate #include <sys/time.h>
187c478bd9Sstevel@tonic-gate 
197c478bd9Sstevel@tonic-gate #include "tip.h"
207c478bd9Sstevel@tonic-gate 
21*8d489c7aSmuffin static char	dialit(char *, char *);
22*8d489c7aSmuffin static char	*sanitize(char *);
23*8d489c7aSmuffin static void	alarmtr(void);
247c478bd9Sstevel@tonic-gate 
257c478bd9Sstevel@tonic-gate static sigjmp_buf	jmpbuf;
267c478bd9Sstevel@tonic-gate static int	child = -1;
277c478bd9Sstevel@tonic-gate 
28*8d489c7aSmuffin int
29*8d489c7aSmuffin v831_dialer(char *num, char *acu)
307c478bd9Sstevel@tonic-gate {
31*8d489c7aSmuffin 	int status, pid;
32*8d489c7aSmuffin 	int timelim;
337c478bd9Sstevel@tonic-gate 
347c478bd9Sstevel@tonic-gate 	if (boolean(value(VERBOSE)))
35*8d489c7aSmuffin 		(void) printf("\nstarting call...");
367c478bd9Sstevel@tonic-gate #ifdef DEBUG
37*8d489c7aSmuffin 	(void) printf("(acu=%s)\n", acu);
387c478bd9Sstevel@tonic-gate #endif
397c478bd9Sstevel@tonic-gate 	if ((AC = open(acu, O_RDWR)) < 0) {
407c478bd9Sstevel@tonic-gate 		if (errno == EBUSY)
41*8d489c7aSmuffin 			(void) printf("line busy...");
427c478bd9Sstevel@tonic-gate 		else
43*8d489c7aSmuffin 			(void) printf("acu open error...");
447c478bd9Sstevel@tonic-gate 		return (0);
457c478bd9Sstevel@tonic-gate 	}
467c478bd9Sstevel@tonic-gate 	if (sigsetjmp(jmpbuf, 1)) {
47*8d489c7aSmuffin 		(void) kill(child, SIGKILL);
48*8d489c7aSmuffin 		(void) close(AC);
497c478bd9Sstevel@tonic-gate 		return (0);
507c478bd9Sstevel@tonic-gate 	}
51*8d489c7aSmuffin 	(void) signal(SIGALRM, (sig_handler_t)alarmtr);
527c478bd9Sstevel@tonic-gate 	timelim = 5 * strlen(num);
53*8d489c7aSmuffin 	(void) alarm(timelim < 30 ? 30 : timelim);
547c478bd9Sstevel@tonic-gate 	if ((child = fork()) == 0) {
557c478bd9Sstevel@tonic-gate 		/*
567c478bd9Sstevel@tonic-gate 		 * ignore this stuff for aborts
577c478bd9Sstevel@tonic-gate 		 */
58*8d489c7aSmuffin 		(void) signal(SIGALRM, SIG_IGN);
59*8d489c7aSmuffin 		(void) signal(SIGINT, SIG_IGN);
60*8d489c7aSmuffin 		(void) signal(SIGQUIT, SIG_IGN);
61*8d489c7aSmuffin 		(void) sleep(2);
627c478bd9Sstevel@tonic-gate 		exit(dialit(num, acu) != 'A');
637c478bd9Sstevel@tonic-gate 	}
647c478bd9Sstevel@tonic-gate 	/*
657c478bd9Sstevel@tonic-gate 	 * open line - will return on carrier
667c478bd9Sstevel@tonic-gate 	 */
677c478bd9Sstevel@tonic-gate 	if ((FD = open(DV, O_RDWR)) < 0) {
687c478bd9Sstevel@tonic-gate #ifdef DEBUG
69*8d489c7aSmuffin 		(void) printf("(after open, errno=%d)\n", errno);
707c478bd9Sstevel@tonic-gate #endif
717c478bd9Sstevel@tonic-gate 		if (errno == EIO)
72*8d489c7aSmuffin 			(void) printf("lost carrier...");
737c478bd9Sstevel@tonic-gate 		else
74*8d489c7aSmuffin 			(void) printf("dialup line open failed...");
75*8d489c7aSmuffin 		(void) alarm(0);
76*8d489c7aSmuffin 		(void) kill(child, SIGKILL);
77*8d489c7aSmuffin 		(void) close(AC);
787c478bd9Sstevel@tonic-gate 		return (0);
797c478bd9Sstevel@tonic-gate 	}
80*8d489c7aSmuffin 	(void) alarm(0);
81*8d489c7aSmuffin 	(void) signal(SIGALRM, SIG_DFL);
827c478bd9Sstevel@tonic-gate 	while ((pid = wait(&status)) != child && pid != -1)
837c478bd9Sstevel@tonic-gate 		;
847c478bd9Sstevel@tonic-gate 	if (status) {
85*8d489c7aSmuffin 		(void) close(AC);
867c478bd9Sstevel@tonic-gate 		return (0);
877c478bd9Sstevel@tonic-gate 	}
887c478bd9Sstevel@tonic-gate 	return (1);
897c478bd9Sstevel@tonic-gate }
907c478bd9Sstevel@tonic-gate 
917c478bd9Sstevel@tonic-gate static void
92*8d489c7aSmuffin alarmtr(void)
937c478bd9Sstevel@tonic-gate {
947c478bd9Sstevel@tonic-gate 
95*8d489c7aSmuffin 	(void) alarm(0);
967c478bd9Sstevel@tonic-gate 	siglongjmp(jmpbuf, 1);
977c478bd9Sstevel@tonic-gate }
987c478bd9Sstevel@tonic-gate 
997c478bd9Sstevel@tonic-gate /*
1007c478bd9Sstevel@tonic-gate  * Insurance, for some reason we don't seem to be
1017c478bd9Sstevel@tonic-gate  *  hanging up...
1027c478bd9Sstevel@tonic-gate  */
103*8d489c7aSmuffin void
104*8d489c7aSmuffin v831_disconnect(void)
1057c478bd9Sstevel@tonic-gate {
1067c478bd9Sstevel@tonic-gate 	struct termios cntrl;
1077c478bd9Sstevel@tonic-gate 	int dtr = TIOCM_DTR;
1087c478bd9Sstevel@tonic-gate 
109*8d489c7aSmuffin 	(void) sleep(2);
1107c478bd9Sstevel@tonic-gate #ifdef DEBUG
1117c478bd9Sstevel@tonic-gate 	printf("[disconnect: FD=%d]\n", FD);
1127c478bd9Sstevel@tonic-gate #endif
1137c478bd9Sstevel@tonic-gate 	if (FD > 0) {
114*8d489c7aSmuffin 		(void) ioctl(FD, TIOCMBIC, &dtr);
115*8d489c7aSmuffin 		(void) ioctl(FD, TCGETS, &cntrl);
116*8d489c7aSmuffin 		(void) cfsetospeed(&cntrl, B0);
1177c478bd9Sstevel@tonic-gate 		cntrl.c_cflag &= ~XCLUDE;
118*8d489c7aSmuffin 		(void) ioctl(FD, TCSETSF, &cntrl);
1197c478bd9Sstevel@tonic-gate 	}
120*8d489c7aSmuffin 	(void) close(FD);
1217c478bd9Sstevel@tonic-gate }
1227c478bd9Sstevel@tonic-gate 
123*8d489c7aSmuffin void
124*8d489c7aSmuffin v831_abort(void)
1257c478bd9Sstevel@tonic-gate {
1267c478bd9Sstevel@tonic-gate 	int dtr = TIOCM_DTR;
1277c478bd9Sstevel@tonic-gate 	struct termios buf;
1287c478bd9Sstevel@tonic-gate 
1297c478bd9Sstevel@tonic-gate #ifdef DEBUG
130*8d489c7aSmuffin 	(void) printf("[abort: AC=%d]\n", AC);
1317c478bd9Sstevel@tonic-gate #endif
132*8d489c7aSmuffin 	(void) sleep(2);
1337c478bd9Sstevel@tonic-gate 	if (child > 0)
134*8d489c7aSmuffin 		(void) kill(child, SIGKILL);
1357c478bd9Sstevel@tonic-gate 	if (AC > 0) {
136*8d489c7aSmuffin 		(void) ioctl(FD, TCGETS, &buf);
1377c478bd9Sstevel@tonic-gate 		buf.c_cflag &= ~XCLUDE;
138*8d489c7aSmuffin 		(void) ioctl(FD, TCSETSF, &buf);
139*8d489c7aSmuffin 		(void) close(AC);
1407c478bd9Sstevel@tonic-gate 	}
1417c478bd9Sstevel@tonic-gate 	if (FD > 0)
142*8d489c7aSmuffin 		(void) ioctl(FD, TIOCMBIC, &dtr);
143*8d489c7aSmuffin 	(void) close(FD);
1447c478bd9Sstevel@tonic-gate }
1457c478bd9Sstevel@tonic-gate 
1467c478bd9Sstevel@tonic-gate /*
1477c478bd9Sstevel@tonic-gate  * Sigh, this probably must be changed at each site.
1487c478bd9Sstevel@tonic-gate  */
1497c478bd9Sstevel@tonic-gate struct vaconfig {
1507c478bd9Sstevel@tonic-gate 	char	*vc_name;
1517c478bd9Sstevel@tonic-gate 	char	vc_rack;
1527c478bd9Sstevel@tonic-gate 	char	vc_modem;
1537c478bd9Sstevel@tonic-gate } vaconfig[] = {
1547c478bd9Sstevel@tonic-gate 	{ "/dev/cua0", '4', '0' },
1557c478bd9Sstevel@tonic-gate 	{ "/dev/cua1", '4', '1' },
1567c478bd9Sstevel@tonic-gate 	{ 0 }
1577c478bd9Sstevel@tonic-gate };
1587c478bd9Sstevel@tonic-gate 
159*8d489c7aSmuffin #define	pc(x)	(c = x, (void) write(AC, &c, 1))
1607c478bd9Sstevel@tonic-gate #define	ABORT	01
1617c478bd9Sstevel@tonic-gate #define	SI	017
1627c478bd9Sstevel@tonic-gate #define	STX	02
1637c478bd9Sstevel@tonic-gate #define	ETX	03
1647c478bd9Sstevel@tonic-gate 
165*8d489c7aSmuffin static char
166*8d489c7aSmuffin dialit(char *phonenum, char *acu)
1677c478bd9Sstevel@tonic-gate {
168*8d489c7aSmuffin 	struct vaconfig *vp;
1697c478bd9Sstevel@tonic-gate 	struct termios cntrl;
170*8d489c7aSmuffin 	char c;
1717c478bd9Sstevel@tonic-gate 	int i;
1727c478bd9Sstevel@tonic-gate 
1737c478bd9Sstevel@tonic-gate 	phonenum = sanitize(phonenum);
1747c478bd9Sstevel@tonic-gate #ifdef DEBUG
175*8d489c7aSmuffin 	(void) printf("(dial phonenum=%s)\n", phonenum);
1767c478bd9Sstevel@tonic-gate #endif
1777c478bd9Sstevel@tonic-gate 	if (*phonenum == '<' && phonenum[1] == 0)
1787c478bd9Sstevel@tonic-gate 		return ('Z');
1797c478bd9Sstevel@tonic-gate 	for (vp = vaconfig; vp->vc_name; vp++)
1807c478bd9Sstevel@tonic-gate 		if (strcmp(vp->vc_name, acu) == 0)
1817c478bd9Sstevel@tonic-gate 			break;
1827c478bd9Sstevel@tonic-gate 	if (vp->vc_name == 0) {
183*8d489c7aSmuffin 		(void) printf("Unable to locate dialer (%s)\n", acu);
1847c478bd9Sstevel@tonic-gate 		return ('K');
1857c478bd9Sstevel@tonic-gate 	}
186*8d489c7aSmuffin 	(void) ioctl(AC, TCGETS, &cntrl);
187*8d489c7aSmuffin 	(void) cfsetospeed(&cntrl, B0);
188*8d489c7aSmuffin 	(void) cfsetispeed(&cntrl, B0);
1897c478bd9Sstevel@tonic-gate 	cntrl.c_cflag &= ~(CSIZE|PARENB|PARODD);
190*8d489c7aSmuffin 	(void) cfsetospeed(&cntrl, B2400);
1917c478bd9Sstevel@tonic-gate 	cntrl.c_cflag |= CS8;
1927c478bd9Sstevel@tonic-gate 	cntrl.c_iflag &= IXOFF|IXANY;
1937c478bd9Sstevel@tonic-gate 	cntrl.c_lflag &= ~(ICANON|ISIG);
1947c478bd9Sstevel@tonic-gate 	cntrl.c_oflag = 0;
1957c478bd9Sstevel@tonic-gate 	cntrl.c_cc[VMIN] = cntrl.c_cc[VTIME] = 0;
196*8d489c7aSmuffin 	(void) ioctl(AC, TCSETSF, &cntrl);
197*8d489c7aSmuffin 	(void) ioctl(AC, TCFLSH, TCOFLUSH);
1987c478bd9Sstevel@tonic-gate 	pc(STX);
1997c478bd9Sstevel@tonic-gate 	pc(vp->vc_rack);
2007c478bd9Sstevel@tonic-gate 	pc(vp->vc_modem);
2017c478bd9Sstevel@tonic-gate 	while (*phonenum && *phonenum != '<')
2027c478bd9Sstevel@tonic-gate 		pc(*phonenum++);
2037c478bd9Sstevel@tonic-gate 	pc(SI);
2047c478bd9Sstevel@tonic-gate 	pc(ETX);
205*8d489c7aSmuffin 	(void) sleep(1);
2067c478bd9Sstevel@tonic-gate 	i = read(AC, &c, 1);
2077c478bd9Sstevel@tonic-gate #ifdef DEBUG
2087c478bd9Sstevel@tonic-gate 	printf("read %d chars, char=%c, errno %d\n", i, c, errno);
2097c478bd9Sstevel@tonic-gate #endif
2107c478bd9Sstevel@tonic-gate 	if (i != 1)
2117c478bd9Sstevel@tonic-gate 		c = 'M';
2127c478bd9Sstevel@tonic-gate 	if (c == 'B' || c == 'G') {
2137c478bd9Sstevel@tonic-gate 		char cc, oc = c;
2147c478bd9Sstevel@tonic-gate 
2157c478bd9Sstevel@tonic-gate 		pc(ABORT);
216*8d489c7aSmuffin 		(void) read(AC, &cc, 1);
2177c478bd9Sstevel@tonic-gate #ifdef DEBUG
218*8d489c7aSmuffin 		(void) printf("abort response=%c\n", cc);
2197c478bd9Sstevel@tonic-gate #endif
2207c478bd9Sstevel@tonic-gate 		c = oc;
2217c478bd9Sstevel@tonic-gate 		v831_disconnect();
2227c478bd9Sstevel@tonic-gate 	}
223*8d489c7aSmuffin 	(void) close(AC);
2247c478bd9Sstevel@tonic-gate #ifdef DEBUG
225*8d489c7aSmuffin 	(void) printf("dialit: returns %c\n", c);
2267c478bd9Sstevel@tonic-gate #endif
2277c478bd9Sstevel@tonic-gate 	return (c);
2287c478bd9Sstevel@tonic-gate }
2297c478bd9Sstevel@tonic-gate 
2307c478bd9Sstevel@tonic-gate static char *
231*8d489c7aSmuffin sanitize(char *s)
2327c478bd9Sstevel@tonic-gate {
2337c478bd9Sstevel@tonic-gate 	static char buf[128];
234*8d489c7aSmuffin 	char *cp;
2357c478bd9Sstevel@tonic-gate 
2367c478bd9Sstevel@tonic-gate 	for (cp = buf; *s; s++) {
2377c478bd9Sstevel@tonic-gate 		if (!isdigit(*s) && *s == '<' && *s != '_')
2387c478bd9Sstevel@tonic-gate 			continue;
2397c478bd9Sstevel@tonic-gate 		if (*s == '_')
2407c478bd9Sstevel@tonic-gate 			*s = '=';
2417c478bd9Sstevel@tonic-gate 		*cp++ = *s;
2427c478bd9Sstevel@tonic-gate 	}
2437c478bd9Sstevel@tonic-gate 	*cp++ = 0;
2447c478bd9Sstevel@tonic-gate 	return (buf);
2457c478bd9Sstevel@tonic-gate }
246