1/*	$OpenBSD: biz22.c,v 1.13 2006/03/17 19:17:13 moritz Exp $	*/
2/*	$NetBSD: biz22.c,v 1.6 1997/02/11 09:24:11 mrg Exp $	*/
3
4/*
5 * Copyright (c) 1983, 1993
6 *	The Regents of the University of California.  All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of the University nor the names of its contributors
17 *    may be used to endorse or promote products derived from this software
18 *    without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 */
32
33#include <sys/cdefs.h>
34__FBSDID("$FreeBSD: releng/11.0/usr.bin/tip/libacu/biz22.c 161754 2006-08-31 14:14:30Z ru $");
35
36#ifndef lint
37#if 0
38static char sccsid[] = "@(#)biz22.c	8.1 (Berkeley) 6/6/93";
39static const char rcsid[] = "$OpenBSD: biz22.c,v 1.13 2006/03/17 19:17:13 moritz Exp $";
40#endif
41#endif /* not lint */
42
43#include "tip.h"
44
45#define DISCONNECT_CMD	"\20\04"	/* disconnection string */
46
47static	int dialtimeout = 0;
48static	jmp_buf timeoutbuf;
49
50static int	biz_dialer(char *, char *);
51static void	sigALRM(int);
52static int	cmd(char *);
53static int	detect(char *);
54
55/*
56 * Dial up on a BIZCOMP Model 1022 with either
57 * 	tone dialing (mod = "V")
58 *	pulse dialing (mod = "W")
59 */
60static int
61biz_dialer(char *num, char *mod)
62{
63	int connected = 0;
64	char cbuf[40];
65
66	if (boolean(value(VERBOSE)))
67		printf("\nstarting call...");
68	/*
69	 * Disable auto-answer and configure for tone/pulse
70	 *  dialing
71	 */
72	if (cmd("\02K\r")) {
73		printf("can't initialize bizcomp...");
74		return (0);
75	}
76	(void)strlcpy(cbuf, "\02.\r", sizeof cbuf);
77	cbuf[1] = *mod;
78	if (cmd(cbuf)) {
79		printf("can't set dialing mode...");
80		return (0);
81	}
82	(void)snprintf(cbuf, sizeof(cbuf), "\02D%s\r", num);
83	write(FD, cbuf, strlen(cbuf));
84	if (!detect("7\r")) {
85		printf("can't get dial tone...");
86		return (0);
87	}
88	if (boolean(value(VERBOSE)))
89		printf("ringing...");
90	/*
91	 * The reply from the BIZCOMP should be:
92	 *	2 \r or 7 \r	failure
93	 *	1 \r		success
94	 */
95	connected = detect("1\r");
96#ifdef ACULOG
97	if (dialtimeout) {
98		char line[80];
99
100		(void)snprintf(line, sizeof line, "%ld second dial timeout",
101			number(value(DIALTIMEOUT)));
102		logent(value(HOST), num, "biz1022", line);
103	}
104#endif
105	if (dialtimeout)
106		biz22_disconnect();	/* insurance */
107	return (connected);
108}
109
110int
111biz22w_dialer(char *num, char *acu)
112{
113	return (biz_dialer(num, "W"));
114}
115
116int
117biz22f_dialer(char *num, char *acu)
118{
119	return (biz_dialer(num, "V"));
120}
121
122void
123biz22_disconnect(void)
124{
125	write(FD, DISCONNECT_CMD, sizeof(DISCONNECT_CMD)-1);
126	sleep(2);
127	tcflush(FD, TCIOFLUSH);
128}
129
130void
131biz22_abort(void)
132{
133	write(FD, "\02", 1);
134}
135
136/*ARGSUSED*/
137static void
138sigALRM(int signo)
139{
140	dialtimeout = 1;
141	longjmp(timeoutbuf, 1);
142}
143
144static int
145cmd(char *s)
146{
147	sig_t f;
148	char c;
149
150	write(FD, s, strlen(s));
151	f = signal(SIGALRM, sigALRM);
152	if (setjmp(timeoutbuf)) {
153		biz22_abort();
154		signal(SIGALRM, f);
155		return (1);
156	}
157	alarm(number(value(DIALTIMEOUT)));
158	read(FD, &c, 1);
159	alarm(0);
160	signal(SIGALRM, f);
161	c &= 0177;
162	return (c != '\r');
163}
164
165static int
166detect(char *s)
167{
168	sig_t f;
169	char c;
170
171	f = signal(SIGALRM, sigALRM);
172	dialtimeout = 0;
173	while (*s) {
174		if (setjmp(timeoutbuf)) {
175			biz22_abort();
176			break;
177		}
178		alarm(number(value(DIALTIMEOUT)));
179		read(FD, &c, 1);
180		alarm(0);
181		c &= 0177;
182		if (c != *s++)
183			return (0);
184	}
185	signal(SIGALRM, f);
186	return (dialtimeout == 0);
187}
188