xref: /original-bsd/usr.bin/tip/aculib/v831.c (revision 331bfa8d)
1 /*
2  * Copyright (c) 1983 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  */
7 
8 #ifndef lint
9 static char sccsid[] = "@(#)v831.c	5.4 (Berkeley) 02/04/91";
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	int alarmtr();
19 extern	errno;
20 
21 static jmp_buf jmpbuf;
22 static int child = -1;
23 
24 v831_dialer(num, acu)
25         char *num, *acu;
26 {
27         int status, pid, connected = 1;
28         register int timelim;
29 
30         if (boolean(value(VERBOSE)))
31                 printf("\nstarting call...");
32 #ifdef DEBUG
33         printf ("(acu=%s)\n", acu);
34 #endif
35         if ((AC = open(acu, O_RDWR)) < 0) {
36                 if (errno == EBUSY)
37                         printf("line busy...");
38                 else
39                         printf("acu open error...");
40                 return (0);
41         }
42         if (setjmp(jmpbuf)) {
43                 kill(child, SIGKILL);
44                 close(AC);
45                 return (0);
46         }
47         signal(SIGALRM, alarmtr);
48         timelim = 5 * strlen(num);
49         alarm(timelim < 30 ? 30 : timelim);
50         if ((child = fork()) == 0) {
51                 /*
52                  * ignore this stuff for aborts
53                  */
54                 signal(SIGALRM, SIG_IGN);
55 		signal(SIGINT, SIG_IGN);
56                 signal(SIGQUIT, SIG_IGN);
57                 sleep(2);
58                 exit(dialit(num, acu) != 'A');
59         }
60         /*
61          * open line - will return on carrier
62          */
63         if ((FD = open(DV, O_RDWR)) < 0) {
64 #ifdef DEBUG
65                 printf("(after open, errno=%d)\n", errno);
66 #endif
67                 if (errno == EIO)
68                         printf("lost carrier...");
69                 else
70                         printf("dialup line open failed...");
71                 alarm(0);
72                 kill(child, SIGKILL);
73                 close(AC);
74                 return (0);
75         }
76         alarm(0);
77 #ifdef notdef
78         ioctl(AC, TIOCHPCL, 0);
79 #endif
80         signal(SIGALRM, SIG_DFL);
81         while ((pid = wait(&status)) != child && pid != -1)
82                 ;
83         if (status) {
84                 close(AC);
85                 return (0);
86         }
87         return (1);
88 }
89 
90 static
91 alarmtr()
92 {
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  */
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 
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
157 dialit(phonenum, acu)
158 	register char *phonenum;
159 	char *acu;
160 {
161         register struct vaconfig *vp;
162 	struct sgttyb cntrl;
163         char c, *sanitize();
164         int i, two = 2;
165 
166         phonenum = sanitize(phonenum);
167 #ifdef DEBUG
168         printf ("(dial phonenum=%s)\n", phonenum);
169 #endif
170         if (*phonenum == '<' && phonenum[1] == 0)
171                 return ('Z');
172 	for (vp = vaconfig; vp->vc_name; vp++)
173 		if (strcmp(vp->vc_name, acu) == 0)
174 			break;
175 	if (vp->vc_name == 0) {
176 		printf("Unable to locate dialer (%s)\n", acu);
177 		return ('K');
178 	}
179         ioctl(AC, TIOCGETP, &cntrl);
180         cntrl.sg_ispeed = cntrl.sg_ospeed = B2400;
181         cntrl.sg_flags = RAW | EVENP | ODDP;
182         ioctl(AC, TIOCSETP, &cntrl);
183 	ioctl(AC, TIOCFLUSH, &two);
184         pc(STX);
185 	pc(vp->vc_rack);
186 	pc(vp->vc_modem);
187 	while (*phonenum && *phonenum != '<')
188 		pc(*phonenum++);
189         pc(SI);
190 	pc(ETX);
191         sleep(1);
192         i = read(AC, &c, 1);
193 #ifdef DEBUG
194         printf("read %d chars, char=%c, errno %d\n", i, c, errno);
195 #endif
196         if (i != 1)
197 		c = 'M';
198         if (c == 'B' || c == 'G') {
199                 char cc, oc = c;
200 
201                 pc(ABORT);
202                 read(AC, &cc, 1);
203 #ifdef DEBUG
204                 printf("abort response=%c\n", cc);
205 #endif
206                 c = oc;
207                 v831_disconnect();
208         }
209         close(AC);
210 #ifdef DEBUG
211         printf("dialit: returns %c\n", c);
212 #endif
213         return (c);
214 }
215 
216 static char *
217 sanitize(s)
218 	register char *s;
219 {
220         static char buf[128];
221         register char *cp;
222 
223         for (cp = buf; *s; s++) {
224 		if (!isdigit(*s) && *s == '<' && *s != '_')
225 			continue;
226 		if (*s == '_')
227 			*s = '=';
228 		*cp++ = *s;
229 	}
230         *cp++ = 0;
231         return (buf);
232 }
233