Blame


1 6b5c4000 2026-03-02 rsadowski /* $OpenBSD: util.c,v 1.6 2026/03/02 19:28:01 rsadowski Exp $ */
2 0e5011aa 2015-11-21 reyk
3 0e5011aa 2015-11-21 reyk /*
4 0e5011aa 2015-11-21 reyk * Copyright (c) 2006 - 2015 Reyk Floeter <reyk@openbsd.org>
5 0e5011aa 2015-11-21 reyk *
6 0e5011aa 2015-11-21 reyk * Permission to use, copy, modify, and distribute this software for any
7 0e5011aa 2015-11-21 reyk * purpose with or without fee is hereby granted, provided that the above
8 0e5011aa 2015-11-21 reyk * copyright notice and this permission notice appear in all copies.
9 0e5011aa 2015-11-21 reyk *
10 0e5011aa 2015-11-21 reyk * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 0e5011aa 2015-11-21 reyk * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 0e5011aa 2015-11-21 reyk * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 0e5011aa 2015-11-21 reyk * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 0e5011aa 2015-11-21 reyk * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 0e5011aa 2015-11-21 reyk * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 0e5011aa 2015-11-21 reyk * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 0e5011aa 2015-11-21 reyk */
18 0e5011aa 2015-11-21 reyk
19 0e5011aa 2015-11-21 reyk #include <sys/types.h>
20 0e5011aa 2015-11-21 reyk #include <sys/socket.h>
21 0e5011aa 2015-11-21 reyk #include <sys/time.h>
22 0e5011aa 2015-11-21 reyk
23 0e5011aa 2015-11-21 reyk #include <stdio.h>
24 0e5011aa 2015-11-21 reyk #include <string.h>
25 0e5011aa 2015-11-21 reyk #include <time.h>
26 0e5011aa 2015-11-21 reyk #include <netdb.h>
27 0e5011aa 2015-11-21 reyk #include <ctype.h>
28 0e5011aa 2015-11-21 reyk
29 0e5011aa 2015-11-21 reyk #include "relayd.h"
30 6b5c4000 2026-03-02 rsadowski #include "log.h"
31 0e5011aa 2015-11-21 reyk
32 0e5011aa 2015-11-21 reyk const char *
33 0e5011aa 2015-11-21 reyk host_error(enum host_error he)
34 0e5011aa 2015-11-21 reyk {
35 0e5011aa 2015-11-21 reyk switch (he) {
36 0e5011aa 2015-11-21 reyk case HCE_NONE:
37 0e5011aa 2015-11-21 reyk return ("none");
38 0e5011aa 2015-11-21 reyk break;
39 0e5011aa 2015-11-21 reyk case HCE_ABORT:
40 0e5011aa 2015-11-21 reyk return ("aborted");
41 0e5011aa 2015-11-21 reyk break;
42 0e5011aa 2015-11-21 reyk case HCE_INTERVAL_TIMEOUT:
43 0e5011aa 2015-11-21 reyk return ("interval timeout");
44 0e5011aa 2015-11-21 reyk break;
45 0e5011aa 2015-11-21 reyk case HCE_ICMP_OK:
46 0e5011aa 2015-11-21 reyk return ("icmp ok");
47 0e5011aa 2015-11-21 reyk break;
48 0e5011aa 2015-11-21 reyk case HCE_ICMP_READ_TIMEOUT:
49 0e5011aa 2015-11-21 reyk return ("icmp read timeout");
50 0e5011aa 2015-11-21 reyk break;
51 0e5011aa 2015-11-21 reyk case HCE_ICMP_WRITE_TIMEOUT:
52 0e5011aa 2015-11-21 reyk return ("icmp write timeout");
53 0e5011aa 2015-11-21 reyk break;
54 0e5011aa 2015-11-21 reyk case HCE_TCP_SOCKET_ERROR:
55 0e5011aa 2015-11-21 reyk return ("tcp socket error");
56 0e5011aa 2015-11-21 reyk break;
57 0e5011aa 2015-11-21 reyk case HCE_TCP_SOCKET_LIMIT:
58 0e5011aa 2015-11-21 reyk return ("tcp socket limit");
59 0e5011aa 2015-11-21 reyk break;
60 0e5011aa 2015-11-21 reyk case HCE_TCP_SOCKET_OPTION:
61 0e5011aa 2015-11-21 reyk return ("tcp socket option");
62 0e5011aa 2015-11-21 reyk break;
63 0e5011aa 2015-11-21 reyk case HCE_TCP_CONNECT_FAIL:
64 0e5011aa 2015-11-21 reyk return ("tcp connect failed");
65 0e5011aa 2015-11-21 reyk break;
66 0e5011aa 2015-11-21 reyk case HCE_TCP_CONNECT_TIMEOUT:
67 0e5011aa 2015-11-21 reyk return ("tcp connect timeout");
68 0e5011aa 2015-11-21 reyk break;
69 0e5011aa 2015-11-21 reyk case HCE_TCP_CONNECT_OK:
70 0e5011aa 2015-11-21 reyk return ("tcp connect ok");
71 0e5011aa 2015-11-21 reyk break;
72 0e5011aa 2015-11-21 reyk case HCE_TCP_WRITE_TIMEOUT:
73 0e5011aa 2015-11-21 reyk return ("tcp write timeout");
74 0e5011aa 2015-11-21 reyk break;
75 0e5011aa 2015-11-21 reyk case HCE_TCP_WRITE_FAIL:
76 0e5011aa 2015-11-21 reyk return ("tcp write failed");
77 0e5011aa 2015-11-21 reyk break;
78 0e5011aa 2015-11-21 reyk case HCE_TCP_READ_TIMEOUT:
79 0e5011aa 2015-11-21 reyk return ("tcp read timeout");
80 0e5011aa 2015-11-21 reyk break;
81 0e5011aa 2015-11-21 reyk case HCE_TCP_READ_FAIL:
82 0e5011aa 2015-11-21 reyk return ("tcp read failed");
83 0e5011aa 2015-11-21 reyk break;
84 0e5011aa 2015-11-21 reyk case HCE_SCRIPT_OK:
85 0e5011aa 2015-11-21 reyk return ("script ok");
86 0e5011aa 2015-11-21 reyk break;
87 0e5011aa 2015-11-21 reyk case HCE_SCRIPT_FAIL:
88 0e5011aa 2015-11-21 reyk return ("script failed");
89 0e5011aa 2015-11-21 reyk break;
90 0e5011aa 2015-11-21 reyk case HCE_TLS_CONNECT_OK:
91 0e5011aa 2015-11-21 reyk return ("tls connect ok");
92 0e5011aa 2015-11-21 reyk break;
93 0e5011aa 2015-11-21 reyk case HCE_TLS_CONNECT_FAIL:
94 0e5011aa 2015-11-21 reyk return ("tls connect failed");
95 0e5011aa 2015-11-21 reyk break;
96 0e5011aa 2015-11-21 reyk case HCE_TLS_CONNECT_TIMEOUT:
97 0e5011aa 2015-11-21 reyk return ("tls connect timeout");
98 0e5011aa 2015-11-21 reyk break;
99 0e5011aa 2015-11-21 reyk case HCE_TLS_CONNECT_ERROR:
100 0e5011aa 2015-11-21 reyk return ("tls connect error");
101 0e5011aa 2015-11-21 reyk break;
102 0e5011aa 2015-11-21 reyk case HCE_TLS_READ_TIMEOUT:
103 0e5011aa 2015-11-21 reyk return ("tls read timeout");
104 0e5011aa 2015-11-21 reyk break;
105 0e5011aa 2015-11-21 reyk case HCE_TLS_WRITE_TIMEOUT:
106 0e5011aa 2015-11-21 reyk return ("tls write timeout");
107 0e5011aa 2015-11-21 reyk break;
108 0e5011aa 2015-11-21 reyk case HCE_TLS_READ_ERROR:
109 0e5011aa 2015-11-21 reyk return ("tls read error");
110 0e5011aa 2015-11-21 reyk break;
111 0e5011aa 2015-11-21 reyk case HCE_TLS_WRITE_ERROR:
112 0e5011aa 2015-11-21 reyk return ("tls write error");
113 0e5011aa 2015-11-21 reyk break;
114 0e5011aa 2015-11-21 reyk case HCE_SEND_EXPECT_FAIL:
115 0e5011aa 2015-11-21 reyk return ("send/expect failed");
116 0e5011aa 2015-11-21 reyk break;
117 0e5011aa 2015-11-21 reyk case HCE_SEND_EXPECT_OK:
118 0e5011aa 2015-11-21 reyk return ("send/expect ok");
119 0e5011aa 2015-11-21 reyk break;
120 0e5011aa 2015-11-21 reyk case HCE_HTTP_CODE_ERROR:
121 0e5011aa 2015-11-21 reyk return ("http code malformed");
122 0e5011aa 2015-11-21 reyk break;
123 0e5011aa 2015-11-21 reyk case HCE_HTTP_CODE_FAIL:
124 0e5011aa 2015-11-21 reyk return ("http code mismatch");
125 0e5011aa 2015-11-21 reyk break;
126 0e5011aa 2015-11-21 reyk case HCE_HTTP_CODE_OK:
127 0e5011aa 2015-11-21 reyk return ("http code ok");
128 0e5011aa 2015-11-21 reyk break;
129 0e5011aa 2015-11-21 reyk case HCE_HTTP_DIGEST_ERROR:
130 0e5011aa 2015-11-21 reyk return ("http digest malformed");
131 0e5011aa 2015-11-21 reyk break;
132 0e5011aa 2015-11-21 reyk case HCE_HTTP_DIGEST_FAIL:
133 0e5011aa 2015-11-21 reyk return ("http digest mismatch");
134 0e5011aa 2015-11-21 reyk break;
135 0e5011aa 2015-11-21 reyk case HCE_HTTP_DIGEST_OK:
136 0e5011aa 2015-11-21 reyk return ("http digest ok");
137 0e5011aa 2015-11-21 reyk break;
138 0e5011aa 2015-11-21 reyk }
139 0e5011aa 2015-11-21 reyk /* NOTREACHED */
140 0e5011aa 2015-11-21 reyk return ("invalid");
141 0e5011aa 2015-11-21 reyk }
142 0e5011aa 2015-11-21 reyk
143 0e5011aa 2015-11-21 reyk const char *
144 0e5011aa 2015-11-21 reyk host_status(enum host_status status)
145 0e5011aa 2015-11-21 reyk {
146 0e5011aa 2015-11-21 reyk switch (status) {
147 0e5011aa 2015-11-21 reyk case HOST_DOWN:
148 0e5011aa 2015-11-21 reyk return ("down");
149 0e5011aa 2015-11-21 reyk case HOST_UNKNOWN:
150 0e5011aa 2015-11-21 reyk return ("unknown");
151 0e5011aa 2015-11-21 reyk case HOST_UP:
152 0e5011aa 2015-11-21 reyk return ("up");
153 04447a38 2024-09-20 jsg }
154 0e5011aa 2015-11-21 reyk /* NOTREACHED */
155 0e5011aa 2015-11-21 reyk return ("invalid");
156 0e5011aa 2015-11-21 reyk }
157 0e5011aa 2015-11-21 reyk
158 0e5011aa 2015-11-21 reyk const char *
159 0e5011aa 2015-11-21 reyk table_check(enum table_check check)
160 0e5011aa 2015-11-21 reyk {
161 0e5011aa 2015-11-21 reyk switch (check) {
162 0e5011aa 2015-11-21 reyk case CHECK_NOCHECK:
163 0e5011aa 2015-11-21 reyk return ("none");
164 0e5011aa 2015-11-21 reyk case CHECK_ICMP:
165 0e5011aa 2015-11-21 reyk return ("icmp");
166 0e5011aa 2015-11-21 reyk case CHECK_TCP:
167 0e5011aa 2015-11-21 reyk return ("tcp");
168 0e5011aa 2015-11-21 reyk case CHECK_HTTP_CODE:
169 0e5011aa 2015-11-21 reyk return ("http code");
170 0e5011aa 2015-11-21 reyk case CHECK_HTTP_DIGEST:
171 0e5011aa 2015-11-21 reyk return ("http digest");
172 738b3cc9 2019-09-15 rob case CHECK_BINSEND_EXPECT:
173 0e5011aa 2015-11-21 reyk case CHECK_SEND_EXPECT:
174 0e5011aa 2015-11-21 reyk return ("send expect");
175 0e5011aa 2015-11-21 reyk case CHECK_SCRIPT:
176 0e5011aa 2015-11-21 reyk return ("script");
177 04447a38 2024-09-20 jsg }
178 0e5011aa 2015-11-21 reyk /* NOTREACHED */
179 0e5011aa 2015-11-21 reyk return ("invalid");
180 0e5011aa 2015-11-21 reyk }
181 0e5011aa 2015-11-21 reyk
182 b8764354 2019-05-13 reyk #ifdef DEBUG
183 0e5011aa 2015-11-21 reyk const char *
184 b8764354 2019-05-13 reyk relay_state(enum relay_state state)
185 b8764354 2019-05-13 reyk {
186 b8764354 2019-05-13 reyk switch (state) {
187 b8764354 2019-05-13 reyk case STATE_INIT:
188 b8764354 2019-05-13 reyk return ("init");
189 b8764354 2019-05-13 reyk case STATE_PENDING:
190 b8764354 2019-05-13 reyk return ("pending");
191 b8764354 2019-05-13 reyk case STATE_PRECONNECT:
192 b8764354 2019-05-13 reyk return ("preconnect");
193 b8764354 2019-05-13 reyk case STATE_CONNECTED:
194 b8764354 2019-05-13 reyk return ("connected");
195 b8764354 2019-05-13 reyk case STATE_CLOSED:
196 b8764354 2019-05-13 reyk return ("closed");
197 b8764354 2019-05-13 reyk case STATE_DONE:
198 b8764354 2019-05-13 reyk return ("done");
199 04447a38 2024-09-20 jsg }
200 b8764354 2019-05-13 reyk /* NOTREACHED */
201 b8764354 2019-05-13 reyk return ("invalid");
202 b8764354 2019-05-13 reyk }
203 b8764354 2019-05-13 reyk #endif
204 b8764354 2019-05-13 reyk
205 b8764354 2019-05-13 reyk const char *
206 0e5011aa 2015-11-21 reyk print_availability(u_long cnt, u_long up)
207 0e5011aa 2015-11-21 reyk {
208 0e5011aa 2015-11-21 reyk static char buf[BUFSIZ];
209 0e5011aa 2015-11-21 reyk
210 0e5011aa 2015-11-21 reyk if (cnt == 0)
211 0e5011aa 2015-11-21 reyk return ("");
212 0e5011aa 2015-11-21 reyk bzero(buf, sizeof(buf));
213 0e5011aa 2015-11-21 reyk snprintf(buf, sizeof(buf), "%.2f%%", (double)up / cnt * 100);
214 0e5011aa 2015-11-21 reyk return (buf);
215 0e5011aa 2015-11-21 reyk }
216 0e5011aa 2015-11-21 reyk
217 0e5011aa 2015-11-21 reyk const char *
218 0e5011aa 2015-11-21 reyk print_host(struct sockaddr_storage *ss, char *buf, size_t len)
219 0e5011aa 2015-11-21 reyk {
220 0e5011aa 2015-11-21 reyk if (getnameinfo((struct sockaddr *)ss, ss->ss_len,
221 0e5011aa 2015-11-21 reyk buf, len, NULL, 0, NI_NUMERICHOST) != 0) {
222 0e5011aa 2015-11-21 reyk buf[0] = '\0';
223 0e5011aa 2015-11-21 reyk return (NULL);
224 0e5011aa 2015-11-21 reyk }
225 0e5011aa 2015-11-21 reyk return (buf);
226 0e5011aa 2015-11-21 reyk }
227 0e5011aa 2015-11-21 reyk
228 0e5011aa 2015-11-21 reyk const char *
229 0e5011aa 2015-11-21 reyk print_time(struct timeval *a, struct timeval *b, char *buf, size_t len)
230 0e5011aa 2015-11-21 reyk {
231 0e5011aa 2015-11-21 reyk struct timeval tv;
232 0e5011aa 2015-11-21 reyk u_long h, sec, min;
233 0e5011aa 2015-11-21 reyk
234 0e5011aa 2015-11-21 reyk timerclear(&tv);
235 0e5011aa 2015-11-21 reyk timersub(a, b, &tv);
236 0e5011aa 2015-11-21 reyk sec = tv.tv_sec % 60;
237 0e5011aa 2015-11-21 reyk min = tv.tv_sec / 60 % 60;
238 0e5011aa 2015-11-21 reyk h = tv.tv_sec / 60 / 60;
239 0e5011aa 2015-11-21 reyk
240 0e5011aa 2015-11-21 reyk snprintf(buf, len, "%.2lu:%.2lu:%.2lu", h, min, sec);
241 0e5011aa 2015-11-21 reyk return (buf);
242 0e5011aa 2015-11-21 reyk }
243 0e5011aa 2015-11-21 reyk
244 0e5011aa 2015-11-21 reyk const char *
245 0e5011aa 2015-11-21 reyk printb_flags(const u_int32_t v, const char *bits)
246 0e5011aa 2015-11-21 reyk {
247 0e5011aa 2015-11-21 reyk static char buf[2][BUFSIZ];
248 0e5011aa 2015-11-21 reyk static int idx = 0;
249 0e5011aa 2015-11-21 reyk int i, any = 0;
250 0e5011aa 2015-11-21 reyk char c, *p, *r;
251 0e5011aa 2015-11-21 reyk
252 0e5011aa 2015-11-21 reyk p = r = buf[++idx % 2];
253 0e5011aa 2015-11-21 reyk bzero(p, BUFSIZ);
254 0e5011aa 2015-11-21 reyk
255 0e5011aa 2015-11-21 reyk if (bits) {
256 0e5011aa 2015-11-21 reyk bits++;
257 0e5011aa 2015-11-21 reyk while ((i = *bits++)) {
258 0e5011aa 2015-11-21 reyk if (v & (1 << (i - 1))) {
259 0e5011aa 2015-11-21 reyk if (any) {
260 0e5011aa 2015-11-21 reyk *p++ = ',';
261 0e5011aa 2015-11-21 reyk *p++ = ' ';
262 0e5011aa 2015-11-21 reyk }
263 0e5011aa 2015-11-21 reyk any = 1;
264 0e5011aa 2015-11-21 reyk for (; (c = *bits) > 32; bits++) {
265 0e5011aa 2015-11-21 reyk if (c == '_')
266 0e5011aa 2015-11-21 reyk *p++ = ' ';
267 0e5011aa 2015-11-21 reyk else
268 0e5011aa 2015-11-21 reyk *p++ = tolower((u_char)c);
269 0e5011aa 2015-11-21 reyk }
270 0e5011aa 2015-11-21 reyk } else
271 0e5011aa 2015-11-21 reyk for (; *bits > 32; bits++)
272 0e5011aa 2015-11-21 reyk ;
273 0e5011aa 2015-11-21 reyk }
274 0e5011aa 2015-11-21 reyk }
275 0e5011aa 2015-11-21 reyk
276 0e5011aa 2015-11-21 reyk return (r);
277 0e5011aa 2015-11-21 reyk }
278 0e5011aa 2015-11-21 reyk
279 0e5011aa 2015-11-21 reyk void
280 0e5011aa 2015-11-21 reyk getmonotime(struct timeval *tv)
281 0e5011aa 2015-11-21 reyk {
282 0e5011aa 2015-11-21 reyk struct timespec ts;
283 0e5011aa 2015-11-21 reyk
284 0e5011aa 2015-11-21 reyk if (clock_gettime(CLOCK_MONOTONIC, &ts))
285 0e5011aa 2015-11-21 reyk fatal("clock_gettime");
286 0e5011aa 2015-11-21 reyk
287 0e5011aa 2015-11-21 reyk TIMESPEC_TO_TIMEVAL(tv, &ts);
288 0e5011aa 2015-11-21 reyk }
289 738b3cc9 2019-09-15 rob
290 738b3cc9 2019-09-15 rob struct ibuf *
291 738b3cc9 2019-09-15 rob string2binary(const char *string)
292 738b3cc9 2019-09-15 rob {
293 738b3cc9 2019-09-15 rob struct ibuf *ibuf = NULL;
294 a6b1057a 2023-06-21 claudio unsigned char ch, r;
295 a6b1057a 2023-06-21 claudio size_t i, len;
296 738b3cc9 2019-09-15 rob
297 a6b1057a 2023-06-21 claudio len = strlen(string);
298 a6b1057a 2023-06-21 claudio if (len % 2 != 0)
299 a6b1057a 2023-06-21 claudio goto fail;
300 a6b1057a 2023-06-21 claudio if ((ibuf = ibuf_open(len / 2)) == NULL)
301 a6b1057a 2023-06-21 claudio goto fail;
302 738b3cc9 2019-09-15 rob
303 a6b1057a 2023-06-21 claudio while (*string) {
304 a6b1057a 2023-06-21 claudio r = 0;
305 a6b1057a 2023-06-21 claudio for (i = 0; i < 2; i++) {
306 a6b1057a 2023-06-21 claudio ch = string[i];
307 a6b1057a 2023-06-21 claudio if (isdigit(ch))
308 a6b1057a 2023-06-21 claudio ch -= '0';
309 a6b1057a 2023-06-21 claudio else if (islower(ch))
310 a6b1057a 2023-06-21 claudio ch -= ('a' - 10);
311 a6b1057a 2023-06-21 claudio else if (isupper(ch))
312 a6b1057a 2023-06-21 claudio ch -= ('A' - 10);
313 a6b1057a 2023-06-21 claudio else
314 a6b1057a 2023-06-21 claudio goto fail;
315 a6b1057a 2023-06-21 claudio if (ch > 0xf)
316 a6b1057a 2023-06-21 claudio goto fail;
317 a6b1057a 2023-06-21 claudio r = r << 4 | ch;
318 738b3cc9 2019-09-15 rob }
319 a6b1057a 2023-06-21 claudio if (ibuf_add_n8(ibuf, r) == -1)
320 a6b1057a 2023-06-21 claudio goto fail;
321 a6b1057a 2023-06-21 claudio string += 2;
322 738b3cc9 2019-09-15 rob }
323 a6b1057a 2023-06-21 claudio
324 738b3cc9 2019-09-15 rob return ibuf;
325 a6b1057a 2023-06-21 claudio
326 a6b1057a 2023-06-21 claudio fail:
327 a6b1057a 2023-06-21 claudio ibuf_free(ibuf);
328 a6b1057a 2023-06-21 claudio return NULL;
329 738b3cc9 2019-09-15 rob }
330 738b3cc9 2019-09-15 rob
331 738b3cc9 2019-09-15 rob void
332 738b3cc9 2019-09-15 rob print_hex(uint8_t *buf, off_t offset, size_t length)
333 738b3cc9 2019-09-15 rob {
334 738b3cc9 2019-09-15 rob unsigned int i;
335 738b3cc9 2019-09-15 rob
336 738b3cc9 2019-09-15 rob if (log_getverbose() < 3 || !length)
337 738b3cc9 2019-09-15 rob return;
338 738b3cc9 2019-09-15 rob
339 738b3cc9 2019-09-15 rob for (i = 0; i < length; i++) {
340 738b3cc9 2019-09-15 rob if (i && (i % 4) == 0) {
341 738b3cc9 2019-09-15 rob if ((i % 32) == 0)
342 738b3cc9 2019-09-15 rob print_debug("\n");
343 738b3cc9 2019-09-15 rob else
344 738b3cc9 2019-09-15 rob print_debug(" ");
345 738b3cc9 2019-09-15 rob }
346 738b3cc9 2019-09-15 rob print_debug("%02x", buf[offset + i]);
347 738b3cc9 2019-09-15 rob }
348 738b3cc9 2019-09-15 rob print_debug("\n");
349 738b3cc9 2019-09-15 rob }
350 738b3cc9 2019-09-15 rob
351 738b3cc9 2019-09-15 rob void
352 738b3cc9 2019-09-15 rob print_debug(const char *emsg, ...)
353 738b3cc9 2019-09-15 rob {
354 738b3cc9 2019-09-15 rob va_list ap;
355 738b3cc9 2019-09-15 rob
356 738b3cc9 2019-09-15 rob if (log_getverbose() > 2) {
357 738b3cc9 2019-09-15 rob va_start(ap, emsg);
358 738b3cc9 2019-09-15 rob vfprintf(stderr, emsg, ap);
359 738b3cc9 2019-09-15 rob va_end(ap);
360 738b3cc9 2019-09-15 rob }
361 738b3cc9 2019-09-15 rob }