OSSP CVS Repository

ossp - Difference in ossp-pkg/lmtp2nntp/lmtp2nntp_config.c versions 1.50 and 1.51
Not logged in
[Honeypot]  [Browse]  [Home]  [Login]  [Reports
[Search]  [Ticket]  [Timeline
  [History

ossp-pkg/lmtp2nntp/lmtp2nntp_config.c 1.50 -> 1.51

--- lmtp2nntp_config.c   2002/02/14 15:11:08     1.50
+++ lmtp2nntp_config.c   2002/02/20 15:42:26     1.51
@@ -39,6 +39,7 @@
 #include "pcre.h"
 #include "popt.h"
 #include "str.h"
+#include "var.h"
 #include "val.h"
 
 /* library version check (compile-time) */
@@ -103,6 +104,8 @@
     return L2_OK;
 }
 
+static void headersimulation(lmtp2nntp_t *); //FIXME
+
 void config_context(lmtp2nntp_t *ctx)
 {
     ex_t ex;
@@ -539,6 +542,8 @@
             char *cpVal;
             headerrule_t *hrI;
             headerrule_t *hrP;
+            const char *cpError;
+            int iError;
 
             if (   (val_get(ctx->val, "option.headerrule", &ov) != VAL_OK)
                 || (ov->ndata <  0)
@@ -554,8 +559,10 @@
                     log2(ctx, DEBUG, "cp = (data.m)[%d] = \"%s\"", i, cp);
 
                     hrNew = (headerrule_t *)mallocex(sizeof(headerrule_t));
-                    hrNew->next   = NULL;
-                    hrNew->carve  = NULL; // initialize variables which might have resources allocated that need to be cleaned up when an exception is caught
+                    hrNew->next      = NULL;
+                    hrNew->carve     = NULL;
+                    hrNew->pcreRegex = NULL;
+                    hrNew->pcreExtra = NULL;
                     
                     cp = hrNew->carve = strdupex(cp);
                     /* priority */
@@ -600,8 +607,21 @@
                     hrNew->header = cpHeader;
                     hrNew->val    = cpVal;
 
+                    if (cpRegex != NULL) {
+                        /* compile regular expression into finite state machine and optimize */
+                        if ((hrNew->pcreRegex = pcre_compile(cpRegex, PCRE_CASELESS, &cpError, &iError, NULL)) == NULL) {
+                            log3(ctx, ERROR, "option --headerrule, regex (%s) failed at pos %d with %s", cpRegex, iError, cpError);
+                            throw(0,0,0);
+                        }
+                        hrNew->pcreExtra = pcre_study(hrNew->pcreRegex, 0, &cpError);
+                        if (cpError != NULL) {
+                            log1(ctx, ERROR, "option --headerrule, regex optimization failed with %s", cpError);
+                            throw(0,0,0);
+                        }
+                    }
+
                     if (ctx->option_firstheaderrule == NULL)
-                        ctx->option_firstheaderrule = (headerrule_t *)hrNew; // interesting point since hrNew is declared volatile we have to cast it. This makes me unhappy as it enlarges the code which is far from the spirit of lib_ex
+                        ctx->option_firstheaderrule = (headerrule_t *)hrNew; /* first */
                     else {
                         for (hrP = NULL, hrI = ctx->option_firstheaderrule;
                              hrI != NULL && hrI->pri <= hrNew->pri;
@@ -611,23 +631,20 @@
                         if (hrP != NULL)
                             hrP->next = (headerrule_t *)hrNew; /* append */
                         else
-                            ctx->option_firstheaderrule = (headerrule_t *)hrNew; /* newfirst */
+                            ctx->option_firstheaderrule = (headerrule_t *)hrNew; /* new first */
                     }
-                    /* after linking the structure into a parental-controlled structure we
-                       expect that the parental cleanup will handle normal and exceptional
-                       resource releasing and therefore we *must* reset this variable initialization
-                       to avoid accidental local cleanup! In fact, this code will fail if the
-                       next statement is omitted.
-                     */
-                    hrNew = NULL; // initialize variables which might have resources allocated that need to be cleaned up when an exception is caught
-
+                    hrNew = NULL; /* release cleanup responsibility */
                 }
             }
         }
-        cleanup { // make sure the conditional variables are *always* proper initialized and cleared volatile
+        cleanup {
             if (hrNew != NULL) {
                 if (hrNew->carve != NULL)
                     freeex(hrNew->carve);
+                if (hrNew->pcreRegex != NULL)
+                    free(hrNew->pcreRegex);
+                if (hrNew->pcreExtra != NULL)
+                    free(hrNew->pcreExtra);
                 freeex((headerrule_t *)hrNew);
             }
         }
@@ -1004,6 +1021,8 @@
     catch (ex)
         rethrow;
 
+    headersimulation(ctx); //FIXME
+
 //void testpcre(void)
 {
     char       *szRegex;
@@ -1077,3 +1096,307 @@
 CUS:
     return;
 }
+
+
+
+static void headerdestroy(headerdata_t *hdC)
+{
+    int i;
+
+    if (hdC->ndata > 1) {
+        for (i = 0; i < hdC->ndata; i++) {
+            if (hdC->data.m[i] == NULL)
+                break;
+            free(hdC->data.m[i]);
+        }
+        free (hdC->data.m);
+    } else
+    if (hdC->ndata == 1)
+        if (hdC->data.s != NULL)
+            free(hdC->data.s);
+    if (hdC->name != NULL)
+        free(hdC->name);
+    if (hdC->prev != NULL && hdC->prev->next == hdC)
+        return; //FIXME still linked, cannot be destroyed
+    if (hdC->next != NULL && hdC->next->prev == hdC)
+        return; //FIXME still linked, cannot be destroyed
+    free(hdC);
+}
+
+static void headerdelete(headerdata_t *hdC)
+{
+    if (hdC->prev != NULL)
+        hdC->prev->next = hdC->next;
+    hdC->next = NULL;
+    if (hdC->next != NULL)
+        hdC->next->prev = hdC->prev;
+    hdC->prev = NULL;
+    headerdestroy(hdC);
+}
+
+static void headerreplace(headerdata_t *hdC, headerdata_t *hdNew)
+{
+    hdNew->prev = hdC->prev;
+    hdC->prev = NULL;
+    hdNew->next = hdC->next;
+    hdC->next = NULL;
+    headerdestroy(hdC);
+}
+
+static headerdata_t *headercreate(void)
+{
+    ex_t ex;
+    volatile headerdata_t *hdNew = NULL;
+    try {
+        hdNew = mallocex(sizeof(headerdata_t));
+        hdNew->prev  = NULL;
+        hdNew->next  = NULL;
+        hdNew->name  = NULL;
+        hdNew->ndata = 0;
+    }
+    catch (ex) {
+        if (hdNew != NULL)
+            free((headerdata_t *)hdNew);
+        rethrow;
+    }
+    return (headerdata_t *)hdNew;
+}
+#if 0
+//headermatrix()
+{
+    volatile header_t *hNew = NULL;
+    try {
+        char *cp;
+
+        cp = NULL;
+        while ((cp = argz_next(ctx->msg->azHeaders, ctx->msg->asHeaders, cp)) != NULL) {
+            hNew = mallocex(sizeof(header_t));
+            //FIXME
+        }
+    }
+    cleanup {
+        if (hNew != NULL)
+            free(hNew);
+    }
+    catch(ex) {
+        rethrow;
+    }
+}
+#endif
+
+static var_config_t ctx_lookup_cfg = {
+    '$',          /* varinit       */ 
+    '{',          /* startdelim    */ 
+    '}',          /* enddelim      */ 
+    '[',          /* startindex    */ 
+    ']',          /* endindex      */ 
+    '#',          /* current_index */ 
+    '\\',         /* escape        */ 
+    "a-zA-Z0-9_.-" /* namechars     */ 
+};
+
+static var_rc_t ctx_lookup(
+    void *_ctx, 
+    const char *var_ptr, size_t var_len, int var_idx,
+    const char **val_ptr, size_t *val_len, size_t *val_size)
+{
+    lmtp2nntp_t *ctx = (lmtp2nntp_t *)_ctx;
+    /*FIXME
+    const char *name;
+    size_t len;
+    char *cp;
+    */
+    var_rc_t rc;
+
+    log2(ctx, DEBUG, "lookup variable \"%s\" (%d)", var_ptr, var_len);
+    rc = VAR_ERR_UNDEFINED_VARIABLE;
+    if (strncasecmp(var_ptr, "test", var_len) == 0) {
+    }
+    else if (strncasecmp(var_ptr, "xyz", var_len) == 0) {
+        *val_ptr = "Hello, World!";
+        *val_len = strlen("Hello, World!");
+        *val_size = 0;
+        rc = VAR_OK;
+    }
+    if (rc == VAR_OK)
+        log4(ctx, DEBUG, "lookup variable \"%s\" (%d) ok: result is \"%s\" (%d)", var_ptr, var_len, *val_ptr, *val_len);
+    else
+        log3(ctx, DEBUG, "lookup variable \"%s\" (%d) failed: %s", var_ptr, var_len, var_strerror(rc));
+    return rc;
+}
+
+static void headerrewrite(lmtp2nntp_t *ctx)
+{
+    headerrule_t *hrI;
+    headerdata_t *hdI, *hdNew;
+    /*
+    char *cp;
+    int i;
+    char *cpPri;
+    char *cpRegex;
+    char *cpHeader;
+    char *cpVal;
+    headerrule_t *hrP;
+    hrNew->pri    = atoi(cpPri);
+    hrNew->regex  = cpRegex;
+    hrNew->header = cpHeader;
+    hrNew->val    = cpVal;
+    char       *szRegex;
+    pcre       *pcreRegex;
+    pcre_extra *pcreExtra;
+    const char *szError;
+    int         nErrorOffset;
+    int         opt;
+    char       *buf;
+    int         buf_size;
+#define OVECSIZE 30
+    int         ovec[OVECSIZE];
+    int         i;
+    const char **cpList;
+    */
+    int         ovec[OVECSIZE];
+    int         iCheck;
+
+    { //FIXME debug code block
+        int i;
+
+        log0(ctx, DEBUG, "FIXME trace ---------- headerrewrite() ----------");
+        for (hrI = ctx->option_firstheaderrule; hrI != NULL; hrI = hrI->next)
+            log1(ctx, DEBUG, "hrI->header=%s", hrI->header);
+        for (hdI = ctx->msg->hdFirst; hdI != NULL; hdI = hdI->next) {
+            if (hdI->ndata == 0)
+                log1(ctx, DEBUG, "hdI->name=%s, (NO DATA)", hdI->name);
+            if (hdI->ndata == 1)
+                log2(ctx, DEBUG, "hdI->name=%s, hdI->data.s=%s", hdI->name, hdI->data.s);
+            if (hdI->ndata > 1)
+                for (i = 0; i < hdI->ndata; i++)
+                    log3(ctx, DEBUG, "hdI->name=%s, hdI->data.m[%d]=%s", hdI->name, i, hdI->data.m[i]);
+        }
+    }
+    
+    for (hrI = ctx->option_firstheaderrule; hrI != NULL; hrI = hrI->next) { /* for each rule */
+        //log1(ctx, DEBUG, "FIXME trace loop hrI=%.8lx", hrI);
+        if (hrI->regex != NULL) {
+            log1(ctx, DEBUG, "rule has regex %s", hrI->regex);
+            for (hdI = ctx->msg->hdFirst; hdI != NULL; hdI = hdI->next) { /* for each header */
+                //log2(ctx, DEBUG, "FIXME trace loop hdI=%.8lx, hI->name=\"%s\"", hdI, hdI->name);
+                if (hdI->name == NULL || strlen(hdI->name) == 0)
+                    continue; //FIXME header w/o name cannot happen normally
+                iCheck = pcre_exec(hrI->pcreRegex, hrI->pcreExtra, hdI->name, strlen(hdI->name), 0, 0, ovec, OVECSIZE);
+                log1(ctx, DEBUG, "FIXME trace iCheck=%d", iCheck);
+                if (iCheck >= 1) {
+                    log0(ctx, DEBUG, "regex matches");
+                    hdNew = headercreate();
+                    hdNew->name = strdupex(hrI->header); //FIXME rename ->header to ->name
+                    {
+                    var_rc_t var_rc;
+                    char *res_ptr;
+                    if ((var_rc = var_expand(hrI->val, strlen(hrI->val), &res_ptr, NULL,
+                                             ctx_lookup, ctx, &ctx_lookup_cfg, TRUE)) != VAR_OK) {
+                        log2(ctx, ERROR, "expansion of '%s' failed: %s", hrI->val, var_strerror(var_rc));
+                    }
+                    log2(ctx, ERROR, "expansion of '%s' succeeded: %s", hrI->val, res_ptr);
+                    hdNew->data.s = res_ptr;
+                    hdNew->ndata = 1;
+                    /*FIXME clean up data.m */
+                    headerreplace(hdI, hdNew);
+                    if (hdNew->prev == NULL)
+                        ctx->msg->hdFirst = hdNew;
+                    hdI = hdNew;
+                    }
+                }
+            }
+        }
+        else {
+            log1(ctx, DEBUG, "rule has no regex but static header %s", hrI->header);
+            hdNew = headercreate();
+            hdNew->name = strdupex(hrI->header); //FIXME rename ->header to ->name
+            hdNew->data.s = strdupex(hrI->val);
+            hdNew->ndata = 1;
+            /*FIXME clean up data.m */
+            for (hdI = ctx->msg->hdFirst; hdI != NULL; hdI = hdI->next) { /* for each header */
+                if (hdI->name == NULL || strlen(hdI->name) == 0)
+                    continue; //FIXME header w/o name cannot happen normally
+                log2(ctx, DEBUG, "hrI->header=%s, hdI->name=%s", hrI->header, hdI->name);
+                if (strcmp(hrI->header, hdI->name) == 0)
+                    break;
+            }
+            if (hdI != NULL) {
+                log1(ctx, DEBUG, "replacing header %s", hrI->header);
+                headerreplace(hdI, hdNew);
+                if (hdNew->prev == NULL)
+                    ctx->msg->hdFirst = hdNew;
+            }
+            else {
+                log1(ctx, DEBUG, "appending header %s", hrI->header);
+                for (hdI = ctx->msg->hdFirst; hdI->next != NULL; hdI = hdI->next);
+                hdI->next = hdNew;
+                hdNew->prev = hdI;
+            }
+        }
+    }
+
+    { //FIXME debug code block
+        int i;
+
+        log0(ctx, DEBUG, "FIXME trace ---------- headerrewrite() ---------- FINISH");
+        for (hrI = ctx->option_firstheaderrule; hrI != NULL; hrI = hrI->next)
+            log1(ctx, DEBUG, "hrI->header=%s", hrI->header);
+        for (hdI = ctx->msg->hdFirst; hdI != NULL; hdI = hdI->next) {
+            if (hdI->ndata == 0)
+                log1(ctx, DEBUG, "hdI->name=%s, (NO DATA)", hdI->name);
+            if (hdI->ndata == 1)
+                log2(ctx, DEBUG, "hdI->name=%s, hdI->data.s=%s", hdI->name, hdI->data.s);
+            if (hdI->ndata > 1)
+                for (i = 0; i < hdI->ndata; i++)
+                    log3(ctx, DEBUG, "hdI->name=%s, hdI->data.m[%d]=%s", hdI->name, i, hdI->data.m[i]);
+        }
+    }
+}
+
+static void headersimulation(lmtp2nntp_t *ctx)
+{
+    headerdata_t *hdI, *hdNew;
+
+    ctx->msg = msg_create();
+
+    log0(ctx, DEBUG, "FIXME simulation - GO");
+    char *replyto[4] = { "foo@example.com", "bar@example.com", "quux@example.com", NULL };
+
+    hdNew = headercreate();
+    hdNew->name = "To";
+    hdNew->data.s = "foo@invalid.com";
+    hdNew->ndata = 1;
+    ctx->msg->hdFirst = hdNew;
+    hdI = hdNew;
+
+    hdNew = headercreate();
+    hdNew->name = "Reply-To";
+    hdNew->data.m = replyto;
+    hdNew->ndata = 3;
+    hdI->next = hdNew;
+    hdI = hdNew;
+
+    hdNew = headercreate();
+    hdNew->name = "Subject";
+    hdNew->data.s = "a tiny little test";
+    hdNew->ndata = 1;
+    hdI->next = hdNew;
+    hdI = hdNew;
+
+    hdNew = headercreate();
+    hdNew->name = "Date";
+    hdNew->data.s = "Mon, 18 Feb 2002 09:43:52 +0100";
+    hdNew->ndata = 1;
+    hdI->next = hdNew;
+    hdI = hdNew;
+
+    hdNew = headercreate();
+    hdNew->name = "Message-ID";
+    hdNew->data.s = "<200201172300.AAA29400@procter012.pg-cw.de>";
+    hdNew->ndata = 1;
+    hdI->next = hdNew;
+    hdI = hdNew;
+
+    headerrewrite(ctx);
+}

CVSTrac 2.0.1