If targets want to replace the values, they will have to use dynamically
allocated memory. If they can't free the values, because the pointer
might point to statically allocated memory, memory will be lost.
Unfortunately stack allocation will not do, since we will then not be able
to detect multiple replacements.
To impose as little a performance issue as possible, the dynamic allo-
cation is only done when either chain is present. If the filter mecha-
nism is not used, the values will not be copied.
int status;
static c_complain_t no_write_complaint = C_COMPLAIN_INIT_STATIC;
int status;
static c_complain_t no_write_complaint = C_COMPLAIN_INIT_STATIC;
+ value_t *saved_values;
+ int saved_values_len;
+
- if ((vl == NULL) || (*vl->type == '\0')) {
+ if ((vl == NULL) || (vl->type[0] == 0)
+ || (vl->values == NULL) || (vl->values_len < 1))
+ {
ERROR ("plugin_dispatch_values: Invalid value list.");
return (-1);
}
ERROR ("plugin_dispatch_values: Invalid value list.");
return (-1);
}
escape_slashes (vl->type, sizeof (vl->type));
escape_slashes (vl->type_instance, sizeof (vl->type_instance));
escape_slashes (vl->type, sizeof (vl->type));
escape_slashes (vl->type_instance, sizeof (vl->type_instance));
+ /* Copy the values. This way, we can assure `targets' that they get
+ * dynamically allocated values, which they can free and replace if
+ * they like. */
+ if ((pre_cache_chain != NULL) || (post_cache_chain != NULL))
+ {
+ saved_values = vl->values;
+ saved_values_len = vl->values_len;
+
+ vl->values = (value_t *) calloc (vl->values_len,
+ sizeof (*vl->values));
+ if (vl->values == NULL)
+ {
+ ERROR ("plugin_dispatch_values: calloc failed.");
+ vl->values = saved_values;
+ return (-1);
+ }
+ memcpy (vl->values, saved_values,
+ vl->values_len * sizeof (*vl->values));
+ }
+ else /* if ((pre == NULL) && (post == NULL)) */
+ {
+ saved_values = NULL;
+ saved_values_len = 0;
+ }
+
if (pre_cache_chain != NULL)
{
status = fc_process_chain (ds, vl, pre_cache_chain);
if (pre_cache_chain != NULL)
{
status = fc_process_chain (ds, vl, pre_cache_chain);
status, status);
}
else if (status == FC_TARGET_STOP)
status, status);
}
else if (status == FC_TARGET_STOP)
+ {
+ /* Restore the state of the value_list so that plugins
+ * don't get confused.. */
+ if (saved_values != NULL)
+ {
+ free (vl->values);
+ vl->values = saved_values;
+ vl->values_len = saved_values_len;
+ }
}
/* Update the value cache */
}
/* Update the value cache */
else
fc_default_action (ds, vl);
else
fc_default_action (ds, vl);
+ /* Restore the state of the value_list so that plugins don't get
+ * confused.. */
+ if (saved_values != NULL)
+ {
+ free (vl->values);
+ vl->values = saved_values;
+ vl->values_len = saved_values_len;
+ }
+
return (0);
} /* int plugin_dispatch_values */
return (0);
} /* int plugin_dispatch_values */