xref: /illumos-gate/usr/src/cmd/tip/aculib/v831.c (revision 1e094e1b)
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  */
58d489c7aSmuffin 
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  */
118d489c7aSmuffin 
127c478bd9Sstevel@tonic-gate /*
137c478bd9Sstevel@tonic-gate  * Routines for dialing up on Vadic 831
147c478bd9Sstevel@tonic-gate  */
157c478bd9Sstevel@tonic-gate #include <sys/time.h>
167c478bd9Sstevel@tonic-gate 
177c478bd9Sstevel@tonic-gate #include "tip.h"
187c478bd9Sstevel@tonic-gate 
19*1e094e1bSToomas Soome int AC;
208d489c7aSmuffin static char	dialit(char *, char *);
218d489c7aSmuffin static char	*sanitize(char *);
228d489c7aSmuffin static void	alarmtr(void);
237c478bd9Sstevel@tonic-gate 
248d489c7aSmuffin static sigjmp_buf	jmpbuf;
258d489c7aSmuffin static int	child = -1;
267c478bd9Sstevel@tonic-gate 
278d489c7aSmuffin int
v831_dialer(char * num,char * acu)288d489c7aSmuffin v831_dialer(char *num, char *acu)
297c478bd9Sstevel@tonic-gate {
308d489c7aSmuffin 	int status, pid;
318d489c7aSmuffin 	int timelim;
327c478bd9Sstevel@tonic-gate 
337c478bd9Sstevel@tonic-gate 	if (boolean(value(VERBOSE)))
348d489c7aSmuffin 		(void) printf("\nstarting call...");
357c478bd9Sstevel@tonic-gate #ifdef DEBUG
368d489c7aSmuffin 	(void) printf("(acu=%s)\n", acu);
377c478bd9Sstevel@tonic-gate #endif
387c478bd9Sstevel@tonic-gate 	if ((AC = open(acu, O_RDWR)) < 0) {
397c478bd9Sstevel@tonic-gate 		if (errno == EBUSY)
408d489c7aSmuffin 			(void) printf("line busy...");
417c478bd9Sstevel@tonic-gate 		else
428d489c7aSmuffin 			(void) printf("acu open error...");
437c478bd9Sstevel@tonic-gate 		return (0);
447c478bd9Sstevel@tonic-gate 	}
457c478bd9Sstevel@tonic-gate 	if (sigsetjmp(jmpbuf, 1)) {
468d489c7aSmuffin 		(void) kill(child, SIGKILL);
478d489c7aSmuffin 		(void) close(AC);
487c478bd9Sstevel@tonic-gate 		return (0);
497c478bd9Sstevel@tonic-gate 	}
508d489c7aSmuffin 	(void) signal(SIGALRM, (sig_handler_t)alarmtr);
517c478bd9Sstevel@tonic-gate 	timelim = 5 * strlen(num);
528d489c7aSmuffin 	(void) alarm(timelim < 30 ? 30 : timelim);
537c478bd9Sstevel@tonic-gate 	if ((child = fork()) == 0) {
547c478bd9Sstevel@tonic-gate 		/*
557c478bd9Sstevel@tonic-gate 		 * ignore this stuff for aborts
567c478bd9Sstevel@tonic-gate 		 */
578d489c7aSmuffin 		(void) signal(SIGALRM, SIG_IGN);
588d489c7aSmuffin 		(void) signal(SIGINT, SIG_IGN);
598d489c7aSmuffin 		(void) signal(SIGQUIT, SIG_IGN);
608d489c7aSmuffin 		(void) sleep(2);
617c478bd9Sstevel@tonic-gate 		exit(dialit(num, acu) != 'A');
627c478bd9Sstevel@tonic-gate 	}
637c478bd9Sstevel@tonic-gate 	/*
647c478bd9Sstevel@tonic-gate 	 * open line - will return on carrier
657c478bd9Sstevel@tonic-gate 	 */
667c478bd9Sstevel@tonic-gate 	if ((FD = open(DV, O_RDWR)) < 0) {
677c478bd9Sstevel@tonic-gate #ifdef DEBUG
688d489c7aSmuffin 		(void) printf("(after open, errno=%d)\n", errno);
697c478bd9Sstevel@tonic-gate #endif
707c478bd9Sstevel@tonic-gate 		if (errno == EIO)
718d489c7aSmuffin 			(void) printf("lost carrier...");
727c478bd9Sstevel@tonic-gate 		else
738d489c7aSmuffin 			(void) printf("dialup line open failed...");
748d489c7aSmuffin 		(void) alarm(0);
758d489c7aSmuffin 		(void) kill(child, SIGKILL);
768d489c7aSmuffin 		(void) close(AC);
777c478bd9Sstevel@tonic-gate 		return (0);
787c478bd9Sstevel@tonic-gate 	}
798d489c7aSmuffin 	(void) alarm(0);
808d489c7aSmuffin 	(void) signal(SIGALRM, SIG_DFL);
817c478bd9Sstevel@tonic-gate 	while ((pid = wait(&status)) != child && pid != -1)
827c478bd9Sstevel@tonic-gate 		;
837c478bd9Sstevel@tonic-gate 	if (status) {
848d489c7aSmuffin 		(void) close(AC);
857c478bd9Sstevel@tonic-gate 		return (0);
867c478bd9Sstevel@tonic-gate 	}
877c478bd9Sstevel@tonic-gate 	return (1);
887c478bd9Sstevel@tonic-gate }
897c478bd9Sstevel@tonic-gate 
907c478bd9Sstevel@tonic-gate static void
alarmtr(void)918d489c7aSmuffin alarmtr(void)
927c478bd9Sstevel@tonic-gate {
937c478bd9Sstevel@tonic-gate 
948d489c7aSmuffin 	(void) alarm(0);
957c478bd9Sstevel@tonic-gate 	siglongjmp(jmpbuf, 1);
967c478bd9Sstevel@tonic-gate }
977c478bd9Sstevel@tonic-gate 
987c478bd9Sstevel@tonic-gate /*
997c478bd9Sstevel@tonic-gate  * Insurance, for some reason we don't seem to be
1007c478bd9Sstevel@tonic-gate  *  hanging up...
1017c478bd9Sstevel@tonic-gate  */
1028d489c7aSmuffin void
v831_disconnect(void)1038d489c7aSmuffin v831_disconnect(void)
1047c478bd9Sstevel@tonic-gate {
1057c478bd9Sstevel@tonic-gate 	struct termios cntrl;
1067c478bd9Sstevel@tonic-gate 	int dtr = TIOCM_DTR;
1077c478bd9Sstevel@tonic-gate 
1088d489c7aSmuffin 	(void) sleep(2);
1097c478bd9Sstevel@tonic-gate #ifdef DEBUG
1107c478bd9Sstevel@tonic-gate 	printf("[disconnect: FD=%d]\n", FD);
1117c478bd9Sstevel@tonic-gate #endif
1127c478bd9Sstevel@tonic-gate 	if (FD > 0) {
1138d489c7aSmuffin 		(void) ioctl(FD, TIOCMBIC, &dtr);
1148d489c7aSmuffin 		(void) ioctl(FD, TCGETS, &cntrl);
1158d489c7aSmuffin 		(void) cfsetospeed(&cntrl, B0);
1167c478bd9Sstevel@tonic-gate 		cntrl.c_cflag &= ~XCLUDE;
1178d489c7aSmuffin 		(void) ioctl(FD, TCSETSF, &cntrl);
1187c478bd9Sstevel@tonic-gate 	}
1198d489c7aSmuffin 	(void) close(FD);
1207c478bd9Sstevel@tonic-gate }
1217c478bd9Sstevel@tonic-gate 
1228d489c7aSmuffin void
v831_abort(void)1238d489c7aSmuffin v831_abort(void)
1247c478bd9Sstevel@tonic-gate {
1257c478bd9Sstevel@tonic-gate 	int dtr = TIOCM_DTR;
1267c478bd9Sstevel@tonic-gate 	struct termios buf;
1277c478bd9Sstevel@tonic-gate 
1287c478bd9Sstevel@tonic-gate #ifdef DEBUG
1298d489c7aSmuffin 	(void) printf("[abort: AC=%d]\n", AC);
1307c478bd9Sstevel@tonic-gate #endif
1318d489c7aSmuffin 	(void) sleep(2);
1327c478bd9Sstevel@tonic-gate 	if (child > 0)
1338d489c7aSmuffin 		(void) kill(child, SIGKILL);
1347c478bd9Sstevel@tonic-gate 	if (AC > 0) {
1358d489c7aSmuffin 		(void) ioctl(FD, TCGETS, &buf);
1367c478bd9Sstevel@tonic-gate 		buf.c_cflag &= ~XCLUDE;
1378d489c7aSmuffin 		(void) ioctl(FD, TCSETSF, &buf);
1388d489c7aSmuffin 		(void) close(AC);
1397c478bd9Sstevel@tonic-gate 	}
1407c478bd9Sstevel@tonic-gate 	if (FD > 0)
1418d489c7aSmuffin 		(void) ioctl(FD, TIOCMBIC, &dtr);
1428d489c7aSmuffin 	(void) close(FD);
1437c478bd9Sstevel@tonic-gate }
1447c478bd9Sstevel@tonic-gate 
1457c478bd9Sstevel@tonic-gate /*
1467c478bd9Sstevel@tonic-gate  * Sigh, this probably must be changed at each site.
1477c478bd9Sstevel@tonic-gate  */
1487c478bd9Sstevel@tonic-gate struct vaconfig {
1497c478bd9Sstevel@tonic-gate 	char	*vc_name;
1507c478bd9Sstevel@tonic-gate 	char	vc_rack;
1517c478bd9Sstevel@tonic-gate 	char	vc_modem;
1527c478bd9Sstevel@tonic-gate } vaconfig[] = {
1537c478bd9Sstevel@tonic-gate 	{ "/dev/cua0", '4', '0' },
1547c478bd9Sstevel@tonic-gate 	{ "/dev/cua1", '4', '1' },
1557c478bd9Sstevel@tonic-gate 	{ 0 }
1567c478bd9Sstevel@tonic-gate };
1577c478bd9Sstevel@tonic-gate 
1588d489c7aSmuffin #define	pc(x)	(c = x, (void) write(AC, &c, 1))
1597c478bd9Sstevel@tonic-gate #define	ABORT	01
1607c478bd9Sstevel@tonic-gate #define	SI	017
1617c478bd9Sstevel@tonic-gate #define	STX	02
1627c478bd9Sstevel@tonic-gate #define	ETX	03
1637c478bd9Sstevel@tonic-gate 
1648d489c7aSmuffin static char
dialit(char * phonenum,char * acu)1658d489c7aSmuffin dialit(char *phonenum, char *acu)
1667c478bd9Sstevel@tonic-gate {
1678d489c7aSmuffin 	struct vaconfig *vp;
1687c478bd9Sstevel@tonic-gate 	struct termios cntrl;
1698d489c7aSmuffin 	char c;
1707c478bd9Sstevel@tonic-gate 	int i;
1717c478bd9Sstevel@tonic-gate 
1727c478bd9Sstevel@tonic-gate 	phonenum = sanitize(phonenum);
1737c478bd9Sstevel@tonic-gate #ifdef DEBUG
1748d489c7aSmuffin 	(void) printf("(dial phonenum=%s)\n", phonenum);
1757c478bd9Sstevel@tonic-gate #endif
1767c478bd9Sstevel@tonic-gate 	if (*phonenum == '<' && phonenum[1] == 0)
1777c478bd9Sstevel@tonic-gate 		return ('Z');
1787c478bd9Sstevel@tonic-gate 	for (vp = vaconfig; vp->vc_name; vp++)
1797c478bd9Sstevel@tonic-gate 		if (strcmp(vp->vc_name, acu) == 0)
1807c478bd9Sstevel@tonic-gate 			break;
1817c478bd9Sstevel@tonic-gate 	if (vp->vc_name == 0) {
1828d489c7aSmuffin 		(void) printf("Unable to locate dialer (%s)\n", acu);
1837c478bd9Sstevel@tonic-gate 		return ('K');
1847c478bd9Sstevel@tonic-gate 	}
1858d489c7aSmuffin 	(void) ioctl(AC, TCGETS, &cntrl);
1868d489c7aSmuffin 	(void) cfsetospeed(&cntrl, B0);
1878d489c7aSmuffin 	(void) cfsetispeed(&cntrl, B0);
1887c478bd9Sstevel@tonic-gate 	cntrl.c_cflag &= ~(CSIZE|PARENB|PARODD);
1898d489c7aSmuffin 	(void) cfsetospeed(&cntrl, B2400);
1907c478bd9Sstevel@tonic-gate 	cntrl.c_cflag |= CS8;
1917c478bd9Sstevel@tonic-gate 	cntrl.c_iflag &= IXOFF|IXANY;
1927c478bd9Sstevel@tonic-gate 	cntrl.c_lflag &= ~(ICANON|ISIG);
1937c478bd9Sstevel@tonic-gate 	cntrl.c_oflag = 0;
1947c478bd9Sstevel@tonic-gate 	cntrl.c_cc[VMIN] = cntrl.c_cc[VTIME] = 0;
1958d489c7aSmuffin 	(void) ioctl(AC, TCSETSF, &cntrl);
1968d489c7aSmuffin 	(void) ioctl(AC, TCFLSH, TCOFLUSH);
1977c478bd9Sstevel@tonic-gate 	pc(STX);
1987c478bd9Sstevel@tonic-gate 	pc(vp->vc_rack);
1997c478bd9Sstevel@tonic-gate 	pc(vp->vc_modem);
2007c478bd9Sstevel@tonic-gate 	while (*phonenum && *phonenum != '<')
2017c478bd9Sstevel@tonic-gate 		pc(*phonenum++);
2027c478bd9Sstevel@tonic-gate 	pc(SI);
2037c478bd9Sstevel@tonic-gate 	pc(ETX);
2048d489c7aSmuffin 	(void) sleep(1);
2057c478bd9Sstevel@tonic-gate 	i = read(AC, &c, 1);
2067c478bd9Sstevel@tonic-gate #ifdef DEBUG
2077c478bd9Sstevel@tonic-gate 	printf("read %d chars, char=%c, errno %d\n", i, c, errno);
2087c478bd9Sstevel@tonic-gate #endif
2097c478bd9Sstevel@tonic-gate 	if (i != 1)
2107c478bd9Sstevel@tonic-gate 		c = 'M';
2117c478bd9Sstevel@tonic-gate 	if (c == 'B' || c == 'G') {
2127c478bd9Sstevel@tonic-gate 		char cc, oc = c;
2137c478bd9Sstevel@tonic-gate 
2147c478bd9Sstevel@tonic-gate 		pc(ABORT);
2158d489c7aSmuffin 		(void) read(AC, &cc, 1);
2167c478bd9Sstevel@tonic-gate #ifdef DEBUG
2178d489c7aSmuffin 		(void) printf("abort response=%c\n", cc);
2187c478bd9Sstevel@tonic-gate #endif
2197c478bd9Sstevel@tonic-gate 		c = oc;
2207c478bd9Sstevel@tonic-gate 		v831_disconnect();
2217c478bd9Sstevel@tonic-gate 	}
2228d489c7aSmuffin 	(void) close(AC);
2237c478bd9Sstevel@tonic-gate #ifdef DEBUG
2248d489c7aSmuffin 	(void) printf("dialit: returns %c\n", c);
2257c478bd9Sstevel@tonic-gate #endif
2267c478bd9Sstevel@tonic-gate 	return (c);
2277c478bd9Sstevel@tonic-gate }
2287c478bd9Sstevel@tonic-gate 
2297c478bd9Sstevel@tonic-gate static char *
sanitize(char * s)2308d489c7aSmuffin sanitize(char *s)
2317c478bd9Sstevel@tonic-gate {
2327c478bd9Sstevel@tonic-gate 	static char buf[128];
2338d489c7aSmuffin 	char *cp;
2347c478bd9Sstevel@tonic-gate 
2357c478bd9Sstevel@tonic-gate 	for (cp = buf; *s; s++) {
2367c478bd9Sstevel@tonic-gate 		if (!isdigit(*s) && *s == '<' && *s != '_')
2377c478bd9Sstevel@tonic-gate 			continue;
2387c478bd9Sstevel@tonic-gate 		if (*s == '_')
2397c478bd9Sstevel@tonic-gate 			*s = '=';
2407c478bd9Sstevel@tonic-gate 		*cp++ = *s;
2417c478bd9Sstevel@tonic-gate 	}
2427c478bd9Sstevel@tonic-gate 	*cp++ = 0;
2437c478bd9Sstevel@tonic-gate 	return (buf);
2447c478bd9Sstevel@tonic-gate }
245