head 1.12;
access;
symbols
L2_0_9_13:1.12
FSL_1_7_0:1.12
L2_0_9_12:1.12
LMTP2NNTP_1_4_1:1.12
LMTP2NNTP_1_4_0:1.12
FSL_1_6_1:1.12
L2_0_9_11:1.12
FSL_1_6_0:1.11
FSL_1_6b2:1.11
L2_0_9_10:1.11
FSL_1_6b1:1.11
L2_0_9_9:1.11
LMTP2NNTP_1_3_0:1.10
LMTP2NNTP_1_3b2:1.10
LMTP2NNTP_1_3b1:1.10
LMTP2NNTP_1_3a3:1.10
FSL_1_5_0:1.10
LMTP2NNTP_1_3a2:1.10
FSL_1_5a3:1.10
LMTP2NNTP_1_3a1:1.10
FSL_1_5a2:1.10
L2_0_9_8:1.10
FSL_1_5a1:1.10
L2_0_9_7:1.10
L2_0_9_6:1.10
FSL_1_4_0:1.10
FSL_1_4b1:1.10
L2_0_9_5:1.10
FSL_1_4a1:1.10
FSL_1_3_0:1.10
FSL_1_3b1:1.10
L2_0_9_4:1.10
FSL_1_2_1:1.10
L2_0_9_3:1.10
FSL_1_2_0:1.10
L2_0_9_2:1.10
FSL_1_1_0:1.10
FSL_1_1b1:1.10
WORKOFF:1.10.0.2
WORKOFF_BP:1.10
FSL_1_0_8:1.10
LMTP2NNTP_1_2_0:1.10
LMTP2NNTP_1_2b4:1.10
LMTP2NNTP_1_2b3:1.10
LMTP2NNTP_1_2b2:1.10
LMTP2NNTP_1_2b1:1.10
LMTP2NNTP_1_2a8:1.10
LMTP2NNTP_1_2a7:1.10
FSL_1_0_7:1.10
FSL_1_0_6:1.9
FSL_1_0_5:1.9
FSL_1_0_4:1.9
L2_0_9_1:1.9
FSL_1_0_3:1.9
LMTP2NNTP_1_2a6:1.9
FSL_1_0_2:1.9
FSL_1_0_1:1.9
FSL_1_0_0:1.9
FSL_0_9_0:1.9
L2_0_9_0:1.9
FSL_0_1_12:1.8
FSL_0_1_11:1.8
FSL_0_1_10:1.8
FSL_0_1_9:1.8
FSL_0_1_8:1.8
FSL_0_1_7:1.8
FSL_0_1_6:1.8
FSL_0_1_5:1.8
FSL_0_1_1:1.8
LMTP2NNTP_1_2a5:1.7
LMTP2NNTP_1_2a4:1.7
LMTP2NNTP_1_2a3:1.7
LMTP2NNTP_1_2a1:1.4;
locks; strict;
comment @ * @;
1.12
date 2005.10.03.08.08.11; author rse; state Exp;
branches;
next 1.11;
1.11
date 2005.01.24.15.03.17; author rse; state Exp;
branches;
next 1.10;
1.10
date 2003.01.06.11.41.51; author rse; state Exp;
branches;
next 1.9;
1.9
date 2002.07.30.19.08.25; author rse; state Exp;
branches;
next 1.8;
1.8
date 2002.07.17.13.22.02; author thl; state Exp;
branches;
next 1.7;
1.7
date 2002.01.02.17.07.38; author rse; state Exp;
branches;
next 1.6;
1.6
date 2001.12.22.22.18.34; author rse; state Exp;
branches;
next 1.5;
1.5
date 2001.12.14.12.39.08; author rse; state Exp;
branches;
next 1.4;
1.4
date 2001.11.16.19.45.12; author ms; state Exp;
branches;
next 1.3;
1.3
date 2001.11.07.11.37.18; author rse; state Exp;
branches;
next 1.2;
1.2
date 2001.11.04.13.55.06; author rse; state Exp;
branches;
next 1.1;
1.1
date 2001.11.04.13.21.17; author rse; state Exp;
branches;
next ;
desc
@@
1.12
log
@Adjust copyright messages for new year 2005.
@
text
@/*
** OSSP l2 - Flexible Logging
** Copyright (c) 2001-2005 Cable & Wireless
** Copyright (c) 2001-2005 The OSSP Project
** Copyright (c) 2001-2005 Ralf S. Engelschall
**
** This file is part of OSSP l2, a flexible logging library which
** can be found at http://www.ossp.org/pkg/lib/l2/.
**
** Permission to use, copy, modify, and distribute this software for
** any purpose with or without fee is hereby granted, provided that
** the above copyright notice and this permission notice appear in all
** copies.
**
** THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
** WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
** IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
** USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
** OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
** SUCH DAMAGE.
**
** l2_env.c: environment object
*/
#include "l2_p.h"
/* create environment object */
l2_result_t l2_env_create(l2_env_t **envp)
{
l2_env_t *env;
int i;
/* argument sanity check */
if (envp == NULL)
return L2_ERR_ARG;
/* allocate environment structure */
if ((env = (l2_env_t *)malloc(sizeof(l2_env_t))) == NULL)
return L2_ERR_SYS;
/* initialize environment structure */
env->rvErrorInfo = L2_OK;
env->szErrorInfo[0] = '\0';
env->szError[0] = '\0';
env->levelmask = L2_LEVEL_ALL;
env->flushmask = L2_LEVEL_NONE;
env->interval = 0;
for (i = 0; i < L2_MAX_FORMATTERS; i++)
env->formatters[i].cb = NULL;
for (i = 0; i < L2_MAX_HANDLERS; i++)
env->handlers[i] = NULL;
/* pre-configure all handlers we ship */
l2_env_handler(env, &l2_handler_null);
l2_env_handler(env, &l2_handler_fd);
l2_env_handler(env, &l2_handler_file);
l2_env_handler(env, &l2_handler_pipe);
l2_env_handler(env, &l2_handler_socket);
l2_env_handler(env, &l2_handler_syslog);
l2_env_handler(env, &l2_handler_smtp);
l2_env_handler(env, &l2_handler_noop);
l2_env_handler(env, &l2_handler_filter);
l2_env_handler(env, &l2_handler_prefix);
l2_env_handler(env, &l2_handler_buffer);
/* pass new object to caller */
(*envp) = env;
return L2_OK;
}
/* destroy environment object */
l2_result_t l2_env_destroy(l2_env_t *env)
{
/* argument sanity check */
if (env == NULL)
return L2_ERR_ARG;
/* free env structure */
free(env);
return L2_OK;
}
/* set environment level masks */
l2_result_t l2_env_levels(l2_env_t *env, unsigned int levelmask, unsigned int flushmask)
{
/* argument sanity check */
if (env == NULL)
return L2_ERR_ARG;
/* override global level mask */
env->levelmask = levelmask;
env->flushmask = flushmask;
return L2_OK;
}
/* attach formatter to environment */
l2_result_t l2_env_formatter(l2_env_t *env, char id, l2_formatter_t cb, l2_context_t *ctx)
{
int i;
/* argument sanity check */
if (env == NULL || id == '\0' || cb == NULL)
return L2_ERR_ARG;
/* find next free formatter position in formatter array */
for (i = 0; i < L2_MAX_FORMATTERS && env->formatters[i].cb != NULL; i++)
;
if (i == L2_MAX_FORMATTERS)
return L2_ERR_MEM;
/* attach formatter to env */
env->formatters[i].id = id;
env->formatters[i].ctx = ctx;
env->formatters[i].cb = cb;
return L2_OK;
}
/* attach handler to environment */
l2_result_t l2_env_handler(l2_env_t *env, l2_handler_t *h)
{
int i;
/* argument sanity check */
if (env == NULL || h == NULL)
return L2_ERR_ARG;
/* find next free handler position in handler array */
for (i = 0; i < L2_MAX_HANDLERS && env->handlers[i] != NULL; i++)
;
if (i == L2_MAX_HANDLERS)
return L2_ERR_MEM;
/* attach handler to env */
env->handlers[i] = h;
env->handlers[i] = h;
return L2_OK;
}
/* remember additional error information */
l2_result_t l2_env_errorinfo(l2_env_t *env, l2_result_t rv, const char *fmt, ...)
{
va_list ap;
/* argument sanity check */
if (env == NULL || rv == L2_OK || fmt == NULL)
return L2_ERR_ARG;
/* remember error information */
va_start(ap, fmt);
l2_util_vsprintf(env->szErrorInfo, sizeof(env->szErrorInfo), fmt, ap);
env->rvErrorInfo = rv;
va_end(ap);
return L2_OK;
}
/* retrieve string description of error result code */
char *l2_env_strerror(l2_env_t *env, l2_result_t rv)
{
char *sz;
char *cpBuf;
int nBuf;
int n;
/* argument sanity check */
if (env == NULL)
return NULL;
/* start at begin of buffer */
cpBuf = env->szError;
nBuf = sizeof(env->szError);
/* translate result value into corresponding string */
if (rv == L2_OK) sz = "everything ok";
else if (rv == L2_OK_PASS) sz = "everything ok - pass downstream";
else if (rv == L2_ERR_ARG) sz = "invalid argument";
else if (rv == L2_ERR_USE) sz = "invalid use";
else if (rv == L2_ERR_MEM) sz = "no more memory available";
else if (rv == L2_ERR_SYS) sz = "operating system error";
else if (rv == L2_ERR_IO) sz = "input/output error";
else if (rv == L2_ERR_FMT) sz = "formatting error";
else if (rv == L2_ERR_INT) sz = "internal error";
else if (rv == L2_ERR_SYN) sz = "syntax error";
else if (rv == L2_ERR_CH) sz = "no (more) channel found";
else sz = "unknown error";
n = l2_util_sprintf(cpBuf, nBuf, "%s", sz);
cpBuf += n;
nBuf -= n;
/* optionally annotate with error information */
if (rv == env->rvErrorInfo && env->szErrorInfo[0] != '\0') {
n = l2_util_sprintf(cpBuf, nBuf, "; %s", env->szErrorInfo);
cpBuf += n;
nBuf -= n;
}
/* optionally annotate with operating system error information */
if (rv == L2_ERR_SYS) {
n = l2_util_sprintf(cpBuf, nBuf, "; %s (%d)", strerror(errno), errno);
cpBuf += n;
nBuf -= n;
}
/* return pointer to internal buffer */
return env->szError;
}
/* sets the virtual timer to the interval value in env */
static int set_alarm(l2_env_t *env)
{
#if defined(HAVE_SETITIMER) && defined(HAVE_SYS_TIME_H)
struct itimerval valtest, valnew;
/* initialize auto vars before using them */
memset(&valnew, 0, sizeof(valnew));
valnew.it_interval.tv_sec = (long)env->interval;
valnew.it_interval.tv_usec = 0L; /* no microsecond granularity */
valnew.it_value.tv_sec = (long)env->interval;
valnew.it_value.tv_usec = 0L; /* no microsecond granularity */
if ((getitimer(L2_BUFFER_TIMER, &valtest) == 0) &&
((valtest.it_value.tv_sec | valtest.it_value.tv_usec |
valtest.it_interval.tv_sec | valtest.it_interval.tv_usec) == 0L))
return (setitimer(L2_BUFFER_TIMER, &valnew, 0) ? L2_ERR_INT : L2_OK);
else {
env->interval = L2_BROKEN_TIMER; /* mark this timer as broken */
assert(FALSE); /* throw the switch right away when debugging */
return L2_ERR_ARG;
}
#else
unsigned int uiAlarmed = 0;
assert(env->interval >= 0); /* guard against a broken timer */
assert(!(uiAlarmed = alarm((unsigned int)iInterval)));
if (uiAlarmed) { /* check if SIGALRM is occupied */
alarm(uiAlarmed); /* ...if so, then hack in the old value */
env->interval = L2_BROKEN_TIMER; /* ...mark this timer as broken */
return L2_ERR_INT;
}
else
return L2_OK;
#endif
}
/* l2_env_settimer will change or disappear with */
/* the arrival of the multiplexed L2 timer object */
/* set the L2 timer */
l2_result_t l2_env_settimer(l2_env_t *env, int iInterval)
{
if ((env == NULL) || (iInterval < 0)) /* argument sanity check */
return L2_ERR_ARG;
/* short circuit if setting again with identical interval value */
if (env->interval == iInterval)
return L2_OK;
/* one value only, no multiplexed timer support */
if (env->interval != 0) /* && (env->interval != iInterval) */
return L2_ERR_ARG;
env->interval = iInterval;
if (set_alarm(env) != L2_OK) {
env->interval = L2_BROKEN_TIMER; /* L2 timer is broken */
return L2_ERR_INT;
}
else
return L2_OK;
}
@
1.11
log
@Adjust copyright messages for new year 2005.
@
text
@d3 3
a5 3
** Copyright (c) 2001-2004 Cable & Wireless
** Copyright (c) 2001-2004 The OSSP Project
** Copyright (c) 2001-2004 Ralf S. Engelschall
@
1.10
log
@- remove trailing whitespaces
- adjust copyright messages
- consistently use "OSSP l2"
- consistently talk about "Flexible Logging"
- use standard OSSP ASCII-art
@
text
@d3 3
a5 3
** Copyright (c) 2001-2003 Cable & Wireless Deutschland GmbH
** Copyright (c) 2001-2003 The OSSP Project (http://www.ossp.org/)
** Copyright (c) 2001-2003 Ralf S. Engelschall
@
1.9
log
@polish for release
@
text
@d2 4
a5 3
** OSSP l2 - Logging Library
** Copyright (c) 2001-2002 The OSSP Project (http://www.ossp.org/)
** Copyright (c) 2001-2002 Cable & Wireless Deutschland (http://www.cw.com/de/)
d7 1
a7 1
** This file is part of OSSP L2, a flexible logging library which
d42 2
a43 2
/* allocate environment structure */
@
1.8
log
@align l2_env_strerror with l2.h
@
text
@d2 1
a2 1
** L2 - OSSP Logging Library
d7 1
a7 1
** can be found at http://www.ossp.org/pkg/l2/.
@
1.7
log
@bump copyright year
@
text
@d186 1
d195 1
@
1.6
log
@Fix l2_spec_error function and remove again the not
really needed l2_env_verrorinfo function.
@
text
@d3 2
a4 2
** Copyright (c) 2001 The OSSP Project (http://www.ossp.org/)
** Copyright (c) 2001 Cable & Wireless Deutschland (http://www.cw.com/de/)
@
1.5
log
@provide l2_env_verrorinfo() and a new L2_ERR_SYN
@
text
@a154 10
/* remember error information */
va_start(ap, fmt);
l2_env_verrorinfo(env, rv, fmt, ap);
va_end(ap);
return L2_OK;
}
l2_result_t l2_env_verrorinfo(l2_env_t *env, l2_result_t rv, const char *fmt, va_list ap)
{
d160 1
d163 1
@
1.4
log
@Introduced new tree safe timer logic to the L2 environment.
@
text
@d155 10
a169 1
va_start(ap, fmt);
a171 1
va_end(ap);
d201 1
@
1.3
log
@More preparations for forthcoming channel tree specification parser
(especially to allow the parser to determine the handler structure
from a handler name without introducing another and this way redundant
sub-API):
- add "char *name" to l2_handler_t in order to tag each
handler structure with the corresponding channel name
- add l2_env_handler() function to add handler to
l2_env_t objects. All l2_handler_xxxx are automatically
pre-configured there after l2_env_create().
- change l2_channel_create() to take a "const char *name"
(handler name) instead of the "l2_handler_t *h" (handler
pointer) to make the stuff consistent and more clear.
- adjust l2_test.c to reflect the changes.
@
text
@d52 1
d214 62
@
1.2
log
@code cleanups
@
text
@d54 15
d123 22
@
1.1
log
@Channel-Only Revamping Step 2:
- moved code of l2_stream.c into (new) l2_env.c and l2_channel.c
- created new l2_env_t and l2_env_xxx()
- changed l2_xx_create() functions to also return l2_result_t
- moved error handling into l2_env_t
- replaced l2_channel_stack() with two new and more flexible
l2_channel_link() and l2_channel_unlink() functions
- rewritten test stuff in l2_test.c to use new structure
- added new l2_channel_env() function for retriving l2_env_t
Puhhh....
@
text
@d27 1
a27 2
** l2_env.c: environment
**
a29 1
#include "l2.h"
d33 1
a33 1
l2_result_t l2_env_create(l2_env_t **env)
d35 1
d37 4
d42 2
a43 2
/* allocate env structure */
if (((*env) = (l2_env_t *)malloc(sizeof(l2_env_t))) == NULL)
d46 6
a51 6
/* initialize env structure */
(*env)->rvErrorInfo = L2_OK;
(*env)->szErrorInfo[0] = '\0';
(*env)->szError[0] = '\0';
(*env)->levelmask = L2_LEVEL_ALL;
(*env)->flushmask = L2_LEVEL_NONE;
d53 4
a56 1
(*env)->formatters[i].cb = NULL;
d105 3
a107 3
env->formatters[i].id = id;
env->formatters[i].ctx = ctx;
env->formatters[i].cb = cb;
d112 1
d130 1
@