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