xref: /freebsd/usr.bin/tip/libacu/v831.c (revision 8a16b7a18f5d0b031f09832fd7752fba717e2a97)
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 
4*8a16b7a1SPedro F. Giffuni /*-
5*8a16b7a1SPedro F. Giffuni  * SPDX-License-Identifier: BSD-3-Clause
6*8a16b7a1SPedro F. Giffuni  *
718cc36fbSJordan K. Hubbard  * Copyright (c) 1983, 1993
818cc36fbSJordan K. Hubbard  *	The Regents of the University of California.  All rights reserved.
918cc36fbSJordan K. Hubbard  *
1018cc36fbSJordan K. Hubbard  * Redistribution and use in source and binary forms, with or without
1118cc36fbSJordan K. Hubbard  * modification, are permitted provided that the following conditions
1218cc36fbSJordan K. Hubbard  * are met:
1318cc36fbSJordan K. Hubbard  * 1. Redistributions of source code must retain the above copyright
1418cc36fbSJordan K. Hubbard  *    notice, this list of conditions and the following disclaimer.
1518cc36fbSJordan K. Hubbard  * 2. Redistributions in binary form must reproduce the above copyright
1618cc36fbSJordan K. Hubbard  *    notice, this list of conditions and the following disclaimer in the
1718cc36fbSJordan K. Hubbard  *    documentation and/or other materials provided with the distribution.
18fa92e883SRuslan Ermilov  * 3. Neither the name of the University nor the names of its contributors
1918cc36fbSJordan K. Hubbard  *    may be used to endorse or promote products derived from this software
2018cc36fbSJordan K. Hubbard  *    without specific prior written permission.
2118cc36fbSJordan K. Hubbard  *
2218cc36fbSJordan K. Hubbard  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2318cc36fbSJordan K. Hubbard  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2418cc36fbSJordan K. Hubbard  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2518cc36fbSJordan K. Hubbard  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2618cc36fbSJordan K. Hubbard  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2718cc36fbSJordan K. Hubbard  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2818cc36fbSJordan K. Hubbard  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2918cc36fbSJordan K. Hubbard  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3018cc36fbSJordan K. Hubbard  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3118cc36fbSJordan K. Hubbard  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3218cc36fbSJordan K. Hubbard  * SUCH DAMAGE.
3318cc36fbSJordan K. Hubbard  */
3418cc36fbSJordan K. Hubbard 
3565785b55SMark Murray #include <sys/cdefs.h>
3665785b55SMark Murray __FBSDID("$FreeBSD$");
3765785b55SMark Murray 
3818cc36fbSJordan K. Hubbard #ifndef lint
390f3bdf5dSMark Murray #if 0
4018cc36fbSJordan K. Hubbard static char sccsid[] = "@(#)v831.c	8.1 (Berkeley) 6/6/93";
41fa92e883SRuslan Ermilov static const char rcsid[] = "$OpenBSD: v831.c,v 1.11 2006/03/17 19:17:13 moritz Exp $";
4265785b55SMark Murray #endif
4318cc36fbSJordan K. Hubbard #endif /* not lint */
4418cc36fbSJordan K. Hubbard 
4518cc36fbSJordan K. Hubbard /*
4618cc36fbSJordan K. Hubbard  * Routines for dialing up on Vadic 831
4718cc36fbSJordan K. Hubbard  */
4818cc36fbSJordan K. Hubbard #include "tip.h"
490f3bdf5dSMark Murray #include <termios.h>
5018cc36fbSJordan K. Hubbard 
5118cc36fbSJordan K. Hubbard static jmp_buf jmpbuf;
52fa92e883SRuslan Ermilov static pid_t child = -1;
53fa92e883SRuslan Ermilov 
54fa92e883SRuslan Ermilov static void	alarmtr(int);
55fa92e883SRuslan Ermilov static int	dialit(char *, char *);
56fa92e883SRuslan Ermilov static char *	sanitize(char *);
5718cc36fbSJordan K. Hubbard 
580f3bdf5dSMark Murray int
59fa92e883SRuslan Ermilov v831_dialer(char *num, char *acu)
6018cc36fbSJordan K. Hubbard {
61fa92e883SRuslan Ermilov         int status;
620f3bdf5dSMark Murray         int timelim;
63fa92e883SRuslan Ermilov 	pid_t pid;
6418cc36fbSJordan K. Hubbard 
6518cc36fbSJordan K. Hubbard         if (boolean(value(VERBOSE)))
6618cc36fbSJordan K. Hubbard                 printf("\nstarting call...");
6718cc36fbSJordan K. Hubbard #ifdef DEBUG
6818cc36fbSJordan K. Hubbard         printf ("(acu=%s)\n", acu);
6918cc36fbSJordan K. Hubbard #endif
7018cc36fbSJordan K. Hubbard         if ((AC = open(acu, O_RDWR)) < 0) {
7118cc36fbSJordan K. Hubbard                 if (errno == EBUSY)
7218cc36fbSJordan K. Hubbard                         printf("line busy...");
7318cc36fbSJordan K. Hubbard                 else
7418cc36fbSJordan K. Hubbard                         printf("acu open error...");
7518cc36fbSJordan K. Hubbard                 return (0);
7618cc36fbSJordan K. Hubbard         }
7718cc36fbSJordan K. Hubbard         if (setjmp(jmpbuf)) {
7818cc36fbSJordan K. Hubbard                 kill(child, SIGKILL);
7918cc36fbSJordan K. Hubbard                 close(AC);
8018cc36fbSJordan K. Hubbard                 return (0);
8118cc36fbSJordan K. Hubbard         }
8218cc36fbSJordan K. Hubbard         signal(SIGALRM, alarmtr);
8318cc36fbSJordan K. Hubbard         timelim = 5 * strlen(num);
8418cc36fbSJordan K. Hubbard         alarm(timelim < 30 ? 30 : timelim);
8518cc36fbSJordan K. Hubbard         if ((child = fork()) == 0) {
8618cc36fbSJordan K. Hubbard                 /*
8718cc36fbSJordan K. Hubbard                  * ignore this stuff for aborts
8818cc36fbSJordan K. Hubbard                  */
8918cc36fbSJordan K. Hubbard                 signal(SIGALRM, SIG_IGN);
9018cc36fbSJordan K. Hubbard 		signal(SIGINT, SIG_IGN);
9118cc36fbSJordan K. Hubbard                 signal(SIGQUIT, SIG_IGN);
9218cc36fbSJordan K. Hubbard                 sleep(2);
9318cc36fbSJordan K. Hubbard                 exit(dialit(num, acu) != 'A');
9418cc36fbSJordan K. Hubbard         }
9518cc36fbSJordan K. Hubbard         /*
9618cc36fbSJordan K. Hubbard          * open line - will return on carrier
9718cc36fbSJordan K. Hubbard          */
9818cc36fbSJordan K. Hubbard         if ((FD = open(DV, O_RDWR)) < 0) {
9918cc36fbSJordan K. Hubbard #ifdef DEBUG
10018cc36fbSJordan K. Hubbard                 printf("(after open, errno=%d)\n", errno);
10118cc36fbSJordan K. Hubbard #endif
10218cc36fbSJordan K. Hubbard                 if (errno == EIO)
10318cc36fbSJordan K. Hubbard                         printf("lost carrier...");
10418cc36fbSJordan K. Hubbard                 else
10518cc36fbSJordan K. Hubbard                         printf("dialup line open failed...");
10618cc36fbSJordan K. Hubbard                 alarm(0);
10718cc36fbSJordan K. Hubbard                 kill(child, SIGKILL);
10818cc36fbSJordan K. Hubbard                 close(AC);
10918cc36fbSJordan K. Hubbard                 return (0);
11018cc36fbSJordan K. Hubbard         }
11118cc36fbSJordan K. Hubbard         alarm(0);
11218cc36fbSJordan K. Hubbard         signal(SIGALRM, SIG_DFL);
11318cc36fbSJordan K. Hubbard         while ((pid = wait(&status)) != child && pid != -1)
11418cc36fbSJordan K. Hubbard                 ;
11518cc36fbSJordan K. Hubbard         if (status) {
11618cc36fbSJordan K. Hubbard                 close(AC);
11718cc36fbSJordan K. Hubbard                 return (0);
11818cc36fbSJordan K. Hubbard         }
11918cc36fbSJordan K. Hubbard         return (1);
12018cc36fbSJordan K. Hubbard }
12118cc36fbSJordan K. Hubbard 
122fa92e883SRuslan Ermilov /*ARGSUSED*/
12318cc36fbSJordan K. Hubbard static void
124fa92e883SRuslan Ermilov alarmtr(int signo)
12518cc36fbSJordan K. Hubbard {
12618cc36fbSJordan K. Hubbard         alarm(0);
12718cc36fbSJordan K. Hubbard         longjmp(jmpbuf, 1);
12818cc36fbSJordan K. Hubbard }
12918cc36fbSJordan K. Hubbard 
13018cc36fbSJordan K. Hubbard /*
13118cc36fbSJordan K. Hubbard  * Insurance, for some reason we don't seem to be
13218cc36fbSJordan K. Hubbard  *  hanging up...
13318cc36fbSJordan K. Hubbard  */
1340f3bdf5dSMark Murray void
135fa92e883SRuslan Ermilov v831_disconnect(void)
13618cc36fbSJordan K. Hubbard {
1370f3bdf5dSMark Murray 	struct termios	cntrl;
1380f3bdf5dSMark Murray 
13918cc36fbSJordan K. Hubbard         sleep(2);
14018cc36fbSJordan K. Hubbard #ifdef DEBUG
14118cc36fbSJordan K. Hubbard         printf("[disconnect: FD=%d]\n", FD);
14218cc36fbSJordan K. Hubbard #endif
14318cc36fbSJordan K. Hubbard         if (FD > 0) {
14418cc36fbSJordan K. Hubbard                 ioctl(FD, TIOCCDTR, 0);
1450f3bdf5dSMark Murray 		tcgetattr(FD, &cntrl);
1460f3bdf5dSMark Murray 		cfsetospeed(&cntrl, 0);
1470f3bdf5dSMark Murray 		cfsetispeed(&cntrl, 0);
1480f3bdf5dSMark Murray 		tcsetattr(FD, TCSAFLUSH, &cntrl);
1490f3bdf5dSMark Murray                 ioctl(FD, TIOCNXCL, NULL);
15018cc36fbSJordan K. Hubbard         }
15118cc36fbSJordan K. Hubbard         close(FD);
15218cc36fbSJordan K. Hubbard }
15318cc36fbSJordan K. Hubbard 
1540f3bdf5dSMark Murray void
155fa92e883SRuslan Ermilov v831_abort(void)
15618cc36fbSJordan K. Hubbard {
15718cc36fbSJordan K. Hubbard #ifdef DEBUG
15818cc36fbSJordan K. Hubbard         printf("[abort: AC=%d]\n", AC);
15918cc36fbSJordan K. Hubbard #endif
16018cc36fbSJordan K. Hubbard         sleep(2);
16118cc36fbSJordan K. Hubbard         if (child > 0)
16218cc36fbSJordan K. Hubbard                 kill(child, SIGKILL);
163fa92e883SRuslan Ermilov         if (FD > 0)
1640f3bdf5dSMark Murray                 ioctl(FD, TIOCNXCL, NULL);
16518cc36fbSJordan K. Hubbard         close(AC);
16618cc36fbSJordan K. Hubbard         if (FD > 0)
16718cc36fbSJordan K. Hubbard                 ioctl(FD, TIOCCDTR, 0);
16818cc36fbSJordan K. Hubbard         close(FD);
16918cc36fbSJordan K. Hubbard }
17018cc36fbSJordan K. Hubbard 
17118cc36fbSJordan K. Hubbard /*
17218cc36fbSJordan K. Hubbard  * Sigh, this probably must be changed at each site.
17318cc36fbSJordan K. Hubbard  */
17418cc36fbSJordan K. Hubbard struct vaconfig {
17518cc36fbSJordan K. Hubbard 	char	*vc_name;
17618cc36fbSJordan K. Hubbard 	char	vc_rack;
17718cc36fbSJordan K. Hubbard 	char	vc_modem;
17818cc36fbSJordan K. Hubbard } vaconfig[] = {
17918cc36fbSJordan K. Hubbard 	{ "/dev/cua0",'4','0' },
18018cc36fbSJordan K. Hubbard 	{ "/dev/cua1",'4','1' },
18107bb01e3SRuslan Ermilov 	{ NULL, '\0', '\0' }
18218cc36fbSJordan K. Hubbard };
18318cc36fbSJordan K. Hubbard 
18418cc36fbSJordan K. Hubbard #define pc(x)	(c = x, write(AC,&c,1))
18518cc36fbSJordan K. Hubbard #define ABORT	01
18618cc36fbSJordan K. Hubbard #define SI	017
18718cc36fbSJordan K. Hubbard #define STX	02
18818cc36fbSJordan K. Hubbard #define ETX	03
18918cc36fbSJordan K. Hubbard 
19018cc36fbSJordan K. Hubbard static int
191fa92e883SRuslan Ermilov dialit(char *phonenum, char *acu)
19218cc36fbSJordan K. Hubbard {
1930f3bdf5dSMark Murray         struct vaconfig *vp;
1940f3bdf5dSMark Murray 	struct termios cntrl;
19518cc36fbSJordan K. Hubbard         char c;
1960f3bdf5dSMark Murray         int i;
19718cc36fbSJordan K. Hubbard 
19818cc36fbSJordan K. Hubbard         phonenum = sanitize(phonenum);
19918cc36fbSJordan K. Hubbard #ifdef DEBUG
20018cc36fbSJordan K. Hubbard         printf ("(dial phonenum=%s)\n", phonenum);
20118cc36fbSJordan K. Hubbard #endif
20218cc36fbSJordan K. Hubbard         if (*phonenum == '<' && phonenum[1] == 0)
20318cc36fbSJordan K. Hubbard                 return ('Z');
20418cc36fbSJordan K. Hubbard 	for (vp = vaconfig; vp->vc_name; vp++)
20518cc36fbSJordan K. Hubbard 		if (strcmp(vp->vc_name, acu) == 0)
20618cc36fbSJordan K. Hubbard 			break;
20718cc36fbSJordan K. Hubbard 	if (vp->vc_name == 0) {
20818cc36fbSJordan K. Hubbard 		printf("Unable to locate dialer (%s)\n", acu);
20918cc36fbSJordan K. Hubbard 		return ('K');
21018cc36fbSJordan K. Hubbard 	}
2110f3bdf5dSMark Murray 	tcgetattr(AC, &cntrl);
2120f3bdf5dSMark Murray 	cfsetospeed(&cntrl, B2400);
2130f3bdf5dSMark Murray 	cfsetispeed(&cntrl, B2400);
2140f3bdf5dSMark Murray 	cntrl.c_cflag |= PARODD | PARENB;
2150f3bdf5dSMark Murray 	cntrl.c_lflag &= ~(ISIG | ICANON);
2160f3bdf5dSMark Murray 	tcsetattr(AC, TCSANOW, &cntrl);
2170f3bdf5dSMark Murray 	tcflush(AC, TCIOFLUSH);
21818cc36fbSJordan K. Hubbard         pc(STX);
21918cc36fbSJordan K. Hubbard 	pc(vp->vc_rack);
22018cc36fbSJordan K. Hubbard 	pc(vp->vc_modem);
22118cc36fbSJordan K. Hubbard 	while (*phonenum && *phonenum != '<')
22218cc36fbSJordan K. Hubbard 		pc(*phonenum++);
22318cc36fbSJordan K. Hubbard         pc(SI);
22418cc36fbSJordan K. Hubbard 	pc(ETX);
22518cc36fbSJordan K. Hubbard         sleep(1);
22618cc36fbSJordan K. Hubbard         i = read(AC, &c, 1);
22718cc36fbSJordan K. Hubbard #ifdef DEBUG
22818cc36fbSJordan K. Hubbard         printf("read %d chars, char=%c, errno %d\n", i, c, errno);
22918cc36fbSJordan K. Hubbard #endif
23018cc36fbSJordan K. Hubbard         if (i != 1)
23118cc36fbSJordan K. Hubbard 		c = 'M';
23218cc36fbSJordan K. Hubbard         if (c == 'B' || c == 'G') {
23318cc36fbSJordan K. Hubbard                 char cc, oc = c;
23418cc36fbSJordan K. Hubbard 
23518cc36fbSJordan K. Hubbard                 pc(ABORT);
23618cc36fbSJordan K. Hubbard                 read(AC, &cc, 1);
23718cc36fbSJordan K. Hubbard #ifdef DEBUG
23818cc36fbSJordan K. Hubbard                 printf("abort response=%c\n", cc);
23918cc36fbSJordan K. Hubbard #endif
24018cc36fbSJordan K. Hubbard                 c = oc;
24118cc36fbSJordan K. Hubbard                 v831_disconnect();
24218cc36fbSJordan K. Hubbard         }
24318cc36fbSJordan K. Hubbard         close(AC);
24418cc36fbSJordan K. Hubbard #ifdef DEBUG
24518cc36fbSJordan K. Hubbard         printf("dialit: returns %c\n", c);
24618cc36fbSJordan K. Hubbard #endif
24718cc36fbSJordan K. Hubbard         return (c);
24818cc36fbSJordan K. Hubbard }
24918cc36fbSJordan K. Hubbard 
25018cc36fbSJordan K. Hubbard static char *
251fa92e883SRuslan Ermilov sanitize(char *s)
25218cc36fbSJordan K. Hubbard {
25318cc36fbSJordan K. Hubbard         static char buf[128];
2540f3bdf5dSMark Murray         char *cp;
25518cc36fbSJordan K. Hubbard 
25618cc36fbSJordan K. Hubbard         for (cp = buf; *s; s++) {
25718cc36fbSJordan K. Hubbard 		if (!isdigit(*s) && *s == '<' && *s != '_')
25818cc36fbSJordan K. Hubbard 			continue;
25918cc36fbSJordan K. Hubbard 		if (*s == '_')
26018cc36fbSJordan K. Hubbard 			*s = '=';
26118cc36fbSJordan K. Hubbard 		*cp++ = *s;
26218cc36fbSJordan K. Hubbard 	}
26318cc36fbSJordan K. Hubbard         *cp++ = 0;
26418cc36fbSJordan K. Hubbard         return (buf);
26518cc36fbSJordan K. Hubbard }
266