Home | History | Annotate | Line # | Download | only in aculib
biz31.c revision 1.1
      1 /*
      2  * Copyright (c) 1983 The Regents of the University of California.
      3  * All rights reserved.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions
      7  * are met:
      8  * 1. Redistributions of source code must retain the above copyright
      9  *    notice, this list of conditions and the following disclaimer.
     10  * 2. Redistributions in binary form must reproduce the above copyright
     11  *    notice, this list of conditions and the following disclaimer in the
     12  *    documentation and/or other materials provided with the distribution.
     13  * 3. All advertising materials mentioning features or use of this software
     14  *    must display the following acknowledgement:
     15  *	This product includes software developed by the University of
     16  *	California, Berkeley and its contributors.
     17  * 4. Neither the name of the University nor the names of its contributors
     18  *    may be used to endorse or promote products derived from this software
     19  *    without specific prior written permission.
     20  *
     21  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     31  * SUCH DAMAGE.
     32  */
     33 
     34 #ifndef lint
     35 static char sccsid[] = "@(#)biz31.c	5.4 (Berkeley) 6/1/90";
     36 #endif /* not lint */
     37 
     38 #include "tip.h"
     39 
     40 #define MAXRETRY	3		/* sync up retry count */
     41 #define DISCONNECT_CMD	"\21\25\11\24"	/* disconnection string */
     42 
     43 static	void sigALRM();
     44 static	int timeout = 0;
     45 static	jmp_buf timeoutbuf;
     46 
     47 /*
     48  * Dial up on a BIZCOMP Model 1031 with either
     49  * 	tone dialing (mod = "f")
     50  *	pulse dialing (mod = "w")
     51  */
     52 static int
     53 biz_dialer(num, mod)
     54 	char *num, *mod;
     55 {
     56 	register int connected = 0;
     57 
     58 	if (!bizsync(FD)) {
     59 		logent(value(HOST), "", "biz", "out of sync");
     60 		printf("bizcomp out of sync\n");
     61 		delock(uucplock);
     62 		exit(0);
     63 	}
     64 	if (boolean(value(VERBOSE)))
     65 		printf("\nstarting call...");
     66 	echo("#\rk$\r$\n");			/* disable auto-answer */
     67 	echo("$>$.$ #\r");			/* tone/pulse dialing */
     68 	echo(mod);
     69 	echo("$\r$\n");
     70 	echo("$>$.$ #\re$ ");			/* disconnection sequence */
     71 	echo(DISCONNECT_CMD);
     72 	echo("\r$\n$\r$\n");
     73 	echo("$>$.$ #\rr$ ");			/* repeat dial */
     74 	echo(num);
     75 	echo("\r$\n");
     76 	if (boolean(value(VERBOSE)))
     77 		printf("ringing...");
     78 	/*
     79 	 * The reply from the BIZCOMP should be:
     80 	 *	`^G NO CONNECTION\r\n^G\r\n'	failure
     81 	 *	` CONNECTION\r\n^G'		success
     82 	 */
     83 	connected = detect(" ");
     84 #ifdef ACULOG
     85 	if (timeout) {
     86 		char line[80];
     87 
     88 		sprintf(line, "%d second dial timeout",
     89 			number(value(DIALTIMEOUT)));
     90 		logent(value(HOST), num, "biz", line);
     91 	}
     92 #endif
     93 	if (!connected)
     94 		flush(" NO CONNECTION\r\n\07\r\n");
     95 	else
     96 		flush("CONNECTION\r\n\07");
     97 	if (timeout)
     98 		biz31_disconnect();	/* insurance */
     99 	return (connected);
    100 }
    101 
    102 biz31w_dialer(num, acu)
    103 	char *num, *acu;
    104 {
    105 
    106 	return (biz_dialer(num, "w"));
    107 }
    108 
    109 biz31f_dialer(num, acu)
    110 	char *num, *acu;
    111 {
    112 
    113 	return (biz_dialer(num, "f"));
    114 }
    115 
    116 biz31_disconnect()
    117 {
    118 
    119 	write(FD, DISCONNECT_CMD, 4);
    120 	sleep(2);
    121 	ioctl(FD, TIOCFLUSH);
    122 }
    123 
    124 biz31_abort()
    125 {
    126 
    127 	write(FD, "\33", 1);
    128 }
    129 
    130 static int
    131 echo(s)
    132 	register char *s;
    133 {
    134 	char c;
    135 
    136 	while (c = *s++) switch (c) {
    137 
    138 	case '$':
    139 		read(FD, &c, 1);
    140 		s++;
    141 		break;
    142 
    143 	case '#':
    144 		c = *s++;
    145 		write(FD, &c, 1);
    146 		break;
    147 
    148 	default:
    149 		write(FD, &c, 1);
    150 		read(FD, &c, 1);
    151 	}
    152 }
    153 
    154 static void
    155 sigALRM()
    156 {
    157 
    158 	timeout = 1;
    159 	longjmp(timeoutbuf, 1);
    160 }
    161 
    162 static int
    163 detect(s)
    164 	register char *s;
    165 {
    166 	sig_t f;
    167 	char c;
    168 
    169 	f = signal(SIGALRM, sigALRM);
    170 	timeout = 0;
    171 	while (*s) {
    172 		if (setjmp(timeoutbuf)) {
    173 			printf("\07timeout waiting for reply\n");
    174 			biz31_abort();
    175 			break;
    176 		}
    177 		alarm(number(value(DIALTIMEOUT)));
    178 		read(FD, &c, 1);
    179 		alarm(0);
    180 		if (c != *s++)
    181 			break;
    182 	}
    183 	signal(SIGALRM, f);
    184 	return (timeout == 0);
    185 }
    186 
    187 static int
    188 flush(s)
    189 	register char *s;
    190 {
    191 	sig_t f;
    192 	char c;
    193 
    194 	f = signal(SIGALRM, sigALRM);
    195 	while (*s++) {
    196 		if (setjmp(timeoutbuf))
    197 			break;
    198 		alarm(10);
    199 		read(FD, &c, 1);
    200 		alarm(0);
    201 	}
    202 	signal(SIGALRM, f);
    203 	timeout = 0;			/* guard against disconnection */
    204 }
    205 
    206 /*
    207  * This convoluted piece of code attempts to get
    208  *  the bizcomp in sync.  If you don't have the capacity or nread
    209  *  call there are gory ways to simulate this.
    210  */
    211 static int
    212 bizsync(fd)
    213 {
    214 #ifdef FIOCAPACITY
    215 	struct capacity b;
    216 #	define chars(b)	((b).cp_nbytes)
    217 #	define IOCTL	FIOCAPACITY
    218 #endif
    219 #ifdef FIONREAD
    220 	long b;
    221 #	define chars(b)	(b)
    222 #	define IOCTL	FIONREAD
    223 #endif
    224 	register int already = 0;
    225 	char buf[10];
    226 
    227 retry:
    228 	if (ioctl(fd, IOCTL, (caddr_t)&b) >= 0 && chars(b) > 0)
    229 		ioctl(fd, TIOCFLUSH);
    230 	write(fd, "\rp>\r", 4);
    231 	sleep(1);
    232 	if (ioctl(fd, IOCTL, (caddr_t)&b) >= 0) {
    233 		if (chars(b) != 10) {
    234 	nono:
    235 			if (already > MAXRETRY)
    236 				return (0);
    237 			write(fd, DISCONNECT_CMD, 4);
    238 			sleep(2);
    239 			already++;
    240 			goto retry;
    241 		} else {
    242 			read(fd, buf, 10);
    243 			if (strncmp(buf, "p >\r\n\r\n>", 8))
    244 				goto nono;
    245 		}
    246 	}
    247 	return (1);
    248 }
    249