void create_settings() { setting_create("master-volume"); setting_create("master-waveform"); synth_model.setting_master_volume = setting_find("master-volume"); synth_model.setting_master_waveform = setting_find("master-waveform"); setting_init_as_int(synth_model.setting_master_volume, 0); setting_init_as_enum(synth_model.setting_master_waveform, (int)WAVETABLE_SINE, &master_waveform_type); }
/** * Change value in given set of settings (non-recursively, parent sets are * not affected in any way). Function will fail if setting with given name is * not a part of set of settings. * Mutual exclusion is ensured by set_value(). * * @warning * Failure in this function usually points to insufficient input validation * OR logic error. * Caller should always check the return value. * * @retval ISC_R_SUCCESS Value was changed. * @retval ISC_R_IGNORE Value wasn't changed because it is same as original. * @retval ISC_R_NOTFOUND Setting was not found in given set of settings. * @retval ISC_R_NOMEMORY * @retval Others Conversion errors. */ isc_result_t setting_set(const char *const name, const settings_set_t *set, const char *const value) { isc_result_t result; setting_t *setting = NULL; CHECK(setting_find(name, set, ISC_FALSE, ISC_FALSE, &setting)); return set_value(set->mctx, set, setting, value); cleanup: log_bug("setting '%s' was not found in set of settings '%s'", name, set->name); return result; }
/** * Check if all the settings in given set of setting have defined value, * possibly indirectly through parent set of settings. * * Error message is logged for each setting without defined value. * * @retval ISC_TRUE All settings have value defined. * @retval ISC_FALSE At least one setting do not have defined value. */ isc_boolean_t settings_set_isfilled(settings_set_t *set) { isc_result_t result; isc_boolean_t isfiled = ISC_TRUE; REQUIRE(set != NULL); for (int i = 0; set->first_setting[i].name != NULL; i++) { const char *name = set->first_setting[i].name; result = setting_find(name, set, ISC_TRUE, ISC_TRUE, NULL); if (result != ISC_R_SUCCESS) { log_error_r("argument '%s' must be set " "in set of settings '%s'", name, set->name); isfiled = ISC_FALSE; } } return isfiled; }
/** * Get value associated with a setting. Search starts in set of settings * passed by caller and continues in parent sets until the setting with defined * value is found. * * @warning * This function is not expected to fail because all settings should * have default value defined (in topmost set of settings). * Caller should always check the return value, regardless this assumption. * * @param[in] type Data type expected by caller. * @param[out] target Type of pointer must agree with requested setting type. * @retval ISC_R_SUCCESS Required value was found and target was filled in. * @retval ISC_R_NOTFOUND Value is not defined in specified set of * settings either in parent sets. * @retval ISC_R_UNEXPECTED Type mismatch between expected type and type * of setting in settings tree. (I.e. programming * error.) */ static isc_result_t ATTR_NONNULLS ATTR_CHECKRESULT setting_get(const char *const name, const setting_type_t type, const settings_set_t *const set, void *target) { isc_result_t result; setting_t *setting = NULL; REQUIRE(name != NULL); REQUIRE(target != NULL); CHECK(setting_find(name, set, isc_boolean_true, isc_boolean_true, &setting)); if (setting->type != type) { log_bug("incompatible setting data type requested " "for name '%s' in set of settings '%s'", name, set->name); \ return ISC_R_UNEXPECTED; } switch (type) { case ST_UNSIGNED_INTEGER: *(isc_uint32_t *)target = setting->value.value_uint; break; case ST_STRING: *(char **)target = setting->value.value_char; break; case ST_BOOLEAN: *(isc_boolean_t *)target = setting->value.value_boolean; break; default: UNEXPECTED_ERROR(__FILE__, __LINE__, "invalid setting_type_t value %u", type); break; } return ISC_R_SUCCESS; cleanup: log_bug("setting '%s' was not found in settings tree", name); return result; }
/** * Un-set value in given set of settings (non-recursively, parent sets are * not affected in any way). Function will fail if setting with given name is * not a part of set of settings. * Mutual exclusion is ensured by isc_task_beginexclusive(). * * @warning * Failure in this function usually points to logic error. * Caller should always check return value. * * @retval ISC_R_SUCCESS Setting was un-set. * @retval ISC_R_IGNORE Setting wasn't changed because wasn't set. * @retval ISC_R_NOTFOUND Required setting was not found * in given set of settings. */ isc_result_t setting_unset(const char *const name, const settings_set_t *set) { isc_result_t result; setting_t *setting = NULL; CHECK(setting_find(name, set, ISC_FALSE, ISC_FALSE, &setting)); if (!setting->filled) return ISC_R_IGNORE; LOCK(set->lock); switch (setting->type) { case ST_STRING: if (setting->is_dynamic) isc_mem_free(set->mctx, setting->value.value_char); setting->is_dynamic = ISC_FALSE; break; case ST_UNSIGNED_INTEGER: case ST_BOOLEAN: break; default: UNEXPECTED_ERROR(__FILE__, __LINE__, "invalid setting_type_t value %u", setting->type); break; } setting->filled = 0; cleanup: UNLOCK(set->lock); if (result == ISC_R_NOTFOUND) log_bug("setting '%s' was not found in set of settings '%s'", name, set->name); return result; }
/** * Set all values specified by vector of strings to setting set. Setting name * is separated from it's argument with one or more characters defined by * @link SETTING_NAME_SEPARATORS@endlink. * * @retval ISC_R_SUCCESS All strings in argument vector were processed and set. * @retval Others Memory or parsing errors. * * @warning One string in argument vector is limited to * @link SETTING_LINE_MAXLENGTH@endlink. * * @note * @code{.txt} * Calling settings_set_fill() with argument array * * {"setting1 value 1 ", * "bind_dn cn=Directory manager" } * * will result in setting values to two separate settings: * * "setting1" = "value 1 " * "bind_dn" = "cn=Directory manager" * * Please note the positions of white spaces. * @endcode */ isc_result_t settings_set_fill(settings_set_t *set, const char *const *argv) { isc_result_t result; int i; const char *name; char *value; for (i = 0; argv[i] != NULL; i++) { char buff[SETTING_LINE_MAXLENGTH] = ""; CHECK(isc_string_copy(buff, SETTING_LINE_MAXLENGTH, argv[i])); value = buff; name = isc_string_separate(&value, SETTING_NAME_SEPARATORS); if (name == NULL || value == NULL) CLEANUP_WITH(ISC_R_UNEXPECTEDEND); value += strspn(value, SETTING_NAME_SEPARATORS); if (setting_find(name, set, ISC_FALSE, ISC_TRUE, NULL) != ISC_R_NOTFOUND) { log_error("multiple definitions of setting '%s' in " "set of settings '%s'", name, set->name); CLEANUP_WITH(ISC_R_EXISTS); } result = setting_set(name, set, value); if (result != ISC_R_SUCCESS && result != ISC_R_IGNORE) goto cleanup; } return ISC_R_SUCCESS; cleanup: log_error_r("cannot parse settings from '%s': " "problematic configuration line:" "\n%s\n" "error code", set->name, argv[i]); /* TODO: Free memory in case of error. */ return result; }
/** * Change setting 'name' to value specified by attribute 'attr_name' in LDAP * entry. Setting is un-set if specified value is missing in LDAP entry. * * @warning Multi-value attributes are no supported. * * @retval ISC_R_SUCCESS Setting was changed (set or unset). * @retval ISC_R_IGNORE Setting wasn't changed because value in settings set * and LDAP entry was same. * @retval ISC_R_NOTFOUND Required setting was not found in given set. * @retval Others Memory allocation or conversion errors. */ isc_result_t setting_update_from_ldap_entry(const char *name, settings_set_t *set, const char *attr_name, ldap_entry_t *entry) { isc_result_t result; setting_t *setting = NULL; ldap_valuelist_t values; CHECK(setting_find(name, set, ISC_FALSE, ISC_FALSE, &setting)); result = ldap_entry_getvalues(entry, attr_name, &values); if (result == ISC_R_NOTFOUND || HEAD(values) == NULL) { CHECK(setting_unset(name, set)); log_debug(2, "setting '%s' (%s) was deleted in object %s", name, attr_name, ldap_entry_logname(entry)); return ISC_R_SUCCESS; } else if (result != ISC_R_SUCCESS) { goto cleanup; } if (HEAD(values) != TAIL(values)) { log_bug("multi-value attributes are not supported: attribute " "'%s' in %s", attr_name, ldap_entry_logname(entry)); return ISC_R_NOTIMPLEMENTED; } CHECK(setting_set(name, set, HEAD(values)->value)); log_debug(2, "setting '%s' (%s) was changed to '%s' in %s", name, attr_name, HEAD(values)->value, ldap_entry_logname(entry)); cleanup: if (result == ISC_R_NOTFOUND) log_bug("setting '%s' was not found in settings set '%s'", name, set->name); return result; }