17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*b0daa853SStephen Hanson * Common Development and Distribution License (the "License"). 6*b0daa853SStephen Hanson * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217aec1d6eScindi 227c478bd9Sstevel@tonic-gate /* 23*b0daa853SStephen Hanson * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 247c478bd9Sstevel@tonic-gate * Use is subject to license terms. 257c478bd9Sstevel@tonic-gate */ 267c478bd9Sstevel@tonic-gate 277c478bd9Sstevel@tonic-gate #include <pthread.h> 287c478bd9Sstevel@tonic-gate #include <unistd.h> 297c478bd9Sstevel@tonic-gate #include <signal.h> 307c478bd9Sstevel@tonic-gate #include <inttypes.h> 317c478bd9Sstevel@tonic-gate #include <alloca.h> 327c478bd9Sstevel@tonic-gate #include <strings.h> 337c478bd9Sstevel@tonic-gate #include <stdlib.h> 347c478bd9Sstevel@tonic-gate #include <stdio.h> 357c478bd9Sstevel@tonic-gate 367c478bd9Sstevel@tonic-gate #include <fmd_conf.h> 377c478bd9Sstevel@tonic-gate #include <fmd_alloc.h> 387c478bd9Sstevel@tonic-gate #include <fmd_error.h> 397c478bd9Sstevel@tonic-gate #include <fmd_subr.h> 407c478bd9Sstevel@tonic-gate #include <fmd_string.h> 417c478bd9Sstevel@tonic-gate #include <fmd.h> 427c478bd9Sstevel@tonic-gate 437c478bd9Sstevel@tonic-gate const char FMD_PROP_SUBSCRIPTIONS[] = "_subscriptions"; 447c478bd9Sstevel@tonic-gate const char FMD_PROP_DICTIONARIES[] = "_dictionaries"; 457c478bd9Sstevel@tonic-gate 467c478bd9Sstevel@tonic-gate /* 477c478bd9Sstevel@tonic-gate * The property formals defined in _fmd_conf_defv[] are added to every config 487c478bd9Sstevel@tonic-gate * dictionary that is created. Here we define several special FMD_PROP_* 497c478bd9Sstevel@tonic-gate * properties that are used to implement the config file keyword actions, as 507c478bd9Sstevel@tonic-gate * well as properties that should be inherited by fmd_conf_t's from fmd.d_conf. 517c478bd9Sstevel@tonic-gate */ 527c478bd9Sstevel@tonic-gate static const fmd_conf_formal_t _fmd_conf_defv[] = { 537c478bd9Sstevel@tonic-gate { FMD_PROP_SUBSCRIPTIONS, &fmd_conf_list, "" }, 547c478bd9Sstevel@tonic-gate { FMD_PROP_DICTIONARIES, &fmd_conf_list, "" }, 557c478bd9Sstevel@tonic-gate { "fmd.isaname", &fmd_conf_parent, "isaname" }, 567c478bd9Sstevel@tonic-gate { "fmd.machine", &fmd_conf_parent, "machine" }, 577c478bd9Sstevel@tonic-gate { "fmd.platform", &fmd_conf_parent, "platform" }, 587c478bd9Sstevel@tonic-gate { "fmd.rootdir", &fmd_conf_parent, "rootdir" }, 597c478bd9Sstevel@tonic-gate }; 607c478bd9Sstevel@tonic-gate 617c478bd9Sstevel@tonic-gate static const int _fmd_conf_defc = 627c478bd9Sstevel@tonic-gate sizeof (_fmd_conf_defv) / sizeof (_fmd_conf_defv[0]); 637c478bd9Sstevel@tonic-gate 647c478bd9Sstevel@tonic-gate static int 657c478bd9Sstevel@tonic-gate set_bool(fmd_conf_param_t *pp, const char *s) 667c478bd9Sstevel@tonic-gate { 677c478bd9Sstevel@tonic-gate if (strcasecmp(s, "true") == 0) 687c478bd9Sstevel@tonic-gate pp->cp_value.cpv_num = 1; 697c478bd9Sstevel@tonic-gate else if (strcasecmp(s, "false") == 0) 707c478bd9Sstevel@tonic-gate pp->cp_value.cpv_num = 0; 717c478bd9Sstevel@tonic-gate else 727c478bd9Sstevel@tonic-gate return (fmd_set_errno(EFMD_CONF_INVAL)); 737c478bd9Sstevel@tonic-gate 747c478bd9Sstevel@tonic-gate return (0); 757c478bd9Sstevel@tonic-gate } 767c478bd9Sstevel@tonic-gate 777c478bd9Sstevel@tonic-gate static void 787c478bd9Sstevel@tonic-gate get_bool(const fmd_conf_param_t *pp, void *ptr) 797c478bd9Sstevel@tonic-gate { 807c478bd9Sstevel@tonic-gate *((int *)ptr) = (int)pp->cp_value.cpv_num; 817c478bd9Sstevel@tonic-gate } 827c478bd9Sstevel@tonic-gate 837c478bd9Sstevel@tonic-gate static int 84d9638e54Smws set_i32x(fmd_conf_param_t *pp, const char *s, int64_t min, int64_t max) 857c478bd9Sstevel@tonic-gate { 867c478bd9Sstevel@tonic-gate int64_t val; 877c478bd9Sstevel@tonic-gate char *end; 887c478bd9Sstevel@tonic-gate 897c478bd9Sstevel@tonic-gate errno = 0; 907c478bd9Sstevel@tonic-gate val = strtoll(s, &end, 0); 917c478bd9Sstevel@tonic-gate 92d9638e54Smws if (errno == EOVERFLOW || val < min || val > max) 937c478bd9Sstevel@tonic-gate return (fmd_set_errno(EFMD_CONF_OVERFLOW)); 947c478bd9Sstevel@tonic-gate 957c478bd9Sstevel@tonic-gate if (errno != 0 || end == s || *end != '\0') 967c478bd9Sstevel@tonic-gate return (fmd_set_errno(EFMD_CONF_INVAL)); 977c478bd9Sstevel@tonic-gate 987c478bd9Sstevel@tonic-gate pp->cp_value.cpv_num = val; 997c478bd9Sstevel@tonic-gate return (0); 1007c478bd9Sstevel@tonic-gate } 1017c478bd9Sstevel@tonic-gate 102d9638e54Smws static int 103d9638e54Smws set_i8(fmd_conf_param_t *pp, const char *s) 104d9638e54Smws { 105d9638e54Smws return (set_i32x(pp, s, INT8_MIN, INT8_MAX)); 106d9638e54Smws } 107d9638e54Smws 108d9638e54Smws static int 109d9638e54Smws set_i16(fmd_conf_param_t *pp, const char *s) 110d9638e54Smws { 111d9638e54Smws return (set_i32x(pp, s, INT16_MIN, INT16_MAX)); 112d9638e54Smws } 113d9638e54Smws 114d9638e54Smws static int 115d9638e54Smws set_i32(fmd_conf_param_t *pp, const char *s) 116d9638e54Smws { 117d9638e54Smws return (set_i32x(pp, s, INT32_MIN, INT32_MAX)); 118d9638e54Smws } 119d9638e54Smws 1207c478bd9Sstevel@tonic-gate static void 1217c478bd9Sstevel@tonic-gate get_i32(const fmd_conf_param_t *pp, void *ptr) 1227c478bd9Sstevel@tonic-gate { 1237c478bd9Sstevel@tonic-gate *((int32_t *)ptr) = (int32_t)pp->cp_value.cpv_num; 1247c478bd9Sstevel@tonic-gate } 1257c478bd9Sstevel@tonic-gate 1267c478bd9Sstevel@tonic-gate static int 127d9638e54Smws set_ui32x(fmd_conf_param_t *pp, const char *s, uint64_t max) 1287c478bd9Sstevel@tonic-gate { 1297c478bd9Sstevel@tonic-gate uint64_t val; 1307c478bd9Sstevel@tonic-gate char *end; 1317c478bd9Sstevel@tonic-gate 1327c478bd9Sstevel@tonic-gate errno = 0; 1337c478bd9Sstevel@tonic-gate val = strtoull(s, &end, 0); 1347c478bd9Sstevel@tonic-gate 135d9638e54Smws if (errno == EOVERFLOW || val > max) 1367c478bd9Sstevel@tonic-gate return (fmd_set_errno(EFMD_CONF_OVERFLOW)); 1377c478bd9Sstevel@tonic-gate 1387c478bd9Sstevel@tonic-gate if (errno != 0 || end == s || *end != '\0') 1397c478bd9Sstevel@tonic-gate return (fmd_set_errno(EFMD_CONF_INVAL)); 1407c478bd9Sstevel@tonic-gate 1417c478bd9Sstevel@tonic-gate pp->cp_value.cpv_num = val; 1427c478bd9Sstevel@tonic-gate return (0); 1437c478bd9Sstevel@tonic-gate } 1447c478bd9Sstevel@tonic-gate 145d9638e54Smws static int 146d9638e54Smws set_ui8(fmd_conf_param_t *pp, const char *s) 147d9638e54Smws { 148d9638e54Smws return (set_ui32x(pp, s, UINT8_MAX)); 149d9638e54Smws } 150d9638e54Smws 151d9638e54Smws static int 152d9638e54Smws set_ui16(fmd_conf_param_t *pp, const char *s) 153d9638e54Smws { 154d9638e54Smws return (set_ui32x(pp, s, UINT16_MAX)); 155d9638e54Smws } 156d9638e54Smws 157d9638e54Smws static int 158d9638e54Smws set_ui32(fmd_conf_param_t *pp, const char *s) 159d9638e54Smws { 160d9638e54Smws return (set_ui32x(pp, s, UINT32_MAX)); 161d9638e54Smws } 162d9638e54Smws 1637c478bd9Sstevel@tonic-gate static void 1647c478bd9Sstevel@tonic-gate get_ui32(const fmd_conf_param_t *pp, void *ptr) 1657c478bd9Sstevel@tonic-gate { 1667c478bd9Sstevel@tonic-gate *((uint32_t *)ptr) = (uint32_t)pp->cp_value.cpv_num; 1677c478bd9Sstevel@tonic-gate } 1687c478bd9Sstevel@tonic-gate 1697c478bd9Sstevel@tonic-gate static int 1707c478bd9Sstevel@tonic-gate set_i64(fmd_conf_param_t *pp, const char *s) 1717c478bd9Sstevel@tonic-gate { 1727c478bd9Sstevel@tonic-gate int64_t val; 1737c478bd9Sstevel@tonic-gate char *end; 1747c478bd9Sstevel@tonic-gate 1757c478bd9Sstevel@tonic-gate errno = 0; 1767c478bd9Sstevel@tonic-gate val = strtoll(s, &end, 0); 1777c478bd9Sstevel@tonic-gate 1787c478bd9Sstevel@tonic-gate if (errno == EOVERFLOW) 1797c478bd9Sstevel@tonic-gate return (fmd_set_errno(EFMD_CONF_OVERFLOW)); 1807c478bd9Sstevel@tonic-gate 1817c478bd9Sstevel@tonic-gate if (errno != 0 || end == s || *end != '\0') 1827c478bd9Sstevel@tonic-gate return (fmd_set_errno(EFMD_CONF_INVAL)); 1837c478bd9Sstevel@tonic-gate 1847c478bd9Sstevel@tonic-gate pp->cp_value.cpv_num = val; 1857c478bd9Sstevel@tonic-gate return (0); 1867c478bd9Sstevel@tonic-gate } 1877c478bd9Sstevel@tonic-gate 1887c478bd9Sstevel@tonic-gate static void 1897c478bd9Sstevel@tonic-gate get_i64(const fmd_conf_param_t *pp, void *ptr) 1907c478bd9Sstevel@tonic-gate { 1917c478bd9Sstevel@tonic-gate *((int64_t *)ptr) = (int64_t)pp->cp_value.cpv_num; 1927c478bd9Sstevel@tonic-gate } 1937c478bd9Sstevel@tonic-gate 1947c478bd9Sstevel@tonic-gate static int 1957c478bd9Sstevel@tonic-gate set_ui64(fmd_conf_param_t *pp, const char *s) 1967c478bd9Sstevel@tonic-gate { 1977c478bd9Sstevel@tonic-gate uint64_t val; 1987c478bd9Sstevel@tonic-gate char *end; 1997c478bd9Sstevel@tonic-gate 2007c478bd9Sstevel@tonic-gate errno = 0; 2017c478bd9Sstevel@tonic-gate val = strtoull(s, &end, 0); 2027c478bd9Sstevel@tonic-gate 2037c478bd9Sstevel@tonic-gate if (errno == EOVERFLOW) 2047c478bd9Sstevel@tonic-gate return (fmd_set_errno(EFMD_CONF_OVERFLOW)); 2057c478bd9Sstevel@tonic-gate 2067c478bd9Sstevel@tonic-gate if (errno != 0 || end == s || *end != '\0') 2077c478bd9Sstevel@tonic-gate return (fmd_set_errno(EFMD_CONF_INVAL)); 2087c478bd9Sstevel@tonic-gate 2097c478bd9Sstevel@tonic-gate pp->cp_value.cpv_num = val; 2107c478bd9Sstevel@tonic-gate return (0); 2117c478bd9Sstevel@tonic-gate } 2127c478bd9Sstevel@tonic-gate 2137c478bd9Sstevel@tonic-gate static void 2147c478bd9Sstevel@tonic-gate get_ui64(const fmd_conf_param_t *pp, void *ptr) 2157c478bd9Sstevel@tonic-gate { 2167c478bd9Sstevel@tonic-gate *((uint64_t *)ptr) = pp->cp_value.cpv_num; 2177c478bd9Sstevel@tonic-gate } 2187c478bd9Sstevel@tonic-gate 2197c478bd9Sstevel@tonic-gate static int 2207c478bd9Sstevel@tonic-gate set_str(fmd_conf_param_t *pp, const char *s) 2217c478bd9Sstevel@tonic-gate { 2227c478bd9Sstevel@tonic-gate fmd_strfree(pp->cp_value.cpv_str); 2237c478bd9Sstevel@tonic-gate pp->cp_value.cpv_str = fmd_strdup(s, FMD_SLEEP); 2247c478bd9Sstevel@tonic-gate return (0); 2257c478bd9Sstevel@tonic-gate } 2267c478bd9Sstevel@tonic-gate 2277c478bd9Sstevel@tonic-gate static void 2287c478bd9Sstevel@tonic-gate get_str(const fmd_conf_param_t *pp, void *ptr) 2297c478bd9Sstevel@tonic-gate { 2307c478bd9Sstevel@tonic-gate *((const char **)ptr) = pp->cp_value.cpv_str; 2317c478bd9Sstevel@tonic-gate } 2327c478bd9Sstevel@tonic-gate 2337c478bd9Sstevel@tonic-gate static void 2347c478bd9Sstevel@tonic-gate free_str(fmd_conf_param_t *pp) 2357c478bd9Sstevel@tonic-gate { 2367c478bd9Sstevel@tonic-gate fmd_strfree(pp->cp_value.cpv_str); 2377c478bd9Sstevel@tonic-gate pp->cp_value.cpv_str = NULL; 2387c478bd9Sstevel@tonic-gate } 2397c478bd9Sstevel@tonic-gate 2407c478bd9Sstevel@tonic-gate static int 2417c478bd9Sstevel@tonic-gate set_path(fmd_conf_param_t *pp, const char *value) 2427c478bd9Sstevel@tonic-gate { 2437c478bd9Sstevel@tonic-gate size_t len = strlen(value); 2447c478bd9Sstevel@tonic-gate char *s = alloca(len + 1); 2457c478bd9Sstevel@tonic-gate 2467c478bd9Sstevel@tonic-gate char **patv = alloca(sizeof (char *) * len / 2); 2477c478bd9Sstevel@tonic-gate int patc = 0; 2487c478bd9Sstevel@tonic-gate 2497c478bd9Sstevel@tonic-gate static const char *const percent_sign = "%"; 2507c478bd9Sstevel@tonic-gate char *p, *q; 2517c478bd9Sstevel@tonic-gate int c, i; 2527c478bd9Sstevel@tonic-gate 2537c478bd9Sstevel@tonic-gate static const struct fmd_conf_token { 2547c478bd9Sstevel@tonic-gate char tok_tag; 2557c478bd9Sstevel@tonic-gate const char *const *tok_val; 2567c478bd9Sstevel@tonic-gate } tokens[] = { 2577c478bd9Sstevel@tonic-gate { 'i', &fmd.d_platform }, 2587c478bd9Sstevel@tonic-gate { 'm', &fmd.d_machine }, 2597c478bd9Sstevel@tonic-gate { 'p', &fmd.d_isaname }, 2607c478bd9Sstevel@tonic-gate { 'r', &fmd.d_rootdir }, 2617c478bd9Sstevel@tonic-gate { '%', &percent_sign }, 2627c478bd9Sstevel@tonic-gate { 0, NULL } 2637c478bd9Sstevel@tonic-gate }; 2647c478bd9Sstevel@tonic-gate 2657c478bd9Sstevel@tonic-gate const struct fmd_conf_token *tok; 2667c478bd9Sstevel@tonic-gate fmd_conf_path_t *pap; 2677c478bd9Sstevel@tonic-gate 2687c478bd9Sstevel@tonic-gate pp->cp_formal->cf_ops->co_free(pp); 2697c478bd9Sstevel@tonic-gate (void) strcpy(s, value); 2707c478bd9Sstevel@tonic-gate 2717c478bd9Sstevel@tonic-gate for (p = strtok_r(s, ":", &q); p != NULL; p = strtok_r(NULL, ":", &q)) 2727c478bd9Sstevel@tonic-gate patv[patc++] = p; 2737c478bd9Sstevel@tonic-gate 2747c478bd9Sstevel@tonic-gate pap = fmd_alloc(sizeof (fmd_conf_path_t), FMD_SLEEP); 2757c478bd9Sstevel@tonic-gate pap->cpa_argv = fmd_alloc(sizeof (char *) * patc, FMD_SLEEP); 2767c478bd9Sstevel@tonic-gate pap->cpa_argc = patc; 2777c478bd9Sstevel@tonic-gate 2787c478bd9Sstevel@tonic-gate for (i = 0; i < patc; i++) { 2797c478bd9Sstevel@tonic-gate for (len = 0, p = patv[i]; (c = *p) != '\0'; p++, len++) { 2807c478bd9Sstevel@tonic-gate if (c != '%' || (c = p[1]) == '\0') 2817c478bd9Sstevel@tonic-gate continue; 2827c478bd9Sstevel@tonic-gate 2837c478bd9Sstevel@tonic-gate for (tok = tokens; tok->tok_tag != 0; tok++) { 2847c478bd9Sstevel@tonic-gate if (c == tok->tok_tag) { 2857c478bd9Sstevel@tonic-gate len += strlen(*tok->tok_val) - 1; 2867c478bd9Sstevel@tonic-gate p++; 2877c478bd9Sstevel@tonic-gate break; 2887c478bd9Sstevel@tonic-gate } 2897c478bd9Sstevel@tonic-gate } 2907c478bd9Sstevel@tonic-gate } 2917c478bd9Sstevel@tonic-gate 2927c478bd9Sstevel@tonic-gate pap->cpa_argv[i] = q = fmd_alloc(len + 1, FMD_SLEEP); 2937c478bd9Sstevel@tonic-gate q[len] = '\0'; 2947c478bd9Sstevel@tonic-gate 2957c478bd9Sstevel@tonic-gate for (p = patv[i]; (c = *p) != '\0'; p++) { 2967c478bd9Sstevel@tonic-gate if (c != '%' || (c = p[1]) == '\0') { 2977c478bd9Sstevel@tonic-gate *q++ = c; 2987c478bd9Sstevel@tonic-gate continue; 2997c478bd9Sstevel@tonic-gate } 3007c478bd9Sstevel@tonic-gate 3017c478bd9Sstevel@tonic-gate for (tok = tokens; tok->tok_tag != 0; tok++) { 3027c478bd9Sstevel@tonic-gate if (c == tok->tok_tag) { 3037c478bd9Sstevel@tonic-gate (void) strcpy(q, *tok->tok_val); 3047c478bd9Sstevel@tonic-gate q += strlen(q); 3057c478bd9Sstevel@tonic-gate p++; 3067c478bd9Sstevel@tonic-gate break; 3077c478bd9Sstevel@tonic-gate } 3087c478bd9Sstevel@tonic-gate } 3097c478bd9Sstevel@tonic-gate 3107c478bd9Sstevel@tonic-gate if (tok->tok_tag == 0) 3117c478bd9Sstevel@tonic-gate *q++ = c; 3127c478bd9Sstevel@tonic-gate } 3137c478bd9Sstevel@tonic-gate } 3147c478bd9Sstevel@tonic-gate 3157c478bd9Sstevel@tonic-gate pp->cp_value.cpv_ptr = pap; 3167c478bd9Sstevel@tonic-gate return (0); 3177c478bd9Sstevel@tonic-gate } 3187c478bd9Sstevel@tonic-gate 3197c478bd9Sstevel@tonic-gate static int 3207c478bd9Sstevel@tonic-gate set_lst(fmd_conf_param_t *pp, const char *value) 3217c478bd9Sstevel@tonic-gate { 3227c478bd9Sstevel@tonic-gate fmd_conf_path_t *old; 3237c478bd9Sstevel@tonic-gate 3247c478bd9Sstevel@tonic-gate old = pp->cp_value.cpv_ptr; 3257c478bd9Sstevel@tonic-gate pp->cp_value.cpv_ptr = NULL; 3267c478bd9Sstevel@tonic-gate 3277c478bd9Sstevel@tonic-gate if (set_path(pp, value) != 0) { 3287c478bd9Sstevel@tonic-gate pp->cp_value.cpv_ptr = old; 3297c478bd9Sstevel@tonic-gate return (-1); /* errno is set for us */ 3307c478bd9Sstevel@tonic-gate } 3317c478bd9Sstevel@tonic-gate 3327c478bd9Sstevel@tonic-gate if (old != NULL) { 3337c478bd9Sstevel@tonic-gate fmd_conf_path_t *new = pp->cp_value.cpv_ptr; 3347c478bd9Sstevel@tonic-gate int i, totc = old->cpa_argc + new->cpa_argc; 3357c478bd9Sstevel@tonic-gate 3367c478bd9Sstevel@tonic-gate int new_argc = new->cpa_argc; 3377c478bd9Sstevel@tonic-gate const char **new_argv = new->cpa_argv; 3387c478bd9Sstevel@tonic-gate 3397c478bd9Sstevel@tonic-gate new->cpa_argc = 0; 3407c478bd9Sstevel@tonic-gate new->cpa_argv = fmd_alloc(sizeof (char *) * totc, FMD_SLEEP); 3417c478bd9Sstevel@tonic-gate 3427c478bd9Sstevel@tonic-gate for (i = 0; i < old->cpa_argc; i++) 3437c478bd9Sstevel@tonic-gate new->cpa_argv[new->cpa_argc++] = old->cpa_argv[i]; 3447c478bd9Sstevel@tonic-gate 3457c478bd9Sstevel@tonic-gate for (i = 0; i < new_argc; i++) 3467c478bd9Sstevel@tonic-gate new->cpa_argv[new->cpa_argc++] = new_argv[i]; 3477c478bd9Sstevel@tonic-gate 3487c478bd9Sstevel@tonic-gate ASSERT(new->cpa_argc == totc); 3497c478bd9Sstevel@tonic-gate 3507c478bd9Sstevel@tonic-gate fmd_free(new_argv, sizeof (char *) * new_argc); 3517c478bd9Sstevel@tonic-gate fmd_free(old->cpa_argv, sizeof (char *) * old->cpa_argc); 3527c478bd9Sstevel@tonic-gate fmd_free(old, sizeof (fmd_conf_path_t)); 3537c478bd9Sstevel@tonic-gate } 3547c478bd9Sstevel@tonic-gate 3557c478bd9Sstevel@tonic-gate return (0); 3567c478bd9Sstevel@tonic-gate } 3577c478bd9Sstevel@tonic-gate 3587c478bd9Sstevel@tonic-gate static int 3597c478bd9Sstevel@tonic-gate del_lst(fmd_conf_param_t *pp, const char *value) 3607c478bd9Sstevel@tonic-gate { 3617c478bd9Sstevel@tonic-gate fmd_conf_path_t *pap = pp->cp_value.cpv_ptr; 3627c478bd9Sstevel@tonic-gate const char **new_argv; 3637c478bd9Sstevel@tonic-gate int i, new_argc; 3647c478bd9Sstevel@tonic-gate 3657c478bd9Sstevel@tonic-gate for (i = 0; i < pap->cpa_argc; i++) { 3667c478bd9Sstevel@tonic-gate if (strcmp(pap->cpa_argv[i], value) == 0) 3677c478bd9Sstevel@tonic-gate break; 3687c478bd9Sstevel@tonic-gate } 3697c478bd9Sstevel@tonic-gate 3707c478bd9Sstevel@tonic-gate if (i == pap->cpa_argc) 3717c478bd9Sstevel@tonic-gate return (fmd_set_errno(ENOENT)); 3727c478bd9Sstevel@tonic-gate 3737c478bd9Sstevel@tonic-gate fmd_strfree((char *)pap->cpa_argv[i]); 3747c478bd9Sstevel@tonic-gate pap->cpa_argv[i] = NULL; 3757c478bd9Sstevel@tonic-gate 3767c478bd9Sstevel@tonic-gate new_argc = 0; 3777c478bd9Sstevel@tonic-gate new_argv = fmd_alloc(sizeof (char *) * (pap->cpa_argc - 1), FMD_SLEEP); 3787c478bd9Sstevel@tonic-gate 3797c478bd9Sstevel@tonic-gate for (i = 0; i < pap->cpa_argc; i++) { 3807c478bd9Sstevel@tonic-gate if (pap->cpa_argv[i] != NULL) 3817c478bd9Sstevel@tonic-gate new_argv[new_argc++] = pap->cpa_argv[i]; 3827c478bd9Sstevel@tonic-gate } 3837c478bd9Sstevel@tonic-gate 3847c478bd9Sstevel@tonic-gate fmd_free(pap->cpa_argv, sizeof (char *) * pap->cpa_argc); 3857c478bd9Sstevel@tonic-gate pap->cpa_argv = new_argv; 3867c478bd9Sstevel@tonic-gate pap->cpa_argc = new_argc; 3877c478bd9Sstevel@tonic-gate 3887c478bd9Sstevel@tonic-gate return (0); 3897c478bd9Sstevel@tonic-gate } 3907c478bd9Sstevel@tonic-gate 3917c478bd9Sstevel@tonic-gate static void 3927c478bd9Sstevel@tonic-gate get_path(const fmd_conf_param_t *pp, void *ptr) 3937c478bd9Sstevel@tonic-gate { 3947c478bd9Sstevel@tonic-gate *((fmd_conf_path_t **)ptr) = (fmd_conf_path_t *)pp->cp_value.cpv_ptr; 3957c478bd9Sstevel@tonic-gate } 3967c478bd9Sstevel@tonic-gate 3977c478bd9Sstevel@tonic-gate static void 3987c478bd9Sstevel@tonic-gate free_path(fmd_conf_param_t *pp) 3997c478bd9Sstevel@tonic-gate { 4007c478bd9Sstevel@tonic-gate fmd_conf_path_t *pap = pp->cp_value.cpv_ptr; 4017c478bd9Sstevel@tonic-gate int i; 4027c478bd9Sstevel@tonic-gate 4037c478bd9Sstevel@tonic-gate if (pap == NULL) 4047c478bd9Sstevel@tonic-gate return; /* no value was ever set */ 4057c478bd9Sstevel@tonic-gate 4067c478bd9Sstevel@tonic-gate for (i = 0; i < pap->cpa_argc; i++) 4077c478bd9Sstevel@tonic-gate fmd_strfree((char *)pap->cpa_argv[i]); 4087c478bd9Sstevel@tonic-gate 4097c478bd9Sstevel@tonic-gate fmd_free(pap->cpa_argv, sizeof (char *) * pap->cpa_argc); 4107c478bd9Sstevel@tonic-gate fmd_free(pap, sizeof (fmd_conf_path_t)); 4117c478bd9Sstevel@tonic-gate pp->cp_value.cpv_ptr = NULL; 4127c478bd9Sstevel@tonic-gate } 4137c478bd9Sstevel@tonic-gate 4147c478bd9Sstevel@tonic-gate static int 4157c478bd9Sstevel@tonic-gate set_time(fmd_conf_param_t *pp, const char *s) 4167c478bd9Sstevel@tonic-gate { 4177c478bd9Sstevel@tonic-gate static const struct { 4187c478bd9Sstevel@tonic-gate const char *name; 4197c478bd9Sstevel@tonic-gate hrtime_t mul; 4207c478bd9Sstevel@tonic-gate } suffix[] = { 4217c478bd9Sstevel@tonic-gate { "ns", NANOSEC / NANOSEC }, 4227c478bd9Sstevel@tonic-gate { "nsec", NANOSEC / NANOSEC }, 4237c478bd9Sstevel@tonic-gate { "us", NANOSEC / MICROSEC }, 4247c478bd9Sstevel@tonic-gate { "usec", NANOSEC / MICROSEC }, 4257c478bd9Sstevel@tonic-gate { "ms", NANOSEC / MILLISEC }, 4267c478bd9Sstevel@tonic-gate { "msec", NANOSEC / MILLISEC }, 4277c478bd9Sstevel@tonic-gate { "s", NANOSEC / SEC }, 4287c478bd9Sstevel@tonic-gate { "sec", NANOSEC / SEC }, 4297c478bd9Sstevel@tonic-gate { "m", NANOSEC * (hrtime_t)60 }, 4307c478bd9Sstevel@tonic-gate { "min", NANOSEC * (hrtime_t)60 }, 4317c478bd9Sstevel@tonic-gate { "h", NANOSEC * (hrtime_t)(60 * 60) }, 4327c478bd9Sstevel@tonic-gate { "hour", NANOSEC * (hrtime_t)(60 * 60) }, 4337c478bd9Sstevel@tonic-gate { "d", NANOSEC * (hrtime_t)(24 * 60 * 60) }, 4347c478bd9Sstevel@tonic-gate { "day", NANOSEC * (hrtime_t)(24 * 60 * 60) }, 4357c478bd9Sstevel@tonic-gate { "hz", 0 }, 4367c478bd9Sstevel@tonic-gate { NULL } 4377c478bd9Sstevel@tonic-gate }; 4387c478bd9Sstevel@tonic-gate 4397c478bd9Sstevel@tonic-gate hrtime_t val, mul = 1; 4407c478bd9Sstevel@tonic-gate char *end; 4417c478bd9Sstevel@tonic-gate int i; 4427c478bd9Sstevel@tonic-gate 4437c478bd9Sstevel@tonic-gate errno = 0; 4447c478bd9Sstevel@tonic-gate val = strtoull(s, &end, 0); 4457c478bd9Sstevel@tonic-gate 4467c478bd9Sstevel@tonic-gate if (errno == EOVERFLOW) 4477c478bd9Sstevel@tonic-gate return (fmd_set_errno(EFMD_CONF_OVERFLOW)); 4487c478bd9Sstevel@tonic-gate 4497c478bd9Sstevel@tonic-gate if (errno != 0 || end == s) 4507c478bd9Sstevel@tonic-gate return (fmd_set_errno(EFMD_CONF_INVAL)); 4517c478bd9Sstevel@tonic-gate 4527c478bd9Sstevel@tonic-gate for (i = 0; suffix[i].name != NULL; i++) { 4537c478bd9Sstevel@tonic-gate if (strcasecmp(suffix[i].name, end) == 0) { 4547c478bd9Sstevel@tonic-gate mul = suffix[i].mul; 4557c478bd9Sstevel@tonic-gate break; 4567c478bd9Sstevel@tonic-gate } 4577c478bd9Sstevel@tonic-gate } 4587c478bd9Sstevel@tonic-gate 4597c478bd9Sstevel@tonic-gate if (suffix[i].name == NULL && *end != '\0') 4607c478bd9Sstevel@tonic-gate return (fmd_set_errno(EFMD_CONF_INVAL)); 4617c478bd9Sstevel@tonic-gate 4627c478bd9Sstevel@tonic-gate if (mul == 0) { 4637c478bd9Sstevel@tonic-gate if (val != 0) 4647c478bd9Sstevel@tonic-gate val = NANOSEC / val; /* compute val as value per sec */ 4657c478bd9Sstevel@tonic-gate } else 4667c478bd9Sstevel@tonic-gate val *= mul; 4677c478bd9Sstevel@tonic-gate 4687c478bd9Sstevel@tonic-gate pp->cp_value.cpv_num = val; 4697c478bd9Sstevel@tonic-gate return (0); 4707c478bd9Sstevel@tonic-gate } 4717c478bd9Sstevel@tonic-gate 4727c478bd9Sstevel@tonic-gate static int 4737c478bd9Sstevel@tonic-gate set_size(fmd_conf_param_t *pp, const char *s) 4747c478bd9Sstevel@tonic-gate { 4757c478bd9Sstevel@tonic-gate size_t len = strlen(s); 4767c478bd9Sstevel@tonic-gate uint64_t val, mul = 1; 4777c478bd9Sstevel@tonic-gate char *end; 4787c478bd9Sstevel@tonic-gate 4797c478bd9Sstevel@tonic-gate switch (s[len - 1]) { 4807c478bd9Sstevel@tonic-gate case 't': 4817c478bd9Sstevel@tonic-gate case 'T': 4827c478bd9Sstevel@tonic-gate mul *= 1024; 4837c478bd9Sstevel@tonic-gate /*FALLTHRU*/ 4847c478bd9Sstevel@tonic-gate case 'g': 4857c478bd9Sstevel@tonic-gate case 'G': 4867c478bd9Sstevel@tonic-gate mul *= 1024; 4877c478bd9Sstevel@tonic-gate /*FALLTHRU*/ 4887c478bd9Sstevel@tonic-gate case 'm': 4897c478bd9Sstevel@tonic-gate case 'M': 4907c478bd9Sstevel@tonic-gate mul *= 1024; 4917c478bd9Sstevel@tonic-gate /*FALLTHRU*/ 4927c478bd9Sstevel@tonic-gate case 'k': 4937c478bd9Sstevel@tonic-gate case 'K': 4947c478bd9Sstevel@tonic-gate mul *= 1024; 4957c478bd9Sstevel@tonic-gate /*FALLTHRU*/ 4967c478bd9Sstevel@tonic-gate default: 4977c478bd9Sstevel@tonic-gate break; 4987c478bd9Sstevel@tonic-gate } 4997c478bd9Sstevel@tonic-gate 5007c478bd9Sstevel@tonic-gate errno = 0; 5017c478bd9Sstevel@tonic-gate val = strtoull(s, &end, 0) * mul; 5027c478bd9Sstevel@tonic-gate 5037c478bd9Sstevel@tonic-gate if (errno == EOVERFLOW) 5047c478bd9Sstevel@tonic-gate return (fmd_set_errno(EFMD_CONF_OVERFLOW)); 5057c478bd9Sstevel@tonic-gate 5067c478bd9Sstevel@tonic-gate if ((mul != 1 && end != &s[len - 1]) || 5077c478bd9Sstevel@tonic-gate (mul == 1 && *end != '\0') || errno != 0) 5087c478bd9Sstevel@tonic-gate return (fmd_set_errno(EFMD_CONF_INVAL)); 5097c478bd9Sstevel@tonic-gate 5107c478bd9Sstevel@tonic-gate pp->cp_value.cpv_num = val; 5117c478bd9Sstevel@tonic-gate return (0); 5127c478bd9Sstevel@tonic-gate } 5137c478bd9Sstevel@tonic-gate 5147c478bd9Sstevel@tonic-gate static int 5157c478bd9Sstevel@tonic-gate set_sig(fmd_conf_param_t *pp, const char *s) 5167c478bd9Sstevel@tonic-gate { 5177c478bd9Sstevel@tonic-gate int sig; 5187c478bd9Sstevel@tonic-gate 5197c478bd9Sstevel@tonic-gate if (strncasecmp(s, "SIG", 3) == 0) 5207c478bd9Sstevel@tonic-gate s += 3; /* be friendlier than strsig() and permit the prefix */ 5217c478bd9Sstevel@tonic-gate 5227c478bd9Sstevel@tonic-gate if (str2sig(s, &sig) != 0) 5237c478bd9Sstevel@tonic-gate return (fmd_set_errno(EFMD_CONF_INVAL)); 5247c478bd9Sstevel@tonic-gate 5257c478bd9Sstevel@tonic-gate pp->cp_value.cpv_num = sig; 5267c478bd9Sstevel@tonic-gate return (0); 5277c478bd9Sstevel@tonic-gate } 5287c478bd9Sstevel@tonic-gate 5297c478bd9Sstevel@tonic-gate static void 5307c478bd9Sstevel@tonic-gate get_par(const fmd_conf_param_t *pp, void *ptr) 5317c478bd9Sstevel@tonic-gate { 5327c478bd9Sstevel@tonic-gate if (fmd_conf_getprop(fmd.d_conf, pp->cp_formal->cf_default, ptr) != 0) { 5337c478bd9Sstevel@tonic-gate fmd_panic("fmd.d_conf does not define '%s' (inherited as %s)\n", 5347c478bd9Sstevel@tonic-gate (char *)pp->cp_formal->cf_default, pp->cp_formal->cf_name); 5357c478bd9Sstevel@tonic-gate } 5367c478bd9Sstevel@tonic-gate } 5377c478bd9Sstevel@tonic-gate 5387c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 5397c478bd9Sstevel@tonic-gate static int 5407c478bd9Sstevel@tonic-gate set_par(fmd_conf_param_t *pp, const char *s) 5417c478bd9Sstevel@tonic-gate { 5427c478bd9Sstevel@tonic-gate return (fmd_set_errno(EFMD_CONF_RDONLY)); 5437c478bd9Sstevel@tonic-gate } 5447c478bd9Sstevel@tonic-gate 5457c478bd9Sstevel@tonic-gate /* 5467c478bd9Sstevel@tonic-gate * Utility routine for callers who define custom ops where a list of string 5477c478bd9Sstevel@tonic-gate * tokens are translated into a bitmask. 'cmp' should be set to point to an 5487c478bd9Sstevel@tonic-gate * array of fmd_conf_mode_t's where the final element has cm_name == NULL. 5497c478bd9Sstevel@tonic-gate */ 5507c478bd9Sstevel@tonic-gate int 551d9638e54Smws fmd_conf_mode_set(const fmd_conf_mode_t *cma, 5527c478bd9Sstevel@tonic-gate fmd_conf_param_t *pp, const char *value) 5537c478bd9Sstevel@tonic-gate { 554d9638e54Smws const fmd_conf_mode_t *cmp; 5557c478bd9Sstevel@tonic-gate char *p, *q, *s = fmd_strdup(value, FMD_SLEEP); 5567c478bd9Sstevel@tonic-gate size_t len = value ? strlen(value) + 1 : 0; 5577c478bd9Sstevel@tonic-gate uint_t mode = 0; 5587c478bd9Sstevel@tonic-gate 5597c478bd9Sstevel@tonic-gate if (s == NULL) { 5607c478bd9Sstevel@tonic-gate pp->cp_value.cpv_num = 0; 5617c478bd9Sstevel@tonic-gate return (0); 5627c478bd9Sstevel@tonic-gate } 5637c478bd9Sstevel@tonic-gate 5647c478bd9Sstevel@tonic-gate for (p = strtok_r(s, ",", &q); p != NULL; p = strtok_r(NULL, ",", &q)) { 565d9638e54Smws for (cmp = cma; cmp->cm_name != NULL; cmp++) { 5667c478bd9Sstevel@tonic-gate if (strcmp(cmp->cm_name, p) == 0) { 5677c478bd9Sstevel@tonic-gate mode |= cmp->cm_bits; 5687c478bd9Sstevel@tonic-gate break; 5697c478bd9Sstevel@tonic-gate } 5707c478bd9Sstevel@tonic-gate } 5717c478bd9Sstevel@tonic-gate 5727c478bd9Sstevel@tonic-gate if (cmp->cm_name == NULL) { 5737c478bd9Sstevel@tonic-gate fmd_free(s, len); 5747c478bd9Sstevel@tonic-gate return (fmd_set_errno(EFMD_CONF_INVAL)); 5757c478bd9Sstevel@tonic-gate } 5767c478bd9Sstevel@tonic-gate } 5777c478bd9Sstevel@tonic-gate 5787c478bd9Sstevel@tonic-gate pp->cp_value.cpv_num = mode; 5797c478bd9Sstevel@tonic-gate fmd_free(s, len); 5807c478bd9Sstevel@tonic-gate return (0); 5817c478bd9Sstevel@tonic-gate } 5827c478bd9Sstevel@tonic-gate 5837c478bd9Sstevel@tonic-gate void 5847c478bd9Sstevel@tonic-gate fmd_conf_mode_get(const fmd_conf_param_t *pp, void *ptr) 5857c478bd9Sstevel@tonic-gate { 5867c478bd9Sstevel@tonic-gate *((uint_t *)ptr) = (uint_t)pp->cp_value.cpv_num; 5877c478bd9Sstevel@tonic-gate } 5887c478bd9Sstevel@tonic-gate 5897c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 5907c478bd9Sstevel@tonic-gate int 5917c478bd9Sstevel@tonic-gate fmd_conf_notsup(fmd_conf_param_t *pp, const char *value) 5927c478bd9Sstevel@tonic-gate { 5937c478bd9Sstevel@tonic-gate return (fmd_set_errno(ENOTSUP)); 5947c478bd9Sstevel@tonic-gate } 5957c478bd9Sstevel@tonic-gate 5967c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 5977c478bd9Sstevel@tonic-gate void 5987c478bd9Sstevel@tonic-gate fmd_conf_nop(fmd_conf_param_t *pp) 5997c478bd9Sstevel@tonic-gate { 6007c478bd9Sstevel@tonic-gate /* no free required for integer-type parameters */ 6017c478bd9Sstevel@tonic-gate } 6027c478bd9Sstevel@tonic-gate 6037c478bd9Sstevel@tonic-gate #define CONF_DEFINE(name, a, b, c, d) \ 6047c478bd9Sstevel@tonic-gate const fmd_conf_ops_t name = { a, b, c, d } 6057c478bd9Sstevel@tonic-gate 6067c478bd9Sstevel@tonic-gate CONF_DEFINE(fmd_conf_bool, set_bool, get_bool, fmd_conf_notsup, fmd_conf_nop); 607d9638e54Smws CONF_DEFINE(fmd_conf_int8, set_i8, get_i32, fmd_conf_notsup, fmd_conf_nop); 608d9638e54Smws CONF_DEFINE(fmd_conf_uint8, set_ui8, get_ui32, fmd_conf_notsup, fmd_conf_nop); 609d9638e54Smws CONF_DEFINE(fmd_conf_int16, set_i16, get_i32, fmd_conf_notsup, fmd_conf_nop); 610d9638e54Smws CONF_DEFINE(fmd_conf_uint16, set_ui16, get_ui32, fmd_conf_notsup, fmd_conf_nop); 6117c478bd9Sstevel@tonic-gate CONF_DEFINE(fmd_conf_int32, set_i32, get_i32, fmd_conf_notsup, fmd_conf_nop); 6127c478bd9Sstevel@tonic-gate CONF_DEFINE(fmd_conf_uint32, set_ui32, get_ui32, fmd_conf_notsup, fmd_conf_nop); 6137c478bd9Sstevel@tonic-gate CONF_DEFINE(fmd_conf_int64, set_i64, get_i64, fmd_conf_notsup, fmd_conf_nop); 6147c478bd9Sstevel@tonic-gate CONF_DEFINE(fmd_conf_uint64, set_ui64, get_ui64, fmd_conf_notsup, fmd_conf_nop); 6157c478bd9Sstevel@tonic-gate CONF_DEFINE(fmd_conf_string, set_str, get_str, fmd_conf_notsup, free_str); 6167c478bd9Sstevel@tonic-gate CONF_DEFINE(fmd_conf_path, set_path, get_path, fmd_conf_notsup, free_path); 6177c478bd9Sstevel@tonic-gate CONF_DEFINE(fmd_conf_list, set_lst, get_path, del_lst, free_path); 6187c478bd9Sstevel@tonic-gate CONF_DEFINE(fmd_conf_time, set_time, get_ui64, fmd_conf_notsup, fmd_conf_nop); 6197c478bd9Sstevel@tonic-gate CONF_DEFINE(fmd_conf_size, set_size, get_ui64, fmd_conf_notsup, fmd_conf_nop); 6207c478bd9Sstevel@tonic-gate CONF_DEFINE(fmd_conf_signal, set_sig, get_i32, fmd_conf_notsup, fmd_conf_nop); 6217c478bd9Sstevel@tonic-gate CONF_DEFINE(fmd_conf_parent, set_par, get_par, fmd_conf_notsup, fmd_conf_nop); 6227c478bd9Sstevel@tonic-gate 6237c478bd9Sstevel@tonic-gate static char * 6247c478bd9Sstevel@tonic-gate fmd_conf_skipstr(char *s) 6257c478bd9Sstevel@tonic-gate { 6267c478bd9Sstevel@tonic-gate int c; 6277c478bd9Sstevel@tonic-gate 6287c478bd9Sstevel@tonic-gate while ((c = *s) != '\0') { 6297c478bd9Sstevel@tonic-gate if (c == '\\') 6307c478bd9Sstevel@tonic-gate s++; 6317c478bd9Sstevel@tonic-gate else if (c == '"') 6327c478bd9Sstevel@tonic-gate break; 6337c478bd9Sstevel@tonic-gate s++; 6347c478bd9Sstevel@tonic-gate } 6357c478bd9Sstevel@tonic-gate 6367c478bd9Sstevel@tonic-gate return (s); 6377c478bd9Sstevel@tonic-gate } 6387c478bd9Sstevel@tonic-gate 6397c478bd9Sstevel@tonic-gate static char * 6407c478bd9Sstevel@tonic-gate fmd_conf_skipnws(char *s) 6417c478bd9Sstevel@tonic-gate { 6427c478bd9Sstevel@tonic-gate while (strchr("\f\n\r\t\v ", *s) == NULL) 6437c478bd9Sstevel@tonic-gate s++; 6447c478bd9Sstevel@tonic-gate 6457c478bd9Sstevel@tonic-gate return (s); 6467c478bd9Sstevel@tonic-gate } 6477c478bd9Sstevel@tonic-gate 6487c478bd9Sstevel@tonic-gate static int 6497c478bd9Sstevel@tonic-gate fmd_conf_tokenize(char *s, char *tokv[]) 6507c478bd9Sstevel@tonic-gate { 6517c478bd9Sstevel@tonic-gate int c, tokc = 0; 6527c478bd9Sstevel@tonic-gate 6537c478bd9Sstevel@tonic-gate while ((c = *s) != '\0') { 6547c478bd9Sstevel@tonic-gate switch (c) { 6557c478bd9Sstevel@tonic-gate case '"': 6567c478bd9Sstevel@tonic-gate tokv[tokc] = s + 1; 6577c478bd9Sstevel@tonic-gate s = fmd_conf_skipstr(s + 1); 6587c478bd9Sstevel@tonic-gate *s++ = '\0'; 6597c478bd9Sstevel@tonic-gate (void) fmd_stresc2chr(tokv[tokc++]); 6607c478bd9Sstevel@tonic-gate continue; 6617c478bd9Sstevel@tonic-gate case '\f': case '\n': case '\r': 6627c478bd9Sstevel@tonic-gate case '\t': case '\v': case ' ': 6637c478bd9Sstevel@tonic-gate s++; 6647c478bd9Sstevel@tonic-gate continue; 6657c478bd9Sstevel@tonic-gate default: 6667c478bd9Sstevel@tonic-gate tokv[tokc++] = s; 6677c478bd9Sstevel@tonic-gate s = fmd_conf_skipnws(s); 6687c478bd9Sstevel@tonic-gate *s++ = '\0'; 6697c478bd9Sstevel@tonic-gate } 6707c478bd9Sstevel@tonic-gate } 6717c478bd9Sstevel@tonic-gate 6727c478bd9Sstevel@tonic-gate return (tokc); 6737c478bd9Sstevel@tonic-gate } 6747c478bd9Sstevel@tonic-gate 6757c478bd9Sstevel@tonic-gate static int 6767c478bd9Sstevel@tonic-gate fmd_conf_exec_setprop(fmd_conf_t *cfp, int argc, char *argv[]) 6777c478bd9Sstevel@tonic-gate { 6787c478bd9Sstevel@tonic-gate if (argc != 2) 6797c478bd9Sstevel@tonic-gate return (fmd_set_errno(EFMD_CONF_USAGE)); 6807c478bd9Sstevel@tonic-gate 6817c478bd9Sstevel@tonic-gate return (fmd_conf_setprop(cfp, argv[0], argv[1])); 6827c478bd9Sstevel@tonic-gate } 6837c478bd9Sstevel@tonic-gate 6847c478bd9Sstevel@tonic-gate static int 6857c478bd9Sstevel@tonic-gate fmd_conf_exec_subscribe(fmd_conf_t *cfp, int argc, char *argv[]) 6867c478bd9Sstevel@tonic-gate { 6877c478bd9Sstevel@tonic-gate if (argc != 1) 6887c478bd9Sstevel@tonic-gate return (fmd_set_errno(EFMD_CONF_USAGE)); 6897c478bd9Sstevel@tonic-gate 6907c478bd9Sstevel@tonic-gate return (fmd_conf_setprop(cfp, FMD_PROP_SUBSCRIPTIONS, argv[0])); 6917c478bd9Sstevel@tonic-gate } 6927c478bd9Sstevel@tonic-gate 6937c478bd9Sstevel@tonic-gate static int 6947c478bd9Sstevel@tonic-gate fmd_conf_exec_dictionary(fmd_conf_t *cfp, int argc, char *argv[]) 6957c478bd9Sstevel@tonic-gate { 6967c478bd9Sstevel@tonic-gate if (argc != 1) 6977c478bd9Sstevel@tonic-gate return (fmd_set_errno(EFMD_CONF_USAGE)); 6987c478bd9Sstevel@tonic-gate 6997c478bd9Sstevel@tonic-gate return (fmd_conf_setprop(cfp, FMD_PROP_DICTIONARIES, argv[0])); 7007c478bd9Sstevel@tonic-gate } 7017c478bd9Sstevel@tonic-gate 7027c478bd9Sstevel@tonic-gate static int 7037c478bd9Sstevel@tonic-gate fmd_conf_parse(fmd_conf_t *cfp, const char *file) 7047c478bd9Sstevel@tonic-gate { 7057c478bd9Sstevel@tonic-gate static const fmd_conf_verb_t verbs[] = { 7067c478bd9Sstevel@tonic-gate { "setprop", fmd_conf_exec_setprop }, 7077c478bd9Sstevel@tonic-gate { "subscribe", fmd_conf_exec_subscribe }, 7087c478bd9Sstevel@tonic-gate { "dictionary", fmd_conf_exec_dictionary }, 7097c478bd9Sstevel@tonic-gate { NULL, NULL } 7107c478bd9Sstevel@tonic-gate }; 7117c478bd9Sstevel@tonic-gate 7127c478bd9Sstevel@tonic-gate int line, errs = 0; 7137c478bd9Sstevel@tonic-gate char buf[BUFSIZ]; 7147c478bd9Sstevel@tonic-gate FILE *fp; 7157c478bd9Sstevel@tonic-gate 7167c478bd9Sstevel@tonic-gate if ((fp = fopen(file, "r")) == NULL) { 717*b0daa853SStephen Hanson if (errno == EMFILE) 718*b0daa853SStephen Hanson fmd_error(EFMD_EXIT, "failed to open %s: %s\n", 719*b0daa853SStephen Hanson file, fmd_strerror(errno)); 720*b0daa853SStephen Hanson else 7217c478bd9Sstevel@tonic-gate fmd_error(EFMD_CONF_OPEN, "failed to open %s: %s\n", 7227c478bd9Sstevel@tonic-gate file, fmd_strerror(errno)); 7237c478bd9Sstevel@tonic-gate return (fmd_set_errno(EFMD_CONF_OPEN)); 7247c478bd9Sstevel@tonic-gate } 7257c478bd9Sstevel@tonic-gate 7267c478bd9Sstevel@tonic-gate for (line = 1; fgets(buf, sizeof (buf), fp) != NULL; line++) { 7277c478bd9Sstevel@tonic-gate char *tokv[sizeof (buf) / 2 + 1]; 7287c478bd9Sstevel@tonic-gate int tokc = fmd_conf_tokenize(buf, tokv); 7297c478bd9Sstevel@tonic-gate const fmd_conf_verb_t *vp; 7307c478bd9Sstevel@tonic-gate 7317c478bd9Sstevel@tonic-gate if (tokc == 0 || tokv[0][0] == '#') 7327c478bd9Sstevel@tonic-gate continue; /* skip blank lines and comment lines */ 7337c478bd9Sstevel@tonic-gate 7347c478bd9Sstevel@tonic-gate for (vp = verbs; vp->cv_name != NULL; vp++) { 7357c478bd9Sstevel@tonic-gate if (strcmp(tokv[0], vp->cv_name) == 0) 7367c478bd9Sstevel@tonic-gate break; 7377c478bd9Sstevel@tonic-gate } 7387c478bd9Sstevel@tonic-gate 7397c478bd9Sstevel@tonic-gate if (vp->cv_name == NULL) { 7407c478bd9Sstevel@tonic-gate fmd_error(EFMD_CONF_KEYWORD, "\"%s\", line %d: " 7417c478bd9Sstevel@tonic-gate "invalid configuration file keyword: %s\n", 7427c478bd9Sstevel@tonic-gate file, line, tokv[0]); 7437c478bd9Sstevel@tonic-gate errs++; 7447c478bd9Sstevel@tonic-gate continue; 7457c478bd9Sstevel@tonic-gate } 7467c478bd9Sstevel@tonic-gate 7477c478bd9Sstevel@tonic-gate if (vp->cv_exec(cfp, tokc - 1, tokv + 1) != 0) { 7487c478bd9Sstevel@tonic-gate fmd_error(errno, "\"%s\", line %d", file, line); 7497c478bd9Sstevel@tonic-gate errs++; 7507c478bd9Sstevel@tonic-gate continue; 7517c478bd9Sstevel@tonic-gate } 7527c478bd9Sstevel@tonic-gate } 7537c478bd9Sstevel@tonic-gate 7547c478bd9Sstevel@tonic-gate if (ferror(fp) != 0 || fclose(fp) != 0) 7557c478bd9Sstevel@tonic-gate return (fmd_set_errno(EFMD_CONF_IO)); 7567c478bd9Sstevel@tonic-gate 7577c478bd9Sstevel@tonic-gate if (errs != 0) 7587c478bd9Sstevel@tonic-gate return (fmd_set_errno(EFMD_CONF_ERRS)); 7597c478bd9Sstevel@tonic-gate 7607c478bd9Sstevel@tonic-gate return (0); 7617c478bd9Sstevel@tonic-gate } 7627c478bd9Sstevel@tonic-gate 7637c478bd9Sstevel@tonic-gate static void 7647c478bd9Sstevel@tonic-gate fmd_conf_fill(fmd_conf_t *cfp, fmd_conf_param_t *ppbuf, 7657c478bd9Sstevel@tonic-gate int argc, const fmd_conf_formal_t *argv, int checkid) 7667c478bd9Sstevel@tonic-gate { 7677c478bd9Sstevel@tonic-gate int i; 7687c478bd9Sstevel@tonic-gate 7697c478bd9Sstevel@tonic-gate for (i = 0; i < argc; i++, argv++) { 7707c478bd9Sstevel@tonic-gate fmd_conf_param_t *op, *pp = ppbuf + i; 7717c478bd9Sstevel@tonic-gate const char *name = argv->cf_name; 7727c478bd9Sstevel@tonic-gate ulong_t h = fmd_strhash(name) % cfp->cf_parhashlen; 7737c478bd9Sstevel@tonic-gate 7747c478bd9Sstevel@tonic-gate if (fmd_strbadid(name, checkid) != NULL) { 7757c478bd9Sstevel@tonic-gate fmd_error(EFMD_CONF_PROPNAME, "ignoring invalid formal " 7767c478bd9Sstevel@tonic-gate "property %s\n", name); 7777c478bd9Sstevel@tonic-gate continue; 7787c478bd9Sstevel@tonic-gate } 7797c478bd9Sstevel@tonic-gate 7807c478bd9Sstevel@tonic-gate for (op = cfp->cf_parhash[h]; op != NULL; op = op->cp_next) { 7817c478bd9Sstevel@tonic-gate if (strcmp(op->cp_formal->cf_name, name) == 0) { 7827c478bd9Sstevel@tonic-gate fmd_error(EFMD_CONF_PROPDUP, "ignoring " 7837c478bd9Sstevel@tonic-gate "duplicate formal property %s\n", name); 7847c478bd9Sstevel@tonic-gate break; 7857c478bd9Sstevel@tonic-gate } 7867c478bd9Sstevel@tonic-gate } 7877c478bd9Sstevel@tonic-gate 7887c478bd9Sstevel@tonic-gate if (op != NULL) 7897c478bd9Sstevel@tonic-gate continue; 7907c478bd9Sstevel@tonic-gate 7917c478bd9Sstevel@tonic-gate pp->cp_formal = argv; 7927c478bd9Sstevel@tonic-gate pp->cp_next = cfp->cf_parhash[h]; 7937c478bd9Sstevel@tonic-gate cfp->cf_parhash[h] = pp; 7947c478bd9Sstevel@tonic-gate 7957c478bd9Sstevel@tonic-gate if (argv->cf_default && argv->cf_ops != &fmd_conf_parent && 7967c478bd9Sstevel@tonic-gate fmd_conf_setprop(cfp, name, argv->cf_default) != 0) { 7977c478bd9Sstevel@tonic-gate fmd_error(EFMD_CONF_DEFAULT, "ignoring invalid default " 7987c478bd9Sstevel@tonic-gate "<%s> for property %s: %s\n", argv->cf_default, 7997c478bd9Sstevel@tonic-gate name, fmd_strerror(errno)); 8007c478bd9Sstevel@tonic-gate } 8017c478bd9Sstevel@tonic-gate } 8027c478bd9Sstevel@tonic-gate } 8037c478bd9Sstevel@tonic-gate 8047c478bd9Sstevel@tonic-gate fmd_conf_t * 805d9638e54Smws fmd_conf_open(const char *file, int argc, 806d9638e54Smws const fmd_conf_formal_t *argv, uint_t flag) 8077c478bd9Sstevel@tonic-gate { 8087c478bd9Sstevel@tonic-gate fmd_conf_t *cfp = fmd_alloc(sizeof (fmd_conf_t), FMD_SLEEP); 8097c478bd9Sstevel@tonic-gate 8107c478bd9Sstevel@tonic-gate (void) pthread_rwlock_init(&cfp->cf_lock, NULL); 8117c478bd9Sstevel@tonic-gate cfp->cf_argv = argv; 8127c478bd9Sstevel@tonic-gate cfp->cf_argc = argc; 813d9638e54Smws cfp->cf_flag = flag; 8147c478bd9Sstevel@tonic-gate 8157c478bd9Sstevel@tonic-gate cfp->cf_params = fmd_zalloc( 8167c478bd9Sstevel@tonic-gate sizeof (fmd_conf_param_t) * (_fmd_conf_defc + argc), FMD_SLEEP); 8177c478bd9Sstevel@tonic-gate 8187c478bd9Sstevel@tonic-gate cfp->cf_parhashlen = fmd.d_str_buckets; 8197c478bd9Sstevel@tonic-gate cfp->cf_parhash = fmd_zalloc( 8207c478bd9Sstevel@tonic-gate sizeof (fmd_conf_param_t *) * cfp->cf_parhashlen, FMD_SLEEP); 8217c478bd9Sstevel@tonic-gate 822d9638e54Smws cfp->cf_defer = NULL; 823d9638e54Smws 8247c478bd9Sstevel@tonic-gate fmd_conf_fill(cfp, cfp->cf_params, _fmd_conf_defc, _fmd_conf_defv, 0); 8257c478bd9Sstevel@tonic-gate fmd_conf_fill(cfp, cfp->cf_params + _fmd_conf_defc, argc, argv, 1); 8267c478bd9Sstevel@tonic-gate 8277c478bd9Sstevel@tonic-gate if (file != NULL && fmd_conf_parse(cfp, file) != 0) { 8287c478bd9Sstevel@tonic-gate fmd_conf_close(cfp); 8297c478bd9Sstevel@tonic-gate return (NULL); 8307c478bd9Sstevel@tonic-gate } 8317c478bd9Sstevel@tonic-gate 8327c478bd9Sstevel@tonic-gate return (cfp); 8337c478bd9Sstevel@tonic-gate } 8347c478bd9Sstevel@tonic-gate 8357c478bd9Sstevel@tonic-gate void 8367c478bd9Sstevel@tonic-gate fmd_conf_merge(fmd_conf_t *cfp, const char *file) 8377c478bd9Sstevel@tonic-gate { 8387c478bd9Sstevel@tonic-gate (void) fmd_conf_parse(cfp, file); 8397c478bd9Sstevel@tonic-gate } 8407c478bd9Sstevel@tonic-gate 8417c478bd9Sstevel@tonic-gate void 842d9638e54Smws fmd_conf_propagate(fmd_conf_t *src, fmd_conf_t *dst, const char *scope) 843d9638e54Smws { 844d9638e54Smws size_t len = strlen(scope); 845d9638e54Smws fmd_conf_defer_t *cdp; 846d9638e54Smws 847d9638e54Smws (void) pthread_rwlock_rdlock(&src->cf_lock); 848d9638e54Smws 849d9638e54Smws for (cdp = src->cf_defer; cdp != NULL; cdp = cdp->cd_next) { 850d9638e54Smws if (len == (size_t)(strchr(cdp->cd_name, ':') - cdp->cd_name) && 851d9638e54Smws strncmp(cdp->cd_name, scope, len) == 0 && fmd_conf_setprop( 852d9638e54Smws dst, cdp->cd_name + len + 1, cdp->cd_value) != 0) { 853d9638e54Smws fmd_error(EFMD_CONF_DEFER, 854d9638e54Smws "failed to apply deferred property %s to %s: %s\n", 855d9638e54Smws cdp->cd_name, scope, fmd_strerror(errno)); 856d9638e54Smws } 857d9638e54Smws } 858d9638e54Smws 859d9638e54Smws (void) pthread_rwlock_unlock(&src->cf_lock); 860d9638e54Smws } 861d9638e54Smws 862d9638e54Smws void 8637c478bd9Sstevel@tonic-gate fmd_conf_close(fmd_conf_t *cfp) 8647c478bd9Sstevel@tonic-gate { 8657c478bd9Sstevel@tonic-gate fmd_conf_param_t *pp = cfp->cf_params; 8667c478bd9Sstevel@tonic-gate int i, nparams = _fmd_conf_defc + cfp->cf_argc; 867d9638e54Smws fmd_conf_defer_t *cdp, *ndp; 868d9638e54Smws 869d9638e54Smws for (cdp = cfp->cf_defer; cdp != NULL; cdp = ndp) { 870d9638e54Smws ndp = cdp->cd_next; 871d9638e54Smws fmd_strfree(cdp->cd_name); 872d9638e54Smws fmd_strfree(cdp->cd_value); 873d9638e54Smws fmd_free(cdp, sizeof (fmd_conf_defer_t)); 874d9638e54Smws } 8757c478bd9Sstevel@tonic-gate 8767c478bd9Sstevel@tonic-gate fmd_free(cfp->cf_parhash, 8777c478bd9Sstevel@tonic-gate sizeof (fmd_conf_param_t *) * cfp->cf_parhashlen); 8787c478bd9Sstevel@tonic-gate 8797c478bd9Sstevel@tonic-gate for (i = 0; i < nparams; i++, pp++) { 8807c478bd9Sstevel@tonic-gate if (pp->cp_formal != NULL) 8817c478bd9Sstevel@tonic-gate pp->cp_formal->cf_ops->co_free(pp); 8827c478bd9Sstevel@tonic-gate } 8837c478bd9Sstevel@tonic-gate 8847c478bd9Sstevel@tonic-gate fmd_free(cfp->cf_params, sizeof (fmd_conf_param_t) * nparams); 8857c478bd9Sstevel@tonic-gate fmd_free(cfp, sizeof (fmd_conf_t)); 8867c478bd9Sstevel@tonic-gate } 8877c478bd9Sstevel@tonic-gate 8887c478bd9Sstevel@tonic-gate static fmd_conf_param_t * 8897c478bd9Sstevel@tonic-gate fmd_conf_getparam(fmd_conf_t *cfp, const char *name) 8907c478bd9Sstevel@tonic-gate { 8917c478bd9Sstevel@tonic-gate ulong_t h = fmd_strhash(name) % cfp->cf_parhashlen; 8927c478bd9Sstevel@tonic-gate fmd_conf_param_t *pp = cfp->cf_parhash[h]; 8937c478bd9Sstevel@tonic-gate 8947c478bd9Sstevel@tonic-gate ASSERT(RW_LOCK_HELD(&cfp->cf_lock)); 8957c478bd9Sstevel@tonic-gate 8967c478bd9Sstevel@tonic-gate for (; pp != NULL; pp = pp->cp_next) { 8977c478bd9Sstevel@tonic-gate if (strcmp(name, pp->cp_formal->cf_name) == 0) 8987c478bd9Sstevel@tonic-gate return (pp); 8997c478bd9Sstevel@tonic-gate } 9007c478bd9Sstevel@tonic-gate 9017c478bd9Sstevel@tonic-gate return (NULL); 9027c478bd9Sstevel@tonic-gate } 9037c478bd9Sstevel@tonic-gate 9047aec1d6eScindi /* 9057aec1d6eScindi * String-friendly version of fmd_conf_getprop(): return the string as our 9067aec1d6eScindi * return value, and return NULL if the string is the empty string. 9077aec1d6eScindi */ 9087aec1d6eScindi const char * 9097aec1d6eScindi fmd_conf_getnzstr(fmd_conf_t *cfp, const char *name) 9107aec1d6eScindi { 9117aec1d6eScindi const fmd_conf_param_t *pp; 9127aec1d6eScindi char *s = NULL; 9137aec1d6eScindi 9147aec1d6eScindi (void) pthread_rwlock_rdlock(&cfp->cf_lock); 9157aec1d6eScindi 9167aec1d6eScindi if ((pp = fmd_conf_getparam(cfp, name)) != NULL) { 9177aec1d6eScindi ASSERT(pp->cp_formal->cf_ops == &fmd_conf_string); 9187aec1d6eScindi pp->cp_formal->cf_ops->co_get(pp, &s); 9197aec1d6eScindi } else 9207aec1d6eScindi (void) fmd_set_errno(EFMD_CONF_NOPROP); 9217aec1d6eScindi 9227aec1d6eScindi (void) pthread_rwlock_unlock(&cfp->cf_lock); 9237aec1d6eScindi 9247aec1d6eScindi if (s != NULL && s[0] == '\0') { 9257aec1d6eScindi (void) fmd_set_errno(EFMD_CONF_UNDEF); 9267aec1d6eScindi s = NULL; 9277aec1d6eScindi } 9287aec1d6eScindi 9297aec1d6eScindi return (s); 9307aec1d6eScindi } 9317aec1d6eScindi 9327c478bd9Sstevel@tonic-gate const fmd_conf_ops_t * 9337c478bd9Sstevel@tonic-gate fmd_conf_gettype(fmd_conf_t *cfp, const char *name) 9347c478bd9Sstevel@tonic-gate { 9357c478bd9Sstevel@tonic-gate const fmd_conf_param_t *pp; 9367c478bd9Sstevel@tonic-gate const fmd_conf_ops_t *ops = NULL; 9377c478bd9Sstevel@tonic-gate 9387c478bd9Sstevel@tonic-gate (void) pthread_rwlock_rdlock(&cfp->cf_lock); 9397c478bd9Sstevel@tonic-gate 9407c478bd9Sstevel@tonic-gate if ((pp = fmd_conf_getparam(cfp, name)) != NULL) { 9417c478bd9Sstevel@tonic-gate if ((ops = pp->cp_formal->cf_ops) == &fmd_conf_parent) { 9427c478bd9Sstevel@tonic-gate ops = fmd_conf_gettype(fmd.d_conf, 9437c478bd9Sstevel@tonic-gate pp->cp_formal->cf_default); 9447c478bd9Sstevel@tonic-gate } 9457c478bd9Sstevel@tonic-gate } else 9467c478bd9Sstevel@tonic-gate (void) fmd_set_errno(EFMD_CONF_NOPROP); 9477c478bd9Sstevel@tonic-gate 9487c478bd9Sstevel@tonic-gate (void) pthread_rwlock_unlock(&cfp->cf_lock); 9497c478bd9Sstevel@tonic-gate return (ops); 9507c478bd9Sstevel@tonic-gate } 9517c478bd9Sstevel@tonic-gate 9527c478bd9Sstevel@tonic-gate int 9537c478bd9Sstevel@tonic-gate fmd_conf_getprop(fmd_conf_t *cfp, const char *name, void *data) 9547c478bd9Sstevel@tonic-gate { 9557c478bd9Sstevel@tonic-gate const fmd_conf_param_t *pp; 9567c478bd9Sstevel@tonic-gate int err = 0; 9577c478bd9Sstevel@tonic-gate 9587c478bd9Sstevel@tonic-gate (void) pthread_rwlock_rdlock(&cfp->cf_lock); 9597c478bd9Sstevel@tonic-gate 9607c478bd9Sstevel@tonic-gate if ((pp = fmd_conf_getparam(cfp, name)) != NULL) 9617c478bd9Sstevel@tonic-gate pp->cp_formal->cf_ops->co_get(pp, data); 9627c478bd9Sstevel@tonic-gate else 9637c478bd9Sstevel@tonic-gate err = fmd_set_errno(EFMD_CONF_NOPROP); 9647c478bd9Sstevel@tonic-gate 9657c478bd9Sstevel@tonic-gate (void) pthread_rwlock_unlock(&cfp->cf_lock); 9667c478bd9Sstevel@tonic-gate return (err); 9677c478bd9Sstevel@tonic-gate } 9687c478bd9Sstevel@tonic-gate 969d9638e54Smws static int 970d9638e54Smws fmd_conf_setdefer(fmd_conf_t *cfp, const char *name, const char *value) 971d9638e54Smws { 972d9638e54Smws fmd_conf_defer_t *cdp; 973d9638e54Smws 974d9638e54Smws if (!(cfp->cf_flag & FMD_CONF_DEFER)) 975d9638e54Smws return (fmd_set_errno(EFMD_CONF_NODEFER)); 976d9638e54Smws 977d9638e54Smws (void) pthread_rwlock_wrlock(&cfp->cf_lock); 978d9638e54Smws 979d9638e54Smws for (cdp = cfp->cf_defer; cdp != NULL; cdp = cdp->cd_next) { 980d9638e54Smws if (strcmp(name, cdp->cd_name) == 0) { 981d9638e54Smws fmd_strfree(cdp->cd_value); 982d9638e54Smws cdp->cd_value = fmd_strdup(value, FMD_SLEEP); 983d9638e54Smws goto out; 984d9638e54Smws } 985d9638e54Smws } 986d9638e54Smws 987d9638e54Smws cdp = fmd_alloc(sizeof (fmd_conf_defer_t), FMD_SLEEP); 988d9638e54Smws 989d9638e54Smws cdp->cd_name = fmd_strdup(name, FMD_SLEEP); 990d9638e54Smws cdp->cd_value = fmd_strdup(value, FMD_SLEEP); 991d9638e54Smws cdp->cd_next = cfp->cf_defer; 992d9638e54Smws 993d9638e54Smws cfp->cf_defer = cdp; 994d9638e54Smws out: 995d9638e54Smws (void) pthread_rwlock_unlock(&cfp->cf_lock); 996d9638e54Smws return (0); 997d9638e54Smws } 998d9638e54Smws 9997c478bd9Sstevel@tonic-gate int 10007c478bd9Sstevel@tonic-gate fmd_conf_setprop(fmd_conf_t *cfp, const char *name, const char *value) 10017c478bd9Sstevel@tonic-gate { 10027c478bd9Sstevel@tonic-gate fmd_conf_param_t *pp; 10037c478bd9Sstevel@tonic-gate int err; 10047c478bd9Sstevel@tonic-gate 1005d9638e54Smws if (strchr(name, ':') != NULL) 1006d9638e54Smws return (fmd_conf_setdefer(cfp, name, value)); 1007d9638e54Smws 10087c478bd9Sstevel@tonic-gate (void) pthread_rwlock_wrlock(&cfp->cf_lock); 10097c478bd9Sstevel@tonic-gate 10107c478bd9Sstevel@tonic-gate if ((pp = fmd_conf_getparam(cfp, name)) != NULL) 10117c478bd9Sstevel@tonic-gate err = pp->cp_formal->cf_ops->co_set(pp, value); 10127c478bd9Sstevel@tonic-gate else 10137c478bd9Sstevel@tonic-gate err = fmd_set_errno(EFMD_CONF_NOPROP); 10147c478bd9Sstevel@tonic-gate 10157c478bd9Sstevel@tonic-gate (void) pthread_rwlock_unlock(&cfp->cf_lock); 10167c478bd9Sstevel@tonic-gate return (err); 10177c478bd9Sstevel@tonic-gate } 10187c478bd9Sstevel@tonic-gate 10197c478bd9Sstevel@tonic-gate int 10207c478bd9Sstevel@tonic-gate fmd_conf_delprop(fmd_conf_t *cfp, const char *name, const char *value) 10217c478bd9Sstevel@tonic-gate { 10227c478bd9Sstevel@tonic-gate fmd_conf_param_t *pp; 10237c478bd9Sstevel@tonic-gate int err; 10247c478bd9Sstevel@tonic-gate 10257c478bd9Sstevel@tonic-gate (void) pthread_rwlock_wrlock(&cfp->cf_lock); 10267c478bd9Sstevel@tonic-gate 10277c478bd9Sstevel@tonic-gate if ((pp = fmd_conf_getparam(cfp, name)) != NULL) 10287c478bd9Sstevel@tonic-gate err = pp->cp_formal->cf_ops->co_del(pp, value); 10297c478bd9Sstevel@tonic-gate else 10307c478bd9Sstevel@tonic-gate err = fmd_set_errno(EFMD_CONF_NOPROP); 10317c478bd9Sstevel@tonic-gate 10327c478bd9Sstevel@tonic-gate (void) pthread_rwlock_unlock(&cfp->cf_lock); 10337c478bd9Sstevel@tonic-gate return (err); 10347c478bd9Sstevel@tonic-gate } 1035