diff options
author | Nalin Dahyabhai <nalin.dahyabhai@pobox.com> | 2008-04-02 17:24:19 -0400 |
---|---|---|
committer | Nalin Dahyabhai <nalin.dahyabhai@pobox.com> | 2008-04-02 17:24:19 -0400 |
commit | 7d9f164cdc7ae0e7d1b0a967c1ea52a5e5e5a5ca (patch) | |
tree | 142315b6b5faaab9a0eb07ba9a0d5a897845c70f /src | |
parent | 2ec2f4549722921c1ad8a0d3b994a872fe781fd3 (diff) | |
download | slapi-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.c | 5 | ||||
-rw-r--r-- | src/map.c | 292 | ||||
-rw-r--r-- | src/map.h | 1 | ||||
-rw-r--r-- | src/plugin.c | 5 |
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, @@ -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) +{ } @@ -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: |