Index: ossp-pkg/lmtp2nntp/fixme.h RCS File: /v/ossp/cvs/ossp-pkg/lmtp2nntp/Attic/fixme.h,v rcsdiff -q -kk '-r1.14' '-r1.15' -u '/v/ossp/cvs/ossp-pkg/lmtp2nntp/Attic/fixme.h,v' 2>/dev/null --- fixme.h 2002/02/13 16:25:38 1.14 +++ fixme.h 2002/02/14 11:03:52 1.15 @@ -34,6 +34,7 @@ typedef struct headerrule_st headerrule_t; struct headerrule_st { headerrule_t *next; + char *carve; /* pri, regex, header, val carved out here, so free up only this */ int pri; char *regex; char *header; Index: ossp-pkg/lmtp2nntp/lmtp2nntp_config.c RCS File: /v/ossp/cvs/ossp-pkg/lmtp2nntp/lmtp2nntp_config.c,v rcsdiff -q -kk '-r1.48' '-r1.49' -u '/v/ossp/cvs/ossp-pkg/lmtp2nntp/lmtp2nntp_config.c,v' 2>/dev/null --- lmtp2nntp_config.c 2002/02/13 16:25:38 1.48 +++ lmtp2nntp_config.c 2002/02/14 11:03:52 1.49 @@ -527,82 +527,112 @@ rethrow; /* --headerrule MULTI */ - try { - char *cp; - int i; - char *cpPri; - char *cpRegex; - char *cpHeader; - char *cpVal; - headerrule_t *hrNew; - headerrule_t *hrI; - headerrule_t *hrP; - - if ( (val_get(ctx->val, "option.headerrule", &ov) != VAL_OK) - || (ov->ndata < 0) - || (ov->ndata >= 1 && ov->data.m == NULL) - ) throw(0,0,0); - log1(ctx, DEBUG, "ov->ndata = %d", ov->ndata); - for (i = 0; i < ov->ndata; i++) - log2(ctx, TRACE, "--headerule[%d] = \"%s\"", i, (ov->data.m)[i]); - - if (ov->ndata >= 1) { - for (i = 0; i < ov->ndata; i++) { - cp = (ov->data.m)[i]; - log2(ctx, DEBUG, "cp = (data.m)[%d] = \"%s\"", i, cp); - cp = strdup(cp); //FIXME - /* priority */ - cpPri = cp; - if ((cp = strchr(cp, ':')) == NULL) { - log1(ctx, ERROR, "option --headerrule, priority (%s) terminating colon missing", (ov->data.m)[i]); - throw(0,0,0); - } - *cp = NUL; - cp++; - /* regex */ - cpRegex = cp; - if ((cp = strchr(cp, ':')) == NULL) { - log1(ctx, ERROR, "option --headerrule, regex (%s) terminating colon missing", (ov->data.m)[i]); - throw(0,0,0); - } - *cp = NUL; - cp++; - /* header */ - cpHeader = cp; - if ((cp = strchr(cp, ':')) == NULL) { - log1(ctx, ERROR, "option --headerrule, header (%s) terminating colon missing", (ov->data.m)[i]); - throw(0,0,0); - } - *cp = NUL; - cp++; - /* value */ - cpVal = cp; - - if ((hrNew = (headerrule_t *)malloc(sizeof(headerrule_t))) == NULL) throw(0,0,0); - hrNew->next = NULL; - hrNew->pri = atoi(cpPri); - hrNew->regex = cpRegex; - hrNew->header = cpHeader; - hrNew->val = cpVal; - - if (ctx->option_firstheaderrule == NULL) - ctx->option_firstheaderrule = hrNew; - else { - for (hrP = NULL, hrI = ctx->option_firstheaderrule; - hrI != NULL && hrI->pri <= hrNew->pri; - hrP = hrI, hrI = hrI->next); - if (hrI != NULL) - hrNew->next = hrI; /* insert */ - if (hrP != NULL) - hrP->next = hrNew; /* append */ - else - ctx->option_firstheaderrule = hrNew; /* newfirst */ + { + volatile headerrule_t *hrNew = NULL; // declare and initialize variables which might have resources allocated that need to be cleaned up when an exception is caught + try { + char *cp; + int i; + char *cpPri; + char *cpRegex; + char *cpHeader; + char *cpVal; + headerrule_t *hrI; + headerrule_t *hrP; + + if ( (val_get(ctx->val, "option.headerrule", &ov) != VAL_OK) + || (ov->ndata < 0) + || (ov->ndata >= 1 && ov->data.m == NULL) + ) throw(0,0,0); + log1(ctx, DEBUG, "ov->ndata = %d", ov->ndata); + for (i = 0; i < ov->ndata; i++) + log2(ctx, TRACE, "--headerule[%d] = \"%s\"", i, (ov->data.m)[i]); + + if (ov->ndata >= 1) { + for (i = 0; i < ov->ndata; i++) { + cp = (ov->data.m)[i]; + 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 + + cp = hrNew->carve = strdupex(cp); + /* priority */ + cpPri = cp; + if ((cp = strchr(cp, ':')) == NULL) { + log1(ctx, ERROR, "option --headerrule, priority (%s) terminating colon missing", (ov->data.m)[i]); + throw(0,0,0); + } + *cp = NUL; + if (strlen(cpPri) == 0) + cpPri = "0"; + cp++; + /* regex */ + cpRegex = cp; + if ((cp = strchr(cp, ':')) == NULL) { + log1(ctx, ERROR, "option --headerrule, regex (%s) terminating colon missing", (ov->data.m)[i]); + throw(0,0,0); + } + *cp = NUL; + if (strlen(cpRegex) == 0) + cpRegex = NULL; + cp++; + /* header */ + cpHeader = cp; + if ((cp = strchr(cp, ':')) == NULL) { + log1(ctx, ERROR, "option --headerrule, header (%s) terminating colon missing", (ov->data.m)[i]); + throw(0,0,0); + } + *cp = NUL; + if (strlen(cpHeader) == 0) { + log1(ctx, ERROR, "option --headerrule, header (%s) missing", (ov->data.m)[i]); + throw(0,0,0); + } + cp++; + /* value */ + cpVal = cp; + if (strlen(cpVal) == 0) + cpVal = NULL; + + hrNew->pri = atoi(cpPri); + hrNew->regex = cpRegex; + hrNew->header = cpHeader; + hrNew->val = cpVal; + + 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 + else { + for (hrP = NULL, hrI = ctx->option_firstheaderrule; + hrI != NULL && hrI->pri <= hrNew->pri; + hrP = hrI, hrI = hrI->next); + if (hrI != NULL) + hrNew->next = hrI; /* insert */ + if (hrP != NULL) + hrP->next = (headerrule_t *)hrNew; /* append */ + else + ctx->option_firstheaderrule = (headerrule_t *)hrNew; /* newfirst */ + } + /* 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 + } } } + cleanup { // make sure the conditional variables are *always* proper initialized and cleared volatile + if (hrNew != NULL) { + if (hrNew->carve != NULL) + freeex(hrNew->carve); + freeex((headerrule_t *)hrNew); + } + } + catch (ex) + rethrow; } - catch (ex) - rethrow; /* --mailfrom SINGLE */ try { Index: ossp-pkg/lmtp2nntp/lmtp2nntp_main.c RCS File: /v/ossp/cvs/ossp-pkg/lmtp2nntp/lmtp2nntp_main.c,v rcsdiff -q -kk '-r1.40' '-r1.41' -u '/v/ossp/cvs/ossp-pkg/lmtp2nntp/lmtp2nntp_main.c,v' 2>/dev/null --- lmtp2nntp_main.c 2002/02/13 16:25:38 1.40 +++ lmtp2nntp_main.c 2002/02/14 11:03:52 1.41 @@ -405,9 +405,9 @@ fprintf(stderr, "DEBUG: los geht's\n"); for (hrI = ctx->option_firstheaderrule; hrI != NULL; hrI = hrI->next) { fprintf(stderr, "DEBUG: cpPri = %d\n", hrI->pri); - fprintf(stderr, "DEBUG: cpRegex = \"%s\"\n", hrI->regex); - fprintf(stderr, "DEBUG: cpHeader = \"%s\"\n", hrI->header); - fprintf(stderr, "DEBUG: cpValue = \"%s\"\n", hrI->val); + fprintf(stderr, "DEBUG: cpRegex = \"%s\"\n", hrI->regex == NULL ? "(NULL)" : hrI->regex); + fprintf(stderr, "DEBUG: cpHeader = \"%s\"\n", hrI->header == NULL ? "(NULL)" : hrI->header); + fprintf(stderr, "DEBUG: cpValue = \"%s\"\n", hrI->val == NULL ? "(NULL)" : hrI->val); } fprintf(stderr, "DEBUG: das war's\n"); }