#undef LOGERR_TAG
#endif
+/* syslog protocol is 1k message max, RFC 3164 section 4.1 */
+#define LOGERR_SYSLOGBUF 1024 + sizeof(int)
+
#define UNUSED(a) (void)(a)
struct logctx {
char log_buf[BUFSIZ];
unsigned int log_opts;
+ int log_syslogfd;
#ifndef SMALL
FILE *log_file;
#ifdef LOGERR_TAG
static struct logctx _logctx = {
/* syslog style, but without the hostname or tag. */
.log_opts = LOGERR_LOG | LOGERR_LOG_DATE | LOGERR_LOG_PID,
+ .log_syslogfd = -1,
};
-#if defined(LOGERR_TAG) && defined(__linux__)
+#if defined(__linux__)
/* Poor man's getprogname(3). */
static char *_logprog;
static const char *
* so zero the buffer. */
if ((_logprog = calloc(1, PATH_MAX + 1)) == NULL)
return NULL;
+ if (readlink("/proc/self/exe", _logprog, PATH_MAX + 1) == -1) {
+ free(_logprog);
+ _logprog = NULL;
+ return NULL;
+ }
}
- if (readlink("/proc/self/exe", _logprog, PATH_MAX + 1) == -1)
- return NULL;
if (_logprog[0] == '[')
return NULL;
p = strrchr(_logprog, '/');
struct logctx *ctx = &_logctx;
int len = 0;
+ if (ctx->log_syslogfd != -1) {
+ char buf[LOGERR_SYSLOGBUF];
+
+ memcpy(buf, &pri, sizeof(pri));
+ len = vsnprintf(buf + sizeof(pri), sizeof(buf) - sizeof(pri),
+ fmt, args);
+ if (len != -1)
+ len = (int)write(ctx->log_syslogfd, buf,
+ ((size_t)++len) + sizeof(pri));
+ return len;
+ }
+
if (ctx->log_opts & LOGERR_ERR &&
(pri <= LOG_ERR ||
(!(ctx->log_opts & LOGERR_QUIET) && pri <= LOG_INFO) ||
(ctx->log_opts & LOGERR_DEBUG && pri <= LOG_DEBUG)))
len = vlogprintf_r(ctx, stderr, fmt, args);
- if (!(ctx->log_opts & LOGERR_LOG))
- return len;
-
#ifndef SMALL
if (ctx->log_file != NULL &&
(pri != LOG_DEBUG || (ctx->log_opts & LOGERR_DEBUG)))
len = vlogprintf_r(ctx, ctx->log_file, fmt, args);
#endif
- vsyslog(pri, fmt, args);
+ if (ctx->log_opts & LOGERR_LOG)
+ vsyslog(pri, fmt, args);
+
return len;
}
#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 5))
va_end(args);
}
+int
+loggetsyslogfd(void)
+{
+ struct logctx *ctx = &_logctx;
+
+ return ctx->log_syslogfd;
+}
+
+void
+logsetsyslogfd(int fd)
+{
+ struct logctx *ctx = &_logctx;
+
+ ctx->log_syslogfd = fd;
+}
+
+int
+loghandlesyslogfd(int fd)
+{
+ char buf[LOGERR_SYSLOGBUF];
+ int len, pri;
+
+ len = (int)read(fd, buf, sizeof(buf));
+ if (len == -1)
+ return -1;
+
+ /* Ensure we have pri and a terminator */
+ if (len < (int)sizeof(pri) + 1 || buf[len - 1] != '\0') {
+ errno = EINVAL;
+ return -1;
+ }
+
+ memcpy(&pri, buf, sizeof(pri));
+ logmessage(pri, "%s", buf + sizeof(pri));
+ return len;
+}
+
unsigned int
loggetopts(void)
{
(void)setvbuf(stderr, ctx->log_buf, _IOLBF, sizeof(ctx->log_buf));
- if (!(ctx->log_opts & LOGERR_LOG))
- return 1;
-
-#ifdef LOG_NDELAY
- opts |= LOG_NDELAY;
-#endif
if (ctx->log_opts & LOGERR_LOG_PID)
opts |= LOG_PID;
- openlog(NULL, opts, LOGERR_SYSLOG_FACILITY);
+ openlog(getprogname(), opts, LOGERR_SYSLOG_FACILITY);
if (path == NULL)
return 1;
fclose(ctx->log_file);
ctx->log_file = NULL;
#endif
-#if defined(LOGERR_TAG) && defined(__linux__)
+#if defined(__linux__)
free(_logprog);
#endif
}
logerr(__func__);
}
+static void
+ps_root_syslog(void *arg)
+{
+ struct dhcpcd_ctx *ctx = arg;
+
+ if (loghandlesyslogfd(ctx->ps_syslog_fd) == -1)
+ logerr(__func__);
+}
+
pid_t
ps_root_start(struct dhcpcd_ctx *ctx)
{
- int fd[2];
+ int logfd[2], datafd[2];
pid_t pid;
- if (socketpair(AF_UNIX, SOCK_DGRAM | SOCK_CXNB, 0, fd) == -1)
+ if (xsocketpair(AF_UNIX, SOCK_DGRAM | SOCK_CXNB, 0, logfd) == -1)
return -1;
- if (ps_setbuf_fdpair(fd) == -1)
+#ifdef PRIVSEP_RIGHTS
+ if (ps_rights_limit_fdpair(logfd) == -1)
+ return -1;
+#endif
+
+ if (socketpair(AF_UNIX, SOCK_DGRAM | SOCK_CXNB, 0, datafd) == -1)
+ return -1;
+ if (ps_setbuf_fdpair(datafd) == -1)
return -1;
#ifdef PRIVSEP_RIGHTS
- if (ps_rights_limit_fdpair(fd) == -1)
+ if (ps_rights_limit_fdpair(datafd) == -1)
return -1;
#endif
ps_root_startcb, ps_root_signalcb, 0);
if (pid == 0) {
- ctx->ps_data_fd = fd[1];
- close(fd[0]);
+ ctx->ps_syslog_fd = logfd[1];
+ if (eloop_event_add(ctx->eloop, ctx->ps_syslog_fd,
+ ps_root_syslog, ctx) == -1)
+ return -1;
+ close(logfd[0]);
+ ctx->ps_data_fd = datafd[1];
+ close(datafd[0]);
return 0;
} else if (pid == -1)
return -1;
- ctx->ps_data_fd = fd[0];
- close(fd[1]);
+ logsetsyslogfd(logfd[0]);
+ close(logfd[1]);
+
+ ctx->ps_data_fd = datafd[0];
+ close(datafd[1]);
if (eloop_event_add(ctx->eloop, ctx->ps_data_fd,
ps_root_dispatch, ctx) == -1)
return -1;