/* * Gets integer property value. * Caller is responsible to have enough memory allocated. */ int smb_smf_get_integer_property(smb_scfhandle_t *handle, char *propname, int64_t *valint) { int ret = SMBD_SMF_OK; scf_value_t *value = NULL; scf_property_t *prop = NULL; if (handle == NULL) return (SMBD_SMF_SYSTEM_ERR); value = scf_value_create(handle->scf_handle); prop = scf_property_create(handle->scf_handle); if ((prop) && (value) && (scf_pg_get_property(handle->scf_pg, propname, prop) == 0)) { if (scf_property_get_value(prop, value) == 0) { if (scf_value_get_integer(value, valint) != 0) { ret = SMBD_SMF_SYSTEM_ERR; } } else { ret = SMBD_SMF_SYSTEM_ERR; } } else { ret = SMBD_SMF_SYSTEM_ERR; } if (value != NULL) scf_value_destroy(value); if (prop != NULL) scf_property_destroy(prop); return (ret); }
static void kbd_defaults(int kbd) { scf_handle_t *h = NULL; scf_snapshot_t *snap = NULL; scf_instance_t *inst = NULL; scf_propertygroup_t *pg = NULL; scf_property_t *prop = NULL; scf_value_t *val = NULL; int layout_num; char *val_layout = NULL, *val_abort = NULL; uint8_t val_click; int64_t val_delay, val_rate; int64_t val_kbd_beeper, val_console_beeper; if ((h = scf_handle_create(SCF_VERSION)) == NULL || scf_handle_bind(h) != 0 || (inst = scf_instance_create(h)) == NULL || (snap = scf_snapshot_create(h)) == NULL || (pg = scf_pg_create(h)) == NULL || (prop = scf_property_create(h)) == NULL || (val = scf_value_create(h)) == NULL) { goto out; } if (scf_handle_decode_fmri(h, KBD_FMRI, NULL, NULL, inst, NULL, NULL, SCF_DECODE_FMRI_REQUIRE_INSTANCE) != 0) { goto out; } if (scf_instance_get_snapshot(inst, "running", snap) != 0) { scf_snapshot_destroy(snap); snap = NULL; } if (scf_instance_get_pg_composed(inst, snap, KBD_PG, pg) != 0) { goto out; } if ((val_abort = malloc(KBD_MAX_NAME_LEN)) == NULL) { (void) fprintf(stderr, "Can not alloc memory for keyboard properties\n"); goto out; } if ((val_layout = malloc(KBD_MAX_NAME_LEN)) == NULL) { (void) fprintf(stderr, "Can not alloc memory for keyboard properties\n"); goto out; } if (scf_pg_get_property(pg, KBD_PROP_KEYCLICK, prop) != 0 || scf_property_get_value(prop, val) != 0 || scf_value_get_boolean(val, &val_click) == -1) { (void) fprintf(stderr, "Can not get KEYCLICK\n"); } if (val_click == 1) (void) click("on", kbd); else if (val_click == 0) (void) click("off", kbd); else (void) fprintf(stderr, BAD_DEFAULT_INT, KBD_PROP_KEYCLICK, val_click); if (scf_pg_get_property(pg, KBD_PROP_KEYBOARD_ABORT, prop) != 0 || scf_property_get_value(prop, val) != 0 || scf_value_get_astring(val, val_abort, KBD_MAX_NAME_LEN) == -1) { (void) fprintf(stderr, "Can not get KEYBOARD_ABORT\n"); } if (*val_abort != '\0') { /* * ABORT must equal "enable", "disable" or "alternate" */ if ((strcmp(val_abort, "enable") == 0) || (strcmp(val_abort, "alternate") == 0) || (strcmp(val_abort, "disable") == 0)) (void) abort_enable(val_abort, kbd); else (void) fprintf(stderr, BAD_DEFAULT_STR, KBD_PROP_KEYBOARD_ABORT, val_abort); } if (scf_pg_get_property(pg, KBD_PROP_RPTDELAY, prop) != 0 || scf_property_get_value(prop, val) != 0 || scf_value_get_integer(val, &val_delay) == -1) { (void) fprintf(stderr, "Can not get RPTDELAY\n"); } if (val_delay > 0) (void) set_rptdelay(val_delay, kbd); else (void) fprintf(stderr, BAD_DEFAULT_LLINT, KBD_PROP_RPTDELAY, val_delay); if (scf_pg_get_property(pg, KBD_PROP_RPTRATE, prop) != 0 || scf_property_get_value(prop, val) != 0 || scf_value_get_integer(val, &val_rate) == -1) { (void) fprintf(stderr, "Can not get RPTRATE\n"); } if (val_rate > 0) (void) set_rptrate(val_rate, kbd); else (void) fprintf(stderr, BAD_DEFAULT_LLINT, KBD_PROP_RPTRATE, val_rate); if (scf_pg_get_property(pg, KBD_PROP_LAYOUT, prop) != 0 || scf_property_get_value(prop, val) != 0 || scf_value_get_astring(val, val_layout, KBD_MAX_NAME_LEN) == -1) { (void) fprintf(stderr, "Can not get LAYOUT\n"); } if (*val_layout != '\0') { /* * LAYOUT must be one of the layouts supported in kbd_layouts */ if (get_layouts() != 0) goto out; if ((layout_num = get_layout_number(val_layout)) == -1) { (void) fprintf(stderr, BAD_DEFAULT_STR, KBD_PROP_LAYOUT, val_layout); goto out; } (void) set_layout(kbd, layout_num); } if (scf_pg_get_property(pg, KBD_PROP_FREQ, prop) != 0 || scf_property_get_value(prop, val) != 0 || scf_value_get_integer(val, &val_kbd_beeper) == -1) { (void) fprintf(stderr, "Can not get FREQ\n"); } if (val_kbd_beeper >= 0 && val_kbd_beeper <= INT16_MAX) (void) set_beep_freq(kbd, "keyboard", val_kbd_beeper); else (void) fprintf(stderr, BAD_DEFAULT_LLINT, KBD_PROP_FREQ, val_kbd_beeper); if (scf_pg_get_property(pg, KBD_PROP_CONSFREQ, prop) != 0 || scf_property_get_value(prop, val) != 0 || scf_value_get_integer(val, &val_console_beeper) == -1) { (void) fprintf(stderr, "Can not get CONSFREQ\n"); } if (val_console_beeper >= 0 && val_console_beeper <= INT16_MAX) (void) set_beep_freq(kbd, "console", val_console_beeper); else (void) fprintf(stderr, BAD_DEFAULT_LLINT, KBD_PROP_CONSFREQ, val_console_beeper); out: if (val_layout != NULL) free(val_layout); if (val_abort != NULL) free(val_abort); if (snap != NULL) scf_snapshot_destroy(snap); scf_value_destroy(val); scf_property_destroy(prop); scf_pg_destroy(pg); scf_instance_destroy(inst); scf_handle_destroy(h); }
/* * Create a property_t which represents an scf_property_t. Returns * 0 - success * ECANCELED - prop's pg was deleted * ECONNABORTED - repository disconnected * ENOMEM - out of memory * EACCES - permission denied when reading property */ static int load_property(scf_property_t *prop, property_t **ipp) { property_t *iprop; int r; ssize_t ssz; /* get name */ if (scf_property_get_name(prop, loadbuf, loadbuf_sz) < 0) { switch (scf_error()) { case SCF_ERROR_DELETED: return (ECANCELED); case SCF_ERROR_CONNECTION_BROKEN: return (ECONNABORTED); case SCF_ERROR_NOT_BOUND: case SCF_ERROR_NOT_SET: default: bad_error("scf_property_get_name", scf_error()); } } iprop = internal_property_new(); iprop->sc_property_name = strdup(loadbuf); if (iprop->sc_property_name == NULL) { internal_property_free(iprop); return (ENOMEM); } /* get type */ if (scf_property_type(prop, &iprop->sc_value_type) != 0) { switch (scf_error()) { case SCF_ERROR_DELETED: r = ECANCELED; goto out; case SCF_ERROR_CONNECTION_BROKEN: r = ECONNABORTED; goto out; case SCF_ERROR_NOT_BOUND: case SCF_ERROR_NOT_SET: default: bad_error("scf_property_type", scf_error()); } } /* get values */ if (scf_iter_property_values(load_valiter, prop) != 0) { switch (scf_error()) { case SCF_ERROR_DELETED: r = ECANCELED; goto out; case SCF_ERROR_CONNECTION_BROKEN: r = ECONNABORTED; goto out; case SCF_ERROR_HANDLE_MISMATCH: case SCF_ERROR_NOT_BOUND: case SCF_ERROR_NOT_SET: default: bad_error("scf_iter_property_values", scf_error()); } } for (;;) { value_t *ival; r = scf_iter_next_value(load_valiter, load_val); if (r == 0) break; if (r != 1) { switch (scf_error()) { case SCF_ERROR_DELETED: r = ECANCELED; goto out; case SCF_ERROR_CONNECTION_BROKEN: r = ECONNABORTED; goto out; case SCF_ERROR_PERMISSION_DENIED: r = EACCES; goto out; case SCF_ERROR_HANDLE_MISMATCH: case SCF_ERROR_NOT_BOUND: case SCF_ERROR_NOT_SET: case SCF_ERROR_INVALID_ARGUMENT: default: bad_error("scf_iter_next_value", scf_error()); } } ival = internal_value_new(); ival->sc_type = scf_value_type(load_val); assert(ival->sc_type != SCF_TYPE_INVALID); switch (ival->sc_type) { case SCF_TYPE_BOOLEAN: { uint8_t b; r = scf_value_get_boolean(load_val, &b); if (r != 0) bad_error("scf_value_get_boolean", scf_error()); ival->sc_u.sc_count = b; break; } case SCF_TYPE_COUNT: r = scf_value_get_count(load_val, &ival->sc_u.sc_count); if (r != 0) bad_error("scf_value_get_count", scf_error()); break; case SCF_TYPE_INTEGER: r = scf_value_get_integer(load_val, &ival->sc_u.sc_integer); if (r != 0) bad_error("scf_value_get_integer", scf_error()); break; default: ssz = scf_value_get_as_string(load_val, loadbuf, loadbuf_sz); if (ssz < 0) bad_error("scf_value_get_as_string", scf_error()); ival->sc_u.sc_string = strdup(loadbuf); if (ival->sc_u.sc_string == NULL) { r = ENOMEM; goto out; } ival->sc_free = internal_value_free_str; } internal_attach_value(iprop, ival); } *ipp = iprop; return (0); out: free(iprop->sc_property_name); internal_property_free(iprop); return (r); }
int fs_smf_get_prop(smf_fstype_t fstype, char *prop_name, char *cbuf, char *instance, scf_type_t sctype, char *fmri, int *bufsz) { fs_smfhandle_t *phandle = NULL; scf_handle_t *handle; scf_propertygroup_t *pg; scf_property_t *prop; scf_value_t *val; scf_instance_t *inst; int ret = 0, len = 0, length; int64_t valint = 0; char srv[MAXPATHLEN], *p, *svcname; const char *pgname; uint8_t bval; /* * The SVC names we are using currently are already * appended by default. Fix this for instances project. */ snprintf(srv, MAXPATHLEN, "%s", fmri); p = strstr(fmri, ":default"); if (p == NULL) { strcat(srv, ":"); if (instance == NULL) instance = "default"; if (strlen(srv) + strlen(instance) > MAXPATHLEN) goto out; strncat(srv, instance, strlen(instance)); } svcname = srv; phandle = fs_smf_init(fmri, instance); if (phandle == NULL) return (SMF_SYSTEM_ERR); handle = phandle->fs_handle; pg = phandle->fs_pg; inst = phandle->fs_instance; prop = phandle->fs_property; val = phandle->fs_value; if (handle == NULL || pg == NULL || prop == NULL || val == NULL || inst == NULL) { return (SMF_SYSTEM_ERR); } if (scf_handle_decode_fmri(handle, svcname, phandle->fs_scope, phandle->fs_service, inst, NULL, NULL, 0) != 0) { ret = scf_error(); goto out; } if (fstype == AUTOFS_SMF) pgname = AUTOFS_PROPS_PGNAME; else pgname = NFS_PROPS_PGNAME; if (scf_instance_get_pg(inst, pgname, pg) != -1) { if (scf_pg_get_property(pg, prop_name, prop) != SCF_SUCCESS) { ret = scf_error(); goto out; } if (scf_property_get_value(prop, val) != SCF_SUCCESS) { ret = scf_error(); goto out; } switch (sctype) { case SCF_TYPE_ASTRING: len = scf_value_get_astring(val, cbuf, *bufsz); if (len < 0 || len > *bufsz) { ret = scf_error(); goto out; } ret = 0; *bufsz = len; break; case SCF_TYPE_INTEGER: if (scf_value_get_integer(val, &valint) != 0) { ret = scf_error(); goto out; } length = snprintf(cbuf, *bufsz, "%lld", valint); if (length < 0 || length > *bufsz) { ret = SA_BAD_VALUE; goto out; } ret = 0; break; case SCF_TYPE_BOOLEAN: if (scf_value_get_boolean(val, &bval) != 0) { ret = scf_error(); goto out; } if (bval == 1) { length = snprintf(cbuf, *bufsz, "%s", "true"); } else { length = snprintf(cbuf, *bufsz, "%s", "false"); } if (length < 0 || length > *bufsz) { ret = SA_BAD_VALUE; goto out; } break; } } else { ret = scf_error(); } if ((ret != 0) && scf_error() != SCF_ERROR_NONE) { /* * This is a workaround for the NFS service manifests not * containing the proper properties in local zones. * * When in a local zone and the property doesn't exist on an NFS * service (most likely nfs/server or nfs/client), don't print * the error. The caller will still see the correct error code, * but a user creating a delegated dataset or mounting an NFS * share won't see this spurious error. */ if (getzoneid() == GLOBAL_ZONEID || scf_error() != SCF_ERROR_NOT_FOUND) { fprintf(stdout, gettext("%s\n"), scf_strerror(ret)); } } out: fs_smf_fini(phandle); return (ret); }
int fs_smf_get_prop(smf_fstype_t fstype, char *prop_name, char *cbuf, char *instance, scf_type_t sctype, char *fmri, int *bufsz) { fs_smfhandle_t *phandle = NULL; scf_handle_t *handle; scf_propertygroup_t *pg; scf_property_t *prop; scf_value_t *val; scf_instance_t *inst; int ret = 0, len = 0, length; int64_t valint = 0; char srv[MAXPATHLEN], *p, *svcname; const char *pgname; uint8_t bval; /* * The SVC names we are using currently are already * appended by default. Fix this for instances project. */ snprintf(srv, MAXPATHLEN, "%s", fmri); p = strstr(fmri, ":default"); if (p == NULL) { strcat(srv, ":"); if (instance == NULL) instance = "default"; if (strlen(srv) + strlen(instance) > MAXPATHLEN) goto out; strncat(srv, instance, strlen(instance)); } svcname = srv; phandle = fs_smf_init(fmri, instance); if (phandle == NULL) return (SMF_SYSTEM_ERR); handle = phandle->fs_handle; pg = phandle->fs_pg; inst = phandle->fs_instance; prop = phandle->fs_property; val = phandle->fs_value; if (handle == NULL || pg == NULL || prop == NULL || val == NULL || inst == NULL) { return (SMF_SYSTEM_ERR); } if (scf_handle_decode_fmri(handle, svcname, phandle->fs_scope, phandle->fs_service, inst, NULL, NULL, 0) != 0) { ret = scf_error(); goto out; } if (fstype == AUTOFS_SMF) pgname = AUTOFS_PROPS_PGNAME; else pgname = NFS_PROPS_PGNAME; if (scf_instance_get_pg(inst, pgname, pg) != -1) { if (scf_pg_get_property(pg, prop_name, prop) != SCF_SUCCESS) { ret = scf_error(); goto out; } if (scf_property_get_value(prop, val) != SCF_SUCCESS) { ret = scf_error(); goto out; } switch (sctype) { case SCF_TYPE_ASTRING: len = scf_value_get_astring(val, cbuf, *bufsz); if (len < 0 || len > *bufsz) { ret = scf_error(); goto out; } ret = 0; *bufsz = len; break; case SCF_TYPE_INTEGER: if (scf_value_get_integer(val, &valint) != 0) { ret = scf_error(); goto out; } length = snprintf(cbuf, *bufsz, "%lld", valint); if (length < 0 || length > *bufsz) { ret = SA_BAD_VALUE; goto out; } ret = 0; break; case SCF_TYPE_BOOLEAN: if (scf_value_get_boolean(val, &bval) != 0) { ret = scf_error(); goto out; } if (bval == 1) { length = snprintf(cbuf, *bufsz, "%s", "true"); } else { length = snprintf(cbuf, *bufsz, "%s", "false"); } if (length < 0 || length > *bufsz) { ret = SA_BAD_VALUE; goto out; } break; } } else { ret = scf_error(); } if ((ret != 0) && scf_error() != SCF_ERROR_NONE) fprintf(stdout, gettext("%s\n"), scf_strerror(ret)); out: fs_smf_fini(phandle); return (ret); }