xref: /onnv-gate/usr/src/cmd/tip/aculib/biz31.c (revision 549:9e644232f978)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
30Sstevel@tonic-gate  * Use is subject to license terms.
40Sstevel@tonic-gate  */
5*549Smuffin 
60Sstevel@tonic-gate /*
70Sstevel@tonic-gate  * Copyright (c) 1983 Regents of the University of California.
80Sstevel@tonic-gate  * All rights reserved. The Berkeley software License Agreement
90Sstevel@tonic-gate  * specifies the terms and conditions for redistribution.
100Sstevel@tonic-gate  */
11*549Smuffin 
12*549Smuffin #pragma ident	"%Z%%M%	%I%	%E% SMI"
130Sstevel@tonic-gate 
140Sstevel@tonic-gate #include "tip.h"
150Sstevel@tonic-gate 
160Sstevel@tonic-gate #define	MAXRETRY	3		/* sync up retry count */
170Sstevel@tonic-gate #define	DISCONNECT_CMD	"\21\25\11\24"	/* disconnection string */
180Sstevel@tonic-gate 
19*549Smuffin static int	detect(char *);
20*549Smuffin static int	bizsync(int);
21*549Smuffin static void	echo(char *);
22*549Smuffin static void	flush(char *);
23*549Smuffin static void	sigALRM(void);
24*549Smuffin static int	timeout = 0;
25*549Smuffin static sigjmp_buf	timeoutbuf;
26*549Smuffin 
27*549Smuffin void	biz31_disconnect(void);
280Sstevel@tonic-gate 
290Sstevel@tonic-gate /*
300Sstevel@tonic-gate  * Dial up on a BIZCOMP Model 1031 with either
310Sstevel@tonic-gate  * 	tone dialing (mod = "f")
320Sstevel@tonic-gate  *	pulse dialing (mod = "w")
330Sstevel@tonic-gate  */
340Sstevel@tonic-gate static int
biz_dialer(char * num,char * mod)35*549Smuffin biz_dialer(char *num, char *mod)
360Sstevel@tonic-gate {
37*549Smuffin 	int connected = 0;
380Sstevel@tonic-gate 
390Sstevel@tonic-gate 	if (!bizsync(FD)) {
400Sstevel@tonic-gate 		logent(value(HOST), "", "biz", "out of sync");
41*549Smuffin 		(void) printf("bizcomp out of sync\n");
420Sstevel@tonic-gate 		delock(uucplock);
430Sstevel@tonic-gate 		exit(0);
440Sstevel@tonic-gate 	}
450Sstevel@tonic-gate 	if (boolean(value(VERBOSE)))
46*549Smuffin 		(void) printf("\nstarting call...");
470Sstevel@tonic-gate 	echo("#\rk$\r$\n");			/* disable auto-answer */
480Sstevel@tonic-gate 	echo("$>$.$ #\r");			/* tone/pulse dialing */
490Sstevel@tonic-gate 	echo(mod);
500Sstevel@tonic-gate 	echo("$\r$\n");
510Sstevel@tonic-gate 	echo("$>$.$ #\re$ ");			/* disconnection sequence */
520Sstevel@tonic-gate 	echo(DISCONNECT_CMD);
530Sstevel@tonic-gate 	echo("\r$\n$\r$\n");
540Sstevel@tonic-gate 	echo("$>$.$ #\rr$ ");			/* repeat dial */
550Sstevel@tonic-gate 	echo(num);
560Sstevel@tonic-gate 	echo("\r$\n");
570Sstevel@tonic-gate 	if (boolean(value(VERBOSE)))
58*549Smuffin 		(void) printf("ringing...");
590Sstevel@tonic-gate 	/*
600Sstevel@tonic-gate 	 * The reply from the BIZCOMP should be:
610Sstevel@tonic-gate 	 *	`^G NO CONNECTION\r\n^G\r\n'	failure
620Sstevel@tonic-gate 	 *	` CONNECTION\r\n^G'		success
630Sstevel@tonic-gate 	 */
640Sstevel@tonic-gate 	connected = detect(" ");
650Sstevel@tonic-gate #ifdef ACULOG
660Sstevel@tonic-gate 	if (timeout) {
670Sstevel@tonic-gate 		char line[80];
680Sstevel@tonic-gate 
69*549Smuffin 		(void) sprintf(line, "%d second dial timeout",
70*549Smuffin 		    number(value(DIALTIMEOUT)));
710Sstevel@tonic-gate 		logent(value(HOST), num, "biz", line);
720Sstevel@tonic-gate 	}
730Sstevel@tonic-gate #endif
740Sstevel@tonic-gate 	if (!connected)
750Sstevel@tonic-gate 		flush(" NO CONNECTION\r\n\07\r\n");
760Sstevel@tonic-gate 	else
770Sstevel@tonic-gate 		flush("CONNECTION\r\n\07");
780Sstevel@tonic-gate 	if (timeout)
790Sstevel@tonic-gate 		biz31_disconnect();	/* insurance */
800Sstevel@tonic-gate 	return (connected);
810Sstevel@tonic-gate }
820Sstevel@tonic-gate 
83*549Smuffin /* ARGSUSED */
84*549Smuffin int
biz31w_dialer(char * num,char * acu)85*549Smuffin biz31w_dialer(char *num, char *acu)
860Sstevel@tonic-gate {
870Sstevel@tonic-gate 
880Sstevel@tonic-gate 	return (biz_dialer(num, "w"));
890Sstevel@tonic-gate }
900Sstevel@tonic-gate 
91*549Smuffin /* ARGSUSED */
92*549Smuffin int
biz31f_dialer(char * num,char * acu)93*549Smuffin biz31f_dialer(char *num, char *acu)
940Sstevel@tonic-gate {
950Sstevel@tonic-gate 
960Sstevel@tonic-gate 	return (biz_dialer(num, "f"));
970Sstevel@tonic-gate }
980Sstevel@tonic-gate 
99*549Smuffin void
biz31_disconnect(void)100*549Smuffin biz31_disconnect(void)
1010Sstevel@tonic-gate {
1020Sstevel@tonic-gate 
103*549Smuffin 	(void) write(FD, DISCONNECT_CMD, 4);
104*549Smuffin 	(void) sleep(2);
105*549Smuffin 	(void) ioctl(FD, TCFLSH, TCOFLUSH);
1060Sstevel@tonic-gate }
1070Sstevel@tonic-gate 
108*549Smuffin void
biz31_abort(void)109*549Smuffin biz31_abort(void)
1100Sstevel@tonic-gate {
1110Sstevel@tonic-gate 
112*549Smuffin 	(void) write(FD, "\33", 1);
1130Sstevel@tonic-gate }
1140Sstevel@tonic-gate 
115*549Smuffin static void
echo(char * s)116*549Smuffin echo(char *s)
1170Sstevel@tonic-gate {
1180Sstevel@tonic-gate 	char c;
1190Sstevel@tonic-gate 
1200Sstevel@tonic-gate 	while (c = *s++) {
1210Sstevel@tonic-gate 		switch (c) {
1220Sstevel@tonic-gate 		case '$':
123*549Smuffin 			(void) read(FD, &c, 1);
1240Sstevel@tonic-gate 			s++;
1250Sstevel@tonic-gate 			break;
1260Sstevel@tonic-gate 
1270Sstevel@tonic-gate 		case '#':
1280Sstevel@tonic-gate 			c = *s++;
129*549Smuffin 			(void) write(FD, &c, 1);
1300Sstevel@tonic-gate 			break;
1310Sstevel@tonic-gate 
1320Sstevel@tonic-gate 		default:
133*549Smuffin 			(void) write(FD, &c, 1);
134*549Smuffin 			(void) read(FD, &c, 1);
1350Sstevel@tonic-gate 		}
1360Sstevel@tonic-gate 	}
1370Sstevel@tonic-gate }
1380Sstevel@tonic-gate 
1390Sstevel@tonic-gate static void
sigALRM(void)140*549Smuffin sigALRM(void)
1410Sstevel@tonic-gate {
1420Sstevel@tonic-gate 
1430Sstevel@tonic-gate 	timeout = 1;
1440Sstevel@tonic-gate 	siglongjmp(timeoutbuf, 1);
1450Sstevel@tonic-gate }
1460Sstevel@tonic-gate 
1470Sstevel@tonic-gate static int
detect(char * s)148*549Smuffin detect(char *s)
1490Sstevel@tonic-gate {
1500Sstevel@tonic-gate 	char c;
1510Sstevel@tonic-gate 	sig_handler_t f;
1520Sstevel@tonic-gate 
1530Sstevel@tonic-gate 	f = signal(SIGALRM, (sig_handler_t)sigALRM);
1540Sstevel@tonic-gate 	timeout = 0;
1550Sstevel@tonic-gate 	while (*s) {
1560Sstevel@tonic-gate 		if (sigsetjmp(timeoutbuf, 1)) {
157*549Smuffin 			(void) printf("\07timeout waiting for reply\n");
1580Sstevel@tonic-gate 			biz31_abort();
1590Sstevel@tonic-gate 			break;
1600Sstevel@tonic-gate 		}
161*549Smuffin 		(void) alarm(number(value(DIALTIMEOUT)));
162*549Smuffin 		(void) read(FD, &c, 1);
163*549Smuffin 		(void) alarm(0);
1640Sstevel@tonic-gate 		if (c != *s++)
1650Sstevel@tonic-gate 			break;
1660Sstevel@tonic-gate 	}
167*549Smuffin 	(void) signal(SIGALRM, f);
1680Sstevel@tonic-gate 	return (timeout == 0);
1690Sstevel@tonic-gate }
1700Sstevel@tonic-gate 
171*549Smuffin static void
flush(char * s)172*549Smuffin flush(char *s)
1730Sstevel@tonic-gate {
1740Sstevel@tonic-gate 	char c;
1750Sstevel@tonic-gate 	sig_handler_t f;
1760Sstevel@tonic-gate 
1770Sstevel@tonic-gate 	f = signal(SIGALRM, (sig_handler_t)sigALRM);
1780Sstevel@tonic-gate 	while (*s++) {
1790Sstevel@tonic-gate 		if (sigsetjmp(timeoutbuf, 1))
1800Sstevel@tonic-gate 			break;
181*549Smuffin 		(void) alarm(10);
182*549Smuffin 		(void) read(FD, &c, 1);
183*549Smuffin 		(void) alarm(0);
1840Sstevel@tonic-gate 	}
185*549Smuffin 	(void) signal(SIGALRM, f);
1860Sstevel@tonic-gate 	timeout = 0;			/* guard against disconnection */
1870Sstevel@tonic-gate }
1880Sstevel@tonic-gate 
1890Sstevel@tonic-gate /*
1900Sstevel@tonic-gate  * This convoluted piece of code attempts to get
1910Sstevel@tonic-gate  *  the bizcomp in sync.  If you don't have the capacity or nread
1920Sstevel@tonic-gate  *  call there are gory ways to simulate this.
1930Sstevel@tonic-gate  */
1940Sstevel@tonic-gate static int
bizsync(int fd)195*549Smuffin bizsync(int fd)
1960Sstevel@tonic-gate {
1970Sstevel@tonic-gate #ifdef FIOCAPACITY
1980Sstevel@tonic-gate 	struct capacity b;
1990Sstevel@tonic-gate #define	chars(b)	((b).cp_nbytes)
2000Sstevel@tonic-gate #define	IOCTL	FIOCAPACITY
2010Sstevel@tonic-gate #endif
2020Sstevel@tonic-gate #ifdef FIONREAD
2030Sstevel@tonic-gate 	long b;
2040Sstevel@tonic-gate #define	chars(b)	(b)
2050Sstevel@tonic-gate #define	IOCTL	FIONREAD
2060Sstevel@tonic-gate #endif
207*549Smuffin 	int already = 0;
2080Sstevel@tonic-gate 	char buf[10];
2090Sstevel@tonic-gate 
2100Sstevel@tonic-gate retry:
2110Sstevel@tonic-gate 	if (ioctl(fd, IOCTL, (caddr_t)&b) >= 0 && chars(b) > 0)
212*549Smuffin 		(void) ioctl(fd, TCFLSH, TCIOFLUSH);
213*549Smuffin 	(void) write(fd, "\rp>\r", 4);
214*549Smuffin 	(void) sleep(1);
2150Sstevel@tonic-gate 	if (ioctl(fd, IOCTL, (caddr_t)&b) >= 0) {
2160Sstevel@tonic-gate 		if (chars(b) != 10) {
2170Sstevel@tonic-gate 	nono:
2180Sstevel@tonic-gate 			if (already > MAXRETRY)
2190Sstevel@tonic-gate 				return (0);
220*549Smuffin 			(void) write(fd, DISCONNECT_CMD, 4);
221*549Smuffin 			(void) sleep(2);
2220Sstevel@tonic-gate 			already++;
2230Sstevel@tonic-gate 			goto retry;
2240Sstevel@tonic-gate 		} else {
225*549Smuffin 			(void) read(fd, buf, 10);
2260Sstevel@tonic-gate 			if (strncmp(buf, "p >\r\n\r\n>", 8))
2270Sstevel@tonic-gate 				goto nono;
2280Sstevel@tonic-gate 		}
2290Sstevel@tonic-gate 	}
2300Sstevel@tonic-gate 	return (1);
2310Sstevel@tonic-gate }
232