xref: /freebsd/usr.bin/tip/libacu/v831.c (revision 0f3bdf5df978c1d74d4b5e0429ced9613debcc3c)
10f3bdf5dSMark Murray /*	$OpenBSD: v831.c,v 1.6 2001/11/19 19:02:16 mpech Exp $	*/
20f3bdf5dSMark Murray /*	$NetBSD: v831.c,v 1.5 1996/12/29 10:42:01 cgd Exp $	*/
30f3bdf5dSMark Murray 
40f3bdf5dSMark Murray /*
50f3bdf5dSMark Murray  * Copyright (c) 1983, 1993
60f3bdf5dSMark Murray  *	The Regents of the University of California.  All rights reserved.
70f3bdf5dSMark Murray  *
80f3bdf5dSMark Murray  * Redistribution and use in source and binary forms, with or without
90f3bdf5dSMark Murray  * modification, are permitted provided that the following conditions
100f3bdf5dSMark Murray  * are met:
110f3bdf5dSMark Murray  * 1. Redistributions of source code must retain the above copyright
120f3bdf5dSMark Murray  *    notice, this list of conditions and the following disclaimer.
130f3bdf5dSMark Murray  * 2. Redistributions in binary form must reproduce the above copyright
140f3bdf5dSMark Murray  *    notice, this list of conditions and the following disclaimer in the
150f3bdf5dSMark Murray  *    documentation and/or other materials provided with the distribution.
160f3bdf5dSMark Murray  * 3. All advertising materials mentioning features or use of this software
170f3bdf5dSMark Murray  *    must display the following acknowledgement:
180f3bdf5dSMark Murray  *	This product includes software developed by the University of
190f3bdf5dSMark Murray  *	California, Berkeley and its contributors.
200f3bdf5dSMark Murray  * 4. Neither the name of the University nor the names of its contributors
210f3bdf5dSMark Murray  *    may be used to endorse or promote products derived from this software
220f3bdf5dSMark Murray  *    without specific prior written permission.
230f3bdf5dSMark Murray  *
240f3bdf5dSMark Murray  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
250f3bdf5dSMark Murray  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
260f3bdf5dSMark Murray  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
270f3bdf5dSMark Murray  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
280f3bdf5dSMark Murray  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
290f3bdf5dSMark Murray  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
300f3bdf5dSMark Murray  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
310f3bdf5dSMark Murray  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
320f3bdf5dSMark Murray  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
330f3bdf5dSMark Murray  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
340f3bdf5dSMark Murray  * SUCH DAMAGE.
350f3bdf5dSMark Murray  */
360f3bdf5dSMark Murray 
370f3bdf5dSMark Murray #ifndef lint
380f3bdf5dSMark Murray #if 0
390f3bdf5dSMark Murray static char sccsid[] = "@(#)v831.c	8.1 (Berkeley) 6/6/93";
400f3bdf5dSMark Murray #endif
410f3bdf5dSMark Murray static char rcsid[] = "$OpenBSD: v831.c,v 1.6 2001/11/19 19:02:16 mpech Exp $";
420f3bdf5dSMark Murray #endif /* not lint */
430f3bdf5dSMark Murray 
440f3bdf5dSMark Murray /*
450f3bdf5dSMark Murray  * Routines for dialing up on Vadic 831
460f3bdf5dSMark Murray  */
470f3bdf5dSMark Murray #include "tip.h"
480f3bdf5dSMark Murray #include <termios.h>
490f3bdf5dSMark Murray 
500f3bdf5dSMark Murray void	v831_abort();
510f3bdf5dSMark Murray static	void alarmtr();
520f3bdf5dSMark Murray static	int dialit();
530f3bdf5dSMark Murray static	char *sanitize();
540f3bdf5dSMark Murray 
550f3bdf5dSMark Murray static jmp_buf jmpbuf;
560f3bdf5dSMark Murray static int child = -1;
570f3bdf5dSMark Murray 
580f3bdf5dSMark Murray int
590f3bdf5dSMark Murray v831_dialer(num, acu)
600f3bdf5dSMark Murray         char *num, *acu;
610f3bdf5dSMark Murray {
620f3bdf5dSMark Murray         int status, pid;
630f3bdf5dSMark Murray         int timelim;
640f3bdf5dSMark Murray 
650f3bdf5dSMark Murray         if (boolean(value(VERBOSE)))
660f3bdf5dSMark Murray                 printf("\nstarting call...");
670f3bdf5dSMark Murray #ifdef DEBUG
680f3bdf5dSMark Murray         printf ("(acu=%s)\n", acu);
690f3bdf5dSMark Murray #endif
700f3bdf5dSMark Murray         if ((AC = open(acu, O_RDWR)) < 0) {
710f3bdf5dSMark Murray                 if (errno == EBUSY)
720f3bdf5dSMark Murray                         printf("line busy...");
730f3bdf5dSMark Murray                 else
740f3bdf5dSMark Murray                         printf("acu open error...");
750f3bdf5dSMark Murray                 return (0);
760f3bdf5dSMark Murray         }
770f3bdf5dSMark Murray         if (setjmp(jmpbuf)) {
780f3bdf5dSMark Murray                 kill(child, SIGKILL);
790f3bdf5dSMark Murray                 close(AC);
800f3bdf5dSMark Murray                 return (0);
810f3bdf5dSMark Murray         }
820f3bdf5dSMark Murray         signal(SIGALRM, alarmtr);
830f3bdf5dSMark Murray         timelim = 5 * strlen(num);
840f3bdf5dSMark Murray         alarm(timelim < 30 ? 30 : timelim);
850f3bdf5dSMark Murray         if ((child = fork()) == 0) {
860f3bdf5dSMark Murray                 /*
870f3bdf5dSMark Murray                  * ignore this stuff for aborts
880f3bdf5dSMark Murray                  */
890f3bdf5dSMark Murray                 signal(SIGALRM, SIG_IGN);
900f3bdf5dSMark Murray 		signal(SIGINT, SIG_IGN);
910f3bdf5dSMark Murray                 signal(SIGQUIT, SIG_IGN);
920f3bdf5dSMark Murray                 sleep(2);
930f3bdf5dSMark Murray                 exit(dialit(num, acu) != 'A');
940f3bdf5dSMark Murray         }
950f3bdf5dSMark Murray         /*
960f3bdf5dSMark Murray          * open line - will return on carrier
970f3bdf5dSMark Murray          */
980f3bdf5dSMark Murray         if ((FD = open(DV, O_RDWR)) < 0) {
990f3bdf5dSMark Murray #ifdef DEBUG
1000f3bdf5dSMark Murray                 printf("(after open, errno=%d)\n", errno);
1010f3bdf5dSMark Murray #endif
1020f3bdf5dSMark Murray                 if (errno == EIO)
1030f3bdf5dSMark Murray                         printf("lost carrier...");
1040f3bdf5dSMark Murray                 else
1050f3bdf5dSMark Murray                         printf("dialup line open failed...");
1060f3bdf5dSMark Murray                 alarm(0);
1070f3bdf5dSMark Murray                 kill(child, SIGKILL);
1080f3bdf5dSMark Murray                 close(AC);
1090f3bdf5dSMark Murray                 return (0);
1100f3bdf5dSMark Murray         }
1110f3bdf5dSMark Murray         alarm(0);
1120f3bdf5dSMark Murray         signal(SIGALRM, SIG_DFL);
1130f3bdf5dSMark Murray         while ((pid = wait(&status)) != child && pid != -1)
1140f3bdf5dSMark Murray                 ;
1150f3bdf5dSMark Murray         if (status) {
1160f3bdf5dSMark Murray                 close(AC);
1170f3bdf5dSMark Murray                 return (0);
1180f3bdf5dSMark Murray         }
1190f3bdf5dSMark Murray         return (1);
1200f3bdf5dSMark Murray }
1210f3bdf5dSMark Murray 
1220f3bdf5dSMark Murray static void
1230f3bdf5dSMark Murray alarmtr()
1240f3bdf5dSMark Murray {
1250f3bdf5dSMark Murray         alarm(0);
1260f3bdf5dSMark Murray         longjmp(jmpbuf, 1);
1270f3bdf5dSMark Murray }
1280f3bdf5dSMark Murray 
1290f3bdf5dSMark Murray /*
1300f3bdf5dSMark Murray  * Insurance, for some reason we don't seem to be
1310f3bdf5dSMark Murray  *  hanging up...
1320f3bdf5dSMark Murray  */
1330f3bdf5dSMark Murray void
1340f3bdf5dSMark Murray v831_disconnect()
1350f3bdf5dSMark Murray {
1360f3bdf5dSMark Murray 	struct termios	cntrl;
1370f3bdf5dSMark Murray 
1380f3bdf5dSMark Murray         sleep(2);
1390f3bdf5dSMark Murray #ifdef DEBUG
1400f3bdf5dSMark Murray         printf("[disconnect: FD=%d]\n", FD);
1410f3bdf5dSMark Murray #endif
1420f3bdf5dSMark Murray         if (FD > 0) {
1430f3bdf5dSMark Murray                 ioctl(FD, TIOCCDTR, 0);
1440f3bdf5dSMark Murray 		tcgetattr(FD, &cntrl);
1450f3bdf5dSMark Murray 		cfsetospeed(&cntrl, 0);
1460f3bdf5dSMark Murray 		cfsetispeed(&cntrl, 0);
1470f3bdf5dSMark Murray 		tcsetattr(FD, TCSAFLUSH, &cntrl);
1480f3bdf5dSMark Murray                 ioctl(FD, TIOCNXCL, NULL);
1490f3bdf5dSMark Murray         }
1500f3bdf5dSMark Murray         close(FD);
1510f3bdf5dSMark Murray }
1520f3bdf5dSMark Murray 
1530f3bdf5dSMark Murray void
1540f3bdf5dSMark Murray v831_abort()
1550f3bdf5dSMark Murray {
1560f3bdf5dSMark Murray 
1570f3bdf5dSMark Murray #ifdef DEBUG
1580f3bdf5dSMark Murray         printf("[abort: AC=%d]\n", AC);
1590f3bdf5dSMark Murray #endif
1600f3bdf5dSMark Murray         sleep(2);
1610f3bdf5dSMark Murray         if (child > 0)
1620f3bdf5dSMark Murray                 kill(child, SIGKILL);
1630f3bdf5dSMark Murray         if (AC > 0)
1640f3bdf5dSMark Murray                 ioctl(FD, TIOCNXCL, NULL);
1650f3bdf5dSMark Murray                 close(AC);
1660f3bdf5dSMark Murray         if (FD > 0)
1670f3bdf5dSMark Murray                 ioctl(FD, TIOCCDTR, 0);
1680f3bdf5dSMark Murray         close(FD);
1690f3bdf5dSMark Murray }
1700f3bdf5dSMark Murray 
1710f3bdf5dSMark Murray /*
1720f3bdf5dSMark Murray  * Sigh, this probably must be changed at each site.
1730f3bdf5dSMark Murray  */
1740f3bdf5dSMark Murray struct vaconfig {
1750f3bdf5dSMark Murray 	char	*vc_name;
1760f3bdf5dSMark Murray 	char	vc_rack;
1770f3bdf5dSMark Murray 	char	vc_modem;
1780f3bdf5dSMark Murray } vaconfig[] = {
1790f3bdf5dSMark Murray 	{ "/dev/cua0",'4','0' },
1800f3bdf5dSMark Murray 	{ "/dev/cua1",'4','1' },
1810f3bdf5dSMark Murray 	{ 0 }
1820f3bdf5dSMark Murray };
1830f3bdf5dSMark Murray 
1840f3bdf5dSMark Murray #define pc(x)	(c = x, write(AC,&c,1))
1850f3bdf5dSMark Murray #define ABORT	01
1860f3bdf5dSMark Murray #define SI	017
1870f3bdf5dSMark Murray #define STX	02
1880f3bdf5dSMark Murray #define ETX	03
1890f3bdf5dSMark Murray 
1900f3bdf5dSMark Murray static int
1910f3bdf5dSMark Murray dialit(phonenum, acu)
1920f3bdf5dSMark Murray 	char *phonenum;
1930f3bdf5dSMark Murray 	char *acu;
1940f3bdf5dSMark Murray {
1950f3bdf5dSMark Murray         struct vaconfig *vp;
1960f3bdf5dSMark Murray 	struct termios cntrl;
1970f3bdf5dSMark Murray         char c;
1980f3bdf5dSMark Murray         int i;
1990f3bdf5dSMark Murray 
2000f3bdf5dSMark Murray         phonenum = sanitize(phonenum);
2010f3bdf5dSMark Murray #ifdef DEBUG
2020f3bdf5dSMark Murray         printf ("(dial phonenum=%s)\n", phonenum);
2030f3bdf5dSMark Murray #endif
2040f3bdf5dSMark Murray         if (*phonenum == '<' && phonenum[1] == 0)
2050f3bdf5dSMark Murray                 return ('Z');
2060f3bdf5dSMark Murray 	for (vp = vaconfig; vp->vc_name; vp++)
2070f3bdf5dSMark Murray 		if (strcmp(vp->vc_name, acu) == 0)
2080f3bdf5dSMark Murray 			break;
2090f3bdf5dSMark Murray 	if (vp->vc_name == 0) {
2100f3bdf5dSMark Murray 		printf("Unable to locate dialer (%s)\n", acu);
2110f3bdf5dSMark Murray 		return ('K');
2120f3bdf5dSMark Murray 	}
2130f3bdf5dSMark Murray 	tcgetattr(AC, &cntrl);
2140f3bdf5dSMark Murray 	cfsetospeed(&cntrl, B2400);
2150f3bdf5dSMark Murray 	cfsetispeed(&cntrl, B2400);
2160f3bdf5dSMark Murray 	cntrl.c_cflag |= PARODD | PARENB;
2170f3bdf5dSMark Murray 	cntrl.c_lflag &= ~(ISIG | ICANON);
2180f3bdf5dSMark Murray 	tcsetattr(AC, TCSANOW, &cntrl);
2190f3bdf5dSMark Murray 	tcflush(AC, TCIOFLUSH);
2200f3bdf5dSMark Murray         pc(STX);
2210f3bdf5dSMark Murray 	pc(vp->vc_rack);
2220f3bdf5dSMark Murray 	pc(vp->vc_modem);
2230f3bdf5dSMark Murray 	while (*phonenum && *phonenum != '<')
2240f3bdf5dSMark Murray 		pc(*phonenum++);
2250f3bdf5dSMark Murray         pc(SI);
2260f3bdf5dSMark Murray 	pc(ETX);
2270f3bdf5dSMark Murray         sleep(1);
2280f3bdf5dSMark Murray         i = read(AC, &c, 1);
2290f3bdf5dSMark Murray #ifdef DEBUG
2300f3bdf5dSMark Murray         printf("read %d chars, char=%c, errno %d\n", i, c, errno);
2310f3bdf5dSMark Murray #endif
2320f3bdf5dSMark Murray         if (i != 1)
2330f3bdf5dSMark Murray 		c = 'M';
2340f3bdf5dSMark Murray         if (c == 'B' || c == 'G') {
2350f3bdf5dSMark Murray                 char cc, oc = c;
2360f3bdf5dSMark Murray 
2370f3bdf5dSMark Murray                 pc(ABORT);
2380f3bdf5dSMark Murray                 read(AC, &cc, 1);
2390f3bdf5dSMark Murray #ifdef DEBUG
2400f3bdf5dSMark Murray                 printf("abort response=%c\n", cc);
2410f3bdf5dSMark Murray #endif
2420f3bdf5dSMark Murray                 c = oc;
2430f3bdf5dSMark Murray                 v831_disconnect();
2440f3bdf5dSMark Murray         }
2450f3bdf5dSMark Murray         close(AC);
2460f3bdf5dSMark Murray #ifdef DEBUG
2470f3bdf5dSMark Murray         printf("dialit: returns %c\n", c);
2480f3bdf5dSMark Murray #endif
2490f3bdf5dSMark Murray         return (c);
2500f3bdf5dSMark Murray }
2510f3bdf5dSMark Murray 
2520f3bdf5dSMark Murray static char *
2530f3bdf5dSMark Murray sanitize(s)
2540f3bdf5dSMark Murray 	char *s;
2550f3bdf5dSMark Murray {
2560f3bdf5dSMark Murray         static char buf[128];
2570f3bdf5dSMark Murray         char *cp;
2580f3bdf5dSMark Murray 
2590f3bdf5dSMark Murray         for (cp = buf; *s; s++) {
2600f3bdf5dSMark Murray 		if (!isdigit(*s) && *s == '<' && *s != '_')
2610f3bdf5dSMark Murray 			continue;
2620f3bdf5dSMark Murray 		if (*s == '_')
2630f3bdf5dSMark Murray 			*s = '=';
2640f3bdf5dSMark Murray 		*cp++ = *s;
2650f3bdf5dSMark Murray 	}
2660f3bdf5dSMark Murray         *cp++ = 0;
2670f3bdf5dSMark Murray         return (buf);
2680f3bdf5dSMark Murray }
269