+static int tr_meta_data_action_invoke(/* {{{ */
+ tr_meta_data_action_t *act_head,
+ meta_data_t **dest) {
+ int status;
+ regmatch_t matches[8] = {[0] = {0}};
+
+ if (act_head == NULL)
+ return (-EINVAL);
+
+ if ((*dest) == NULL) /* nothing to do */
+ return (0);
+
+ for (tr_meta_data_action_t *act = act_head; act != NULL; act = act->next) {
+ char temp[DATA_MAX_NAME_LEN];
+ char *subst_status;
+ int value_type;
+ int meta_data_status;
+ char *value;
+ meta_data_t *result;
+
+ value_type = meta_data_type(*dest, act->key);
+ if (value_type == 0) /* not found */
+ continue;
+ if (value_type != MD_TYPE_STRING) {
+ WARNING("Target `replace': Attempting replace on metadata key `%s', "
+ "which isn't a string.",
+ act->key);
+ continue;
+ }
+
+ meta_data_status = meta_data_get_string(*dest, act->key, &value);
+ if (meta_data_status != 0) {
+ ERROR("Target `replace': Unable to retrieve metadata value for `%s'.",
+ act->key);
+ return (meta_data_status);
+ }
+
+ DEBUG("target_replace plugin: tr_meta_data_action_invoke: `%s' "
+ "old value = `%s'",
+ act->key, value);
+
+ status = regexec(&act->re, value, STATIC_ARRAY_SIZE(matches), matches,
+ /* flags = */ 0);
+ if (status == REG_NOMATCH) {
+ sfree(value);
+ continue;
+ } else if (status != 0) {
+ char errbuf[1024] = "";
+
+ regerror(status, &act->re, errbuf, sizeof(errbuf));
+ ERROR("Target `replace': Executing a regular expression failed: %s.",
+ errbuf);
+ sfree(value);
+ continue;
+ }
+
+ if (act->replacement == NULL) {
+ /* no replacement; delete the key */
+ DEBUG("target_replace plugin: tr_meta_data_action_invoke: "
+ "deleting `%s'",
+ act->key);
+ meta_data_delete(*dest, act->key);
+ sfree(value);
+ continue;
+ }
+
+ subst_status = subst(temp, sizeof(temp), value, (size_t)matches[0].rm_so,
+ (size_t)matches[0].rm_eo, act->replacement);
+ if (subst_status == NULL) {
+ ERROR("Target `replace': subst (value = %s, start = %zu, end = %zu, "
+ "replacement = %s) failed.",
+ value, (size_t)matches[0].rm_so, (size_t)matches[0].rm_eo,
+ act->replacement);
+ sfree(value);
+ continue;
+ }
+
+ DEBUG("target_replace plugin: tr_meta_data_action_invoke: `%s' "
+ "value `%s' -> `%s'",
+ act->key, value, temp);
+
+ if ((result = meta_data_create()) == NULL) {
+ ERROR("Target `replace': failed to create metadata for `%s'.", act->key);
+ sfree(value);
+ return (-ENOMEM);
+ }
+
+ meta_data_status = meta_data_add_string(result, act->key, temp);
+ if (meta_data_status != 0) {
+ ERROR("Target `replace': Unable to set metadata value for `%s'.",
+ act->key);
+ meta_data_destroy(result);
+ sfree(value);
+ return (meta_data_status);
+ }
+
+ meta_data_clone_merge(dest, result);
+ meta_data_destroy(result);
+ sfree(value);
+ } /* for (act = act_head; act != NULL; act = act->next) */
+
+ return (0);
+} /* }}} int tr_meta_data_action_invoke */
+
+static int tr_destroy(void **user_data) /* {{{ */