config.c revision 194097
1158115Sume/*- 2158115Sume * Copyright (c) 2005 Michael Bushkov <bushman@rsu.ru> 3158115Sume * All rights reserved. 4158115Sume * 5158115Sume * Redistribution and use in source and binary forms, with or without 6158115Sume * modification, are permitted provided that the following conditions 7158115Sume * are met: 8158115Sume * 1. Redistributions of source code must retain the above copyright 9158115Sume * notice, this list of conditions and the following disclaimer. 10158115Sume * 2. Redistributions in binary form must reproduce the above copyright 11158115Sume * notice, this list of conditions and the following disclaimer in the 12158115Sume * documentation and/or other materials provided with the distribution. 13158115Sume * 14158115Sume * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15158115Sume * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16158115Sume * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17158115Sume * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18158115Sume * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19158115Sume * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20158115Sume * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21158115Sume * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22158115Sume * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23158115Sume * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24158115Sume * SUCH DAMAGE. 25158115Sume * 26158115Sume */ 27158115Sume 28158115Sume#include <sys/cdefs.h> 29158115Sume__FBSDID("$FreeBSD: head/usr.sbin/nscd/config.c 194097 2009-06-13 01:22:56Z des $"); 30158115Sume 31194089Sdes#include <sys/stat.h> 32194089Sdes#include <sys/time.h> 33194089Sdes 34158115Sume#include <assert.h> 35158115Sume#include <math.h> 36194089Sdes#include <nsswitch.h> 37194089Sdes#include <pthread.h> 38158115Sume#include <stdio.h> 39158115Sume#include <stdlib.h> 40158115Sume#include <string.h> 41194089Sdes 42158115Sume#include "config.h" 43158115Sume#include "debug.h" 44158115Sume#include "log.h" 45158115Sume 46158115Sume/* 47158115Sume * Default entries, which always exist in the configuration 48158115Sume */ 49158115Sumeconst char *c_default_entries[6] = { 50158115Sume NSDB_PASSWD, 51158115Sume NSDB_GROUP, 52158115Sume NSDB_HOSTS, 53158115Sume NSDB_SERVICES, 54158115Sume NSDB_PROTOCOLS, 55158115Sume NSDB_RPC 56158115Sume }; 57158115Sume 58158115Sumestatic int configuration_entry_cmp(const void *, const void *); 59158115Sumestatic int configuration_entry_sort_cmp(const void *, const void *); 60158115Sumestatic int configuration_entry_cache_mp_sort_cmp(const void *, const void *); 61158115Sumestatic int configuration_entry_cache_mp_cmp(const void *, const void *); 62158115Sumestatic int configuration_entry_cache_mp_part_cmp(const void *, const void *); 63158115Sumestatic struct configuration_entry *create_configuration_entry(const char *, 64158115Sume struct timeval const *, struct timeval const *, 65158115Sume struct common_cache_entry_params const *, 66158115Sume struct common_cache_entry_params const *, 67158115Sume struct mp_cache_entry_params const *); 68158115Sume 69158115Sumestatic int 70158115Sumeconfiguration_entry_sort_cmp(const void *e1, const void *e2) 71158115Sume{ 72158115Sume return (strcmp((*((struct configuration_entry **)e1))->name, 73158115Sume (*((struct configuration_entry **)e2))->name 74158115Sume )); 75158115Sume} 76158115Sume 77158115Sumestatic int 78158115Sumeconfiguration_entry_cmp(const void *e1, const void *e2) 79158115Sume{ 80158115Sume return (strcmp((const char *)e1, 81158115Sume (*((struct configuration_entry **)e2))->name 82158115Sume )); 83158115Sume} 84158115Sume 85158115Sumestatic int 86158115Sumeconfiguration_entry_cache_mp_sort_cmp(const void *e1, const void *e2) 87158115Sume{ 88158115Sume return (strcmp((*((cache_entry *)e1))->params->entry_name, 89158115Sume (*((cache_entry *)e2))->params->entry_name 90158115Sume )); 91158115Sume} 92158115Sume 93158115Sumestatic int 94158115Sumeconfiguration_entry_cache_mp_cmp(const void *e1, const void *e2) 95158115Sume{ 96158115Sume return (strcmp((const char *)e1, 97158115Sume (*((cache_entry *)e2))->params->entry_name 98158115Sume )); 99158115Sume} 100158115Sume 101158115Sumestatic int 102158115Sumeconfiguration_entry_cache_mp_part_cmp(const void *e1, const void *e2) 103158115Sume{ 104158115Sume return (strncmp((const char *)e1, 105158115Sume (*((cache_entry *)e2))->params->entry_name, 106158115Sume strlen((const char *)e1) 107158115Sume )); 108158115Sume} 109158115Sume 110158115Sumestatic struct configuration_entry * 111158115Sumecreate_configuration_entry(const char *name, 112158115Sume struct timeval const *common_timeout, 113158115Sume struct timeval const *mp_timeout, 114158115Sume struct common_cache_entry_params const *positive_params, 115158115Sume struct common_cache_entry_params const *negative_params, 116158115Sume struct mp_cache_entry_params const *mp_params) 117158115Sume{ 118158115Sume struct configuration_entry *retval; 119158115Sume size_t size; 120158115Sume int res; 121158115Sume 122158115Sume TRACE_IN(create_configuration_entry); 123158115Sume assert(name != NULL); 124158115Sume assert(positive_params != NULL); 125158115Sume assert(negative_params != NULL); 126158115Sume assert(mp_params != NULL); 127158115Sume 128183770Sdelphij retval = (struct configuration_entry *)calloc(1, 129158115Sume sizeof(struct configuration_entry)); 130158115Sume assert(retval != NULL); 131158115Sume 132158115Sume res = pthread_mutex_init(&retval->positive_cache_lock, NULL); 133158115Sume if (res != 0) { 134158115Sume free(retval); 135158115Sume LOG_ERR_2("create_configuration_entry", 136158115Sume "can't create positive cache lock"); 137158115Sume TRACE_OUT(create_configuration_entry); 138158115Sume return (NULL); 139158115Sume } 140158115Sume 141158115Sume res = pthread_mutex_init(&retval->negative_cache_lock, NULL); 142158115Sume if (res != 0) { 143158115Sume pthread_mutex_destroy(&retval->positive_cache_lock); 144158115Sume free(retval); 145158115Sume LOG_ERR_2("create_configuration_entry", 146158115Sume "can't create negative cache lock"); 147158115Sume TRACE_OUT(create_configuration_entry); 148158115Sume return (NULL); 149158115Sume } 150158115Sume 151158115Sume res = pthread_mutex_init(&retval->mp_cache_lock, NULL); 152158115Sume if (res != 0) { 153158115Sume pthread_mutex_destroy(&retval->positive_cache_lock); 154158115Sume pthread_mutex_destroy(&retval->negative_cache_lock); 155158115Sume free(retval); 156158115Sume LOG_ERR_2("create_configuration_entry", 157158115Sume "can't create negative cache lock"); 158158115Sume TRACE_OUT(create_configuration_entry); 159158115Sume return (NULL); 160158115Sume } 161158115Sume 162158115Sume memcpy(&retval->positive_cache_params, positive_params, 163158115Sume sizeof(struct common_cache_entry_params)); 164158115Sume memcpy(&retval->negative_cache_params, negative_params, 165158115Sume sizeof(struct common_cache_entry_params)); 166158115Sume memcpy(&retval->mp_cache_params, mp_params, 167158115Sume sizeof(struct mp_cache_entry_params)); 168158115Sume 169158115Sume size = strlen(name); 170183770Sdelphij retval->name = (char *)calloc(1, size + 1); 171158115Sume assert(retval->name != NULL); 172158115Sume memcpy(retval->name, name, size); 173158115Sume 174158115Sume memcpy(&retval->common_query_timeout, common_timeout, 175158115Sume sizeof(struct timeval)); 176158115Sume memcpy(&retval->mp_query_timeout, mp_timeout, 177158115Sume sizeof(struct timeval)); 178158115Sume 179194097Sdes asprintf(&retval->positive_cache_params.cep.entry_name, "%s+", name); 180194097Sdes assert(retval->positive_cache_params.cep.entry_name != NULL); 181158115Sume 182194097Sdes asprintf(&retval->negative_cache_params.cep.entry_name, "%s-", name); 183194097Sdes assert(retval->negative_cache_params.cep.entry_name != NULL); 184158115Sume 185194097Sdes asprintf(&retval->mp_cache_params.cep.entry_name, "%s*", name); 186194097Sdes assert(retval->mp_cache_params.cep.entry_name != NULL); 187158115Sume 188158115Sume TRACE_OUT(create_configuration_entry); 189158115Sume return (retval); 190158115Sume} 191158115Sume 192158115Sume/* 193158115Sume * Creates configuration entry and fills it with default values 194158115Sume */ 195158115Sumestruct configuration_entry * 196158115Sumecreate_def_configuration_entry(const char *name) 197158115Sume{ 198158115Sume struct common_cache_entry_params positive_params, negative_params; 199158115Sume struct mp_cache_entry_params mp_params; 200158115Sume struct timeval default_common_timeout, default_mp_timeout; 201158115Sume 202158115Sume struct configuration_entry *res = NULL; 203158115Sume 204158115Sume TRACE_IN(create_def_configuration_entry); 205158115Sume memset(&positive_params, 0, 206158115Sume sizeof(struct common_cache_entry_params)); 207194097Sdes positive_params.cep.entry_type = CET_COMMON; 208158115Sume positive_params.cache_entries_size = DEFAULT_CACHE_HT_SIZE; 209158115Sume positive_params.max_elemsize = DEFAULT_POSITIVE_ELEMENTS_SIZE; 210158115Sume positive_params.satisf_elemsize = DEFAULT_POSITIVE_ELEMENTS_SIZE / 2; 211158115Sume positive_params.max_lifetime.tv_sec = DEFAULT_POSITIVE_LIFETIME; 212158115Sume positive_params.policy = CPT_LRU; 213158115Sume 214158115Sume memcpy(&negative_params, &positive_params, 215158115Sume sizeof(struct common_cache_entry_params)); 216158115Sume negative_params.max_elemsize = DEFAULT_NEGATIVE_ELEMENTS_SIZE; 217158115Sume negative_params.satisf_elemsize = DEFAULT_NEGATIVE_ELEMENTS_SIZE / 2; 218158115Sume negative_params.max_lifetime.tv_sec = DEFAULT_NEGATIVE_LIFETIME; 219158115Sume negative_params.policy = CPT_FIFO; 220158115Sume 221158115Sume memset(&default_common_timeout, 0, sizeof(struct timeval)); 222158115Sume default_common_timeout.tv_sec = DEFAULT_COMMON_ENTRY_TIMEOUT; 223158115Sume 224158115Sume memset(&default_mp_timeout, 0, sizeof(struct timeval)); 225158115Sume default_mp_timeout.tv_sec = DEFAULT_MP_ENTRY_TIMEOUT; 226158115Sume 227158115Sume memset(&mp_params, 0, 228158115Sume sizeof(struct mp_cache_entry_params)); 229194097Sdes mp_params.cep.entry_type = CET_MULTIPART; 230158115Sume mp_params.max_elemsize = DEFAULT_MULTIPART_ELEMENTS_SIZE; 231158115Sume mp_params.max_sessions = DEFAULT_MULITPART_SESSIONS_SIZE; 232158115Sume mp_params.max_lifetime.tv_sec = DEFAULT_MULITPART_LIFETIME; 233158115Sume 234158115Sume res = create_configuration_entry(name, &default_common_timeout, 235158115Sume &default_mp_timeout, &positive_params, &negative_params, 236158115Sume &mp_params); 237158115Sume 238158115Sume TRACE_OUT(create_def_configuration_entry); 239158115Sume return (res); 240158115Sume} 241158115Sume 242158115Sumevoid 243158115Sumedestroy_configuration_entry(struct configuration_entry *entry) 244158115Sume{ 245158115Sume TRACE_IN(destroy_configuration_entry); 246158115Sume assert(entry != NULL); 247158115Sume pthread_mutex_destroy(&entry->positive_cache_lock); 248158115Sume pthread_mutex_destroy(&entry->negative_cache_lock); 249158115Sume pthread_mutex_destroy(&entry->mp_cache_lock); 250158115Sume free(entry->name); 251194097Sdes free(entry->positive_cache_params.cep.entry_name); 252194097Sdes free(entry->negative_cache_params.cep.entry_name); 253194097Sdes free(entry->mp_cache_params.cep.entry_name); 254158115Sume free(entry->mp_cache_entries); 255158115Sume free(entry); 256158115Sume TRACE_OUT(destroy_configuration_entry); 257158115Sume} 258158115Sume 259158115Sumeint 260158115Sumeadd_configuration_entry(struct configuration *config, 261158115Sume struct configuration_entry *entry) 262158115Sume{ 263158115Sume TRACE_IN(add_configuration_entry); 264158115Sume assert(entry != NULL); 265158115Sume assert(entry->name != NULL); 266158115Sume if (configuration_find_entry(config, entry->name) != NULL) { 267158115Sume TRACE_OUT(add_configuration_entry); 268158115Sume return (-1); 269158115Sume } 270158115Sume 271158115Sume if (config->entries_size == config->entries_capacity) { 272158115Sume struct configuration_entry **new_entries; 273158115Sume 274158115Sume config->entries_capacity *= 2; 275183770Sdelphij new_entries = (struct configuration_entry **)calloc(1, 276158115Sume sizeof(struct configuration_entry *) * 277158115Sume config->entries_capacity); 278158115Sume assert(new_entries != NULL); 279158115Sume memcpy(new_entries, config->entries, 280158115Sume sizeof(struct configuration_entry *) * 281158115Sume config->entries_size); 282158115Sume 283158115Sume free(config->entries); 284158115Sume config->entries = new_entries; 285158115Sume } 286158115Sume 287158115Sume config->entries[config->entries_size++] = entry; 288158115Sume qsort(config->entries, config->entries_size, 289158115Sume sizeof(struct configuration_entry *), 290158115Sume configuration_entry_sort_cmp); 291158115Sume 292158115Sume TRACE_OUT(add_configuration_entry); 293158115Sume return (0); 294158115Sume} 295158115Sume 296158115Sumesize_t 297158115Sumeconfiguration_get_entries_size(struct configuration *config) 298158115Sume{ 299158115Sume TRACE_IN(configuration_get_entries_size); 300158115Sume assert(config != NULL); 301158115Sume TRACE_OUT(configuration_get_entries_size); 302158115Sume return (config->entries_size); 303158115Sume} 304158115Sume 305158115Sumestruct configuration_entry * 306158115Sumeconfiguration_get_entry(struct configuration *config, size_t index) 307158115Sume{ 308158115Sume TRACE_IN(configuration_get_entry); 309158115Sume assert(config != NULL); 310158115Sume assert(index < config->entries_size); 311158115Sume TRACE_OUT(configuration_get_entry); 312158115Sume return (config->entries[index]); 313158115Sume} 314158115Sume 315158115Sumestruct configuration_entry * 316158115Sumeconfiguration_find_entry(struct configuration *config, 317158115Sume const char *name) 318158115Sume{ 319158115Sume struct configuration_entry **retval; 320158115Sume 321158115Sume TRACE_IN(configuration_find_entry); 322158115Sume 323158115Sume retval = bsearch(name, config->entries, config->entries_size, 324158115Sume sizeof(struct configuration_entry *), configuration_entry_cmp); 325158115Sume TRACE_OUT(configuration_find_entry); 326158115Sume 327158115Sume return ((retval != NULL) ? *retval : NULL); 328158115Sume} 329158115Sume 330158115Sume/* 331158115Sume * All multipart cache entries are stored in the configuration_entry in the 332158115Sume * sorted array (sorted by names). The 3 functions below manage this array. 333158115Sume */ 334158115Sume 335158115Sumeint 336158115Sumeconfiguration_entry_add_mp_cache_entry(struct configuration_entry *config_entry, 337158115Sume cache_entry c_entry) 338158115Sume{ 339158115Sume cache_entry *new_mp_entries, *old_mp_entries; 340158115Sume 341158115Sume TRACE_IN(configuration_entry_add_mp_cache_entry); 342158115Sume ++config_entry->mp_cache_entries_size; 343158115Sume new_mp_entries = (cache_entry *)malloc(sizeof(cache_entry) * 344158115Sume config_entry->mp_cache_entries_size); 345158115Sume assert(new_mp_entries != NULL); 346158115Sume new_mp_entries[0] = c_entry; 347158115Sume 348158115Sume if (config_entry->mp_cache_entries_size - 1 > 0) { 349158115Sume memcpy(new_mp_entries + 1, 350158115Sume config_entry->mp_cache_entries, 351158115Sume (config_entry->mp_cache_entries_size - 1) * 352158115Sume sizeof(cache_entry)); 353158115Sume } 354158115Sume 355158115Sume old_mp_entries = config_entry->mp_cache_entries; 356158115Sume config_entry->mp_cache_entries = new_mp_entries; 357158115Sume free(old_mp_entries); 358158115Sume 359158115Sume qsort(config_entry->mp_cache_entries, 360158115Sume config_entry->mp_cache_entries_size, 361158115Sume sizeof(cache_entry), 362158115Sume configuration_entry_cache_mp_sort_cmp); 363158115Sume 364158115Sume TRACE_OUT(configuration_entry_add_mp_cache_entry); 365158115Sume return (0); 366158115Sume} 367158115Sume 368158115Sumecache_entry 369158115Sumeconfiguration_entry_find_mp_cache_entry( 370158115Sume struct configuration_entry *config_entry, const char *mp_name) 371158115Sume{ 372158115Sume cache_entry *result; 373158115Sume 374158115Sume TRACE_IN(configuration_entry_find_mp_cache_entry); 375158115Sume result = bsearch(mp_name, config_entry->mp_cache_entries, 376158115Sume config_entry->mp_cache_entries_size, 377158115Sume sizeof(cache_entry), configuration_entry_cache_mp_cmp); 378158115Sume 379158115Sume if (result == NULL) { 380158115Sume TRACE_OUT(configuration_entry_find_mp_cache_entry); 381158115Sume return (NULL); 382158115Sume } else { 383158115Sume TRACE_OUT(configuration_entry_find_mp_cache_entry); 384158115Sume return (*result); 385158115Sume } 386158115Sume} 387158115Sume 388158115Sume/* 389158115Sume * Searches for all multipart entries with names starting with mp_name. 390158115Sume * Needed for cache flushing. 391158115Sume */ 392158115Sumeint 393158115Sumeconfiguration_entry_find_mp_cache_entries( 394158115Sume struct configuration_entry *config_entry, const char *mp_name, 395158115Sume cache_entry **start, cache_entry **finish) 396158115Sume{ 397158115Sume cache_entry *result; 398158115Sume 399158115Sume TRACE_IN(configuration_entry_find_mp_cache_entries); 400158115Sume result = bsearch(mp_name, config_entry->mp_cache_entries, 401158115Sume config_entry->mp_cache_entries_size, 402158115Sume sizeof(cache_entry), configuration_entry_cache_mp_part_cmp); 403158115Sume 404158115Sume if (result == NULL) { 405158115Sume TRACE_OUT(configuration_entry_find_mp_cache_entries); 406158115Sume return (-1); 407158115Sume } 408158115Sume 409158115Sume *start = result; 410158115Sume *finish = result + 1; 411158115Sume 412158115Sume while (*start != config_entry->mp_cache_entries) { 413158115Sume if (configuration_entry_cache_mp_part_cmp(mp_name, *start - 1) == 0) 414158115Sume *start = *start - 1; 415158115Sume else 416158115Sume break; 417158115Sume } 418158115Sume 419158115Sume while (*finish != config_entry->mp_cache_entries + 420158115Sume config_entry->mp_cache_entries_size) { 421158115Sume 422158115Sume if (configuration_entry_cache_mp_part_cmp( 423158115Sume mp_name, *finish) == 0) 424158115Sume *finish = *finish + 1; 425158115Sume else 426158115Sume break; 427158115Sume } 428158115Sume 429158115Sume TRACE_OUT(configuration_entry_find_mp_cache_entries); 430158115Sume return (0); 431158115Sume} 432158115Sume 433158115Sume/* 434158115Sume * Configuration entry uses rwlock to handle access to its fields. 435158115Sume */ 436158115Sumevoid 437158115Sumeconfiguration_lock_rdlock(struct configuration *config) 438158115Sume{ 439158115Sume TRACE_IN(configuration_lock_rdlock); 440158115Sume pthread_rwlock_rdlock(&config->rwlock); 441158115Sume TRACE_OUT(configuration_lock_rdlock); 442158115Sume} 443158115Sume 444158115Sumevoid 445158115Sumeconfiguration_lock_wrlock(struct configuration *config) 446158115Sume{ 447158115Sume TRACE_IN(configuration_lock_wrlock); 448158115Sume pthread_rwlock_wrlock(&config->rwlock); 449158115Sume TRACE_OUT(configuration_lock_wrlock); 450158115Sume} 451158115Sume 452158115Sumevoid 453158115Sumeconfiguration_unlock(struct configuration *config) 454158115Sume{ 455158115Sume TRACE_IN(configuration_unlock); 456158115Sume pthread_rwlock_unlock(&config->rwlock); 457158115Sume TRACE_OUT(configuration_unlock); 458158115Sume} 459158115Sume 460158115Sume/* 461158115Sume * Configuration entry uses 3 mutexes to handle cache operations. They are 462158115Sume * acquired by configuration_lock_entry and configuration_unlock_entry 463158115Sume * functions. 464158115Sume */ 465158115Sumevoid 466158115Sumeconfiguration_lock_entry(struct configuration_entry *entry, 467158115Sume enum config_entry_lock_type lock_type) 468158115Sume{ 469158115Sume TRACE_IN(configuration_lock_entry); 470158115Sume assert(entry != NULL); 471158115Sume 472158115Sume switch (lock_type) { 473158115Sume case CELT_POSITIVE: 474158115Sume pthread_mutex_lock(&entry->positive_cache_lock); 475158115Sume break; 476158115Sume case CELT_NEGATIVE: 477158115Sume pthread_mutex_lock(&entry->negative_cache_lock); 478158115Sume break; 479158115Sume case CELT_MULTIPART: 480158115Sume pthread_mutex_lock(&entry->mp_cache_lock); 481158115Sume break; 482158115Sume default: 483158115Sume /* should be unreachable */ 484158115Sume break; 485158115Sume } 486158115Sume TRACE_OUT(configuration_lock_entry); 487158115Sume} 488158115Sume 489158115Sumevoid 490158115Sumeconfiguration_unlock_entry(struct configuration_entry *entry, 491158115Sume enum config_entry_lock_type lock_type) 492158115Sume{ 493158115Sume TRACE_IN(configuration_unlock_entry); 494158115Sume assert(entry != NULL); 495158115Sume 496158115Sume switch (lock_type) { 497158115Sume case CELT_POSITIVE: 498158115Sume pthread_mutex_unlock(&entry->positive_cache_lock); 499158115Sume break; 500158115Sume case CELT_NEGATIVE: 501158115Sume pthread_mutex_unlock(&entry->negative_cache_lock); 502158115Sume break; 503158115Sume case CELT_MULTIPART: 504158115Sume pthread_mutex_unlock(&entry->mp_cache_lock); 505158115Sume break; 506158115Sume default: 507158115Sume /* should be unreachable */ 508158115Sume break; 509158115Sume } 510158115Sume TRACE_OUT(configuration_unlock_entry); 511158115Sume} 512158115Sume 513158115Sumestruct configuration * 514158115Sumeinit_configuration(void) 515158115Sume{ 516158115Sume struct configuration *retval; 517158115Sume 518158115Sume TRACE_IN(init_configuration); 519183770Sdelphij retval = (struct configuration *)calloc(1, sizeof(struct configuration)); 520158115Sume assert(retval != NULL); 521158115Sume 522158115Sume retval->entries_capacity = INITIAL_ENTRIES_CAPACITY; 523183770Sdelphij retval->entries = (struct configuration_entry **)calloc(1, 524158115Sume sizeof(struct configuration_entry *) * 525158115Sume retval->entries_capacity); 526158115Sume assert(retval->entries != NULL); 527158115Sume 528158115Sume pthread_rwlock_init(&retval->rwlock, NULL); 529158115Sume 530158115Sume TRACE_OUT(init_configuration); 531158115Sume return (retval); 532158115Sume} 533158115Sume 534158115Sumevoid 535158115Sumefill_configuration_defaults(struct configuration *config) 536158115Sume{ 537158115Sume size_t len, i; 538158115Sume 539158115Sume TRACE_IN(fill_configuration_defaults); 540158115Sume assert(config != NULL); 541158115Sume 542158115Sume if (config->socket_path != NULL) 543158115Sume free(config->socket_path); 544158115Sume 545158115Sume len = strlen(DEFAULT_SOCKET_PATH); 546183770Sdelphij config->socket_path = (char *)calloc(1, len + 1); 547158115Sume assert(config->socket_path != NULL); 548158115Sume memcpy(config->socket_path, DEFAULT_SOCKET_PATH, len); 549158115Sume 550158115Sume len = strlen(DEFAULT_PIDFILE_PATH); 551183770Sdelphij config->pidfile_path = (char *)calloc(1, len + 1); 552158115Sume assert(config->pidfile_path != NULL); 553158115Sume memcpy(config->pidfile_path, DEFAULT_PIDFILE_PATH, len); 554158115Sume 555158115Sume config->socket_mode = S_IFSOCK | S_IRUSR | S_IWUSR | 556158115Sume S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; 557158115Sume config->force_unlink = 1; 558158115Sume 559158115Sume config->query_timeout = DEFAULT_QUERY_TIMEOUT; 560158115Sume config->threads_num = DEFAULT_THREADS_NUM; 561158115Sume 562158115Sume for (i = 0; i < config->entries_size; ++i) 563158115Sume destroy_configuration_entry(config->entries[i]); 564158115Sume config->entries_size = 0; 565158115Sume 566158115Sume TRACE_OUT(fill_configuration_defaults); 567158115Sume} 568158115Sume 569158115Sumevoid 570158115Sumedestroy_configuration(struct configuration *config) 571158115Sume{ 572194096Sdes unsigned int i; 573194096Sdes 574158115Sume TRACE_IN(destroy_configuration); 575158115Sume assert(config != NULL); 576158115Sume free(config->pidfile_path); 577158115Sume free(config->socket_path); 578158115Sume 579158115Sume for (i = 0; i < config->entries_size; ++i) 580158115Sume destroy_configuration_entry(config->entries[i]); 581158115Sume free(config->entries); 582158115Sume 583158115Sume pthread_rwlock_destroy(&config->rwlock); 584158115Sume free(config); 585158115Sume TRACE_OUT(destroy_configuration); 586158115Sume} 587