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) 06/06/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 } 222