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