1 /* $OpenBSD: v831.c,v 1.6 2001/11/19 19:02:16 mpech Exp $ */ 2 /* $NetBSD: v831.c,v 1.5 1996/12/29 10:42:01 cgd Exp $ */ 3 4 /* 5 * Copyright (c) 1983, 1993 6 * The Regents of the University of California. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. All advertising materials mentioning features or use of this software 17 * must display the following acknowledgement: 18 * This product includes software developed by the University of 19 * California, Berkeley and its contributors. 20 * 4. Neither the name of the University nor the names of its contributors 21 * may be used to endorse or promote products derived from this software 22 * without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 */ 36 37 #include <sys/cdefs.h> 38 __FBSDID("$FreeBSD$"); 39 40 #ifndef lint 41 #if 0 42 static char sccsid[] = "@(#)v831.c 8.1 (Berkeley) 6/6/93"; 43 static char rcsid[] = "$OpenBSD: v831.c,v 1.6 2001/11/19 19:02:16 mpech Exp $"; 44 #endif 45 #endif /* not lint */ 46 47 /* 48 * Routines for dialing up on Vadic 831 49 */ 50 #include "tip.h" 51 #include <termios.h> 52 53 void v831_abort(); 54 static void alarmtr(); 55 static int dialit(); 56 static char *sanitize(); 57 58 static jmp_buf jmpbuf; 59 static int child = -1; 60 61 int 62 v831_dialer(num, acu) 63 char *num, *acu; 64 { 65 int status, pid; 66 int timelim; 67 68 if (boolean(value(VERBOSE))) 69 printf("\nstarting call..."); 70 #ifdef DEBUG 71 printf ("(acu=%s)\n", acu); 72 #endif 73 if ((AC = open(acu, O_RDWR)) < 0) { 74 if (errno == EBUSY) 75 printf("line busy..."); 76 else 77 printf("acu open error..."); 78 return (0); 79 } 80 if (setjmp(jmpbuf)) { 81 kill(child, SIGKILL); 82 close(AC); 83 return (0); 84 } 85 signal(SIGALRM, alarmtr); 86 timelim = 5 * strlen(num); 87 alarm(timelim < 30 ? 30 : timelim); 88 if ((child = fork()) == 0) { 89 /* 90 * ignore this stuff for aborts 91 */ 92 signal(SIGALRM, SIG_IGN); 93 signal(SIGINT, SIG_IGN); 94 signal(SIGQUIT, SIG_IGN); 95 sleep(2); 96 exit(dialit(num, acu) != 'A'); 97 } 98 /* 99 * open line - will return on carrier 100 */ 101 if ((FD = open(DV, O_RDWR)) < 0) { 102 #ifdef DEBUG 103 printf("(after open, errno=%d)\n", errno); 104 #endif 105 if (errno == EIO) 106 printf("lost carrier..."); 107 else 108 printf("dialup line open failed..."); 109 alarm(0); 110 kill(child, SIGKILL); 111 close(AC); 112 return (0); 113 } 114 alarm(0); 115 signal(SIGALRM, SIG_DFL); 116 while ((pid = wait(&status)) != child && pid != -1) 117 ; 118 if (status) { 119 close(AC); 120 return (0); 121 } 122 return (1); 123 } 124 125 static void 126 alarmtr() 127 { 128 alarm(0); 129 longjmp(jmpbuf, 1); 130 } 131 132 /* 133 * Insurance, for some reason we don't seem to be 134 * hanging up... 135 */ 136 void 137 v831_disconnect() 138 { 139 struct termios cntrl; 140 141 sleep(2); 142 #ifdef DEBUG 143 printf("[disconnect: FD=%d]\n", FD); 144 #endif 145 if (FD > 0) { 146 ioctl(FD, TIOCCDTR, 0); 147 tcgetattr(FD, &cntrl); 148 cfsetospeed(&cntrl, 0); 149 cfsetispeed(&cntrl, 0); 150 tcsetattr(FD, TCSAFLUSH, &cntrl); 151 ioctl(FD, TIOCNXCL, NULL); 152 } 153 close(FD); 154 } 155 156 void 157 v831_abort() 158 { 159 160 #ifdef DEBUG 161 printf("[abort: AC=%d]\n", AC); 162 #endif 163 sleep(2); 164 if (child > 0) 165 kill(child, SIGKILL); 166 if (AC > 0) 167 ioctl(FD, TIOCNXCL, NULL); 168 close(AC); 169 if (FD > 0) 170 ioctl(FD, TIOCCDTR, 0); 171 close(FD); 172 } 173 174 /* 175 * Sigh, this probably must be changed at each site. 176 */ 177 struct vaconfig { 178 char *vc_name; 179 char vc_rack; 180 char vc_modem; 181 } vaconfig[] = { 182 { "/dev/cua0",'4','0' }, 183 { "/dev/cua1",'4','1' }, 184 { 0 } 185 }; 186 187 #define pc(x) (c = x, write(AC,&c,1)) 188 #define ABORT 01 189 #define SI 017 190 #define STX 02 191 #define ETX 03 192 193 static int 194 dialit(phonenum, acu) 195 char *phonenum; 196 char *acu; 197 { 198 struct vaconfig *vp; 199 struct termios cntrl; 200 char c; 201 int i; 202 203 phonenum = sanitize(phonenum); 204 #ifdef DEBUG 205 printf ("(dial phonenum=%s)\n", phonenum); 206 #endif 207 if (*phonenum == '<' && phonenum[1] == 0) 208 return ('Z'); 209 for (vp = vaconfig; vp->vc_name; vp++) 210 if (strcmp(vp->vc_name, acu) == 0) 211 break; 212 if (vp->vc_name == 0) { 213 printf("Unable to locate dialer (%s)\n", acu); 214 return ('K'); 215 } 216 tcgetattr(AC, &cntrl); 217 cfsetospeed(&cntrl, B2400); 218 cfsetispeed(&cntrl, B2400); 219 cntrl.c_cflag |= PARODD | PARENB; 220 cntrl.c_lflag &= ~(ISIG | ICANON); 221 tcsetattr(AC, TCSANOW, &cntrl); 222 tcflush(AC, TCIOFLUSH); 223 pc(STX); 224 pc(vp->vc_rack); 225 pc(vp->vc_modem); 226 while (*phonenum && *phonenum != '<') 227 pc(*phonenum++); 228 pc(SI); 229 pc(ETX); 230 sleep(1); 231 i = read(AC, &c, 1); 232 #ifdef DEBUG 233 printf("read %d chars, char=%c, errno %d\n", i, c, errno); 234 #endif 235 if (i != 1) 236 c = 'M'; 237 if (c == 'B' || c == 'G') { 238 char cc, oc = c; 239 240 pc(ABORT); 241 read(AC, &cc, 1); 242 #ifdef DEBUG 243 printf("abort response=%c\n", cc); 244 #endif 245 c = oc; 246 v831_disconnect(); 247 } 248 close(AC); 249 #ifdef DEBUG 250 printf("dialit: returns %c\n", c); 251 #endif 252 return (c); 253 } 254 255 static char * 256 sanitize(s) 257 char *s; 258 { 259 static char buf[128]; 260 char *cp; 261 262 for (cp = buf; *s; s++) { 263 if (!isdigit(*s) && *s == '<' && *s != '_') 264 continue; 265 if (*s == '_') 266 *s = '='; 267 *cp++ = *s; 268 } 269 *cp++ = 0; 270 return (buf); 271 } 272