xref: /illumos-gate/usr/src/cmd/tip/aculib/biz31.c (revision 8d489c7a)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
37c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
47c478bd9Sstevel@tonic-gate  */
5*8d489c7aSmuffin 
67c478bd9Sstevel@tonic-gate /*
77c478bd9Sstevel@tonic-gate  * Copyright (c) 1983 Regents of the University of California.
87c478bd9Sstevel@tonic-gate  * All rights reserved. The Berkeley software License Agreement
97c478bd9Sstevel@tonic-gate  * specifies the terms and conditions for redistribution.
107c478bd9Sstevel@tonic-gate  */
11*8d489c7aSmuffin 
12*8d489c7aSmuffin #pragma ident	"%Z%%M%	%I%	%E% SMI"
137c478bd9Sstevel@tonic-gate 
147c478bd9Sstevel@tonic-gate #include "tip.h"
157c478bd9Sstevel@tonic-gate 
167c478bd9Sstevel@tonic-gate #define	MAXRETRY	3		/* sync up retry count */
177c478bd9Sstevel@tonic-gate #define	DISCONNECT_CMD	"\21\25\11\24"	/* disconnection string */
187c478bd9Sstevel@tonic-gate 
19*8d489c7aSmuffin static int	detect(char *);
20*8d489c7aSmuffin static int	bizsync(int);
21*8d489c7aSmuffin static void	echo(char *);
22*8d489c7aSmuffin static void	flush(char *);
23*8d489c7aSmuffin static void	sigALRM(void);
24*8d489c7aSmuffin static int	timeout = 0;
25*8d489c7aSmuffin static sigjmp_buf	timeoutbuf;
26*8d489c7aSmuffin 
27*8d489c7aSmuffin void	biz31_disconnect(void);
287c478bd9Sstevel@tonic-gate 
297c478bd9Sstevel@tonic-gate /*
307c478bd9Sstevel@tonic-gate  * Dial up on a BIZCOMP Model 1031 with either
317c478bd9Sstevel@tonic-gate  * 	tone dialing (mod = "f")
327c478bd9Sstevel@tonic-gate  *	pulse dialing (mod = "w")
337c478bd9Sstevel@tonic-gate  */
347c478bd9Sstevel@tonic-gate static int
biz_dialer(char * num,char * mod)35*8d489c7aSmuffin biz_dialer(char *num, char *mod)
367c478bd9Sstevel@tonic-gate {
37*8d489c7aSmuffin 	int connected = 0;
387c478bd9Sstevel@tonic-gate 
397c478bd9Sstevel@tonic-gate 	if (!bizsync(FD)) {
407c478bd9Sstevel@tonic-gate 		logent(value(HOST), "", "biz", "out of sync");
41*8d489c7aSmuffin 		(void) printf("bizcomp out of sync\n");
427c478bd9Sstevel@tonic-gate 		delock(uucplock);
437c478bd9Sstevel@tonic-gate 		exit(0);
447c478bd9Sstevel@tonic-gate 	}
457c478bd9Sstevel@tonic-gate 	if (boolean(value(VERBOSE)))
46*8d489c7aSmuffin 		(void) printf("\nstarting call...");
477c478bd9Sstevel@tonic-gate 	echo("#\rk$\r$\n");			/* disable auto-answer */
487c478bd9Sstevel@tonic-gate 	echo("$>$.$ #\r");			/* tone/pulse dialing */
497c478bd9Sstevel@tonic-gate 	echo(mod);
507c478bd9Sstevel@tonic-gate 	echo("$\r$\n");
517c478bd9Sstevel@tonic-gate 	echo("$>$.$ #\re$ ");			/* disconnection sequence */
527c478bd9Sstevel@tonic-gate 	echo(DISCONNECT_CMD);
537c478bd9Sstevel@tonic-gate 	echo("\r$\n$\r$\n");
547c478bd9Sstevel@tonic-gate 	echo("$>$.$ #\rr$ ");			/* repeat dial */
557c478bd9Sstevel@tonic-gate 	echo(num);
567c478bd9Sstevel@tonic-gate 	echo("\r$\n");
577c478bd9Sstevel@tonic-gate 	if (boolean(value(VERBOSE)))
58*8d489c7aSmuffin 		(void) printf("ringing...");
597c478bd9Sstevel@tonic-gate 	/*
607c478bd9Sstevel@tonic-gate 	 * The reply from the BIZCOMP should be:
617c478bd9Sstevel@tonic-gate 	 *	`^G NO CONNECTION\r\n^G\r\n'	failure
627c478bd9Sstevel@tonic-gate 	 *	` CONNECTION\r\n^G'		success
637c478bd9Sstevel@tonic-gate 	 */
647c478bd9Sstevel@tonic-gate 	connected = detect(" ");
657c478bd9Sstevel@tonic-gate #ifdef ACULOG
667c478bd9Sstevel@tonic-gate 	if (timeout) {
677c478bd9Sstevel@tonic-gate 		char line[80];
687c478bd9Sstevel@tonic-gate 
69*8d489c7aSmuffin 		(void) sprintf(line, "%d second dial timeout",
70*8d489c7aSmuffin 		    number(value(DIALTIMEOUT)));
717c478bd9Sstevel@tonic-gate 		logent(value(HOST), num, "biz", line);
727c478bd9Sstevel@tonic-gate 	}
737c478bd9Sstevel@tonic-gate #endif
747c478bd9Sstevel@tonic-gate 	if (!connected)
757c478bd9Sstevel@tonic-gate 		flush(" NO CONNECTION\r\n\07\r\n");
767c478bd9Sstevel@tonic-gate 	else
777c478bd9Sstevel@tonic-gate 		flush("CONNECTION\r\n\07");
787c478bd9Sstevel@tonic-gate 	if (timeout)
797c478bd9Sstevel@tonic-gate 		biz31_disconnect();	/* insurance */
807c478bd9Sstevel@tonic-gate 	return (connected);
817c478bd9Sstevel@tonic-gate }
827c478bd9Sstevel@tonic-gate 
83*8d489c7aSmuffin /* ARGSUSED */
84*8d489c7aSmuffin int
biz31w_dialer(char * num,char * acu)85*8d489c7aSmuffin biz31w_dialer(char *num, char *acu)
867c478bd9Sstevel@tonic-gate {
877c478bd9Sstevel@tonic-gate 
887c478bd9Sstevel@tonic-gate 	return (biz_dialer(num, "w"));
897c478bd9Sstevel@tonic-gate }
907c478bd9Sstevel@tonic-gate 
91*8d489c7aSmuffin /* ARGSUSED */
92*8d489c7aSmuffin int
biz31f_dialer(char * num,char * acu)93*8d489c7aSmuffin biz31f_dialer(char *num, char *acu)
947c478bd9Sstevel@tonic-gate {
957c478bd9Sstevel@tonic-gate 
967c478bd9Sstevel@tonic-gate 	return (biz_dialer(num, "f"));
977c478bd9Sstevel@tonic-gate }
987c478bd9Sstevel@tonic-gate 
99*8d489c7aSmuffin void
biz31_disconnect(void)100*8d489c7aSmuffin biz31_disconnect(void)
1017c478bd9Sstevel@tonic-gate {
1027c478bd9Sstevel@tonic-gate 
103*8d489c7aSmuffin 	(void) write(FD, DISCONNECT_CMD, 4);
104*8d489c7aSmuffin 	(void) sleep(2);
105*8d489c7aSmuffin 	(void) ioctl(FD, TCFLSH, TCOFLUSH);
1067c478bd9Sstevel@tonic-gate }
1077c478bd9Sstevel@tonic-gate 
108*8d489c7aSmuffin void
biz31_abort(void)109*8d489c7aSmuffin biz31_abort(void)
1107c478bd9Sstevel@tonic-gate {
1117c478bd9Sstevel@tonic-gate 
112*8d489c7aSmuffin 	(void) write(FD, "\33", 1);
1137c478bd9Sstevel@tonic-gate }
1147c478bd9Sstevel@tonic-gate 
115*8d489c7aSmuffin static void
echo(char * s)116*8d489c7aSmuffin echo(char *s)
1177c478bd9Sstevel@tonic-gate {
1187c478bd9Sstevel@tonic-gate 	char c;
1197c478bd9Sstevel@tonic-gate 
1207c478bd9Sstevel@tonic-gate 	while (c = *s++) {
1217c478bd9Sstevel@tonic-gate 		switch (c) {
1227c478bd9Sstevel@tonic-gate 		case '$':
123*8d489c7aSmuffin 			(void) read(FD, &c, 1);
1247c478bd9Sstevel@tonic-gate 			s++;
1257c478bd9Sstevel@tonic-gate 			break;
1267c478bd9Sstevel@tonic-gate 
1277c478bd9Sstevel@tonic-gate 		case '#':
1287c478bd9Sstevel@tonic-gate 			c = *s++;
129*8d489c7aSmuffin 			(void) write(FD, &c, 1);
1307c478bd9Sstevel@tonic-gate 			break;
1317c478bd9Sstevel@tonic-gate 
1327c478bd9Sstevel@tonic-gate 		default:
133*8d489c7aSmuffin 			(void) write(FD, &c, 1);
134*8d489c7aSmuffin 			(void) read(FD, &c, 1);
1357c478bd9Sstevel@tonic-gate 		}
1367c478bd9Sstevel@tonic-gate 	}
1377c478bd9Sstevel@tonic-gate }
1387c478bd9Sstevel@tonic-gate 
1397c478bd9Sstevel@tonic-gate static void
sigALRM(void)140*8d489c7aSmuffin sigALRM(void)
1417c478bd9Sstevel@tonic-gate {
1427c478bd9Sstevel@tonic-gate 
1437c478bd9Sstevel@tonic-gate 	timeout = 1;
1447c478bd9Sstevel@tonic-gate 	siglongjmp(timeoutbuf, 1);
1457c478bd9Sstevel@tonic-gate }
1467c478bd9Sstevel@tonic-gate 
1477c478bd9Sstevel@tonic-gate static int
detect(char * s)148*8d489c7aSmuffin detect(char *s)
1497c478bd9Sstevel@tonic-gate {
1507c478bd9Sstevel@tonic-gate 	char c;
1517c478bd9Sstevel@tonic-gate 	sig_handler_t f;
1527c478bd9Sstevel@tonic-gate 
1537c478bd9Sstevel@tonic-gate 	f = signal(SIGALRM, (sig_handler_t)sigALRM);
1547c478bd9Sstevel@tonic-gate 	timeout = 0;
1557c478bd9Sstevel@tonic-gate 	while (*s) {
1567c478bd9Sstevel@tonic-gate 		if (sigsetjmp(timeoutbuf, 1)) {
157*8d489c7aSmuffin 			(void) printf("\07timeout waiting for reply\n");
1587c478bd9Sstevel@tonic-gate 			biz31_abort();
1597c478bd9Sstevel@tonic-gate 			break;
1607c478bd9Sstevel@tonic-gate 		}
161*8d489c7aSmuffin 		(void) alarm(number(value(DIALTIMEOUT)));
162*8d489c7aSmuffin 		(void) read(FD, &c, 1);
163*8d489c7aSmuffin 		(void) alarm(0);
1647c478bd9Sstevel@tonic-gate 		if (c != *s++)
1657c478bd9Sstevel@tonic-gate 			break;
1667c478bd9Sstevel@tonic-gate 	}
167*8d489c7aSmuffin 	(void) signal(SIGALRM, f);
1687c478bd9Sstevel@tonic-gate 	return (timeout == 0);
1697c478bd9Sstevel@tonic-gate }
1707c478bd9Sstevel@tonic-gate 
171*8d489c7aSmuffin static void
flush(char * s)172*8d489c7aSmuffin flush(char *s)
1737c478bd9Sstevel@tonic-gate {
1747c478bd9Sstevel@tonic-gate 	char c;
1757c478bd9Sstevel@tonic-gate 	sig_handler_t f;
1767c478bd9Sstevel@tonic-gate 
1777c478bd9Sstevel@tonic-gate 	f = signal(SIGALRM, (sig_handler_t)sigALRM);
1787c478bd9Sstevel@tonic-gate 	while (*s++) {
1797c478bd9Sstevel@tonic-gate 		if (sigsetjmp(timeoutbuf, 1))
1807c478bd9Sstevel@tonic-gate 			break;
181*8d489c7aSmuffin 		(void) alarm(10);
182*8d489c7aSmuffin 		(void) read(FD, &c, 1);
183*8d489c7aSmuffin 		(void) alarm(0);
1847c478bd9Sstevel@tonic-gate 	}
185*8d489c7aSmuffin 	(void) signal(SIGALRM, f);
1867c478bd9Sstevel@tonic-gate 	timeout = 0;			/* guard against disconnection */
1877c478bd9Sstevel@tonic-gate }
1887c478bd9Sstevel@tonic-gate 
1897c478bd9Sstevel@tonic-gate /*
1907c478bd9Sstevel@tonic-gate  * This convoluted piece of code attempts to get
1917c478bd9Sstevel@tonic-gate  *  the bizcomp in sync.  If you don't have the capacity or nread
1927c478bd9Sstevel@tonic-gate  *  call there are gory ways to simulate this.
1937c478bd9Sstevel@tonic-gate  */
1947c478bd9Sstevel@tonic-gate static int
bizsync(int fd)195*8d489c7aSmuffin bizsync(int fd)
1967c478bd9Sstevel@tonic-gate {
1977c478bd9Sstevel@tonic-gate #ifdef FIOCAPACITY
1987c478bd9Sstevel@tonic-gate 	struct capacity b;
1997c478bd9Sstevel@tonic-gate #define	chars(b)	((b).cp_nbytes)
2007c478bd9Sstevel@tonic-gate #define	IOCTL	FIOCAPACITY
2017c478bd9Sstevel@tonic-gate #endif
2027c478bd9Sstevel@tonic-gate #ifdef FIONREAD
2037c478bd9Sstevel@tonic-gate 	long b;
2047c478bd9Sstevel@tonic-gate #define	chars(b)	(b)
2057c478bd9Sstevel@tonic-gate #define	IOCTL	FIONREAD
2067c478bd9Sstevel@tonic-gate #endif
207*8d489c7aSmuffin 	int already = 0;
2087c478bd9Sstevel@tonic-gate 	char buf[10];
2097c478bd9Sstevel@tonic-gate 
2107c478bd9Sstevel@tonic-gate retry:
2117c478bd9Sstevel@tonic-gate 	if (ioctl(fd, IOCTL, (caddr_t)&b) >= 0 && chars(b) > 0)
212*8d489c7aSmuffin 		(void) ioctl(fd, TCFLSH, TCIOFLUSH);
213*8d489c7aSmuffin 	(void) write(fd, "\rp>\r", 4);
214*8d489c7aSmuffin 	(void) sleep(1);
2157c478bd9Sstevel@tonic-gate 	if (ioctl(fd, IOCTL, (caddr_t)&b) >= 0) {
2167c478bd9Sstevel@tonic-gate 		if (chars(b) != 10) {
2177c478bd9Sstevel@tonic-gate 	nono:
2187c478bd9Sstevel@tonic-gate 			if (already > MAXRETRY)
2197c478bd9Sstevel@tonic-gate 				return (0);
220*8d489c7aSmuffin 			(void) write(fd, DISCONNECT_CMD, 4);
221*8d489c7aSmuffin 			(void) sleep(2);
2227c478bd9Sstevel@tonic-gate 			already++;
2237c478bd9Sstevel@tonic-gate 			goto retry;
2247c478bd9Sstevel@tonic-gate 		} else {
225*8d489c7aSmuffin 			(void) read(fd, buf, 10);
2267c478bd9Sstevel@tonic-gate 			if (strncmp(buf, "p >\r\n\r\n>", 8))
2277c478bd9Sstevel@tonic-gate 				goto nono;
2287c478bd9Sstevel@tonic-gate 		}
2297c478bd9Sstevel@tonic-gate 	}
2307c478bd9Sstevel@tonic-gate 	return (1);
2317c478bd9Sstevel@tonic-gate }
232