a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina/*
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina Authors:
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina Pavel Březina <pbrezina@redhat.com>
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina Copyright (C) 2016 Red Hat
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina This program is free software; you can redistribute it and/or modify
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina it under the terms of the GNU General Public License as published by
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina the Free Software Foundation; either version 3 of the License, or
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina (at your option) any later version.
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina This program is distributed in the hope that it will be useful,
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina but WITHOUT ANY WARRANTY; without even the implied warranty of
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina GNU General Public License for more details.
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina You should have received a copy of the GNU General Public License
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina along with this program. If not, see <http://www.gnu.org/licenses/>.
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina*/
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina#include <talloc.h>
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina#include <dhash.h>
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina#include "util/util.h"
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina#include "util/sss_ptr_hash.h"
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březinastatic bool sss_ptr_hash_check_type(void *ptr, const char *type)
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina{
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina void *type_ptr;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina type_ptr = talloc_check_name(ptr, type);
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina if (type_ptr == NULL) {
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina DEBUG(SSSDBG_CRIT_FAILURE,
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina "Invalid data type detected. Expected [%s], got [%s].\n",
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina type, talloc_get_name(ptr));
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina return false;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina }
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina return true;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina}
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březinastruct sss_ptr_hash_delete_data {
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina hash_delete_callback *callback;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina void *pvt;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina};
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březinastruct sss_ptr_hash_value {
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina struct sss_ptr_hash_spy *spy;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina void *ptr;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina};
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březinastruct sss_ptr_hash_spy {
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina struct sss_ptr_hash_value *value;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina hash_table_t *table;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina const char *key;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina};
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březinastatic int
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březinasss_ptr_hash_spy_destructor(struct sss_ptr_hash_spy *spy)
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina{
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina spy->value->spy = NULL;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina spy->value->ptr = NULL;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina /* This results in removing entry from hash table and freeing the value. */
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina sss_ptr_hash_delete(spy->table, spy->key, false);
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina return 0;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina}
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březinastatic struct sss_ptr_hash_spy *
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březinasss_ptr_hash_spy_create(TALLOC_CTX *mem_ctx,
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina hash_table_t *table,
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina const char *key,
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina struct sss_ptr_hash_value *value)
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina{
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina struct sss_ptr_hash_spy *spy;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina spy = talloc_zero(mem_ctx, struct sss_ptr_hash_spy);
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina if (spy == NULL) {
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory!\n");
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina return NULL;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina }
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina spy->key = talloc_strdup(spy, key);
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina if (spy->key == NULL) {
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina talloc_free(spy);
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina return NULL;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina }
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina spy->table = table;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina spy->value = value;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina talloc_set_destructor(spy, sss_ptr_hash_spy_destructor);
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina return spy;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina}
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březinastatic int
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březinasss_ptr_hash_value_destructor(struct sss_ptr_hash_value *value)
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina{
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina if (value->spy != NULL) {
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina /* Disable spy destructor and free it. */
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina talloc_set_destructor(value->spy, NULL);
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina talloc_zfree(value->spy);
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina }
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina return 0;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina}
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březinastatic struct sss_ptr_hash_value *
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březinasss_ptr_hash_value_create(hash_table_t *table,
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina const char *key,
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina void *talloc_ptr)
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina{
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina struct sss_ptr_hash_value *value;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina value = talloc_zero(table, struct sss_ptr_hash_value);
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina if (value == NULL) {
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina return NULL;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina }
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina value->spy = sss_ptr_hash_spy_create(talloc_ptr, table, key, value);
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina if (value->spy == NULL) {
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina talloc_free(value);
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina return NULL;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina }
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina value->ptr = talloc_ptr;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina talloc_set_destructor(value, sss_ptr_hash_value_destructor);
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina return value;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina}
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březinastatic void
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březinasss_ptr_hash_delete_cb(hash_entry_t *item,
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina hash_destroy_enum deltype,
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina void *pvt)
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina{
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina struct sss_ptr_hash_delete_data *data;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina struct sss_ptr_hash_value *value;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina void *ptr;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina data = talloc_get_type(pvt, struct sss_ptr_hash_delete_data);
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina if (data == NULL) {
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina DEBUG(SSSDBG_CRIT_FAILURE, "Invalid data!\n");
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina return;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina }
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina value = talloc_get_type(item->value.ptr, struct sss_ptr_hash_value);
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina if (value == NULL) {
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina DEBUG(SSSDBG_CRIT_FAILURE, "Invalid value!\n");
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina return;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina }
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina ptr = value->ptr;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina /* Free value. */
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina talloc_free(value);
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina /* Switch to the input value and call custom callback. */
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina if (data->callback != NULL) {
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina item->value.ptr = ptr;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina data->callback(item, deltype, data->pvt);
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina }
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina}
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březinahash_table_t *sss_ptr_hash_create(TALLOC_CTX *mem_ctx,
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina hash_delete_callback *del_cb,
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina void *del_cb_pvt)
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina{
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina struct sss_ptr_hash_delete_data *data;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina hash_table_t *table;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina errno_t ret;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina data = talloc_zero(NULL, struct sss_ptr_hash_delete_data);
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina if (data == NULL) {
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina return NULL;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina }
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina data->callback = del_cb;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina data->pvt = del_cb_pvt;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina ret = sss_hash_create_ex(mem_ctx, 10, &table, 0, 0, 0, 0,
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina sss_ptr_hash_delete_cb, data);
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina if (ret != EOK) {
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create hash table [%d]: %s\n",
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina ret, sss_strerror(ret));
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina talloc_free(data);
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina return NULL;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina }
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina talloc_steal(table, data);
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina return table;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina}
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březinaerrno_t _sss_ptr_hash_add(hash_table_t *table,
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina const char *key,
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina void *talloc_ptr,
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina const char *type,
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina bool override)
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina{
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina struct sss_ptr_hash_value *value;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina hash_value_t table_value;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina hash_key_t table_key;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina int hret;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina if (table == NULL || key == NULL) {
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina DEBUG(SSSDBG_CRIT_FAILURE, "Invalid input!\n");
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina return EINVAL;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina }
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina if (!sss_ptr_hash_check_type(talloc_ptr, type)) {
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina return ERR_INVALID_DATA_TYPE;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina }
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina value = sss_ptr_hash_value_create(table, key, talloc_ptr);
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina if (value == NULL) {
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina return ENOMEM;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina }
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina table_key.type = HASH_KEY_STRING;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina table_key.str = discard_const_p(char, key);
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina table_value.type = HASH_VALUE_PTR;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina table_value.ptr = value;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina if (override == false && hash_has_key(table, &table_key)) {
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina return EEXIST;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina }
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina hret = hash_enter(table, &table_key, &table_value);
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina if (hret != HASH_SUCCESS) {
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina DEBUG(SSSDBG_CRIT_FAILURE, "Unable to add key %s!\n", key);
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina talloc_free(value);
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina return EIO;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina }
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina return EOK;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina}
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březinastatic struct sss_ptr_hash_value *
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březinasss_ptr_hash_lookup_internal(hash_table_t *table,
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina const char *key)
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina{
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina hash_value_t table_value;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina hash_key_t table_key;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina int hret;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina table_key.type = HASH_KEY_STRING;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina table_key.str = discard_const_p(char, key);
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina hret = hash_lookup(table, &table_key, &table_value);
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina if (hret == HASH_ERROR_KEY_NOT_FOUND) {
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina return NULL;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina } else if (hret != HASH_SUCCESS) {
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina DEBUG(SSSDBG_CRIT_FAILURE, "Unable to search hash table [%d]\n", hret);
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina return NULL;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina }
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina /* Check value type. */
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina if (table_value.type != HASH_VALUE_PTR) {
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina DEBUG(SSSDBG_CRIT_FAILURE, "Invalid value type found: %d\n",
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina table_value.type);
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina return NULL;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina }
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina if (!sss_ptr_hash_check_type(table_value.ptr, "struct sss_ptr_hash_value")) {
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina return NULL;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina }
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina return table_value.ptr;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina}
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březinavoid *_sss_ptr_hash_lookup(hash_table_t *table,
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina const char *key,
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina const char *type)
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina{
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina struct sss_ptr_hash_value *value;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina value = sss_ptr_hash_lookup_internal(table, key);
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina if (value == NULL || value->ptr == NULL) {
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina return NULL;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina }
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina if (!sss_ptr_hash_check_type(value->ptr, type)) {
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina return NULL;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina }
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina return value->ptr;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina}
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březinavoid sss_ptr_hash_delete(hash_table_t *table,
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina const char *key,
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina bool free_value)
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina{
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina struct sss_ptr_hash_value *value;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina hash_key_t table_key;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina int hret;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina void *ptr;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina if (table == NULL || key == NULL) {
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina return;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina }
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina value = sss_ptr_hash_lookup_internal(table, key);
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina if (value == NULL) {
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina /* Value not found. */
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina return;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina }
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina ptr = value->ptr;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina table_key.type = HASH_KEY_STRING;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina table_key.str = discard_const_p(char, key);
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina /* Delete table entry. This will free value and spy in delete callback. */
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina hret = hash_delete(table, &table_key);
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina if (hret != HASH_SUCCESS && hret != HASH_ERROR_KEY_NOT_FOUND) {
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina DEBUG(SSSDBG_CRIT_FAILURE, "Unable to remove key from table [%d]\n",
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina hret);
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina }
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina /* Also free the original value if requested. */
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina if (free_value) {
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina talloc_free(ptr);
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina }
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina return;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina}
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březinavoid sss_ptr_hash_delete_all(hash_table_t *table,
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina bool free_values)
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina{
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina struct sss_ptr_hash_value *value;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina hash_value_t *values;
50a6d01182aba430313746ba71c55e364bf9c6d6Sumit Bose unsigned long count;
50a6d01182aba430313746ba71c55e364bf9c6d6Sumit Bose unsigned long i;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina int hret;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina void *ptr;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina if (table == NULL) {
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina return;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina }
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina hret = hash_values(table, &count, &values);
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina if (hret != HASH_SUCCESS) {
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina DEBUG(SSSDBG_CRIT_FAILURE, "Unable to get values [%d]\n", hret);
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina return;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina }
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina for (i = 0; i < count; i++) {
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina value = values[i].ptr;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina ptr = value->ptr;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina /* This will remove the entry from hash table and free value. */
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina talloc_free(value->spy);
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina if (free_values) {
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina /* Also free the original value. */
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina talloc_free(ptr);
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina }
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina }
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina return;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina}
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březinabool sss_ptr_hash_has_key(hash_table_t *table,
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina const char *key)
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina{
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina hash_key_t table_key;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina table_key.type = HASH_KEY_STRING;
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina table_key.str = discard_const_p(char, key);
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina return hash_has_key(table, &table_key);
a5a3bbb0bbaeb8946c228c2fb7f0cf450595dd3ePavel Březina}