xref: /freebsd/usr.bin/tip/libacu/v831.c (revision 07bb01e3d4ef046f266665f3a826faaa08a0865a)
1fa92e883SRuslan Ermilov /*	$OpenBSD: v831.c,v 1.11 2006/03/17 19:17:13 moritz Exp $	*/
20f3bdf5dSMark Murray /*	$NetBSD: v831.c,v 1.5 1996/12/29 10:42:01 cgd Exp $	*/
30f3bdf5dSMark Murray 
418cc36fbSJordan K. Hubbard /*
518cc36fbSJordan K. Hubbard  * Copyright (c) 1983, 1993
618cc36fbSJordan K. Hubbard  *	The Regents of the University of California.  All rights reserved.
718cc36fbSJordan K. Hubbard  *
818cc36fbSJordan K. Hubbard  * Redistribution and use in source and binary forms, with or without
918cc36fbSJordan K. Hubbard  * modification, are permitted provided that the following conditions
1018cc36fbSJordan K. Hubbard  * are met:
1118cc36fbSJordan K. Hubbard  * 1. Redistributions of source code must retain the above copyright
1218cc36fbSJordan K. Hubbard  *    notice, this list of conditions and the following disclaimer.
1318cc36fbSJordan K. Hubbard  * 2. Redistributions in binary form must reproduce the above copyright
1418cc36fbSJordan K. Hubbard  *    notice, this list of conditions and the following disclaimer in the
1518cc36fbSJordan K. Hubbard  *    documentation and/or other materials provided with the distribution.
16fa92e883SRuslan Ermilov  * 3. Neither the name of the University nor the names of its contributors
1718cc36fbSJordan K. Hubbard  *    may be used to endorse or promote products derived from this software
1818cc36fbSJordan K. Hubbard  *    without specific prior written permission.
1918cc36fbSJordan K. Hubbard  *
2018cc36fbSJordan K. Hubbard  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2118cc36fbSJordan K. Hubbard  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2218cc36fbSJordan K. Hubbard  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2318cc36fbSJordan K. Hubbard  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2418cc36fbSJordan K. Hubbard  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2518cc36fbSJordan K. Hubbard  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2618cc36fbSJordan K. Hubbard  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2718cc36fbSJordan K. Hubbard  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2818cc36fbSJordan K. Hubbard  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2918cc36fbSJordan K. Hubbard  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3018cc36fbSJordan K. Hubbard  * SUCH DAMAGE.
3118cc36fbSJordan K. Hubbard  */
3218cc36fbSJordan K. Hubbard 
3365785b55SMark Murray #include <sys/cdefs.h>
3465785b55SMark Murray __FBSDID("$FreeBSD$");
3565785b55SMark Murray 
3618cc36fbSJordan K. Hubbard #ifndef lint
370f3bdf5dSMark Murray #if 0
3818cc36fbSJordan K. Hubbard static char sccsid[] = "@(#)v831.c	8.1 (Berkeley) 6/6/93";
39fa92e883SRuslan Ermilov static const char rcsid[] = "$OpenBSD: v831.c,v 1.11 2006/03/17 19:17:13 moritz Exp $";
4065785b55SMark Murray #endif
4118cc36fbSJordan K. Hubbard #endif /* not lint */
4218cc36fbSJordan K. Hubbard 
4318cc36fbSJordan K. Hubbard /*
4418cc36fbSJordan K. Hubbard  * Routines for dialing up on Vadic 831
4518cc36fbSJordan K. Hubbard  */
4618cc36fbSJordan K. Hubbard #include "tip.h"
470f3bdf5dSMark Murray #include <termios.h>
4818cc36fbSJordan K. Hubbard 
4918cc36fbSJordan K. Hubbard static jmp_buf jmpbuf;
50fa92e883SRuslan Ermilov static pid_t child = -1;
51fa92e883SRuslan Ermilov 
52fa92e883SRuslan Ermilov static void	alarmtr(int);
53fa92e883SRuslan Ermilov static int	dialit(char *, char *);
54fa92e883SRuslan Ermilov static char *	sanitize(char *);
5518cc36fbSJordan K. Hubbard 
560f3bdf5dSMark Murray int
57fa92e883SRuslan Ermilov v831_dialer(char *num, char *acu)
5818cc36fbSJordan K. Hubbard {
59fa92e883SRuslan Ermilov         int status;
600f3bdf5dSMark Murray         int timelim;
61fa92e883SRuslan Ermilov 	pid_t pid;
6218cc36fbSJordan K. Hubbard 
6318cc36fbSJordan K. Hubbard         if (boolean(value(VERBOSE)))
6418cc36fbSJordan K. Hubbard                 printf("\nstarting call...");
6518cc36fbSJordan K. Hubbard #ifdef DEBUG
6618cc36fbSJordan K. Hubbard         printf ("(acu=%s)\n", acu);
6718cc36fbSJordan K. Hubbard #endif
6818cc36fbSJordan K. Hubbard         if ((AC = open(acu, O_RDWR)) < 0) {
6918cc36fbSJordan K. Hubbard                 if (errno == EBUSY)
7018cc36fbSJordan K. Hubbard                         printf("line busy...");
7118cc36fbSJordan K. Hubbard                 else
7218cc36fbSJordan K. Hubbard                         printf("acu open error...");
7318cc36fbSJordan K. Hubbard                 return (0);
7418cc36fbSJordan K. Hubbard         }
7518cc36fbSJordan K. Hubbard         if (setjmp(jmpbuf)) {
7618cc36fbSJordan K. Hubbard                 kill(child, SIGKILL);
7718cc36fbSJordan K. Hubbard                 close(AC);
7818cc36fbSJordan K. Hubbard                 return (0);
7918cc36fbSJordan K. Hubbard         }
8018cc36fbSJordan K. Hubbard         signal(SIGALRM, alarmtr);
8118cc36fbSJordan K. Hubbard         timelim = 5 * strlen(num);
8218cc36fbSJordan K. Hubbard         alarm(timelim < 30 ? 30 : timelim);
8318cc36fbSJordan K. Hubbard         if ((child = fork()) == 0) {
8418cc36fbSJordan K. Hubbard                 /*
8518cc36fbSJordan K. Hubbard                  * ignore this stuff for aborts
8618cc36fbSJordan K. Hubbard                  */
8718cc36fbSJordan K. Hubbard                 signal(SIGALRM, SIG_IGN);
8818cc36fbSJordan K. Hubbard 		signal(SIGINT, SIG_IGN);
8918cc36fbSJordan K. Hubbard                 signal(SIGQUIT, SIG_IGN);
9018cc36fbSJordan K. Hubbard                 sleep(2);
9118cc36fbSJordan K. Hubbard                 exit(dialit(num, acu) != 'A');
9218cc36fbSJordan K. Hubbard         }
9318cc36fbSJordan K. Hubbard         /*
9418cc36fbSJordan K. Hubbard          * open line - will return on carrier
9518cc36fbSJordan K. Hubbard          */
9618cc36fbSJordan K. Hubbard         if ((FD = open(DV, O_RDWR)) < 0) {
9718cc36fbSJordan K. Hubbard #ifdef DEBUG
9818cc36fbSJordan K. Hubbard                 printf("(after open, errno=%d)\n", errno);
9918cc36fbSJordan K. Hubbard #endif
10018cc36fbSJordan K. Hubbard                 if (errno == EIO)
10118cc36fbSJordan K. Hubbard                         printf("lost carrier...");
10218cc36fbSJordan K. Hubbard                 else
10318cc36fbSJordan K. Hubbard                         printf("dialup line open failed...");
10418cc36fbSJordan K. Hubbard                 alarm(0);
10518cc36fbSJordan K. Hubbard                 kill(child, SIGKILL);
10618cc36fbSJordan K. Hubbard                 close(AC);
10718cc36fbSJordan K. Hubbard                 return (0);
10818cc36fbSJordan K. Hubbard         }
10918cc36fbSJordan K. Hubbard         alarm(0);
11018cc36fbSJordan K. Hubbard         signal(SIGALRM, SIG_DFL);
11118cc36fbSJordan K. Hubbard         while ((pid = wait(&status)) != child && pid != -1)
11218cc36fbSJordan K. Hubbard                 ;
11318cc36fbSJordan K. Hubbard         if (status) {
11418cc36fbSJordan K. Hubbard                 close(AC);
11518cc36fbSJordan K. Hubbard                 return (0);
11618cc36fbSJordan K. Hubbard         }
11718cc36fbSJordan K. Hubbard         return (1);
11818cc36fbSJordan K. Hubbard }
11918cc36fbSJordan K. Hubbard 
120fa92e883SRuslan Ermilov /*ARGSUSED*/
12118cc36fbSJordan K. Hubbard static void
122fa92e883SRuslan Ermilov alarmtr(int signo)
12318cc36fbSJordan K. Hubbard {
12418cc36fbSJordan K. Hubbard         alarm(0);
12518cc36fbSJordan K. Hubbard         longjmp(jmpbuf, 1);
12618cc36fbSJordan K. Hubbard }
12718cc36fbSJordan K. Hubbard 
12818cc36fbSJordan K. Hubbard /*
12918cc36fbSJordan K. Hubbard  * Insurance, for some reason we don't seem to be
13018cc36fbSJordan K. Hubbard  *  hanging up...
13118cc36fbSJordan K. Hubbard  */
1320f3bdf5dSMark Murray void
133fa92e883SRuslan Ermilov v831_disconnect(void)
13418cc36fbSJordan K. Hubbard {
1350f3bdf5dSMark Murray 	struct termios	cntrl;
1360f3bdf5dSMark Murray 
13718cc36fbSJordan K. Hubbard         sleep(2);
13818cc36fbSJordan K. Hubbard #ifdef DEBUG
13918cc36fbSJordan K. Hubbard         printf("[disconnect: FD=%d]\n", FD);
14018cc36fbSJordan K. Hubbard #endif
14118cc36fbSJordan K. Hubbard         if (FD > 0) {
14218cc36fbSJordan K. Hubbard                 ioctl(FD, TIOCCDTR, 0);
1430f3bdf5dSMark Murray 		tcgetattr(FD, &cntrl);
1440f3bdf5dSMark Murray 		cfsetospeed(&cntrl, 0);
1450f3bdf5dSMark Murray 		cfsetispeed(&cntrl, 0);
1460f3bdf5dSMark Murray 		tcsetattr(FD, TCSAFLUSH, &cntrl);
1470f3bdf5dSMark Murray                 ioctl(FD, TIOCNXCL, NULL);
14818cc36fbSJordan K. Hubbard         }
14918cc36fbSJordan K. Hubbard         close(FD);
15018cc36fbSJordan K. Hubbard }
15118cc36fbSJordan K. Hubbard 
1520f3bdf5dSMark Murray void
153fa92e883SRuslan Ermilov v831_abort(void)
15418cc36fbSJordan K. Hubbard {
15518cc36fbSJordan K. Hubbard #ifdef DEBUG
15618cc36fbSJordan K. Hubbard         printf("[abort: AC=%d]\n", AC);
15718cc36fbSJordan K. Hubbard #endif
15818cc36fbSJordan K. Hubbard         sleep(2);
15918cc36fbSJordan K. Hubbard         if (child > 0)
16018cc36fbSJordan K. Hubbard                 kill(child, SIGKILL);
161fa92e883SRuslan Ermilov         if (FD > 0)
1620f3bdf5dSMark Murray                 ioctl(FD, TIOCNXCL, NULL);
16318cc36fbSJordan K. Hubbard         close(AC);
16418cc36fbSJordan K. Hubbard         if (FD > 0)
16518cc36fbSJordan K. Hubbard                 ioctl(FD, TIOCCDTR, 0);
16618cc36fbSJordan K. Hubbard         close(FD);
16718cc36fbSJordan K. Hubbard }
16818cc36fbSJordan K. Hubbard 
16918cc36fbSJordan K. Hubbard /*
17018cc36fbSJordan K. Hubbard  * Sigh, this probably must be changed at each site.
17118cc36fbSJordan K. Hubbard  */
17218cc36fbSJordan K. Hubbard struct vaconfig {
17318cc36fbSJordan K. Hubbard 	char	*vc_name;
17418cc36fbSJordan K. Hubbard 	char	vc_rack;
17518cc36fbSJordan K. Hubbard 	char	vc_modem;
17618cc36fbSJordan K. Hubbard } vaconfig[] = {
17718cc36fbSJordan K. Hubbard 	{ "/dev/cua0",'4','0' },
17818cc36fbSJordan K. Hubbard 	{ "/dev/cua1",'4','1' },
17907bb01e3SRuslan Ermilov 	{ NULL, '\0', '\0' }
18018cc36fbSJordan K. Hubbard };
18118cc36fbSJordan K. Hubbard 
18218cc36fbSJordan K. Hubbard #define pc(x)	(c = x, write(AC,&c,1))
18318cc36fbSJordan K. Hubbard #define ABORT	01
18418cc36fbSJordan K. Hubbard #define SI	017
18518cc36fbSJordan K. Hubbard #define STX	02
18618cc36fbSJordan K. Hubbard #define ETX	03
18718cc36fbSJordan K. Hubbard 
18818cc36fbSJordan K. Hubbard static int
189fa92e883SRuslan Ermilov dialit(char *phonenum, char *acu)
19018cc36fbSJordan K. Hubbard {
1910f3bdf5dSMark Murray         struct vaconfig *vp;
1920f3bdf5dSMark Murray 	struct termios cntrl;
19318cc36fbSJordan K. Hubbard         char c;
1940f3bdf5dSMark Murray         int i;
19518cc36fbSJordan K. Hubbard 
19618cc36fbSJordan K. Hubbard         phonenum = sanitize(phonenum);
19718cc36fbSJordan K. Hubbard #ifdef DEBUG
19818cc36fbSJordan K. Hubbard         printf ("(dial phonenum=%s)\n", phonenum);
19918cc36fbSJordan K. Hubbard #endif
20018cc36fbSJordan K. Hubbard         if (*phonenum == '<' && phonenum[1] == 0)
20118cc36fbSJordan K. Hubbard                 return ('Z');
20218cc36fbSJordan K. Hubbard 	for (vp = vaconfig; vp->vc_name; vp++)
20318cc36fbSJordan K. Hubbard 		if (strcmp(vp->vc_name, acu) == 0)
20418cc36fbSJordan K. Hubbard 			break;
20518cc36fbSJordan K. Hubbard 	if (vp->vc_name == 0) {
20618cc36fbSJordan K. Hubbard 		printf("Unable to locate dialer (%s)\n", acu);
20718cc36fbSJordan K. Hubbard 		return ('K');
20818cc36fbSJordan K. Hubbard 	}
2090f3bdf5dSMark Murray 	tcgetattr(AC, &cntrl);
2100f3bdf5dSMark Murray 	cfsetospeed(&cntrl, B2400);
2110f3bdf5dSMark Murray 	cfsetispeed(&cntrl, B2400);
2120f3bdf5dSMark Murray 	cntrl.c_cflag |= PARODD | PARENB;
2130f3bdf5dSMark Murray 	cntrl.c_lflag &= ~(ISIG | ICANON);
2140f3bdf5dSMark Murray 	tcsetattr(AC, TCSANOW, &cntrl);
2150f3bdf5dSMark Murray 	tcflush(AC, TCIOFLUSH);
21618cc36fbSJordan K. Hubbard         pc(STX);
21718cc36fbSJordan K. Hubbard 	pc(vp->vc_rack);
21818cc36fbSJordan K. Hubbard 	pc(vp->vc_modem);
21918cc36fbSJordan K. Hubbard 	while (*phonenum && *phonenum != '<')
22018cc36fbSJordan K. Hubbard 		pc(*phonenum++);
22118cc36fbSJordan K. Hubbard         pc(SI);
22218cc36fbSJordan K. Hubbard 	pc(ETX);
22318cc36fbSJordan K. Hubbard         sleep(1);
22418cc36fbSJordan K. Hubbard         i = read(AC, &c, 1);
22518cc36fbSJordan K. Hubbard #ifdef DEBUG
22618cc36fbSJordan K. Hubbard         printf("read %d chars, char=%c, errno %d\n", i, c, errno);
22718cc36fbSJordan K. Hubbard #endif
22818cc36fbSJordan K. Hubbard         if (i != 1)
22918cc36fbSJordan K. Hubbard 		c = 'M';
23018cc36fbSJordan K. Hubbard         if (c == 'B' || c == 'G') {
23118cc36fbSJordan K. Hubbard                 char cc, oc = c;
23218cc36fbSJordan K. Hubbard 
23318cc36fbSJordan K. Hubbard                 pc(ABORT);
23418cc36fbSJordan K. Hubbard                 read(AC, &cc, 1);
23518cc36fbSJordan K. Hubbard #ifdef DEBUG
23618cc36fbSJordan K. Hubbard                 printf("abort response=%c\n", cc);
23718cc36fbSJordan K. Hubbard #endif
23818cc36fbSJordan K. Hubbard                 c = oc;
23918cc36fbSJordan K. Hubbard                 v831_disconnect();
24018cc36fbSJordan K. Hubbard         }
24118cc36fbSJordan K. Hubbard         close(AC);
24218cc36fbSJordan K. Hubbard #ifdef DEBUG
24318cc36fbSJordan K. Hubbard         printf("dialit: returns %c\n", c);
24418cc36fbSJordan K. Hubbard #endif
24518cc36fbSJordan K. Hubbard         return (c);
24618cc36fbSJordan K. Hubbard }
24718cc36fbSJordan K. Hubbard 
24818cc36fbSJordan K. Hubbard static char *
249fa92e883SRuslan Ermilov sanitize(char *s)
25018cc36fbSJordan K. Hubbard {
25118cc36fbSJordan K. Hubbard         static char buf[128];
2520f3bdf5dSMark Murray         char *cp;
25318cc36fbSJordan K. Hubbard 
25418cc36fbSJordan K. Hubbard         for (cp = buf; *s; s++) {
25518cc36fbSJordan K. Hubbard 		if (!isdigit(*s) && *s == '<' && *s != '_')
25618cc36fbSJordan K. Hubbard 			continue;
25718cc36fbSJordan K. Hubbard 		if (*s == '_')
25818cc36fbSJordan K. Hubbard 			*s = '=';
25918cc36fbSJordan K. Hubbard 		*cp++ = *s;
26018cc36fbSJordan K. Hubbard 	}
26118cc36fbSJordan K. Hubbard         *cp++ = 0;
26218cc36fbSJordan K. Hubbard         return (buf);
26318cc36fbSJordan K. Hubbard }
264