1 /* $OpenBSD: acu.c,v 1.10 2004/05/26 18:17:58 deraadt Exp $ */
2 /* $NetBSD: acu.c,v 1.4 1996/12/29 10:34:03 cgd 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 #ifndef lint
34 #if 0
35 static char sccsid[] = "@(#)acu.c 8.1 (Berkeley) 6/6/93";
36 #endif
37 static const char rcsid[] = "$OpenBSD: acu.c,v 1.10 2004/05/26 18:17:58 deraadt Exp $";
38 #endif /* not lint */
39
40 #include "tip.h"
41
42 static acu_t *acu = NOACU;
43 static int conflag;
44 static void acuabort();
45 static acu_t *acutype();
46 static jmp_buf jmpbuf;
47 /*
48 * Establish connection for tip
49 *
50 * If DU is true, we should dial an ACU whose type is AT.
51 * The phone numbers are in PN, and the call unit is in CU.
52 *
53 * If the PN is an '@', then we consult the PHONES file for
54 * the phone numbers. This file is /etc/phones, unless overriden
55 * by an exported shell variable.
56 *
57 * The data base files must be in the format:
58 * host-name[ \t]*phone-number
59 * with the possibility of multiple phone numbers
60 * for a single host acting as a rotary (in the order
61 * found in the file).
62 */
63 char *
connect()64 connect()
65 {
66 char *cp = PN;
67 char *phnum, string[256];
68 FILE *fd;
69 volatile int tried = 0;
70
71 if (!DU) { /* regular connect message */
72 if (CM != NOSTR)
73 parwrite(FD, CM, size(CM));
74 logent(value(HOST), "", DV, "call completed");
75 return (NOSTR);
76 }
77 /*
78 * @ =>'s use data base in PHONES environment variable
79 * otherwise, use /etc/phones
80 */
81 signal(SIGINT, acuabort);
82 signal(SIGQUIT, acuabort);
83 if (setjmp(jmpbuf)) {
84 signal(SIGINT, SIG_IGN);
85 signal(SIGQUIT, SIG_IGN);
86 printf("\ncall aborted\n");
87 logent(value(HOST), "", "", "call aborted");
88 if (acu != NOACU) {
89 setboolean(value(VERBOSE), FALSE);
90 if (conflag)
91 disconnect(NOSTR);
92 else
93 (*acu->acu_abort)();
94 }
95 return ("interrupt");
96 }
97 if ((acu = acutype(AT)) == NOACU)
98 return ("unknown ACU type");
99 if (*cp != '@') {
100 while (*cp) {
101 phnum = cp;
102 cp = strpbrk(cp, ",");
103 if (*cp != '\0')
104 *cp++ = '\0';
105
106 if (strlen(phnum) == 0)
107 continue;
108
109 conflag = (*acu->acu_dialer)(phnum, CU);
110 if (conflag)
111 break;
112
113 logent(value(HOST), phnum, acu->acu_name, "call failed");
114 tried++;
115 }
116 } else {
117 if ((fd = fopen(PH, "r")) == NOFILE) {
118 printf("%s: ", PH);
119 return ("can't open phone number file");
120 }
121 while (fgets(string, sizeof(string), fd) != NOSTR) {
122 cp = &string[strcspn(string, " \t\n")];
123 if (*cp != '\0')
124 *cp++ = '\0';
125
126 if (strcmp(string, value(HOST)) != 0)
127 continue;
128
129 cp += strspn(cp, " \t\n");
130 phnum = cp;
131 *(cp + strcspn(cp, ",\n")) = '\0';
132
133 if (strlen(phnum) == 0)
134 continue;
135
136 conflag = (*acu->acu_dialer)(phnum, CU);
137 if (conflag)
138 break;
139
140 logent(value(HOST), phnum, acu->acu_name, "call failed");
141 tried++;
142 }
143 fclose(fd);
144 }
145 if (conflag) {
146 if (CM != NOSTR)
147 parwrite(FD, CM, size(CM));
148 logent(value(HOST), phnum, acu->acu_name, "call completed");
149 return (NOSTR);
150 } else if (!tried) {
151 logent(value(HOST), "", acu->acu_name, "missing phone number");
152 return ("missing phone number");
153 } else {
154 (*acu->acu_abort)();
155 return ("call failed");
156 }
157 }
158
159 void
disconnect(reason)160 disconnect(reason)
161 char *reason;
162 {
163 if (!conflag) {
164 logent(value(HOST), "", DV, "call terminated");
165 return;
166 }
167 if (reason == NOSTR) {
168 logent(value(HOST), "", acu->acu_name, "call terminated");
169 if (boolean(value(VERBOSE)))
170 printf("\r\ndisconnecting...");
171 } else
172 logent(value(HOST), "", acu->acu_name, reason);
173 (*acu->acu_disconnect)();
174 }
175
176 static void
acuabort(int s)177 acuabort(int s)
178 {
179 signal(s, SIG_IGN);
180 longjmp(jmpbuf, 1);
181 }
182
183 static acu_t *
acutype(s)184 acutype(s)
185 char *s;
186 {
187 acu_t *p;
188 extern acu_t acutable[];
189
190 for (p = acutable; p->acu_name != '\0'; p++)
191 if (!strcmp(s, p->acu_name))
192 return (p);
193 return (NOACU);
194 }
195