Home | History | Annotate | Download | only in aculib
      1 /*
      2  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
      3  * Use is subject to license terms.
      4  */
      5 
      6 /*
      7  * Copyright (c) 1983 Regents of the University of California.
      8  * All rights reserved. The Berkeley software License Agreement
      9  * specifies the terms and conditions for redistribution.
     10  */
     11 
     12 #pragma ident	"%Z%%M%	%I%	%E% SMI"
     13 
     14 #include "tip.h"
     15 
     16 #define	MAXRETRY	3		/* sync up retry count */
     17 #define	DISCONNECT_CMD	"\21\25\11\24"	/* disconnection string */
     18 
     19 static int	detect(char *);
     20 static int	bizsync(int);
     21 static void	echo(char *);
     22 static void	flush(char *);
     23 static void	sigALRM(void);
     24 static int	timeout = 0;
     25 static sigjmp_buf	timeoutbuf;
     26 
     27 void	biz31_disconnect(void);
     28 
     29 /*
     30  * Dial up on a BIZCOMP Model 1031 with either
     31  * 	tone dialing (mod = "f")
     32  *	pulse dialing (mod = "w")
     33  */
     34 static int
     35 biz_dialer(char *num, char *mod)
     36 {
     37 	int connected = 0;
     38 
     39 	if (!bizsync(FD)) {
     40 		logent(value(HOST), "", "biz", "out of sync");
     41 		(void) printf("bizcomp out of sync\n");
     42 		delock(uucplock);
     43 		exit(0);
     44 	}
     45 	if (boolean(value(VERBOSE)))
     46 		(void) printf("\nstarting call...");
     47 	echo("#\rk$\r$\n");			/* disable auto-answer */
     48 	echo("$>$.$ #\r");			/* tone/pulse dialing */
     49 	echo(mod);
     50 	echo("$\r$\n");
     51 	echo("$>$.$ #\re$ ");			/* disconnection sequence */
     52 	echo(DISCONNECT_CMD);
     53 	echo("\r$\n$\r$\n");
     54 	echo("$>$.$ #\rr$ ");			/* repeat dial */
     55 	echo(num);
     56 	echo("\r$\n");
     57 	if (boolean(value(VERBOSE)))
     58 		(void) printf("ringing...");
     59 	/*
     60 	 * The reply from the BIZCOMP should be:
     61 	 *	`^G NO CONNECTION\r\n^G\r\n'	failure
     62 	 *	` CONNECTION\r\n^G'		success
     63 	 */
     64 	connected = detect(" ");
     65 #ifdef ACULOG
     66 	if (timeout) {
     67 		char line[80];
     68 
     69 		(void) sprintf(line, "%d second dial timeout",
     70 		    number(value(DIALTIMEOUT)));
     71 		logent(value(HOST), num, "biz", line);
     72 	}
     73 #endif
     74 	if (!connected)
     75 		flush(" NO CONNECTION\r\n\07\r\n");
     76 	else
     77 		flush("CONNECTION\r\n\07");
     78 	if (timeout)
     79 		biz31_disconnect();	/* insurance */
     80 	return (connected);
     81 }
     82 
     83 /* ARGSUSED */
     84 int
     85 biz31w_dialer(char *num, char *acu)
     86 {
     87 
     88 	return (biz_dialer(num, "w"));
     89 }
     90 
     91 /* ARGSUSED */
     92 int
     93 biz31f_dialer(char *num, char *acu)
     94 {
     95 
     96 	return (biz_dialer(num, "f"));
     97 }
     98 
     99 void
    100 biz31_disconnect(void)
    101 {
    102 
    103 	(void) write(FD, DISCONNECT_CMD, 4);
    104 	(void) sleep(2);
    105 	(void) ioctl(FD, TCFLSH, TCOFLUSH);
    106 }
    107 
    108 void
    109 biz31_abort(void)
    110 {
    111 
    112 	(void) write(FD, "\33", 1);
    113 }
    114 
    115 static void
    116 echo(char *s)
    117 {
    118 	char c;
    119 
    120 	while (c = *s++) {
    121 		switch (c) {
    122 		case '$':
    123 			(void) read(FD, &c, 1);
    124 			s++;
    125 			break;
    126 
    127 		case '#':
    128 			c = *s++;
    129 			(void) write(FD, &c, 1);
    130 			break;
    131 
    132 		default:
    133 			(void) write(FD, &c, 1);
    134 			(void) read(FD, &c, 1);
    135 		}
    136 	}
    137 }
    138 
    139 static void
    140 sigALRM(void)
    141 {
    142 
    143 	timeout = 1;
    144 	siglongjmp(timeoutbuf, 1);
    145 }
    146 
    147 static int
    148 detect(char *s)
    149 {
    150 	char c;
    151 	sig_handler_t f;
    152 
    153 	f = signal(SIGALRM, (sig_handler_t)sigALRM);
    154 	timeout = 0;
    155 	while (*s) {
    156 		if (sigsetjmp(timeoutbuf, 1)) {
    157 			(void) printf("\07timeout waiting for reply\n");
    158 			biz31_abort();
    159 			break;
    160 		}
    161 		(void) alarm(number(value(DIALTIMEOUT)));
    162 		(void) read(FD, &c, 1);
    163 		(void) alarm(0);
    164 		if (c != *s++)
    165 			break;
    166 	}
    167 	(void) signal(SIGALRM, f);
    168 	return (timeout == 0);
    169 }
    170 
    171 static void
    172 flush(char *s)
    173 {
    174 	char c;
    175 	sig_handler_t f;
    176 
    177 	f = signal(SIGALRM, (sig_handler_t)sigALRM);
    178 	while (*s++) {
    179 		if (sigsetjmp(timeoutbuf, 1))
    180 			break;
    181 		(void) alarm(10);
    182 		(void) read(FD, &c, 1);
    183 		(void) alarm(0);
    184 	}
    185 	(void) signal(SIGALRM, f);
    186 	timeout = 0;			/* guard against disconnection */
    187 }
    188 
    189 /*
    190  * This convoluted piece of code attempts to get
    191  *  the bizcomp in sync.  If you don't have the capacity or nread
    192  *  call there are gory ways to simulate this.
    193  */
    194 static int
    195 bizsync(int fd)
    196 {
    197 #ifdef FIOCAPACITY
    198 	struct capacity b;
    199 #define	chars(b)	((b).cp_nbytes)
    200 #define	IOCTL	FIOCAPACITY
    201 #endif
    202 #ifdef FIONREAD
    203 	long b;
    204 #define	chars(b)	(b)
    205 #define	IOCTL	FIONREAD
    206 #endif
    207 	int already = 0;
    208 	char buf[10];
    209 
    210 retry:
    211 	if (ioctl(fd, IOCTL, (caddr_t)&b) >= 0 && chars(b) > 0)
    212 		(void) ioctl(fd, TCFLSH, TCIOFLUSH);
    213 	(void) write(fd, "\rp>\r", 4);
    214 	(void) sleep(1);
    215 	if (ioctl(fd, IOCTL, (caddr_t)&b) >= 0) {
    216 		if (chars(b) != 10) {
    217 	nono:
    218 			if (already > MAXRETRY)
    219 				return (0);
    220 			(void) write(fd, DISCONNECT_CMD, 4);
    221 			(void) sleep(2);
    222 			already++;
    223 			goto retry;
    224 		} else {
    225 			(void) read(fd, buf, 10);
    226 			if (strncmp(buf, "p >\r\n\r\n>", 8))
    227 				goto nono;
    228 		}
    229 	}
    230 	return (1);
    231 }
    232