static void modify_defaults(int argc, char *argv[]) { int i, j; char *value; scf_instance_t *inst; inetd_prop_t *mod, *prop_table; size_t numprops; ssize_t max_val; int64_t new_int; if ((inst = scf_instance_create(h)) == NULL) scfdie(); if (scf_handle_decode_fmri(h, INETD_INSTANCE_FMRI, NULL, NULL, inst, NULL, NULL, SCF_DECODE_FMRI_EXACT) == -1) { if (scf_error() == SCF_ERROR_NOT_FOUND) { uu_die(gettext("inetd instance missing in repository." "\n")); } else { scfdie(); } } if ((max_val = scf_limit(SCF_LIMIT_MAX_VALUE_LENGTH)) < 0) scfdie(); prop_table = get_prop_table(&numprops); if ((mod = malloc(numprops * sizeof (inetd_prop_t))) == NULL) uu_die(gettext("Error: Out of memory.\n")); (void) memcpy(mod, prop_table, numprops * sizeof (inetd_prop_t)); for (i = 0; i < argc; i++) { /* Separate argument into name and value pair */ if ((value = strchr(argv[i], '=')) == NULL) uu_die(gettext("Error: Malformed name=value pair \"%s" "\"\n"), argv[i]); *value = '\0'; value++; /* Find property name in array of defaults */ for (j = 0; mod[j].ip_name != NULL; j++) { if (!mod[j].ip_default) continue; if (strcmp(mod[j].ip_name, argv[i]) == 0) break; } if (mod[j].ip_name == NULL) uu_die(gettext("Error: \"%s\" is not a default inetd " "property.\n"), argv[i]); if (*value == '\0') uu_die(gettext("Cannot accept NULL values for default " "properties.\n")); switch (mod[j].ip_type) { case INET_TYPE_INTEGER: if (uu_strtoint(value, &new_int, sizeof (new_int), NULL, NULL, NULL) == -1) uu_die(gettext("Error: \"%s\" is not a valid " "integer value.\n"), value); mod[j].ip_value.iv_int = new_int; break; case INET_TYPE_STRING: if (strlen(value) >= max_val) uu_die(gettext("Error: String value is longer " "than %l characters.\n"), max_val); if ((mod[j].ip_value.iv_string = strdup(value)) == NULL) uu_die(gettext("Error: Out of memory.\n")); break; case INET_TYPE_BOOLEAN: if (strcasecmp(value, INETADM_TRUE_STR) == 0) mod[j].ip_value.iv_boolean = B_TRUE; else if (strcasecmp(value, INETADM_FALSE_STR) == 0) mod[j].ip_value.iv_boolean = B_FALSE; else uu_die(gettext("Error: \"%s\" is not a valid " "boolean value. (TRUE or FALSE)\n"), value); } /* mark property for modification */ mod[j].ip_error = IVE_VALID; } commit_props(inst, mod, B_TRUE); free(mod); scf_instance_destroy(inst); if (refresh_inetd() != 0) uu_warn(gettext("Warning: Unable to refresh inetd.\n")); }
/* * Returns B_TRUE if all required properties were read from the repository * (whether taken from the defaults or directly from the instance), they * all had valid values, all the required methods were present, and they * each had the required properties with valid values. Else, returns B_FALSE. * If the function returns B_TRUE, the storage referenced by 'cfg' is set * to point at an allocated instance_cfg_t initialized based on the basic * properties (not method or defaults). */ static boolean_t valid_inst_props(const char *fmri, inetd_prop_t *bprops, inetd_prop_t **mprops, basic_cfg_t **cfg) { boolean_t valid; size_t num_bprops; int i; valid = valid_props(bprops, fmri, cfg, proto_info_pool, conn_ind_pool); /* * Double check we've got all necessary properties (valid_props() * doesn't enforce the presence of defaults), and output error messages * for each invalid/ missing property. */ (void) get_prop_table(&num_bprops); for (i = 0; bprops[i].ip_name != NULL; i++) { switch (bprops[i].ip_error) { case IVE_UNSET: if (!bprops[i].ip_default) continue; if ((i == PT_ARG0_INDEX) || (i == PT_EXEC_INDEX)) continue; /* FALLTHROUGH */ case IVE_INVALID: error_msg(gettext("Property '%s' of instance " "%s is missing, inconsistent or invalid"), bprops[i].ip_name, fmri); valid = B_FALSE; } } for (i = 0; i < NUM_METHODS; i++) { int j; /* check if any properties are set */ for (j = 0; mprops[i][j].ip_name != NULL; j++) { if (mprops[i][j].ip_error != IVE_UNSET) break; } if (mprops[i][j].ip_name == NULL) { /* an unspecified method */ if ((instance_method_t)i == IM_START) { error_msg(gettext( "Unspecified %s method for instance %s"), START_METHOD_NAME, fmri); valid = B_FALSE; } } else if (mprops[i][MP_EXEC].ip_error == IVE_UNSET) { error_msg(gettext("Missing %s property from method %s " "of instance %s"), PR_EXEC_NAME, methods[(instance_method_t)i].name, fmri); valid = B_FALSE; } } if (!valid) { destroy_basic_cfg(*cfg); *cfg = NULL; } return (valid); }
static int modify_inst_props_cb(void *data, scf_walkinfo_t *wip) { int i, j; char *value; const char *fmri = wip->fmri; scf_instance_t *inst = wip->inst; inetd_prop_t *mod, *prop_table; size_t numprops; ssize_t max_val; int64_t new_int; int argc = ((arglist_t *)data)->argc; char **argv = ((arglist_t *)data)->argv; if ((max_val = scf_limit(SCF_LIMIT_MAX_VALUE_LENGTH)) < 0) scfdie(); prop_table = get_prop_table(&numprops); if ((mod = malloc(numprops * sizeof (inetd_prop_t))) == NULL) uu_die(gettext("Error: Out of memory.\n")); (void) memcpy(mod, prop_table, numprops * sizeof (inetd_prop_t)); /* * For each property to be changed, look up the property name in the * property table. Change each property in the mod array, and then * write the entire thing back. */ for (i = 0; i < argc; i++) { /* Separate argument into name and value pair */ if ((value = strchr(argv[i], '=')) == NULL) uu_die(gettext("Error: Malformed name=value pair " "\"%s\"\n"), argv[i]); *value = '\0'; value++; /* Find property name in array of properties */ for (j = 0; mod[j].ip_name != NULL; j++) { if (strcmp(mod[j].ip_name, argv[i]) == 0) break; } if (mod[j].ip_name == NULL) uu_die(gettext("Error: \"%s\" is not a valid " "property.\n"), argv[i]); if (*value == '\0') { if ((mod[j].ip_default) || (j == PT_ARG0_INDEX)) { /* mark property for deletion */ mod[j].ip_error = IVE_INVALID; /* return the '=' taken out above */ *(--value) = '='; continue; } else { uu_die(gettext("\"%s\" is a mandatory " "property and can not be deleted.\n"), argv[i]); } } switch (mod[j].ip_type) { case INET_TYPE_INTEGER: if (uu_strtoint(value, &new_int, sizeof (new_int), NULL, NULL, NULL) == -1) uu_die(gettext("Error: \"%s\" is not a valid " "integer value.\n"), value); mod[j].ip_value.iv_int = new_int; break; case INET_TYPE_STRING: if (strlen(value) >= max_val) { uu_die(gettext("Error: String value is longer " "than %l characters.\n"), max_val); } else if ((mod[j].ip_value.iv_string = strdup(value)) == NULL) { uu_die(gettext("Error: Out of memory.\n")); } break; case INET_TYPE_STRING_LIST: if ((mod[j].ip_value.iv_string_list = get_protos(value)) == NULL) { if (errno == ENOMEM) { uu_die(gettext( "Error: Out of memory.\n")); } else if (errno == E2BIG) { uu_die(gettext( "Error: String value in " "%s property longer than " "%l characters.\n"), PR_PROTO_NAME, max_val); } else { uu_die(gettext( "Error: No values " "specified for %s " "property.\n"), PR_PROTO_NAME); } } break; case INET_TYPE_BOOLEAN: if (strcasecmp(value, INETADM_TRUE_STR) == 0) mod[j].ip_value.iv_boolean = B_TRUE; else if (strcasecmp(value, INETADM_FALSE_STR) == 0) mod[j].ip_value.iv_boolean = B_FALSE; else uu_die(gettext("Error: \"%s\" is not a valid " "boolean value. (TRUE or FALSE)\n"), value); } /* mark property for modification */ mod[j].ip_error = IVE_VALID; /* return the '=' taken out above */ *(--value) = '='; } commit_props(inst, mod, B_FALSE); free(mod); if (smf_refresh_instance(fmri) != 0) uu_die(gettext("Error: Unable to refresh instance %s.\n"), fmri); return (0); }