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 /* 13 * Routines for dialing up on Vadic 831 14 */ 15 #include <sys/time.h> 16 17 #include "tip.h" 18 19 int AC; 20 static char dialit(char *, char *); 21 static char *sanitize(char *); 22 static void alarmtr(void); 23 24 static sigjmp_buf jmpbuf; 25 static int child = -1; 26 27 int 28 v831_dialer(char *num, char *acu) 29 { 30 int status, pid; 31 int timelim; 32 33 if (boolean(value(VERBOSE))) 34 (void) printf("\nstarting call..."); 35 #ifdef DEBUG 36 (void) printf("(acu=%s)\n", acu); 37 #endif 38 if ((AC = open(acu, O_RDWR)) < 0) { 39 if (errno == EBUSY) 40 (void) printf("line busy..."); 41 else 42 (void) printf("acu open error..."); 43 return (0); 44 } 45 if (sigsetjmp(jmpbuf, 1)) { 46 (void) kill(child, SIGKILL); 47 (void) close(AC); 48 return (0); 49 } 50 (void) signal(SIGALRM, (sig_handler_t)alarmtr); 51 timelim = 5 * strlen(num); 52 (void) alarm(timelim < 30 ? 30 : timelim); 53 if ((child = fork()) == 0) { 54 /* 55 * ignore this stuff for aborts 56 */ 57 (void) signal(SIGALRM, SIG_IGN); 58 (void) signal(SIGINT, SIG_IGN); 59 (void) signal(SIGQUIT, SIG_IGN); 60 (void) sleep(2); 61 exit(dialit(num, acu) != 'A'); 62 } 63 /* 64 * open line - will return on carrier 65 */ 66 if ((FD = open(DV, O_RDWR)) < 0) { 67 #ifdef DEBUG 68 (void) printf("(after open, errno=%d)\n", errno); 69 #endif 70 if (errno == EIO) 71 (void) printf("lost carrier..."); 72 else 73 (void) printf("dialup line open failed..."); 74 (void) alarm(0); 75 (void) kill(child, SIGKILL); 76 (void) close(AC); 77 return (0); 78 } 79 (void) alarm(0); 80 (void) signal(SIGALRM, SIG_DFL); 81 while ((pid = wait(&status)) != child && pid != -1) 82 ; 83 if (status) { 84 (void) close(AC); 85 return (0); 86 } 87 return (1); 88 } 89 90 static void 91 alarmtr(void) 92 { 93 94 (void) alarm(0); 95 siglongjmp(jmpbuf, 1); 96 } 97 98 /* 99 * Insurance, for some reason we don't seem to be 100 * hanging up... 101 */ 102 void 103 v831_disconnect(void) 104 { 105 struct termios cntrl; 106 int dtr = TIOCM_DTR; 107 108 (void) sleep(2); 109 #ifdef DEBUG 110 printf("[disconnect: FD=%d]\n", FD); 111 #endif 112 if (FD > 0) { 113 (void) ioctl(FD, TIOCMBIC, &dtr); 114 (void) ioctl(FD, TCGETS, &cntrl); 115 (void) cfsetospeed(&cntrl, B0); 116 cntrl.c_cflag &= ~XCLUDE; 117 (void) ioctl(FD, TCSETSF, &cntrl); 118 } 119 (void) close(FD); 120 } 121 122 void 123 v831_abort(void) 124 { 125 int dtr = TIOCM_DTR; 126 struct termios buf; 127 128 #ifdef DEBUG 129 (void) printf("[abort: AC=%d]\n", AC); 130 #endif 131 (void) sleep(2); 132 if (child > 0) 133 (void) kill(child, SIGKILL); 134 if (AC > 0) { 135 (void) ioctl(FD, TCGETS, &buf); 136 buf.c_cflag &= ~XCLUDE; 137 (void) ioctl(FD, TCSETSF, &buf); 138 (void) close(AC); 139 } 140 if (FD > 0) 141 (void) ioctl(FD, TIOCMBIC, &dtr); 142 (void) close(FD); 143 } 144 145 /* 146 * Sigh, this probably must be changed at each site. 147 */ 148 struct vaconfig { 149 char *vc_name; 150 char vc_rack; 151 char vc_modem; 152 } vaconfig[] = { 153 { "/dev/cua0", '4', '0' }, 154 { "/dev/cua1", '4', '1' }, 155 { 0 } 156 }; 157 158 #define pc(x) (c = x, (void) write(AC, &c, 1)) 159 #define ABORT 01 160 #define SI 017 161 #define STX 02 162 #define ETX 03 163 164 static char 165 dialit(char *phonenum, char *acu) 166 { 167 struct vaconfig *vp; 168 struct termios cntrl; 169 char c; 170 int i; 171 172 phonenum = sanitize(phonenum); 173 #ifdef DEBUG 174 (void) printf("(dial phonenum=%s)\n", phonenum); 175 #endif 176 if (*phonenum == '<' && phonenum[1] == 0) 177 return ('Z'); 178 for (vp = vaconfig; vp->vc_name; vp++) 179 if (strcmp(vp->vc_name, acu) == 0) 180 break; 181 if (vp->vc_name == 0) { 182 (void) printf("Unable to locate dialer (%s)\n", acu); 183 return ('K'); 184 } 185 (void) ioctl(AC, TCGETS, &cntrl); 186 (void) cfsetospeed(&cntrl, B0); 187 (void) cfsetispeed(&cntrl, B0); 188 cntrl.c_cflag &= ~(CSIZE|PARENB|PARODD); 189 (void) cfsetospeed(&cntrl, B2400); 190 cntrl.c_cflag |= CS8; 191 cntrl.c_iflag &= IXOFF|IXANY; 192 cntrl.c_lflag &= ~(ICANON|ISIG); 193 cntrl.c_oflag = 0; 194 cntrl.c_cc[VMIN] = cntrl.c_cc[VTIME] = 0; 195 (void) ioctl(AC, TCSETSF, &cntrl); 196 (void) ioctl(AC, TCFLSH, TCOFLUSH); 197 pc(STX); 198 pc(vp->vc_rack); 199 pc(vp->vc_modem); 200 while (*phonenum && *phonenum != '<') 201 pc(*phonenum++); 202 pc(SI); 203 pc(ETX); 204 (void) sleep(1); 205 i = read(AC, &c, 1); 206 #ifdef DEBUG 207 printf("read %d chars, char=%c, errno %d\n", i, c, errno); 208 #endif 209 if (i != 1) 210 c = 'M'; 211 if (c == 'B' || c == 'G') { 212 char cc, oc = c; 213 214 pc(ABORT); 215 (void) read(AC, &cc, 1); 216 #ifdef DEBUG 217 (void) printf("abort response=%c\n", cc); 218 #endif 219 c = oc; 220 v831_disconnect(); 221 } 222 (void) close(AC); 223 #ifdef DEBUG 224 (void) printf("dialit: returns %c\n", c); 225 #endif 226 return (c); 227 } 228 229 static char * 230 sanitize(char *s) 231 { 232 static char buf[128]; 233 char *cp; 234 235 for (cp = buf; *s; s++) { 236 if (!isdigit(*s) && *s == '<' && *s != '_') 237 continue; 238 if (*s == '_') 239 *s = '='; 240 *cp++ = *s; 241 } 242 *cp++ = 0; 243 return (buf); 244 } 245