10Sstevel@tonic-gate /* 20Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 30Sstevel@tonic-gate * Use is subject to license terms. 40Sstevel@tonic-gate */ 5*549Smuffin 60Sstevel@tonic-gate /* 70Sstevel@tonic-gate * Copyright (c) 1983 Regents of the University of California. 80Sstevel@tonic-gate * All rights reserved. The Berkeley software License Agreement 90Sstevel@tonic-gate * specifies the terms and conditions for redistribution. 100Sstevel@tonic-gate */ 11*549Smuffin 12*549Smuffin #pragma ident "%Z%%M% %I% %E% SMI" 130Sstevel@tonic-gate 140Sstevel@tonic-gate /* 150Sstevel@tonic-gate * Routines for dialing up on Vadic 831 160Sstevel@tonic-gate */ 170Sstevel@tonic-gate #include <sys/time.h> 180Sstevel@tonic-gate 190Sstevel@tonic-gate #include "tip.h" 200Sstevel@tonic-gate 21*549Smuffin static char dialit(char *, char *); 22*549Smuffin static char *sanitize(char *); 23*549Smuffin static void alarmtr(void); 240Sstevel@tonic-gate 25*549Smuffin static sigjmp_buf jmpbuf; 26*549Smuffin static int child = -1; 270Sstevel@tonic-gate 28*549Smuffin int 29*549Smuffin v831_dialer(char *num, char *acu) 300Sstevel@tonic-gate { 31*549Smuffin int status, pid; 32*549Smuffin int timelim; 330Sstevel@tonic-gate 340Sstevel@tonic-gate if (boolean(value(VERBOSE))) 35*549Smuffin (void) printf("\nstarting call..."); 360Sstevel@tonic-gate #ifdef DEBUG 37*549Smuffin (void) printf("(acu=%s)\n", acu); 380Sstevel@tonic-gate #endif 390Sstevel@tonic-gate if ((AC = open(acu, O_RDWR)) < 0) { 400Sstevel@tonic-gate if (errno == EBUSY) 41*549Smuffin (void) printf("line busy..."); 420Sstevel@tonic-gate else 43*549Smuffin (void) printf("acu open error..."); 440Sstevel@tonic-gate return (0); 450Sstevel@tonic-gate } 460Sstevel@tonic-gate if (sigsetjmp(jmpbuf, 1)) { 47*549Smuffin (void) kill(child, SIGKILL); 48*549Smuffin (void) close(AC); 490Sstevel@tonic-gate return (0); 500Sstevel@tonic-gate } 51*549Smuffin (void) signal(SIGALRM, (sig_handler_t)alarmtr); 520Sstevel@tonic-gate timelim = 5 * strlen(num); 53*549Smuffin (void) alarm(timelim < 30 ? 30 : timelim); 540Sstevel@tonic-gate if ((child = fork()) == 0) { 550Sstevel@tonic-gate /* 560Sstevel@tonic-gate * ignore this stuff for aborts 570Sstevel@tonic-gate */ 58*549Smuffin (void) signal(SIGALRM, SIG_IGN); 59*549Smuffin (void) signal(SIGINT, SIG_IGN); 60*549Smuffin (void) signal(SIGQUIT, SIG_IGN); 61*549Smuffin (void) sleep(2); 620Sstevel@tonic-gate exit(dialit(num, acu) != 'A'); 630Sstevel@tonic-gate } 640Sstevel@tonic-gate /* 650Sstevel@tonic-gate * open line - will return on carrier 660Sstevel@tonic-gate */ 670Sstevel@tonic-gate if ((FD = open(DV, O_RDWR)) < 0) { 680Sstevel@tonic-gate #ifdef DEBUG 69*549Smuffin (void) printf("(after open, errno=%d)\n", errno); 700Sstevel@tonic-gate #endif 710Sstevel@tonic-gate if (errno == EIO) 72*549Smuffin (void) printf("lost carrier..."); 730Sstevel@tonic-gate else 74*549Smuffin (void) printf("dialup line open failed..."); 75*549Smuffin (void) alarm(0); 76*549Smuffin (void) kill(child, SIGKILL); 77*549Smuffin (void) close(AC); 780Sstevel@tonic-gate return (0); 790Sstevel@tonic-gate } 80*549Smuffin (void) alarm(0); 81*549Smuffin (void) signal(SIGALRM, SIG_DFL); 820Sstevel@tonic-gate while ((pid = wait(&status)) != child && pid != -1) 830Sstevel@tonic-gate ; 840Sstevel@tonic-gate if (status) { 85*549Smuffin (void) close(AC); 860Sstevel@tonic-gate return (0); 870Sstevel@tonic-gate } 880Sstevel@tonic-gate return (1); 890Sstevel@tonic-gate } 900Sstevel@tonic-gate 910Sstevel@tonic-gate static void 92*549Smuffin alarmtr(void) 930Sstevel@tonic-gate { 940Sstevel@tonic-gate 95*549Smuffin (void) alarm(0); 960Sstevel@tonic-gate siglongjmp(jmpbuf, 1); 970Sstevel@tonic-gate } 980Sstevel@tonic-gate 990Sstevel@tonic-gate /* 1000Sstevel@tonic-gate * Insurance, for some reason we don't seem to be 1010Sstevel@tonic-gate * hanging up... 1020Sstevel@tonic-gate */ 103*549Smuffin void 104*549Smuffin v831_disconnect(void) 1050Sstevel@tonic-gate { 1060Sstevel@tonic-gate struct termios cntrl; 1070Sstevel@tonic-gate int dtr = TIOCM_DTR; 1080Sstevel@tonic-gate 109*549Smuffin (void) sleep(2); 1100Sstevel@tonic-gate #ifdef DEBUG 1110Sstevel@tonic-gate printf("[disconnect: FD=%d]\n", FD); 1120Sstevel@tonic-gate #endif 1130Sstevel@tonic-gate if (FD > 0) { 114*549Smuffin (void) ioctl(FD, TIOCMBIC, &dtr); 115*549Smuffin (void) ioctl(FD, TCGETS, &cntrl); 116*549Smuffin (void) cfsetospeed(&cntrl, B0); 1170Sstevel@tonic-gate cntrl.c_cflag &= ~XCLUDE; 118*549Smuffin (void) ioctl(FD, TCSETSF, &cntrl); 1190Sstevel@tonic-gate } 120*549Smuffin (void) close(FD); 1210Sstevel@tonic-gate } 1220Sstevel@tonic-gate 123*549Smuffin void 124*549Smuffin v831_abort(void) 1250Sstevel@tonic-gate { 1260Sstevel@tonic-gate int dtr = TIOCM_DTR; 1270Sstevel@tonic-gate struct termios buf; 1280Sstevel@tonic-gate 1290Sstevel@tonic-gate #ifdef DEBUG 130*549Smuffin (void) printf("[abort: AC=%d]\n", AC); 1310Sstevel@tonic-gate #endif 132*549Smuffin (void) sleep(2); 1330Sstevel@tonic-gate if (child > 0) 134*549Smuffin (void) kill(child, SIGKILL); 1350Sstevel@tonic-gate if (AC > 0) { 136*549Smuffin (void) ioctl(FD, TCGETS, &buf); 1370Sstevel@tonic-gate buf.c_cflag &= ~XCLUDE; 138*549Smuffin (void) ioctl(FD, TCSETSF, &buf); 139*549Smuffin (void) close(AC); 1400Sstevel@tonic-gate } 1410Sstevel@tonic-gate if (FD > 0) 142*549Smuffin (void) ioctl(FD, TIOCMBIC, &dtr); 143*549Smuffin (void) close(FD); 1440Sstevel@tonic-gate } 1450Sstevel@tonic-gate 1460Sstevel@tonic-gate /* 1470Sstevel@tonic-gate * Sigh, this probably must be changed at each site. 1480Sstevel@tonic-gate */ 1490Sstevel@tonic-gate struct vaconfig { 1500Sstevel@tonic-gate char *vc_name; 1510Sstevel@tonic-gate char vc_rack; 1520Sstevel@tonic-gate char vc_modem; 1530Sstevel@tonic-gate } vaconfig[] = { 1540Sstevel@tonic-gate { "/dev/cua0", '4', '0' }, 1550Sstevel@tonic-gate { "/dev/cua1", '4', '1' }, 1560Sstevel@tonic-gate { 0 } 1570Sstevel@tonic-gate }; 1580Sstevel@tonic-gate 159*549Smuffin #define pc(x) (c = x, (void) write(AC, &c, 1)) 1600Sstevel@tonic-gate #define ABORT 01 1610Sstevel@tonic-gate #define SI 017 1620Sstevel@tonic-gate #define STX 02 1630Sstevel@tonic-gate #define ETX 03 1640Sstevel@tonic-gate 165*549Smuffin static char 166*549Smuffin dialit(char *phonenum, char *acu) 1670Sstevel@tonic-gate { 168*549Smuffin struct vaconfig *vp; 1690Sstevel@tonic-gate struct termios cntrl; 170*549Smuffin char c; 1710Sstevel@tonic-gate int i; 1720Sstevel@tonic-gate 1730Sstevel@tonic-gate phonenum = sanitize(phonenum); 1740Sstevel@tonic-gate #ifdef DEBUG 175*549Smuffin (void) printf("(dial phonenum=%s)\n", phonenum); 1760Sstevel@tonic-gate #endif 1770Sstevel@tonic-gate if (*phonenum == '<' && phonenum[1] == 0) 1780Sstevel@tonic-gate return ('Z'); 1790Sstevel@tonic-gate for (vp = vaconfig; vp->vc_name; vp++) 1800Sstevel@tonic-gate if (strcmp(vp->vc_name, acu) == 0) 1810Sstevel@tonic-gate break; 1820Sstevel@tonic-gate if (vp->vc_name == 0) { 183*549Smuffin (void) printf("Unable to locate dialer (%s)\n", acu); 1840Sstevel@tonic-gate return ('K'); 1850Sstevel@tonic-gate } 186*549Smuffin (void) ioctl(AC, TCGETS, &cntrl); 187*549Smuffin (void) cfsetospeed(&cntrl, B0); 188*549Smuffin (void) cfsetispeed(&cntrl, B0); 1890Sstevel@tonic-gate cntrl.c_cflag &= ~(CSIZE|PARENB|PARODD); 190*549Smuffin (void) cfsetospeed(&cntrl, B2400); 1910Sstevel@tonic-gate cntrl.c_cflag |= CS8; 1920Sstevel@tonic-gate cntrl.c_iflag &= IXOFF|IXANY; 1930Sstevel@tonic-gate cntrl.c_lflag &= ~(ICANON|ISIG); 1940Sstevel@tonic-gate cntrl.c_oflag = 0; 1950Sstevel@tonic-gate cntrl.c_cc[VMIN] = cntrl.c_cc[VTIME] = 0; 196*549Smuffin (void) ioctl(AC, TCSETSF, &cntrl); 197*549Smuffin (void) ioctl(AC, TCFLSH, TCOFLUSH); 1980Sstevel@tonic-gate pc(STX); 1990Sstevel@tonic-gate pc(vp->vc_rack); 2000Sstevel@tonic-gate pc(vp->vc_modem); 2010Sstevel@tonic-gate while (*phonenum && *phonenum != '<') 2020Sstevel@tonic-gate pc(*phonenum++); 2030Sstevel@tonic-gate pc(SI); 2040Sstevel@tonic-gate pc(ETX); 205*549Smuffin (void) sleep(1); 2060Sstevel@tonic-gate i = read(AC, &c, 1); 2070Sstevel@tonic-gate #ifdef DEBUG 2080Sstevel@tonic-gate printf("read %d chars, char=%c, errno %d\n", i, c, errno); 2090Sstevel@tonic-gate #endif 2100Sstevel@tonic-gate if (i != 1) 2110Sstevel@tonic-gate c = 'M'; 2120Sstevel@tonic-gate if (c == 'B' || c == 'G') { 2130Sstevel@tonic-gate char cc, oc = c; 2140Sstevel@tonic-gate 2150Sstevel@tonic-gate pc(ABORT); 216*549Smuffin (void) read(AC, &cc, 1); 2170Sstevel@tonic-gate #ifdef DEBUG 218*549Smuffin (void) printf("abort response=%c\n", cc); 2190Sstevel@tonic-gate #endif 2200Sstevel@tonic-gate c = oc; 2210Sstevel@tonic-gate v831_disconnect(); 2220Sstevel@tonic-gate } 223*549Smuffin (void) close(AC); 2240Sstevel@tonic-gate #ifdef DEBUG 225*549Smuffin (void) printf("dialit: returns %c\n", c); 2260Sstevel@tonic-gate #endif 2270Sstevel@tonic-gate return (c); 2280Sstevel@tonic-gate } 2290Sstevel@tonic-gate 2300Sstevel@tonic-gate static char * 231*549Smuffin sanitize(char *s) 2320Sstevel@tonic-gate { 2330Sstevel@tonic-gate static char buf[128]; 234*549Smuffin char *cp; 2350Sstevel@tonic-gate 2360Sstevel@tonic-gate for (cp = buf; *s; s++) { 2370Sstevel@tonic-gate if (!isdigit(*s) && *s == '<' && *s != '_') 2380Sstevel@tonic-gate continue; 2390Sstevel@tonic-gate if (*s == '_') 2400Sstevel@tonic-gate *s = '='; 2410Sstevel@tonic-gate *cp++ = *s; 2420Sstevel@tonic-gate } 2430Sstevel@tonic-gate *cp++ = 0; 2440Sstevel@tonic-gate return (buf); 2450Sstevel@tonic-gate } 246