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