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