blob: 5ddce9616ba8767d63703a80e0db51597f7a462d [file] [log] [blame]
/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include <stdint.h>
#include <ap_config.h>
#include "ap_mpm.h"
#include "ap_provider.h"
#include <http_core.h>
#include <httpd.h>
#include <http_log.h>
#include <http_main.h>
#include <apr_version.h>
#include <apr_pools.h>
#include <apr_strings.h>
#include "unixd.h"
#include "scoreboard.h"
#include "mpm_common.h"
#include "syslog.h"
#if APR_HAVE_UNISTD_H
#include <unistd.h>
#endif
typedef struct {
const char *t_name;
int t_val;
} TRANS;
static const TRANS facilities[] = {
{"auth", LOG_AUTH},
#ifdef LOG_AUTHPRIV
{"authpriv",LOG_AUTHPRIV},
#endif
#ifdef LOG_CRON
{"cron", LOG_CRON},
#endif
#ifdef LOG_DAEMON
{"daemon", LOG_DAEMON},
#endif
#ifdef LOG_FTP
{"ftp", LOG_FTP},
#endif
#ifdef LOG_KERN
{"kern", LOG_KERN},
#endif
#ifdef LOG_LPR
{"lpr", LOG_LPR},
#endif
#ifdef LOG_MAIL
{"mail", LOG_MAIL},
#endif
#ifdef LOG_NEWS
{"news", LOG_NEWS},
#endif
#ifdef LOG_SYSLOG
{"syslog", LOG_SYSLOG},
#endif
#ifdef LOG_USER
{"user", LOG_USER},
#endif
#ifdef LOG_UUCP
{"uucp", LOG_UUCP},
#endif
#ifdef LOG_LOCAL0
{"local0", LOG_LOCAL0},
#endif
#ifdef LOG_LOCAL1
{"local1", LOG_LOCAL1},
#endif
#ifdef LOG_LOCAL2
{"local2", LOG_LOCAL2},
#endif
#ifdef LOG_LOCAL3
{"local3", LOG_LOCAL3},
#endif
#ifdef LOG_LOCAL4
{"local4", LOG_LOCAL4},
#endif
#ifdef LOG_LOCAL5
{"local5", LOG_LOCAL5},
#endif
#ifdef LOG_LOCAL6
{"local6", LOG_LOCAL6},
#endif
#ifdef LOG_LOCAL7
{"local7", LOG_LOCAL7},
#endif
{NULL, -1},
};
static void *syslog_error_log_init(apr_pool_t *p, server_rec *s)
{
char *fname = s->error_fname;
void *success = (void *)p; /* anything non-NULL is success */
if (*fname == '\0') {
openlog(ap_server_argv0, LOG_NDELAY|LOG_CONS|LOG_PID, LOG_LOCAL7);
}
else {
/* s->error_fname could be [level]:[tag] (see #60525) */
const char *tag;
apr_size_t flen;
const TRANS *fac;
tag = strchr(fname, ':');
if (tag) {
flen = tag - fname;
tag++;
if (*tag == '\0') {
tag = ap_server_argv0;
}
} else {
flen = strlen(fname);
tag = ap_server_argv0;
}
if (flen == 0) {
/* Was something like syslog::foobar */
openlog(tag, LOG_NDELAY|LOG_CONS|LOG_PID, LOG_LOCAL7);
} else {
for (fac = facilities; fac->t_name; fac++) {
if (!strncasecmp(fname, fac->t_name, flen)) {
openlog(tag, LOG_NDELAY|LOG_CONS|LOG_PID,
fac->t_val);
return success;
}
}
/* Huh? Invalid level name? */
return NULL;
}
}
return success;
}
static apr_status_t syslog_error_log(const ap_errorlog_info *info,
void *handle, const char *errstr,
apr_size_t len)
{
int level = info->level;
if (level != APLOG_NOTICE) {
syslog(level < LOG_PRIMASK ? level : APLOG_DEBUG, "%.*s", (int)len, errstr);
}
return APR_SUCCESS;
}
static const char *syslog_error_log_parse(cmd_parms *cmd, const char *arg)
{
const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
if (err != NULL) {
return apr_pstrcat(cmd->pool,
"When using syslog error log provider, ", err,
NULL);
}
return NULL;
}
static void syslog_register_hooks(apr_pool_t *p)
{
static const ap_errorlog_provider syslog_provider = {
&syslog_error_log_init,
&syslog_error_log,
&syslog_error_log_parse,
0
};
ap_register_provider(p, AP_ERRORLOG_PROVIDER_GROUP, "syslog",
AP_ERRORLOG_PROVIDER_VERSION, &syslog_provider);
}
AP_DECLARE_MODULE(syslog) =
{
STANDARD20_MODULE_STUFF,
NULL,
NULL,
NULL,
NULL,
NULL,
syslog_register_hooks,
};