/* 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 #include #include "ap_mpm.h" #include "ap_provider.h" #include #include #include #include #include #include #include #include "unixd.h" #include "scoreboard.h" #include "mpm_common.h" #include "syslog.h" #if APR_HAVE_UNISTD_H #include #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, };