1 /* $OpenBSD: acu.c,v 1.12 2006/03/17 14:43:06 moritz Exp $ */
2 /* $NetBSD: acu.c,v 1.4 1996/12/29 10:34:03 cgd Exp $ */
3
4 /*-
5 * SPDX-License-Identifier: BSD-3-Clause
6 *
7 * Copyright (c) 1983, 1993
8 * The Regents of the University of California. All rights reserved.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of the University nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 */
34
35 #include "tip.h"
36
37 static acu_t *acu = NOACU;
38 static int conflag;
39 static void acuabort(int);
40 static acu_t *acutype(char *);
41 static jmp_buf jmpbuf;
42 /*
43 * Establish connection for tip
44 *
45 * If DU is true, we should dial an ACU whose type is AT.
46 * The phone numbers are in PN, and the call unit is in CU.
47 *
48 * If the PN is an '@', then we consult the PHONES file for
49 * the phone numbers. This file is /etc/phones, unless overridden
50 * by an exported shell variable.
51 *
52 * The data base files must be in the format:
53 * host-name[ \t]*phone-number
54 * with the possibility of multiple phone numbers
55 * for a single host acting as a rotary (in the order
56 * found in the file).
57 */
58 char *
con(void)59 con(void)
60 {
61 char *cp = PN;
62 char *phnum, string[256];
63 FILE *fd;
64 volatile int tried = 0;
65
66 if (!DU) { /* regular connect message */
67 if (CM != NOSTR)
68 parwrite(FD, CM, size(CM));
69 logent(value(HOST), "", DV, "call completed");
70 return (NOSTR);
71 }
72 /*
73 * @ =>'s use data base in PHONES environment variable
74 * otherwise, use /etc/phones
75 */
76 signal(SIGINT, acuabort);
77 signal(SIGQUIT, acuabort);
78 if (setjmp(jmpbuf)) {
79 signal(SIGINT, SIG_IGN);
80 signal(SIGQUIT, SIG_IGN);
81 printf("\ncall aborted\n");
82 logent(value(HOST), "", "", "call aborted");
83 if (acu != NOACU) {
84 setboolean(value(VERBOSE), FALSE);
85 if (conflag)
86 disconnect(NOSTR);
87 else
88 (*acu->acu_abort)();
89 }
90 return ("interrupt");
91 }
92 if ((acu = acutype(AT)) == NOACU)
93 return ("unknown ACU type");
94 if (*cp != '@') {
95 while (*cp) {
96 phnum = cp;
97 cp += strcspn(cp, ",");
98 if (*cp != '\0')
99 *cp++ = '\0';
100
101 if (strlen(phnum) == 0)
102 continue;
103
104 conflag = (*acu->acu_dialer)(phnum, CU);
105 if (conflag)
106 break;
107
108 logent(value(HOST), phnum, acu->acu_name, "call failed");
109 tried++;
110 }
111 } else {
112 if ((fd = fopen(PH, "r")) == NOFILE) {
113 printf("%s: ", PH);
114 return ("can't open phone number file");
115 }
116 while (fgets(string, sizeof(string), fd) != NOSTR) {
117 cp = &string[strcspn(string, " \t\n")];
118 if (*cp != '\0')
119 *cp++ = '\0';
120
121 if (strcmp(string, value(HOST)) != 0)
122 continue;
123
124 cp += strspn(cp, " \t\n");
125 phnum = cp;
126 *(cp + strcspn(cp, ",\n")) = '\0';
127
128 if (strlen(phnum) == 0)
129 continue;
130
131 conflag = (*acu->acu_dialer)(phnum, CU);
132 if (conflag)
133 break;
134
135 logent(value(HOST), phnum, acu->acu_name, "call failed");
136 tried++;
137 }
138 fclose(fd);
139 }
140 if (conflag) {
141 if (CM != NOSTR)
142 parwrite(FD, CM, size(CM));
143 logent(value(HOST), phnum, acu->acu_name, "call completed");
144 return (NOSTR);
145 } else if (!tried) {
146 logent(value(HOST), "", acu->acu_name, "missing phone number");
147 return ("missing phone number");
148 } else {
149 (*acu->acu_abort)();
150 return ("call failed");
151 }
152 }
153
154 void
disconnect(char * reason)155 disconnect(char *reason)
156 {
157 if (!conflag) {
158 logent(value(HOST), "", DV, "call terminated");
159 return;
160 }
161 if (reason == NOSTR) {
162 logent(value(HOST), "", acu->acu_name, "call terminated");
163 if (boolean(value(VERBOSE)))
164 printf("\r\ndisconnecting...");
165 } else
166 logent(value(HOST), "", acu->acu_name, reason);
167 (*acu->acu_disconnect)();
168 }
169
170 static void
acuabort(int s)171 acuabort(int s)
172 {
173 signal(s, SIG_IGN);
174 longjmp(jmpbuf, 1);
175 }
176
177 static acu_t *
acutype(char * s)178 acutype(char *s)
179 {
180 acu_t *p;
181 extern acu_t acutable[];
182
183 for (p = acutable; p->acu_name != NULL; p++)
184 if (!strcmp(s, p->acu_name))
185 return (p);
186 return (NOACU);
187 }
188