|
|
|
@ -1,3 +1,8 @@
|
|
|
|
|
/* _XOPEN_SOURCE >= 500 for vsnprintf() */
|
|
|
|
|
#ifndef _XOPEN_SOURCE
|
|
|
|
|
#define _XOPEN_SOURCE 700
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#include "first.h"
|
|
|
|
|
|
|
|
|
|
#include "base.h"
|
|
|
|
@ -8,6 +13,7 @@
|
|
|
|
|
#include <time.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#include <stdarg.h>
|
|
|
|
|
#include <stdio.h> /* vsnprintf() */
|
|
|
|
|
#include <stdlib.h> /* malloc() free() */
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
|
|
|
|
@ -218,6 +224,88 @@ int log_error_write_multiline_buffer(server *srv, const char *filename, unsigned
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
log_buffer_vprintf (buffer * const b,
|
|
|
|
|
const char * const fmt, va_list ap)
|
|
|
|
|
{
|
|
|
|
|
/* NOTE: log_buffer_prepare() ensures 0 != b->used */
|
|
|
|
|
/*assert(0 != b->used);*//*(only because code calcs below assume this)*/
|
|
|
|
|
/*assert(0 != b->size);*//*(errh->b should not have 0 size here)*/
|
|
|
|
|
size_t blen = buffer_string_length(b);
|
|
|
|
|
size_t bsp = buffer_string_space(b)+1;
|
|
|
|
|
char *s = b->ptr + blen;
|
|
|
|
|
size_t n;
|
|
|
|
|
|
|
|
|
|
va_list aptry;
|
|
|
|
|
va_copy(aptry, ap);
|
|
|
|
|
n = (size_t)vsnprintf(s, bsp, fmt, aptry);
|
|
|
|
|
va_end(aptry);
|
|
|
|
|
|
|
|
|
|
if (n >= bsp) {
|
|
|
|
|
buffer_string_prepare_append(b, n); /*(must re-read s after realloc)*/
|
|
|
|
|
vsnprintf((s = b->ptr + blen), buffer_string_space(b)+1, fmt, ap);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
size_t i;
|
|
|
|
|
for (i = 0; i < n && ' ' <= s[i] && s[i] <= '~'; ++i) ;/*(ASCII isprint())*/
|
|
|
|
|
if (i == n) {
|
|
|
|
|
buffer_string_set_length(b, blen + n);
|
|
|
|
|
return; /* common case; nothing to encode */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* need to encode log line
|
|
|
|
|
* copy original line fragment, append encoded line to buffer, free copy */
|
|
|
|
|
char * const src = (char *)malloc(n);
|
|
|
|
|
memcpy(src, s, n); /*(note: not '\0'-terminated)*/
|
|
|
|
|
buffer_append_string_c_escaped(b, src, n);
|
|
|
|
|
free(src);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
log_error_va_list_impl (const log_error_st * const errh,
|
|
|
|
|
const char * const filename,
|
|
|
|
|
const unsigned int line,
|
|
|
|
|
const char * const fmt, va_list ap,
|
|
|
|
|
const int perr)
|
|
|
|
|
{
|
|
|
|
|
const int errnum = errno;
|
|
|
|
|
buffer * const b = errh->b;
|
|
|
|
|
if (-1 == log_buffer_prepare(errh, filename, line, b)) return;
|
|
|
|
|
log_buffer_vprintf(b, fmt, ap);
|
|
|
|
|
if (perr) {
|
|
|
|
|
buffer_append_string_len(b, CONST_STR_LEN(": "));
|
|
|
|
|
buffer_append_string(b, strerror(errnum));
|
|
|
|
|
}
|
|
|
|
|
log_write(errh, b);
|
|
|
|
|
errno = errnum;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
log_error(const log_error_st * const errh,
|
|
|
|
|
const char * const filename, const unsigned int line,
|
|
|
|
|
const char *fmt, ...)
|
|
|
|
|
{
|
|
|
|
|
va_list ap;
|
|
|
|
|
va_start(ap, fmt);
|
|
|
|
|
log_error_va_list_impl(errh, filename, line, fmt, ap, 0);
|
|
|
|
|
va_end(ap);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
log_perror (const log_error_st * const errh,
|
|
|
|
|
const char * const filename, const unsigned int line,
|
|
|
|
|
const char * const fmt, ...)
|
|
|
|
|
{
|
|
|
|
|
va_list ap;
|
|
|
|
|
va_start(ap, fmt);
|
|
|
|
|
log_error_va_list_impl(errh, filename, line, fmt, ap, 1);
|
|
|
|
|
va_end(ap);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
log_error_st *
|
|
|
|
|
log_error_st_init (time_t *cur_ts_ptr, time_t *last_ts_ptr)
|
|
|
|
|
{
|
|
|
|
|