Blame src/lognorm.c

Packit 1422b7
/* liblognorm - a fast samples-based log normalization library
Packit 1422b7
 * Copyright 2010 by Rainer Gerhards and Adiscon GmbH.
Packit 1422b7
 *
Packit 1422b7
 * This file is part of liblognorm.
Packit 1422b7
 *
Packit 1422b7
 * Released under ASL 2.0
Packit 1422b7
 */
Packit 1422b7
#include "config.h"
Packit 1422b7
#include <stdlib.h>
Packit 1422b7
#include <stdio.h>
Packit 1422b7
#include <stdarg.h>
Packit 1422b7
#include <string.h>
Packit 1422b7
Packit 1422b7
#include "liblognorm.h"
Packit 1422b7
#include "lognorm.h"
Packit 1422b7
Packit 1422b7
/* Code taken from rsyslog ASL 2.0 code.
Packit 1422b7
 * From varmojfekoj's mail on why he provided rs_strerror_r():
Packit 1422b7
 * There are two problems with strerror_r():
Packit 1422b7
 * I see you've rewritten some of the code which calls it to use only
Packit 1422b7
 * the supplied buffer; unfortunately the GNU implementation sometimes
Packit 1422b7
 * doesn't use the buffer at all and returns a pointer to some
Packit 1422b7
 * immutable string instead, as noted in the man page.
Packit 1422b7
 *
Packit 1422b7
 * The other problem is that on some systems strerror_r() has a return
Packit 1422b7
 * type of int.
Packit 1422b7
 *
Packit 1422b7
 * So I've written a wrapper function rs_strerror_r(), which should
Packit 1422b7
 * take care of all this and be used instead.
Packit 1422b7
 */
Packit 1422b7
static char *
Packit 1422b7
rs_strerror_r(const int errnum, char *const buf, const size_t buflen) {
Packit 1422b7
#ifndef HAVE_STRERROR_R
Packit 1422b7
	char *pszErr;
Packit 1422b7
	pszErr = strerror(errnum);
Packit 1422b7
	snprintf(buf, buflen, "%s", pszErr);
Packit 1422b7
#else
Packit 1422b7
#	ifdef STRERROR_R_CHAR_P
Packit 1422b7
		char *p = strerror_r(errnum, buf, buflen);
Packit 1422b7
		if (p != buf) {
Packit 1422b7
			strncpy(buf, p, buflen);
Packit 1422b7
			buf[buflen - 1] = '\0';
Packit 1422b7
		}
Packit 1422b7
#	else
Packit 1422b7
		strerror_r(errnum, buf, buflen);
Packit 1422b7
#	endif
Packit 1422b7
#endif
Packit 1422b7
	return buf;
Packit 1422b7
}
Packit 1422b7
/**
Packit 1422b7
 * Generate some debug message and call the caller provided callback.
Packit 1422b7
 *
Packit 1422b7
 * Will first check if a user callback is registered. If not, returns
Packit 1422b7
 * immediately.
Packit 1422b7
 */
Packit 1422b7
void
Packit 1422b7
ln_dbgprintf(ln_ctx ctx, const char *fmt, ...)
Packit 1422b7
{
Packit 1422b7
	va_list ap;
Packit 1422b7
	char buf[8*1024];
Packit 1422b7
	size_t lenBuf;
Packit 1422b7
Packit 1422b7
	if(ctx->dbgCB == NULL)
Packit 1422b7
		goto done;
Packit 1422b7
	
Packit 1422b7
	va_start(ap, fmt);
Packit 1422b7
	lenBuf = vsnprintf(buf, sizeof(buf), fmt, ap);
Packit 1422b7
	va_end(ap);
Packit 1422b7
	if(lenBuf >= sizeof(buf)) {
Packit 1422b7
		/* prevent buffer overruns and garbagge display */
Packit 1422b7
		buf[sizeof(buf) - 5] = '.';
Packit 1422b7
		buf[sizeof(buf) - 4] = '.';
Packit 1422b7
		buf[sizeof(buf) - 3] = '.';
Packit 1422b7
		buf[sizeof(buf) - 2] = '\n';
Packit 1422b7
		buf[sizeof(buf) - 1] = '\0';
Packit 1422b7
		lenBuf = sizeof(buf) - 1;
Packit 1422b7
	}
Packit 1422b7
Packit 1422b7
	ctx->dbgCB(ctx->dbgCookie, buf, lenBuf);
Packit 1422b7
done:	return;
Packit 1422b7
}
Packit 1422b7
Packit 1422b7
/**
Packit 1422b7
 * Generate error message and call the caller provided callback.
Packit 1422b7
 * eno is the OS errno. If non-zero, the OS error description
Packit 1422b7
 * will be added after the user-provided string.
Packit 1422b7
 *
Packit 1422b7
 * Will first check if a user callback is registered. If not, returns
Packit 1422b7
 * immediately.
Packit 1422b7
 */
Packit 1422b7
void
Packit 1422b7
ln_errprintf(const ln_ctx ctx, const int eno, const char *fmt, ...)
Packit 1422b7
{
Packit 1422b7
	va_list ap;
Packit 1422b7
	char buf[8*1024];
Packit 1422b7
	char errbuf[1024];
Packit 1422b7
	char finalbuf[9*1024];
Packit 1422b7
	size_t lenBuf;
Packit 1422b7
	char *msg;
Packit 1422b7
Packit 1422b7
	if(ctx->errmsgCB == NULL)
Packit 1422b7
		goto done;
Packit 1422b7
	
Packit 1422b7
	va_start(ap, fmt);
Packit 1422b7
	lenBuf = vsnprintf(buf, sizeof(buf), fmt, ap);
Packit 1422b7
	va_end(ap);
Packit 1422b7
	if(lenBuf >= sizeof(buf)) {
Packit 1422b7
		/* prevent buffer overrruns and garbagge display */
Packit 1422b7
		buf[sizeof(buf) - 5] = '.';
Packit 1422b7
		buf[sizeof(buf) - 4] = '.';
Packit 1422b7
		buf[sizeof(buf) - 3] = '.';
Packit 1422b7
		buf[sizeof(buf) - 2] = '\n';
Packit 1422b7
		buf[sizeof(buf) - 1] = '\0';
Packit 1422b7
		lenBuf = sizeof(buf) - 1;
Packit 1422b7
	}
Packit 1422b7
Packit 1422b7
	if(eno != 0) {
Packit 1422b7
		rs_strerror_r(eno, errbuf, sizeof(errbuf));
Packit 1422b7
		lenBuf = snprintf(finalbuf, sizeof(finalbuf), "%s: %s", buf, errbuf);
Packit 1422b7
		msg = finalbuf;
Packit 1422b7
	} else {
Packit 1422b7
		msg = buf;
Packit 1422b7
	}
Packit 1422b7
Packit 1422b7
	if(ctx->conf_file != NULL) {
Packit 1422b7
		/* error during config processing, add line info */
Packit 1422b7
		const char *const m = strdup(msg);
Packit 1422b7
		lenBuf = snprintf(finalbuf, sizeof(finalbuf), "rulebase file %s[%d]: %s",
Packit 1422b7
			ctx->conf_file, ctx->conf_ln_nbr, m);
Packit 1422b7
		msg = finalbuf;
Packit 1422b7
		free((void*) m);
Packit 1422b7
	}
Packit 1422b7
Packit 1422b7
	ctx->errmsgCB(ctx->dbgCookie, msg, lenBuf);
Packit 1422b7
	ln_dbgprintf(ctx, "%s", msg);
Packit 1422b7
done:	return;
Packit 1422b7
}
Packit 1422b7
Packit 1422b7
void
Packit 1422b7
ln_enableDebug(ln_ctx ctx, int i)
Packit 1422b7
{
Packit 1422b7
	ctx->debug = i & 0x01;
Packit 1422b7
}