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