2 __RCSID("$NetBSD: common.c,v 1.14 2015/07/09 10:15:34 roy Exp $");
5 * dhcpcd - DHCP client daemon
6 * Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
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
31 #include <sys/param.h>
53 #include "if-options.h"
56 # define _PATH_DEVNULL "/dev/null"
60 get_hostname(char *buf
, size_t buflen
, int short_hostname
)
64 if (gethostname(buf
, buflen
) != 0)
66 buf
[buflen
- 1] = '\0';
67 if (strcmp(buf
, "(none)") == 0 ||
68 strcmp(buf
, "localhost") == 0 ||
69 strncmp(buf
, "localhost.", strlen("localhost.")) == 0 ||
84 logger_open(struct dhcpcd_ctx
*ctx
)
88 int f
= O_CREAT
| O_APPEND
| O_TRUNC
;
93 ctx
->log_fd
= open(ctx
->logfile
, O_WRONLY
| f
, 0644);
94 if (ctx
->log_fd
== -1)
95 warn("open: %s", ctx
->logfile
);
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
);
104 openlog(PACKAGE
, LOG_PID
, LOG_DAEMON
);
108 logger_close(struct dhcpcd_ctx
*ctx
)
111 if (ctx
->log_fd
!= -1) {
119 logger(struct dhcpcd_ctx
*ctx
, int pri
, const char *fmt
, ...)
123 #ifndef HAVE_PRINTF_M
127 if (pri
>= LOG_DEBUG
&& ctx
&& !(ctx
->options
& DHCPCD_DEBUG
))
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)
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] == '%') {
149 } else if (p
[0] == '%' && p
[1] == 'm') {
151 serr
= strerror(serrno
);
152 fmt_wrote
= strlcpy(fp
, serr
, fmt_left
);
153 if (fmt_wrote
> fmt_left
)
156 fmt_left
-= fmt_wrote
;
171 if (ctx
== NULL
|| !(ctx
->options
& DHCPCD_QUIET
)) {
175 vfprintf(pri
<= LOG_ERR
? stderr
: stdout
, fmt
, vac
);
176 fputc('\n', pri
<= LOG_ERR
? stderr
: stdout
);
183 if (ctx
&& ctx
->log_fd
!= -1) {
187 /* Write the time, syslog style. month day time - */
188 if (gettimeofday(&tv
, NULL
) != -1) {
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");
202 vsyslog(pri
, fmt
, va
);
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;
214 len
+= strlen(prefix
) + 1;
217 logger(ctx
, LOG_ERR
, "%s: %m", __func__
);
221 snprintf(*e
, len
, "%s_%s=%s", prefix
, var
, value
);
223 snprintf(*e
, len
, "%s=%s", var
, value
);
228 setvard(struct dhcpcd_ctx
*ctx
,
229 char **e
, const char *prefix
, const char *var
, size_t value
)
234 snprintf(buffer
, sizeof(buffer
), "%zu", value
);
235 return setvar(ctx
, e
, prefix
, var
, buffer
);
239 addvar(struct dhcpcd_ctx
*ctx
,
240 char ***e
, const char *prefix
, const char *var
, const char *value
)
244 len
= setvar(ctx
, *e
, prefix
, var
, value
);
251 addvard(struct dhcpcd_ctx
*ctx
,
252 char ***e
, const char *prefix
, const char *var
, size_t value
)
256 snprintf(buffer
, sizeof(buffer
), "%zu", value
);
257 return addvar(ctx
, e
, prefix
, var
, buffer
);
261 hwaddr_ntoa(const unsigned char *hwaddr
, size_t hwlen
, char *buf
, size_t buflen
)
270 if (hwlen
* 3 > buflen
) {
276 for (i
= 0; i
< hwlen
; i
++) {
279 p
+= snprintf(p
, 3, "%.2x", hwaddr
[i
]);
286 hwaddr_aton(unsigned char *buffer
, const char *addr
)
289 const char *p
= addr
;
290 unsigned char *bp
= buffer
;
297 /* Ensure that digits are hex */
298 if (isxdigit((unsigned char)c
[0]) == 0 ||
299 isxdigit((unsigned char)c
[1]) == 0)
304 /* We should have at least two entries 00:01 */
305 if (len
== 0 && *p
== '\0') {
309 /* Ensure that next data is EOL or a seperator with data */
310 if (!(*p
== '\0' || (*p
== ':' && *(p
+ 1) != '\0'))) {
317 *bp
++ = (unsigned char)strtol(c
, NULL
, 16);