1161754Sru/* $OpenBSD: biz31.c,v 1.10 2006/03/17 19:17:13 moritz Exp $ */ 288276Smarkm/* $NetBSD: biz31.c,v 1.5 1997/02/11 09:24:14 mrg Exp $ */ 388276Smarkm 47527Sjkh/* 57527Sjkh * Copyright (c) 1983, 1993 67527Sjkh * The Regents of the University of California. All rights reserved. 77527Sjkh * 87527Sjkh * Redistribution and use in source and binary forms, with or without 97527Sjkh * modification, are permitted provided that the following conditions 107527Sjkh * are met: 117527Sjkh * 1. Redistributions of source code must retain the above copyright 127527Sjkh * notice, this list of conditions and the following disclaimer. 137527Sjkh * 2. Redistributions in binary form must reproduce the above copyright 147527Sjkh * notice, this list of conditions and the following disclaimer in the 157527Sjkh * documentation and/or other materials provided with the distribution. 16161754Sru * 3. Neither the name of the University nor the names of its contributors 177527Sjkh * may be used to endorse or promote products derived from this software 187527Sjkh * without specific prior written permission. 197527Sjkh * 207527Sjkh * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 217527Sjkh * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 227527Sjkh * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 237527Sjkh * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 247527Sjkh * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 257527Sjkh * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 267527Sjkh * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 277527Sjkh * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 287527Sjkh * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 297527Sjkh * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 307527Sjkh * SUCH DAMAGE. 317527Sjkh */ 327527Sjkh 3388276Smarkm#include <sys/cdefs.h> 3488276Smarkm__FBSDID("$FreeBSD$"); 3588276Smarkm 367527Sjkh#ifndef lint 3788276Smarkm#if 0 387527Sjkhstatic char sccsid[] = "@(#)biz31.c 8.1 (Berkeley) 6/6/93"; 39161754Srustatic char rcsid[] = "$OpenBSD: biz31.c,v 1.10 2006/03/17 19:17:13 moritz Exp $"; 4088276Smarkm#endif 417527Sjkh#endif /* not lint */ 427527Sjkh 437527Sjkh#include "tip.h" 447527Sjkh 457527Sjkh#define MAXRETRY 3 /* sync up retry count */ 467527Sjkh#define DISCONNECT_CMD "\21\25\11\24" /* disconnection string */ 477527Sjkh 48161754Srustatic int biz_dialer(char *, char *); 49161754Srustatic int bizsync(int); 50161754Srustatic int echo(char *); 51161754Srustatic void sigALRM(int); 52161754Srustatic int detect(char *); 53161754Srustatic int flush(char *); 54161754Srustatic int bizsync(int); 55161754Sru 567527Sjkhstatic int timeout = 0; 577527Sjkhstatic jmp_buf timeoutbuf; 587527Sjkh 597527Sjkh/* 607527Sjkh * Dial up on a BIZCOMP Model 1031 with either 617527Sjkh * tone dialing (mod = "f") 627527Sjkh * pulse dialing (mod = "w") 637527Sjkh */ 647527Sjkhstatic int 65161754Srubiz_dialer(char *num, char *mod) 667527Sjkh{ 6788276Smarkm int connected = 0; 687527Sjkh 697527Sjkh if (!bizsync(FD)) { 707527Sjkh logent(value(HOST), "", "biz", "out of sync"); 717527Sjkh printf("bizcomp out of sync\n"); 727527Sjkh delock(uucplock); 737527Sjkh exit(0); 747527Sjkh } 757527Sjkh if (boolean(value(VERBOSE))) 767527Sjkh printf("\nstarting call..."); 777527Sjkh echo("#\rk$\r$\n"); /* disable auto-answer */ 787527Sjkh echo("$>$.$ #\r"); /* tone/pulse dialing */ 797527Sjkh echo(mod); 807527Sjkh echo("$\r$\n"); 817527Sjkh echo("$>$.$ #\re$ "); /* disconnection sequence */ 827527Sjkh echo(DISCONNECT_CMD); 837527Sjkh echo("\r$\n$\r$\n"); 847527Sjkh echo("$>$.$ #\rr$ "); /* repeat dial */ 857527Sjkh echo(num); 867527Sjkh echo("\r$\n"); 877527Sjkh if (boolean(value(VERBOSE))) 887527Sjkh printf("ringing..."); 897527Sjkh /* 907527Sjkh * The reply from the BIZCOMP should be: 917527Sjkh * `^G NO CONNECTION\r\n^G\r\n' failure 927527Sjkh * ` CONNECTION\r\n^G' success 937527Sjkh */ 947527Sjkh connected = detect(" "); 9588276Smarkm#ifdef ACULOG 967527Sjkh if (timeout) { 977527Sjkh char line[80]; 987527Sjkh 99161754Sru (void)snprintf(line, sizeof line, "%ld second dial timeout", 1007527Sjkh number(value(DIALTIMEOUT))); 1017527Sjkh logent(value(HOST), num, "biz", line); 1027527Sjkh } 1037527Sjkh#endif 1047527Sjkh if (!connected) 1057527Sjkh flush(" NO CONNECTION\r\n\07\r\n"); 1067527Sjkh else 1077527Sjkh flush("CONNECTION\r\n\07"); 1087527Sjkh if (timeout) 1097527Sjkh biz31_disconnect(); /* insurance */ 1107527Sjkh return (connected); 1117527Sjkh} 1127527Sjkh 113161754Sruint 114161754Srubiz31w_dialer(char *num, char *acu) 1157527Sjkh{ 1167527Sjkh return (biz_dialer(num, "w")); 1177527Sjkh} 1187527Sjkh 119161754Sruint 120161754Srubiz31f_dialer(char *num, char *acu) 1217527Sjkh{ 1227527Sjkh return (biz_dialer(num, "f")); 1237527Sjkh} 1247527Sjkh 125161754Sruvoid 126161754Srubiz31_disconnect(void) 1277527Sjkh{ 128161754Sru write(FD, DISCONNECT_CMD, sizeof(DISCONNECT_CMD)-1); 1297527Sjkh sleep(2); 13088276Smarkm tcflush(FD, TCIOFLUSH); 1317527Sjkh} 1327527Sjkh 133161754Sruvoid 134161754Srubiz31_abort(void) 1357527Sjkh{ 1367527Sjkh write(FD, "\33", 1); 1377527Sjkh} 1387527Sjkh 1397527Sjkhstatic int 140161754Sruecho(char *s) 1417527Sjkh{ 1427527Sjkh char c; 1437527Sjkh 1447527Sjkh while (c = *s++) switch (c) { 1457527Sjkh 1467527Sjkh case '$': 1477527Sjkh read(FD, &c, 1); 1487527Sjkh s++; 1497527Sjkh break; 1507527Sjkh 1517527Sjkh case '#': 1527527Sjkh c = *s++; 1537527Sjkh write(FD, &c, 1); 1547527Sjkh break; 1557527Sjkh 1567527Sjkh default: 1577527Sjkh write(FD, &c, 1); 1587527Sjkh read(FD, &c, 1); 1597527Sjkh } 1607527Sjkh} 1617527Sjkh 162161754Sru/*ARGSUSED*/ 1637527Sjkhstatic void 164161754SrusigALRM(int signo) 1657527Sjkh{ 1667527Sjkh timeout = 1; 1677527Sjkh longjmp(timeoutbuf, 1); 1687527Sjkh} 1697527Sjkh 1707527Sjkhstatic int 171161754Srudetect(char *s) 1727527Sjkh{ 1737527Sjkh sig_t f; 1747527Sjkh char c; 1757527Sjkh 1767527Sjkh f = signal(SIGALRM, sigALRM); 1777527Sjkh timeout = 0; 1787527Sjkh while (*s) { 1797527Sjkh if (setjmp(timeoutbuf)) { 1807527Sjkh printf("\07timeout waiting for reply\n"); 1817527Sjkh biz31_abort(); 1827527Sjkh break; 1837527Sjkh } 1847527Sjkh alarm(number(value(DIALTIMEOUT))); 1857527Sjkh read(FD, &c, 1); 1867527Sjkh alarm(0); 1877527Sjkh if (c != *s++) 1887527Sjkh break; 1897527Sjkh } 1907527Sjkh signal(SIGALRM, f); 1917527Sjkh return (timeout == 0); 1927527Sjkh} 1937527Sjkh 1947527Sjkhstatic int 195161754Sruflush(char *s) 1967527Sjkh{ 1977527Sjkh sig_t f; 1987527Sjkh char c; 1997527Sjkh 2007527Sjkh f = signal(SIGALRM, sigALRM); 2017527Sjkh while (*s++) { 2027527Sjkh if (setjmp(timeoutbuf)) 2037527Sjkh break; 2047527Sjkh alarm(10); 2057527Sjkh read(FD, &c, 1); 2067527Sjkh alarm(0); 2077527Sjkh } 2087527Sjkh signal(SIGALRM, f); 2097527Sjkh timeout = 0; /* guard against disconnection */ 2107527Sjkh} 2117527Sjkh 2127527Sjkh/* 2137527Sjkh * This convoluted piece of code attempts to get 2147527Sjkh * the bizcomp in sync. If you don't have the capacity or nread 2157527Sjkh * call there are gory ways to simulate this. 2167527Sjkh */ 2177527Sjkhstatic int 218161754Srubizsync(int fd) 2197527Sjkh{ 2207527Sjkh#ifdef FIOCAPACITY 2217527Sjkh struct capacity b; 2227527Sjkh# define chars(b) ((b).cp_nbytes) 2237527Sjkh# define IOCTL FIOCAPACITY 2247527Sjkh#endif 2257527Sjkh#ifdef FIONREAD 2267527Sjkh long b; 2277527Sjkh# define chars(b) (b) 2287527Sjkh# define IOCTL FIONREAD 2297527Sjkh#endif 23088276Smarkm int already = 0; 2317527Sjkh char buf[10]; 2327527Sjkh 2337527Sjkhretry: 2347527Sjkh if (ioctl(fd, IOCTL, (caddr_t)&b) >= 0 && chars(b) > 0) 23588276Smarkm tcflush(FD, TCIOFLUSH); 2367527Sjkh write(fd, "\rp>\r", 4); 2377527Sjkh sleep(1); 2387527Sjkh if (ioctl(fd, IOCTL, (caddr_t)&b) >= 0) { 2397527Sjkh if (chars(b) != 10) { 2407527Sjkh nono: 2417527Sjkh if (already > MAXRETRY) 2427527Sjkh return (0); 2437527Sjkh write(fd, DISCONNECT_CMD, 4); 2447527Sjkh sleep(2); 2457527Sjkh already++; 2467527Sjkh goto retry; 2477527Sjkh } else { 2487527Sjkh read(fd, buf, 10); 2497527Sjkh if (strncmp(buf, "p >\r\n\r\n>", 8)) 2507527Sjkh goto nono; 2517527Sjkh } 2527527Sjkh } 2537527Sjkh return (1); 2547527Sjkh} 255