summaryrefslogtreecommitdiffstats
path: root/usr.sbin/httpd/logger.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/httpd/logger.c')
-rw-r--r--usr.sbin/httpd/logger.c164
1 files changed, 164 insertions, 0 deletions
diff --git a/usr.sbin/httpd/logger.c b/usr.sbin/httpd/logger.c
new file mode 100644
index 00000000000..b567f25f00d
--- /dev/null
+++ b/usr.sbin/httpd/logger.c
@@ -0,0 +1,164 @@
+/* $OpenBSD: logger.c,v 1.1 2014/08/04 15:49:28 reyk Exp $ */
+
+/*
+ * Copyright (c) 2014 Reyk Floeter <reyk@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <net/if.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <event.h>
+
+#include "httpd.h"
+
+int logger_dispatch_parent(int, struct privsep_proc *,
+ struct imsg *);
+int logger_dispatch_server(int, struct privsep_proc *,
+ struct imsg *);
+void logger_shutdown(void);
+void logger_close(void);
+void logger_init(struct privsep *, struct privsep_proc *p, void *);
+int logger_start(void);
+int logger_log(struct imsg *);
+
+static struct httpd *env = NULL;
+int proc_id;
+int log_fd = -1;
+int error_fd = -1;
+
+static struct privsep_proc procs[] = {
+ { "parent", PROC_PARENT, logger_dispatch_parent },
+ { "server", PROC_SERVER, logger_dispatch_server }
+};
+
+pid_t
+logger(struct privsep *ps, struct privsep_proc *p)
+{
+ env = ps->ps_env;
+ return (proc_run(ps, p, procs, nitems(procs), logger_init, NULL));
+}
+
+void
+logger_shutdown(void)
+{
+ logger_close();
+ config_purge(env, CONFIG_ALL);
+}
+
+void
+logger_close(void)
+{
+ if (log_fd != -1) {
+ close(log_fd);
+ log_fd = -1;
+ }
+ if (error_fd != -1) {
+ close(error_fd);
+ error_fd = -1;
+ }
+}
+
+void
+logger_init(struct privsep *ps, struct privsep_proc *p, void *arg)
+{
+ if (config_init(ps->ps_env) == -1)
+ fatal("failed to initialize configuration");
+
+ /* Set to current prefork id */
+ proc_id = p->p_instance;
+
+ /* We use a custom shutdown callback */
+ p->p_shutdown = logger_shutdown;
+}
+
+int
+logger_start(void)
+{
+ logger_close();
+ if ((log_fd = open(HTTPD_ACCESS_LOG,
+ O_WRONLY|O_APPEND|O_CREAT, 0644)) == -1)
+ return (-1);
+ if ((error_fd = open(HTTPD_ERROR_LOG,
+ O_WRONLY|O_APPEND|O_CREAT, 0644)) == -1)
+ return (-1);
+ return (0);
+}
+
+int
+logger_log(struct imsg *imsg)
+{
+ char *logline;
+ int fd;
+
+ if (imsg->hdr.type == IMSG_LOG_ACCESS)
+ fd = log_fd;
+ else
+ fd = error_fd;
+
+ /* XXX get_string() would sanitize the string, but add a malloc */
+ logline = imsg->data;
+
+ /* For debug output */
+ log_debug("%s", logline);
+
+ if (dprintf(fd, "%s\n", logline) == -1) {
+ if (logger_start() == -1)
+ return (-1);
+ }
+
+ return (0);
+}
+
+int
+logger_dispatch_parent(int fd, struct privsep_proc *p, struct imsg *imsg)
+{
+ switch (imsg->hdr.type) {
+ case IMSG_CFG_DONE:
+ config_getcfg(env, imsg);
+ break;
+ case IMSG_CTL_START:
+ case IMSG_CTL_REOPEN:
+ return (logger_start());
+ case IMSG_CTL_RESET:
+ config_getreset(env, imsg);
+ break;
+ default:
+ return (-1);
+ }
+
+ return (0);
+}
+
+int
+logger_dispatch_server(int fd, struct privsep_proc *p, struct imsg *imsg)
+{
+ switch (imsg->hdr.type) {
+ case IMSG_LOG_ACCESS:
+ return (logger_log(imsg));
+ case IMSG_LOG_ERROR:
+ return (logger_log(imsg));
+ default:
+ return (-1);
+ }
+
+ return (0);
+}