OSSP CVS Repository

ossp - Check-in [1248]
Not logged in
[Honeypot]  [Browse]  [Home]  [Login]  [Reports
[Search]  [Ticket]  [Timeline
  [Patchset]  [Tagging/Branching

Check-in Number: 1248
Date: 2001-Nov-04 14:21:17 (local)
2001-Nov-04 13:21:17 (UTC)
User:rse
Branch:
Comment: 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....

Tickets:
Inspections:
Files:
ossp-pkg/l2/Makefile.in      1.26 -> 1.27     4 inserted, 3 deleted
ossp-pkg/l2/TODO      1.35 -> 1.36     5 inserted, 0 deleted
ossp-pkg/l2/l2.h.in      1.14 -> 1.15     37 inserted, 24 deleted
ossp-pkg/l2/l2_ch_filter.c      1.11 -> 1.12     5 inserted, 2 deleted
ossp-pkg/l2/l2_channel.c      1.21 -> 1.22     197 inserted, 77 deleted
ossp-pkg/l2/l2_env.c      added-> 1.1
ossp-pkg/l2/l2_p.h      1.25 -> 1.26     6 inserted, 12 deleted
ossp-pkg/l2/l2_stream.c      1.21->removed
ossp-pkg/l2/l2_test.c      1.37 -> 1.38     53 inserted, 147 deleted

ossp-pkg/l2/Makefile.in 1.26 -> 1.27

--- 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


ossp-pkg/l2/TODO 1.35 -> 1.36

--- 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 ;)


ossp-pkg/l2/l2.h.in 1.14 -> 1.15

--- 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__ */
 


ossp-pkg/l2/l2_ch_filter.c 1.11 -> 1.12

--- 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;
         }
     }


ossp-pkg/l2/l2_channel.c 1.21 -> 1.22

--- 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;
 }
 


ossp-pkg/l2/l2_env.c -> 1.1

*** /dev/null    Tue Mar 19 03:47:24 2024
--- -    Tue Mar 19 03:48:17 2024
***************
*** 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;
+ }
+ 


ossp-pkg/l2/l2_p.h 1.25 -> 1.26

--- 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 */


ossp-pkg/l2/l2_stream.c 1.21 -> 1.22



ossp-pkg/l2/l2_test.c 1.37 -> 1.38

--- 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;

CVSTrac 2.0.1