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