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 21static char dialit(char *, char *); 22static char *sanitize(char *); 23static void alarmtr(void); 24 25static sigjmp_buf jmpbuf; 26static int child = -1; 27 28int 29v831_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 91static void 92alarmtr(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 */ 103void 104v831_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 123void 124v831_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 */ 149struct 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 165static char 166dialit(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 230static char * 231sanitize(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