10f3bdf5dSMark Murray /* $OpenBSD: v831.c,v 1.6 2001/11/19 19:02:16 mpech Exp $ */ 20f3bdf5dSMark Murray /* $NetBSD: v831.c,v 1.5 1996/12/29 10:42:01 cgd Exp $ */ 30f3bdf5dSMark Murray 40f3bdf5dSMark Murray /* 50f3bdf5dSMark Murray * Copyright (c) 1983, 1993 60f3bdf5dSMark Murray * The Regents of the University of California. All rights reserved. 70f3bdf5dSMark Murray * 80f3bdf5dSMark Murray * Redistribution and use in source and binary forms, with or without 90f3bdf5dSMark Murray * modification, are permitted provided that the following conditions 100f3bdf5dSMark Murray * are met: 110f3bdf5dSMark Murray * 1. Redistributions of source code must retain the above copyright 120f3bdf5dSMark Murray * notice, this list of conditions and the following disclaimer. 130f3bdf5dSMark Murray * 2. Redistributions in binary form must reproduce the above copyright 140f3bdf5dSMark Murray * notice, this list of conditions and the following disclaimer in the 150f3bdf5dSMark Murray * documentation and/or other materials provided with the distribution. 160f3bdf5dSMark Murray * 3. All advertising materials mentioning features or use of this software 170f3bdf5dSMark Murray * must display the following acknowledgement: 180f3bdf5dSMark Murray * This product includes software developed by the University of 190f3bdf5dSMark Murray * California, Berkeley and its contributors. 200f3bdf5dSMark Murray * 4. Neither the name of the University nor the names of its contributors 210f3bdf5dSMark Murray * may be used to endorse or promote products derived from this software 220f3bdf5dSMark Murray * without specific prior written permission. 230f3bdf5dSMark Murray * 240f3bdf5dSMark Murray * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 250f3bdf5dSMark Murray * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 260f3bdf5dSMark Murray * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 270f3bdf5dSMark Murray * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 280f3bdf5dSMark Murray * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 290f3bdf5dSMark Murray * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 300f3bdf5dSMark Murray * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 310f3bdf5dSMark Murray * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 320f3bdf5dSMark Murray * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 330f3bdf5dSMark Murray * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 340f3bdf5dSMark Murray * SUCH DAMAGE. 350f3bdf5dSMark Murray */ 360f3bdf5dSMark Murray 370f3bdf5dSMark Murray #ifndef lint 380f3bdf5dSMark Murray #if 0 390f3bdf5dSMark Murray static char sccsid[] = "@(#)v831.c 8.1 (Berkeley) 6/6/93"; 400f3bdf5dSMark Murray #endif 410f3bdf5dSMark Murray static char rcsid[] = "$OpenBSD: v831.c,v 1.6 2001/11/19 19:02:16 mpech Exp $"; 420f3bdf5dSMark Murray #endif /* not lint */ 430f3bdf5dSMark Murray 440f3bdf5dSMark Murray /* 450f3bdf5dSMark Murray * Routines for dialing up on Vadic 831 460f3bdf5dSMark Murray */ 470f3bdf5dSMark Murray #include "tip.h" 480f3bdf5dSMark Murray #include <termios.h> 490f3bdf5dSMark Murray 500f3bdf5dSMark Murray void v831_abort(); 510f3bdf5dSMark Murray static void alarmtr(); 520f3bdf5dSMark Murray static int dialit(); 530f3bdf5dSMark Murray static char *sanitize(); 540f3bdf5dSMark Murray 550f3bdf5dSMark Murray static jmp_buf jmpbuf; 560f3bdf5dSMark Murray static int child = -1; 570f3bdf5dSMark Murray 580f3bdf5dSMark Murray int 590f3bdf5dSMark Murray v831_dialer(num, acu) 600f3bdf5dSMark Murray char *num, *acu; 610f3bdf5dSMark Murray { 620f3bdf5dSMark Murray int status, pid; 630f3bdf5dSMark Murray int timelim; 640f3bdf5dSMark Murray 650f3bdf5dSMark Murray if (boolean(value(VERBOSE))) 660f3bdf5dSMark Murray printf("\nstarting call..."); 670f3bdf5dSMark Murray #ifdef DEBUG 680f3bdf5dSMark Murray printf ("(acu=%s)\n", acu); 690f3bdf5dSMark Murray #endif 700f3bdf5dSMark Murray if ((AC = open(acu, O_RDWR)) < 0) { 710f3bdf5dSMark Murray if (errno == EBUSY) 720f3bdf5dSMark Murray printf("line busy..."); 730f3bdf5dSMark Murray else 740f3bdf5dSMark Murray printf("acu open error..."); 750f3bdf5dSMark Murray return (0); 760f3bdf5dSMark Murray } 770f3bdf5dSMark Murray if (setjmp(jmpbuf)) { 780f3bdf5dSMark Murray kill(child, SIGKILL); 790f3bdf5dSMark Murray close(AC); 800f3bdf5dSMark Murray return (0); 810f3bdf5dSMark Murray } 820f3bdf5dSMark Murray signal(SIGALRM, alarmtr); 830f3bdf5dSMark Murray timelim = 5 * strlen(num); 840f3bdf5dSMark Murray alarm(timelim < 30 ? 30 : timelim); 850f3bdf5dSMark Murray if ((child = fork()) == 0) { 860f3bdf5dSMark Murray /* 870f3bdf5dSMark Murray * ignore this stuff for aborts 880f3bdf5dSMark Murray */ 890f3bdf5dSMark Murray signal(SIGALRM, SIG_IGN); 900f3bdf5dSMark Murray signal(SIGINT, SIG_IGN); 910f3bdf5dSMark Murray signal(SIGQUIT, SIG_IGN); 920f3bdf5dSMark Murray sleep(2); 930f3bdf5dSMark Murray exit(dialit(num, acu) != 'A'); 940f3bdf5dSMark Murray } 950f3bdf5dSMark Murray /* 960f3bdf5dSMark Murray * open line - will return on carrier 970f3bdf5dSMark Murray */ 980f3bdf5dSMark Murray if ((FD = open(DV, O_RDWR)) < 0) { 990f3bdf5dSMark Murray #ifdef DEBUG 1000f3bdf5dSMark Murray printf("(after open, errno=%d)\n", errno); 1010f3bdf5dSMark Murray #endif 1020f3bdf5dSMark Murray if (errno == EIO) 1030f3bdf5dSMark Murray printf("lost carrier..."); 1040f3bdf5dSMark Murray else 1050f3bdf5dSMark Murray printf("dialup line open failed..."); 1060f3bdf5dSMark Murray alarm(0); 1070f3bdf5dSMark Murray kill(child, SIGKILL); 1080f3bdf5dSMark Murray close(AC); 1090f3bdf5dSMark Murray return (0); 1100f3bdf5dSMark Murray } 1110f3bdf5dSMark Murray alarm(0); 1120f3bdf5dSMark Murray signal(SIGALRM, SIG_DFL); 1130f3bdf5dSMark Murray while ((pid = wait(&status)) != child && pid != -1) 1140f3bdf5dSMark Murray ; 1150f3bdf5dSMark Murray if (status) { 1160f3bdf5dSMark Murray close(AC); 1170f3bdf5dSMark Murray return (0); 1180f3bdf5dSMark Murray } 1190f3bdf5dSMark Murray return (1); 1200f3bdf5dSMark Murray } 1210f3bdf5dSMark Murray 1220f3bdf5dSMark Murray static void 1230f3bdf5dSMark Murray alarmtr() 1240f3bdf5dSMark Murray { 1250f3bdf5dSMark Murray alarm(0); 1260f3bdf5dSMark Murray longjmp(jmpbuf, 1); 1270f3bdf5dSMark Murray } 1280f3bdf5dSMark Murray 1290f3bdf5dSMark Murray /* 1300f3bdf5dSMark Murray * Insurance, for some reason we don't seem to be 1310f3bdf5dSMark Murray * hanging up... 1320f3bdf5dSMark Murray */ 1330f3bdf5dSMark Murray void 1340f3bdf5dSMark Murray v831_disconnect() 1350f3bdf5dSMark Murray { 1360f3bdf5dSMark Murray struct termios cntrl; 1370f3bdf5dSMark Murray 1380f3bdf5dSMark Murray sleep(2); 1390f3bdf5dSMark Murray #ifdef DEBUG 1400f3bdf5dSMark Murray printf("[disconnect: FD=%d]\n", FD); 1410f3bdf5dSMark Murray #endif 1420f3bdf5dSMark Murray if (FD > 0) { 1430f3bdf5dSMark Murray ioctl(FD, TIOCCDTR, 0); 1440f3bdf5dSMark Murray tcgetattr(FD, &cntrl); 1450f3bdf5dSMark Murray cfsetospeed(&cntrl, 0); 1460f3bdf5dSMark Murray cfsetispeed(&cntrl, 0); 1470f3bdf5dSMark Murray tcsetattr(FD, TCSAFLUSH, &cntrl); 1480f3bdf5dSMark Murray ioctl(FD, TIOCNXCL, NULL); 1490f3bdf5dSMark Murray } 1500f3bdf5dSMark Murray close(FD); 1510f3bdf5dSMark Murray } 1520f3bdf5dSMark Murray 1530f3bdf5dSMark Murray void 1540f3bdf5dSMark Murray v831_abort() 1550f3bdf5dSMark Murray { 1560f3bdf5dSMark Murray 1570f3bdf5dSMark Murray #ifdef DEBUG 1580f3bdf5dSMark Murray printf("[abort: AC=%d]\n", AC); 1590f3bdf5dSMark Murray #endif 1600f3bdf5dSMark Murray sleep(2); 1610f3bdf5dSMark Murray if (child > 0) 1620f3bdf5dSMark Murray kill(child, SIGKILL); 1630f3bdf5dSMark Murray if (AC > 0) 1640f3bdf5dSMark Murray ioctl(FD, TIOCNXCL, NULL); 1650f3bdf5dSMark Murray close(AC); 1660f3bdf5dSMark Murray if (FD > 0) 1670f3bdf5dSMark Murray ioctl(FD, TIOCCDTR, 0); 1680f3bdf5dSMark Murray close(FD); 1690f3bdf5dSMark Murray } 1700f3bdf5dSMark Murray 1710f3bdf5dSMark Murray /* 1720f3bdf5dSMark Murray * Sigh, this probably must be changed at each site. 1730f3bdf5dSMark Murray */ 1740f3bdf5dSMark Murray struct vaconfig { 1750f3bdf5dSMark Murray char *vc_name; 1760f3bdf5dSMark Murray char vc_rack; 1770f3bdf5dSMark Murray char vc_modem; 1780f3bdf5dSMark Murray } vaconfig[] = { 1790f3bdf5dSMark Murray { "/dev/cua0",'4','0' }, 1800f3bdf5dSMark Murray { "/dev/cua1",'4','1' }, 1810f3bdf5dSMark Murray { 0 } 1820f3bdf5dSMark Murray }; 1830f3bdf5dSMark Murray 1840f3bdf5dSMark Murray #define pc(x) (c = x, write(AC,&c,1)) 1850f3bdf5dSMark Murray #define ABORT 01 1860f3bdf5dSMark Murray #define SI 017 1870f3bdf5dSMark Murray #define STX 02 1880f3bdf5dSMark Murray #define ETX 03 1890f3bdf5dSMark Murray 1900f3bdf5dSMark Murray static int 1910f3bdf5dSMark Murray dialit(phonenum, acu) 1920f3bdf5dSMark Murray char *phonenum; 1930f3bdf5dSMark Murray char *acu; 1940f3bdf5dSMark Murray { 1950f3bdf5dSMark Murray struct vaconfig *vp; 1960f3bdf5dSMark Murray struct termios cntrl; 1970f3bdf5dSMark Murray char c; 1980f3bdf5dSMark Murray int i; 1990f3bdf5dSMark Murray 2000f3bdf5dSMark Murray phonenum = sanitize(phonenum); 2010f3bdf5dSMark Murray #ifdef DEBUG 2020f3bdf5dSMark Murray printf ("(dial phonenum=%s)\n", phonenum); 2030f3bdf5dSMark Murray #endif 2040f3bdf5dSMark Murray if (*phonenum == '<' && phonenum[1] == 0) 2050f3bdf5dSMark Murray return ('Z'); 2060f3bdf5dSMark Murray for (vp = vaconfig; vp->vc_name; vp++) 2070f3bdf5dSMark Murray if (strcmp(vp->vc_name, acu) == 0) 2080f3bdf5dSMark Murray break; 2090f3bdf5dSMark Murray if (vp->vc_name == 0) { 2100f3bdf5dSMark Murray printf("Unable to locate dialer (%s)\n", acu); 2110f3bdf5dSMark Murray return ('K'); 2120f3bdf5dSMark Murray } 2130f3bdf5dSMark Murray tcgetattr(AC, &cntrl); 2140f3bdf5dSMark Murray cfsetospeed(&cntrl, B2400); 2150f3bdf5dSMark Murray cfsetispeed(&cntrl, B2400); 2160f3bdf5dSMark Murray cntrl.c_cflag |= PARODD | PARENB; 2170f3bdf5dSMark Murray cntrl.c_lflag &= ~(ISIG | ICANON); 2180f3bdf5dSMark Murray tcsetattr(AC, TCSANOW, &cntrl); 2190f3bdf5dSMark Murray tcflush(AC, TCIOFLUSH); 2200f3bdf5dSMark Murray pc(STX); 2210f3bdf5dSMark Murray pc(vp->vc_rack); 2220f3bdf5dSMark Murray pc(vp->vc_modem); 2230f3bdf5dSMark Murray while (*phonenum && *phonenum != '<') 2240f3bdf5dSMark Murray pc(*phonenum++); 2250f3bdf5dSMark Murray pc(SI); 2260f3bdf5dSMark Murray pc(ETX); 2270f3bdf5dSMark Murray sleep(1); 2280f3bdf5dSMark Murray i = read(AC, &c, 1); 2290f3bdf5dSMark Murray #ifdef DEBUG 2300f3bdf5dSMark Murray printf("read %d chars, char=%c, errno %d\n", i, c, errno); 2310f3bdf5dSMark Murray #endif 2320f3bdf5dSMark Murray if (i != 1) 2330f3bdf5dSMark Murray c = 'M'; 2340f3bdf5dSMark Murray if (c == 'B' || c == 'G') { 2350f3bdf5dSMark Murray char cc, oc = c; 2360f3bdf5dSMark Murray 2370f3bdf5dSMark Murray pc(ABORT); 2380f3bdf5dSMark Murray read(AC, &cc, 1); 2390f3bdf5dSMark Murray #ifdef DEBUG 2400f3bdf5dSMark Murray printf("abort response=%c\n", cc); 2410f3bdf5dSMark Murray #endif 2420f3bdf5dSMark Murray c = oc; 2430f3bdf5dSMark Murray v831_disconnect(); 2440f3bdf5dSMark Murray } 2450f3bdf5dSMark Murray close(AC); 2460f3bdf5dSMark Murray #ifdef DEBUG 2470f3bdf5dSMark Murray printf("dialit: returns %c\n", c); 2480f3bdf5dSMark Murray #endif 2490f3bdf5dSMark Murray return (c); 2500f3bdf5dSMark Murray } 2510f3bdf5dSMark Murray 2520f3bdf5dSMark Murray static char * 2530f3bdf5dSMark Murray sanitize(s) 2540f3bdf5dSMark Murray char *s; 2550f3bdf5dSMark Murray { 2560f3bdf5dSMark Murray static char buf[128]; 2570f3bdf5dSMark Murray char *cp; 2580f3bdf5dSMark Murray 2590f3bdf5dSMark Murray for (cp = buf; *s; s++) { 2600f3bdf5dSMark Murray if (!isdigit(*s) && *s == '<' && *s != '_') 2610f3bdf5dSMark Murray continue; 2620f3bdf5dSMark Murray if (*s == '_') 2630f3bdf5dSMark Murray *s = '='; 2640f3bdf5dSMark Murray *cp++ = *s; 2650f3bdf5dSMark Murray } 2660f3bdf5dSMark Murray *cp++ = 0; 2670f3bdf5dSMark Murray return (buf); 2680f3bdf5dSMark Murray } 269