xref: /netbsd-src/usr.bin/tip/aculib/v831.c (revision dc73bb47b8fa1be342344b067df642a1bf20a254)
1*dc73bb47Sdholland /*	$NetBSD: v831.c,v 1.13 2016/06/30 05:56:46 dholland Exp $	*/
239801cccSjtc 
361f28255Scgd /*
439801cccSjtc  * Copyright (c) 1983, 1993
539801cccSjtc  *	The Regents of the University of California.  All rights reserved.
661f28255Scgd  *
761f28255Scgd  * Redistribution and use in source and binary forms, with or without
861f28255Scgd  * modification, are permitted provided that the following conditions
961f28255Scgd  * are met:
1061f28255Scgd  * 1. Redistributions of source code must retain the above copyright
1161f28255Scgd  *    notice, this list of conditions and the following disclaimer.
1261f28255Scgd  * 2. Redistributions in binary form must reproduce the above copyright
1361f28255Scgd  *    notice, this list of conditions and the following disclaimer in the
1461f28255Scgd  *    documentation and/or other materials provided with the distribution.
1589aaa1bbSagc  * 3. Neither the name of the University nor the names of its contributors
1661f28255Scgd  *    may be used to endorse or promote products derived from this software
1761f28255Scgd  *    without specific prior written permission.
1861f28255Scgd  *
1961f28255Scgd  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2061f28255Scgd  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2161f28255Scgd  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2261f28255Scgd  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2361f28255Scgd  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2461f28255Scgd  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2561f28255Scgd  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2661f28255Scgd  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2761f28255Scgd  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2861f28255Scgd  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2961f28255Scgd  * SUCH DAMAGE.
3061f28255Scgd  */
3161f28255Scgd 
32e37283e1Slukem #include <sys/cdefs.h>
3361f28255Scgd #ifndef lint
3439801cccSjtc #if 0
3539801cccSjtc static char sccsid[] = "@(#)v831.c	8.1 (Berkeley) 6/6/93";
3639801cccSjtc #endif
37*dc73bb47Sdholland __RCSID("$NetBSD: v831.c,v 1.13 2016/06/30 05:56:46 dholland Exp $");
3861f28255Scgd #endif /* not lint */
3961f28255Scgd 
4061f28255Scgd /*
4161f28255Scgd  * Routines for dialing up on Vadic 831
4261f28255Scgd  */
4361f28255Scgd #include "tip.h"
4461f28255Scgd 
4561f28255Scgd static jmp_buf jmpbuf;
4661f28255Scgd static int child = -1;
4761f28255Scgd 
4858c2151fSperry static	void	alarmtr(int);
4958c2151fSperry static	int	dialit(char *, char *);
5058c2151fSperry static	char   *sanitize(char *);
51e37283e1Slukem 
52e37283e1Slukem int
v831_dialer(char * num,char * acu)5358c2151fSperry v831_dialer(char *num, char *acu)
5461f28255Scgd {
554f6045fcSchristos         int status, mypid;
56e37283e1Slukem         int timelim;
5761f28255Scgd 
5861f28255Scgd         if (boolean(value(VERBOSE)))
59ffe34450Schristos                 (void)printf("\nstarting call...");
6061f28255Scgd #ifdef DEBUG
61ffe34450Schristos         (void)printf("(acu=%s)\n", acu);
6261f28255Scgd #endif
6361f28255Scgd         if ((AC = open(acu, O_RDWR)) < 0) {
6461f28255Scgd                 if (errno == EBUSY)
65ffe34450Schristos                         (void)printf("line busy...");
6661f28255Scgd                 else
67ffe34450Schristos                         (void)printf("acu open error...");
6861f28255Scgd                 return (0);
6961f28255Scgd         }
7061f28255Scgd         if (setjmp(jmpbuf)) {
71ffe34450Schristos 		(void)kill(child, SIGKILL);
72ffe34450Schristos 		(void)close(AC);
7361f28255Scgd                 return (0);
7461f28255Scgd         }
75ffe34450Schristos         (void)signal(SIGALRM, alarmtr);
7661f28255Scgd         timelim = 5 * strlen(num);
77ffe34450Schristos         (void)alarm((unsigned)(timelim < 30 ? 30 : timelim));
7861f28255Scgd         if ((child = fork()) == 0) {
7961f28255Scgd                 /*
8061f28255Scgd                  * ignore this stuff for aborts
8161f28255Scgd                  */
82ffe34450Schristos                 (void)signal(SIGALRM, SIG_IGN);
83ffe34450Schristos 		(void)signal(SIGINT, SIG_IGN);
84ffe34450Schristos                 (void)signal(SIGQUIT, SIG_IGN);
85ffe34450Schristos                 (void)sleep(2);
8661f28255Scgd                 exit(dialit(num, acu) != 'A');
8761f28255Scgd         }
8861f28255Scgd         /*
8961f28255Scgd          * open line - will return on carrier
9061f28255Scgd          */
9161f28255Scgd         if ((FD = open(DV, O_RDWR)) < 0) {
9261f28255Scgd #ifdef DEBUG
93ffe34450Schristos                 (void)printf("(after open, errno=%d)\n", errno);
9461f28255Scgd #endif
9561f28255Scgd                 if (errno == EIO)
96ffe34450Schristos                         (void)printf("lost carrier...");
9761f28255Scgd                 else
98ffe34450Schristos                         (void)printf("dialup line open failed...");
99ffe34450Schristos                 (void)alarm(0);
100ffe34450Schristos                 (void)kill(child, SIGKILL);
101ffe34450Schristos                 (void)close(AC);
10261f28255Scgd                 return (0);
10361f28255Scgd         }
104ffe34450Schristos         (void)alarm(0);
105ffe34450Schristos         (void)signal(SIGALRM, SIG_DFL);
1064f6045fcSchristos         while ((mypid = wait(&status)) != child && mypid != -1)
10761f28255Scgd                 ;
10861f28255Scgd         if (status) {
109ffe34450Schristos                 (void)close(AC);
11061f28255Scgd                 return (0);
11161f28255Scgd         }
11261f28255Scgd         return (1);
11361f28255Scgd }
11461f28255Scgd 
11561f28255Scgd static void
116ffe34450Schristos /*ARGSUSED*/
alarmtr(int dummy __unused)117ffe34450Schristos alarmtr(int dummy __unused)
11861f28255Scgd {
11997eafd50Smrg 
120ffe34450Schristos         (void)alarm(0);
12161f28255Scgd         longjmp(jmpbuf, 1);
12261f28255Scgd }
12361f28255Scgd 
12461f28255Scgd /*
12561f28255Scgd  * Insurance, for some reason we don't seem to be
12661f28255Scgd  *  hanging up...
12761f28255Scgd  */
128e37283e1Slukem void
v831_disconnect(void)12958c2151fSperry v831_disconnect(void)
13061f28255Scgd {
131258108ceSpk 	struct termios	cntrl;
13261f28255Scgd 
133ffe34450Schristos         (void)sleep(2);
13461f28255Scgd #ifdef DEBUG
135ffe34450Schristos         (void)printf("[disconnect: FD=%d]\n", FD);
13661f28255Scgd #endif
13761f28255Scgd         if (FD > 0) {
138ffe34450Schristos                 (void)ioctl(FD, TIOCCDTR, 0);
139ffe34450Schristos 		(void)tcgetattr(FD, &cntrl);
140ffe34450Schristos 		(void)cfsetospeed(&cntrl, 0);
141ffe34450Schristos 		(void)cfsetispeed(&cntrl, 0);
142ffe34450Schristos 		(void)tcsetattr(FD, TCSAFLUSH, &cntrl);
143ffe34450Schristos                 (void)ioctl(FD, TIOCNXCL, NULL);
14461f28255Scgd         }
145ffe34450Schristos         (void)close(FD);
14661f28255Scgd }
14761f28255Scgd 
148e37283e1Slukem void
v831_abort(void)14958c2151fSperry v831_abort(void)
15061f28255Scgd {
15161f28255Scgd 
15261f28255Scgd #ifdef DEBUG
153ffe34450Schristos         (void)printf("[abort: AC=%d]\n", AC);
15461f28255Scgd #endif
155ffe34450Schristos         (void)sleep(2);
15661f28255Scgd         if (child > 0)
157ffe34450Schristos                 (void)kill(child, SIGKILL);
15861f28255Scgd         if (AC > 0)
159ffe34450Schristos                 (void)ioctl(FD, TIOCNXCL, NULL);
160ffe34450Schristos                 (void)close(AC);
16161f28255Scgd         if (FD > 0)
162ffe34450Schristos                 (void)ioctl(FD, TIOCCDTR, 0);
163ffe34450Schristos         (void)close(FD);
16461f28255Scgd }
16561f28255Scgd 
16661f28255Scgd /*
16761f28255Scgd  * Sigh, this probably must be changed at each site.
16861f28255Scgd  */
16961f28255Scgd struct vaconfig {
1704f6045fcSchristos 	const char	*vc_name;
17161f28255Scgd 	char	vc_rack;
17261f28255Scgd 	char	vc_modem;
17361f28255Scgd } vaconfig[] = {
17461f28255Scgd 	{ "/dev/cua0",'4','0' },
17561f28255Scgd 	{ "/dev/cua1",'4','1' },
176ffe34450Schristos 	{ 0, '\0', '\0' }
17761f28255Scgd };
17861f28255Scgd 
179ffe34450Schristos #define pc(x)	(void)(c = x, write(AC,&c,1))
18061f28255Scgd #define ABORT	01
18161f28255Scgd #define SI	017
18261f28255Scgd #define STX	02
18361f28255Scgd #define ETX	03
18461f28255Scgd 
18561f28255Scgd static int
dialit(char * phonenum,char * acu)18658c2151fSperry dialit(char *phonenum, char *acu)
18761f28255Scgd {
188e37283e1Slukem         struct vaconfig *vp;
189258108ceSpk 	struct termios cntrl;
19061f28255Scgd         char c;
191e37283e1Slukem         int i;
19261f28255Scgd 
19361f28255Scgd         phonenum = sanitize(phonenum);
19461f28255Scgd #ifdef DEBUG
195ffe34450Schristos         (void)printf("(dial phonenum=%s)\n", phonenum);
19661f28255Scgd #endif
19761f28255Scgd         if (*phonenum == '<' && phonenum[1] == 0)
19861f28255Scgd                 return ('Z');
19961f28255Scgd 	for (vp = vaconfig; vp->vc_name; vp++)
20061f28255Scgd 		if (strcmp(vp->vc_name, acu) == 0)
20161f28255Scgd 			break;
20261f28255Scgd 	if (vp->vc_name == 0) {
203ffe34450Schristos 		(void)printf("Unable to locate dialer (%s)\n", acu);
20461f28255Scgd 		return ('K');
20561f28255Scgd 	}
206ffe34450Schristos 	(void)tcgetattr(AC, &cntrl);
207ffe34450Schristos 	(void)cfsetospeed(&cntrl, B2400);
208ffe34450Schristos 	(void)cfsetispeed(&cntrl, B2400);
209258108ceSpk 	cntrl.c_cflag |= PARODD | PARENB;
210258108ceSpk 	cntrl.c_lflag &= ~(ISIG | ICANON);
211ffe34450Schristos 	(void)tcsetattr(AC, TCSANOW, &cntrl);
212ffe34450Schristos 	(void)tcflush(AC, TCIOFLUSH);
21361f28255Scgd         pc(STX);
21461f28255Scgd 	pc(vp->vc_rack);
21561f28255Scgd 	pc(vp->vc_modem);
21661f28255Scgd 	while (*phonenum && *phonenum != '<')
21761f28255Scgd 		pc(*phonenum++);
21861f28255Scgd         pc(SI);
21961f28255Scgd 	pc(ETX);
220ffe34450Schristos         (void)sleep(1);
22161f28255Scgd         i = read(AC, &c, 1);
22261f28255Scgd #ifdef DEBUG
223ffe34450Schristos         (void)printf("read %d chars, char=%c, errno %d\n", i, c, errno);
22461f28255Scgd #endif
22561f28255Scgd         if (i != 1)
22661f28255Scgd 		c = 'M';
22761f28255Scgd         if (c == 'B' || c == 'G') {
22861f28255Scgd                 char cc, oc = c;
22961f28255Scgd 
23061f28255Scgd                 pc(ABORT);
231ffe34450Schristos                 (void)read(AC, &cc, 1);
23261f28255Scgd #ifdef DEBUG
233ffe34450Schristos                 (void)printf("abort response=%c\n", cc);
23461f28255Scgd #endif
23561f28255Scgd                 c = oc;
23661f28255Scgd                 v831_disconnect();
23761f28255Scgd         }
238ffe34450Schristos         (void)close(AC);
23961f28255Scgd #ifdef DEBUG
240ffe34450Schristos         (void)printf("dialit: returns %c\n", c);
24161f28255Scgd #endif
24261f28255Scgd         return (c);
24361f28255Scgd }
24461f28255Scgd 
24561f28255Scgd static char *
sanitize(char * s)24658c2151fSperry sanitize(char *s)
24761f28255Scgd {
24861f28255Scgd         static char buf[128];
249e37283e1Slukem         char *cp;
25061f28255Scgd 
25197eafd50Smrg         for (cp = buf; *s && buf + sizeof buf - cp > 1; s++) {
252*dc73bb47Sdholland 		if (!isdigit((unsigned char)*s) && *s != '<' && *s != '_')
25361f28255Scgd 			continue;
25461f28255Scgd 		if (*s == '_')
25561f28255Scgd 			*s = '=';
25661f28255Scgd 		*cp++ = *s;
25761f28255Scgd 	}
25861f28255Scgd         *cp++ = 0;
25961f28255Scgd         return (buf);
26061f28255Scgd }
261