From 80c8021ef1dcf911c170dc7917b1de9087b0b8e0 Mon Sep 17 00:00:00 2001 From: Nalin Dahyabhai Date: Fri, 6 Jan 2012 15:42:33 -0500 Subject: - Make a note of which attributes we read from any entry when evaluating data, and when we're later called for a modify request which doesn't modify any of those attributes, skip recalculating the entry contents (should make a dent in #771493). --- src/back-nis.c | 19 ++++++-- src/back-sch.c | 17 +++++-- src/back-shr.c | 151 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--- src/backend.h | 13 ++++- src/format.c | 149 +++++++++++++++++++++++++++++++++++++++++--------------- src/format.h | 4 +- 6 files changed, 300 insertions(+), 53 deletions(-) (limited to 'src') diff --git a/src/back-nis.c b/src/back-nis.c index 0588795..1e9381c 100644 --- a/src/back-nis.c +++ b/src/back-nis.c @@ -1,5 +1,5 @@ /* - * Copyright 2008,2011 Red Hat, Inc. + * Copyright 2008,2011,2012 Red Hat, Inc. * * This Program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -86,6 +86,8 @@ backend_free_set_data_contents(void *data) free(set_data->common.group); free(set_data->common.set); backend_shr_free_strlist(set_data->common.bases); + format_free_attr_list(set_data->common.rel_attrs); + free(set_data->common.rel_attr_list); format_free_attr_list(set_data->common.ref_attrs); format_free_inref_attrs(set_data->common.inref_attrs); format_free_ref_attr_list(set_data->common.ref_attr_list); @@ -118,6 +120,11 @@ backend_copy_set_data(const struct backend_set_data *data) ret->common.set = strdup(data->common.set); ret->common.bases = backend_shr_dup_strlist(data->common.bases); ret->common.entry_filter = strdup(data->common.entry_filter); + ret->common.rel_attrs = data->common.rel_attrs ? + format_dup_attr_list(data->common.rel_attrs) : + NULL; + ret->common.rel_attr_list = NULL; + ret->common.rel_attrs_list = NULL; ret->common.ref_attrs = data->common.ref_attrs ? format_dup_attr_list(data->common.ref_attrs) : NULL; @@ -184,6 +191,7 @@ backend_gather_data(struct plugin_state *state, Slapi_Entry *e, const char *domain, const char *map, char **single_formats, char **group_formats, const char *disallowed_chars, + char ***rel_attrs, char ***ref_attrs, struct format_inref_attr ***inref_attrs, struct format_ref_attr_list ***ref_attr_list, @@ -243,7 +251,7 @@ backend_gather_data(struct plugin_state *state, Slapi_Entry *e, singles[i] = format_get_data(state, e, domain, map, single_formats[i], disallowed_chars, - ref_attrs, inref_attrs, + rel_attrs, ref_attrs, inref_attrs, ref_attr_list, inref_attr_list, &single_lengths[i]); if (singles[i] != NULL) { @@ -271,7 +279,7 @@ backend_gather_data(struct plugin_state *state, Slapi_Entry *e, groups[j] = format_get_data_set(state, e, domain, map, group_formats[i], disallowed_chars, - ref_attrs, inref_attrs, + rel_attrs, ref_attrs, inref_attrs, ref_attr_list, inref_attr_list, &group_lengths[j]); if (groups[j] != NULL) { @@ -348,6 +356,7 @@ backend_set_entry(Slapi_Entry *e, struct backend_set_data *data) data->key_formats, data->keys_formats, data->disallowed_chars, + &data->common.rel_attrs, &data->common.ref_attrs, &data->common.inref_attrs, &data->common.ref_attr_list, @@ -364,6 +373,7 @@ backend_set_entry(Slapi_Entry *e, struct backend_set_data *data) data->value_formats, data->values_formats, data->disallowed_chars, + &data->common.rel_attrs, &data->common.ref_attrs, &data->common.inref_attrs, &data->common.ref_attr_list, @@ -589,6 +599,9 @@ backend_set_config_read_config(struct plugin_state *state, Slapi_Entry *e, ret.common.set = strdup(map); ret.common.bases = use_bases; ret.common.entry_filter = use_entry_filter; + ret.common.rel_attrs = NULL; + ret.common.rel_attr_list = NULL; + ret.common.rel_attrs_list = NULL; ret.common.ref_attrs = NULL; ret.common.inref_attrs = NULL; ret.common.ref_attr_list = NULL; diff --git a/src/back-sch.c b/src/back-sch.c index c17a353..d166581 100644 --- a/src/back-sch.c +++ b/src/back-sch.c @@ -1,5 +1,5 @@ /* - * Copyright 2008,2009,2010,2011 Red Hat, Inc. + * Copyright 2008,2009,2010,2011,2012 Red Hat, Inc. * * This Program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -90,6 +90,8 @@ backend_set_config_free_config_contents(void *data) free(set_data->common.group); free(set_data->common.set); free(set_data->common.bases); + format_free_attr_list(set_data->common.rel_attrs); + free(set_data->common.rel_attr_list); format_free_attr_list(set_data->common.ref_attrs); format_free_inref_attrs(set_data->common.inref_attrs); format_free_ref_attr_list(set_data->common.ref_attr_list); @@ -119,6 +121,11 @@ backend_copy_set_config(const struct backend_set_data *data) ret->common.group = slapi_dn_normalize(strdup(data->common.group)); ret->common.set = slapi_dn_normalize(strdup(data->common.set)); ret->common.bases = backend_shr_dup_strlist(data->common.bases); + ret->common.rel_attrs = data->common.rel_attrs ? + format_dup_attr_list(data->common.rel_attrs) : + NULL; + ret->common.rel_attr_list = NULL; + ret->common.rel_attrs_list = NULL; ret->common.ref_attrs = data->common.ref_attrs ? format_dup_attr_list(data->common.ref_attrs) : NULL; @@ -178,6 +185,9 @@ backend_set_config_read_config(struct plugin_state *state, Slapi_Entry *e, strdup(container); ret.common.bases = bases; ret.common.entry_filter = entry_filter; + ret.common.rel_attrs = NULL; + ret.common.rel_attr_list = NULL; + ret.common.rel_attrs_list = NULL; ret.common.ref_attrs = NULL; ret.common.inref_attrs = NULL; ret.common.ref_attr_list = NULL; @@ -288,6 +298,7 @@ backend_set_entry(Slapi_Entry *e, struct backend_set_data *data) rdn = format_get_data(data->common.state, e, data->common.group, data->common.set, data->rdn_format, NULL, + &data->common.rel_attrs, &data->common.ref_attrs, &data->common.inref_attrs, &data->common.ref_attr_list, @@ -321,6 +332,7 @@ backend_set_entry(Slapi_Entry *e, struct backend_set_data *data) data->common.set, data->attribute_format[i], NULL, + &data->common.rel_attrs, &data->common.ref_attrs, &data->common.inref_attrs, &data->common.ref_attr_list, @@ -396,9 +408,8 @@ backend_set_entry(Slapi_Entry *e, struct backend_set_data *data) slapi_entry_add_string(entry, "objectClass", "extensibleObject"); } - /* Clean up some LDIF. */ + /* Clean up the entry by doing a round trip through the LDIF parser. */ ldif = slapi_entry2str(entry, &len); - /* Recreate the entry. */ slapi_entry_free(entry); entry = slapi_str2entry(ldif, SLAPI_STR2ENTRY_REMOVEDUPVALS | diff --git a/src/back-shr.c b/src/back-shr.c index 180fb33..c9f46a6 100644 --- a/src/back-shr.c +++ b/src/back-shr.c @@ -1,5 +1,5 @@ /* - * Copyright 2008,2010,2011 Red Hat, Inc. + * Copyright 2008,2010,2011,2012 Red Hat, Inc. * * This Program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -119,6 +119,45 @@ backend_shr_read_server_name(struct plugin_state *state, char **master) return (*master != NULL) ? 0 : -1; } +/* Cache the list of relevant attributes, updating if needed, and return its + * value. Mainly used for logging. */ +static const char * +backend_shr_get_rel_attr_list(struct backend_shr_set_data *data) +{ + int i, length; + + if (data->rel_attrs_list == data->rel_attrs) { + return data->rel_attr_list; + } else { + free(data->rel_attr_list); + if (data->rel_attrs == NULL) { + data->rel_attr_list = NULL; + } else { + for (i = 0, length = 0; + data->rel_attrs[i] != NULL; + i++) { + length += (strlen(data->rel_attrs[i]) + 1); + } + if (length > 0) { + data->rel_attr_list = malloc(length); + for (i = 0, length = 0; + (data->rel_attrs[i] != NULL); + i++) { + if (i > 0) { + strcpy(data->rel_attr_list + length++, ","); + } + strcpy(data->rel_attr_list + length, data->rel_attrs[i]); + length += strlen(data->rel_attrs[i]); + } + } else { + data->rel_attr_list = NULL; + } + } + data->rel_attrs_list = data->rel_attrs; + } + return data->rel_attr_list; +} + /* Manipulate string lists. */ void backend_shr_free_strlist(char **strlist) @@ -768,11 +807,39 @@ backend_shr_note_entry_sdn_cb(Slapi_Entry *e, void *cbdata_ptr) return 0; } +/* Build a string representation of the list of attributes being modified by + * this list of mods, typically for logging purposes. */ +static char * +backend_shr_mods_as_string(LDAPMod **mods) +{ + char *ret; + int i, length; + + ret = NULL; + for (i = 0, length = 0; (mods != NULL) && (mods[i] != NULL); i++) { + length += (strlen(mods[i]->mod_type) + 1); + } + if (length > 0) { + ret = malloc(length); + for (i = 0, length = 0; + (mods != NULL) && (mods[i] != NULL); + i++) { + if (i > 0) { + strcpy(ret + length++, ","); + } + strcpy(ret + length, mods[i]->mod_type); + length += strlen(mods[i]->mod_type); + } + } + return ret; +} + /* Update any entries in the map for which the passed-in entry will affect the * values which are derived. */ struct backend_shr_update_references_cbdata { Slapi_PBlock *pb; Slapi_Entry *e; + LDAPMod **mods; }; static bool_t @@ -800,12 +867,44 @@ backend_shr_update_references_cb(const char *group, const char *set, struct format_ref_attr_list_link *this_attr_link, *prev_attr_link; struct format_ref_attr_list_link *next_attr_link; const char *ndn, *dn; + char *modlist; int i, j, k, l, disposition, buffer_flags, n_ref_attrs, scope; set_data = backend_data; cbdata = cbdata_ptr; state = set_data->state; + /* If the entry didn't change any attributes which are at all relevant + * to this map, then we don't need to recompute anything. */ + if ((cbdata->mods != NULL) && (set_data->rel_attrs != NULL)) { + for (i = 0; cbdata->mods[i] != NULL; i++) { + for (j = 0; set_data->rel_attrs[j] != NULL; j++) { + if (slapi_attr_types_equivalent(cbdata->mods[i]->mod_type, + set_data->rel_attrs[j])) { + break; + } + } + if (set_data->rel_attrs[j] != NULL) { + break; + } + } + if (cbdata->mods[i] == NULL) { + modlist = backend_shr_mods_as_string(cbdata->mods); + slapi_log_error(SLAPI_LOG_PLUGIN, + state->plugin_desc->spd_id, + "no interesting reference-based " + "changes for \"%s\"/\"%s\" " + "made in \"%s\" (%s not in %s)\n", + set_data->group, + set_data->set, + slapi_entry_get_ndn(cbdata->e), + modlist, + backend_shr_get_rel_attr_list(set_data)); + free(modlist); + return TRUE; + } + } + /* For every entry in this set which refers to this entry using * a DN stored in an attribute, update that entry. */ @@ -1304,11 +1403,13 @@ backend_shr_update_references_cb(const char *group, const char *set, } void -backend_shr_update_references(struct plugin_state *state, Slapi_Entry *e) +backend_shr_update_references(struct plugin_state *state, Slapi_Entry *e, + LDAPMod **mods) { struct backend_shr_update_references_cbdata cbdata; cbdata.e = e; cbdata.pb = slapi_pblock_new(); + cbdata.mods = mods; if (!map_data_foreach_map(state, NULL, backend_shr_update_references_cb, &cbdata)) { slapi_log_error(SLAPI_LOG_PLUGIN, @@ -1411,7 +1512,7 @@ backend_shr_add_cb(Slapi_PBlock *pb) } /* Update entries in maps which are affected by this entry. */ - backend_shr_update_references(cbdata.state, cbdata.e); + backend_shr_update_references(cbdata.state, cbdata.e, NULL); map_unlock(); wrap_dec_call_level(); @@ -1424,6 +1525,7 @@ struct backend_shr_modify_entry_cbdata { LDAPMod **mods; Slapi_Entry *e_pre, *e_post; char *ndn; + char *modlist; }; static bool_t @@ -1432,10 +1534,44 @@ backend_shr_modify_entry_cb(const char *group, const char *set, bool_t flag, { struct backend_shr_set_data *set_data; struct backend_shr_modify_entry_cbdata *cbdata; + int i, j; set_data = backend_data; cbdata = cbdata_ptr; + /* If the entry didn't change any attributes which are at all relevant + * to the map, and it both was and is still is in the map, then we + * don't need to recompute anything. */ + if ((cbdata->mods != NULL) && (set_data->rel_attrs != NULL)) { + for (i = 0; cbdata->mods[i] != NULL; i++) { + for (j = 0; set_data->rel_attrs[j] != NULL; j++) { + if (slapi_attr_types_equivalent(cbdata->mods[i]->mod_type, + set_data->rel_attrs[j])) { + break; + } + } + if (set_data->rel_attrs[j] != NULL) { + break; + } + } + if ((cbdata->mods[i] == NULL) && + backend_shr_entry_matches_set(set_data, cbdata->pb, + cbdata->e_pre) && + backend_shr_entry_matches_set(set_data, cbdata->pb, + cbdata->e_post)) { + slapi_log_error(SLAPI_LOG_PLUGIN, + cbdata->state->plugin_desc->spd_id, + "no interesting changes for " + "\"%s\"/\"%s\" made in (\"%s\") " + "(%s not in %s)\n", + set_data->group, + set_data->set, + cbdata->ndn, + cbdata->modlist, + backend_shr_get_rel_attr_list(set_data)); + return TRUE; + } + } /* If the entry used to match the map, remove it. */ if (backend_shr_entry_matches_set(set_data, cbdata->pb, cbdata->e_pre)) { @@ -1484,6 +1620,7 @@ backend_shr_modify_cb(Slapi_PBlock *pb) slapi_pblock_get(pb, SLAPI_ENTRY_POST_OP, &cbdata.e_post); cbdata.ndn = slapi_entry_get_ndn(cbdata.e_pre); cbdata.pb = pb; + cbdata.modlist = NULL; slapi_log_error(SLAPI_LOG_PLUGIN, cbdata.state->plugin_desc->spd_id, "modified \"%s\"\n", cbdata.ndn); /* Check for NULL entries, indicative of a failure elsewhere (?). */ @@ -1499,6 +1636,7 @@ backend_shr_modify_cb(Slapi_PBlock *pb) "post-modify entry is NULL\n"); return 0; } + cbdata.modlist = backend_shr_mods_as_string(cbdata.mods); /* Modify map entries which corresponded to this directory server * entry. */ wrap_inc_call_level(); @@ -1512,10 +1650,10 @@ backend_shr_modify_cb(Slapi_PBlock *pb) } /* Update entries which need to be updated in case they are no longer * affected by this entry. */ - backend_shr_update_references(cbdata.state, cbdata.e_pre); + backend_shr_update_references(cbdata.state, cbdata.e_pre, cbdata.mods); /* Update entries which need to be updated in case they are now * affected by this entry. */ - backend_shr_update_references(cbdata.state, cbdata.e_post); + backend_shr_update_references(cbdata.state, cbdata.e_post, cbdata.mods); /* If it's a map configuration entry, reconfigure, clear, and * repopulate the map. */ if (backend_shr_entry_is_a_set(cbdata.state, pb, cbdata.e_pre)) { @@ -1545,6 +1683,7 @@ backend_shr_modify_cb(Slapi_PBlock *pb) } map_unlock(); wrap_dec_call_level(); + free(cbdata.modlist); return 0; } @@ -1746,7 +1885,7 @@ backend_shr_delete_cb(Slapi_PBlock *pb) } /* Update entries which need to be updated in case they are no longer * affected by this entry. */ - backend_shr_update_references(cbdata.state, cbdata.e); + backend_shr_update_references(cbdata.state, cbdata.e, NULL); map_unlock(); wrap_dec_call_level(); return 0; diff --git a/src/backend.h b/src/backend.h index 09f5af6..73ae182 100644 --- a/src/backend.h +++ b/src/backend.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Red Hat, Inc. + * Copyright 2008,2012 Red Hat, Inc. * * This Program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -29,8 +29,19 @@ struct format_inref_attr; struct backend_shr_set_data { struct plugin_state *state; char *group, *set, **bases, *entry_filter; + /* The list of "relevant" attributes, from _any_ entry, which matter + * when we're evaluating key or value data. We skip updating an entry + * in this map if a modification request doesn't touch any of these + * attributes. */ + char **rel_attrs, *rel_attr_list, **rel_attrs_list; + /* The list of attributes in source entries for this map which directly + * name other entries. */ char **ref_attrs; + /* A list of group/set/attributes by which source entries in any other + * group/set refer to entries in this set. */ struct format_inref_attr **inref_attrs; + /* More general-purpose versions of the above, which allow for + * overriding the search bases and filters as well. */ struct format_ref_attr_list **ref_attr_list, **inref_attr_list; struct backend_set_data *self; }; diff --git a/src/format.c b/src/format.c index 698ea34..9871ac6 100644 --- a/src/format.c +++ b/src/format.c @@ -1,5 +1,5 @@ /* - * Copyright 2008,2010,2011 Red Hat, Inc. + * Copyright 2008,2010,2011,2012 Red Hat, Inc. * * This Program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -62,7 +62,7 @@ static int format_expand(struct plugin_state *state, const char *fmt, const char *disallowed, char *outbuf, int outbuf_len, struct format_choice **outbuf_choices, - char ***ref_attrs, + char ***rel_attrs, char ***ref_attrs, struct format_inref_attr ***inref_attrs, struct format_ref_attr_list ***ref_attr_list, struct format_ref_attr_list ***inref_attr_list); @@ -918,6 +918,7 @@ format_first(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, const char *args, const char *disallowed, char *outbuf, int outbuf_len, struct format_choice **outbuf_choices, + char ***rel_attrs, char ***ref_attrs, struct format_inref_attr ***inref_attrs, struct format_ref_attr_list ***ref_attr_list, struct format_ref_attr_list ***inref_attr_list) @@ -948,7 +949,7 @@ format_first(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, ret = -ENOENT; values = format_get_data_set(state, e, group, set, value_format, disallowed, - ref_attrs, inref_attrs, + rel_attrs, ref_attrs, inref_attrs, ref_attr_list, inref_attr_list, &lengths); if (values == NULL) { @@ -965,7 +966,7 @@ format_first(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, default_value, NULL, outbuf, outbuf_len, outbuf_choices, - ref_attrs, inref_attrs, + rel_attrs, ref_attrs, inref_attrs, ref_attr_list, inref_attr_list); ret = i; } @@ -1005,6 +1006,7 @@ format_deref_x(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, char *filter, const char *disallowed, char *outbuf, int outbuf_len, struct format_choice **outbuf_choices, + char ***rel_attrs, char ***ref_attrs, struct format_inref_attr ***inref_attrs, struct format_ref_attr_list ***ref_attr_list, struct format_ref_attr_list ***inref_attr_list) @@ -1019,6 +1021,10 @@ format_deref_x(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, const char *cref; const struct berval *val; struct berval **choices; + /* Note that this map cares about this attribute. */ + if (rel_attrs != NULL) { + format_add_attrlist(rel_attrs, ref_attr); + } /* Note that the attribute in this entry refers to other entries. */ if (ref_attrs != NULL) { format_add_attrlist(ref_attrs, ref_attr); @@ -1067,6 +1073,10 @@ format_deref_x(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, "%s: reading \"%s\" from \"%s\"\n", fname, target_attr, slapi_sdn_get_ndn(refdn)); slapi_sdn_free(&refdn); + /* Note that this map cares about this attribute. */ + if (rel_attrs != NULL) { + format_add_attrlist(rel_attrs, target_attr); + } /* Pull out the attribute from the referred-to entry. */ if (slapi_vattr_values_get(ref, target_attr, &values, &disposition, &actual_attr, @@ -1106,6 +1116,7 @@ format_deref(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, const char *args, const char *disallowed, char *outbuf, int outbuf_len, struct format_choice **outbuf_choices, + char ***rel_attrs, char ***ref_attrs, struct format_inref_attr ***inref_attrs, struct format_ref_attr_list ***ref_attr_list, struct format_ref_attr_list ***inref_attr_list) @@ -1136,7 +1147,7 @@ format_deref(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, ret = format_deref_x(state, pb, e, "deref", group, set, ref_attr, target_attr, NULL, disallowed, outbuf, outbuf_len, outbuf_choices, - ref_attrs, inref_attrs, + rel_attrs, ref_attrs, inref_attrs, ref_attr_list, inref_attr_list); format_free_parsed_args(argv); return ret; @@ -1148,7 +1159,8 @@ format_deref_f(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, const char *args, const char *disallowed, char *outbuf, int outbuf_len, struct format_choice **outbuf_choices, - char ***ref_attrs, struct format_inref_attr ***inref_attrs, + char ***rel_attrs, char ***ref_attrs, + struct format_inref_attr ***inref_attrs, struct format_ref_attr_list ***ref_attr_list, struct format_ref_attr_list ***inref_attr_list) { @@ -1179,7 +1191,7 @@ format_deref_f(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, ret = format_deref_x(state, pb, e, "deref_f", group, set, ref_attr, target_attr, filter, disallowed, outbuf, outbuf_len, outbuf_choices, - ref_attrs, inref_attrs, + rel_attrs, ref_attrs, inref_attrs, ref_attr_list, inref_attr_list); format_free_parsed_args(argv); return ret; @@ -1196,7 +1208,8 @@ format_deref_rx(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, const char *disallowed, char *outbuf, int outbuf_len, struct format_choice **outbuf_choices, - char ***ref_attrs, struct format_inref_attr ***inref_attrs, + char ***rel_attrs, char ***ref_attrs, + struct format_inref_attr ***inref_attrs, struct format_ref_attr_list ***ref_attr_list, struct format_ref_attr_list ***inref_attr_list) { @@ -1212,6 +1225,13 @@ format_deref_rx(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, struct berval **choices; struct format_ref_attr_list *list; + /* Note that this map cares about all of these attributes. */ + if ((rel_attrs != NULL) && (attributes != NULL)) { + for (i = 0; attributes[i] != NULL; i++) { + format_add_attrlist(rel_attrs, attributes[i]); + } + } + /* Note that this list of attributes is used for pulling up data. */ format_add_ref_attr_list(ref_attr_list, group, set, attributes, filters); @@ -1351,6 +1371,7 @@ format_deref_r(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, const char *args, const char *disallowed, char *outbuf, int outbuf_len, struct format_choice **outbuf_choices, + char ***rel_attrs, char ***ref_attrs, struct format_inref_attr ***inref_attrs, struct format_ref_attr_list ***ref_attr_list, struct format_ref_attr_list ***inref_attr_list) @@ -1382,7 +1403,7 @@ format_deref_r(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, disallowed, outbuf, outbuf_len, outbuf_choices, - ref_attrs, inref_attrs, + rel_attrs, ref_attrs, inref_attrs, ref_attr_list, inref_attr_list); format_free_parsed_args(argv); return ret; @@ -1394,6 +1415,7 @@ format_deref_rf(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, const char *args, const char *disallowed, char *outbuf, int outbuf_len, struct format_choice **outbuf_choices, + char ***rel_attrs, char ***ref_attrs, struct format_inref_attr ***inref_attrs, struct format_ref_attr_list ***ref_attr_list, struct format_ref_attr_list ***inref_attr_list) @@ -1451,7 +1473,7 @@ format_deref_rf(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, disallowed, outbuf, outbuf_len, outbuf_choices, - ref_attrs, inref_attrs, + rel_attrs, ref_attrs, inref_attrs, ref_attr_list, inref_attr_list); free(filters); free(attrs); @@ -1519,7 +1541,8 @@ format_referred(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, const char *args, const char *disallowed, char *outbuf, int outbuf_len, struct format_choice **outbuf_choices, - char ***ref_attrs, struct format_inref_attr ***inref_attrs, + char ***rel_attrs, char ***ref_attrs, + struct format_inref_attr ***inref_attrs, struct format_ref_attr_list ***ref_attr_list, struct format_ref_attr_list ***inref_attr_list) { @@ -1581,6 +1604,12 @@ format_referred(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, return -ENOENT; } + /* Note that this map cares both attributes. */ + if (rel_attrs != NULL) { + format_add_attrlist(rel_attrs, other_attr); + format_add_attrlist(rel_attrs, attr); + } + /* Note that the attribute in this map refers to this entry. */ if (inref_attrs != NULL) { format_add_inref_attrs(inref_attrs, group, @@ -1726,6 +1755,7 @@ format_referred_r(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, const char *args, const char *disallowed, char *outbuf, int outbuf_len, struct format_choice **outbuf_choices, + char ***rel_attrs, char ***ref_attrs, struct format_inref_attr ***inref_attrs, struct format_ref_attr_list ***ref_attr_list, struct format_ref_attr_list ***inref_attr_list) @@ -1788,6 +1818,14 @@ format_referred_r(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, } attr_links[i] = NULL; + /* Note that this map cares about these attributes. */ + if (rel_attrs != NULL) { + format_add_attrlist(rel_attrs, attr); + for (i = 0; attr_links[i] != NULL; i++) { + format_add_attrlist(rel_attrs, attr_links[i]); + } + } + /* Note this list of attributes. */ format_add_ref_attr_list(inref_attr_list, group, set, attr_links, NULL); list = format_find_ref_attr_list(*inref_attr_list, group, set, @@ -1964,7 +2002,8 @@ format_merge(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, const char *args, const char *disallowed, char *outbuf, int outbuf_len, struct format_choice **outbuf_choices, - char ***ref_attrs, struct format_inref_attr ***inref_attrs, + char ***rel_attrs, char ***ref_attrs, + struct format_inref_attr ***inref_attrs, struct format_ref_attr_list ***ref_attr_list, struct format_ref_attr_list ***inref_attr_list) { @@ -1993,7 +2032,7 @@ format_merge(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, "merge: expanding ->%s<-\n", argv[i]); values = format_get_data_set(state, e, group, set, argv[i], disallowed, - ref_attrs, inref_attrs, + rel_attrs, ref_attrs, inref_attrs, ref_attr_list, inref_attr_list, &lengths); if (values == NULL) { @@ -2048,6 +2087,7 @@ format_match_generic(struct plugin_state *state, const char *disallowed, char *outbuf, int outbuf_len, struct format_choice **outbuf_choices, + char ***rel_attrs, char ***ref_attrs, struct format_inref_attr ***inref_attrs, struct format_ref_attr_list ***ref_attr_list, @@ -2080,7 +2120,7 @@ format_match_generic(struct plugin_state *state, lengths = NULL; values = format_get_data_set(state, e, group, set, argv[0], disallowed, - ref_attrs, inref_attrs, + rel_attrs, ref_attrs, inref_attrs, ref_attr_list, inref_attr_list, &lengths); if (values != NULL) { @@ -2134,6 +2174,7 @@ format_match_generic(struct plugin_state *state, group, set, argv[default_arg], disallowed, + rel_attrs, ref_attrs, inref_attrs, ref_attr_list, @@ -2240,14 +2281,15 @@ format_match(struct plugin_state *state, const char *args, const char *disallowed, char *outbuf, int outbuf_len, struct format_choice **outbuf_choices, - char ***ref_attrs, struct format_inref_attr ***inref_attrs, + char ***rel_attrs, char ***ref_attrs, + struct format_inref_attr ***inref_attrs, struct format_ref_attr_list ***ref_attr_list, struct format_ref_attr_list ***inref_attr_list) { return format_match_generic(state, pb, e, group, set, args, 2, 2, disallowed, outbuf, outbuf_len, outbuf_choices, - ref_attrs, inref_attrs, + rel_attrs, ref_attrs, inref_attrs, ref_attr_list, inref_attr_list, "format_match", format_match_cb); } @@ -2280,14 +2322,15 @@ format_regmatch(struct plugin_state *state, const char *args, const char *disallowed, char *outbuf, int outbuf_len, struct format_choice **outbuf_choices, - char ***ref_attrs, struct format_inref_attr ***inref_attrs, + char ***rel_attrs, char ***ref_attrs, + struct format_inref_attr ***inref_attrs, struct format_ref_attr_list ***ref_attr_list, struct format_ref_attr_list ***inref_attr_list) { return format_match_generic(state, pb, e, group, set, args, 2, 2, disallowed, outbuf, outbuf_len, outbuf_choices, - ref_attrs, inref_attrs, + rel_attrs, ref_attrs, inref_attrs, ref_attr_list, inref_attr_list, "format_regmatch", format_regmatch_cb); } @@ -2303,14 +2346,15 @@ format_regmatchi(struct plugin_state *state, const char *args, const char *disallowed, char *outbuf, int outbuf_len, struct format_choice **outbuf_choices, - char ***ref_attrs, struct format_inref_attr ***inref_attrs, + char ***rel_attrs, char ***ref_attrs, + struct format_inref_attr ***inref_attrs, struct format_ref_attr_list ***ref_attr_list, struct format_ref_attr_list ***inref_attr_list) { return format_match_generic(state, pb, e, group, set, args, 2, 2, disallowed, outbuf, outbuf_len, outbuf_choices, - ref_attrs, inref_attrs, + rel_attrs, ref_attrs, inref_attrs, ref_attr_list, inref_attr_list, "format_regmatchi", format_regmatchi_cb); } @@ -2436,14 +2480,15 @@ format_regsub(struct plugin_state *state, const char *args, const char *disallowed, char *outbuf, int outbuf_len, struct format_choice **outbuf_choices, - char ***ref_attrs, struct format_inref_attr ***inref_attrs, + char ***rel_attrs, char ***ref_attrs, + struct format_inref_attr ***inref_attrs, struct format_ref_attr_list ***ref_attr_list, struct format_ref_attr_list ***inref_attr_list) { return format_match_generic(state, pb, e, group, set, args, 3, 3, disallowed, outbuf, outbuf_len, outbuf_choices, - ref_attrs, inref_attrs, + rel_attrs, ref_attrs, inref_attrs, ref_attr_list, inref_attr_list, "format_regsub", format_regsub_cb); } @@ -2459,14 +2504,15 @@ format_regsubi(struct plugin_state *state, const char *args, const char *disallowed, char *outbuf, int outbuf_len, struct format_choice **outbuf_choices, - char ***ref_attrs, struct format_inref_attr ***inref_attrs, + char ***rel_attrs, char ***ref_attrs, + struct format_inref_attr ***inref_attrs, struct format_ref_attr_list ***ref_attr_list, struct format_ref_attr_list ***inref_attr_list) { return format_match_generic(state, pb, e, group, set, args, 3, 3, disallowed, outbuf, outbuf_len, outbuf_choices, - ref_attrs, inref_attrs, + rel_attrs, ref_attrs, inref_attrs, ref_attr_list, inref_attr_list, "format_regsubi", format_regsubi_cb); } @@ -2482,7 +2528,8 @@ format_ifeq(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, const char *args, const char *disallowed, char *outbuf, int outbuf_len, struct format_choice **outbuf_choices, - char ***ref_attrs, struct format_inref_attr ***inref_attrs, + char ***rel_attrs, char ***ref_attrs, + struct format_inref_attr ***inref_attrs, struct format_ref_attr_list ***ref_attr_list, struct format_ref_attr_list ***inref_attr_list) { @@ -2513,10 +2560,15 @@ format_ifeq(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, return -EINVAL; } + /* Note that this map cares about the tested attribute. */ + if (rel_attrs != NULL) { + format_add_attrlist(rel_attrs, argv[0]); + } + /* Evaluate the value expression to get a list of candidate values. */ values = format_get_data_set(state, e, group, set, argv[1], disallowed, - ref_attrs, inref_attrs, + rel_attrs, ref_attrs, inref_attrs, ref_attr_list, inref_attr_list, &lengths); if (values == NULL) { @@ -2556,7 +2608,7 @@ format_ifeq(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, argv[matched ? 2 : 3], disallowed, outbuf, outbuf_len, outbuf_choices, - ref_attrs, inref_attrs, + rel_attrs, ref_attrs, inref_attrs, ref_attr_list, inref_attr_list); format_free_parsed_args(argv); return ret; @@ -2570,7 +2622,8 @@ format_collect(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, const char *args, const char *disallowed, char *outbuf, int outbuf_len, struct format_choice **outbuf_choices, - char ***ref_attrs, struct format_inref_attr ***inref_attrs, + char ***rel_attrs, char ***ref_attrs, + struct format_inref_attr ***inref_attrs, struct format_ref_attr_list ***ref_attr_list, struct format_ref_attr_list ***inref_attr_list) { @@ -2598,7 +2651,7 @@ format_collect(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, /* Evaluate this argument. */ values = format_get_data_set(state, e, group, set, argv[i], disallowed, - ref_attrs, inref_attrs, + rel_attrs, ref_attrs, inref_attrs, ref_attr_list, inref_attr_list, &lengths); if (values != NULL) { @@ -2663,7 +2716,8 @@ format_link(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, const char *args, const char *disallowed, char *outbuf, int outbuf_len, struct format_choice **outbuf_choices, - char ***ref_attrs, struct format_inref_attr ***inref_attrs, + char ***rel_attrs, char ***ref_attrs, + struct format_inref_attr ***inref_attrs, struct format_ref_attr_list ***ref_attr_list, struct format_ref_attr_list ***inref_attr_list) { @@ -2713,6 +2767,7 @@ format_link(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, "link: evaluating \"%s\"\n", argv[i]); values[i / 3] = format_get_data_set(state, e, group, set, argv[i], disallowed, + rel_attrs, ref_attrs, inref_attrs, ref_attr_list, inref_attr_list, @@ -2858,6 +2913,7 @@ format_lookup_fn(const char *fnname) const char *args, const char *disallowed, char *outbuf, int outbuf_len, struct format_choice **outbuf_choices, + char ***rel_attrs, char ***ref_attrs, struct format_inref_attr ***inref_attrs, struct format_ref_attr_list ***ref_attr_list, @@ -2951,7 +3007,7 @@ format_check_disallowed(const struct berval *bv, const char *disallowed) static struct berval format_single(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, const char *attr, const char *disallowed, - struct berval ***values) + char ***attrlist, struct berval ***values) { Slapi_ValueSet *value_set; Slapi_Value *value; @@ -2960,6 +3016,9 @@ format_single(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, const struct berval *val; struct berval bv; int count, disposition, buffer_flags, i; + if (attrlist != NULL) { + format_add_attrlist(attrlist, attr); + } memset(&bv, 0, sizeof(bv)); if (slapi_vattr_values_get(e, (char *) attr, &value_set, &disposition, &actual_attr, @@ -3189,6 +3248,7 @@ format_expand_simple(struct plugin_state *state, const char *fmt, const char *disallowed, char *outbuf, int outbuf_len, struct format_choice **outbuf_choices, + char ***rel_attrs, char ***ref_attrs, struct format_inref_attr ***inref_attrs, struct format_ref_attr_list ***ref_attr_list, @@ -3285,7 +3345,7 @@ format_expand_simple(struct plugin_state *state, /* Retrieve the value. */ values = NULL; tmp = format_single(state, pb, e, attribute, disallowed, - outbuf_choices ? &values : NULL); + rel_attrs, outbuf_choices ? &values : NULL); if (tmp.bv_val == NULL) { /* The attribute is undefined, or we're treating it as if it * is. */ @@ -3298,6 +3358,7 @@ format_expand_simple(struct plugin_state *state, default_value, NULL, outbuf, outbuf_len, outbuf_choices, + rel_attrs, ref_attrs, inref_attrs, ref_attr_list, inref_attr_list); @@ -3316,6 +3377,7 @@ format_expand_simple(struct plugin_state *state, alternate_value, NULL, outbuf, outbuf_len, outbuf_choices, + rel_attrs, ref_attrs, inref_attrs, ref_attr_list, inref_attr_list); @@ -3343,7 +3405,7 @@ format_expand_simple(struct plugin_state *state, i = format_expand(state, pb, e, group, set, alternate_value, NULL, outbuf, outbuf_len, outbuf_choices, - ref_attrs, inref_attrs, + rel_attrs, ref_attrs, inref_attrs, ref_attr_list, inref_attr_list); free(tmp.bv_val); free(expr); @@ -3382,7 +3444,8 @@ format_expand(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, const char *fmt, const char *disallowed, char *outbuf, int outbuf_len, struct format_choice **outbuf_choices, - char ***ref_attrs, struct format_inref_attr ***inref_attrs, + char ***rel_attrs, char ***ref_attrs, + struct format_inref_attr ***inref_attrs, struct format_ref_attr_list ***ref_attr_list, struct format_ref_attr_list ***inref_attr_list) { @@ -3396,6 +3459,7 @@ format_expand(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, const char *args, const char *disallowed, char *outbuf, int outbuf_len, struct format_choice **outbuf_choices, + char ***rel_attrs, char ***ref_attrs, struct format_inref_attr ***inref_attrs, struct format_ref_attr_list ***ref_attr_list, @@ -3456,6 +3520,7 @@ format_expand(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, outbuf + j, outbuf_len - j, outbuf_choices, + rel_attrs, ref_attrs, inref_attrs, ref_attr_list, @@ -3560,6 +3625,7 @@ format_expand(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, params, disallowed, outbuf + j, outbuf_len - j, outbuf_choices, + rel_attrs, ref_attrs, inref_attrs, ref_attr_list, inref_attr_list); @@ -3617,7 +3683,8 @@ format_format(struct plugin_state *state, Slapi_Entry *e, const char *group, const char *set, const char *fmt, const char *disallowed, struct format_choice **choices, - char ***ref_attrs, struct format_inref_attr ***inref_attrs, + char ***rel_attrs, char ***ref_attrs, + struct format_inref_attr ***inref_attrs, struct format_ref_attr_list ***ref_attr_list, struct format_ref_attr_list ***inref_attr_list, unsigned int *data_length) @@ -3645,7 +3712,7 @@ format_format(struct plugin_state *state, Slapi_Entry *e, i = format_expand(state, pb, e, group, set, fmt, disallowed, buf, buflen, choices, - ref_attrs, inref_attrs, + rel_attrs, ref_attrs, inref_attrs, ref_attr_list, inref_attr_list); if ((i >= 0) && (i < buflen)) { buf[i] = '\0'; @@ -3705,6 +3772,7 @@ char * format_get_data(struct plugin_state *state, Slapi_Entry *e, const char *group, const char *set, const char *fmt, const char *disallowed, + char ***rel_attrs, char ***ref_attrs, struct format_inref_attr ***inref_attrs, struct format_ref_attr_list ***ref_attr_list, @@ -3712,8 +3780,10 @@ format_get_data(struct plugin_state *state, Slapi_Entry *e, unsigned int *data_length) { unsigned int ignored; - return format_format(state, e, group, set, fmt, disallowed, - NULL, ref_attrs, inref_attrs, + return format_format(state, e, group, set, fmt, + disallowed, NULL, + rel_attrs, + ref_attrs, inref_attrs, ref_attr_list, inref_attr_list, data_length ? data_length : &ignored); } @@ -3734,6 +3804,7 @@ char ** format_get_data_set(struct plugin_state *state, Slapi_Entry *e, const char *group, const char *set, const char *fmt, const char *disallowed, + char ***rel_attrs, char ***ref_attrs, struct format_inref_attr ***inref_attrs, struct format_ref_attr_list ***ref_attr_list, @@ -3748,7 +3819,7 @@ format_get_data_set(struct plugin_state *state, Slapi_Entry *e, choices = NULL; template = format_format(state, e, group, set, fmt, disallowed, &choices, - ref_attrs, inref_attrs, + rel_attrs, ref_attrs, inref_attrs, ref_attr_list, inref_attr_list, &template_len); if (template == NULL) { diff --git a/src/format.h b/src/format.h index b5dbf3e..ff3edda 100644 --- a/src/format.h +++ b/src/format.h @@ -1,5 +1,5 @@ /* - * Copyright 2008,2010,2011 Red Hat, Inc. + * Copyright 2008,2010,2011,2012 Red Hat, Inc. * * This Program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -58,6 +58,7 @@ char *format_get_data(struct plugin_state *state, struct slapi_entry *e, const char *domain, const char *map, const char *fmt, const char *disallowed_chars, + char ***rel_attrs, char ***ref_attrs, struct format_inref_attr ***inref_attrs, struct format_ref_attr_list ***ref_attr_list, @@ -68,6 +69,7 @@ char **format_get_data_set(struct plugin_state *state, Slapi_Entry *e, const char *domain, const char *map, const char *fmt, const char *disallowed, + char ***rel_attrs, char ***ref_attrs, struct format_inref_attr ***inref_attrs, struct format_ref_attr_list ***ref_attr_list, -- cgit