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);
247c478bd9Sstevel@tonic-gate static int timeout = 0;
257c478bd9Sstevel@tonic-gate static sigjmp_buf timeoutbuf;
267c478bd9Sstevel@tonic-gate
27*8d489c7aSmuffin void biz31_disconnect(void);
28*8d489c7aSmuffin
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",
707c478bd9Sstevel@tonic-gate 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