Ejemplo n.º 1
0
/*
 * 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);
}
Ejemplo n.º 2
0
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);
}
Ejemplo n.º 3
0
/*
 * 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);
}
Ejemplo n.º 4
0
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);
}
Ejemplo n.º 5
0
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);
}