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