Remove building with NOCRYPTO option
[minix3.git] / external / bsd / dhcpcd / dist / common.c
blob6cbfeb8449c5765fad62bd71e20601c8c8e8e977
1 #include <sys/cdefs.h>
2 __RCSID("$NetBSD: common.c,v 1.14 2015/07/09 10:15:34 roy Exp $");
4 /*
5 * dhcpcd - DHCP client daemon
6 * Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
7 * All rights reserved
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
31 #include <sys/param.h>
32 #include <sys/time.h>
34 #include <ctype.h>
35 #include <err.h>
36 #include <errno.h>
37 #include <fcntl.h>
38 #include <limits.h>
39 #ifdef BSD
40 # include <paths.h>
41 #endif
42 #include <stdarg.h>
43 #include <stdint.h>
44 #include <stdio.h>
45 #include <stdlib.h>
46 #include <string.h>
47 #include <syslog.h>
48 #include <time.h>
49 #include <unistd.h>
51 #include "common.h"
52 #include "dhcpcd.h"
53 #include "if-options.h"
55 #ifndef _PATH_DEVNULL
56 # define _PATH_DEVNULL "/dev/null"
57 #endif
59 const char *
60 get_hostname(char *buf, size_t buflen, int short_hostname)
62 char *p;
64 if (gethostname(buf, buflen) != 0)
65 return NULL;
66 buf[buflen - 1] = '\0';
67 if (strcmp(buf, "(none)") == 0 ||
68 strcmp(buf, "localhost") == 0 ||
69 strncmp(buf, "localhost.", strlen("localhost.")) == 0 ||
70 buf[0] == '.')
71 return NULL;
73 if (short_hostname) {
74 p = strchr(buf, '.');
75 if (p)
76 *p = '\0';
79 return buf;
82 #if USE_LOGFILE
83 void
84 logger_open(struct dhcpcd_ctx *ctx)
87 if (ctx->logfile) {
88 int f = O_CREAT | O_APPEND | O_TRUNC;
90 #ifdef O_CLOEXEC
91 f |= O_CLOEXEC;
92 #endif
93 ctx->log_fd = open(ctx->logfile, O_WRONLY | f, 0644);
94 if (ctx->log_fd == -1)
95 warn("open: %s", ctx->logfile);
96 #ifndef O_CLOEXEC
97 else {
98 if (fcntl(ctx->log_fd, F_GETFD, &f) == -1 ||
99 fcntl(ctx->log_fd, F_SETFD, f | FD_CLOEXEC) == -1)
100 warn("fcntl: %s", ctx->logfile);
102 #endif
103 } else
104 openlog(PACKAGE, LOG_PID, LOG_DAEMON);
107 void
108 logger_close(struct dhcpcd_ctx *ctx)
111 if (ctx->log_fd != -1) {
112 close(ctx->log_fd);
113 ctx->log_fd = -1;
115 closelog();
118 void
119 logger(struct dhcpcd_ctx *ctx, int pri, const char *fmt, ...)
121 va_list va;
122 int serrno;
123 #ifndef HAVE_PRINTF_M
124 char fmt_cpy[1024];
125 #endif
127 if (pri >= LOG_DEBUG && ctx && !(ctx->options & DHCPCD_DEBUG))
128 return;
130 serrno = errno;
131 va_start(va, fmt);
133 #ifndef HAVE_PRINTF_M
134 /* Print strerrno(errno) in place of %m */
135 if (ctx == NULL || !(ctx->options & DHCPCD_QUIET) || ctx->log_fd != -1)
137 const char *p;
138 char *fp = fmt_cpy, *serr = NULL;
139 size_t fmt_left = sizeof(fmt_cpy) - 1, fmt_wrote;
141 for (p = fmt; *p != '\0'; p++) {
142 if (p[0] == '%' && p[1] == '%') {
143 if (fmt_left < 2)
144 break;
145 *fp++ = '%';
146 *fp++ = '%';
147 fmt_left -= 2;
148 p++;
149 } else if (p[0] == '%' && p[1] == 'm') {
150 if (serr == NULL)
151 serr = strerror(serrno);
152 fmt_wrote = strlcpy(fp, serr, fmt_left);
153 if (fmt_wrote > fmt_left)
154 break;
155 fp += fmt_wrote;
156 fmt_left -= fmt_wrote;
157 p++;
158 } else {
159 *fp++ = *p;
160 --fmt_left;
162 if (fmt_left == 0)
163 break;
165 *fp++ = '\0';
166 fmt = fmt_cpy;
169 #endif
171 if (ctx == NULL || !(ctx->options & DHCPCD_QUIET)) {
172 va_list vac;
174 va_copy(vac, va);
175 vfprintf(pri <= LOG_ERR ? stderr : stdout, fmt, vac);
176 fputc('\n', pri <= LOG_ERR ? stderr : stdout);
177 va_end(vac);
180 #ifdef HAVE_PRINTF_M
181 errno = serrno;
182 #endif
183 if (ctx && ctx->log_fd != -1) {
184 struct timeval tv;
185 char buf[32];
187 /* Write the time, syslog style. month day time - */
188 if (gettimeofday(&tv, NULL) != -1) {
189 time_t now;
190 struct tm tmnow;
192 tzset();
193 now = tv.tv_sec;
194 localtime_r(&now, &tmnow);
195 strftime(buf, sizeof(buf), "%b %d %T ", &tmnow);
196 dprintf(ctx->log_fd, "%s", buf);
199 vdprintf(ctx->log_fd, fmt, va);
200 dprintf(ctx->log_fd, "\n");
201 } else
202 vsyslog(pri, fmt, va);
203 va_end(va);
205 #endif
207 ssize_t
208 setvar(struct dhcpcd_ctx *ctx,
209 char **e, const char *prefix, const char *var, const char *value)
211 size_t len = strlen(var) + strlen(value) + 3;
213 if (prefix)
214 len += strlen(prefix) + 1;
215 *e = malloc(len);
216 if (*e == NULL) {
217 logger(ctx, LOG_ERR, "%s: %m", __func__);
218 return -1;
220 if (prefix)
221 snprintf(*e, len, "%s_%s=%s", prefix, var, value);
222 else
223 snprintf(*e, len, "%s=%s", var, value);
224 return (ssize_t)len;
227 ssize_t
228 setvard(struct dhcpcd_ctx *ctx,
229 char **e, const char *prefix, const char *var, size_t value)
232 char buffer[32];
234 snprintf(buffer, sizeof(buffer), "%zu", value);
235 return setvar(ctx, e, prefix, var, buffer);
238 ssize_t
239 addvar(struct dhcpcd_ctx *ctx,
240 char ***e, const char *prefix, const char *var, const char *value)
242 ssize_t len;
244 len = setvar(ctx, *e, prefix, var, value);
245 if (len != -1)
246 (*e)++;
247 return (ssize_t)len;
250 ssize_t
251 addvard(struct dhcpcd_ctx *ctx,
252 char ***e, const char *prefix, const char *var, size_t value)
254 char buffer[32];
256 snprintf(buffer, sizeof(buffer), "%zu", value);
257 return addvar(ctx, e, prefix, var, buffer);
260 char *
261 hwaddr_ntoa(const unsigned char *hwaddr, size_t hwlen, char *buf, size_t buflen)
263 char *p;
264 size_t i;
266 if (buf == NULL) {
267 return NULL;
270 if (hwlen * 3 > buflen) {
271 errno = ENOBUFS;
272 return 0;
275 p = buf;
276 for (i = 0; i < hwlen; i++) {
277 if (i > 0)
278 *p ++= ':';
279 p += snprintf(p, 3, "%.2x", hwaddr[i]);
281 *p ++= '\0';
282 return buf;
285 size_t
286 hwaddr_aton(unsigned char *buffer, const char *addr)
288 char c[3];
289 const char *p = addr;
290 unsigned char *bp = buffer;
291 size_t len = 0;
293 c[2] = '\0';
294 while (*p) {
295 c[0] = *p++;
296 c[1] = *p++;
297 /* Ensure that digits are hex */
298 if (isxdigit((unsigned char)c[0]) == 0 ||
299 isxdigit((unsigned char)c[1]) == 0)
301 errno = EINVAL;
302 return 0;
304 /* We should have at least two entries 00:01 */
305 if (len == 0 && *p == '\0') {
306 errno = EINVAL;
307 return 0;
309 /* Ensure that next data is EOL or a seperator with data */
310 if (!(*p == '\0' || (*p == ':' && *(p + 1) != '\0'))) {
311 errno = EINVAL;
312 return 0;
314 if (*p)
315 p++;
316 if (bp)
317 *bp++ = (unsigned char)strtol(c, NULL, 16);
318 len++;
320 return len;