Home | History | Annotate | Line # | Download | only in aculib
biz31.c revision 1.8
      1 /*	$NetBSD: biz31.c,v 1.8 2003/08/07 11:16:21 agc 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[] = "@(#)biz31.c	8.1 (Berkeley) 6/6/93";
     36 #endif
     37 __RCSID("$NetBSD: biz31.c,v 1.8 2003/08/07 11:16:21 agc Exp $");
     38 #endif /* not lint */
     39 
     40 #include "tip.h"
     41 
     42 #define MAXRETRY	3		/* sync up retry count */
     43 #define DISCONNECT_CMD	"\21\25\11\24"	/* disconnection string */
     44 
     45 static	void sigALRM();
     46 static	int timeout = 0;
     47 static	jmp_buf timeoutbuf;
     48 
     49 /*
     50  * Dial up on a BIZCOMP Model 1031 with either
     51  * 	tone dialing (mod = "f")
     52  *	pulse dialing (mod = "w")
     53  */
     54 static int
     55 biz_dialer(num, mod)
     56 	char *num, *mod;
     57 {
     58 	int connected = 0;
     59 
     60 	if (!bizsync(FD)) {
     61 		logent(value(HOST), "", "biz", "out of sync");
     62 		printf("bizcomp out of sync\n");
     63 		delock(uucplock);
     64 		exit(0);
     65 	}
     66 	if (boolean(value(VERBOSE)))
     67 		printf("\nstarting call...");
     68 	echo("#\rk$\r$\n");			/* disable auto-answer */
     69 	echo("$>$.$ #\r");			/* tone/pulse dialing */
     70 	echo(mod);
     71 	echo("$\r$\n");
     72 	echo("$>$.$ #\re$ ");			/* disconnection sequence */
     73 	echo(DISCONNECT_CMD);
     74 	echo("\r$\n$\r$\n");
     75 	echo("$>$.$ #\rr$ ");			/* repeat dial */
     76 	echo(num);
     77 	echo("\r$\n");
     78 	if (boolean(value(VERBOSE)))
     79 		printf("ringing...");
     80 	/*
     81 	 * The reply from the BIZCOMP should be:
     82 	 *	`^G NO CONNECTION\r\n^G\r\n'	failure
     83 	 *	` CONNECTION\r\n^G'		success
     84 	 */
     85 	connected = detect(" ");
     86 #ifdef ACULOG
     87 	if (timeout) {
     88 		char line[80];
     89 
     90 		(void)snprintf(line, sizeof line, "%d second dial timeout",
     91 			number(value(DIALTIMEOUT)));
     92 		logent(value(HOST), num, "biz", line);
     93 	}
     94 #endif
     95 	if (!connected)
     96 		flush(" NO CONNECTION\r\n\07\r\n");
     97 	else
     98 		flush("CONNECTION\r\n\07");
     99 	if (timeout)
    100 		biz31_disconnect();	/* insurance */
    101 	return (connected);
    102 }
    103 
    104 biz31w_dialer(num, acu)
    105 	char *num, *acu;
    106 {
    107 
    108 	return (biz_dialer(num, "w"));
    109 }
    110 
    111 biz31f_dialer(num, acu)
    112 	char *num, *acu;
    113 {
    114 
    115 	return (biz_dialer(num, "f"));
    116 }
    117 
    118 biz31_disconnect()
    119 {
    120 
    121 	write(FD, DISCONNECT_CMD, 4);
    122 	sleep(2);
    123 	tcflush(FD, TCIOFLUSH);
    124 }
    125 
    126 biz31_abort()
    127 {
    128 
    129 	write(FD, "\33", 1);
    130 }
    131 
    132 static int
    133 echo(s)
    134 	char *s;
    135 {
    136 	char c;
    137 
    138 	while (c = *s++) switch (c) {
    139 	case '$':
    140 		read(FD, &c, 1);
    141 		s++;
    142 		break;
    143 
    144 	case '#':
    145 		c = *s++;
    146 		write(FD, &c, 1);
    147 		break;
    148 
    149 	default:
    150 		write(FD, &c, 1);
    151 		read(FD, &c, 1);
    152 	}
    153 }
    154 
    155 static void
    156 sigALRM()
    157 {
    158 
    159 	timeout = 1;
    160 	longjmp(timeoutbuf, 1);
    161 }
    162 
    163 static int
    164 detect(s)
    165 	char *s;
    166 {
    167 	sig_t f;
    168 	char c;
    169 
    170 	f = signal(SIGALRM, sigALRM);
    171 	timeout = 0;
    172 	while (*s) {
    173 		if (setjmp(timeoutbuf)) {
    174 			printf("\07timeout waiting for reply\n");
    175 			biz31_abort();
    176 			break;
    177 		}
    178 		alarm(number(value(DIALTIMEOUT)));
    179 		read(FD, &c, 1);
    180 		alarm(0);
    181 		if (c != *s++)
    182 			break;
    183 	}
    184 	signal(SIGALRM, f);
    185 	return (timeout == 0);
    186 }
    187 
    188 static int
    189 flush(s)
    190 	char *s;
    191 {
    192 	sig_t f;
    193 	char c;
    194 
    195 	f = signal(SIGALRM, sigALRM);
    196 	while (*s++) {
    197 		if (setjmp(timeoutbuf))
    198 			break;
    199 		alarm(10);
    200 		read(FD, &c, 1);
    201 		alarm(0);
    202 	}
    203 	signal(SIGALRM, f);
    204 	timeout = 0;			/* guard against disconnection */
    205 }
    206 
    207 /*
    208  * This convoluted piece of code attempts to get
    209  *  the bizcomp in sync.  If you don't have the capacity or nread
    210  *  call there are gory ways to simulate this.
    211  */
    212 static int
    213 bizsync(fd)
    214 {
    215 #ifdef FIOCAPACITY
    216 	struct capacity b;
    217 #	define chars(b)	((b).cp_nbytes)
    218 #	define IOCTL	FIOCAPACITY
    219 #endif
    220 #ifdef FIONREAD
    221 	long b;
    222 #	define chars(b)	(b)
    223 #	define IOCTL	FIONREAD
    224 #endif
    225 	int already = 0;
    226 	char buf[10];
    227 
    228 retry:
    229 	if (ioctl(fd, IOCTL, (caddr_t)&b) >= 0 && chars(b) > 0)
    230 		tcflush(FD, TCIOFLUSH);
    231 	write(fd, "\rp>\r", 4);
    232 	sleep(1);
    233 	if (ioctl(fd, IOCTL, (caddr_t)&b) >= 0) {
    234 		if (chars(b) != 10) {
    235 	nono:
    236 			if (already > MAXRETRY)
    237 				return (0);
    238 			write(fd, DISCONNECT_CMD, 4);
    239 			sleep(2);
    240 			already++;
    241 			goto retry;
    242 		} else {
    243 			read(fd, buf, 10);
    244 			if (strncmp(buf, "p >\r\n\r\n>", 8))
    245 				goto nono;
    246 		}
    247 	}
    248 	return (1);
    249 }
    250