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