/* * Return a snapshot for the supplied instance and snapshot name. */ static scf_snapshot_t * get_snapshot(const scf_instance_t *inst, const char *snapshot) { scf_snapshot_t *snap = scf_snapshot_create(hndl); if (snap == NULL) scfdie(); if (scf_instance_get_snapshot(inst, snapshot, snap) == -1) { switch (scf_error()) { case SCF_ERROR_INVALID_ARGUMENT: die(gettext("Invalid snapshot name.\n")); /* NOTREACHED */ case SCF_ERROR_NOT_FOUND: if (sflag == 0) { scf_snapshot_destroy(snap); snap = NULL; } else die(gettext("No such snapshot.\n")); break; default: scfdie(); } } return (snap); }
static int set_svc_enable_cb(void *data, scf_walkinfo_t *wip) { uint8_t desired = *(uint8_t *)data; const char *instname = wip->fmri; if (desired) { if (smf_enable_instance(instname, 0) == 0) return (0); } else { if (smf_disable_instance(instname, 0) == 0) return (0); } switch (scf_error()) { case SCF_ERROR_INVALID_ARGUMENT: uu_die(gettext("Error: \"%s\" is not a valid service " "instance.\n"), instname); break; case SCF_ERROR_NOT_FOUND: uu_die(gettext("Error: Service instance \"%s\" not found.\n"), instname); break; default: scfdie(); } return (0); }
/* * Add the proto list contained in array 'plist' to entry 'entry', storing * aside the scf_value_t's created and added to the entry in a list that the * pointer referenced by sv_list is made to point at. */ static void add_proto_list(scf_transaction_entry_t *entry, scf_handle_t *hdl, char **plist, uu_list_t **sv_list) { scf_val_el_t *sv_el; int i; static uu_list_pool_t *sv_pool = NULL; if ((sv_pool == NULL) && ((sv_pool = uu_list_pool_create("sv_pool", sizeof (scf_val_el_t), offsetof(scf_val_el_t, link), NULL, UU_LIST_POOL_DEBUG)) == NULL)) uu_die(gettext("Error: %s.\n"), uu_strerror(uu_error())); if ((*sv_list = uu_list_create(sv_pool, NULL, 0)) == NULL) uu_die(gettext("Error: %s.\n"), uu_strerror(uu_error())); for (i = 0; plist[i] != NULL; i++) { if ((sv_el = malloc(sizeof (scf_val_el_t))) == NULL) uu_die(gettext("Error:")); if (((sv_el->val = scf_value_create(hdl)) == NULL) || (scf_value_set_astring(sv_el->val, plist[i]) != 0) || (scf_entry_add_value(entry, sv_el->val) != 0)) scfdie(); uu_list_node_init(sv_el, &sv_el->link, sv_pool); (void) uu_list_insert_after(*sv_list, NULL, sv_el); } }
static void list_services() { (void) printf("%-10s%-15s%s\n", "ENABLED", "STATE", "FMRI"); if (scf_simple_walk_instances(SCF_STATE_ALL, NULL, list_callback) == SCF_FAILED) scfdie(); }
static void delete_prop(const scf_instance_t *inst, const char *pg, const char *prop) { scf_transaction_t *tx; scf_transaction_entry_t *ent; scf_propertygroup_t *gpg; scf_property_t *eprop; int ret; if ((gpg = scf_pg_create(h)) == NULL || (eprop = scf_property_create(h)) == NULL || (tx = scf_transaction_create(h)) == NULL || (ent = scf_entry_create(h)) == NULL) scfdie(); if (scf_instance_get_pg(inst, pg, gpg) != SCF_SUCCESS) { if (scf_error() != SCF_ERROR_NOT_FOUND) scfdie(); uu_die(gettext("Error: \"%s\" property group missing.\n"), pg); } do { if (scf_transaction_start(tx, gpg) != SCF_SUCCESS) { if (scf_error() != SCF_ERROR_PERMISSION_DENIED) scfdie(); uu_die(gettext("Error: Permission denied.\n")); } if (scf_transaction_property_delete(tx, ent, prop) != SCF_SUCCESS) { if (scf_error() != SCF_ERROR_NOT_FOUND) scfdie(); uu_die( gettext("Error: \"%s\" property does not exist.\n"), prop); } ret = scf_transaction_commit(tx); if (ret < 0) { if (scf_error() != SCF_ERROR_PERMISSION_DENIED) scfdie(); uu_die(gettext("Error: Permission denied.\n")); } if (ret == 0) { scf_transaction_reset(tx); if (scf_pg_update(gpg) == -1) scfdie(); } } while (ret == 0); (void) scf_entry_destroy(ent); scf_transaction_destroy(tx); scf_property_destroy(eprop); scf_pg_destroy(gpg); }
/* * display_prop() all of the properties in the given property group. Force * types to true so identification will be displayed. */ static void display_pg(scf_propertygroup_t *pg) { scf_property_t *prop; scf_iter_t *iter; int ret; types = 1; /* Always display types for whole propertygroups. */ if ((prop = scf_property_create(hndl)) == NULL || (iter = scf_iter_create(hndl)) == NULL) scfdie(); if (scf_iter_pg_properties(iter, pg) == -1) scfdie(); while ((ret = scf_iter_next_property(iter, prop)) == 1) display_prop(pg, prop); if (ret == -1) scfdie(); scf_iter_destroy(iter); scf_property_destroy(prop); }
static void print_value(scf_value_t *val) { char *buf, *qbuf; ssize_t bufsz, r; bufsz = scf_value_get_as_string(val, NULL, 0) + 1; if (bufsz - 1 < 0) scfdie(); buf = safe_malloc(bufsz); r = scf_value_get_as_string(val, buf, bufsz); assert(r + 1 == bufsz); qbuf = quote_for_shell(buf); (void) fputs(qbuf, stdout); free(qbuf); free(buf); }
static void list_defaults() { scf_handle_t *h; scf_error_t err; int i; inetd_prop_t *proptable; size_t numprops; if (((h = scf_handle_create(SCF_VERSION)) == NULL) || (scf_handle_bind(h) == -1)) scfdie(); if ((proptable = read_default_props(h, &numprops, &err)) == NULL) { uu_die(gettext("Unexpected libscf error: %s. Exiting.\n"), scf_strerror(err)); } (void) printf("NAME=VALUE\n"); for (i = 0; i < numprops; i++) { if (!proptable[i].ip_default) continue; if (proptable[i].ip_error == IVE_UNSET) { (void) uu_warn(gettext("Error: Default property %s " "missing.\n"), proptable[i].ip_name); continue; } (void) printf("%s=", proptable[i].ip_name); print_prop_val(&proptable[i]); } free_instance_props(proptable); }
/* * Without -p options, just call display_pg(). Otherwise display_prop() the * named properties of the property group. */ static void process_pg(scf_propertygroup_t *pg) { scf_property_t *prop; svcprop_prop_node_t *spn; if (uu_list_first(prop_list) == NULL) { if (quiet) return; display_pg(pg); return; } prop = scf_property_create(hndl); if (prop == NULL) scfdie(); for (spn = uu_list_first(prop_list); spn != NULL; spn = uu_list_next(prop_list, spn)) { if (spn->spn_comp2 != NULL) { char *buf; buf = safe_malloc(max_scf_fmri_length + 1); if (scf_pg_to_fmri(pg, buf, max_scf_fmri_length + 1) == -1) scfdie(); uu_xdie(UU_EXIT_USAGE, gettext("-p argument `%s/%s' " "has too many components for property " "group `%s'.\n"), spn->spn_comp1, spn->spn_comp2, buf); free(buf); } if (scf_pg_get_property(pg, spn->spn_comp1, prop) == 0) { if (!quiet) display_prop(pg, prop); continue; } if (scf_error() != SCF_ERROR_NOT_FOUND) scfdie(); if (PRINT_NOPROP_ERRORS) { char *buf; buf = safe_malloc(max_scf_fmri_length + 1); if (scf_pg_to_fmri(pg, buf, max_scf_fmri_length + 1) == -1) scfdie(); uu_warn(gettext("Couldn't find property `%s' in " "property group `%s'.\n"), spn->spn_comp1, buf); free(buf); } noprop_common_action(); } }
/* * Entity (service or instance): If there are -p options, * display_{pg,prop}() the named property groups and/or properties. Otherwise * display_pg() all property groups. */ static void process_ent(scf_entityp_t ent) { scf_snapshot_t *snap = NULL; scf_propertygroup_t *pg; scf_property_t *prop; scf_iter_t *iter; svcprop_prop_node_t *spn; int ret, err; if (uu_list_numnodes(prop_list) == 0) { if (quiet) return; if ((pg = scf_pg_create(hndl)) == NULL || (iter = scf_iter_create(hndl)) == NULL) scfdie(); if (cflag || Cflag || ent.type != ENT_INSTANCE) { if (scf_iter_entity_pgs(iter, ent) == -1) scfdie(); } else { if (snapshot != NULL) snap = get_snapshot(ent.u.inst, snapshot); if (scf_iter_instance_pgs_composed(iter, ent.u.inst, snap) == -1) scfdie(); if (snap) scf_snapshot_destroy(snap); } while ((ret = scf_iter_next_pg(iter, pg)) == 1) display_pg(pg); if (ret == -1) scfdie(); /* * In normal usage, i.e. against the running snapshot, * we must iterate over the current non-persistent * pg's. */ if (sflag == 0 && snap != NULL) { scf_iter_reset(iter); if (scf_iter_instance_pgs_composed(iter, ent.u.inst, NULL) == -1) scfdie(); while ((ret = scf_iter_next_pg(iter, pg)) == 1) { uint32_t flags; if (scf_pg_get_flags(pg, &flags) == -1) scfdie(); if (flags & SCF_PG_FLAG_NONPERSISTENT) display_pg(pg); } } if (ret == -1) scfdie(); scf_iter_destroy(iter); scf_pg_destroy(pg); return; } if ((pg = scf_pg_create(hndl)) == NULL || (prop = scf_property_create(hndl)) == NULL) scfdie(); if (ent.type == ENT_INSTANCE && snapshot != NULL) snap = get_snapshot(ent.u.inst, snapshot); for (spn = uu_list_first(prop_list); spn != NULL; spn = uu_list_next(prop_list, spn)) { if (ent.type == ENT_INSTANCE) { if (Cflag) ret = scf_instance_get_pg(ent.u.inst, spn->spn_comp1, pg); else ret = scf_instance_get_pg_composed(ent.u.inst, snap, spn->spn_comp1, pg); err = scf_error(); /* * If we didn't find it in the specified snapshot, use * the current values if the pg is nonpersistent. */ if (ret == -1 && !Cflag &&snap != NULL && err == SCF_ERROR_NOT_FOUND) { ret = scf_instance_get_pg_composed( ent.u.inst, NULL, spn->spn_comp1, pg); if (ret == 0) { uint32_t flags; if (scf_pg_get_flags(pg, &flags) == -1) scfdie(); if ((flags & SCF_PG_FLAG_NONPERSISTENT) == 0) { ret = -1; } } } } else { /* * If we are displaying properties for a service, * treat it as though it were a composed, current * lookup. (implicit cflag) However, if a snapshot * was specified, fail. */ if (sflag) die(gettext("Only instances have " "snapshots.\n")); ret = scf_entity_get_pg(ent, spn->spn_comp1, pg); err = scf_error(); } if (ret == -1) { if (err != SCF_ERROR_NOT_FOUND) scfdie(); if (PRINT_NOPROP_ERRORS) { char *buf; buf = safe_malloc(max_scf_fmri_length + 1); if (scf_entity_to_fmri(ent, buf, max_scf_fmri_length + 1) == -1) scfdie(); uu_warn(gettext("Couldn't find property group " "`%s' for %s `%s'.\n"), spn->spn_comp1, SCF_ENTITY_TYPE_NAME(ent), buf); free(buf); } noprop_common_action(); continue; } if (spn->spn_comp2 == NULL) { if (!quiet) display_pg(pg); continue; } if (scf_pg_get_property(pg, spn->spn_comp2, prop) == -1) { if (scf_error() != SCF_ERROR_NOT_FOUND) scfdie(); if (PRINT_NOPROP_ERRORS) { char *buf; buf = safe_malloc(max_scf_fmri_length + 1); if (scf_entity_to_fmri(ent, buf, max_scf_fmri_length + 1) == -1) scfdie(); /* FMRI syntax knowledge */ uu_warn(gettext("Couldn't find property " "`%s/%s' for %s `%s'.\n"), spn->spn_comp1, spn->spn_comp2, SCF_ENTITY_TYPE_NAME(ent), buf); free(buf); } noprop_common_action(); continue; } if (!quiet) display_prop(pg, prop); } scf_property_destroy(prop); scf_pg_destroy(pg); if (snap) scf_snapshot_destroy(snap); }
/* * Display a property's values on a line. If types is true, prepend * identification (the FMRI if fmris is true, pg/prop otherwise) and the type * of the property. */ static void display_prop(scf_propertygroup_t *pg, scf_property_t *prop) { scf_value_t *val; scf_iter_t *iter; int ret, first, err; const char * const permission_denied_emsg = gettext("Permission denied.\n"); if (types) { scf_type_t ty; char *buf; size_t buf_sz; if (fmris) { buf_sz = max_scf_fmri_length + 1; buf = safe_malloc(buf_sz); if (scf_property_to_fmri(prop, buf, buf_sz) == -1) scfdie(); (void) fputs(buf, stdout); free(buf); } else { buf_sz = max_scf_name_length + 1; buf = safe_malloc(buf_sz); if (scf_pg_get_name(pg, buf, buf_sz) < 0) scfdie(); (void) fputs(buf, stdout); (void) putchar('/'); if (scf_property_get_name(prop, buf, buf_sz) < 0) scfdie(); (void) fputs(buf, stdout); free(buf); } (void) putchar(' '); if (scf_property_type(prop, &ty) == -1) scfdie(); (void) fputs(scf_type_to_string(ty), stdout); (void) putchar(' '); } if ((iter = scf_iter_create(hndl)) == NULL || (val = scf_value_create(hndl)) == NULL) scfdie(); if (scf_iter_property_values(iter, prop) == -1) scfdie(); first = 1; while ((ret = scf_iter_next_value(iter, val)) == 1) { if (first) first = 0; else (void) putchar(' '); print_value(val); } if (ret == -1) { err = scf_error(); if (err == SCF_ERROR_PERMISSION_DENIED) { if (uu_list_numnodes(prop_list) > 0) die(permission_denied_emsg); } else { scfdie(); } } (void) putchar('\n'); scf_iter_destroy(iter); (void) scf_value_destroy(val); }
static void modify_prop(const scf_instance_t *inst, const char *pg, const char *prop, scf_type_t type, void *value) { scf_transaction_t *tx; scf_transaction_entry_t *ent; scf_propertygroup_t *gpg; scf_property_t *eprop; scf_value_t *v; int ret, create = 0; char *fmri; ssize_t max_fmri_len; if ((gpg = scf_pg_create(h)) == NULL || (eprop = scf_property_create(h)) == NULL || (v = scf_value_create(h)) == NULL) scfdie(); /* Get the property group or create it if it is missing. */ if (scf_instance_get_pg(inst, pg, gpg) == -1) { if (scf_error() != SCF_ERROR_NOT_FOUND) scfdie(); max_fmri_len = scf_limit(SCF_LIMIT_MAX_FMRI_LENGTH); if ((fmri = malloc(max_fmri_len + 1)) == NULL) uu_die(gettext("Error: Out of memory.\n")); if (scf_instance_to_fmri(inst, fmri, max_fmri_len + 1) < 0) scfdie(); syslog(LOG_NOTICE, "inetadm: Property group \"%s\" missing " "from \"%s\", attempting to add it.\n", pg, fmri); free(fmri); if (scf_instance_add_pg(inst, pg, SCF_GROUP_FRAMEWORK, 0, gpg) == -1) { switch (scf_error()) { case SCF_ERROR_EXISTS: break; case SCF_ERROR_PERMISSION_DENIED: uu_die(gettext("Error: Permission denied.\n")); default: scfdie(); } } } if (scf_pg_get_property(gpg, prop, eprop) == -1) { if (scf_error() != SCF_ERROR_NOT_FOUND) scfdie(); create = 1; } if ((tx = scf_transaction_create(h)) == NULL || (ent = scf_entry_create(h)) == NULL) scfdie(); do { uu_list_t *sv_list; if (scf_transaction_start(tx, gpg) == -1) { if (scf_error() != SCF_ERROR_PERMISSION_DENIED) scfdie(); uu_die(gettext("Error: Permission denied.\n")); } /* Modify the property or create it if it is missing */ if (create) ret = scf_transaction_property_new(tx, ent, prop, type); else ret = scf_transaction_property_change_type(tx, ent, prop, type); if (ret == -1) scfdie(); switch (type) { case SCF_TYPE_BOOLEAN: scf_value_set_boolean(v, *(uint8_t *)value); break; case SCF_TYPE_INTEGER: scf_value_set_integer(v, *(int64_t *)value); break; case SCF_TYPE_ASTRING: if (strcmp(prop, PR_PROTO_NAME) == 0) { add_proto_list(ent, h, (char **)value, &sv_list); } else if (scf_value_set_astring(v, value) == -1) { scfdie(); } break; default: uu_die(gettext("Error: Internal inetadm error")); } if ((strcmp(prop, PR_PROTO_NAME) != 0) && (scf_entry_add_value(ent, v) == -1)) scfdie(); ret = scf_transaction_commit(tx); if (ret == -1) { if (scf_error() != SCF_ERROR_PERMISSION_DENIED) scfdie(); uu_die(gettext("Error: Permission denied.\n")); } scf_transaction_reset(tx); if (ret == 0) { if (scf_pg_update(gpg) == -1) scfdie(); } if (strcmp(prop, PR_PROTO_NAME) == 0) remove_proto_list(ent, sv_list); } while (ret == 0); scf_value_destroy(v); scf_entry_destroy(ent); scf_transaction_destroy(tx); scf_property_destroy(eprop); scf_pg_destroy(gpg); }
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")); }
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); }
/* ARGSUSED0 */ static int list_props_cb(void *data, scf_walkinfo_t *wip) { int i; const char *instname = wip->fmri; scf_simple_prop_t *prop; inetd_prop_t *proplist; const char *restart_str; boolean_t is_rpc = B_FALSE; size_t numprops; scf_handle_t *h; scf_error_t err; if (((h = scf_handle_create(SCF_VERSION)) == NULL) || (scf_handle_bind(h) == -1)) scfdie(); /* * Get the property that holds the name of this instance's * restarter, and make sure that it is inetd. */ if ((prop = scf_simple_prop_get(h, instname, SCF_PG_GENERAL, SCF_PROPERTY_RESTARTER)) == NULL) { if (scf_error() == SCF_ERROR_NOT_FOUND) uu_die(gettext("Error: Specified service instance " "\"%s\" has no restarter property. inetd is not " "the delegated restarter of this instance.\n"), instname); if (scf_error() == SCF_ERROR_INVALID_ARGUMENT) uu_die(gettext("Error: \"%s\" is not a valid service " "instance.\n"), instname); scfdie(); } if (((restart_str = scf_simple_prop_next_ustring(prop)) == NULL) || (strstr(restart_str, INETADM_INETD_STR) == NULL)) { uu_die(gettext("Error: inetd is not the delegated restarter of " "specified service instance \"%s\".\n"), instname); } scf_simple_prop_free(prop); /* * This instance is controlled by inetd, so now we display all * of its properties. First the mandatory properties, and then * the properties that have default values, substituting the * default values inherited from inetd as necessary (this is done * for us by read_instance_props()). */ if ((proplist = read_instance_props(h, instname, &numprops, &err)) == NULL) { uu_die(gettext("Unexpected libscf error: %s. Exiting.\n"), scf_strerror(err)); } scf_handle_destroy(h); (void) printf("%-9s%s\n", "SCOPE", "NAME=VALUE"); for (i = 0; i < numprops; i++) { /* Skip rpc version properties if it's not an RPC service */ if ((strcmp(PR_RPC_LW_VER_NAME, proplist[i].ip_name) == 0) || (strcmp(PR_RPC_HI_VER_NAME, proplist[i].ip_name) == 0)) if (!is_rpc) continue; /* If it's not an unset property, print it out. */ if (proplist[i].ip_error != IVE_UNSET) { if (strcmp(PR_ISRPC_NAME, proplist[i].ip_name) == 0) is_rpc = proplist[i].ip_value.iv_boolean; (void) printf("%-9s%s=", proplist[i].from_inetd ? INETADM_DEFAULT_STR : "", proplist[i].ip_name); print_prop_val(&proplist[i]); continue; } /* arg0 is non-default, but also doesn't have to be set. */ if (i == PT_ARG0_INDEX) continue; /* all other properties should have values. */ if (proplist[i].ip_default) { (void) uu_warn(gettext("Error: Property %s is missing " "and has no defined default value.\n"), proplist[i].ip_name); } else { (void) uu_warn(gettext("Error: Required property %s is " "missing.\n"), proplist[i].ip_name); } } free_instance_props(proplist); return (0); }
/* ARGSUSED */ static int do_wait(void *unused, scf_walkinfo_t *wip) { scf_property_t *prop; scf_propertygroup_t *lpg, *pg; const char *propname; svcprop_prop_node_t *p; const char *emsg_not_found = gettext("Not found.\n"); if ((lpg = scf_pg_create(hndl)) == NULL || (prop = scf_property_create(hndl)) == NULL) scfdie(); if (wip->prop != NULL) { if (uu_list_numnodes(prop_list) > 0) uu_xdie(UU_EXIT_USAGE, gettext("-p cannot be used with " "property FMRIs.\n")); pg = wip->pg; assert(strrchr(wip->fmri, '/') != NULL); propname = strrchr(wip->fmri, '/') + 1; } else if (wip->pg != NULL) { p = uu_list_first(prop_list); if (p != NULL) { if (p->spn_comp2 != NULL) uu_xdie(UU_EXIT_USAGE, gettext("-p argument " "\"%s/%s\" has too many components for " "property group %s.\n"), p->spn_comp1, p->spn_comp2, wip->fmri); propname = p->spn_comp1; if (scf_pg_get_property(wip->pg, propname, prop) != SCF_SUCCESS) { switch (scf_error()) { case SCF_ERROR_INVALID_ARGUMENT: uu_xdie(UU_EXIT_USAGE, gettext("Invalid property name " "\"%s\".\n"), propname); /* NOTREACHED */ case SCF_ERROR_NOT_FOUND: die(emsg_not_found); /* NOTREACHED */ default: scfdie(); } } } else { propname = NULL; } pg = wip->pg; } else if (wip->inst != NULL) { p = uu_list_first(prop_list); if (p == NULL) uu_xdie(UU_EXIT_USAGE, gettext("Cannot wait for an instance.\n")); if (scf_instance_get_pg(wip->inst, p->spn_comp1, lpg) != SCF_SUCCESS) { switch (scf_error()) { case SCF_ERROR_INVALID_ARGUMENT: uu_xdie(UU_EXIT_USAGE, gettext("Invalid " "property group name \"%s\".\n"), p->spn_comp1); case SCF_ERROR_NOT_FOUND: die(emsg_not_found); /* NOTREACHED */ default: scfdie(); } } propname = p->spn_comp2; if (propname != NULL) { if (scf_pg_get_property(lpg, propname, prop) != SCF_SUCCESS) { switch (scf_error()) { case SCF_ERROR_INVALID_ARGUMENT: uu_xdie(UU_EXIT_USAGE, gettext("Invalid property name " "\"%s\".\n"), propname); case SCF_ERROR_NOT_FOUND: die(emsg_not_found); /* NOTREACHED */ default: scfdie(); } } } pg = lpg; } else if (wip->svc != NULL) { p = uu_list_first(prop_list); if (p == NULL) uu_xdie(UU_EXIT_USAGE, gettext("Cannot wait for a service.\n")); if (scf_service_get_pg(wip->svc, p->spn_comp1, lpg) != SCF_SUCCESS) { switch (scf_error()) { case SCF_ERROR_INVALID_ARGUMENT: uu_xdie(UU_EXIT_USAGE, gettext("Invalid " "property group name \"%s\".\n"), p->spn_comp1); case SCF_ERROR_NOT_FOUND: die(emsg_not_found); default: scfdie(); } } propname = p->spn_comp2; if (propname != NULL) { if (scf_pg_get_property(lpg, propname, prop) != SCF_SUCCESS) { switch (scf_error()) { case SCF_ERROR_INVALID_ARGUMENT: uu_xdie(UU_EXIT_USAGE, gettext("Invalid property name " "\"%s\".\n"), propname); /* NOTREACHED */ case SCF_ERROR_NOT_FOUND: die(emsg_not_found); /* NOTREACHED */ default: scfdie(); } } } pg = lpg; } else { uu_xdie(UU_EXIT_USAGE, gettext("FMRI must specify an entity, " "property group, or property.\n")); } for (;;) { int ret; ret = _scf_pg_wait(pg, -1); if (ret != SCF_SUCCESS) scfdie(); ret = scf_pg_update(pg); if (ret < 0) { if (scf_error() != SCF_ERROR_DELETED) scfdie(); die(emsg_not_found); } if (ret == SCF_COMPLETE) break; } if (propname != NULL) { if (scf_pg_get_property(pg, propname, prop) == SCF_SUCCESS) { if (!quiet) display_prop(pg, prop); } else { if (scf_error() != SCF_ERROR_NOT_FOUND) scfdie(); if (PRINT_NOPROP_ERRORS) uu_warn(emsg_not_found); return_code = UU_EXIT_FATAL; } } else { if (!quiet) display_pg(pg); } scf_property_destroy(prop); scf_pg_destroy(lpg); return (0); }
int main(int argc, char *argv[]) { int c; scf_walk_callback callback; int flags; int err; (void) setlocale(LC_ALL, ""); (void) textdomain(TEXT_DOMAIN); return_code = UU_EXIT_OK; (void) uu_setpname(argv[0]); prop_pool = uu_list_pool_create("properties", sizeof (svcprop_prop_node_t), offsetof(svcprop_prop_node_t, spn_list_node), NULL, 0); if (prop_pool == NULL) uu_die("%s\n", uu_strerror(uu_error())); prop_list = uu_list_create(prop_pool, NULL, 0); hndl = scf_handle_create(SCF_VERSION); if (hndl == NULL) scfdie(); while ((c = getopt(argc, argv, "Ccfp:qs:tvwz:")) != -1) { switch (c) { case 'C': if (cflag || sflag || wait) usage(); /* Not with -c, -s or -w */ Cflag++; snapshot = NULL; break; case 'c': if (Cflag || sflag || wait) usage(); /* Not with -C, -s or -w */ cflag++; snapshot = NULL; break; case 'f': types = 1; fmris = 1; break; case 'p': add_prop(optarg); break; case 'q': quiet = 1; warn = quiet_warn; die = quiet_die; break; case 's': if (Cflag || cflag || wait) usage(); /* Not with -C, -c or -w */ snapshot = optarg; sflag++; break; case 't': types = 1; break; case 'v': verbose = 1; break; case 'w': if (Cflag || cflag || sflag) usage(); /* Not with -C, -c or -s */ wait = 1; break; case 'z': { scf_value_t *zone; scf_handle_t *h = hndl; if (getzoneid() != GLOBAL_ZONEID) uu_die(gettext("svcprop -z may only be used " "from the global zone\n")); if ((zone = scf_value_create(h)) == NULL) scfdie(); if (scf_value_set_astring(zone, optarg) != SCF_SUCCESS) scfdie(); if (scf_handle_decorate(h, "zone", zone) != SCF_SUCCESS) uu_die(gettext("invalid zone '%s'\n"), optarg); scf_value_destroy(zone); break; } case '?': switch (optopt) { case 'p': usage(); default: break; } /* FALLTHROUGH */ default: usage(); } } if (optind == argc) usage(); max_scf_name_length = scf_limit(SCF_LIMIT_MAX_NAME_LENGTH); max_scf_value_length = scf_limit(SCF_LIMIT_MAX_VALUE_LENGTH); max_scf_fmri_length = scf_limit(SCF_LIMIT_MAX_FMRI_LENGTH); if (max_scf_name_length == -1 || max_scf_value_length == -1 || max_scf_fmri_length == -1) scfdie(); if (scf_handle_bind(hndl) == -1) die(gettext("Could not connect to configuration repository: " "%s.\n"), scf_strerror(scf_error())); flags = SCF_WALK_PROPERTY | SCF_WALK_SERVICE | SCF_WALK_EXPLICIT; if (wait) { if (uu_list_numnodes(prop_list) > 1) usage(); if (argc - optind > 1) usage(); callback = do_wait; } else { callback = process_fmri; flags |= SCF_WALK_MULTIPLE; } if ((err = scf_walk_fmri(hndl, argc - optind, argv + optind, flags, callback, NULL, &return_code, warn)) != 0) { warn(gettext("failed to iterate over instances: %s\n"), scf_strerror(err)); return_code = UU_EXIT_FATAL; } scf_handle_destroy(hndl); return (return_code); }
int main(int argc, char *argv[]) { int opt; uint_t lflag, eflag, dflag, pflag, mflag, Mflag; uint8_t enable; scf_error_t serr; int exit_status = 0; (void) setlocale(LC_ALL, ""); (void) textdomain(TEXT_DOMAIN); if ((h = scf_handle_create(SCF_VERSION)) == NULL) scfdie(); if (scf_handle_bind(h) == -1) uu_die(gettext("Error: Couldn't bind to svc.configd.\n")); if (argc == 1) { list_services(); goto out; } lflag = eflag = dflag = pflag = mflag = Mflag = 0; while ((opt = getopt(argc, argv, "ledpMm?")) != -1) { switch (opt) { case 'l': lflag = 1; break; case 'e': eflag = 1; break; case 'd': dflag = 1; break; case 'p': pflag = 1; break; case 'M': Mflag = 1; break; case 'm': mflag = 1; break; case '?': if (optopt == '?') { usage(B_TRUE); goto out; } else { usage(B_FALSE); } default: usage(B_FALSE); } } /* * All options are mutually exclusive, and we must have an option * if we reached here. */ if (lflag + eflag + dflag + pflag + mflag + Mflag != 1) usage(B_FALSE); argv += optind; argc -= optind; if ((pflag == 0) && (argc == 0)) usage(B_FALSE); serr = 0; if (lflag) { serr = scf_walk_fmri(h, argc, argv, 0, list_props_cb, NULL, &exit_status, uu_warn); } else if (dflag) { enable = 0; serr = scf_walk_fmri(h, argc, argv, 0, set_svc_enable_cb, &enable, &exit_status, uu_warn); } else if (eflag) { enable = 1; serr = scf_walk_fmri(h, argc, argv, 0, set_svc_enable_cb, &enable, &exit_status, uu_warn); } else if (mflag) { arglist_t args; char **cpp = argv; uint_t fmri_args = 0; /* count number of fmri arguments */ while ((fmri_args < argc) && (strchr(*cpp, '=') == NULL)) { fmri_args++; cpp++; } /* if no x=y args or no fmri, show usage */ if ((fmri_args == argc) || (fmri_args == 0)) usage(B_FALSE); /* setup args for modify_inst_props_cb */ args.argc = argc - fmri_args; args.argv = argv + fmri_args; serr = scf_walk_fmri(h, fmri_args, argv, 0, modify_inst_props_cb, &args, &exit_status, uu_warn); } else if (Mflag) { modify_defaults(argc, argv); } else if (pflag) { /* ensure there's no trailing garbage */ if (argc != 0) usage(B_FALSE); list_defaults(); } if (serr != 0) { uu_warn(gettext("failed to iterate over instances: %s"), scf_strerror(serr)); exit(UU_EXIT_FATAL); } out: (void) scf_handle_unbind(h); scf_handle_destroy(h); return (exit_status); }