1161754Sru/*	$OpenBSD: v831.c,v 1.11 2006/03/17 19:17:13 moritz Exp $	*/
288276Smarkm/*	$NetBSD: v831.c,v 1.5 1996/12/29 10:42:01 cgd Exp $	*/
388276Smarkm
47527Sjkh/*
57527Sjkh * Copyright (c) 1983, 1993
67527Sjkh *	The Regents of the University of California.  All rights reserved.
77527Sjkh *
87527Sjkh * Redistribution and use in source and binary forms, with or without
97527Sjkh * modification, are permitted provided that the following conditions
107527Sjkh * are met:
117527Sjkh * 1. Redistributions of source code must retain the above copyright
127527Sjkh *    notice, this list of conditions and the following disclaimer.
137527Sjkh * 2. Redistributions in binary form must reproduce the above copyright
147527Sjkh *    notice, this list of conditions and the following disclaimer in the
157527Sjkh *    documentation and/or other materials provided with the distribution.
16161754Sru * 3. Neither the name of the University nor the names of its contributors
177527Sjkh *    may be used to endorse or promote products derived from this software
187527Sjkh *    without specific prior written permission.
197527Sjkh *
207527Sjkh * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
217527Sjkh * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
227527Sjkh * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
237527Sjkh * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
247527Sjkh * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
257527Sjkh * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
267527Sjkh * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
277527Sjkh * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
287527Sjkh * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
297527Sjkh * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
307527Sjkh * SUCH DAMAGE.
317527Sjkh */
327527Sjkh
3388276Smarkm#include <sys/cdefs.h>
3488276Smarkm__FBSDID("$FreeBSD$");
3588276Smarkm
367527Sjkh#ifndef lint
3788276Smarkm#if 0
387527Sjkhstatic char sccsid[] = "@(#)v831.c	8.1 (Berkeley) 6/6/93";
39161754Srustatic const char rcsid[] = "$OpenBSD: v831.c,v 1.11 2006/03/17 19:17:13 moritz Exp $";
4088276Smarkm#endif
417527Sjkh#endif /* not lint */
427527Sjkh
437527Sjkh/*
447527Sjkh * Routines for dialing up on Vadic 831
457527Sjkh */
467527Sjkh#include "tip.h"
4788276Smarkm#include <termios.h>
487527Sjkh
497527Sjkhstatic jmp_buf jmpbuf;
50161754Srustatic pid_t child = -1;
517527Sjkh
52161754Srustatic void	alarmtr(int);
53161754Srustatic int	dialit(char *, char *);
54161754Srustatic char *	sanitize(char *);
55161754Sru
5688276Smarkmint
57161754Sruv831_dialer(char *num, char *acu)
587527Sjkh{
59161754Sru        int status;
6088276Smarkm        int timelim;
61161754Sru	pid_t pid;
627527Sjkh
637527Sjkh        if (boolean(value(VERBOSE)))
647527Sjkh                printf("\nstarting call...");
657527Sjkh#ifdef DEBUG
667527Sjkh        printf ("(acu=%s)\n", acu);
677527Sjkh#endif
687527Sjkh        if ((AC = open(acu, O_RDWR)) < 0) {
697527Sjkh                if (errno == EBUSY)
707527Sjkh                        printf("line busy...");
717527Sjkh                else
727527Sjkh                        printf("acu open error...");
737527Sjkh                return (0);
747527Sjkh        }
757527Sjkh        if (setjmp(jmpbuf)) {
767527Sjkh                kill(child, SIGKILL);
777527Sjkh                close(AC);
787527Sjkh                return (0);
797527Sjkh        }
807527Sjkh        signal(SIGALRM, alarmtr);
817527Sjkh        timelim = 5 * strlen(num);
827527Sjkh        alarm(timelim < 30 ? 30 : timelim);
837527Sjkh        if ((child = fork()) == 0) {
847527Sjkh                /*
857527Sjkh                 * ignore this stuff for aborts
867527Sjkh                 */
877527Sjkh                signal(SIGALRM, SIG_IGN);
887527Sjkh		signal(SIGINT, SIG_IGN);
897527Sjkh                signal(SIGQUIT, SIG_IGN);
907527Sjkh                sleep(2);
917527Sjkh                exit(dialit(num, acu) != 'A');
927527Sjkh        }
937527Sjkh        /*
947527Sjkh         * open line - will return on carrier
957527Sjkh         */
967527Sjkh        if ((FD = open(DV, O_RDWR)) < 0) {
977527Sjkh#ifdef DEBUG
987527Sjkh                printf("(after open, errno=%d)\n", errno);
997527Sjkh#endif
1007527Sjkh                if (errno == EIO)
1017527Sjkh                        printf("lost carrier...");
1027527Sjkh                else
1037527Sjkh                        printf("dialup line open failed...");
1047527Sjkh                alarm(0);
1057527Sjkh                kill(child, SIGKILL);
1067527Sjkh                close(AC);
1077527Sjkh                return (0);
1087527Sjkh        }
1097527Sjkh        alarm(0);
1107527Sjkh        signal(SIGALRM, SIG_DFL);
1117527Sjkh        while ((pid = wait(&status)) != child && pid != -1)
1127527Sjkh                ;
1137527Sjkh        if (status) {
1147527Sjkh                close(AC);
1157527Sjkh                return (0);
1167527Sjkh        }
1177527Sjkh        return (1);
1187527Sjkh}
1197527Sjkh
120161754Sru/*ARGSUSED*/
1217527Sjkhstatic void
122161754Srualarmtr(int signo)
1237527Sjkh{
1247527Sjkh        alarm(0);
1257527Sjkh        longjmp(jmpbuf, 1);
1267527Sjkh}
1277527Sjkh
1287527Sjkh/*
1297527Sjkh * Insurance, for some reason we don't seem to be
1307527Sjkh *  hanging up...
1317527Sjkh */
13288276Smarkmvoid
133161754Sruv831_disconnect(void)
1347527Sjkh{
13588276Smarkm	struct termios	cntrl;
13688276Smarkm
1377527Sjkh        sleep(2);
1387527Sjkh#ifdef DEBUG
1397527Sjkh        printf("[disconnect: FD=%d]\n", FD);
1407527Sjkh#endif
1417527Sjkh        if (FD > 0) {
1427527Sjkh                ioctl(FD, TIOCCDTR, 0);
14388276Smarkm		tcgetattr(FD, &cntrl);
14488276Smarkm		cfsetospeed(&cntrl, 0);
14588276Smarkm		cfsetispeed(&cntrl, 0);
14688276Smarkm		tcsetattr(FD, TCSAFLUSH, &cntrl);
14788276Smarkm                ioctl(FD, TIOCNXCL, NULL);
1487527Sjkh        }
1497527Sjkh        close(FD);
1507527Sjkh}
1517527Sjkh
15288276Smarkmvoid
153161754Sruv831_abort(void)
1547527Sjkh{
1557527Sjkh#ifdef DEBUG
1567527Sjkh        printf("[abort: AC=%d]\n", AC);
1577527Sjkh#endif
1587527Sjkh        sleep(2);
1597527Sjkh        if (child > 0)
1607527Sjkh                kill(child, SIGKILL);
161161754Sru        if (FD > 0)
16288276Smarkm                ioctl(FD, TIOCNXCL, NULL);
163161754Sru        close(AC);
1647527Sjkh        if (FD > 0)
1657527Sjkh                ioctl(FD, TIOCCDTR, 0);
1667527Sjkh        close(FD);
1677527Sjkh}
1687527Sjkh
1697527Sjkh/*
1707527Sjkh * Sigh, this probably must be changed at each site.
1717527Sjkh */
1727527Sjkhstruct vaconfig {
1737527Sjkh	char	*vc_name;
1747527Sjkh	char	vc_rack;
1757527Sjkh	char	vc_modem;
1767527Sjkh} vaconfig[] = {
1777527Sjkh	{ "/dev/cua0",'4','0' },
1787527Sjkh	{ "/dev/cua1",'4','1' },
179161781Sru	{ NULL, '\0', '\0' }
1807527Sjkh};
1817527Sjkh
1827527Sjkh#define pc(x)	(c = x, write(AC,&c,1))
1837527Sjkh#define ABORT	01
1847527Sjkh#define SI	017
1857527Sjkh#define STX	02
1867527Sjkh#define ETX	03
1877527Sjkh
1887527Sjkhstatic int
189161754Srudialit(char *phonenum, char *acu)
1907527Sjkh{
19188276Smarkm        struct vaconfig *vp;
19288276Smarkm	struct termios cntrl;
1937527Sjkh        char c;
19488276Smarkm        int i;
1957527Sjkh
1967527Sjkh        phonenum = sanitize(phonenum);
1977527Sjkh#ifdef DEBUG
1987527Sjkh        printf ("(dial phonenum=%s)\n", phonenum);
1997527Sjkh#endif
2007527Sjkh        if (*phonenum == '<' && phonenum[1] == 0)
2017527Sjkh                return ('Z');
2027527Sjkh	for (vp = vaconfig; vp->vc_name; vp++)
2037527Sjkh		if (strcmp(vp->vc_name, acu) == 0)
2047527Sjkh			break;
2057527Sjkh	if (vp->vc_name == 0) {
2067527Sjkh		printf("Unable to locate dialer (%s)\n", acu);
2077527Sjkh		return ('K');
2087527Sjkh	}
20988276Smarkm	tcgetattr(AC, &cntrl);
21088276Smarkm	cfsetospeed(&cntrl, B2400);
21188276Smarkm	cfsetispeed(&cntrl, B2400);
21288276Smarkm	cntrl.c_cflag |= PARODD | PARENB;
21388276Smarkm	cntrl.c_lflag &= ~(ISIG | ICANON);
21488276Smarkm	tcsetattr(AC, TCSANOW, &cntrl);
21588276Smarkm	tcflush(AC, TCIOFLUSH);
2167527Sjkh        pc(STX);
2177527Sjkh	pc(vp->vc_rack);
2187527Sjkh	pc(vp->vc_modem);
2197527Sjkh	while (*phonenum && *phonenum != '<')
2207527Sjkh		pc(*phonenum++);
2217527Sjkh        pc(SI);
2227527Sjkh	pc(ETX);
2237527Sjkh        sleep(1);
2247527Sjkh        i = read(AC, &c, 1);
2257527Sjkh#ifdef DEBUG
2267527Sjkh        printf("read %d chars, char=%c, errno %d\n", i, c, errno);
2277527Sjkh#endif
2287527Sjkh        if (i != 1)
2297527Sjkh		c = 'M';
2307527Sjkh        if (c == 'B' || c == 'G') {
2317527Sjkh                char cc, oc = c;
2327527Sjkh
2337527Sjkh                pc(ABORT);
2347527Sjkh                read(AC, &cc, 1);
2357527Sjkh#ifdef DEBUG
2367527Sjkh                printf("abort response=%c\n", cc);
2377527Sjkh#endif
2387527Sjkh                c = oc;
2397527Sjkh                v831_disconnect();
2407527Sjkh        }
2417527Sjkh        close(AC);
2427527Sjkh#ifdef DEBUG
2437527Sjkh        printf("dialit: returns %c\n", c);
2447527Sjkh#endif
2457527Sjkh        return (c);
2467527Sjkh}
2477527Sjkh
2487527Sjkhstatic char *
249161754Srusanitize(char *s)
2507527Sjkh{
2517527Sjkh        static char buf[128];
25288276Smarkm        char *cp;
2537527Sjkh
2547527Sjkh        for (cp = buf; *s; s++) {
2557527Sjkh		if (!isdigit(*s) && *s == '<' && *s != '_')
2567527Sjkh			continue;
2577527Sjkh		if (*s == '_')
2587527Sjkh			*s = '=';
2597527Sjkh		*cp++ = *s;
2607527Sjkh	}
2617527Sjkh        *cp++ = 0;
2627527Sjkh        return (buf);
2637527Sjkh}
264