summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorNalin Dahyabhai <nalin.dahyabhai@pobox.com>2008-04-02 17:24:19 -0400
committerNalin Dahyabhai <nalin.dahyabhai@pobox.com>2008-04-02 17:24:19 -0400
commit7d9f164cdc7ae0e7d1b0a967c1ea52a5e5e5a5ca (patch)
tree142315b6b5faaab9a0eb07ba9a0d5a897845c70f /src
parent2ec2f4549722921c1ad8a0d3b994a872fe781fd3 (diff)
downloadslapi-nis-7d9f164cdc7ae0e7d1b0a967c1ea52a5e5e5a5ca.tar.gz
slapi-nis-7d9f164cdc7ae0e7d1b0a967c1ea52a5e5e5a5ca.tar.xz
slapi-nis-7d9f164cdc7ae0e7d1b0a967c1ea52a5e5e5a5ca.zip
- add an explicit initialization step, and work out how to add/remove map
configuration at an API level
Diffstat (limited to 'src')
-rw-r--r--src/dummymap.c5
-rw-r--r--src/map.c292
-rw-r--r--src/map.h1
-rw-r--r--src/plugin.c5
4 files changed, 276 insertions, 27 deletions
diff --git a/src/dummymap.c b/src/dummymap.c
index 07e6ef4..c648f80 100644
--- a/src/dummymap.c
+++ b/src/dummymap.c
@@ -66,6 +66,11 @@ struct domain domains[] = {
{NULL, NULL},
};
+void
+map_init(struct plugin_state *state)
+{
+}
+
bool_t
map_supports_domain(struct plugin_state *state,
const char *domain,
diff --git a/src/map.c b/src/map.c
index 2d23a99..1298690 100644
--- a/src/map.c
+++ b/src/map.c
@@ -47,6 +47,7 @@ struct {
int n_domains;
} map_data;
+/* Utility function - find the domain record for the named domain. */
static struct domain *
map_find_domain(struct plugin_state *state, const char *domain_name)
{
@@ -59,6 +60,8 @@ map_find_domain(struct plugin_state *state, const char *domain_name)
return NULL;
}
+/* Utility function - find the map record for the named map in the named
+ * domain. */
static struct map *
map_find_map(struct plugin_state *state,
const char *domain_name, const char *map_name)
@@ -76,6 +79,32 @@ map_find_map(struct plugin_state *state,
return NULL;
}
+/* Utility function - find a specific entry in the named map in the named
+ * domain. */
+static struct entry *
+map_find_entry(struct plugin_state *state,
+ const char *domain_name, const char *map_name,
+ unsigned int key_len, const char *key)
+{
+ int i;
+ struct map *map;
+ struct entry *entry;
+ map = map_find_map(state, domain_name, map_name);
+ if (map == NULL) {
+ return NULL;
+ }
+ for (entry = map->entries; entry != NULL; entry = entry->next) {
+ if ((entry->key_len == key_len) &&
+ (memcmp(entry->key, key, key_len) == 0)) {
+ return entry;
+ }
+ }
+ return NULL;
+}
+
+/* Query function: check if we have a record for the domain. Return that
+ * information in "supported", and return TRUE unless we ran into internal
+ * errors. */
bool_t
map_supports_domain(struct plugin_state *state,
const char *domain_name,
@@ -85,6 +114,9 @@ map_supports_domain(struct plugin_state *state,
return TRUE;
}
+/* Query function: check if we have a record for the map in the domain. Return
+ * that information in "supported", and return TRUE unless we ran into internal
+ * errors. */
bool_t
map_supports_map(struct plugin_state *state,
const char *domain_name, const char *map_name,
@@ -94,6 +126,8 @@ map_supports_map(struct plugin_state *state,
return TRUE;
}
+/* Query function: return an indication of the map's age. Should never
+ * decrease. */
bool_t
map_order(struct plugin_state *state,
const char *domain_name, const char *map_name,
@@ -109,29 +143,26 @@ map_order(struct plugin_state *state,
}
}
+/* Query function: return the entry value which matches the key. Return TRUE
+ * if we can find a value which corresponds to the key. */
bool_t
map_match(struct plugin_state *state,
const char *domain_name, const char *map_name,
unsigned int key_len, char *key,
unsigned int *value_len, char **value)
{
- struct map *map;
struct entry *entry;
- map = map_find_map(state, domain_name, map_name);
- if (map == NULL) {
+ entry = map_find_entry(state, domain_name, map_name, key_len, key);
+ if (entry == NULL) {
return FALSE;
}
- for (entry = map->entries; entry != NULL; entry = entry->next) {
- if ((entry->key_len == key_len) &&
- (memcmp(entry->key, key, key_len) == 0)) {
- *value_len = entry->value_len;
- *value = entry->value;
- return TRUE;
- }
- }
- return FALSE;
+ *value_len = entry->value_len;
+ *value = entry->value;
+ return TRUE;
}
+/* Query function: return the first entry's key and value for a map. Return
+ * FALSE if there's no domain or map. */
bool_t
map_first(struct plugin_state *state,
const char *domain_name, const char *map_name,
@@ -155,6 +186,9 @@ map_first(struct plugin_state *state,
return TRUE;
}
+/* Query function: return the successor entry's key and value for a map.
+ * Return FALSE if there's no domain or map, or if the predecessor was the last
+ * key in the map. */
bool_t
map_next(struct plugin_state *state,
const char *domain_name, const char *map_name,
@@ -162,25 +196,229 @@ map_next(struct plugin_state *state,
unsigned int *next_key_len, char **next_key,
unsigned int *next_value_len, char **next_value)
{
- struct map *map;
struct entry *entry;
- map = map_find_map(state, domain_name, map_name);
- if (map == NULL) {
+ entry = map_find_entry(state, domain_name, map_name, prev_len, prev);
+ if ((entry == NULL) || (entry->next == NULL)) {
return FALSE;
}
- for (entry = map->entries; entry != NULL; entry = entry->next) {
- if ((entry->key_len == prev_len) &&
- (memcmp(entry->key, prev, prev_len) == 0)) {
- entry = entry->next;
- if (entry == NULL) {
- return FALSE;
+ *next_key_len = entry->next->key_len;
+ *next_key = entry->next->key;
+ *next_value_len = entry->next->value_len;
+ *next_value = entry->next->value;
+ return TRUE;
+}
+
+/* Remove a map from the configuration, removing its domain record if the map
+ * was the only one that the domain contained. */
+static void
+map_config_unset_map(struct plugin_state *state,
+ const char *domain_name,
+ const char *map_name)
+{
+ struct domain *domain;
+ struct map map;
+ struct entry *entry, *next;
+ int i;
+ /* Check that we have a domain record that matches. */
+ domain = map_find_domain(state, domain_name);
+ if (domain == NULL) {
+ return;
+ }
+ /* Locate the map, remove it from the array of maps. */
+ memset(&map, 0, sizeof(map));
+ for (i = 0; i < domain->n_maps; i++) {
+ if (strcmp(domain->maps[i].name, map_name) == 0) {
+ /* Save the map's contents. */
+ map = domain->maps[i];
+ /* Close the hole in the array. */
+ domain->n_maps--;
+ if (i != domain->n_maps) {
+ memcpy(&domain->maps[i], &domain->maps[i + 1],
+ sizeof(map) * (domain->n_maps - i));
+ }
+ break;
+ }
+ }
+ /* Assuming we didn't fall off the end of the array... */
+ if (i < domain->n_maps) {
+ /* ... free the map's contents. */
+ free(map.name);
+ free(map.search_base);
+ map.search_scope = -1;
+ free(map.entry_filter);
+ free(map.key_attribute);
+ free(map.value_format);
+ map.last_changed = 0;
+ for (entry = map.entries; entry != NULL; entry = next) {
+ next = entry->next;
+ free(entry->dn);
+ entry->key_len = 0;
+ free(entry->key);
+ entry->value_len = 0;
+ free(entry->value);
+ free(entry);
+ }
+ }
+ /* If the domain now contains no maps, remove it, too .*/
+ if (domain->n_maps == 0) {
+ /* Find the domain entry. */
+ for (i = 0; i < map_data.n_domains; i++) {
+ if (strcmp(map_data.domains[i].name,
+ domain_name) == 0) {
+ /* Free the components. */
+ free(domain->name);
+ free(domain->maps);
+ /* Fill in the hole in the domains array. */
+ map_data.n_domains--;
+ if (i != map_data.n_domains) {
+ memcpy(&map_data.domains[i],
+ &map_data.domains[i + 1],
+ sizeof(*domain) *
+ (map_data.n_domains - i));
+ }
+ break;
+ }
+ }
+ }
+}
+
+/* Add a map from the configuration, adding a domain for it if necessary. */
+static void
+map_config_add_map(struct plugin_state *state,
+ const char *domain_name,
+ const char *map_name,
+ const char *search_base,
+ int search_scope,
+ const char *entry_filter,
+ const char *key_attribute,
+ const char *value_format)
+{
+ struct domain *domain, *domains;
+ struct map *map, *maps, map_template;
+ struct entry *entry, *next;
+ int i;
+ /* Locate the domain for this map. */
+ domain = NULL;
+ for (i = 0; i < map_data.n_domains; i++) {
+ if (strcmp(map_data.domains[i].name, domain_name) == 0) {
+ domain = &map_data.domains[i];
+ break;
+ }
+ }
+ /* If we have to, then add the domain list. */
+ if (domain == NULL) {
+ /* Allocate space. */
+ domains = malloc(sizeof(*domain) * (map_data.n_domains + 1));
+ if (domains != NULL) {
+ /* Populate the new domain. */
+ domain = &domains[map_data.n_domains];
+ memset(domain, 0, sizeof(*domain));
+ domain->name = strdup(domain_name);
+ if (domain->name != NULL) {
+ /* Copy in existing data. */
+ memcpy(domains, map_data.domains,
+ sizeof(*domain) * map_data.n_domains);
+ /* Switcheroo. */
+ free(map_data.domains);
+ map_data.domains = domains;
+ map_data.n_domains++;
+ } else {
+ free(domains);
+ /* XXX */
+ return;
+ }
+ }
+ }
+ /* Check if the map's already been defined in the domain. */
+ map = NULL;
+ for (i = 0; i < domain->n_maps; i++) {
+ if (strcmp(domain->maps[i].name, map_name) == 0) {
+ map = &domain->maps[i];
+ break;
+ }
+ }
+ /* We need to either create a new map entry or mess with an old one. */
+ if (map != NULL) {
+ /* Overwrite map data. */
+ memset(&map_template, 0, sizeof(map_template));
+ map_template.name = map->name;
+ map_template.search_base = strdup(search_base);
+ map_template.search_scope = search_scope;
+ map_template.entry_filter = strdup(entry_filter);
+ map_template.key_attribute = strdup(key_attribute);
+ map_template.value_format = strdup(value_format);
+ if ((map_template.name != NULL) &&
+ (map_template.search_base != NULL) &&
+ (map_template.entry_filter != NULL) &&
+ (map_template.key_attribute != NULL) &&
+ (map_template.value_format != NULL)) {
+ /* Free the old search configuration. */
+ free(map->search_base);
+ free(map->entry_filter);
+ free(map->key_attribute);
+ free(map->value_format);
+ /* Clear the old entries list. */
+ for (entry = map->entries;
+ entry != NULL;
+ entry = next) {
+ next = entry->next;
+ free(entry->dn);
+ entry->key_len = 0;
+ free(entry->key);
+ entry->value_len = 0;
+ free(entry->value);
+ free(entry);
+ }
+ /* Actually overwrite the map data. */
+ *map = map_template;
+ } else {
+ free(map_template.search_base);
+ free(map_template.entry_filter);
+ free(map_template.key_attribute);
+ free(map_template.value_format);
+ /* XXX */
+ return;
+ }
+ } else {
+ /* Allocate space. */
+ maps = malloc(sizeof(*map) * (domain->n_maps + 1));
+ if (maps != NULL) {
+ /* Populate the new map. */
+ map = &maps[domain->n_maps];
+ memset(map, 0, sizeof(*map));
+ map->name = strdup(map_name);
+ map->search_base = strdup(search_base);
+ map->search_scope = search_scope;
+ map->entry_filter = strdup(entry_filter);
+ map->key_attribute = strdup(key_attribute);
+ map->value_format = strdup(value_format);
+ if ((map->name != NULL) &&
+ (map->search_base != NULL) &&
+ (map->entry_filter != NULL) &&
+ (map->key_attribute != NULL) &&
+ (map->value_format != NULL)) {
+ /* Copy in existing data. */
+ memcpy(maps, domain->maps,
+ sizeof(*map) * domain->n_maps);
+ /* Switcheroo. */
+ free(domain->maps);
+ domain->maps = maps;
+ domain->n_maps++;
+ } else {
+ free(map->name);
+ free(map->search_base);
+ free(map->entry_filter);
+ free(map->key_attribute);
+ free(map->value_format);
+ free(maps);
+ /* XXX */
+ return;
}
- *next_key_len = entry->key_len;
- *next_key = entry->key;
- *next_value_len = entry->value_len;
- *next_value = entry->value;
- return TRUE;
}
}
- return FALSE;
+}
+
+void
+map_init(struct plugin_state *state)
+{
}
diff --git a/src/map.h b/src/map.h
index dc42c42..2964ab5 100644
--- a/src/map.h
+++ b/src/map.h
@@ -1,4 +1,5 @@
struct plugin_state;
+void map_init(struct plugin_state *state);
bool_t map_supports_domain(struct plugin_state *state,
const char *domain,
bool_t *supported);
diff --git a/src/plugin.c b/src/plugin.c
index 6315b68..8f412f1 100644
--- a/src/plugin.c
+++ b/src/plugin.c
@@ -25,6 +25,7 @@
#include <dirsrv/slapi-plugin.h>
#include "dispatch.h"
+#include "map.h"
#include "nis.h"
#include "plugin.h"
#include "portmap.h"
@@ -229,6 +230,10 @@ plugin_state_init(struct plugin_state **lstate)
slapi_log_error(SLAPI_LOG_PLUGIN,
plugin_description.spd_id,
"set up %d listening sockets\n", state->n_listeners);
+ map_init(state);
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ plugin_description.spd_id,
+ "initialized maps\n");
*lstate = state;
return 0;
failed: