17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 37c478bd9Sstevel@tonic-gate * Use is subject to license terms. 47c478bd9Sstevel@tonic-gate */ 5*8d489c7aSmuffin 67c478bd9Sstevel@tonic-gate /* 77c478bd9Sstevel@tonic-gate * Copyright (c) 1983 Regents of the University of California. 87c478bd9Sstevel@tonic-gate * All rights reserved. The Berkeley software License Agreement 97c478bd9Sstevel@tonic-gate * specifies the terms and conditions for redistribution. 107c478bd9Sstevel@tonic-gate */ 11*8d489c7aSmuffin 12*8d489c7aSmuffin #pragma ident "%Z%%M% %I% %E% SMI" 137c478bd9Sstevel@tonic-gate 147c478bd9Sstevel@tonic-gate /* 157c478bd9Sstevel@tonic-gate * Routines for dialing up on Vadic 831 167c478bd9Sstevel@tonic-gate */ 177c478bd9Sstevel@tonic-gate #include <sys/time.h> 187c478bd9Sstevel@tonic-gate 197c478bd9Sstevel@tonic-gate #include "tip.h" 207c478bd9Sstevel@tonic-gate 21*8d489c7aSmuffin static char dialit(char *, char *); 22*8d489c7aSmuffin static char *sanitize(char *); 23*8d489c7aSmuffin static void alarmtr(void); 247c478bd9Sstevel@tonic-gate 257c478bd9Sstevel@tonic-gate static sigjmp_buf jmpbuf; 267c478bd9Sstevel@tonic-gate static int child = -1; 277c478bd9Sstevel@tonic-gate 28*8d489c7aSmuffin int 29*8d489c7aSmuffin v831_dialer(char *num, char *acu) 307c478bd9Sstevel@tonic-gate { 31*8d489c7aSmuffin int status, pid; 32*8d489c7aSmuffin int timelim; 337c478bd9Sstevel@tonic-gate 347c478bd9Sstevel@tonic-gate if (boolean(value(VERBOSE))) 35*8d489c7aSmuffin (void) printf("\nstarting call..."); 367c478bd9Sstevel@tonic-gate #ifdef DEBUG 37*8d489c7aSmuffin (void) printf("(acu=%s)\n", acu); 387c478bd9Sstevel@tonic-gate #endif 397c478bd9Sstevel@tonic-gate if ((AC = open(acu, O_RDWR)) < 0) { 407c478bd9Sstevel@tonic-gate if (errno == EBUSY) 41*8d489c7aSmuffin (void) printf("line busy..."); 427c478bd9Sstevel@tonic-gate else 43*8d489c7aSmuffin (void) printf("acu open error..."); 447c478bd9Sstevel@tonic-gate return (0); 457c478bd9Sstevel@tonic-gate } 467c478bd9Sstevel@tonic-gate if (sigsetjmp(jmpbuf, 1)) { 47*8d489c7aSmuffin (void) kill(child, SIGKILL); 48*8d489c7aSmuffin (void) close(AC); 497c478bd9Sstevel@tonic-gate return (0); 507c478bd9Sstevel@tonic-gate } 51*8d489c7aSmuffin (void) signal(SIGALRM, (sig_handler_t)alarmtr); 527c478bd9Sstevel@tonic-gate timelim = 5 * strlen(num); 53*8d489c7aSmuffin (void) alarm(timelim < 30 ? 30 : timelim); 547c478bd9Sstevel@tonic-gate if ((child = fork()) == 0) { 557c478bd9Sstevel@tonic-gate /* 567c478bd9Sstevel@tonic-gate * ignore this stuff for aborts 577c478bd9Sstevel@tonic-gate */ 58*8d489c7aSmuffin (void) signal(SIGALRM, SIG_IGN); 59*8d489c7aSmuffin (void) signal(SIGINT, SIG_IGN); 60*8d489c7aSmuffin (void) signal(SIGQUIT, SIG_IGN); 61*8d489c7aSmuffin (void) sleep(2); 627c478bd9Sstevel@tonic-gate exit(dialit(num, acu) != 'A'); 637c478bd9Sstevel@tonic-gate } 647c478bd9Sstevel@tonic-gate /* 657c478bd9Sstevel@tonic-gate * open line - will return on carrier 667c478bd9Sstevel@tonic-gate */ 677c478bd9Sstevel@tonic-gate if ((FD = open(DV, O_RDWR)) < 0) { 687c478bd9Sstevel@tonic-gate #ifdef DEBUG 69*8d489c7aSmuffin (void) printf("(after open, errno=%d)\n", errno); 707c478bd9Sstevel@tonic-gate #endif 717c478bd9Sstevel@tonic-gate if (errno == EIO) 72*8d489c7aSmuffin (void) printf("lost carrier..."); 737c478bd9Sstevel@tonic-gate else 74*8d489c7aSmuffin (void) printf("dialup line open failed..."); 75*8d489c7aSmuffin (void) alarm(0); 76*8d489c7aSmuffin (void) kill(child, SIGKILL); 77*8d489c7aSmuffin (void) close(AC); 787c478bd9Sstevel@tonic-gate return (0); 797c478bd9Sstevel@tonic-gate } 80*8d489c7aSmuffin (void) alarm(0); 81*8d489c7aSmuffin (void) signal(SIGALRM, SIG_DFL); 827c478bd9Sstevel@tonic-gate while ((pid = wait(&status)) != child && pid != -1) 837c478bd9Sstevel@tonic-gate ; 847c478bd9Sstevel@tonic-gate if (status) { 85*8d489c7aSmuffin (void) close(AC); 867c478bd9Sstevel@tonic-gate return (0); 877c478bd9Sstevel@tonic-gate } 887c478bd9Sstevel@tonic-gate return (1); 897c478bd9Sstevel@tonic-gate } 907c478bd9Sstevel@tonic-gate 917c478bd9Sstevel@tonic-gate static void 92*8d489c7aSmuffin alarmtr(void) 937c478bd9Sstevel@tonic-gate { 947c478bd9Sstevel@tonic-gate 95*8d489c7aSmuffin (void) alarm(0); 967c478bd9Sstevel@tonic-gate siglongjmp(jmpbuf, 1); 977c478bd9Sstevel@tonic-gate } 987c478bd9Sstevel@tonic-gate 997c478bd9Sstevel@tonic-gate /* 1007c478bd9Sstevel@tonic-gate * Insurance, for some reason we don't seem to be 1017c478bd9Sstevel@tonic-gate * hanging up... 1027c478bd9Sstevel@tonic-gate */ 103*8d489c7aSmuffin void 104*8d489c7aSmuffin v831_disconnect(void) 1057c478bd9Sstevel@tonic-gate { 1067c478bd9Sstevel@tonic-gate struct termios cntrl; 1077c478bd9Sstevel@tonic-gate int dtr = TIOCM_DTR; 1087c478bd9Sstevel@tonic-gate 109*8d489c7aSmuffin (void) sleep(2); 1107c478bd9Sstevel@tonic-gate #ifdef DEBUG 1117c478bd9Sstevel@tonic-gate printf("[disconnect: FD=%d]\n", FD); 1127c478bd9Sstevel@tonic-gate #endif 1137c478bd9Sstevel@tonic-gate if (FD > 0) { 114*8d489c7aSmuffin (void) ioctl(FD, TIOCMBIC, &dtr); 115*8d489c7aSmuffin (void) ioctl(FD, TCGETS, &cntrl); 116*8d489c7aSmuffin (void) cfsetospeed(&cntrl, B0); 1177c478bd9Sstevel@tonic-gate cntrl.c_cflag &= ~XCLUDE; 118*8d489c7aSmuffin (void) ioctl(FD, TCSETSF, &cntrl); 1197c478bd9Sstevel@tonic-gate } 120*8d489c7aSmuffin (void) close(FD); 1217c478bd9Sstevel@tonic-gate } 1227c478bd9Sstevel@tonic-gate 123*8d489c7aSmuffin void 124*8d489c7aSmuffin v831_abort(void) 1257c478bd9Sstevel@tonic-gate { 1267c478bd9Sstevel@tonic-gate int dtr = TIOCM_DTR; 1277c478bd9Sstevel@tonic-gate struct termios buf; 1287c478bd9Sstevel@tonic-gate 1297c478bd9Sstevel@tonic-gate #ifdef DEBUG 130*8d489c7aSmuffin (void) printf("[abort: AC=%d]\n", AC); 1317c478bd9Sstevel@tonic-gate #endif 132*8d489c7aSmuffin (void) sleep(2); 1337c478bd9Sstevel@tonic-gate if (child > 0) 134*8d489c7aSmuffin (void) kill(child, SIGKILL); 1357c478bd9Sstevel@tonic-gate if (AC > 0) { 136*8d489c7aSmuffin (void) ioctl(FD, TCGETS, &buf); 1377c478bd9Sstevel@tonic-gate buf.c_cflag &= ~XCLUDE; 138*8d489c7aSmuffin (void) ioctl(FD, TCSETSF, &buf); 139*8d489c7aSmuffin (void) close(AC); 1407c478bd9Sstevel@tonic-gate } 1417c478bd9Sstevel@tonic-gate if (FD > 0) 142*8d489c7aSmuffin (void) ioctl(FD, TIOCMBIC, &dtr); 143*8d489c7aSmuffin (void) close(FD); 1447c478bd9Sstevel@tonic-gate } 1457c478bd9Sstevel@tonic-gate 1467c478bd9Sstevel@tonic-gate /* 1477c478bd9Sstevel@tonic-gate * Sigh, this probably must be changed at each site. 1487c478bd9Sstevel@tonic-gate */ 1497c478bd9Sstevel@tonic-gate struct vaconfig { 1507c478bd9Sstevel@tonic-gate char *vc_name; 1517c478bd9Sstevel@tonic-gate char vc_rack; 1527c478bd9Sstevel@tonic-gate char vc_modem; 1537c478bd9Sstevel@tonic-gate } vaconfig[] = { 1547c478bd9Sstevel@tonic-gate { "/dev/cua0", '4', '0' }, 1557c478bd9Sstevel@tonic-gate { "/dev/cua1", '4', '1' }, 1567c478bd9Sstevel@tonic-gate { 0 } 1577c478bd9Sstevel@tonic-gate }; 1587c478bd9Sstevel@tonic-gate 159*8d489c7aSmuffin #define pc(x) (c = x, (void) write(AC, &c, 1)) 1607c478bd9Sstevel@tonic-gate #define ABORT 01 1617c478bd9Sstevel@tonic-gate #define SI 017 1627c478bd9Sstevel@tonic-gate #define STX 02 1637c478bd9Sstevel@tonic-gate #define ETX 03 1647c478bd9Sstevel@tonic-gate 165*8d489c7aSmuffin static char 166*8d489c7aSmuffin dialit(char *phonenum, char *acu) 1677c478bd9Sstevel@tonic-gate { 168*8d489c7aSmuffin struct vaconfig *vp; 1697c478bd9Sstevel@tonic-gate struct termios cntrl; 170*8d489c7aSmuffin char c; 1717c478bd9Sstevel@tonic-gate int i; 1727c478bd9Sstevel@tonic-gate 1737c478bd9Sstevel@tonic-gate phonenum = sanitize(phonenum); 1747c478bd9Sstevel@tonic-gate #ifdef DEBUG 175*8d489c7aSmuffin (void) printf("(dial phonenum=%s)\n", phonenum); 1767c478bd9Sstevel@tonic-gate #endif 1777c478bd9Sstevel@tonic-gate if (*phonenum == '<' && phonenum[1] == 0) 1787c478bd9Sstevel@tonic-gate return ('Z'); 1797c478bd9Sstevel@tonic-gate for (vp = vaconfig; vp->vc_name; vp++) 1807c478bd9Sstevel@tonic-gate if (strcmp(vp->vc_name, acu) == 0) 1817c478bd9Sstevel@tonic-gate break; 1827c478bd9Sstevel@tonic-gate if (vp->vc_name == 0) { 183*8d489c7aSmuffin (void) printf("Unable to locate dialer (%s)\n", acu); 1847c478bd9Sstevel@tonic-gate return ('K'); 1857c478bd9Sstevel@tonic-gate } 186*8d489c7aSmuffin (void) ioctl(AC, TCGETS, &cntrl); 187*8d489c7aSmuffin (void) cfsetospeed(&cntrl, B0); 188*8d489c7aSmuffin (void) cfsetispeed(&cntrl, B0); 1897c478bd9Sstevel@tonic-gate cntrl.c_cflag &= ~(CSIZE|PARENB|PARODD); 190*8d489c7aSmuffin (void) cfsetospeed(&cntrl, B2400); 1917c478bd9Sstevel@tonic-gate cntrl.c_cflag |= CS8; 1927c478bd9Sstevel@tonic-gate cntrl.c_iflag &= IXOFF|IXANY; 1937c478bd9Sstevel@tonic-gate cntrl.c_lflag &= ~(ICANON|ISIG); 1947c478bd9Sstevel@tonic-gate cntrl.c_oflag = 0; 1957c478bd9Sstevel@tonic-gate cntrl.c_cc[VMIN] = cntrl.c_cc[VTIME] = 0; 196*8d489c7aSmuffin (void) ioctl(AC, TCSETSF, &cntrl); 197*8d489c7aSmuffin (void) ioctl(AC, TCFLSH, TCOFLUSH); 1987c478bd9Sstevel@tonic-gate pc(STX); 1997c478bd9Sstevel@tonic-gate pc(vp->vc_rack); 2007c478bd9Sstevel@tonic-gate pc(vp->vc_modem); 2017c478bd9Sstevel@tonic-gate while (*phonenum && *phonenum != '<') 2027c478bd9Sstevel@tonic-gate pc(*phonenum++); 2037c478bd9Sstevel@tonic-gate pc(SI); 2047c478bd9Sstevel@tonic-gate pc(ETX); 205*8d489c7aSmuffin (void) sleep(1); 2067c478bd9Sstevel@tonic-gate i = read(AC, &c, 1); 2077c478bd9Sstevel@tonic-gate #ifdef DEBUG 2087c478bd9Sstevel@tonic-gate printf("read %d chars, char=%c, errno %d\n", i, c, errno); 2097c478bd9Sstevel@tonic-gate #endif 2107c478bd9Sstevel@tonic-gate if (i != 1) 2117c478bd9Sstevel@tonic-gate c = 'M'; 2127c478bd9Sstevel@tonic-gate if (c == 'B' || c == 'G') { 2137c478bd9Sstevel@tonic-gate char cc, oc = c; 2147c478bd9Sstevel@tonic-gate 2157c478bd9Sstevel@tonic-gate pc(ABORT); 216*8d489c7aSmuffin (void) read(AC, &cc, 1); 2177c478bd9Sstevel@tonic-gate #ifdef DEBUG 218*8d489c7aSmuffin (void) printf("abort response=%c\n", cc); 2197c478bd9Sstevel@tonic-gate #endif 2207c478bd9Sstevel@tonic-gate c = oc; 2217c478bd9Sstevel@tonic-gate v831_disconnect(); 2227c478bd9Sstevel@tonic-gate } 223*8d489c7aSmuffin (void) close(AC); 2247c478bd9Sstevel@tonic-gate #ifdef DEBUG 225*8d489c7aSmuffin (void) printf("dialit: returns %c\n", c); 2267c478bd9Sstevel@tonic-gate #endif 2277c478bd9Sstevel@tonic-gate return (c); 2287c478bd9Sstevel@tonic-gate } 2297c478bd9Sstevel@tonic-gate 2307c478bd9Sstevel@tonic-gate static char * 231*8d489c7aSmuffin sanitize(char *s) 2327c478bd9Sstevel@tonic-gate { 2337c478bd9Sstevel@tonic-gate static char buf[128]; 234*8d489c7aSmuffin char *cp; 2357c478bd9Sstevel@tonic-gate 2367c478bd9Sstevel@tonic-gate for (cp = buf; *s; s++) { 2377c478bd9Sstevel@tonic-gate if (!isdigit(*s) && *s == '<' && *s != '_') 2387c478bd9Sstevel@tonic-gate continue; 2397c478bd9Sstevel@tonic-gate if (*s == '_') 2407c478bd9Sstevel@tonic-gate *s = '='; 2417c478bd9Sstevel@tonic-gate *cp++ = *s; 2427c478bd9Sstevel@tonic-gate } 2437c478bd9Sstevel@tonic-gate *cp++ = 0; 2447c478bd9Sstevel@tonic-gate return (buf); 2457c478bd9Sstevel@tonic-gate } 246