1161754Sru/*	$OpenBSD: acu.c,v 1.12 2006/03/17 14:43:06 moritz Exp $	*/
288276Smarkm/*	$NetBSD: acu.c,v 1.4 1996/12/29 10:34:03 cgd Exp $	*/
388276Smarkm
47527Sjkh/*
57527Sjkh * Copyright (c) 1983, 1993
67527Sjkh *	The Regents of the University of California.  All rights reserved.
77527Sjkh *
87527Sjkh * Redistribution and use in source and binary forms, with or without
97527Sjkh * modification, are permitted provided that the following conditions
107527Sjkh * are met:
117527Sjkh * 1. Redistributions of source code must retain the above copyright
127527Sjkh *    notice, this list of conditions and the following disclaimer.
137527Sjkh * 2. Redistributions in binary form must reproduce the above copyright
147527Sjkh *    notice, this list of conditions and the following disclaimer in the
157527Sjkh *    documentation and/or other materials provided with the distribution.
16161754Sru * 3. Neither the name of the University nor the names of its contributors
177527Sjkh *    may be used to endorse or promote products derived from this software
187527Sjkh *    without specific prior written permission.
197527Sjkh *
207527Sjkh * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
217527Sjkh * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
227527Sjkh * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
237527Sjkh * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
247527Sjkh * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
257527Sjkh * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
267527Sjkh * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
277527Sjkh * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
287527Sjkh * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
297527Sjkh * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
307527Sjkh * SUCH DAMAGE.
317527Sjkh */
327527Sjkh
3388276Smarkm#include <sys/cdefs.h>
3488276Smarkm__FBSDID("$FreeBSD$");
3588276Smarkm
367527Sjkh#ifndef lint
3728365Scharnier#if 0
387527Sjkhstatic char sccsid[] = "@(#)acu.c	8.1 (Berkeley) 6/6/93";
39161754Srustatic const char rcsid[] = "$OpenBSD: acu.c,v 1.12 2006/03/17 14:43:06 moritz Exp $";
4028365Scharnier#endif
417527Sjkh#endif /* not lint */
427527Sjkh
437527Sjkh#include "tip.h"
447527Sjkh
457527Sjkhstatic acu_t *acu = NOACU;
467527Sjkhstatic int conflag;
4792922Simpstatic void acuabort(int);
4892922Simpstatic acu_t *acutype(char *);
497527Sjkhstatic jmp_buf jmpbuf;
507527Sjkh/*
517527Sjkh * Establish connection for tip
527527Sjkh *
537527Sjkh * If DU is true, we should dial an ACU whose type is AT.
547527Sjkh * The phone numbers are in PN, and the call unit is in CU.
557527Sjkh *
567527Sjkh * If the PN is an '@', then we consult the PHONES file for
577527Sjkh *   the phone numbers.  This file is /etc/phones, unless overriden
587527Sjkh *   by an exported shell variable.
597527Sjkh *
607527Sjkh * The data base files must be in the format:
617527Sjkh *	host-name[ \t]*phone-number
627527Sjkh *   with the possibility of multiple phone numbers
637527Sjkh *   for a single host acting as a rotary (in the order
647527Sjkh *   found in the file).
657527Sjkh */
66161754Sruchar *
67161754Srucon(void)
687527Sjkh{
6988276Smarkm	char *cp = PN;
707527Sjkh	char *phnum, string[256];
717527Sjkh	FILE *fd;
7288276Smarkm	volatile int tried = 0;
737527Sjkh
747527Sjkh	if (!DU) {		/* regular connect message */
757527Sjkh		if (CM != NOSTR)
7688276Smarkm			parwrite(FD, CM, size(CM));
777527Sjkh		logent(value(HOST), "", DV, "call completed");
787527Sjkh		return (NOSTR);
797527Sjkh	}
807527Sjkh	/*
817527Sjkh	 * @ =>'s use data base in PHONES environment variable
827527Sjkh	 *        otherwise, use /etc/phones
837527Sjkh	 */
847527Sjkh	signal(SIGINT, acuabort);
857527Sjkh	signal(SIGQUIT, acuabort);
867527Sjkh	if (setjmp(jmpbuf)) {
877527Sjkh		signal(SIGINT, SIG_IGN);
887527Sjkh		signal(SIGQUIT, SIG_IGN);
897527Sjkh		printf("\ncall aborted\n");
907527Sjkh		logent(value(HOST), "", "", "call aborted");
917527Sjkh		if (acu != NOACU) {
9288276Smarkm			setboolean(value(VERBOSE), FALSE);
937527Sjkh			if (conflag)
947527Sjkh				disconnect(NOSTR);
957527Sjkh			else
967527Sjkh				(*acu->acu_abort)();
977527Sjkh		}
987527Sjkh		return ("interrupt");
997527Sjkh	}
1007527Sjkh	if ((acu = acutype(AT)) == NOACU)
1017527Sjkh		return ("unknown ACU type");
1027527Sjkh	if (*cp != '@') {
103169514Spav		while (*cp) {
10488276Smarkm			phnum = cp;
105169514Spav			cp += strcspn(cp, ",");
106169514Spav			if (*cp != '\0')
1077527Sjkh				*cp++ = '\0';
1088874Srgrimes
10988276Smarkm			if (strlen(phnum) == 0)
11088276Smarkm				continue;
11188276Smarkm
11288276Smarkm			conflag = (*acu->acu_dialer)(phnum, CU);
11388276Smarkm			if (conflag)
11488276Smarkm				break;
11588276Smarkm
11688276Smarkm			logent(value(HOST), phnum, acu->acu_name, "call failed");
1177527Sjkh			tried++;
1187527Sjkh		}
1197527Sjkh	} else {
1207527Sjkh		if ((fd = fopen(PH, "r")) == NOFILE) {
1217527Sjkh			printf("%s: ", PH);
1227527Sjkh			return ("can't open phone number file");
1237527Sjkh		}
1247527Sjkh		while (fgets(string, sizeof(string), fd) != NOSTR) {
12588276Smarkm			cp = &string[strcspn(string, " \t\n")];
12688276Smarkm			if (*cp != '\0')
1277527Sjkh				*cp++ = '\0';
1288874Srgrimes
12988276Smarkm			if (strcmp(string, value(HOST)) != 0)
13088276Smarkm				continue;
13188276Smarkm
13288276Smarkm			cp += strspn(cp, " \t\n");
13388276Smarkm			phnum = cp;
13488276Smarkm			*(cp + strcspn(cp, ",\n")) = '\0';
13588276Smarkm
13688276Smarkm			if (strlen(phnum) == 0)
13788276Smarkm				continue;
13888276Smarkm
13988276Smarkm			conflag = (*acu->acu_dialer)(phnum, CU);
14088276Smarkm			if (conflag)
14188276Smarkm				break;
142161754Sru
14388276Smarkm			logent(value(HOST), phnum, acu->acu_name, "call failed");
1447527Sjkh			tried++;
1457527Sjkh		}
1467527Sjkh		fclose(fd);
1477527Sjkh	}
14888276Smarkm	if (conflag) {
14988276Smarkm		if (CM != NOSTR)
15088276Smarkm			parwrite(FD, CM, size(CM));
15188276Smarkm		logent(value(HOST), phnum, acu->acu_name, "call completed");
15288276Smarkm		return (NOSTR);
15388276Smarkm	} else if (!tried) {
1547527Sjkh		logent(value(HOST), "", acu->acu_name, "missing phone number");
15588276Smarkm		return ("missing phone number");
15688276Smarkm	} else {
1577527Sjkh		(*acu->acu_abort)();
15888276Smarkm		return ("call failed");
15988276Smarkm	}
1607527Sjkh}
1617527Sjkh
16228365Scharniervoid
163161754Srudisconnect(char *reason)
1647527Sjkh{
1657527Sjkh	if (!conflag) {
1667527Sjkh		logent(value(HOST), "", DV, "call terminated");
1677527Sjkh		return;
1687527Sjkh	}
1697527Sjkh	if (reason == NOSTR) {
1707527Sjkh		logent(value(HOST), "", acu->acu_name, "call terminated");
1717527Sjkh		if (boolean(value(VERBOSE)))
1727527Sjkh			printf("\r\ndisconnecting...");
173161754Sru	} else
1747527Sjkh		logent(value(HOST), "", acu->acu_name, reason);
1757527Sjkh	(*acu->acu_disconnect)();
1767527Sjkh}
1777527Sjkh
1787527Sjkhstatic void
179161754Sruacuabort(int s)
1807527Sjkh{
1817527Sjkh	signal(s, SIG_IGN);
1827527Sjkh	longjmp(jmpbuf, 1);
1837527Sjkh}
1847527Sjkh
1857527Sjkhstatic acu_t *
186161754Sruacutype(char *s)
1877527Sjkh{
18888276Smarkm	acu_t *p;
1897527Sjkh	extern acu_t acutable[];
1907527Sjkh
1917527Sjkh	for (p = acutable; p->acu_name != '\0'; p++)
1927527Sjkh		if (!strcmp(s, p->acu_name))
1937527Sjkh			return (p);
1947527Sjkh	return (NOACU);
1957527Sjkh}
196