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