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