OSSP CVS Repository

ossp - Difference in ossp-pkg/l2/l2_channel.c versions 1.21 and 1.22
Not logged in
[Honeypot]  [Browse]  [Home]  [Login]  [Reports
[Search]  [Ticket]  [Timeline
  [History

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

CVSTrac 2.0.1