From: reyk Date: Mon, 4 Aug 2014 15:49:28 +0000 (+0000) Subject: Add initial support for log files in /var/www/logs/. Logging with X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=844c36159ebc63d46c68376392f46bcb30e544cd;p=openbsd Add initial support for log files in /var/www/logs/. Logging with syslog is still supported but disabled by default. ok deraadt@ --- diff --git a/usr.sbin/httpd/Makefile b/usr.sbin/httpd/Makefile index bda39241aa8..13f6e60c4e0 100644 --- a/usr.sbin/httpd/Makefile +++ b/usr.sbin/httpd/Makefile @@ -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 diff --git a/usr.sbin/httpd/config.c b/usr.sbin/httpd/config.c index 4f695f3d3b4..c8e8af48c52 100644 --- a/usr.sbin/httpd/config.c +++ b/usr.sbin/httpd/config.c @@ -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 @@ -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); } diff --git a/usr.sbin/httpd/control.c b/usr.sbin/httpd/control.c index e35f7b4aab9..1988ba7fc3a 100644 --- a/usr.sbin/httpd/control.c +++ b/usr.sbin/httpd/control.c @@ -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 @@ -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: diff --git a/usr.sbin/httpd/httpd.c b/usr.sbin/httpd/httpd.c index be3e1772d55..235e661a3f6 100644 --- a/usr.sbin/httpd/httpd.c +++ b/usr.sbin/httpd/httpd.c @@ -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 @@ -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 */ diff --git a/usr.sbin/httpd/httpd.conf.5 b/usr.sbin/httpd/httpd.conf.5 index 6eb86990e26..ded89101a20 100644 --- a/usr.sbin/httpd/httpd.conf.5 +++ b/usr.sbin/httpd/httpd.conf.5 @@ -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 .\" @@ -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 diff --git a/usr.sbin/httpd/httpd.h b/usr.sbin/httpd/httpd.h index e62bac3064e..afd759a8317 100644 --- a/usr.sbin/httpd/httpd.h +++ b/usr.sbin/httpd/httpd.h @@ -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 @@ -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 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 + * + * 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 +#include + +#include + +#include +#include +#include +#include +#include +#include + +#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); +} diff --git a/usr.sbin/httpd/parse.y b/usr.sbin/httpd/parse.y index 236e7f776cb..641f20a1d3f 100644 --- a/usr.sbin/httpd/parse.y +++ b/usr.sbin/httpd/parse.y @@ -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 @@ -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 STRING %token 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; diff --git a/usr.sbin/httpd/proc.c b/usr.sbin/httpd/proc.c index 8e522f0c4bd..25feff1ff7f 100644 --- a/usr.sbin/httpd/proc.c +++ b/usr.sbin/httpd/proc.c @@ -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 @@ -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); diff --git a/usr.sbin/httpd/server.c b/usr.sbin/httpd/server.c index ac4c85ce5a1..84f586fbfac 100644 --- a/usr.sbin/httpd/server.c +++ b/usr.sbin/httpd/server.c @@ -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 @@ -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) {