diff options
Diffstat (limited to 'httpd/httpd.h')
-rw-r--r-- | httpd/httpd.h | 688 |
1 files changed, 688 insertions, 0 deletions
diff --git a/httpd/httpd.h b/httpd/httpd.h new file mode 100644 index 0000000..28e02a5 --- /dev/null +++ b/httpd/httpd.h @@ -0,0 +1,688 @@ +/* $OpenBSD: httpd.h,v 1.81 2015/02/23 18:43:18 reyk Exp $ */ + +/* + * Copyright (c) 2006 - 2015 Reyk Floeter <reyk@openbsd.org> + * Copyright (c) 2006, 2007 Pierre-Yves Ritschard <pyr@openbsd.org> + * Copyright (c) 2003, 2004 Henning Brauer <henning@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. + */ + +#ifndef _HTTPD_H +#define _HTTPD_H + +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/queue.h> +#include <sys/tree.h> +#include <sys/time.h> + +#include <net/if.h> + +#include <stdarg.h> +#include <limits.h> +#include <event.h> +#include <imsg.h> +#include <tls.h> + +#define CONF_FILE "/etc/httpd.conf" +#define HTTPD_SOCKET "/var/run/httpd.sock" +#define HTTPD_USER "www" +#define HTTPD_SERVERNAME "OpenBSD httpd" +#define HTTPD_DOCROOT "/htdocs" +#define HTTPD_INDEX "index.html" +#define HTTPD_FCGI_SOCKET "/run/slowcgi.sock" +#define HTTPD_LOGROOT "/logs" +#define HTTPD_ACCESS_LOG "access.log" +#define HTTPD_ERROR_LOG "error.log" +#define HTTPD_TLS_CERT "/etc/ssl/server.crt" +#define HTTPD_TLS_KEY "/etc/ssl/private/server.key" +#define HTTPD_TLS_CIPHERS "HIGH:!aNULL" +#define HTTPD_TLS_DHE_PARAMS "none" +#define HTTPD_TLS_ECDHE_CURVE "auto" +#define FD_RESERVE 5 + +#define SERVER_MAX_CLIENTS 1024 +#define SERVER_TIMEOUT 600 +#define SERVER_CACHESIZE -1 /* use default size */ +#define SERVER_NUMPROC 3 +#define SERVER_MAXPROC 32 +#define SERVER_MAXHEADERLENGTH 8192 +#define SERVER_MAXREQUESTS 100 /* max requests per connection */ +#define SERVER_MAXREQUESTBODY 1048576 /* 1M */ +#define SERVER_BACKLOG 10 +#define SERVER_OUTOF_FD_RETRIES 5 + +#define MEDIATYPE_NAMEMAX 128 /* file name extension */ +#define MEDIATYPE_TYPEMAX 64 /* length of type/subtype */ + +#define CONFIG_RELOAD 0x00 +#define CONFIG_MEDIA 0x01 +#define CONFIG_SERVERS 0x02 +#define CONFIG_AUTH 0x04 +#define CONFIG_ALL 0xff + +#define FCGI_CONTENT_SIZE 65535 + +enum httpchunk { + TOREAD_UNLIMITED = -1, + TOREAD_HTTP_HEADER = -2, + TOREAD_HTTP_CHUNK_LENGTH = -3, + TOREAD_HTTP_CHUNK_TRAILER = -4, + TOREAD_HTTP_NONE = -5 +}; + +#if DEBUG +#define DPRINTF log_debug +#else +#define DPRINTF(x...) do {} while(0) +#endif + +struct ctl_flags { + u_int8_t cf_opts; + u_int32_t cf_flags; +}; + +enum key_type { + KEY_TYPE_NONE = 0, + KEY_TYPE_COOKIE, + KEY_TYPE_HEADER, + KEY_TYPE_PATH, + KEY_TYPE_QUERY, + KEY_TYPE_URL, + KEY_TYPE_MAX +}; + +TAILQ_HEAD(kvlist, kv); +RB_HEAD(kvtree, kv); + +struct kv { + char *kv_key; + char *kv_value; + + enum key_type kv_type; + +#define KV_FLAG_INVALID 0x01 +#define KV_FLAG_GLOBBING 0x02 + u_int8_t kv_flags; + + struct kvlist kv_children; + struct kv *kv_parent; + TAILQ_ENTRY(kv) kv_entry; + + RB_ENTRY(kv) kv_node; +}; + +struct portrange { + in_port_t val[2]; + u_int8_t op; +}; + +struct address { + struct sockaddr_storage ss; + int ipproto; + int prefixlen; + struct portrange port; + char ifname[IFNAMSIZ]; + TAILQ_ENTRY(address) entry; +}; +TAILQ_HEAD(addresslist, address); + +/* initially control.h */ +struct control_sock { + const char *cs_name; + struct event cs_ev; + struct event cs_evt; + int cs_fd; + int cs_restricted; + void *cs_env; + + TAILQ_ENTRY(control_sock) cs_entry; +}; +TAILQ_HEAD(control_socks, control_sock); + +struct { + struct event ev; + int fd; +} control_state; + +enum blockmodes { + BM_NORMAL, + BM_NONBLOCK +}; + +struct imsgev { + struct imsgbuf ibuf; + void (*handler)(int, short, void *); + struct event ev; + struct privsep_proc *proc; + void *data; + short events; +}; + +#define IMSG_SIZE_CHECK(imsg, p) do { \ + if (IMSG_DATA_SIZE(imsg) < sizeof(*p)) \ + fatalx("bad length imsg received"); \ +} while (0) +#define IMSG_DATA_SIZE(imsg) ((imsg)->hdr.len - IMSG_HEADER_SIZE) + +struct ctl_conn { + TAILQ_ENTRY(ctl_conn) entry; + u_int8_t flags; + u_int waiting; +#define CTL_CONN_NOTIFY 0x01 + struct imsgev iev; + +}; +TAILQ_HEAD(ctl_connlist, ctl_conn); + +enum imsg_type { + IMSG_NONE, + IMSG_CTL_OK, + IMSG_CTL_FAIL, + IMSG_CTL_VERBOSE, + IMSG_CTL_RESET, + IMSG_CTL_SHUTDOWN, + IMSG_CTL_RELOAD, + IMSG_CTL_NOTIFY, + IMSG_CTL_END, + IMSG_CTL_START, + IMSG_CTL_REOPEN, + IMSG_CFG_SERVER, + IMSG_CFG_MEDIA, + IMSG_CFG_AUTH, + IMSG_CFG_DONE, + IMSG_LOG_ACCESS, + IMSG_LOG_ERROR, + IMSG_LOG_OPEN +}; + +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_LOGGER + +struct privsep_pipes { + int *pp_pipes[PROC_MAX]; +}; + +struct privsep { + struct privsep_pipes *ps_pipes[PROC_MAX]; + struct privsep_pipes *ps_pp; + + struct imsgev *ps_ievs[PROC_MAX]; + const char *ps_title[PROC_MAX]; + pid_t ps_pid[PROC_MAX]; + u_int8_t ps_what[PROC_MAX]; + + u_int ps_instances[PROC_MAX]; + u_int ps_ninstances; + u_int ps_instance; + + struct control_sock ps_csock; + struct control_socks ps_rcsocks; + + /* Event and signal handlers */ + struct event ps_evsigint; + struct event ps_evsigterm; + struct event ps_evsigchld; + struct event ps_evsighup; + struct event ps_evsigpipe; + struct event ps_evsigusr1; + + int ps_noaction; + struct passwd *ps_pw; + struct httpd *ps_env; +}; + +struct privsep_proc { + const char *p_title; + enum privsep_procid p_id; + int (*p_cb)(int, struct privsep_proc *, + struct imsg *); + pid_t (*p_init)(struct privsep *, + struct privsep_proc *); + void (*p_shutdown)(void); + u_int p_instance; + const char *p_chroot; + struct privsep *p_ps; + struct httpd *p_env; +}; + +enum fcgistate { + FCGI_READ_HEADER, + FCGI_READ_CONTENT, + FCGI_READ_PADDING +}; + +struct client { + u_int32_t clt_id; + pid_t clt_pid; + void *clt_srv; + void *clt_srv_conf; + u_int32_t clt_srv_id; + struct sockaddr_storage clt_srv_ss; + + int clt_s; + in_port_t clt_port; + struct sockaddr_storage clt_ss; + struct bufferevent *clt_bev; + char *clt_buf; + size_t clt_buflen; + struct evbuffer *clt_output; + struct event clt_ev; + void *clt_descreq; + void *clt_descresp; + int clt_sndbufsiz; + + int clt_fd; + struct tls *clt_tls_ctx; + struct bufferevent *clt_srvbev; + + off_t clt_toread; + size_t clt_headerlen; + u_int clt_persist; + int clt_line; + int clt_done; + int clt_chunk; + int clt_inflight; + enum fcgistate clt_fcgi_state; + int clt_fcgi_toread; + int clt_fcgi_padding_len; + int clt_fcgi_type; + int clt_fcgi_chunked; + int clt_fcgi_end; + char *clt_remote_user; + struct evbuffer *clt_srvevb; + + struct evbuffer *clt_log; + struct timeval clt_timeout; + struct timeval clt_tv_start; + struct timeval clt_tv_last; + struct event clt_inflightevt; + + SPLAY_ENTRY(client) clt_nodes; +}; +SPLAY_HEAD(client_tree, client); + +#define SRVFLAG_INDEX 0x00000001 +#define SRVFLAG_NO_INDEX 0x00000002 +#define SRVFLAG_AUTO_INDEX 0x00000004 +#define SRVFLAG_NO_AUTO_INDEX 0x00000008 +#define SRVFLAG_ROOT 0x00000010 +#define SRVFLAG_LOCATION 0x00000020 +#define SRVFLAG_FCGI 0x00000040 +#define SRVFLAG_NO_FCGI 0x00000080 +#define SRVFLAG_LOG 0x00000100 +#define SRVFLAG_NO_LOG 0x00000200 +#define SRVFLAG_SOCKET 0x00000400 +#define SRVFLAG_SYSLOG 0x00000800 +#define SRVFLAG_NO_SYSLOG 0x00001000 +#define SRVFLAG_TLS 0x00002000 +#define SRVFLAG_ACCESS_LOG 0x00004000 +#define SRVFLAG_ERROR_LOG 0x00008000 +#define SRVFLAG_AUTH 0x00010000 +#define SRVFLAG_NO_AUTH 0x00020000 +#define SRVFLAG_BLOCK 0x00040000 +#define SRVFLAG_NO_BLOCK 0x00080000 + +#define SRVFLAG_BITS \ + "\10\01INDEX\02NO_INDEX\03AUTO_INDEX\04NO_AUTO_INDEX" \ + "\05ROOT\06LOCATION\07FCGI\10NO_FCGI\11LOG\12NO_LOG\13SOCKET" \ + "\14SYSLOG\15NO_SYSLOG\16TLS\17ACCESS_LOG\20ERROR_LOG" \ + "\21AUTH\22NO_AUTH\23BLOCK\24NO_BLOCK" + +#define TCPFLAG_NODELAY 0x01 +#define TCPFLAG_NNODELAY 0x02 +#define TCPFLAG_SACK 0x04 +#define TCPFLAG_NSACK 0x08 +#define TCPFLAG_BUFSIZ 0x10 +#define TCPFLAG_IPTTL 0x20 +#define TCPFLAG_IPMINTTL 0x40 +#define TCPFLAG_NSPLICE 0x80 +#define TCPFLAG_DEFAULT 0x00 + +#define TCPFLAG_BITS \ + "\10\01NODELAY\02NO_NODELAY\03SACK\04NO_SACK" \ + "\05SOCKET_BUFFER_SIZE\06IP_TTL\07IP_MINTTL\10NO_SPLICE" + +enum log_format { + LOG_FORMAT_COMMON, + LOG_FORMAT_COMBINED, + LOG_FORMAT_CONNECTION +}; + +struct log_file { + char log_name[NAME_MAX]; + int log_fd; + u_int32_t log_id; + TAILQ_ENTRY(log_file) log_entry; +}; +TAILQ_HEAD(log_files, log_file) log_files; + +struct auth { + char auth_htpasswd[PATH_MAX]; + u_int32_t auth_id; + TAILQ_ENTRY(auth) auth_entry; +}; +TAILQ_HEAD(serverauth, auth); + +struct server_config { + u_int32_t id; + u_int32_t parent_id; + char name[HOST_NAME_MAX+1]; + char location[NAME_MAX]; + char index[NAME_MAX]; + char root[PATH_MAX]; + char socket[PATH_MAX]; + char accesslog[NAME_MAX]; + char errorlog[NAME_MAX]; + + in_port_t port; + struct sockaddr_storage ss; + int prefixlen; + struct timeval timeout; + u_int32_t maxrequests; + size_t maxrequestbody; + + u_int8_t *tls_cert; + size_t tls_cert_len; + char *tls_cert_file; + char tls_ciphers[NAME_MAX]; + char tls_dhe_params[NAME_MAX]; + char tls_ecdhe_curve[NAME_MAX]; + u_int8_t *tls_key; + size_t tls_key_len; + char *tls_key_file; + u_int32_t tls_protocols; + + u_int32_t flags; + int strip; + u_int8_t tcpflags; + int tcpbufsiz; + int tcpbacklog; + u_int8_t tcpipttl; + u_int8_t tcpipminttl; + + enum log_format logformat; + struct log_file *logaccess; + struct log_file *logerror; + + char auth_realm[NAME_MAX]; + u_int32_t auth_id; + struct auth *auth; + + int return_code; + char *return_uri; + off_t return_uri_len; + + TAILQ_ENTRY(server_config) entry; +}; +TAILQ_HEAD(serverhosts, server_config); + +struct server { + TAILQ_ENTRY(server) srv_entry; + struct server_config srv_conf; + struct serverhosts srv_hosts; + + int srv_s; + struct event srv_ev; + struct event srv_evt; + + struct tls *srv_tls_ctx; + struct tls_config *srv_tls_config; + + struct client_tree srv_clients; +}; +TAILQ_HEAD(serverlist, server); + +struct media_type { + char media_name[MEDIATYPE_NAMEMAX]; + char media_type[MEDIATYPE_TYPEMAX]; + char media_subtype[MEDIATYPE_TYPEMAX]; + char *media_encoding; + RB_ENTRY(media_type) media_entry; +}; +RB_HEAD(mediatypes, media_type); + +struct httpd { + u_int8_t sc_opts; + u_int32_t sc_flags; + const char *sc_conffile; + struct event sc_ev; + u_int16_t sc_prefork_server; + u_int16_t sc_id; + int sc_paused; + char *sc_chroot; + char *sc_logdir; + + struct serverlist *sc_servers; + struct mediatypes *sc_mediatypes; + struct serverauth *sc_auth; + + struct privsep *sc_ps; + int sc_reload; +}; + +#define HTTPD_OPT_VERBOSE 0x01 +#define HTTPD_OPT_NOACTION 0x04 + +/* control.c */ +int control_init(struct privsep *, struct control_sock *); +int control_listen(struct control_sock *); +void control_cleanup(struct control_sock *); +void control_dispatch_imsg(int, short, void *); +void control_imsg_forward(struct imsg *); +struct ctl_conn * + control_connbyfd(int); +void socket_set_blockmode(int, enum blockmodes); + +extern struct ctl_connlist ctl_conns; + +/* parse.y */ +int parse_config(const char *, struct httpd *); +int load_config(const char *, struct httpd *); +int cmdline_symset(char *); + +/* server.c */ +pid_t server(struct privsep *, struct privsep_proc *); +int server_tls_load_keypair(struct server *); +int server_privinit(struct server *); +void server_purge(struct server *); +void serverconfig_free(struct server_config *); +void serverconfig_reset(struct server_config *); +int server_socket_af(struct sockaddr_storage *, in_port_t); +in_port_t + server_socket_getport(struct sockaddr_storage *); +int server_socket_connect(struct sockaddr_storage *, in_port_t, + struct server_config *); +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_sendlog(struct server_config *, int, const char *, ...) + __attribute__((__format__ (printf, 3, 4))); +void server_close(struct client *, const char *); +void server_dump(struct client *, const void *, size_t); +int server_client_cmp(struct client *, struct client *); +int server_bufferevent_printf(struct client *, const char *, ...) + __attribute__((__format__ (printf, 2, 3))); +int server_bufferevent_print(struct client *, const char *); +int server_bufferevent_write_buffer(struct client *, + struct evbuffer *); +int server_bufferevent_write_chunk(struct client *, + struct evbuffer *, size_t); +int server_bufferevent_add(struct event *, int); +int server_bufferevent_write(struct client *, void *, size_t); +void server_inflight_dec(struct client *, const char *); +struct server * + server_byaddr(struct sockaddr *, in_port_t); +struct server_config * + serverconfig_byid(u_int32_t); +int server_foreach(int (*)(struct server *, + struct server_config *, void *), void *); + +SPLAY_PROTOTYPE(client_tree, client, clt_nodes, server_client_cmp); + +/* server_http.c */ +void server_http_init(struct server *); +void server_http(struct httpd *); +int server_httpdesc_init(struct client *); +void server_read_http(struct bufferevent *, void *); +void server_abort_http(struct client *, u_int, const char *); +u_int server_httpmethod_byname(const char *); +const char + *server_httpmethod_byid(u_int); +const char + *server_httperror_byid(u_int); +void server_read_httpcontent(struct bufferevent *, void *); +void server_read_httpchunks(struct bufferevent *, void *); +int server_writeheader_http(struct client *clt, struct kv *, void *); +int server_headers(struct client *, void *, + int (*)(struct client *, struct kv *, void *), void *); +int server_writeresponse_http(struct client *); +int server_response_http(struct client *, u_int, struct media_type *, + size_t, time_t); +void server_reset_http(struct client *); +void server_close_http(struct client *); +int server_response(struct httpd *, struct client *); +const char * + server_root_strip(const char *, int); +struct server_config * + server_getlocation(struct client *, const char *); +const char * + server_http_host(struct sockaddr_storage *, char *, size_t); +char *server_http_parsehost(char *, char *, size_t, int *); +ssize_t server_http_time(time_t, char *, size_t); +int server_log_http(struct client *, u_int, size_t); + +/* server_file.c */ +int server_file(struct httpd *, struct client *); +void server_file_error(struct bufferevent *, short, void *); + +/* server_fcgi.c */ +int server_fcgi(struct httpd *, struct client *); +int fcgi_add_stdin(struct client *, struct evbuffer *); + +/* httpd.c */ +void event_again(struct event *, int, short, + void (*)(int, short, void *), + struct timeval *, struct timeval *, void *); +int expand_string(char *, size_t, const char *, const char *); +const char *url_decode(char *); +char *url_encode(const char *); +const char *canonicalize_host(const char *, char *, size_t); +const char *canonicalize_path(const char *, char *, size_t); +size_t path_info(char *); +char *escape_html(const char *); +void imsg_event_add(struct imsgev *); +int imsg_compose_event(struct imsgev *, u_int16_t, u_int32_t, + pid_t, int, void *, u_int16_t); +void socket_rlimit(int); +char *evbuffer_getline(struct evbuffer *); +char *get_string(u_int8_t *, size_t); +void *get_data(u_int8_t *, size_t); +int sockaddr_cmp(struct sockaddr *, struct sockaddr *, int); +struct in6_addr *prefixlen2mask6(u_int8_t, u_int32_t *); +u_int32_t prefixlen2mask(u_int8_t); +int accept_reserve(int, struct sockaddr *, socklen_t *, int, + volatile int *); +struct kv *kv_add(struct kvtree *, char *, char *); +int kv_set(struct kv *, char *, ...); +int kv_setkey(struct kv *, char *, ...); +void kv_delete(struct kvtree *, struct kv *); +struct kv *kv_extend(struct kvtree *, struct kv *, char *); +void kv_purge(struct kvtree *); +void kv_free(struct kv *); +struct kv *kv_inherit(struct kv *, struct kv *); +int kv_log(struct evbuffer *, struct kv *); +struct kv *kv_find(struct kvtree *, struct kv *); +int kv_cmp(struct kv *, struct kv *); +struct media_type + *media_add(struct mediatypes *, struct media_type *); +void media_delete(struct mediatypes *, struct media_type *); +void media_purge(struct mediatypes *); +struct media_type * + media_find(struct mediatypes *, char *); +int media_cmp(struct media_type *, struct media_type *); +RB_PROTOTYPE(kvtree, kv, kv_node, kv_cmp); +RB_PROTOTYPE(mediatypes, media_type, media_entry, media_cmp); +struct auth *auth_add(struct serverauth *, struct auth *); +struct auth *auth_byid(struct serverauth *, u_int32_t); +void auth_free(struct serverauth *, struct auth *); + +/* log.c */ +void log_init(int); +void log_verbose(int); +void log_warn(const char *, ...) __attribute__((__format__ (printf, 1, 2))); +void log_warnx(const char *, ...) __attribute__((__format__ (printf, 1, 2))); +void log_info(const char *, ...) __attribute__((__format__ (printf, 1, 2))); +void log_debug(const char *, ...) __attribute__((__format__ (printf, 1, 2))); +void logit(int, const char *, ...) __attribute__((__format__ (printf, 2, 3))); +void vlog(int, const char *, va_list) __attribute__((__format__ (printf, 2, 0))); +__dead void fatal(const char *); +__dead void fatalx(const char *); +const char *print_host(struct sockaddr_storage *, char *, size_t); +const char *print_time(struct timeval *, struct timeval *, char *, size_t); +const char *printb_flags(const u_int32_t, const char *); +void getmonotime(struct timeval *); + +/* proc.c */ +void proc_init(struct privsep *, struct privsep_proc *, u_int); +void proc_kill(struct privsep *); +void proc_listen(struct privsep *, struct privsep_proc *, size_t); +void proc_dispatch(int, short event, void *); +pid_t proc_run(struct privsep *, struct privsep_proc *, + struct privsep_proc *, u_int, + void (*)(struct privsep *, struct privsep_proc *, void *), void *); +void proc_range(struct privsep *, enum privsep_procid, int *, int *); +int proc_compose_imsg(struct privsep *, enum privsep_procid, int, + u_int16_t, int, void *, u_int16_t); +int proc_composev_imsg(struct privsep *, enum privsep_procid, int, + u_int16_t, int, const struct iovec *, int); +int proc_forward_imsg(struct privsep *, struct imsg *, + enum privsep_procid, int); +struct imsgbuf * + proc_ibuf(struct privsep *, enum privsep_procid, int); +struct imsgev * + proc_iev(struct privsep *, enum privsep_procid, int); +void imsg_event_add(struct imsgev *); +int imsg_compose_event(struct imsgev *, u_int16_t, u_int32_t, + pid_t, int, void *, u_int16_t); +int imsg_composev_event(struct imsgev *, u_int16_t, u_int32_t, + pid_t, int, const struct iovec *, int); + +/* config.c */ +int config_init(struct httpd *); +void config_purge(struct httpd *, u_int); +int config_setreset(struct httpd *, u_int); +int config_getreset(struct httpd *, struct imsg *); +int config_getcfg(struct httpd *, struct imsg *); +int config_setserver(struct httpd *, struct server *); +int config_getserver(struct httpd *, struct imsg *); +int config_setmedia(struct httpd *, struct media_type *); +int config_getmedia(struct httpd *, struct imsg *); +int config_setauth(struct httpd *, struct auth *); +int config_getauth(struct httpd *, struct imsg *); + +/* logger.c */ +pid_t logger(struct privsep *, struct privsep_proc *); +int logger_open_priv(struct imsg *); + +#endif /* _HTTPD_H */ |