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
v831_dialer(char * num,char * acu)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
alarmtr(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
v831_disconnect(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
v831_abort(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
dialit(char * phonenum,char * acu)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 *
sanitize(char * s)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