Add initial support for log files in /var/www/logs/. Logging with
authorreyk <reyk@openbsd.org>
Mon, 4 Aug 2014 15:49:28 +0000 (15:49 +0000)
committerreyk <reyk@openbsd.org>
Mon, 4 Aug 2014 15:49:28 +0000 (15:49 +0000)
syslog is still supported but disabled by default.

ok deraadt@

usr.sbin/httpd/Makefile
usr.sbin/httpd/config.c
usr.sbin/httpd/control.c
usr.sbin/httpd/httpd.c
usr.sbin/httpd/httpd.conf.5
usr.sbin/httpd/httpd.h
usr.sbin/httpd/logger.c [new file with mode: 0644]
usr.sbin/httpd/parse.y
usr.sbin/httpd/proc.c
usr.sbin/httpd/server.c

index bda3924..13f6e60 100644 (file)
@@ -1,8 +1,8 @@
-#      $OpenBSD: Makefile,v 1.23 2014/08/04 11:09:25 reyk Exp $
+#      $OpenBSD: Makefile,v 1.24 2014/08/04 15:49:28 reyk Exp $
 
 PROG=          httpd
 SRCS=          parse.y
-SRCS+=         config.c control.c httpd.c log.c proc.c
+SRCS+=         config.c control.c httpd.c log.c logger.c proc.c
 SRCS+=         server.c server_http.c server_file.c server_fcgi.c
 MAN=           httpd.8 httpd.conf.5
 
index 4f695f3..c8e8af4 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: config.c,v 1.13 2014/08/04 11:09:25 reyk Exp $        */
+/*     $OpenBSD: config.c,v 1.14 2014/08/04 15:49:28 reyk Exp $        */
 
 /*
  * Copyright (c) 2011 - 2014 Reyk Floeter <reyk@openbsd.org>
@@ -60,6 +60,7 @@ config_init(struct httpd *env)
 
                ps->ps_what[PROC_PARENT] = CONFIG_ALL;
                ps->ps_what[PROC_SERVER] = CONFIG_SERVERS|CONFIG_MEDIA;
+               ps->ps_what[PROC_LOGGER] = 0;
        }
 
        /* Other configuration */
@@ -261,14 +262,21 @@ config_getserver_config(struct httpd *env, struct server *srv,
                        srv_conf->logformat = srv->srv_conf.logformat;
                }
 
-               DPRINTF("%s: %s %d received location \"%s\", parent \"%s\"",
+               f = SRVFLAG_SYSLOG|SRVFLAG_NO_SYSLOG;
+               if ((srv_conf->flags & f) == 0)
+                       srv_conf->flags |= srv->srv_conf.flags & f;
+
+               DPRINTF("%s: %s %d location \"%s\", "
+                   "parent \"%s\", flags: %s",
                    __func__, ps->ps_title[privsep_process], ps->ps_instance,
-                   srv_conf->location, srv->srv_conf.name);
+                   srv_conf->location, srv->srv_conf.name,
+                   printb_flags(srv_conf->flags, SRVFLAG_BITS));
        } else {
                /* Add a new "virtual" server */
-               DPRINTF("%s: %s %d received server \"%s\", parent \"%s\"",
+               DPRINTF("%s: %s %d server \"%s\", parent \"%s\", flags: %s",
                    __func__, ps->ps_title[privsep_process], ps->ps_instance,
-                   srv_conf->name, srv->srv_conf.name);
+                   srv_conf->name, srv->srv_conf.name,
+                   printb_flags(srv_conf->flags, SRVFLAG_BITS));
        }
 
        TAILQ_INSERT_TAIL(&srv->srv_hosts, srv_conf, entry);
@@ -319,9 +327,10 @@ config_getserver(struct httpd *env, struct imsg *imsg)
        TAILQ_INSERT_TAIL(&srv->srv_hosts, &srv->srv_conf, entry);
        TAILQ_INSERT_TAIL(env->sc_servers, srv, srv_entry);
 
-       DPRINTF("%s: %s %d received configuration \"%s\"", __func__,
+       DPRINTF("%s: %s %d configuration \"%s\", flags: %s", __func__,
            ps->ps_title[privsep_process], ps->ps_instance,
-           srv->srv_conf.name);
+           srv->srv_conf.name,
+           printb_flags(srv->srv_conf.flags, SRVFLAG_BITS));
 
        return (0);
 }
index e35f7b4..1988ba7 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: control.c,v 1.3 2014/08/04 11:09:25 reyk Exp $        */
+/*     $OpenBSD: control.c,v 1.4 2014/08/04 15:49:28 reyk Exp $        */
 
 /*
  * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -269,6 +269,7 @@ control_dispatch_imsg(int fd, short event, void *arg)
                switch (imsg.hdr.type) {
                case IMSG_CTL_SHUTDOWN:
                case IMSG_CTL_RELOAD:
+               case IMSG_CTL_REOPEN:
                        proc_forward_imsg(env->sc_ps, &imsg, PROC_PARENT, -1);
                        break;
                case IMSG_CTL_NOTIFY:
index be3e177..235e661 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: httpd.c,v 1.14 2014/08/04 14:49:24 reyk Exp $ */
+/*     $OpenBSD: httpd.c,v 1.15 2014/08/04 15:49:28 reyk Exp $ */
 
 /*
  * Copyright (c) 2014 Reyk Floeter <reyk@openbsd.org>
@@ -50,15 +50,19 @@ __dead void  usage(void);
 int             parent_configure(struct httpd *);
 void            parent_configure_done(struct httpd *);
 void            parent_reload(struct httpd *, u_int, const char *);
+void            parent_reopen(struct httpd *);
 void            parent_sig_handler(int, short, void *);
 void            parent_shutdown(struct httpd *);
 int             parent_dispatch_server(int, struct privsep_proc *,
                    struct imsg *);
+int             parent_dispatch_logger(int, struct privsep_proc *,
+                   struct imsg *);
 
 struct httpd                   *httpd_env;
 
 static struct privsep_proc procs[] = {
-       { "server",     PROC_SERVER, parent_dispatch_server, server }
+       { "server",     PROC_SERVER, parent_dispatch_server, server },
+       { "logger",     PROC_LOGGER, parent_dispatch_logger, logger }
 };
 
 void
@@ -122,6 +126,11 @@ parent_sig_handler(int sig, short event, void *arg)
        case SIGPIPE:
                /* ignore */
                break;
+       case SIGUSR1:
+               log_info("%s: reopen requested with SIGUSR1", __func__);
+
+               parent_reopen(ps->ps_env);
+               break;
        default:
                fatalx("unexpected signal");
        }
@@ -227,12 +236,14 @@ main(int argc, char *argv[])
        signal_set(&ps->ps_evsigchld, SIGCHLD, parent_sig_handler, ps);
        signal_set(&ps->ps_evsighup, SIGHUP, parent_sig_handler, ps);
        signal_set(&ps->ps_evsigpipe, SIGPIPE, parent_sig_handler, ps);
+       signal_set(&ps->ps_evsigusr1, SIGUSR1, parent_sig_handler, ps);
 
        signal_add(&ps->ps_evsigint, NULL);
        signal_add(&ps->ps_evsigterm, NULL);
        signal_add(&ps->ps_evsigchld, NULL);
        signal_add(&ps->ps_evsighup, NULL);
        signal_add(&ps->ps_evsigpipe, NULL);
+       signal_add(&ps->ps_evsigusr1, NULL);
 
        proc_listen(ps, procs, nitems(procs));
 
@@ -278,7 +289,7 @@ parent_configure(struct httpd *env)
        }
 
        /* The servers need to reload their config. */
-       env->sc_reload = env->sc_prefork_server;
+       env->sc_reload = env->sc_prefork_server + 1;
 
        for (id = 0; id < PROC_MAX; id++) {
                if (id == privsep_process)
@@ -329,6 +340,13 @@ parent_reload(struct httpd *env, u_int reset, const char *filename)
                config_setreset(env, reset);
 }
 
+void
+parent_reopen(struct httpd *env)
+{
+       proc_compose_imsg(env->sc_ps, PROC_LOGGER, -1, IMSG_CTL_REOPEN,
+           -1, NULL, 0);
+}
+
 void
 parent_configure_done(struct httpd *env)
 {
@@ -383,6 +401,42 @@ parent_dispatch_server(int fd, struct privsep_proc *p, struct imsg *imsg)
        return (0);
 }
 
+int
+parent_dispatch_logger(int fd, struct privsep_proc *p, struct imsg *imsg)
+{
+       struct httpd            *env = p->p_env;
+       u_int                    v;
+       char                    *str = NULL;
+
+       switch (imsg->hdr.type) {
+       case IMSG_CTL_RESET:
+               IMSG_SIZE_CHECK(imsg, &v);
+               memcpy(&v, imsg->data, sizeof(v));
+               parent_reload(env, v, NULL);
+               break;
+       case IMSG_CTL_RELOAD:
+               if (IMSG_DATA_SIZE(imsg) > 0)
+                       str = get_string(imsg->data, IMSG_DATA_SIZE(imsg));
+               parent_reload(env, CONFIG_RELOAD, str);
+               if (str != NULL)
+                       free(str);
+               break;
+       case IMSG_CTL_SHUTDOWN:
+               parent_shutdown(env);
+               break;
+       case IMSG_CTL_REOPEN:
+               parent_reopen(env);
+               break;
+       case IMSG_CFG_DONE:
+               parent_configure_done(env);
+               break;
+       default:
+               return (-1);
+       }
+
+       return (0);
+}
+
 /*
  * Utility functions
  */
index 6eb8699..ded8910 100644 (file)
@@ -1,4 +1,4 @@
-.\"    $OpenBSD: httpd.conf.5,v 1.18 2014/08/03 10:26:43 reyk Exp $
+.\"    $OpenBSD: httpd.conf.5,v 1.19 2014/08/04 15:49:28 reyk Exp $
 .\"
 .\" Copyright (c) 2014 Reyk Floeter <reyk@openbsd.org>
 .\"
@@ -14,7 +14,7 @@
 .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 .\"
-.Dd $Mdocdate: August 3 2014 $
+.Dd $Mdocdate: August 4 2014 $
 .Dt HTTPD.CONF 5
 .Os
 .Sh NAME
@@ -145,8 +145,8 @@ except
 .Ic listen on
 and
 .Ic location .
-.It Oo Ic no Oc Ic log Op Ar style
-Enable writing an access log to syslog.
+.It Oo Ic no Oc Ic log style Op Ar style
+Enable writing an access log to the log files or syslog.
 The
 .Ar style
 can be
@@ -168,6 +168,8 @@ similar to the format that is used by
 .Xr relayd 8 .
 If not specified, the default is
 .Ar common .
+.It Oo Ic no Oc Ic log syslog
+Log to syslog instead of the log files.
 .It Ic root Ar directory
 Set the document root of the server.
 The
index e62bac3..afd759a 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: httpd.h,v 1.39 2014/08/04 14:49:24 reyk Exp $ */
+/*     $OpenBSD: httpd.h,v 1.40 2014/08/04 15:49:28 reyk Exp $ */
 
 /*
  * Copyright (c) 2006 - 2014 Reyk Floeter <reyk@openbsd.org>
@@ -34,6 +34,8 @@
 #define HTTPD_DOCROOT          "/htdocs"
 #define HTTPD_INDEX            "index.html"
 #define HTTPD_FCGI_SOCKET      "/run/slowcgi.sock"
+#define HTTPD_ACCESS_LOG       "/logs/access.log"
+#define HTTPD_ERROR_LOG                "/logs/error.log"
 #define FD_RESERVE             5
 
 #define SERVER_MAX_CLIENTS     1024
@@ -176,20 +178,24 @@ enum imsg_type {
        IMSG_CTL_NOTIFY,
        IMSG_CTL_END,
        IMSG_CTL_START,
+       IMSG_CTL_REOPEN,
        IMSG_CFG_SERVER,
        IMSG_CFG_MEDIA,
-       IMSG_CFG_DONE
+       IMSG_CFG_DONE,
+       IMSG_LOG_ACCESS,
+       IMSG_LOG_ERROR
 };
 
 enum privsep_procid {
        PROC_ALL        = -1,
        PROC_PARENT     = 0,
        PROC_SERVER,
+       PROC_LOGGER,
        PROC_MAX
 } privsep_process;
 
 /* Attach the control socket to the following process */
-#define PROC_CONTROL   PROC_PARENT
+#define PROC_CONTROL   PROC_LOGGER
 
 struct privsep_pipes {
        int                             *pp_pipes[PROC_MAX];
@@ -217,6 +223,7 @@ struct privsep {
        struct event                     ps_evsigchld;
        struct event                     ps_evsighup;
        struct event                     ps_evsigpipe;
+       struct event                     ps_evsigusr1;
 
        int                              ps_noaction;
        struct passwd                   *ps_pw;
@@ -296,10 +303,13 @@ SPLAY_HEAD(client_tree, client);
 #define SRVFLAG_LOG            0x0100
 #define SRVFLAG_NO_LOG         0x0200
 #define SRVFLAG_SOCKET         0x0400
+#define SRVFLAG_SYSLOG         0x0800
+#define SRVFLAG_NO_SYSLOG      0x1000
 
-#define SRVFLAG_BITS                                           \
-       "\10\01INDEX\02NO_INDEX\03AUTO_INDEX\04NO_AUTO_INDEX"   \
-       "\05ROOT\06LOCATION\07FCGI\10NO_FCGI\11LOG\12NO_LOG\13SOCKET"
+#define SRVFLAG_BITS                                                   \
+       "\10\01INDEX\02NO_INDEX\03AUTO_INDEX\04NO_AUTO_INDEX"           \
+       "\05ROOT\06LOCATION\07FCGI\10NO_FCGI\11LOG\12NO_LOG\13SOCKET"   \
+       "\14SYSLOG\15NO_SYSLOG"
 
 #define TCPFLAG_NODELAY                0x01
 #define TCPFLAG_NNODELAY       0x02
@@ -376,6 +386,7 @@ struct httpd {
        struct event             sc_ev;
        u_int16_t                sc_prefork_server;
        u_int16_t                sc_id;
+       int                      sc_paused;
 
        struct serverlist       *sc_servers;
        struct mediatypes       *sc_mediatypes;
@@ -417,6 +428,10 @@ void        server_write(struct bufferevent *, void *);
 void    server_read(struct bufferevent *, void *);
 void    server_error(struct bufferevent *, short, void *);
 void    server_log(struct client *, const char *);
+void    server_log_access(const char *, ...)
+           __attribute__((__format__ (printf, 1, 2)));
+void    server_log_error(const char *, ...)
+           __attribute__((__format__ (printf, 1, 2)));
 void    server_close(struct client *, const char *);
 void    server_dump(struct client *, const void *, size_t);
 int     server_client_cmp(struct client *, struct client *);
@@ -557,4 +572,7 @@ int  config_getserver(struct httpd *, struct imsg *);
 int     config_setmedia(struct httpd *, struct media_type *);
 int     config_getmedia(struct httpd *, struct imsg *);
 
+/* logger.c */
+pid_t   logger(struct privsep *, struct privsep_proc *);
+
 #endif /* _HTTPD_H */
diff --git a/usr.sbin/httpd/logger.c b/usr.sbin/httpd/logger.c
new file mode 100644 (file)
index 0000000..b567f25
--- /dev/null
@@ -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);
+}
index 236e7f7..641f20a 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: parse.y,v 1.20 2014/08/04 11:09:25 reyk Exp $ */
+/*     $OpenBSD: parse.y,v 1.21 2014/08/04 15:49:28 reyk Exp $ */
 
 /*
  * Copyright (c) 2007 - 2014 Reyk Floeter <reyk@openbsd.org>
@@ -124,8 +124,8 @@ typedef struct {
 
 %}
 
-%token AUTO COMMON COMBINED CONNECTION DIRECTORY FCGI INDEX LISTEN LOCATION
-%token LOG NO ON PORT PREFORK ROOT SERVER SOCKET TYPES
+%token AUTO COMMON COMBINED CONNECTION DIRECTORY FCGI FILE INDEX LISTEN
+%token LOCATION LOG NO ON PORT PREFORK ROOT SERVER SOCKET SYSLOG TYPES
 %token ERROR INCLUDE
 %token <v.string>      STRING
 %token  <v.number>     NUMBER
@@ -432,24 +432,41 @@ dirflags  : INDEX STRING          {
                }
                ;
 
-logformat      : LOG COMMON            {
+
+logformat      : LOG logflags
+               | LOG '{' logflags_l '}'
+               | NO LOG                {
+                       srv->srv_conf.flags &= ~SRVFLAG_LOG;
+                       srv->srv_conf.flags |= SRVFLAG_NO_LOG;
+               }
+               ;
+
+logflags_l     : logflags comma logflags_l
+               | logflags
+               ;
+
+logflags       : COMMON                {
                        srv->srv_conf.flags &= ~SRVFLAG_NO_LOG;
                        srv->srv_conf.flags |= SRVFLAG_LOG;
                        srv->srv_conf.logformat = LOG_FORMAT_COMMON;
                }
-               | LOG COMBINED          {
+               | COMBINED              {
                        srv->srv_conf.flags &= ~SRVFLAG_NO_LOG;
                        srv->srv_conf.flags |= SRVFLAG_LOG;
                        srv->srv_conf.logformat = LOG_FORMAT_COMBINED;
                }
-               | LOG CONNECTION        {
+               | CONNECTION            {
                        srv->srv_conf.flags &= ~SRVFLAG_NO_LOG;
                        srv->srv_conf.flags |= SRVFLAG_LOG;
                        srv->srv_conf.logformat = LOG_FORMAT_CONNECTION;
                }
-               | NO LOG                {
-                       srv->srv_conf.flags &= ~SRVFLAG_LOG;
-                       srv->srv_conf.flags |= SRVFLAG_NO_LOG;
+               | SYSLOG                {
+                       srv->srv_conf.flags &= ~SRVFLAG_NO_SYSLOG;
+                       srv->srv_conf.flags |= SRVFLAG_SYSLOG;
+               }
+               | NO SYSLOG             {
+                       srv->srv_conf.flags &= ~SRVFLAG_SYSLOG;
+                       srv->srv_conf.flags |= SRVFLAG_NO_SYSLOG;
                }
                ;
 
@@ -586,6 +603,7 @@ lookup(char *s)
                { "connection",         CONNECTION },
                { "directory",          DIRECTORY },
                { "fastcgi",            FCGI },
+               { "file",               FILE },
                { "include",            INCLUDE },
                { "index",              INDEX },
                { "listen",             LISTEN },
@@ -598,6 +616,7 @@ lookup(char *s)
                { "root",               ROOT },
                { "server",             SERVER },
                { "socket",             SOCKET },
+               { "syslog",             SYSLOG },
                { "types",              TYPES }
        };
        const struct keywords   *p;
index 8e522f0..25feff1 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: proc.c,v 1.3 2014/08/04 11:09:25 reyk Exp $   */
+/*     $OpenBSD: proc.c,v 1.4 2014/08/04 15:49:28 reyk Exp $   */
 
 /*
  * Copyright (c) 2010 - 2014 Reyk Floeter <reyk@openbsd.org>
@@ -321,6 +321,7 @@ proc_sig_handler(int sig, short event, void *arg)
        case SIGCHLD:
        case SIGHUP:
        case SIGPIPE:
+       case SIGUSR1:
                /* ignore */
                break;
        default:
@@ -407,12 +408,14 @@ proc_run(struct privsep *ps, struct privsep_proc *p,
        signal_set(&ps->ps_evsigchld, SIGCHLD, proc_sig_handler, p);
        signal_set(&ps->ps_evsighup, SIGHUP, proc_sig_handler, p);
        signal_set(&ps->ps_evsigpipe, SIGPIPE, proc_sig_handler, p);
+       signal_set(&ps->ps_evsigusr1, SIGUSR1, proc_sig_handler, p);
 
        signal_add(&ps->ps_evsigint, NULL);
        signal_add(&ps->ps_evsigterm, NULL);
        signal_add(&ps->ps_evsigchld, NULL);
        signal_add(&ps->ps_evsighup, NULL);
        signal_add(&ps->ps_evsigpipe, NULL);
+       signal_add(&ps->ps_evsigusr1, NULL);
 
        proc_listen(ps, procs, nproc);
 
index ac4c85c..84f586f 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: server.c,v 1.25 2014/08/04 11:09:25 reyk Exp $        */
+/*     $OpenBSD: server.c,v 1.26 2014/08/04 15:49:28 reyk Exp $        */
 
 /*
  * Copyright (c) 2006 - 2014 Reyk Floeter <reyk@openbsd.org>
@@ -47,6 +47,8 @@
 
 int             server_dispatch_parent(int, struct privsep_proc *,
                    struct imsg *);
+int             server_dispatch_logger(int, struct privsep_proc *,
+                   struct imsg *);
 void            server_shutdown(void);
 
 void            server_init(struct privsep *, struct privsep_proc *p, void *);
@@ -70,7 +72,8 @@ static struct httpd           *env = NULL;
 int                             proc_id;
 
 static struct privsep_proc procs[] = {
-       { "parent",     PROC_PARENT,    server_dispatch_parent }
+       { "parent",     PROC_PARENT,    server_dispatch_parent },
+       { "logger",     PROC_LOGGER,    server_dispatch_logger }
 };
 
 pid_t
@@ -602,33 +605,80 @@ server_inflight_dec(struct client *clt, const char *why)
            __func__, server_inflight, why);
 }
 
+void
+server_log_access(const char *emsg, ...)
+{
+       va_list  ap;
+       char    *msg;
+       int      ret;
+
+       va_start(ap, emsg);
+       ret = vasprintf(&msg, emsg, ap);
+       va_end(ap);
+       if (ret == -1) {
+               log_warn("%s: vasprintf", __func__);
+               return;
+       }
+
+       proc_compose_imsg(env->sc_ps, PROC_LOGGER, -1,
+           IMSG_LOG_ACCESS, -1, msg, strlen(msg) + 1);
+}
+
+void
+server_log_error(const char *emsg, ...)
+{
+       va_list  ap;
+       char    *msg;
+       int      ret;
+
+       va_start(ap, emsg);
+       ret = vasprintf(&msg, emsg, ap);
+       va_end(ap);
+       if (ret == -1) {
+               log_warn("%s: vasprintf", __func__);
+               return;
+       }
+
+       proc_compose_imsg(env->sc_ps, PROC_LOGGER, -1,
+           IMSG_LOG_ERROR, -1, msg, strlen(msg) + 1);
+}
+
 void
 server_log(struct client *clt, const char *msg)
 {
        char                     ibuf[MAXHOSTNAMELEN], obuf[MAXHOSTNAMELEN];
        struct server_config    *srv_conf = clt->clt_srv_conf;
        char                    *ptr = NULL;
-       void                    (*log_cb)(const char *, ...) = NULL;
-       extern int               debug;
+       void                    (*log_infocb)(const char *, ...);
+       void                    (*log_debugcb)(const char *, ...);
+       extern int               verbose;
+
+       if (srv_conf->flags & SRVFLAG_SYSLOG) {
+               log_infocb = log_info;
+               log_debugcb = log_debug;
+       } else {
+               log_infocb = server_log_access;
+               log_debugcb = server_log_error;
+       }
 
        switch (srv_conf->logformat) {
        case LOG_FORMAT_CONNECTION:
-               log_cb = log_info;
+               log_debugcb = server_log_error;
                break;
        default:
-               if (debug)
-                       log_cb = log_debug;
+               if (verbose <= 1)
+                       log_debugcb = NULL;
                if (EVBUFFER_LENGTH(clt->clt_log)) {
                        while ((ptr =
                            evbuffer_readline(clt->clt_log)) != NULL) {
-                               log_info("%s", ptr);
+                               (log_infocb)("%s", ptr);
                                free(ptr);
                        }
                }
                break;
        }
 
-       if (log_cb != NULL && msg != NULL) {
+       if (log_debugcb != NULL && msg != NULL) {
                memset(&ibuf, 0, sizeof(ibuf));
                memset(&obuf, 0, sizeof(obuf));
                (void)print_host(&clt->clt_ss, ibuf, sizeof(ibuf));
@@ -636,7 +686,7 @@ server_log(struct client *clt, const char *msg)
                if (EVBUFFER_LENGTH(clt->clt_log) &&
                    evbuffer_add_printf(clt->clt_log, "\n") != -1)
                        ptr = evbuffer_readline(clt->clt_log);
-               log_cb("server %s, "
+               (log_debugcb)("server %s, "
                    "client %d (%d active), %s:%u -> %s, "
                    "%s%s%s", srv_conf->name, clt->clt_id, server_clients,
                    ibuf, ntohs(clt->clt_port), obuf, msg,
@@ -713,6 +763,17 @@ server_dispatch_parent(int fd, struct privsep_proc *p, struct imsg *imsg)
        return (0);
 }
 
+int
+server_dispatch_logger(int fd, struct privsep_proc *p, struct imsg *imsg)
+{
+       switch (imsg->hdr.type) {
+       default:
+               return (-1);
+       }
+
+       return (0);
+}
+
 int
 server_bufferevent_add(struct event *ev, int timeout)
 {