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 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 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 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 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 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 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 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 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 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 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