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