1 /* 2 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 */ 5 /* 6 * Copyright (c) 1983 Regents of the University of California. 7 * All rights reserved. The Berkeley software License Agreement 8 * specifies the terms and conditions for redistribution. 9 */ 10 #ident "%Z%%M% %I% %E% SMI" /* from UCB 4.7 6/25/83 */ 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 sigjmp_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, TCFLSH, TCOFLUSH); 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++) { 111 switch (c) { 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 129 static void 130 sigALRM() 131 { 132 133 timeout = 1; 134 siglongjmp(timeoutbuf, 1); 135 } 136 137 static int 138 detect(s) 139 register char *s; 140 { 141 char c; 142 sig_handler_t f; 143 144 f = signal(SIGALRM, (sig_handler_t)sigALRM); 145 timeout = 0; 146 while (*s) { 147 if (sigsetjmp(timeoutbuf, 1)) { 148 printf("\07timeout waiting for reply\n"); 149 biz31_abort(); 150 break; 151 } 152 alarm(number(value(DIALTIMEOUT))); 153 read(FD, &c, 1); 154 alarm(0); 155 if (c != *s++) 156 break; 157 } 158 signal(SIGALRM, f); 159 return (timeout == 0); 160 } 161 162 static int 163 flush(s) 164 register char *s; 165 { 166 char c; 167 sig_handler_t f; 168 169 f = signal(SIGALRM, (sig_handler_t)sigALRM); 170 while (*s++) { 171 if (sigsetjmp(timeoutbuf, 1)) 172 break; 173 alarm(10); 174 read(FD, &c, 1); 175 alarm(0); 176 } 177 signal(SIGALRM, f); 178 timeout = 0; /* guard against disconnection */ 179 } 180 181 /* 182 * This convoluted piece of code attempts to get 183 * the bizcomp in sync. If you don't have the capacity or nread 184 * call there are gory ways to simulate this. 185 */ 186 static int 187 bizsync(fd) 188 { 189 #ifdef FIOCAPACITY 190 struct capacity b; 191 #define chars(b) ((b).cp_nbytes) 192 #define IOCTL FIOCAPACITY 193 #endif 194 #ifdef FIONREAD 195 long b; 196 #define chars(b) (b) 197 #define IOCTL FIONREAD 198 #endif 199 register int already = 0; 200 char buf[10]; 201 202 retry: 203 if (ioctl(fd, IOCTL, (caddr_t)&b) >= 0 && chars(b) > 0) 204 ioctl(fd, TCFLSH, TCIOFLUSH); 205 write(fd, "\rp>\r", 4); 206 sleep(1); 207 if (ioctl(fd, IOCTL, (caddr_t)&b) >= 0) { 208 if (chars(b) != 10) { 209 nono: 210 if (already > MAXRETRY) 211 return (0); 212 write(fd, DISCONNECT_CMD, 4); 213 sleep(2); 214 already++; 215 goto retry; 216 } else { 217 read(fd, buf, 10); 218 if (strncmp(buf, "p >\r\n\r\n>", 8)) 219 goto nono; 220 } 221 } 222 return (1); 223 } 224