int wrap_vprintf (void *data, const char *fmt, va_list ap) { char buf[4096]; int len; len = ap_vsnprintf (buf, sizeof(buf), fmt, ap); return wrap_write (data, buf, len); }
API_EXPORT(void) ap_log_printf (const server_rec *s, const char *fmt, ...) { char buf[MAX_STRING_LEN]; va_list args; va_start(args, fmt); ap_vsnprintf(buf, sizeof(buf), fmt, args); ap_log_error(APLOG_MARK, APLOG_ERR, s, buf); va_end(args); }
void ssl_log(server_rec *s, int level, const char *msg, ...) { char tstr[80]; char lstr[20]; char vstr[1024]; char str[1024]; char nstr[2]; int timz; struct tm *t; va_list ap; int add; int i; char *astr; int safe_errno; unsigned long e; SSLSrvConfigRec *sc; char *cpE; char *cpA; /* initialization */ va_start(ap, msg); safe_errno = errno; sc = mySrvConfig(s); /* strip out additional flags */ add = (level & ~SSL_LOG_MASK); level = (level & SSL_LOG_MASK); /* reduce flags when not reasonable in context */ if (add & SSL_ADD_ERRNO && errno == 0) add &= ~SSL_ADD_ERRNO; if (add & SSL_ADD_SSLERR && ERR_peek_error() == 0) add &= ~SSL_ADD_SSLERR; /* we log only levels below, except for errors */ if ( sc->fileLogFile == NULL && !(level & SSL_LOG_ERROR)) return; if ( level > sc->nLogLevel && !(level & SSL_LOG_ERROR)) return; /* determine the time entry string */ if (add & SSL_NO_TIMESTAMP) tstr[0] = NUL; else { t = ap_get_gmtoff(&timz); strftime(tstr, 80, "[%d/%b/%Y %H:%M:%S", t); i = strlen(tstr); ap_snprintf(tstr+i, 80-i, " %05d] ", (unsigned int)getpid()); } /* determine whether newline should be written */ if (add & SSL_NO_NEWLINE) nstr[0] = NUL; else { nstr[0] = '\n'; nstr[1] = NUL; } /* determine level name */ lstr[0] = NUL; if (!(add & SSL_NO_LEVELID)) { for (i = 0; ssl_log_level2string[i].nLevel != 0; i++) { if (ssl_log_level2string[i].nLevel == level) { ap_snprintf(lstr, sizeof(lstr), "[%s]", ssl_log_level2string[i].szLevel); break; } } for (i = strlen(lstr); i <= 7; i++) lstr[i] = ' '; lstr[i] = NUL; } /* create custom message */ ap_vsnprintf(vstr, sizeof(vstr), msg, ap); /* write out SSLog message */ if ((add & SSL_ADD_ERRNO) && (add & SSL_ADD_SSLERR)) astr = " (System and " SSL_LIBRARY_NAME " library errors follow)"; else if (add & SSL_ADD_ERRNO) astr = " (System error follows)"; else if (add & SSL_ADD_SSLERR) astr = " (" SSL_LIBRARY_NAME " library error follows)"; else astr = ""; if (level <= sc->nLogLevel && sc->fileLogFile != NULL) { ap_snprintf(str, sizeof(str), "%s%s%s%s%s", tstr, lstr, vstr, astr, nstr); fprintf(sc->fileLogFile, "%s", str); } if (level & SSL_LOG_ERROR) ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, s, "mod_ssl: %s%s", vstr, astr); /* write out additional attachment messages */ if (add & SSL_ADD_ERRNO) { if (level <= sc->nLogLevel && sc->fileLogFile != NULL) { ap_snprintf(str, sizeof(str), "%s%sSystem: %s (errno: %d)%s", tstr, lstr, strerror(safe_errno), safe_errno, nstr); fprintf(sc->fileLogFile, "%s", str); } if (level & SSL_LOG_ERROR) ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, s, "System: %s (errno: %d)", strerror(safe_errno), safe_errno); } if (add & SSL_ADD_SSLERR) { while ((e = ERR_get_error())) { cpE = ERR_error_string(e, NULL); cpA = ssl_log_annotation(cpE); if (level <= sc->nLogLevel && sc->fileLogFile != NULL) { ap_snprintf(str, sizeof(str), "%s%s%s: %s%s%s%s%s", tstr, lstr, SSL_LIBRARY_NAME, cpE, cpA != NULL ? " [Hint: " : "", cpA != NULL ? cpA : "", cpA != NULL ? "]" : "", nstr); fprintf(sc->fileLogFile, "%s", str); } if (level & SSL_LOG_ERROR) ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, s, "%s: %s%s%s%s", SSL_LIBRARY_NAME, cpE, cpA != NULL ? " [Hint: " : "", cpA != NULL ? cpA : "", cpA != NULL ? "]" : ""); } } /* make sure the next log starts from a clean base */ /* ERR_clear_error(); */ /* cleanup and return */ if (sc->fileLogFile != NULL) fflush(sc->fileLogFile); errno = safe_errno; va_end(ap); return; }
API_EXPORT(void) ap_log_error (const char *file, int line, int level, const server_rec *s, const char *fmt, ...) { va_list args; char errstr[MAX_STRING_LEN]; size_t len; int save_errno = errno; FILE *logf; if (s == NULL) { /* * If we are doing stderr logging (startup), don't log messages that are * above the default server log level unless it is a startup/shutdown * notice */ if (((level & APLOG_LEVELMASK) != APLOG_NOTICE) && ((level & APLOG_LEVELMASK) > DEFAULT_LOGLEVEL)) return; logf = stderr; } else if (s->error_log) { /* * If we are doing normal logging, don't log messages that are * above the server log level unless it is a startup/shutdown notice */ if (((level & APLOG_LEVELMASK) != APLOG_NOTICE) && ((level & APLOG_LEVELMASK) > s->loglevel)) return; logf = s->error_log; } else { /* * If we are doing syslog logging, don't log messages that are * above the server log level (including a startup/shutdown notice) */ if ((level & APLOG_LEVELMASK) > s->loglevel) return; logf = NULL; } if (logf) { len = ap_snprintf(errstr, sizeof(errstr), "[%s] ", ap_get_time()); } else { len = 0; } len += ap_snprintf(errstr + len, sizeof(errstr) - len, "[%s] ", priorities[level & APLOG_LEVELMASK].t_name); if (file && (level & APLOG_LEVELMASK) == APLOG_DEBUG) { #ifdef _OSD_POSIX char tmp[256]; char *e = strrchr(file, '/'); /* In OSD/POSIX, the compiler returns for __FILE__ * a string like: __FILE__="*POSIX(/usr/include/stdio.h)" * (it even returns an absolute path for sources in * the current directory). Here we try to strip this * down to the basename. */ if (e != NULL && e[1] != '\0') { ap_snprintf(tmp, sizeof(tmp), "%s", &e[1]); e = &tmp[strlen(tmp)-1]; if (*e == ')') *e = '\0'; file = tmp; } #endif /*_OSD_POSIX*/ len += ap_snprintf(errstr + len, sizeof(errstr) - len, "%s(%d): ", file, line); } if (!(level & APLOG_NOERRNO) && (save_errno != 0) #ifdef WIN32 && !(level & APLOG_WIN32ERROR) #endif ) { len += ap_snprintf(errstr + len, sizeof(errstr) - len, "(%d)%s: ", save_errno, strerror(save_errno)); } #ifdef WIN32 if (level & APLOG_WIN32ERROR) { int nChars; int nErrorCode; nErrorCode = GetLastError(); len += ap_snprintf(errstr + len, sizeof(errstr) - len, "(%d)", nErrorCode); nChars = FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, NULL, nErrorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language (LPTSTR) errstr + len, sizeof(errstr) - len, NULL ); len += nChars; if (nChars == 0) { /* Um, error occurred, but we can't recurse to log it again * (and it would probably only fail anyway), so lets just * log the numeric value. */ nErrorCode = GetLastError(); len += ap_snprintf(errstr + len, sizeof(errstr) - len, "(FormatMessage failed with code %d): ", nErrorCode); } else { /* FormatMessage put the message in the buffer, but it may * have appended a newline (\r\n). So remove it and use * ": " instead like the Unix errors. The error may also * end with a . before the return - if so, trash it. */ if (len > 1 && errstr[len-2] == '\r' && errstr[len-1] == '\n') { if (len > 2 && errstr[len-3] == '.') len--; errstr[len-2] = ':'; errstr[len-1] = ' '; } } } #endif va_start(args, fmt); len += ap_vsnprintf(errstr + len, sizeof(errstr) - len, fmt, args); va_end(args); /* NULL if we are logging to syslog */ if (logf) { fputs(errstr, logf); fputc('\n', logf); fflush(logf); } #ifdef HAVE_SYSLOG else { syslog(level & APLOG_LEVELMASK, "%s", errstr); } #endif }