Index: ossp-pkg/l2/Makefile.in RCS File: /v/ossp/cvs/ossp-pkg/l2/Makefile.in,v rcsdiff -q -kk '-r1.26' '-r1.27' -u '/v/ossp/cvs/ossp-pkg/l2/Makefile.in,v' 2>/dev/null --- Makefile.in 2001/10/11 08:02:16 1.26 +++ Makefile.in 2001/11/04 13:21:17 1.27 @@ -63,7 +63,7 @@ # list of library object files OBJS = \ - l2_stream.lo \ + l2_env.lo \ l2_channel.lo \ l2_ch_fd.lo \ l2_ch_file.lo \ @@ -86,7 +86,7 @@ # list of source files SRCS = \ - l2_stream.c \ + l2_env.c \ l2_channel.c \ l2_ch_fd.c \ l2_ch_file.c \ @@ -296,13 +296,14 @@ $(OBJS): Makefile # AUTOMATICALLY GENERATED DEPENDENCY LIST - DO NOT EDIT -l2_stream.o: l2_stream.c l2.h l2_p.h l2_config.h l2_ut_pcre.h l2_ut_sa.h +l2_env.o: l2_env.c l2.h l2_p.h l2_config.h l2_ut_pcre.h l2_ut_sa.h l2_channel.o: l2_channel.c l2.h l2_p.h l2_config.h l2_ut_pcre.h l2_ut_sa.h l2_ch_fd.o: l2_ch_fd.c l2.h l2_ch_file.o: l2_ch_file.c l2.h l2_ch_pipe.o: l2_ch_pipe.c l2.h l2_p.h l2_config.h l2_ut_pcre.h l2_ut_sa.h l2_ch_syslog.o: l2_ch_syslog.c l2.h l2_p.h l2_config.h l2_ut_pcre.h l2_ut_sa.h l2_ch_socket.o: l2_ch_socket.c l2.h l2_p.h l2_config.h l2_ut_pcre.h l2_ut_sa.h +l2_ch_irc.o: l2_ch_irc.c l2.h l2_p.h l2_config.h l2_ut_pcre.h l2_ut_sa.h l2_ch_smtp.o: l2_ch_smtp.c l2.h l2_p.h l2_config.h l2_ut_pcre.h l2_ut_sa.h l2_ch_null.o: l2_ch_null.c l2.h l2_ch_filter.o: l2_ch_filter.c l2.h l2_ut_pcre.h Index: ossp-pkg/l2/TODO RCS File: /v/ossp/cvs/ossp-pkg/l2/TODO,v rcsdiff -q -kk '-r1.35' '-r1.36' -u '/v/ossp/cvs/ossp-pkg/l2/TODO,v' 2>/dev/null --- TODO 2001/10/26 10:54:26 1.35 +++ TODO 2001/11/04 13:21:17 1.36 @@ -2,6 +2,11 @@ OSSP L2 ======= +Channel-Only Revamping: +- syscall override ala OSSP SA in l2_env_t +- l2_objects.fig update +- perhaps rename l2_env to l2_ctx and l2_channel_ to just l2_ + - Perhaps we should later also write an l2_ch_bofh.c which something very cool but is undocumented and has its source mangled/scrambled ;) Index: ossp-pkg/l2/l2.h.in RCS File: /v/ossp/cvs/ossp-pkg/l2/l2.h.in,v rcsdiff -q -kk '-r1.14' '-r1.15' -u '/v/ossp/cvs/ossp-pkg/l2/l2.h.in,v' 2>/dev/null --- l2.h.in 2001/11/03 22:51:36 1.14 +++ l2.h.in 2001/11/04 13:21:17 1.15 @@ -70,6 +70,7 @@ struct l2_stream_st; struct l2_channel_st; struct l2_handler_st; +struct l2_env_st; /* corresponding data types for data structures */ typedef union l2_context_un l2_context_t; @@ -77,6 +78,7 @@ typedef struct l2_handler_st l2_handler_t; typedef struct l2_stream_st l2_stream_t; typedef struct l2_channel_st l2_channel_t; +typedef struct l2_env_st l2_env_t; /* list of logging levels (high to low priority; low to high amount of logging) */ typedef enum { @@ -90,12 +92,16 @@ L2_LEVEL_TRACE = (1 << 6), L2_LEVEL_DEBUG = (1 << 7) } l2_level_t; + +/* macro describing a particular custom level */ #define L2_LEVEL_CUSTOM(n) (1 << (8+(n)) -#define L2_LEVEL_ALL ((1 << (8+9+1))-1) -/* all levels from highest (PANIC) to and including a particular low level */ -#define L2_LEVEL_UPTO(level) \ - (((level)-1)|(level)) +/* macro describing all levels */ +#define L2_LEVEL_ALL ((1 << (8+9+1))-1) + +/* macr describing all levels from highest (PANIC) + to and including a particular low level */ +#define L2_LEVEL_UPTO(level) (((level)-1)|(level)) /* list of return values */ typedef enum { @@ -155,6 +161,12 @@ L2_CHANNEL_OUTPUT } l2_chtype_t; +/* list of linking modes */ +typedef enum { + L2_LINK_CHILDS, + L2_LINK_SIBLINGS +} l2_link_t; + /* channel handler specification structure */ struct l2_handler_st { l2_chtype_t type; @@ -192,37 +204,38 @@ extern l2_handler_t l2_handler_prefix; extern l2_handler_t l2_handler_buffer; +/* context operations */ +l2_result_t l2_env_create (l2_env_t **env); +l2_result_t l2_env_destroy (l2_env_t *env); +l2_result_t l2_env_levels (l2_env_t *env, unsigned int levelmask, unsigned int flushmask); +l2_result_t l2_env_formatter (l2_env_t *env, char id, l2_formatter_t cb, l2_context_t *ctx); +l2_result_t l2_env_errorinfo (l2_env_t *env, l2_result_t rv, const char *fmt, ...); +char *l2_env_strerror (l2_env_t *env, l2_result_t rv); + /* channel operations */ -l2_channel_t *l2_channel_create (l2_handler_t *h); +l2_result_t l2_channel_create (l2_channel_t **ch, l2_env_t *env, l2_handler_t *h); +l2_result_t l2_channel_destroy (l2_channel_t *ch); +l2_result_t l2_channel_levels (l2_channel_t *ch, unsigned int levelmask, unsigned int flushmask); l2_result_t l2_channel_configure (l2_channel_t *ch, const char *fmt, ...); l2_result_t l2_channel_open (l2_channel_t *ch); l2_result_t l2_channel_write (l2_channel_t *ch, l2_level_t level, const char *buf, size_t bufsize); l2_result_t l2_channel_flush (l2_channel_t *ch); l2_result_t l2_channel_close (l2_channel_t *ch); -l2_result_t l2_channel_destroy (l2_channel_t *ch); -l2_result_t l2_channel_stack (l2_channel_t *ch, l2_channel_t *chTop); +l2_result_t l2_channel_log (l2_channel_t *ch, l2_level_t level, const char *fmt, ...); +l2_result_t l2_channel_vlog (l2_channel_t *ch, l2_level_t level, const char *fmt, va_list ap); +l2_result_t l2_channel_link (l2_channel_t *ch, l2_link_t id, l2_channel_t *ch2, ...); +l2_result_t l2_channel_unlink (l2_channel_t *ch); l2_result_t l2_channel_upstream (l2_channel_t *ch, l2_channel_t **chU); l2_result_t l2_channel_downstream (l2_channel_t *ch, l2_channel_t **chD); l2_result_t l2_channel_type (l2_channel_t *ch, l2_chtype_t *type); -l2_result_t l2_channel_errorinfo (l2_channel_t *ch, l2_result_t rv, const char *fmt, ...); -char *l2_channel_strerror (l2_channel_t *ch, l2_result_t rv); - -/* stream operations */ -l2_stream_t *l2_stream_create (void); -l2_result_t l2_stream_channel (l2_stream_t *st, l2_channel_t *ch, unsigned int levelmask, unsigned int flushmask); -l2_result_t l2_stream_formatter (l2_stream_t *st, char id, l2_formatter_t cb, l2_context_t *ctx); -l2_result_t l2_stream_levels (l2_stream_t *st, unsigned int levelmask, unsigned int flushmask); -l2_result_t l2_stream_log (l2_stream_t *st, l2_level_t level, const char *fmt, ...); -l2_result_t l2_stream_vlog (l2_stream_t *st, l2_level_t level, const char *fmt, va_list ap); -l2_result_t l2_stream_flush (l2_stream_t *st); -l2_result_t l2_stream_destroy (l2_stream_t *st); +l2_result_t l2_channel_env (l2_channel_t *ch, l2_env_t **env); /* utility operations */ -l2_result_t l2_util_setparams (l2_param_t p[], const char *fmt, va_list ap); -l2_result_t l2_util_l2s (char *string, size_t maxlen, int sep, unsigned int levelmask); -l2_result_t l2_util_s2l (const char *string, size_t maxlen, int sep, unsigned int *levelmask); -l2_result_t l2_util_fmt_string (l2_context_t *, const char, const char *, char *, size_t, size_t *, va_list *); -l2_result_t l2_util_fmt_dump (l2_context_t *, const char, const char *, char *, size_t, size_t *, va_list *); +l2_result_t l2_util_setparams (l2_param_t p[], const char *fmt, va_list ap); +l2_result_t l2_util_l2s (char *string, size_t maxlen, int sep, unsigned int levelmask); +l2_result_t l2_util_s2l (const char *string, size_t maxlen, int sep, unsigned int *levelmask); +l2_result_t l2_util_fmt_string (l2_context_t *, const char, const char *, char *, size_t, size_t *, va_list *); +l2_result_t l2_util_fmt_dump (l2_context_t *, const char, const char *, char *, size_t, size_t *, va_list *); #endif /* __L2_H__ */ Index: ossp-pkg/l2/l2_ch_filter.c RCS File: /v/ossp/cvs/ossp-pkg/l2/l2_ch_filter.c,v rcsdiff -q -kk '-r1.11' '-r1.12' -u '/v/ossp/cvs/ossp-pkg/l2/l2_ch_filter.c,v' 2>/dev/null --- l2_ch_filter.c 2001/11/03 22:51:36 1.11 +++ l2_ch_filter.c 2001/11/04 13:21:17 1.12 @@ -63,6 +63,7 @@ static l2_result_t hook_configure(l2_context_t *ctx, l2_channel_t *ch, const char *fmt, va_list ap) { l2_ch_filter_t *cfg = (l2_ch_filter_t *)ctx->vp; + l2_env_t *env; l2_param_t pa[3]; l2_result_t rv; const char *szError; @@ -79,7 +80,8 @@ if (cfg->szRegex != NULL) { /* compile regular expression into FSM */ if ((cfg->pcreRegex = pcre_compile(cfg->szRegex, 0, &szError, &nErrorOffset, NULL)) == NULL) { - l2_channel_errorinfo(ch, L2_ERR_ARG, "%s ('%c')", szError, cfg->szRegex[nErrorOffset]); + l2_channel_env(ch, &env); + l2_env_errorinfo(env, L2_ERR_ARG, "%s ('%c')", szError, cfg->szRegex[nErrorOffset]); return L2_ERR_ARG; } /* study FSM for more performance */ @@ -87,7 +89,8 @@ if (szError != NULL) { free(cfg->pcreRegex); cfg->pcreRegex = NULL; - l2_channel_errorinfo(ch, L2_ERR_ARG, "%s", szError); + l2_channel_env(ch, &env); + l2_env_errorinfo(env, L2_ERR_ARG, "%s", szError); return L2_ERR_ARG; } } Index: ossp-pkg/l2/l2_channel.c RCS File: /v/ossp/cvs/ossp-pkg/l2/l2_channel.c,v rcsdiff -q -kk '-r1.21' '-r1.22' -u '/v/ossp/cvs/ossp-pkg/l2/l2_channel.c,v' 2>/dev/null --- l2_channel.c 2001/11/03 22:51:36 1.21 +++ l2_channel.c 2001/11/04 13:21:17 1.22 @@ -70,73 +70,127 @@ */ /* create channel */ -l2_channel_t *l2_channel_create(l2_handler_t *h) +l2_result_t l2_channel_create(l2_channel_t **chp, l2_env_t *env, l2_handler_t *h) { l2_channel_t *ch; /* argument sanity check */ - if (h == NULL) - return NULL; + if (h == NULL || env == NULL) + return L2_ERR_ARG; /* allocate channel structure */ if ((ch = (l2_channel_t *)malloc(sizeof(l2_channel_t))) == NULL) - return NULL; + return L2_ERR_SYS; /* initialize channel structure */ + ch->env = env; ch->state = L2_CHSTATE_CREATED; ch->parent = NULL; ch->sibling = NULL; ch->child = NULL; memset(&ch->context, 0, sizeof(l2_context_t)); memcpy(&ch->handler, h, sizeof(l2_handler_t)); - ch->rvErrorInfo = L2_OK; - ch->szErrorInfo[0] = '\0'; - ch->szError[0] = '\0'; - ch->levelmask = L2_LEVEL_ALL; - ch->flushmask = L2_LEVEL_NONE; + ch->levelmask = env->levelmask; + ch->flushmask = env->flushmask; /* (optionally) perform create operation in handler */ if (ch->handler.create != NULL) { if (ch->handler.create(&ch->context, ch) != L2_OK) { free(ch); - return NULL; + return L2_ERR_SYS; } } - return ch; + /* pass object to caller */ + (*chp) = ch; + + return L2_OK; } -/* stack channel on top of another channel */ -l2_result_t l2_channel_stack(l2_channel_t *ch, l2_channel_t *chP) +/* link channels */ +l2_result_t l2_channel_link(l2_channel_t *chR, l2_link_t id, l2_channel_t *chC, ...) { l2_channel_t *chT; + l2_channel_t *chN; + va_list ap; /* argument sanity check */ - if (ch == NULL || chP == NULL) + if (chR == NULL || chC == NULL) return L2_ERR_ARG; - /* make sure both channels are in state "created" */ - if ( ch->state != L2_CHSTATE_CREATED - || chP->state != L2_CHSTATE_CREATED) + /* make sure root channel is in state "created" */ + if (chR->state != L2_CHSTATE_CREATED) return L2_ERR_USE; - /* make sure parent channel is a filter channel */ - if (chP->handler.type != L2_CHANNEL_FILTER) + /* make sure root channel is a filter channel */ + if (chR->handler.type != L2_CHANNEL_FILTER) return L2_ERR_USE; - /* make sure child still has no parent */ - if (ch->parent != NULL) + /* check childs */ + va_start(ap, chC); + chT = chC; + do { + chN = (l2_channel_t *)va_arg(ap, l2_channel_t *); + if (id == L2_LINK_CHILDS && chN != NULL) + if (chT->handler.type != L2_CHANNEL_FILTER) + return L2_ERR_USE; + } while ((chT = chN) != NULL); + va_end(ap); + + /* perform link operation(s) */ + va_start(ap, chC); + do { + chC->parent = chR; + chC->sibling = NULL; + chC->child = NULL; + if (chR->child == NULL) + chR->child = chC; + else { + chT = chR->child; + while (chT->sibling != NULL) + chT = chT->sibling; + chT->sibling = chC; + } + if (id == L2_LINK_CHILDS) + chR = chC; + chC = (l2_channel_t *)va_arg(ap, l2_channel_t *); + } + while (chC != NULL); + va_end(ap); + + return L2_OK; +} + +/* unlink channels */ +l2_result_t l2_channel_unlink(l2_channel_t *ch) +{ + l2_channel_t *chS; + l2_channel_t *chP; + + /* argument sanity check */ + if (ch == NULL) + return L2_ERR_ARG; + + /* make sure channel is in state "created" */ + if (ch->state != L2_CHSTATE_CREATED) return L2_ERR_USE; - /* stack the two channels */ - ch->parent = chP; - if (chP->child == NULL) - chP->child = ch; - else { - chT = chP->child; - while (chT->sibling != NULL) - chT = chT->sibling; - chT->sibling = ch; + /* make sure channel has no childs */ + if (ch->child != NULL) + return L2_ERR_USE; + + /* unlink the channel */ + chP = ch->parent; + ch->parent = NULL; + if (chP != NULL) { + if (chP->child == ch) + chP->child = ch->sibling; + else { + chS = chP->child; + while (chS->sibling != ch) + chS = chS->sibling; + chS->sibling = ch->sibling; + } } return L2_OK; @@ -184,6 +238,20 @@ return L2_OK; } +/* set channel level masks */ +l2_result_t l2_channel_levels(l2_channel_t *ch, unsigned int levelmask, unsigned int flushmask) +{ + /* argument sanity check */ + if (ch == NULL) + return L2_ERR_ARG; + + /* override global level mask */ + ch->levelmask = levelmask; + ch->flushmask = flushmask; + + return L2_OK; +} + /* configure channel */ l2_result_t l2_channel_configure(l2_channel_t *ch, const char *fmt, ...) { @@ -395,67 +463,119 @@ return rv; } -l2_result_t l2_channel_errorinfo(l2_channel_t *ch, l2_result_t rv, const char *fmt, ...) +/* log a message to channel */ +l2_result_t l2_channel_log(l2_channel_t *ch, l2_level_t level, const char *fmt, ...) { va_list ap; + l2_result_t rv; - /* argument sanity check */ - if (ch == NULL || rv == L2_OK || fmt == NULL) - return L2_ERR_ARG; - - /* remember error information */ + /* pass-through to va_list-based variant */ va_start(ap, fmt); - l2_util_vsprintf(ch->szErrorInfo, sizeof(ch->szErrorInfo), fmt, ap); - ch->rvErrorInfo = rv; + rv = l2_channel_vlog(ch, level, fmt, ap); va_end(ap); - return L2_OK; + return rv; } -char *l2_channel_strerror(l2_channel_t *ch, l2_result_t rv) +/* indirect callback function from l2_channel_vlog for flushing */ +static int l2_channel_vlog_flush(l2_util_format_t *vfmt) { - char *sz; - char *cpBuf; - int nBuf; - int n; + /* we do no format buffer flushing */ + return -1; +} - /* argument sanity check */ - if (ch == NULL) - return NULL; +/* indirect callback function from l2_channel_vlog for formatting */ +static void l2_channel_vlog_format( + l2_util_format_t *vfmt, + char *cPrefix, char *cPad, char **cppOut, size_t *npOutLen, + char *cpBuf, int nBufLenMax, char *cpParam, char cId, va_list *apArgs) +{ + l2_env_t *env = (l2_env_t *)(vfmt->data[0].vp); + l2_result_t rv; + int i; - /* start at begin of buffer */ - cpBuf = ch->szError; - nBuf = sizeof(ch->szError); - - /* translate result value into corresponding string */ - if (rv == L2_OK) sz = "everything ok"; - 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 sz = "unknown error"; - n = l2_util_sprintf(cpBuf, nBuf, "%s", sz); - cpBuf += n; - nBuf -= n; - - /* optionally annotate with error information */ - if (rv == ch->rvErrorInfo && ch->szErrorInfo[0] != '\0') { - n = l2_util_sprintf(cpBuf, nBuf, "; %s", ch->szErrorInfo); - cpBuf += n; - nBuf -= n; + /* init formatting result */ + *cPrefix = '\0'; + *cPad = ' '; + *cppOut = NULL; + *npOutLen = 0; + + /* iterate over all configured L2 formatters */ + for (i = 0; i < L2_MAX_FORMATTERS && env->formatters[i].cb != NULL; i++) { + if (env->formatters[i].id == cId) { + rv = env->formatters[i].cb(env->formatters[i].ctx, cId, cpParam, + cpBuf, nBufLenMax, npOutLen, apArgs); + vfmt->data[1].i = (int)rv; + if (rv == L2_OK) { + *cppOut = cpBuf; + break; + } + } } + return; +} + +/* log a message to channel (va_list-variant) */ +l2_result_t l2_channel_vlog(l2_channel_t *ch, l2_level_t level, const char *fmt, va_list ap) +{ + int l, j; + size_t len; + l2_result_t rv; + l2_util_format_t vfmt; + l2_env_t *env; + + /* argument sanity check */ + if (ch == NULL || level == 0 || fmt == NULL || ap == NULL) + return L2_ERR_ARG; + + /* make sure only a single level is specified */ + for (l = level, j = 0; l != 0; l = (l >> 1)) + if (l & 0x1) + j++; + if (j != 1) + return L2_ERR_ARG; + + /* check whether level mask already stops processing */ + if (!(ch->levelmask & level)) + return L2_OK; - /* 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; + /* format message */ + env = ch->env; + vfmt.curpos = env->message; + vfmt.endpos = env->message + L2_MAX_MSGSIZE; + vfmt.data[0].vp = env; + vfmt.data[1].i = L2_ERR_FMT; + vfmt.flush = l2_channel_vlog_flush; + vfmt.format = l2_channel_vlog_format; + if ((len = l2_util_format(&vfmt, fmt, ap)) == -1) + return (l2_result_t)(vfmt.data[1].i); + if (len == 0) + return L2_ERR_FMT; + + /* make sure a trailing newline exists */ + if (env->message[len-1] != '\n') { + if (len == L2_MAX_MSGSIZE) + return L2_ERR_MEM; + env->message[len++] = '\n'; + env->message[len] = '\0'; } - /* return pointer to internal buffer */ - return ch->szError; + /* write message to channel */ + rv = L2_OK; + if ((rv = l2_channel_write(ch, level, env->message, len)) != L2_OK) + return rv; + if (ch->flushmask & level) + l2_channel_flush(ch); + + return rv; +} + +/* return environment object */ +l2_result_t l2_channel_env(l2_channel_t *ch, l2_env_t **env) +{ + if (ch == NULL || env == NULL) + return L2_ERR_ARG; + *env = ch->env; + return L2_OK; } Index: ossp-pkg/l2/l2_env.c RCS File: /v/ossp/cvs/ossp-pkg/l2/l2_env.c,v co -q -kk -p'1.1' '/v/ossp/cvs/ossp-pkg/l2/l2_env.c,v' | diff -u /dev/null - -L'ossp-pkg/l2/l2_env.c' 2>/dev/null --- ossp-pkg/l2/l2_env.c +++ - 2024-04-26 22:56:46.224220580 +0200 @@ -0,0 +1,169 @@ +/* +** L2 - OSSP Logging Library +** Copyright (c) 2001 The OSSP Project (http://www.ossp.org/) +** Copyright (c) 2001 Cable & Wireless Deutschland (http://www.cw.com/de/) +** +** This file is part of OSSP L2, a flexible logging library which +** can be found at http://www.ossp.org/pkg/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 +** +*/ + +#include "l2.h" +#include "l2_p.h" + +/* create environment object */ +l2_result_t l2_env_create(l2_env_t **env) +{ + int i; + + /* allocate env structure */ + if (((*env) = (l2_env_t *)malloc(sizeof(l2_env_t))) == NULL) + return L2_ERR_SYS; + + /* 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; + for (i = 0; i < L2_MAX_FORMATTERS; i++) + (*env)->formatters[i].cb = NULL; + + 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; +} + +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; +} + +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_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 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; +} + Index: ossp-pkg/l2/l2_p.h RCS File: /v/ossp/cvs/ossp-pkg/l2/l2_p.h,v rcsdiff -q -kk '-r1.25' '-r1.26' -u '/v/ossp/cvs/ossp-pkg/l2/l2_p.h,v' 2>/dev/null --- l2_p.h 2001/11/03 22:51:36 1.25 +++ l2_p.h 2001/11/04 13:21:17 1.26 @@ -76,37 +76,31 @@ } l2_chstate_t; struct l2_channel_st { + l2_env_t *env; l2_chstate_t state; l2_channel_t *parent; l2_channel_t *sibling; l2_channel_t *child; l2_context_t context; l2_handler_t handler; - char szError[1024]; - char szErrorInfo[512]; - l2_result_t rvErrorInfo; unsigned int levelmask; unsigned int flushmask; }; typedef struct { - l2_channel_t *ch; - unsigned int levelmask; - unsigned int flushmask; -} l2_channel_entry_t; - -typedef struct { l2_formatter_t cb; void *ctx; char id; } l2_formatter_entry_t; -struct l2_stream_st { +struct l2_env_st { unsigned int levelmask; unsigned int flushmask; - char message[L2_MAX_MSGSIZE]; - l2_channel_entry_t channels[L2_MAX_CHANNELS]; l2_formatter_entry_t formatters[L2_MAX_FORMATTERS]; + char message[L2_MAX_MSGSIZE]; + char szError[1024]; + char szErrorInfo[512]; + l2_result_t rvErrorInfo; }; /* variable argument handling taking care on argument passing conventions */ Index: ossp-pkg/l2/l2_stream.c RCS File: /v/ossp/cvs/ossp-pkg/l2/Attic/l2_stream.c,v co -q -kk -p'1.21' '/v/ossp/cvs/ossp-pkg/l2/Attic/l2_stream.c,v' | diff -u - /dev/null -L'ossp-pkg/l2/l2_stream.c' 2>/dev/null --- ossp-pkg/l2/l2_stream.c +++ /dev/null 2024-04-26 22:55:00.000000000 +0200 @@ -1,278 +0,0 @@ -/* -** L2 - OSSP Logging Library -** Copyright (c) 2001 The OSSP Project (http://www.ossp.org/) -** Copyright (c) 2001 Cable & Wireless Deutschland (http://www.cw.com/de/) -** -** This file is part of OSSP L2, a flexible logging library which -** can be found at http://www.ossp.org/pkg/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.c: internal C implementation -** -*/ - -#include "l2.h" -#include "l2_p.h" - -/* create stream */ -l2_stream_t *l2_stream_create(void) -{ - l2_stream_t *st; - int i; - - /* allocate stream structure */ - if ((st = (l2_stream_t *)malloc(sizeof(l2_stream_t))) == NULL) - return NULL; - - /* initialize stream structure */ - st->levelmask = 0; - st->flushmask = 0; - for (i = 0; i < L2_MAX_CHANNELS; i++) - st->channels[i].ch = NULL; - for (i = 0; i < L2_MAX_FORMATTERS; i++) - st->formatters[i].cb = NULL; - - return st; -} - -/* attach channel to stream */ -l2_result_t l2_stream_channel(l2_stream_t *st, l2_channel_t *ch, unsigned int levelmask, unsigned int flushmask) -{ -#if 0 - l2_channel_t *chC; - l2_channel_t *chN; - l2_chtype_t t; -#endif - int i; - - /* argument sanity check */ - if (st == NULL || ch == NULL || levelmask == 0) - return L2_ERR_ARG; - - /* make sure the stack of channels consists of zero or more - filter channels followed by exactly one output channel */ -#if 0 - for (chC = ch; (chN = l2_channel_downstream(chC)) != NULL; chC = chN) - if (l2_channel_type(chC, &t) == L2_OK && t != L2_CHANNEL_FILTER) - return L2_ERR_USE; - if (l2_channel_type(chC, &t) == L2_OK && t != L2_CHANNEL_OUTPUT) - return L2_ERR_USE; -#endif - - /* find next free channel position in channel array */ - for (i = 0; i < L2_MAX_CHANNELS && st->channels[i].ch != NULL; i++) - ; - if (i == L2_MAX_CHANNELS) - return L2_ERR_MEM; - - /* attach channel to stream */ - st->channels[i].ch = ch; - st->channels[i].levelmask = levelmask; - st->channels[i].flushmask = flushmask; - - return L2_OK; -} - -/* attach formatter to stream */ -l2_result_t l2_stream_formatter(l2_stream_t *st, char id, l2_formatter_t cb, l2_context_t *ctx) -{ - int i; - - /* argument sanity check */ - if (st == NULL || id == '\0' || cb == NULL) - return L2_ERR_ARG; - - /* find next free formatter position in formatter array */ - for (i = 0; i < L2_MAX_FORMATTERS && st->formatters[i].cb != NULL; i++) - ; - if (i == L2_MAX_FORMATTERS) - return L2_ERR_MEM; - - /* attach formatter to stream */ - st->formatters[i].id = id; - st->formatters[i].ctx = ctx; - st->formatters[i].cb = cb; - - return L2_OK; -} - -/* set stream level mask */ -l2_result_t l2_stream_levels(l2_stream_t *st, unsigned int levelmask, unsigned int flushmask) -{ - /* argument sanity check */ - if (st == NULL) - return L2_ERR_ARG; - - /* override global level mask */ - st->levelmask = levelmask; - st->flushmask = flushmask; - - return L2_OK; -} - -/* log a message to stream */ -l2_result_t l2_stream_log(l2_stream_t *st, l2_level_t level, const char *fmt, ...) -{ - va_list ap; - l2_result_t rv; - - /* pass-through to va_list-based variant */ - va_start(ap, fmt); - rv = l2_stream_vlog(st, level, fmt, ap); - va_end(ap); - - return rv; -} - -/* indirect callback function from l2_stream_vlog for flushing */ -static int l2_stream_vlog_flush(l2_util_format_t *vfmt) -{ - /* we do no format buffer flushing */ - return -1; -} - -/* indirect callback function from l2_stream_vlog for formatting */ -static void l2_stream_vlog_format( - l2_util_format_t *vfmt, - char *cPrefix, char *cPad, char **cppOut, size_t *npOutLen, - char *cpBuf, int nBufLenMax, char *cpParam, char cId, va_list *apArgs) -{ - l2_stream_t *st = (l2_stream_t *)(vfmt->data[0].vp); - l2_result_t rv; - int i; - - /* init formatting result */ - *cPrefix = '\0'; - *cPad = ' '; - *cppOut = NULL; - *npOutLen = 0; - - /* iterate over all configured L2 formatters */ - for (i = 0; i < L2_MAX_FORMATTERS && st->formatters[i].cb != NULL; i++) { - if (st->formatters[i].id == cId) { - rv = st->formatters[i].cb(st->formatters[i].ctx, cId, cpParam, - cpBuf, nBufLenMax, npOutLen, apArgs); - vfmt->data[1].i = (int)rv; - if (rv == L2_OK) { - *cppOut = cpBuf; - break; - } - } - } - return; -} - -/* log a message to stream (va_list-variant) */ -l2_result_t l2_stream_vlog(l2_stream_t *st, l2_level_t level, const char *fmt, va_list ap) -{ - int i; - int l, j; - size_t len; - l2_result_t rv; - l2_util_format_t vfmt; - - /* argument sanity check */ - if (st == NULL || level == 0 || fmt == NULL || ap == NULL) - return L2_ERR_ARG; - - /* make sure only a single level is specified */ - for (l = level, j = 0; l != 0; l = (l >> 1)) - if (l & 0x1) - j++; - if (j != 1) - return L2_ERR_ARG; - - /* check whether global level mask already stops processing */ - if (!(st->levelmask & level)) - return L2_OK; - - /* format message */ - vfmt.curpos = st->message; - vfmt.endpos = st->message + L2_MAX_MSGSIZE; - vfmt.data[0].vp = st; - vfmt.data[1].i = L2_ERR_FMT; - vfmt.flush = l2_stream_vlog_flush; - vfmt.format = l2_stream_vlog_format; - if ((len = l2_util_format(&vfmt, fmt, ap)) == -1) - return (l2_result_t)(vfmt.data[1].i); - if (len == 0) - return L2_ERR_FMT; - - /* make sure a trailing newline exists */ - if (st->message[len-1] != '\n') { - if (len == L2_MAX_MSGSIZE) - return L2_ERR_MEM; - st->message[len++] = '\n'; - st->message[len] = '\0'; - } - - /* write message to zero or more channels */ - rv = L2_OK; - for (i = 0; i < L2_MAX_CHANNELS && st->channels[i].ch != NULL; i++) { - if (st->channels[i].levelmask & level) { - if ((rv = l2_channel_write(st->channels[i].ch, level, st->message, len)) != L2_OK) - break; - if ((st->flushmask & level) || (st->channels[i].flushmask & level)) - if ((rv = l2_channel_flush(st->channels[i].ch)) != L2_OK) - break; - } - } - return rv; -} - -/* flush stream */ -l2_result_t l2_stream_flush(l2_stream_t *st) -{ - int i; - l2_result_t rv; - - /* argument sanity check */ - if (st == NULL) - return L2_ERR_ARG; - - /* flush all attached channels */ - for (i = 0; i < L2_MAX_CHANNELS && st->channels[i].ch != NULL; i++) - if ((rv = l2_channel_flush(st->channels[i].ch)) != L2_OK) - return rv; - - return L2_OK; -} - -/* destroy stream */ -l2_result_t l2_stream_destroy(l2_stream_t *st) -{ - int i; - l2_result_t rv; - - /* argument sanity check */ - if (st == NULL) - return L2_ERR_ARG; - - /* destroy all attached channels */ - for (i = 0; i < L2_MAX_CHANNELS && st->channels[i].ch != NULL; i++) - if ((rv = l2_channel_destroy(st->channels[i].ch)) != L2_OK) - return rv; - - /* free stream structure */ - free(st); - - return L2_OK; -} - Index: ossp-pkg/l2/l2_test.c RCS File: /v/ossp/cvs/ossp-pkg/l2/l2_test.c,v rcsdiff -q -kk '-r1.37' '-r1.38' -u '/v/ossp/cvs/ossp-pkg/l2/l2_test.c,v' 2>/dev/null --- l2_test.c 2001/11/03 22:51:36 1.37 +++ l2_test.c 2001/11/04 13:21:17 1.38 @@ -57,182 +57,88 @@ int main(int argc, char *argv[]) { - l2_channel_t *chFilt; + l2_channel_t *chFilter; l2_channel_t *chPrefix; - l2_channel_t *chBuf; + l2_channel_t *chBuffer; l2_channel_t *chFile; -#ifdef WITH_SYSLOG l2_channel_t *chSyslog; -#endif -#ifdef WITH_PIPE - l2_channel_t *chPipe; -#endif -#ifdef WITH_SOCKET - l2_channel_t *chSock; -#endif -#ifdef WITH_IRC - l2_channel_t *chIrc; -#endif -#ifdef WITH_SMTP l2_channel_t *chSmtp; -#endif - l2_stream_t *st; + l2_env_t *env; - /* - * Typical steps to use a buffered file logging stream - */ - if ((st = l2_stream_create()) == NULL) - die("failed to create stream"); + /* create environment */ + if ((l2_env_create(&env)) != L2_OK) + die("failed to create environment"); + if (l2_env_formatter(env, 'k', formatter, NULL) != L2_OK) + die("failed to configure formatter for %%x"); + if (l2_env_formatter(env, 'S', l2_util_fmt_dump, NULL) != L2_OK) + die("failed to configure formatter for %%S"); - if ((chPrefix = l2_channel_create(&l2_handler_prefix)) == NULL) /* Prefix */ + /* create prefix channel */ + if ((l2_channel_create(&chPrefix, env, &l2_handler_prefix)) != L2_OK) die("failed to create prefix channel"); - - if (l2_channel_configure(chPrefix, "prefix,timezone", "[%d-%m-%Y/%H:%M:%S] %L test[%P]: ", "local") != L2_OK) + if (l2_channel_configure(chPrefix, "prefix,timezone", + "[%d-%m-%Y/%H:%M:%S] %L test[%P]: ", "local") != L2_OK) die("failed to configure prefix channel"); - if ((chFilt = l2_channel_create(&l2_handler_filter)) == NULL) /* Filter */ + /* create prefix channel */ + if ((l2_channel_create(&chFilter, env, &l2_handler_filter)) != L2_OK) die("failed to create filter channel"); - - if (l2_channel_configure(chFilt, "regex,negate", "hecking", 0) != L2_OK) + if (l2_channel_configure(chFilter, "regex,negate", "hecking", 0) != L2_OK) die("failed to configure filter channel"); - if ((chBuf = l2_channel_create(&l2_handler_buffer)) == NULL) /* Buffer */ + /* create buffer channel */ + if ((l2_channel_create(&chBuffer, env, &l2_handler_buffer)) != L2_OK) die("failed to create buffer channel"); - - if (l2_channel_configure(chBuf, "size", 800) != L2_OK) + if (l2_channel_configure(chBuffer, "size", 800) != L2_OK) die("failed to configure buffer channel"); - if ((chFile = l2_channel_create(&l2_handler_file)) == NULL) /* File */ + /* create file channel */ + if ((l2_channel_create(&chFile, env, &l2_handler_file)) != L2_OK) die("failed to create file channel"); - if (l2_channel_configure(chFile, "path,append,perm", "l2_test.log", TRUE, 0644) != L2_OK) die("failed to configure file channel"); + if (l2_channel_levels(chFile, L2_LEVEL_UPTO(L2_LEVEL_INFO), L2_LEVEL_NONE) != L2_OK) + die("failed to level of smtp channel"); - if (l2_channel_stack(chFile, chBuf) != L2_OK) - die("failed to stack buffer channel on top of file channel"); - - if (l2_channel_stack(chBuf, chPrefix) != L2_OK) - die("failed to stack prefix channel on top of buffer channel"); - - if (l2_channel_stack(chPrefix, chFilt) != L2_OK) - die("failed to stack filter channel on top of prefix channel"); - - if (l2_channel_open(chFilt) != L2_OK) - die("failed to open channel stack"); - - if (l2_stream_channel(st, chFilt, L2_LEVEL_UPTO(L2_LEVEL_WARNING), L2_LEVEL_NONE) != L2_OK) - die("failed to attach channel stack into stream"); - -#ifdef WITH_SYSLOG - if ((chSyslog = l2_channel_create(&l2_handler_syslog)) == NULL) /* Syslog */ + /* create syslog channel */ + if ((l2_channel_create(&chSyslog, env, &l2_handler_syslog)) != L2_OK) die("failed to create syslog channel"); - if (l2_channel_configure(chSyslog, "ident,facility,target,remotehost,logpid", - "L2-Test", "user", "remote", "en1", 1) != L2_OK) + "L2-Test", "user", "remote", "en1", 1) != L2_OK) die("failed to configure syslog channel"); + if (l2_channel_levels(chSyslog, L2_LEVEL_UPTO(L2_LEVEL_ERROR), L2_LEVEL_ALL) != L2_OK) + die("failed to level of syslog channel"); - if (l2_channel_open(chSyslog) != L2_OK) - die("failed to open channel stack"); - - if (l2_stream_channel(st, chSyslog, L2_LEVEL_UPTO(L2_LEVEL_WARNING), L2_LEVEL_NONE) != L2_OK) - die("failed to attach channel syslog into stream"); -#endif /* Syslog */ - -#ifdef WITH_PIPE - if ((chPipe = l2_channel_create(&l2_handler_pipe)) == NULL) /* Pipe */ - die("failed to create pipe channel"); - -#if 0 - if (l2_channel_configure(chPipe, "mode,path", "direct", "/u/ms/travail/cronolinux/sbin/cronolog -o /u/ms/tmp/crono.log") != L2_OK) - die("failed to configure pipe channel"); -#endif - - if (l2_channel_configure(chPipe, "execmode,path", "shell", "$CRONOLOGDIR/cronolog -o $HOME/tmp/crono.log") != L2_OK) - die("failed to configure pipe channel due to mode and path parameters"); - - if (l2_channel_configure(chPipe, "runtime", "continuous") != L2_OK) - die("failed to configure pipe channel due to continuous parameter"); - - if (l2_channel_open(chPipe) != L2_OK) - die("failed to open pipe channel"); - - if (l2_stream_channel(st, chPipe, L2_LEVEL_UPTO(L2_LEVEL_WARNING), L2_LEVEL_NONE) != L2_OK) - die("failed to attach channel pipe into stream"); -#endif /* Pipe */ - -#ifdef WITH_IRC - /* Atenzione! Before testing IRC start the IRC server. */ - if ((chIrc = l2_channel_create(&l2_handler_irc)) == NULL) /* IRC */ - die("failed to create IRC channel"); - - if (l2_channel_configure(chIrc) != L2_OK) - die("failed to configure IRC channel"); - - if (l2_channel_open(chIrc) != L2_OK) - die("failed to open IRC channel"); - - if (l2_stream_channel(st, chIrc, L2_LEVEL_UPTO(L2_LEVEL_WARNING), L2_LEVEL_NONE) != L2_OK) - die("failed to attach channel IRC into stream"); -#endif /* IRC */ - -#ifdef WITH_SOCKET - /* Atenzione! Before doing any socket testing, make sure you have a valid */ - /* end point listening, or else you will only get an error message when */ - /* the thing tries to connect. */ - if ((chSock = l2_channel_create(&l2_handler_socket)) == NULL) /* Socket */ - die("failed to create socket channel"); - - if (l2_channel_configure(chSock, "proto,host,port",\ - "tcp", "localhost", 2002) != L2_OK) - die("failed to configure socket tcp/ipv4 channel"); -#if 0 - if (l2_channel_configure(chSock, "proto,host,port",\ - "tcp", "0:0:0:0:0:0:0:1", 2002) != L2_OK) - die("failed to configure socket tcp/ipv6 channel"); -#endif - if (l2_channel_open(chSock) != L2_OK) - die("failed to open socket channel"); - - if (l2_stream_channel(st, chSock, L2_LEVEL_UPTO(L2_LEVEL_WARNING), L2_LEVEL_NONE) != L2_OK) - die("failed to attach channel socket into stream"); -#endif /* Socket */ - -#ifdef WITH_SMTP - if ((chSmtp = l2_channel_create(&l2_handler_smtp)) == NULL) /* SMTP */ + /* create smtp channel */ + if ((l2_channel_create(&chSmtp, env, &l2_handler_smtp)) != L2_OK) die("failed to create smtp channel"); - if (l2_channel_configure(chSmtp, "rcpt,host,port", "rse@engelschall.com", "en1", "25") != L2_OK) die("failed to configure smtp channel"); + if (l2_channel_levels(chSmtp, L2_LEVEL_UPTO(L2_LEVEL_PANIC), L2_LEVEL_ALL) != L2_OK) + die("failed to level of smtp channel"); - if (l2_channel_open(chSmtp) != L2_OK) - die("failed to open smtp channel"); - - if (l2_stream_channel(st, chSmtp, L2_LEVEL_UPTO(L2_LEVEL_ERROR), L2_LEVEL_NONE) != L2_OK) - die("failed to attach smtp channel into stream"); -#endif /* SMTP */ - - if (l2_stream_levels(st, L2_LEVEL_UPTO(L2_LEVEL_WARNING), L2_LEVEL_NONE) != L2_OK) - die("failed to set global logging level"); + /* build channel tree */ + if (l2_channel_link(chFilter, L2_LINK_CHILDS, chPrefix, chBuffer, chFile, NULL) != L2_OK) + die("failed to link channels together as a child sequence"); + if (l2_channel_link(chFilter, L2_LINK_SIBLINGS, chSyslog, NULL) != L2_OK) + die("failed to link filter channel on top of syslog channel"); + + /* open channel tree */ + if (l2_channel_open(chFilter) != L2_OK) + die("failed to open channel tree"); - if (l2_stream_formatter(st, 'k', formatter, NULL) != L2_OK) - die("failed to configure formatter for %%x"); - - if (l2_stream_formatter(st, 'S', l2_util_fmt_dump, NULL) != L2_OK) - die("failed to configure formatter for %%S"); - - if (l2_stream_log(st, L2_LEVEL_PANIC, "0Checking localhost %s %{myparm}k <%{text}S><%{hex}S><%{base64}S>\n", "foo", 12345, "foo\1bar", 7, "foo\1bar", 7, "foo\1bar", 7) != L2_OK) - die("failed to log message to stream"); - - if (l2_stream_log(st, L2_LEVEL_PANIC, "1Shecking\n") != L2_OK) - die("failed to log message to stream"); - - if (l2_stream_log(st, L2_LEVEL_PANIC, "2Checking localhost %s %{myparm}k <%{text}S><%{hex}S><%{base64}S>\n", "foo", 12345, "foo\1bar", 7, "foo\1bar", 7, "foo\1bar", 7) != L2_OK) - die("failed to log message to stream"); - - if (l2_stream_log(st, L2_LEVEL_PANIC, "3Shecking\n") != L2_OK) - die("failed to log message to stream"); + /* perform a few log operations */ + if (l2_channel_log(chFilter, L2_LEVEL_PANIC, "1: Checking localhost %s %{myparm}k <%{text}S><%{hex}S><%{base64}S>\n", "foo", 12345, "foo\1bar", 7, "foo\1bar", 7, "foo\1bar", 7) != L2_OK) + die("failed to log message #1 to channel"); + if (l2_channel_log(chFilter, L2_LEVEL_PANIC, "2: Shecking\n") != L2_OK) + die("failed to log message #2 to channel"); + if (l2_channel_log(chFilter, L2_LEVEL_PANIC, "3: Checking localhost %s %{myparm}k <%{text}S><%{hex}S><%{base64}S>\n", "foo", 12345, "foo\1bar", 7, "foo\1bar", 7, "foo\1bar", 7) != L2_OK) + die("failed to log message #3 to channel"); + if (l2_channel_log(chFilter, L2_LEVEL_PANIC, "4: Shecking\n") != L2_OK) + die("failed to log message #4 to channel"); - if (l2_stream_destroy(st) != L2_OK) + /* destroy channel tree */ + if (l2_channel_destroy(chFilter) != L2_OK) die("failed to destroy stream"); return 0;