Example #1
0
/*
 * 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);
}
Example #2
0
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);
}
Example #3
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);
	}
}
Example #4
0
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();
}
Example #5
0
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);
}
Example #6
0
/*
 * 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);
}
Example #7
0
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);
}
Example #8
0
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);
}
Example #9
0
/*
 * 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();
	}
}
Example #10
0
/*
 * 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);
}
Example #11
0
/*
 * 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);
}
Example #12
0
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);
}
Example #13
0
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"));
}
Example #14
0
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);
}
Example #15
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);
}
Example #16
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);
}
Example #17
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);
}
Example #18
0
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);
}