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