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 35static 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 45static jmp_buf Sjbuf; 46 47static void alarmtr(int); 48static int expect(const char *); 49static int notin(const char *, char *); 50static int prefix(const char *, char *); 51static void vawrite(const char *, int); 52 53int 54/*ARGSUSED*/ 55v3451_dialer(char *num, char *acu __unused) 56{ 57 sig_t func; 58 int ok; 59 int slow = number(value(BAUDRATE)) < 1200; 60 char phone[50]; 61 struct termios cntrl; 62 63 /* 64 * Get in synch 65 */ 66 vawrite("I\r", 1 + slow); 67 vawrite("I\r", 1 + slow); 68 vawrite("I\r", 1 + slow); 69 vawrite("\005\r", 2 + slow); 70 if (!expect("READY")) { 71 (void)printf("can't synchronize with vadic 3451\n"); 72 return (0); 73 } 74 (void)tcgetattr(FD, &cntrl); 75 term.c_cflag |= HUPCL; 76 (void)tcsetattr(FD, TCSANOW, &cntrl); 77 (void)sleep(1); 78 vawrite("D\r", 2 + slow); 79 if (!expect("NUMBER?")) { 80 (void)printf("Vadic will not accept dial command\n"); 81 return (0); 82 } 83 (void)snprintf(phone, sizeof phone, "%s\r", num); 84 vawrite(phone, 1 + slow); 85 if (!expect(phone)) { 86 (void)printf("Vadic will not accept phone number\n"); 87 return (0); 88 } 89 func = signal(SIGINT,SIG_IGN); 90 /* 91 * You cannot interrupt the Vadic when its dialing; 92 * even dropping DTR does not work (definitely a 93 * brain damaged design). 94 */ 95 vawrite("\r", 1 + slow); 96 vawrite("\r", 1 + slow); 97 if (!expect("DIALING:")) { 98 (void)printf("Vadic failed to dial\n"); 99 return (0); 100 } 101 if (boolean(value(VERBOSE))) 102 (void)printf("\ndialing..."); 103 ok = expect("ON LINE"); 104 (void)signal(SIGINT, func); 105 if (!ok) { 106 (void)printf("call failed\n"); 107 return (0); 108 } 109 (void)tcflush(FD, TCIOFLUSH); 110 return (1); 111} 112 113void 114v3451_disconnect(void) 115{ 116 117 (void)close(FD); 118} 119 120void 121v3451_abort(void) 122{ 123 124 (void)close(FD); 125} 126 127static void 128vawrite(const char *cp, int delay) 129{ 130 131 for (/*EMPTY*/; *cp; cp++) { 132 (void)write(FD, cp, 1); 133 (void)sleep((unsigned)delay); 134 } 135} 136 137static int 138expect(const char *cp) 139{ 140 char buf[300]; 141 char * volatile rp; 142 int volatile timeout; 143 int volatile online; 144 145 rp = buf; 146 timeout = 30; 147 online = 0; 148 149 if (strcmp(cp, "\"\"") == 0) 150 return (1); 151 *rp = 0; 152 /* 153 * If we are waiting for the Vadic to complete 154 * dialing and get a connection, allow more time 155 * Unfortunately, the Vadic times out 24 seconds after 156 * the last digit is dialed 157 */ 158 online = strcmp(cp, "ON LINE") == 0; 159 if (online) 160 timeout = number(value(DIALTIMEOUT)); 161 (void)signal(SIGALRM, alarmtr); 162 if (setjmp(Sjbuf)) 163 return (0); 164 (void)alarm((unsigned)timeout); 165 while (notin(cp, buf) && rp < buf + sizeof (buf) - 1) { 166 if (online && notin("FAILED CALL", buf) == 0) 167 return (0); 168 if (read(FD, rp, 1) < 0) { 169 (void)alarm(0); 170 return (0); 171 } 172 if (*rp &= 0177) 173 rp++; 174 *rp = '\0'; 175 } 176 (void)alarm(0); 177 return (1); 178} 179 180static void 181/*ARGSUSED*/ 182alarmtr(int dummy __unused) 183{ 184 185 longjmp(Sjbuf, 1); 186} 187 188static int 189notin(const char *sh, char *lg) 190{ 191 192 for (; *lg; lg++) 193 if (prefix(sh, lg)) 194 return (0); 195 return (1); 196} 197 198static int 199prefix(const char *s1, char *s2) 200{ 201 char c; 202 203 while ((c = *s1++) == *s2++) 204 if (c == '\0') 205 return (1); 206 return (c == '\0'); 207} 208