1 /* $OpenBSD: v3451.c,v 1.9 2006/03/17 19:17:13 moritz Exp $ */ 2 /* $NetBSD: v3451.c,v 1.6 1997/02/11 09:24:20 mrg 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. Neither the name of the University nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 */ 32 33 #include <sys/cdefs.h> 34 __FBSDID("$FreeBSD$"); 35 36 #ifndef lint 37 #if 0 38 static char sccsid[] = "@(#)v3451.c 8.1 (Berkeley) 6/6/93"; 39 static const char rcsid[] = "$OpenBSD: v3451.c,v 1.9 2006/03/17 19:17:13 moritz Exp $"; 40 #endif 41 #endif /* not lint */ 42 43 /* 44 * Routines for calling up on a Vadic 3451 Modem 45 */ 46 #include "tip.h" 47 48 static jmp_buf Sjbuf; 49 50 static void vawrite(char *, int); 51 static int expect(char *); 52 static void alarmtr(int); 53 static int notin(char *, char *); 54 static int prefix(char *, char *); 55 56 int 57 v3451_dialer(char *num, char *acu) 58 { 59 sig_t func; 60 int ok; 61 int slow = number(value(BAUDRATE)) < 1200; 62 char phone[50]; 63 struct termios cntrl; 64 65 /* 66 * Get in synch 67 */ 68 vawrite("I\r", 1 + slow); 69 vawrite("I\r", 1 + slow); 70 vawrite("I\r", 1 + slow); 71 vawrite("\005\r", 2 + slow); 72 if (!expect("READY")) { 73 printf("can't synchronize with vadic 3451\n"); 74 #ifdef ACULOG 75 logent(value(HOST), num, "vadic", "can't synch up"); 76 #endif 77 return (0); 78 } 79 tcgetattr(FD, &cntrl); 80 term.c_cflag |= HUPCL; 81 tcsetattr(FD, TCSANOW, &cntrl); 82 sleep(1); 83 vawrite("D\r", 2 + slow); 84 if (!expect("NUMBER?")) { 85 printf("Vadic will not accept dial command\n"); 86 #ifdef ACULOG 87 logent(value(HOST), num, "vadic", "will not accept dial"); 88 #endif 89 return (0); 90 } 91 (void)snprintf(phone, sizeof phone, "%s\r", num); 92 vawrite(phone, 1 + slow); 93 if (!expect(phone)) { 94 printf("Vadic will not accept phone number\n"); 95 #ifdef ACULOG 96 logent(value(HOST), num, "vadic", "will not accept number"); 97 #endif 98 return (0); 99 } 100 func = signal(SIGINT,SIG_IGN); 101 /* 102 * You cannot interrupt the Vadic when its dialing; 103 * even dropping DTR does not work (definitely a 104 * brain damaged design). 105 */ 106 vawrite("\r", 1 + slow); 107 vawrite("\r", 1 + slow); 108 if (!expect("DIALING:")) { 109 printf("Vadic failed to dial\n"); 110 #ifdef ACULOG 111 logent(value(HOST), num, "vadic", "failed to dial"); 112 #endif 113 return (0); 114 } 115 if (boolean(value(VERBOSE))) 116 printf("\ndialing..."); 117 ok = expect("ON LINE"); 118 signal(SIGINT, func); 119 if (!ok) { 120 printf("call failed\n"); 121 #ifdef ACULOG 122 logent(value(HOST), num, "vadic", "call failed"); 123 #endif 124 return (0); 125 } 126 tcflush(FD, TCIOFLUSH); 127 return (1); 128 } 129 130 void 131 v3451_disconnect(void) 132 { 133 close(FD); 134 } 135 136 void 137 v3451_abort(void) 138 { 139 close(FD); 140 } 141 142 static void 143 vawrite(char *cp, int delay) 144 { 145 for (; *cp; sleep(delay), cp++) 146 write(FD, cp, 1); 147 } 148 149 static int 150 expect(char *cp) 151 { 152 char buf[300]; 153 char *rp = buf; 154 int timeout = 30, online = 0; 155 156 if (strcmp(cp, "\"\"") == 0) 157 return (1); 158 *rp = 0; 159 /* 160 * If we are waiting for the Vadic to complete 161 * dialing and get a connection, allow more time 162 * Unfortunately, the Vadic times out 24 seconds after 163 * the last digit is dialed 164 */ 165 online = strcmp(cp, "ON LINE") == 0; 166 if (online) 167 timeout = number(value(DIALTIMEOUT)); 168 signal(SIGALRM, alarmtr); 169 if (setjmp(Sjbuf)) 170 return (0); 171 alarm(timeout); 172 while (notin(cp, buf) && rp < buf + sizeof (buf) - 1) { 173 if (online && notin("FAILED CALL", buf) == 0) 174 return (0); 175 if (read(FD, rp, 1) < 0) { 176 alarm(0); 177 return (0); 178 } 179 if (*rp &= 0177) 180 rp++; 181 *rp = '\0'; 182 } 183 alarm(0); 184 return (1); 185 } 186 187 /*ARGSUSED*/ 188 static void 189 alarmtr(int signo) 190 { 191 longjmp(Sjbuf, 1); 192 } 193 194 static int 195 notin(char *sh, char *lg) 196 { 197 for (; *lg; lg++) 198 if (prefix(sh, lg)) 199 return (0); 200 return (1); 201 } 202 203 static int 204 prefix(char *s1, char *s2) 205 { 206 char c; 207 208 while ((c = *s1++) == *s2++) 209 if (c == '\0') 210 return (1); 211 return (c == '\0'); 212 } 213