cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * CDDL HEADER START
cb5caa98562cf06753163f558cbcfe30b8f4673adjl *
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * The contents of this file are subject to the terms of the
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * Common Development and Distribution License (the "License").
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * You may not use this file except in compliance with the License.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl *
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * or http://www.opensolaris.org/os/licensing.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * See the License for the specific language governing permissions
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * and limitations under the License.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl *
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * When distributing Covered Code, include this CDDL HEADER in each
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * If applicable, add the following below this CDDL HEADER, with the
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * fields enclosed by brackets "[]" replaced with your own identifying
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * information: Portions Copyright [yyyy] [name of copyright owner]
cb5caa98562cf06753163f558cbcfe30b8f4673adjl *
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * CDDL HEADER END
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * Use is subject to license terms.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#pragma ident "%Z%%M% %I% %E% SMI"
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#include <stdio.h>
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#include <stdlib.h>
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#include <string.h>
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#include <ctype.h>
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#include "nscd_db.h"
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * This file implements the database functionality used by the
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * switch and configuration components. The implementation is
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * based on hash and has table. If the need arises in the future,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * the code in this file can be changed to use other algorithms.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * The following lists the functions implemented:
cb5caa98562cf06753163f558cbcfe30b8f4673adjl *
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * _nscd_add_db_entry
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * _nscd_delete_db_entry
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * _nscd_get_db_entry
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * _nscd_alloc_db
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * _nscd_free_db
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * _nscd_walk_db
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * _nscd_delete_db_entry_cookie
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * This structure defines an instance of the hash entry
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * which implements the nscd database entry. The
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * db_entry field should always be the first one in
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * the structure.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjltypedef struct nscd_hash {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_db_entry_t db_entry;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl struct nscd_hash *next_p;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl struct nscd_hash *prev_p;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl} nscd_hash_t;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * This structure defines a nscd database which
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * is implemented as an array of nscd_hash_t.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstruct nscd_db_s {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl int array_size; /* number of elements in hash_tbl_p */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_hash_t **hash_tbl_p;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl};
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * This cookie structure is used to iterate through the
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * database entries contained in a nscd database.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstruct cookie {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl int idx; /* the current bucket */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_hash_t *hash; /* the current hash entry */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_db_t *db; /* the database */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl};
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * FUNCTION: calc_hash
cb5caa98562cf06753163f558cbcfe30b8f4673adjl *
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * Calculate a hash for a string based on the elf_hash
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * algorithm, hash is case insensitive. Uses tolower
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * instead of _tolower because of I18N.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic unsigned long
cb5caa98562cf06753163f558cbcfe30b8f4673adjlcalc_hash(
cb5caa98562cf06753163f558cbcfe30b8f4673adjl const char *str)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl{
cb5caa98562cf06753163f558cbcfe30b8f4673adjl unsigned int hval = 0;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl char ch;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl while (*str != NULL) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl unsigned int g;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ch = (char)*str++;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (isupper(ch))
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ch = _tolower(ch);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl hval = (hval << 4) + ch;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if ((g = (hval & 0xf0000000)) != 0)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl hval ^= g >> 24;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl hval &= ~g;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return ((unsigned long)hval);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * FUNCTION: scan_hash
cb5caa98562cf06753163f558cbcfe30b8f4673adjl *
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * Scan a hash table for a matching hash entry. Assume 'str' is
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * not NULL. If option is NSCD_GET_NEXT_DB_ENTRY and id_num
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * is less than zero, then treats the option as NSCD_GET_FIRST_DB_ENTRY.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic const nscd_hash_t *
cb5caa98562cf06753163f558cbcfe30b8f4673adjlscan_hash(
cb5caa98562cf06753163f558cbcfe30b8f4673adjl int type,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl const char *str,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl const nscd_hash_t *idx_p,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_db_option_t option,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl int id_num)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl{
cb5caa98562cf06753163f558cbcfe30b8f4673adjl int id_matched = 0;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_db_entry_t *db_entry;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl while (idx_p != NULL) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl db_entry = &((nscd_hash_t *)idx_p)->db_entry;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (db_entry->type == type) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (strcasecmp(str, db_entry->name) == 0) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl switch (option) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl case NSCD_GET_FIRST_DB_ENTRY:
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (idx_p);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl case NSCD_GET_EXACT_DB_ENTRY:
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (id_num == db_entry->id_num)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (idx_p);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl break;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl case NSCD_GET_NEXT_DB_ENTRY:
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (id_num < 0)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (idx_p);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (id_matched == 1)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (idx_p);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (id_num == db_entry->id_num)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl id_matched = 1;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl break;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl idx_p = idx_p->next_p;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NULL);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * FUNCTION: _nscd_get_db_entry
cb5caa98562cf06753163f558cbcfe30b8f4673adjl *
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * Find a nscd database entry from a nscd database.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjlconst nscd_db_entry_t *
cb5caa98562cf06753163f558cbcfe30b8f4673adjl_nscd_get_db_entry(
cb5caa98562cf06753163f558cbcfe30b8f4673adjl const nscd_db_t *db,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl int type,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl const char *str,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_db_option_t option,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl int id_num)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl{
cb5caa98562cf06753163f558cbcfe30b8f4673adjl unsigned long hash;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl const nscd_hash_t *idx_p, *hash_p;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (db == NULL || str == NULL)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NULL);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl hash = calc_hash(str);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl idx_p = db->hash_tbl_p[hash % db->array_size];
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl hash_p = scan_hash(type, str, idx_p, option, id_num);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (&hash_p->db_entry);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * FUNCTION: _nscd_add_db_entry
cb5caa98562cf06753163f558cbcfe30b8f4673adjl *
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * Add a nscd database entry to a nscd database. This function
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * is not MT safe. The caller should lock the database to
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * prevent concurrent updates done by other threads.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjlnscd_rc_t
cb5caa98562cf06753163f558cbcfe30b8f4673adjl_nscd_add_db_entry(
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_db_t *db,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl const char *str,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_db_entry_t *entry,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_db_option_t option)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl{
cb5caa98562cf06753163f558cbcfe30b8f4673adjl int i;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl unsigned long hash;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_hash_t *next_p = NULL, *prev_p = NULL;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_hash_t *idx_p, *hash_entry;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_db_entry_t *db_entry;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* find the bucket */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl hash = calc_hash(str);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl i = hash % db->array_size;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl idx_p = db->hash_tbl_p[i];
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* can not replace nothing */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (idx_p == NULL)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (option == NSCD_ADD_DB_ENTRY_REPLACE)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NSCD_DB_ENTRY_NOT_FOUND);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl while (idx_p != NULL) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl db_entry = &idx_p->db_entry;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl switch (option) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl case NSCD_ADD_DB_ENTRY_FIRST:
cb5caa98562cf06753163f558cbcfe30b8f4673adjl next_p = idx_p;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl goto add_entry;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl case NSCD_ADD_DB_ENTRY_REPLACE:
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (db_entry->type != entry->type)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl goto cont;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (strcasecmp(db_entry->name, str) != 0)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl goto cont;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (db_entry->id_num == entry->id_num) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl prev_p = idx_p->prev_p;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl next_p = idx_p->next_p;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl free(idx_p);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl goto add_entry;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl goto cont;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl case NSCD_ADD_DB_ENTRY_IF_NONE:
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (db_entry->type != entry->type)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl break;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (strcasecmp(db_entry->name, str) != 0)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl break;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NSCD_DB_ENTRY_FOUND);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (idx_p->next_p == NULL) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (option == NSCD_ADD_DB_ENTRY_LAST ||
cb5caa98562cf06753163f558cbcfe30b8f4673adjl option == NSCD_ADD_DB_ENTRY_IF_NONE) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl prev_p = idx_p;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl goto add_entry;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl cont:
cb5caa98562cf06753163f558cbcfe30b8f4673adjl idx_p = idx_p->next_p;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl add_entry:
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * the nscd_entry_t field should be the first field
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * in a nscd_hash_t
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl hash_entry = (nscd_hash_t *)entry;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* update the prev link list */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl hash_entry->prev_p = prev_p;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (prev_p == NULL)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl db->hash_tbl_p[i] = hash_entry;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl else
cb5caa98562cf06753163f558cbcfe30b8f4673adjl prev_p->next_p = hash_entry;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* update the next link list */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl hash_entry->next_p = next_p;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (next_p != NULL)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl next_p->prev_p = hash_entry;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NSCD_SUCCESS);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * FUNCTION: _nscd_delete_db_entry
cb5caa98562cf06753163f558cbcfe30b8f4673adjl *
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * Delete a nscd database entry from a nscd database. This
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * function is not MT safe. The caller should lock the
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * database to prevent concurrent updates done by other
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * threads.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjlnscd_rc_t
cb5caa98562cf06753163f558cbcfe30b8f4673adjl_nscd_delete_db_entry(
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_db_t *db,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl int type,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl const char *str,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_db_option_t option,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl int id_num)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl{
cb5caa98562cf06753163f558cbcfe30b8f4673adjl int i;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl int del_more = 0;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl unsigned long hash;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_hash_t *idx_p, *next_p = NULL, *prev_p = NULL;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_db_entry_t *db_entry;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* find the bucket */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl hash = calc_hash(str);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl i = hash % db->array_size;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl idx_p = db->hash_tbl_p[i];
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* delete nothing always works */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (idx_p == NULL)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NSCD_SUCCESS);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl while (idx_p != NULL) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl db_entry = &idx_p->db_entry;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (db_entry->type != type)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl goto cont;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (strcasecmp(db_entry->name, str) != 0)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl goto cont;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl switch (option) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl case NSCD_DEL_FIRST_DB_ENTRY:
cb5caa98562cf06753163f558cbcfe30b8f4673adjl prev_p = idx_p->prev_p;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl next_p = idx_p->next_p;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl del_more = 0;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl break;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl case NSCD_DEL_EXACT_DB_ENTRY:
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (db_entry->id_num == id_num) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl prev_p = idx_p->prev_p;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl next_p = idx_p->next_p;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl del_more = 0;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl } else
cb5caa98562cf06753163f558cbcfe30b8f4673adjl goto cont;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl break;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl case NSCD_DEL_ALL_DB_ENTRY:
cb5caa98562cf06753163f558cbcfe30b8f4673adjl prev_p = idx_p->prev_p;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl next_p = idx_p->next_p;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl break;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (prev_p == NULL)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl db->hash_tbl_p[i] = next_p;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl else
cb5caa98562cf06753163f558cbcfe30b8f4673adjl prev_p->next_p = next_p;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (next_p != NULL)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl next_p->prev_p = prev_p;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl free(idx_p);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (del_more == 0)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl break;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * only when option == NSCD_DEL_ALL_DB_ENTRY
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * will we get here. next_p should be set to
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * idx_p->next_p beforehand
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl idx_p = next_p;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl continue;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl cont:
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl idx_p = idx_p->next_p;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NSCD_SUCCESS);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * FUNCTION: _nscd_alloc_db_entry
cb5caa98562cf06753163f558cbcfe30b8f4673adjl *
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * Allocate and return the memory for a database entry
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * so the caller can insert data and then add it to the
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * database.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjlnscd_db_entry_t *
cb5caa98562cf06753163f558cbcfe30b8f4673adjl_nscd_alloc_db_entry(
cb5caa98562cf06753163f558cbcfe30b8f4673adjl int type,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl const char *name,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl int dataSize,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl int num_data,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl int num_array)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl{
cb5caa98562cf06753163f558cbcfe30b8f4673adjl int size;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl int array_o, data_o;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_hash_t *hash;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl void *p;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* first part: hash data structure and name string */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl size = sizeof (*hash) + strlen(name) + 1;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl array_o = size = roundup(size);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* second part: pointer array to data */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl size += (num_data + num_array) * sizeof (void **);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl size = roundup(size);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* third part: actual data */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl data_o = size;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl size += dataSize;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* allocate the memory */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl hash = (nscd_hash_t *)calloc(1, size);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (hash == NULL)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NULL);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* init the entry based on caller's input */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl hash->db_entry.num_data = num_data;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl hash->db_entry.num_array = num_array;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl hash->db_entry.type = type;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl hash->db_entry.name = (char *)hash + sizeof (*hash);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl p = (char *)hash + array_o;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl hash->db_entry.data_array = (void **)p;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl *(hash->db_entry.data_array) = (char *)hash + data_o;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) strcpy(hash->db_entry.name, name);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (&hash->db_entry);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * FUNCTION: _nscd_delete_db_entry_cookie
cb5caa98562cf06753163f558cbcfe30b8f4673adjl *
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * Delete a database entry using the information from
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * the input 'cookie'.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjlvoid
cb5caa98562cf06753163f558cbcfe30b8f4673adjl_nscd_delete_db_entry_cookie(
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_db_t *db,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl void **cookie)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl{
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_hash_t *hp;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl struct cookie *c;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* snaity check */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (cookie == NULL || *cookie == NULL || db == NULL)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl c = *cookie;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* more snaity check */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (db != c->db || c->hash == NULL ||
cb5caa98562cf06753163f558cbcfe30b8f4673adjl c->idx < 0 || c->idx >= db->array_size)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* retrieve the hash entry from the cookie */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl hp = c->hash;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * Update the next/previous link list.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * Need to update c->hash as well, in case
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * the cookie is also used in a walk-db
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * loop. This is to make sure that the
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * next _nscd_walk_db() call will
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * find the (updated) next hash entry in line.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (hp->prev_p == NULL) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * make sure the current bucket will be
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * walked again if _nscd_walk_db is
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * called next
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl c->hash = NULL;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl db->hash_tbl_p[c->idx] = hp->next_p;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl c->idx--;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl } else {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl c->hash = hp->prev_p;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl hp->prev_p->next_p = hp->next_p;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (hp->next_p != NULL)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl hp->next_p->prev_p = hp->prev_p;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* delete the entry */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl free(hp);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * FUNCTION: _nscd_alloc_db
cb5caa98562cf06753163f558cbcfe30b8f4673adjl *
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * Allocate the space for a nscd database.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl *
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * The input argument, size, indicates the size of the database.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * NSCD_DB_SIZE_LARGE specifies an bucket array of size 67,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * NSCD_DB_SIZE_MEDIUM specifies an bucket array of size 37,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * NSCD_DB_SIZE_SMALL specifies an bucket array of size 13,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * NSCD_DB_SIZE_TINY specifies an bucket array of size 3.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjlnscd_db_t *
cb5caa98562cf06753163f558cbcfe30b8f4673adjl_nscd_alloc_db(
cb5caa98562cf06753163f558cbcfe30b8f4673adjl int size)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl{
cb5caa98562cf06753163f558cbcfe30b8f4673adjl int sz;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_db_t *db;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* allocate the database */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl db = (nscd_db_t *)calloc(1, sizeof (nscd_db_t));
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (db == NULL)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NULL);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* allocate the bucket array */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (size == NSCD_DB_SIZE_LARGE)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl sz = 67;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl else if (size == NSCD_DB_SIZE_MEDIUM)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl sz = 37;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl else if (size == NSCD_DB_SIZE_SMALL)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl sz = 13;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl else if (size == NSCD_DB_SIZE_TINY)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl sz = 3;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl db->hash_tbl_p = (nscd_hash_t **)calloc(sz + 1,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl sizeof (nscd_hash_t *));
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (db->hash_tbl_p == NULL) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl free(db);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NULL);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl db->array_size = sz;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (db);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * FUNCTION: _nscd_free_db
cb5caa98562cf06753163f558cbcfe30b8f4673adjl *
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * Delete a nscd database.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjlvoid
cb5caa98562cf06753163f558cbcfe30b8f4673adjl_nscd_free_db(
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_db_t *db)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl{
cb5caa98562cf06753163f558cbcfe30b8f4673adjl int i;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_hash_t *hp, *next_p;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * find non-empty buckets and for each one of them,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * delete all the database entries in it's link list
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl for (i = 0; i < db->array_size; i++) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl hp = db->hash_tbl_p[i];
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl while (hp != NULL) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl next_p = hp->next_p;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl free(hp);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl hp = next_p;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* free the bucket array */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl free(db->hash_tbl_p);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl free(db);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * FUNCTION: _nscd_walk_db
cb5caa98562cf06753163f558cbcfe30b8f4673adjl *
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * Iterate through the database entries contained in
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * a nscd database and return one entry at a time.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * The cookie structure is used to indicate the
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * location of the returned entry for the next call
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * to this function. For the very first call, *cookie
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * should be set to NULL. For subsequent calls, the one
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * returned by the previous call sould be used.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjlnscd_db_entry_t *
cb5caa98562cf06753163f558cbcfe30b8f4673adjl_nscd_walk_db(
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_db_t *db,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl void **cookie)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl{
cb5caa98562cf06753163f558cbcfe30b8f4673adjl struct cookie *c;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* sanity check */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (cookie == NULL || db == NULL)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NULL);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (*cookie != NULL) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl c = *cookie;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * More sanity check. _nscd_delete_db_entry_cookie()
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * could change c->idx to -1.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (db != c->db ||
cb5caa98562cf06753163f558cbcfe30b8f4673adjl c->idx < -1 || c->idx >= db->array_size)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NULL);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* is there a next entry ? */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (c->hash != NULL)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl c->hash = c->hash->next_p;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* yes, return it */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (c->hash != NULL) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (&c->hash->db_entry);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl } else {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl c = (struct cookie *)calloc(1, sizeof (*c));
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (c == NULL)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NULL);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl c->idx = -1;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl c->hash = NULL;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl c->db = db;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* find the first non-empty bucket */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl for (c->idx++; c->idx < db->array_size; c->idx++) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl c->hash = db->hash_tbl_p[c->idx];
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (c->hash != NULL)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl break;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* no (more) non-empty bucket, we are done */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (c->hash == NULL) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl free(c);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl *cookie = NULL;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NULL);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl *cookie = c;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (&c->hash->db_entry);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}