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