1 /* $OpenBSD: agentx_log.c,v 1.2 2020/10/26 16:02:16 tb Exp $ */
2 /*
3 * Copyright (c) 2020 Martijn van Duren <martijn@openbsd.org>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18 #include <errno.h>
19 #include <stdarg.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23
24 #include "agentx_internal.h"
25
26 #define AGENTX_CONTEXT_NAME(axc) (axc->axc_name_default ? "<default>" : \
27 (char *)axc->axc_name.aos_string)
28 #define AGENTX_GET_CTXNAME(axg) (axg->axg_context_default ? "<default>" : \
29 (char *)axg->axg_context.aos_string)
30
31 enum agentx_log_type {
32 AGENTX_LOG_TYPE_FATAL,
33 AGENTX_LOG_TYPE_WARN,
34 AGENTX_LOG_TYPE_INFO,
35 AGENTX_LOG_TYPE_DEBUG
36 };
37
38 void (*agentx_log_fatal)(const char *, ...)
39 __attribute__((__format__ (printf, 1, 2))) = NULL;
40 void (*agentx_log_warn)(const char *, ...)
41 __attribute__((__format__ (printf, 1, 2))) = NULL;
42 void (*agentx_log_info)(const char *, ...)
43 __attribute__((__format__ (printf, 1, 2))) = NULL;
44 void (*agentx_log_debug)(const char *, ...)
45 __attribute__((__format__ (printf, 1, 2))) = NULL;
46
47
48 static void
49 agentx_log_do(enum agentx_log_type, const char *, va_list, int,
50 struct agentx *, struct agentx_session *, struct agentx_context *,
51 struct agentx_get *);
52
53 void
agentx_log_ax_fatalx(struct agentx * ax,const char * fmt,...)54 agentx_log_ax_fatalx(struct agentx *ax, const char *fmt, ...)
55 {
56 va_list ap;
57
58 va_start(ap, fmt);
59 agentx_log_do(AGENTX_LOG_TYPE_FATAL, fmt, ap, 0, ax, NULL, NULL,
60 NULL);
61 va_end(ap);
62 abort();
63 }
64
65 void
agentx_log_ax_warn(struct agentx * ax,const char * fmt,...)66 agentx_log_ax_warn(struct agentx *ax, const char *fmt, ...)
67 {
68 va_list ap;
69
70 va_start(ap, fmt);
71 agentx_log_do(AGENTX_LOG_TYPE_WARN, fmt, ap, 1, ax, NULL, NULL,
72 NULL);
73 va_end(ap);
74 }
75
76 void
agentx_log_ax_warnx(struct agentx * ax,const char * fmt,...)77 agentx_log_ax_warnx(struct agentx *ax, const char *fmt, ...)
78 {
79 va_list ap;
80
81 va_start(ap, fmt);
82 agentx_log_do(AGENTX_LOG_TYPE_WARN, fmt, ap, 0, ax, NULL, NULL,
83 NULL);
84 va_end(ap);
85 }
86
87 void
agentx_log_ax_info(struct agentx * ax,const char * fmt,...)88 agentx_log_ax_info(struct agentx *ax, const char *fmt, ...)
89 {
90 va_list ap;
91
92 va_start(ap, fmt);
93 agentx_log_do(AGENTX_LOG_TYPE_INFO, fmt, ap, 0, ax, NULL, NULL,
94 NULL);
95 va_end(ap);
96 }
97
98 void
agentx_log_ax_debug(struct agentx * ax,const char * fmt,...)99 agentx_log_ax_debug(struct agentx *ax, const char *fmt, ...)
100 {
101 va_list ap;
102
103 va_start(ap, fmt);
104 agentx_log_do(AGENTX_LOG_TYPE_DEBUG, fmt, ap, 0, ax, NULL, NULL,
105 NULL);
106 va_end(ap);
107 }
108
109 void
agentx_log_axs_fatalx(struct agentx_session * axs,const char * fmt,...)110 agentx_log_axs_fatalx(struct agentx_session *axs, const char *fmt, ...)
111 {
112 va_list ap;
113
114 va_start(ap, fmt);
115 agentx_log_do(AGENTX_LOG_TYPE_FATAL, fmt, ap, 0, NULL, axs, NULL,
116 NULL);
117 va_end(ap);
118 abort();
119 }
120
121 void
agentx_log_axs_warnx(struct agentx_session * axs,const char * fmt,...)122 agentx_log_axs_warnx(struct agentx_session *axs, const char *fmt, ...)
123 {
124 va_list ap;
125
126 va_start(ap, fmt);
127 agentx_log_do(AGENTX_LOG_TYPE_WARN, fmt, ap, 0, NULL, axs, NULL,
128 NULL);
129 va_end(ap);
130 }
131
132 void
agentx_log_axs_warn(struct agentx_session * axs,const char * fmt,...)133 agentx_log_axs_warn(struct agentx_session *axs, const char *fmt, ...)
134 {
135 va_list ap;
136
137 va_start(ap, fmt);
138 agentx_log_do(AGENTX_LOG_TYPE_WARN, fmt, ap, 1, NULL, axs, NULL,
139 NULL);
140 va_end(ap);
141 }
142
143 void
agentx_log_axs_info(struct agentx_session * axs,const char * fmt,...)144 agentx_log_axs_info(struct agentx_session *axs, const char *fmt, ...)
145 {
146 va_list ap;
147
148 va_start(ap, fmt);
149 agentx_log_do(AGENTX_LOG_TYPE_INFO, fmt, ap, 0, NULL, axs, NULL,
150 NULL);
151 va_end(ap);
152 }
153
154 void
agentx_log_axc_fatalx(struct agentx_context * axc,const char * fmt,...)155 agentx_log_axc_fatalx(struct agentx_context *axc, const char *fmt, ...)
156 {
157 va_list ap;
158
159 va_start(ap, fmt);
160 agentx_log_do(AGENTX_LOG_TYPE_FATAL, fmt, ap, 0, NULL, NULL, axc,
161 NULL);
162 va_end(ap);
163 abort();
164 }
165
166 void
agentx_log_axc_warnx(struct agentx_context * axc,const char * fmt,...)167 agentx_log_axc_warnx(struct agentx_context *axc, const char *fmt, ...)
168 {
169 va_list ap;
170
171 va_start(ap, fmt);
172 agentx_log_do(AGENTX_LOG_TYPE_WARN, fmt, ap, 0, NULL, NULL, axc,
173 NULL);
174 va_end(ap);
175 }
176
177 void
agentx_log_axc_warn(struct agentx_context * axc,const char * fmt,...)178 agentx_log_axc_warn(struct agentx_context *axc, const char *fmt, ...)
179 {
180 va_list ap;
181
182 va_start(ap, fmt);
183 agentx_log_do(AGENTX_LOG_TYPE_WARN, fmt, ap, 1, NULL, NULL, axc,
184 NULL);
185 va_end(ap);
186 }
187
188 void
agentx_log_axc_info(struct agentx_context * axc,const char * fmt,...)189 agentx_log_axc_info(struct agentx_context *axc, const char *fmt, ...)
190 {
191 va_list ap;
192
193 va_start(ap, fmt);
194 agentx_log_do(AGENTX_LOG_TYPE_INFO, fmt, ap, 0, NULL, NULL, axc,
195 NULL);
196 va_end(ap);
197 }
198
199 void
agentx_log_axc_debug(struct agentx_context * axc,const char * fmt,...)200 agentx_log_axc_debug(struct agentx_context *axc, const char *fmt, ...)
201 {
202 va_list ap;
203
204 va_start(ap, fmt);
205 agentx_log_do(AGENTX_LOG_TYPE_DEBUG, fmt, ap, 0, NULL, NULL, axc,
206 NULL);
207 va_end(ap);
208 }
209
210 void
agentx_log_axg_fatalx(struct agentx_get * axg,const char * fmt,...)211 agentx_log_axg_fatalx(struct agentx_get *axg, const char *fmt, ...)
212 {
213 va_list ap;
214
215 va_start(ap, fmt);
216 agentx_log_do(AGENTX_LOG_TYPE_FATAL, fmt, ap, 0, NULL, NULL, NULL,
217 axg);
218 va_end(ap);
219 abort();
220 }
221
222 void
agentx_log_axg_warnx(struct agentx_get * axg,const char * fmt,...)223 agentx_log_axg_warnx(struct agentx_get *axg, const char *fmt, ...)
224 {
225 va_list ap;
226
227 va_start(ap, fmt);
228 agentx_log_do(AGENTX_LOG_TYPE_WARN, fmt, ap, 0, NULL, NULL, NULL,
229 axg);
230 va_end(ap);
231 }
232
233 void
agentx_log_axg_warn(struct agentx_get * axg,const char * fmt,...)234 agentx_log_axg_warn(struct agentx_get *axg, const char *fmt, ...)
235 {
236 va_list ap;
237
238 va_start(ap, fmt);
239 agentx_log_do(AGENTX_LOG_TYPE_WARN, fmt, ap, 1, NULL, NULL, NULL,
240 axg);
241 va_end(ap);
242 }
243
244 void
agentx_log_axg_debug(struct agentx_get * axg,const char * fmt,...)245 agentx_log_axg_debug(struct agentx_get *axg, const char *fmt, ...)
246 {
247 va_list ap;
248
249 va_start(ap, fmt);
250 agentx_log_do(AGENTX_LOG_TYPE_DEBUG, fmt, ap, 0, NULL, NULL, NULL,
251 axg);
252 va_end(ap);
253 }
254
255 static void
agentx_log_do(enum agentx_log_type type,const char * fmt,va_list ap,int useerrno,struct agentx * ax,struct agentx_session * axs,struct agentx_context * axc,struct agentx_get * axg)256 agentx_log_do(enum agentx_log_type type, const char *fmt, va_list ap,
257 int useerrno, struct agentx *ax, struct agentx_session *axs,
258 struct agentx_context *axc, struct agentx_get *axg)
259 {
260 void (*agentx_log)(const char *, ...);
261 char buf[1500];
262
263 if (type == AGENTX_LOG_TYPE_FATAL)
264 agentx_log = agentx_log_fatal;
265 else if (type == AGENTX_LOG_TYPE_WARN)
266 agentx_log = agentx_log_warn;
267 else if (type == AGENTX_LOG_TYPE_INFO)
268 agentx_log = agentx_log_info;
269 else
270 agentx_log = agentx_log_debug;
271 if (agentx_log == NULL)
272 return;
273
274 vsnprintf(buf, sizeof(buf), fmt, ap);
275
276 if (axg != NULL) {
277 if (useerrno)
278 agentx_log("[fd:%d sess:%u ctx:%s trid:%u pid:%u]: "
279 "%s: %s", axg->axg_fd, axg->axg_sessionid,
280 AGENTX_GET_CTXNAME(axg), axg->axg_transactionid,
281 axg->axg_packetid, buf, strerror(errno));
282 else
283 agentx_log("[fd:%d sess:%u ctx:%s trid:%u pid:%u]: "
284 "%s", axg->axg_fd, axg->axg_sessionid,
285 AGENTX_GET_CTXNAME(axg), axg->axg_transactionid,
286 axg->axg_packetid, buf);
287 } else if (axc != NULL) {
288 axs = axc->axc_axs;
289 ax = axs->axs_ax;
290 if (useerrno)
291 agentx_log("[fd:%d sess:%u ctx:%s]: %s: %s",
292 ax->ax_fd, axs->axs_id, AGENTX_CONTEXT_NAME(axc),
293 buf, strerror(errno));
294 else
295 agentx_log("[fd:%d sess:%u ctx:%s]: %s", ax->ax_fd,
296 axs->axs_id, AGENTX_CONTEXT_NAME(axc), buf);
297 } else if (axs != NULL) {
298 ax = axs->axs_ax;
299 if (useerrno)
300 agentx_log("[fd:%d sess:%u]: %s: %s", ax->ax_fd,
301 axs->axs_id, buf, strerror(errno));
302 else
303 agentx_log("[fd:%d sess:%u]: %s", ax->ax_fd,
304 axs->axs_id, buf);
305 } else if (ax->ax_fd == -1) {
306 if (useerrno)
307 agentx_log("%s: %s", buf, strerror(errno));
308 else
309 agentx_log("%s", buf);
310 } else {
311 if (useerrno)
312 agentx_log("[fd:%d]: %s: %s", ax->ax_fd, buf,
313 strerror(errno));
314 else
315 agentx_log("[fd:%d]: %s", ax->ax_fd, buf);
316 }
317 }
318