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 @