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