xref: /openbsd-src/usr.sbin/snmpd/log.c (revision 91f110e064cd7c194e59e019b83bb7496c1c84d4)
1 /*	$OpenBSD: log.c,v 1.4 2013/10/17 08:42:44 reyk Exp $	*/
2 
3 /*
4  * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
15  * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
16  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #include <sys/types.h>
20 #include <sys/param.h>
21 #include <sys/queue.h>
22 #include <sys/socket.h>
23 #include <sys/tree.h>
24 
25 #include <netinet/in_systm.h>
26 #include <netinet/in.h>
27 #include <netinet/ip.h>
28 #include <net/if.h>
29 
30 #include <arpa/inet.h>
31 
32 #include <errno.h>
33 #include <stdarg.h>
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #include <syslog.h>
38 #include <event.h>
39 #include <netdb.h>
40 
41 #include <openssl/ssl.h>
42 
43 #include "snmpd.h"
44 
45 int	 debug;
46 int	 verbose;
47 
48 void	 vlog(int, const char *, va_list);
49 void	 logit(int, const char *, ...);
50 
51 void
52 log_init(int n_debug)
53 {
54 	extern char	*__progname;
55 
56 	debug = n_debug;
57 	verbose = n_debug;
58 
59 	if (!debug)
60 		openlog(__progname, LOG_PID | LOG_NDELAY, LOG_DAEMON);
61 
62 	tzset();
63 }
64 
65 void
66 log_verbose(int v)
67 {
68 	verbose = v;
69 }
70 
71 void
72 logit(int pri, const char *fmt, ...)
73 {
74 	va_list	ap;
75 
76 	va_start(ap, fmt);
77 	vlog(pri, fmt, ap);
78 	va_end(ap);
79 }
80 
81 void
82 vlog(int pri, const char *fmt, va_list ap)
83 {
84 	char	*nfmt;
85 
86 	if (debug) {
87 		/* best effort in out of mem situations */
88 		if (asprintf(&nfmt, "%s\n", fmt) == -1) {
89 			vfprintf(stderr, fmt, ap);
90 			fprintf(stderr, "\n");
91 		} else {
92 			vfprintf(stderr, nfmt, ap);
93 			free(nfmt);
94 		}
95 		fflush(stderr);
96 	} else
97 		vsyslog(pri, fmt, ap);
98 }
99 
100 
101 void
102 log_warn(const char *emsg, ...)
103 {
104 	char	*nfmt;
105 	va_list	 ap;
106 
107 	/* best effort to even work in out of memory situations */
108 	if (emsg == NULL)
109 		logit(LOG_CRIT, "%s", strerror(errno));
110 	else {
111 		va_start(ap, emsg);
112 
113 		if (asprintf(&nfmt, "%s: %s", emsg, strerror(errno)) == -1) {
114 			/* we tried it... */
115 			vlog(LOG_CRIT, emsg, ap);
116 			logit(LOG_CRIT, "%s", strerror(errno));
117 		} else {
118 			vlog(LOG_CRIT, nfmt, ap);
119 			free(nfmt);
120 		}
121 		va_end(ap);
122 	}
123 }
124 
125 void
126 log_warnx(const char *emsg, ...)
127 {
128 	va_list	 ap;
129 
130 	va_start(ap, emsg);
131 	vlog(LOG_CRIT, emsg, ap);
132 	va_end(ap);
133 }
134 
135 void
136 log_info(const char *emsg, ...)
137 {
138 	va_list	 ap;
139 
140 	va_start(ap, emsg);
141 	vlog(LOG_INFO, emsg, ap);
142 	va_end(ap);
143 }
144 
145 void
146 log_debug(const char *emsg, ...)
147 {
148 	va_list	 ap;
149 
150 	if (verbose > 1) {
151 		va_start(ap, emsg);
152 		vlog(LOG_DEBUG, emsg, ap);
153 		va_end(ap);
154 	}
155 }
156 
157 void
158 print_debug(const char *emsg, ...)
159 {
160 	va_list	 ap;
161 
162 	if (debug && verbose > 2) {
163 		va_start(ap, emsg);
164 		vfprintf(stderr, emsg, ap);
165 		va_end(ap);
166 	}
167 }
168 
169 void
170 print_verbose(const char *emsg, ...)
171 {
172 	va_list	 ap;
173 
174 	if (verbose) {
175 		va_start(ap, emsg);
176 		vfprintf(stderr, emsg, ap);
177 		va_end(ap);
178 	}
179 }
180 
181 void
182 fatal(const char *emsg)
183 {
184 	if (emsg == NULL)
185 		logit(LOG_CRIT, "fatal: %s", strerror(errno));
186 	else {
187 		if (errno)
188 			logit(LOG_CRIT, "fatal: %s: %s",
189 			    emsg, strerror(errno));
190 		else
191 			logit(LOG_CRIT, "fatal: %s", emsg);
192 	}
193 
194 	exit(1);
195 }
196 
197 void
198 fatalx(const char *emsg)
199 {
200 	errno = 0;
201 	fatal(emsg);
202 }
203 
204 const char *
205 log_in6addr(const struct in6_addr *addr)
206 {
207 	static char		buf[NI_MAXHOST];
208 	struct sockaddr_in6	sa_in6;
209 	u_int16_t		tmp16;
210 
211 	bzero(&sa_in6, sizeof(sa_in6));
212 	sa_in6.sin6_len = sizeof(sa_in6);
213 	sa_in6.sin6_family = AF_INET6;
214 	memcpy(&sa_in6.sin6_addr, addr, sizeof(sa_in6.sin6_addr));
215 
216 	/* XXX thanks, KAME, for this ugliness... adopted from route/show.c */
217 	if (IN6_IS_ADDR_LINKLOCAL(&sa_in6.sin6_addr) ||
218 	    IN6_IS_ADDR_MC_LINKLOCAL(&sa_in6.sin6_addr)) {
219 		memcpy(&tmp16, &sa_in6.sin6_addr.s6_addr[2], sizeof(tmp16));
220 		sa_in6.sin6_scope_id = ntohs(tmp16);
221 		sa_in6.sin6_addr.s6_addr[2] = 0;
222 		sa_in6.sin6_addr.s6_addr[3] = 0;
223 	}
224 
225 	return (print_host((struct sockaddr_storage *)&sa_in6, buf,
226 	    NI_MAXHOST));
227 }
228 
229 const char *
230 print_host(struct sockaddr_storage *ss, char *buf, size_t len)
231 {
232 	if (getnameinfo((struct sockaddr *)ss, ss->ss_len,
233 	    buf, len, NULL, 0, NI_NUMERICHOST) != 0) {
234 		buf[0] = '\0';
235 		return (NULL);
236 	}
237 	return (buf);
238 }
239