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