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