summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorNalin Dahyabhai <nalin@dahyabhai.net>2012-01-06 15:42:33 -0500
committerNalin Dahyabhai <nalin@dahyabhai.net>2012-01-06 15:42:33 -0500
commit80c8021ef1dcf911c170dc7917b1de9087b0b8e0 (patch)
tree70a037e20a2093c5fc54d4c5335511954e16f126 /src
parentd361fe8707d3558a9bad59c61b1f124d2de17772 (diff)
downloadslapi-nis-80c8021ef1dcf911c170dc7917b1de9087b0b8e0.tar.gz
slapi-nis-80c8021ef1dcf911c170dc7917b1de9087b0b8e0.tar.xz
slapi-nis-80c8021ef1dcf911c170dc7917b1de9087b0b8e0.zip
- 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).
Diffstat (limited to 'src')
-rw-r--r--src/back-nis.c19
-rw-r--r--src/back-sch.c17
-rw-r--r--src/back-shr.c151
-rw-r--r--src/backend.h13
-rw-r--r--src/format.c149
-rw-r--r--src/format.h4
6 files changed, 300 insertions, 53 deletions
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,