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