summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/back-shr.c34
-rw-r--r--src/format.c213
-rw-r--r--src/format.h11
3 files changed, 150 insertions, 108 deletions
diff --git a/src/back-shr.c b/src/back-shr.c
index 355686b..7a2eadf 100644
--- a/src/back-shr.c
+++ b/src/back-shr.c
@@ -754,7 +754,7 @@ backend_build_filter(struct plugin_state *state, Slapi_DN *entry_dn,
/* Add the name of this entry to the DN list in the cbdata. */
struct backend_shr_note_entry_sdn_cbdata {
struct plugin_state *state;
- Slapi_DN ***sdn_list;
+ Slapi_DN ***sdn_list, ***sdn_list2;
};
static int
@@ -763,7 +763,8 @@ backend_shr_note_entry_sdn_cb(Slapi_Entry *e, void *cbdata_ptr)
struct backend_shr_note_entry_sdn_cbdata *cbdata = cbdata_ptr;
slapi_log_error(SLAPI_LOG_PLUGIN, cbdata->state->plugin_desc->spd_id,
"matched entry \"%s\"\n", slapi_entry_get_dn(e));
- format_add_sdn_list(cbdata->sdn_list, slapi_entry_get_dn(e));
+ format_add_sdn_list(cbdata->sdn_list, cbdata->sdn_list2,
+ slapi_entry_get_dn(e));
return 0;
}
@@ -785,6 +786,7 @@ backend_shr_update_references_cb(const char *group, const char *set,
struct backend_shr_note_entry_sdn_cbdata note_cbdata;
Slapi_DN *referred_to_sdn, **these_entries, **prev_entries;
Slapi_DN **next_entries, **these_bases, **prev_bases;
+ Slapi_DN **these_entries2, **prev_entries2, **next_entries2;
Slapi_Entry *this_entry;
Slapi_ValueSet *values;
Slapi_Value *value;
@@ -907,9 +909,11 @@ backend_shr_update_references_cb(const char *group, const char *set,
i, slapi_entry_get_ndn(cbdata->e));
ref_attr = ref_attr_list[i];
these_entries = NULL;
+ these_entries2 = NULL;
prev_entries = NULL;
+ prev_entries2 = NULL;
/* Start with this entry. */
- format_add_sdn_list(&these_entries,
+ format_add_sdn_list(&these_entries, &these_entries2,
slapi_entry_get_dn(cbdata->e));
/* Walk the chain backwards. */
for (j = ref_attr->n_links - 1;
@@ -993,6 +997,7 @@ backend_shr_update_references_cb(const char *group, const char *set,
0);
note_cbdata.state = state;
note_cbdata.sdn_list = &these_entries;
+ note_cbdata.sdn_list2 = &these_entries2;
slapi_search_internal_callback_pb(cbdata->pb,
&note_cbdata,
NULL,
@@ -1031,6 +1036,7 @@ backend_shr_update_references_cb(const char *group, const char *set,
0);
note_cbdata.state = state;
note_cbdata.sdn_list = &prev_entries;
+ note_cbdata.sdn_list2 = &prev_entries2;
slapi_search_internal_callback_pb(cbdata->pb,
&note_cbdata,
NULL,
@@ -1043,9 +1049,11 @@ backend_shr_update_references_cb(const char *group, const char *set,
* this was the last link, in which case it's become
* our list of candidates. */
if (j > 0) {
- format_free_sdn_list(these_entries);
+ format_free_sdn_list(these_entries, these_entries2);
these_entries = prev_entries;
+ these_entries2 = prev_entries2;
prev_entries = NULL;
+ prev_entries2 = NULL;
}
/* Log a diagnostic if there's no more work to do. */
if (these_entries == NULL) {
@@ -1082,7 +1090,7 @@ backend_shr_update_references_cb(const char *group, const char *set,
ndn,
set_data->self);
}
- format_free_sdn_list(these_entries);
+ format_free_sdn_list(these_entries, these_entries2);
}
/* Determine if there are any entries in this map which are referred to
@@ -1101,9 +1109,11 @@ backend_shr_update_references_cb(const char *group, const char *set,
i, slapi_entry_get_ndn(cbdata->e));
inref_attr = inref_attr_list[i];
these_entries = NULL;
+ these_entries2 = NULL;
next_entries = NULL;
+ next_entries2 = NULL;
/* Start with this entry. */
- format_add_sdn_list(&these_entries,
+ format_add_sdn_list(&these_entries, &these_entries2,
slapi_entry_get_dn(cbdata->e));
/* Walk the chain, backwards. */
for (j = inref_attr->n_links - 2;
@@ -1185,7 +1195,8 @@ backend_shr_update_references_cb(const char *group, const char *set,
}
/* Add it to the list of entries which
* we'll examine this go-round. */
- format_add_sdn_list(&these_entries, dn);
+ format_add_sdn_list(&these_entries,
+ &these_entries2, dn);
}
slapi_vattr_values_free(&values, &actual_attr,
buffer_flags);
@@ -1236,7 +1247,8 @@ backend_shr_update_references_cb(const char *group, const char *set,
}
/* Add it to the list of entries which
* we'll examine next time. */
- format_add_sdn_list(&next_entries, dn);
+ format_add_sdn_list(&next_entries,
+ &next_entries2, dn);
}
slapi_vattr_values_free(&values, &actual_attr,
buffer_flags);
@@ -1246,9 +1258,11 @@ backend_shr_update_references_cb(const char *group, const char *set,
* this was the last link, in which case it's become
* our list of candidates. */
if (j > 0) {
- format_free_sdn_list(these_entries);
+ format_free_sdn_list(these_entries, these_entries2);
these_entries = next_entries;
+ these_entries2 = next_entries2;
next_entries = NULL;
+ next_entries2 = NULL;
}
/* Log a diagnostic if there's no more work to do. */
if (these_entries == NULL) {
@@ -1283,7 +1297,7 @@ backend_shr_update_references_cb(const char *group, const char *set,
ndn,
set_data->self);
}
- format_free_sdn_list(these_entries);
+ format_free_sdn_list(these_entries, these_entries2);
}
return TRUE;
diff --git a/src/format.c b/src/format.c
index 9b1bb2d..9f8074c 100644
--- a/src/format.c
+++ b/src/format.c
@@ -103,9 +103,19 @@ xmemdup(char *region, int size)
return ret;
}
-/* Maintain a DN list, which is list of distinguished names. */
+/* Maintain a DN list, which is list of distinguished names, and a sorted copy
+ * which we can check for inclusion much faster. */
+static int
+compare_sdn(const void *a, const void *b)
+{
+ const struct slapi_dn **sa, **sb;
+ sa = (const struct slapi_dn **) a;
+ sb = (const struct slapi_dn **) b;
+ return strcmp(slapi_sdn_get_ndn(*sa), slapi_sdn_get_ndn(*sb));
+}
+
void
-format_free_sdn_list(struct slapi_dn **list)
+format_free_sdn_list(struct slapi_dn **list, struct slapi_dn **list2)
{
unsigned int i;
if (list != NULL) {
@@ -114,42 +124,59 @@ format_free_sdn_list(struct slapi_dn **list)
}
free(list);
}
+ free(list2);
}
-struct slapi_dn **
-format_dup_sdn_list(struct slapi_dn **list)
+/* Turn shallow-copy list pointers into deep ones. */
+static void
+format_dup_sdn_list(struct slapi_dn ***list, struct slapi_dn ***list2)
{
- struct slapi_dn **ret;
+ struct slapi_dn **ret = NULL, **ret2 = NULL;
unsigned int i;
- for (i = 0; (list != NULL) && (list[i] != NULL); i++) {
+ for (i = 0;
+ (list != NULL) && (*list != NULL) && ((*list)[i] != NULL);
+ i++) {
continue;
}
- ret = malloc((i + 1) * sizeof(struct slapi_dn*));
- if (ret != NULL) {
- for (i = 0; (list != NULL) && (list[i] != NULL); i++) {
- ret[i] = slapi_sdn_dup(list[i]);
+ if (i > 0) {
+ ret = malloc((i + 1) * sizeof(struct slapi_dn*));
+ ret2 = malloc((i + 1) * sizeof(struct slapi_dn*));
+ if ((ret != NULL) && (ret2 != NULL)) {
+ for (i = 0;
+ (list2 != NULL) && (*list2 != NULL) && ((*list2)[i] != NULL);
+ i++) {
+ ret[i] = slapi_sdn_dup((*list2)[i]);
+ ret2[i] = ret[i];
+ }
+ ret[i] = NULL;
+ ret2[i] = NULL;
+ *list = ret;
+ *list2 = ret2;
}
- ret[i] = NULL;
}
- return ret;
}
-struct slapi_dn **
-format_make_sdn_list(char **list)
+/* Build a list from string DN values. */
+static struct slapi_dn **
+format_make_sdn_list(char **list, struct slapi_dn ***ret,
+ struct slapi_dn ***ret2)
{
- struct slapi_dn **ret;
unsigned int i;
for (i = 0; (list != NULL) && (list[i] != NULL); i++) {
continue;
}
- ret = malloc((i + 1) * sizeof(struct slapi_dn*));
- if (ret != NULL) {
+ *ret = malloc((i + 1) * sizeof(struct slapi_dn*));
+ *ret2 = malloc((i + 1) * sizeof(struct slapi_dn*));
+ if ((*ret != NULL) && (*ret2 != NULL)) {
for (i = 0; (list != NULL) && (list[i] != NULL); i++) {
- ret[i] = slapi_sdn_new_dn_byval(list[i]);
+ (*ret)[i] = slapi_sdn_new_dn_byval(list[i]);
+ (*ret2)[i] = (*ret)[i];
}
- ret[i] = NULL;
+ (*ret)[i] = NULL;
+ (*ret2)[i] = NULL;
+ qsort((*ret2), i, sizeof(**ret2), &compare_sdn);
}
- return ret;
+ return *ret;
}
/* Find the DN in a sorted list. Return either where it is, or where it
@@ -199,66 +226,55 @@ format_bsearch_sdn_list(struct slapi_dn **list, struct slapi_dn *sdn,
return found;
}
-static struct slapi_dn **
-format_add_sdn_list_maybe_sorted(struct slapi_dn ***list, const char *dn,
- bool_t sorted)
+void
+format_add_sdn_list(struct slapi_dn ***list, struct slapi_dn ***list2,
+ const char *dn)
{
- struct slapi_dn **ret, *sdn;
+ struct slapi_dn **ret, **ret2, *sdn;
unsigned int len, point;
sdn = slapi_sdn_new_dn_byval(dn);
- /* Figure out how long the current list is. */
+ /* Figure out the size of the list. */
for (len = 0;
(list != NULL) && (*list != NULL) && ((*list)[len] != NULL);
len++) {
- /* If it's not sorted (because the list is being used as a
- * queue, which is pretty much always), we have to check every
- * entry anyway, so we might as well do it now. */
- if (!sorted && (slapi_sdn_compare((*list)[len], sdn) == 0)) {
- slapi_sdn_free(&sdn);
- return *list;
- }
continue;
}
- if (sorted) {
- /* If it's sorted, we can search for the entry or figure out
- * where to insert the new one. */
- if (format_bsearch_sdn_list(*list, sdn, len, &point)) {
- slapi_sdn_free(&sdn);
- return *list;
- }
- } else {
- /* We're appending. */
- point = len;
+ /* Search the sorted list. */
+ if (format_bsearch_sdn_list(*list2, sdn, len, &point)) {
+ slapi_sdn_free(&sdn);
+ return;
}
+ /* Append the entry to the unsorted list, insert it into the sorted
+ * list. */
ret = malloc((len + 2) * sizeof(struct slapi_dn*));
- if (ret != NULL) {
- /* Copy pointers to entries before the insertion point. */
- memcpy(ret, *list, point * sizeof(ret[0]));
+ ret2 = malloc((len + 2) * sizeof(struct slapi_dn*));
+ if ((ret != NULL) && (ret2 != NULL)) {
+ /* Copy pointers to existing entries. */
+ memcpy(ret, *list, len * sizeof(sdn));
/* The new entry. */
- ret[point] = sdn;
- /* If there are any after the insertion point, add them. */
- if (len > point) {
- memcpy(ret + point + 1, (*list) + point,
- (len - point) * sizeof(ret[0]));
- }
+ ret[len] = sdn;
+ /* The end of the list. */
ret[len + 1] = NULL;
free(*list);
- *list = ret;
+ /* Copy pointers to lesser entries. */
+ if (point > 0) {
+ memcpy(ret2, *list2, point * sizeof(sdn));
+ }
+ /* The new entry. */
+ ret2[point] = sdn;
+ /* The rest of the list. */
+ if (len > point) {
+ memcpy(ret2 + point + 1,
+ (*list2) + point,
+ (len - point) * sizeof(sdn));
+ }
+ ret2[len + 1] = NULL;
+ free(*list2);
}
- return *list;
-}
-
-struct slapi_dn **
-format_add_sdn_list(struct slapi_dn ***list, const char *dn)
-{
- return format_add_sdn_list_maybe_sorted(list, dn, FALSE);
-}
-
-struct slapi_dn **
-format_add_sdn_list_sorted(struct slapi_dn ***list, const char *dn)
-{
- return format_add_sdn_list_maybe_sorted(list, dn, TRUE);
+ *list = ret;
+ *list2 = ret2;
+ return;
}
static int
@@ -278,14 +294,12 @@ format_check_entry(const char *dn, char *filter, void *identity)
}
}
-static struct slapi_dn **
-format_add_filtered_sdn_list(struct slapi_dn ***list, const char *dn,
- char *filter, void *identity)
+static void
+format_add_filtered_sdn_list(struct slapi_dn ***list, struct slapi_dn ***list2,
+ const char *dn, char *filter, void *identity)
{
if (format_check_entry(dn, filter, identity) == 0) {
- return format_add_sdn_list(list, dn);
- } else {
- return *list;
+ format_add_sdn_list(list, list2, dn);
}
}
@@ -306,7 +320,8 @@ format_free_ref_attr_list(struct format_ref_attr_list **list)
if (link->filter != NULL) {
slapi_filter_free(link->filter, TRUE);
}
- format_free_sdn_list(link->base_sdn_list);
+ format_free_sdn_list(link->base_sdn_list,
+ link->base_sdn_list2);
}
free(list[i]->links);
free(list[i]->set);
@@ -369,8 +384,11 @@ format_dup_ref_attr_list(struct format_ref_attr_list **list)
}
}
sdn_list = list[i]->links[j].base_sdn_list;
- ret[i]->links[j].base_sdn_list =
- format_dup_sdn_list(sdn_list);
+ ret[i]->links[j].base_sdn_list = sdn_list;
+ sdn_list = list[i]->links[j].base_sdn_list2;
+ ret[i]->links[j].base_sdn_list2 = sdn_list;
+ format_dup_sdn_list(&ret[i]->links[j].base_sdn_list,
+ &ret[i]->links[j].base_sdn_list2);
ret[i]->n_links++;
}
ret[i]->group = strdup(list[i]->group);
@@ -488,6 +506,7 @@ format_add_ref_attr_list(struct format_ref_attr_list ***list,
}
}
ret[i]->links[j].base_sdn_list = NULL;
+ ret[i]->links[j].base_sdn_list2 = NULL;
}
ret[i]->group = strdup(group);
ret[i]->set = strdup(set);
@@ -670,12 +689,8 @@ format_add_bv_list(struct berval ***bvlist, const struct berval *bv)
if (bvlist == NULL) {
return;
}
- if (*bvlist != NULL) {
- for (i = 0; (*bvlist)[i] != NULL; i++) {
- continue;
- }
- } else {
- i = 0;
+ for (i = 0; (*bvlist != NULL) && ((*bvlist)[i] != NULL); i++) {
+ continue;
}
list = malloc((i + 2) * sizeof(struct berval *));
if (list != NULL) {
@@ -1179,7 +1194,7 @@ format_deref_rx(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e,
{
int i, j, k, argc;
Slapi_Entry *entry;
- Slapi_DN **these, **next;
+ Slapi_DN **these, **these2, **next, **next2;
Slapi_ValueSet *values;
Slapi_Value *value;
int disposition, buffer_flags;
@@ -1197,9 +1212,10 @@ format_deref_rx(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e,
/* Follow the chain: set up the first link. */
these = NULL;
+ these2 = NULL;
choices = NULL;
dn = slapi_entry_get_dn(e);
- format_add_sdn_list(&these, dn);
+ format_add_sdn_list(&these, &these2, dn);
/* For the first N-1 links, read the contents of the named attribute
* from each entry we're examining at this point, and use the values
@@ -1208,6 +1224,7 @@ format_deref_rx(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e,
* caller. */
for (i = 0; (these != NULL) && (i < list->n_links); i++) {
next = NULL;
+ next2 = NULL;
attrs[0] = list->links[i].attribute;
attrs[1] = NULL;
/* Walk the set of entries for this iteration. */
@@ -1221,6 +1238,7 @@ format_deref_rx(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e,
"\"%s\" for \"%s\"\n",
fname, slapi_dn_parent(dn), attrs[0]);
format_add_sdn_list(&list->links[i].base_sdn_list,
+ &list->links[i].base_sdn_list2,
slapi_dn_parent(dn));
/* Pull up the named entry. */
entry = NULL;
@@ -1268,13 +1286,13 @@ format_deref_rx(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e,
}
/* Let's visit the named entry this
* time, in case we're nesting. */
- format_add_filtered_sdn_list(&these,
+ format_add_filtered_sdn_list(&these, &these2,
cvalue,
list->links[i + 1].filter_str,
state->plugin_identity);
/* We need to visit the named entry
* next time. */
- format_add_filtered_sdn_list(&next,
+ format_add_filtered_sdn_list(&next, &next2,
cvalue,
list->links[i + 1].filter_str,
state->plugin_identity);
@@ -1302,13 +1320,15 @@ format_deref_rx(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e,
}
/* Replace the list of entries we're examining now with the
* list of entries we need to examine next. */
- format_free_sdn_list(these);
+ format_free_sdn_list(these, these2);
these = next;
+ these2 = next2;
next = NULL;
+ next2 = NULL;
}
/* Clean up and return any values we found. */
- format_free_sdn_list(these);
+ format_free_sdn_list(these, these2);
if (choices != NULL) {
format_add_choice(outbuf_choices, outbuf, &choices);
return 0;
@@ -1626,7 +1646,7 @@ struct format_referred_r_entry_cbdata {
struct plugin_state *state;
char *attribute;
struct berval ***choices;
- Slapi_DN ***sdn_list;
+ Slapi_DN ***sdn_list, ***sdn_list2;
};
static int
@@ -1643,7 +1663,8 @@ format_referred_r_entry_cb(Slapi_Entry *e, void *cbdata_ptr)
/* Note that we visited this entry. */
slapi_log_error(SLAPI_LOG_PLUGIN, cbdata->state->plugin_desc->spd_id,
"search matched entry \"%s\"\n", slapi_entry_get_dn(e));
- format_add_sdn_list(cbdata->sdn_list, slapi_entry_get_dn(e));
+ format_add_sdn_list(cbdata->sdn_list, cbdata->sdn_list2,
+ slapi_entry_get_dn(e));
sdn = slapi_entry_get_sdn(e);
/* If we're also being asked to pull values out of the entry... */
@@ -1704,6 +1725,7 @@ format_referred_r(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e,
int i, j, k, ret, argc, attrs_list_length;
Slapi_PBlock *local_pb;
Slapi_DN **these_bases, **next_bases, **these_entries, **next_entries;
+ Slapi_DN **these_entries2, **next_entries2;
struct berval **choices;
struct format_referred_r_entry_cbdata entry_cbdata;
struct format_ref_attr_list *list;
@@ -1780,6 +1802,7 @@ format_referred_r(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e,
&set_bases, &set_filter);
for (i = 0; (set_bases != NULL) && (set_bases[i] != NULL); i++) {
format_add_sdn_list(&(list->links[0].base_sdn_list),
+ &(list->links[0].base_sdn_list2),
set_bases[i]);
}
backend_free_set_config(set_bases, set_filter);
@@ -1790,6 +1813,7 @@ format_referred_r(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e,
(set_bases != NULL) && (set_bases[j] != NULL);
j++) {
format_add_sdn_list(&(list->links[i + 1].base_sdn_list),
+ &(list->links[i + 1].base_sdn_list2),
set_bases[j]);
}
backend_free_set_config(set_bases, set_filter);
@@ -1798,9 +1822,12 @@ format_referred_r(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e,
/* Walk the chain, searching for entries which refer to entries at
* this point in the chain. */
these_entries = NULL;
- format_add_sdn_list(&these_entries, slapi_entry_get_dn(e));
+ these_entries2 = NULL;
+ format_add_sdn_list(&these_entries, &these_entries2,
+ slapi_entry_get_dn(e));
choices = NULL;
next_entries = NULL;
+ next_entries2 = NULL;
attrs[0] = attr;
attrs[1] = NULL;
for (i = 0; i < list->n_links - 1; i++) {
@@ -1851,6 +1878,7 @@ format_referred_r(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e,
entry_cbdata.attribute = attr;
entry_cbdata.choices = &choices;
entry_cbdata.sdn_list = &these_entries;
+ entry_cbdata.sdn_list2 = &these_entries2;
slapi_search_internal_callback_pb(local_pb,
&entry_cbdata,
NULL,
@@ -1889,6 +1917,7 @@ format_referred_r(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e,
entry_cbdata.attribute = attr;
entry_cbdata.choices = &choices;
entry_cbdata.sdn_list = &next_entries;
+ entry_cbdata.sdn_list2 = &next_entries2;
slapi_search_internal_callback_pb(local_pb,
&entry_cbdata,
NULL,
@@ -1899,11 +1928,13 @@ format_referred_r(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e,
free(tndn);
}
/* Set up for the next iteration. */
- format_free_sdn_list(these_entries);
+ format_free_sdn_list(these_entries, these_entries2);
these_entries = next_entries;
+ these_entries2 = next_entries2;
next_entries = NULL;
+ next_entries2 = NULL;
}
- format_free_sdn_list(these_entries);
+ format_free_sdn_list(these_entries, these_entries2);
slapi_pblock_destroy(local_pb);
format_free_parsed_args(argv);
diff --git a/src/format.h b/src/format.h
index fb5834b..b5dbf3e 100644
--- a/src/format.h
+++ b/src/format.h
@@ -34,7 +34,7 @@ struct format_ref_attr_list {
struct format_ref_attr_list_link {
char *attribute, *filter_str;
Slapi_Filter *filter;
- struct slapi_dn **base_sdn_list;
+ struct slapi_dn **base_sdn_list, **base_sdn_list2;
} *links;
int n_links;
};
@@ -49,12 +49,9 @@ void format_free_ref_attr_list(struct format_ref_attr_list **);
struct format_ref_attr_list **
format_dup_ref_attr_list(struct format_ref_attr_list **);
-void format_free_sdn_list(struct slapi_dn **list);
-struct slapi_dn **format_dup_sdn_list(struct slapi_dn **list);
-struct slapi_dn **format_make_sdn_list(char **list);
-struct slapi_dn **format_add_sdn_list(struct slapi_dn ***list, const char *dn);
-struct slapi_dn **format_add_sdn_list_sorted(struct slapi_dn ***list,
- const char *dn);
+void format_free_sdn_list(struct slapi_dn **list, struct slapi_dn **list2);
+void format_add_sdn_list(struct slapi_dn ***list, struct slapi_dn ***list2,
+ const char *dn);
void format_free_data(char *data);
char *format_get_data(struct plugin_state *state, struct slapi_entry *e,