xref: /titanic_53/usr/src/cmd/dfs.cmds/sharectl/sharectl.c (revision 4bff34e37def8a90f9194d81bc345c52ba20086a)
16185db85Sdougm /*
26185db85Sdougm  * CDDL HEADER START
36185db85Sdougm  *
46185db85Sdougm  * The contents of this file are subject to the terms of the
56185db85Sdougm  * Common Development and Distribution License (the "License").
66185db85Sdougm  * You may not use this file except in compliance with the License.
76185db85Sdougm  *
86185db85Sdougm  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
96185db85Sdougm  * or http://www.opensolaris.org/os/licensing.
106185db85Sdougm  * See the License for the specific language governing permissions
116185db85Sdougm  * and limitations under the License.
126185db85Sdougm  *
136185db85Sdougm  * When distributing Covered Code, include this CDDL HEADER in each
146185db85Sdougm  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
156185db85Sdougm  * If applicable, add the following below this CDDL HEADER, with the
166185db85Sdougm  * fields enclosed by brackets "[]" replaced with your own identifying
176185db85Sdougm  * information: Portions Copyright [yyyy] [name of copyright owner]
186185db85Sdougm  *
196185db85Sdougm  * CDDL HEADER END
206185db85Sdougm  */
216185db85Sdougm 
226185db85Sdougm /*
23*4bff34e3Sthurlow  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
246185db85Sdougm  * Use is subject to license terms.
256185db85Sdougm  */
266185db85Sdougm 
276185db85Sdougm #pragma ident	"%Z%%M%	%I%	%E% SMI"
286185db85Sdougm 
296185db85Sdougm #include <stdlib.h>
306185db85Sdougm #include <stdio.h>
316185db85Sdougm #include <string.h>
326185db85Sdougm #include <ctype.h>
336185db85Sdougm #include <unistd.h>
346185db85Sdougm #include <getopt.h>
356185db85Sdougm #include <libgen.h>
366185db85Sdougm 
376185db85Sdougm #include "libshare.h"
386185db85Sdougm #include <sharemgr.h>
396185db85Sdougm 
406185db85Sdougm #include <libintl.h>
416185db85Sdougm #include <locale.h>
426185db85Sdougm 
43549ec3ffSdougm static int run_command(char *, int, char **, sa_handle_t);
446185db85Sdougm static void sub_command_help(char *proto);
456185db85Sdougm 
466185db85Sdougm static void
476185db85Sdougm global_help()
486185db85Sdougm {
496185db85Sdougm 	(void) printf(gettext("usage: sharectl <command> [options]\n"));
506185db85Sdougm 	sub_command_help(NULL);
516185db85Sdougm }
526185db85Sdougm 
536185db85Sdougm int
546185db85Sdougm main(int argc, char *argv[])
556185db85Sdougm {
566185db85Sdougm 	int c;
576185db85Sdougm 	int help = 0;
586185db85Sdougm 	int rval;
596185db85Sdougm 	char *command;
60549ec3ffSdougm 	sa_handle_t handle;
616185db85Sdougm 
626185db85Sdougm 	/*
636185db85Sdougm 	 * make sure locale and gettext domain is setup
646185db85Sdougm 	 */
656185db85Sdougm 	(void) setlocale(LC_ALL, "");
666185db85Sdougm 	(void) textdomain(TEXT_DOMAIN);
676185db85Sdougm 
68549ec3ffSdougm 	handle = sa_init(SA_INIT_CONTROL_API);
696185db85Sdougm 
706185db85Sdougm 	while ((c = getopt(argc, argv, "h?")) != EOF) {
716185db85Sdougm 		switch (c) {
726185db85Sdougm 		case '?':
736185db85Sdougm 		case 'h':
746185db85Sdougm 			help = 1;
756185db85Sdougm 			break;
766185db85Sdougm 		default:
776185db85Sdougm 			(void) printf(gettext("Invalid option: %c\n"), c);
786185db85Sdougm 		}
796185db85Sdougm 	}
806185db85Sdougm 	if (optind == argc || help) {
816185db85Sdougm 		/* no subcommand */
826185db85Sdougm 		global_help();
836185db85Sdougm 		exit(0);
846185db85Sdougm 	}
856185db85Sdougm 	optind = 1;
866185db85Sdougm 
876185db85Sdougm 	/*
886185db85Sdougm 	 * now have enough to parse rest of command line
896185db85Sdougm 	 */
906185db85Sdougm 	command = argv[optind];
91549ec3ffSdougm 	rval = run_command(command, argc - optind, argv + optind, handle);
926185db85Sdougm 
93549ec3ffSdougm 	sa_fini(handle);
946185db85Sdougm 	return (rval);
956185db85Sdougm }
966185db85Sdougm 
976185db85Sdougm char *
986185db85Sdougm sc_get_usage(sc_usage_t index)
996185db85Sdougm {
1006185db85Sdougm 	char *ret = NULL;
1016185db85Sdougm 
1026185db85Sdougm 	switch (index) {
1036185db85Sdougm 	case USAGE_CTL_GET:
1043472f5dcSdougm 		ret = gettext("get [-h | -p property ...] proto");
1056185db85Sdougm 		break;
1066185db85Sdougm 	case USAGE_CTL_SET:
1076185db85Sdougm 		ret = gettext("set [-h] -p property=value ... proto");
1086185db85Sdougm 		break;
1096185db85Sdougm 	case USAGE_CTL_STATUS:
1103472f5dcSdougm 		ret = gettext("status [-h | proto ...]");
1116185db85Sdougm 		break;
112*4bff34e3Sthurlow 	case USAGE_CTL_DELSECT:
113*4bff34e3Sthurlow 		ret = gettext("delsect [-h] section proto");
114*4bff34e3Sthurlow 		break;
1156185db85Sdougm 	}
1166185db85Sdougm 	return (ret);
1176185db85Sdougm }
1186185db85Sdougm 
119549ec3ffSdougm /*ARGSUSED*/
1206185db85Sdougm static int
121549ec3ffSdougm sc_get(sa_handle_t handle, int flags, int argc, char *argv[])
1226185db85Sdougm {
1236185db85Sdougm 	char *proto = NULL;
1246185db85Sdougm 	struct options *optlist = NULL;
1256185db85Sdougm 	int ret = SA_OK;
1266185db85Sdougm 	int c;
127*4bff34e3Sthurlow 	sa_protocol_properties_t propset, propsect;
128*4bff34e3Sthurlow 	sa_property_t prop;
129*4bff34e3Sthurlow 	char *section, *value, *name;
130*4bff34e3Sthurlow 	int first = 1;
1316185db85Sdougm 
1326185db85Sdougm 	while ((c = getopt(argc, argv, "?hp:")) != EOF) {
1336185db85Sdougm 		switch (c) {
1346185db85Sdougm 		case 'p':
1356185db85Sdougm 			ret = add_opt(&optlist, optarg, 1);
1366185db85Sdougm 			if (ret != SA_OK) {
13725a68471Sdougm 				(void) printf(gettext(
13825a68471Sdougm 				    "Problem with property: %s\n"), optarg);
1396185db85Sdougm 				return (SA_NO_MEMORY);
1406185db85Sdougm 			}
1416185db85Sdougm 			break;
1426185db85Sdougm 		default:
1436185db85Sdougm 			(void) printf(gettext("usage: %s\n"),
1446185db85Sdougm 			    sc_get_usage(USAGE_CTL_GET));
1456185db85Sdougm 			return (SA_SYNTAX_ERR);
1466185db85Sdougm 		case '?':
1476185db85Sdougm 		case 'h':
1486185db85Sdougm 			(void) printf(gettext("usage: %s\n"),
1496185db85Sdougm 			    sc_get_usage(USAGE_CTL_GET));
1506185db85Sdougm 			return (SA_OK);
1516185db85Sdougm 			break;
1526185db85Sdougm 		}
1536185db85Sdougm 	}
1546185db85Sdougm 
1556185db85Sdougm 	if (optind >= argc) {
15625a68471Sdougm 		(void) printf(gettext("usage: %s\n"),
15725a68471Sdougm 		    sc_get_usage(USAGE_CTL_GET));
1586185db85Sdougm 		(void) printf(gettext("\tprotocol must be specified.\n"));
1596185db85Sdougm 		return (SA_INVALID_PROTOCOL);
1606185db85Sdougm 	}
1616185db85Sdougm 
1626185db85Sdougm 	proto = argv[optind];
163*4bff34e3Sthurlow 	if (!sa_valid_protocol(proto)) {
164*4bff34e3Sthurlow 		(void) printf(gettext("Invalid protocol specified: %s\n"),
165*4bff34e3Sthurlow 		    proto);
166*4bff34e3Sthurlow 		return (SA_INVALID_PROTOCOL);
167*4bff34e3Sthurlow 	}
1686185db85Sdougm 	propset = sa_proto_get_properties(proto);
169*4bff34e3Sthurlow 	if (propset == NULL)
170*4bff34e3Sthurlow 		return (ret);
1716185db85Sdougm 
17225a68471Sdougm 	if (optlist == NULL) {
173*4bff34e3Sthurlow 		/* Display all known properties for this protocol */
174*4bff34e3Sthurlow 		for (propsect = sa_get_protocol_section(propset, NULL);
175*4bff34e3Sthurlow 		    propsect != NULL;
176*4bff34e3Sthurlow 		    propsect = sa_get_next_protocol_section(propsect, NULL)) {
177*4bff34e3Sthurlow 			section = sa_get_property_attr(propsect,
178*4bff34e3Sthurlow 			    "name");
17925a68471Sdougm 			/*
180*4bff34e3Sthurlow 			 * If properties are organized into sections, as
181*4bff34e3Sthurlow 			 * in the SMB client, print the section name.
18225a68471Sdougm 			 */
183*4bff34e3Sthurlow 			if (sa_proto_get_featureset(proto) &
184*4bff34e3Sthurlow 			    SA_FEATURE_HAS_SECTIONS) {
185*4bff34e3Sthurlow 				if (!first)
186*4bff34e3Sthurlow 					(void) printf("\n");
187*4bff34e3Sthurlow 				first = 0;
188*4bff34e3Sthurlow 				(void) printf("[%s]\n", section);
189*4bff34e3Sthurlow 			}
190*4bff34e3Sthurlow 			/* Display properties for this section */
191*4bff34e3Sthurlow 			for (prop = sa_get_protocol_property(propsect, NULL);
19225a68471Sdougm 			    prop != NULL;
193*4bff34e3Sthurlow 			    prop = sa_get_next_protocol_property(prop, NULL)) {
19425a68471Sdougm 
195*4bff34e3Sthurlow 				/* get and display the property and value */
196*4bff34e3Sthurlow 				name = sa_get_property_attr(prop, "type");
1976185db85Sdougm 				if (name != NULL) {
198*4bff34e3Sthurlow 					value = sa_get_property_attr(prop,
199*4bff34e3Sthurlow 					    "value");
200*4bff34e3Sthurlow 					(void) printf(gettext("%s=%s\n"), name,
2016185db85Sdougm 					    value != NULL ? value : "");
2026185db85Sdougm 				}
2036185db85Sdougm 				if (value != NULL)
2046185db85Sdougm 					sa_free_attr_string(value);
2056185db85Sdougm 				if (name != NULL)
2066185db85Sdougm 					sa_free_attr_string(name);
2076185db85Sdougm 			}
208*4bff34e3Sthurlow 		}
2096185db85Sdougm 	} else {
2106185db85Sdougm 		struct options *opt;
211*4bff34e3Sthurlow 
2126185db85Sdougm 		/* list the specified option(s) */
213*4bff34e3Sthurlow 		for (opt = optlist; opt != NULL; opt = opt->next) {
214*4bff34e3Sthurlow 			int printed = 0;
215*4bff34e3Sthurlow 
216*4bff34e3Sthurlow 			for (propsect = sa_get_protocol_section(propset, NULL);
217*4bff34e3Sthurlow 			    propsect != NULL;
218*4bff34e3Sthurlow 			    propsect = sa_get_next_protocol_section(propsect,
219*4bff34e3Sthurlow 			    NULL)) {
220*4bff34e3Sthurlow 
221*4bff34e3Sthurlow 				section = sa_get_property_attr(propsect,
222*4bff34e3Sthurlow 				    "name");
223*4bff34e3Sthurlow 				for (prop = sa_get_protocol_property(propsect,
224*4bff34e3Sthurlow 				    opt->optname);
225*4bff34e3Sthurlow 				    prop != NULL;
226*4bff34e3Sthurlow 				    prop = sa_get_next_protocol_property(
227*4bff34e3Sthurlow 				    propsect, opt->optname)) {
228*4bff34e3Sthurlow 					value = sa_get_property_attr(prop,
229*4bff34e3Sthurlow 					    "value");
230*4bff34e3Sthurlow 					if (sa_proto_get_featureset(proto) &
231*4bff34e3Sthurlow 					    SA_FEATURE_HAS_SECTIONS) {
232*4bff34e3Sthurlow 						(void) printf(
233*4bff34e3Sthurlow 						    gettext("[%s] %s=%s\n"),
234*4bff34e3Sthurlow 						    section, opt->optname,
235*4bff34e3Sthurlow 						    value != NULL ? value : "");
236*4bff34e3Sthurlow 						sa_free_attr_string(section);
2376185db85Sdougm 					} else {
238*4bff34e3Sthurlow 						(void) printf(
239*4bff34e3Sthurlow 						    gettext("%s=%s\n"),
240*4bff34e3Sthurlow 						    opt->optname,
241*4bff34e3Sthurlow 						    value != NULL ? value : "");
242*4bff34e3Sthurlow 					}
243*4bff34e3Sthurlow 					sa_free_attr_string(value);
244*4bff34e3Sthurlow 					printed = 1;
245*4bff34e3Sthurlow 				}
246*4bff34e3Sthurlow 			}
247*4bff34e3Sthurlow 			if (!printed) {
248*4bff34e3Sthurlow 				(void) printf(gettext("%s: not defined\n"),
2496185db85Sdougm 				    opt->optname);
2503472f5dcSdougm 				ret = SA_NO_SUCH_PROP;
2516185db85Sdougm 			}
2526185db85Sdougm 		}
2536185db85Sdougm 	}
2546185db85Sdougm 	return (ret);
2556185db85Sdougm }
2566185db85Sdougm 
257549ec3ffSdougm /*ARGSUSED*/
2586185db85Sdougm static int
259549ec3ffSdougm sc_set(sa_handle_t handle, int flags, int argc, char *argv[])
2606185db85Sdougm {
2616185db85Sdougm 	char *proto = NULL;
2626185db85Sdougm 	struct options *optlist = NULL;
263*4bff34e3Sthurlow 	sa_protocol_properties_t propsect;
2646185db85Sdougm 	int ret = SA_OK;
2656185db85Sdougm 	int c;
266*4bff34e3Sthurlow 	int err;
26725a68471Sdougm 	sa_protocol_properties_t propset;
268*4bff34e3Sthurlow 	sa_property_t prop;
2696185db85Sdougm 
2706185db85Sdougm 	while ((c = getopt(argc, argv, "?hp:")) != EOF) {
2716185db85Sdougm 		switch (c) {
2726185db85Sdougm 		case 'p':
2736185db85Sdougm 			ret = add_opt(&optlist, optarg, 0);
2746185db85Sdougm 			if (ret != SA_OK) {
27525a68471Sdougm 				(void) printf(gettext(
27625a68471Sdougm 				    "Problem with property: %s\n"), optarg);
2776185db85Sdougm 				return (SA_NO_MEMORY);
2786185db85Sdougm 			}
2796185db85Sdougm 			break;
2806185db85Sdougm 		default:
2816185db85Sdougm 			(void) printf(gettext("usage: %s\n"),
2826185db85Sdougm 			    sc_get_usage(USAGE_CTL_SET));
2836185db85Sdougm 			return (SA_SYNTAX_ERR);
2846185db85Sdougm 		case '?':
2856185db85Sdougm 		case 'h':
2866185db85Sdougm 			(void) printf(gettext("usage: %s\n"),
2876185db85Sdougm 			    sc_get_usage(USAGE_CTL_SET));
2886185db85Sdougm 			return (SA_OK);
2896185db85Sdougm 			break;
2906185db85Sdougm 		}
2916185db85Sdougm 	}
2926185db85Sdougm 
2936185db85Sdougm 	if (optind >= argc) {
2946185db85Sdougm 		(void) printf(gettext("usage: %s\n"),
2956185db85Sdougm 		    sc_get_usage(USAGE_CTL_SET));
2966185db85Sdougm 		(void) printf(gettext("\tprotocol must be specified.\n"));
2976185db85Sdougm 		return (SA_INVALID_PROTOCOL);
2986185db85Sdougm 	}
2996185db85Sdougm 
3006185db85Sdougm 	proto = argv[optind];
30125a68471Sdougm 	if (!sa_valid_protocol(proto)) {
30225a68471Sdougm 		(void) printf(gettext("Invalid protocol specified: %s\n"),
30325a68471Sdougm 		    proto);
30425a68471Sdougm 		return (SA_INVALID_PROTOCOL);
30525a68471Sdougm 	}
3066185db85Sdougm 	propset = sa_proto_get_properties(proto);
307*4bff34e3Sthurlow 	if (propset == NULL)
308*4bff34e3Sthurlow 		return (ret);
309*4bff34e3Sthurlow 
3106185db85Sdougm 	if (optlist == NULL) {
3116185db85Sdougm 		(void) printf(gettext("usage: %s\n"),
3126185db85Sdougm 		    sc_get_usage(USAGE_CTL_SET));
31325a68471Sdougm 		(void) printf(gettext(
31425a68471Sdougm 		    "\tat least one property and value "
3156185db85Sdougm 		    "must be specified\n"));
3166185db85Sdougm 	} else {
3176185db85Sdougm 		struct options *opt;
318*4bff34e3Sthurlow 		char *section = NULL;
319*4bff34e3Sthurlow 		/* fetch and change the specified option(s) */
320*4bff34e3Sthurlow 		for (opt = optlist; opt != NULL; opt = opt->next) {
321*4bff34e3Sthurlow 			if (strncmp("section", opt->optname, 7) == 0) {
322*4bff34e3Sthurlow 				if (section != NULL)
323*4bff34e3Sthurlow 					free(section);
324*4bff34e3Sthurlow 				section = strdup(opt->optvalue);
325*4bff34e3Sthurlow 				continue;
326*4bff34e3Sthurlow 			}
327*4bff34e3Sthurlow 			if (sa_proto_get_featureset(proto) &
328*4bff34e3Sthurlow 			    SA_FEATURE_HAS_SECTIONS) {
329*4bff34e3Sthurlow 				propsect = sa_get_protocol_section(propset,
330*4bff34e3Sthurlow 				    section);
331*4bff34e3Sthurlow 				prop = sa_get_protocol_property(propsect,
332*4bff34e3Sthurlow 				    opt->optname);
333*4bff34e3Sthurlow 			} else {
334*4bff34e3Sthurlow 				prop = sa_get_protocol_property(propset,
335*4bff34e3Sthurlow 				    opt->optname);
336*4bff34e3Sthurlow 			}
337*4bff34e3Sthurlow 			if (prop == NULL && sa_proto_get_featureset(proto) &
338*4bff34e3Sthurlow 			    SA_FEATURE_ADD_PROPERTIES) {
339*4bff34e3Sthurlow 				sa_property_t sect;
340*4bff34e3Sthurlow 				sect = sa_create_section(section, NULL);
341*4bff34e3Sthurlow 				sa_set_section_attr(sect, "type", proto);
342*4bff34e3Sthurlow 				(void) sa_add_protocol_property(propset, sect);
343*4bff34e3Sthurlow 				prop = sa_create_property(
344*4bff34e3Sthurlow 				    opt->optname, opt->optvalue);
345*4bff34e3Sthurlow 				(void) sa_add_protocol_property(sect, prop);
346*4bff34e3Sthurlow 			}
3476185db85Sdougm 			if (prop != NULL) {
3483472f5dcSdougm 				/*
349*4bff34e3Sthurlow 				 * "err" is used in order to prevent
350*4bff34e3Sthurlow 				 * setting ret to SA_OK if there has
351*4bff34e3Sthurlow 				 * been a real error. We want to be
352*4bff34e3Sthurlow 				 * able to return an error status on
353*4bff34e3Sthurlow 				 * exit in that case. Error messages
354*4bff34e3Sthurlow 				 * are printed for each error, so we
355*4bff34e3Sthurlow 				 * only care on exit that there was an
356*4bff34e3Sthurlow 				 * error and not the specific error
357*4bff34e3Sthurlow 				 * value.
3583472f5dcSdougm 				 */
359*4bff34e3Sthurlow 				err = sa_set_protocol_property(prop, section,
360*4bff34e3Sthurlow 				    opt->optvalue);
3613472f5dcSdougm 				if (err != SA_OK) {
36225a68471Sdougm 					(void) printf(gettext(
36325a68471Sdougm 					    "Could not set property"
3646185db85Sdougm 					    " %s: %s\n"),
365*4bff34e3Sthurlow 					    opt->optname, sa_errorstr(err));
3663472f5dcSdougm 					ret = err;
3676185db85Sdougm 				}
3686185db85Sdougm 			} else {
369*4bff34e3Sthurlow 				(void) printf(gettext("%s: not defined\n"),
3706185db85Sdougm 				    opt->optname);
3713472f5dcSdougm 				ret = SA_NO_SUCH_PROP;
3726185db85Sdougm 			}
3736185db85Sdougm 		}
3746185db85Sdougm 	}
3756185db85Sdougm 	return (ret);
3766185db85Sdougm }
3776185db85Sdougm 
3786185db85Sdougm static void
3796185db85Sdougm show_status(char *proto)
3806185db85Sdougm {
3816185db85Sdougm 	char *status;
38225a68471Sdougm 
3836185db85Sdougm 	status = sa_get_protocol_status(proto);
3846185db85Sdougm 	(void) printf("%s\t%s\n", proto, status ? gettext(status) : "-");
3856185db85Sdougm 	if (status != NULL)
3866185db85Sdougm 		free(status);
3876185db85Sdougm }
3886185db85Sdougm 
3896185db85Sdougm static int
3906185db85Sdougm valid_proto(char **protos, int num, char *proto)
3916185db85Sdougm {
3926185db85Sdougm 	int i;
3936185db85Sdougm 	for (i = 0; i < num; i++)
3946185db85Sdougm 		if (strcmp(protos[i], proto) == 0)
3956185db85Sdougm 			return (1);
3966185db85Sdougm 	return (0);
3976185db85Sdougm }
3986185db85Sdougm 
399549ec3ffSdougm /*ARGSUSED*/
4006185db85Sdougm static int
401549ec3ffSdougm sc_status(sa_handle_t handle, int flags, int argc, char *argv[])
4026185db85Sdougm {
4036185db85Sdougm 	char **protos;
4046185db85Sdougm 	int ret = SA_OK;
4056185db85Sdougm 	int c;
4066185db85Sdougm 	int i;
4076185db85Sdougm 	int num_proto;
4086185db85Sdougm 	int verbose = 0;
4096185db85Sdougm 
4106185db85Sdougm 	while ((c = getopt(argc, argv, "?hv")) != EOF) {
4116185db85Sdougm 		switch (c) {
4126185db85Sdougm 		case 'v':
4136185db85Sdougm 			verbose++;
4146185db85Sdougm 			break;
4156185db85Sdougm 		case '?':
4166185db85Sdougm 		case 'h':
4176185db85Sdougm 			(void) printf(gettext("usage: %s\n"),
4183472f5dcSdougm 			    sc_get_usage(USAGE_CTL_STATUS));
4196185db85Sdougm 			return (SA_OK);
4206185db85Sdougm 		default:
4216185db85Sdougm 			(void) printf(gettext("usage: %s\n"),
4223472f5dcSdougm 			    sc_get_usage(USAGE_CTL_STATUS));
4236185db85Sdougm 			return (SA_SYNTAX_ERR);
4246185db85Sdougm 		}
4256185db85Sdougm 	}
4266185db85Sdougm 
4276185db85Sdougm 	num_proto = sa_get_protocols(&protos);
4286185db85Sdougm 	if (optind == argc) {
4296185db85Sdougm 		/* status for all protocols */
4306185db85Sdougm 		for (i = 0; i < num_proto; i++) {
4316185db85Sdougm 			show_status(protos[i]);
4326185db85Sdougm 		}
4336185db85Sdougm 	} else {
4346185db85Sdougm 		for (i = optind; i < argc; i++) {
4356185db85Sdougm 			if (valid_proto(protos, num_proto, argv[i])) {
4366185db85Sdougm 				show_status(argv[i]);
4376185db85Sdougm 			} else {
43825a68471Sdougm 				(void) printf(gettext("Invalid protocol: %s\n"),
43925a68471Sdougm 				    argv[i]);
4406185db85Sdougm 				ret = SA_INVALID_PROTOCOL;
4416185db85Sdougm 			}
4426185db85Sdougm 		}
4436185db85Sdougm 	}
4446185db85Sdougm 	if (protos != NULL)
4456185db85Sdougm 		free(protos);
4466185db85Sdougm 	return (ret);
4476185db85Sdougm }
4486185db85Sdougm 
449*4bff34e3Sthurlow /*ARGSUSED*/
450*4bff34e3Sthurlow static int
451*4bff34e3Sthurlow sc_delsect(sa_handle_t handle, int flags, int argc, char *argv[])
452*4bff34e3Sthurlow {
453*4bff34e3Sthurlow 	char *proto = NULL;
454*4bff34e3Sthurlow 	char *section = NULL;
455*4bff34e3Sthurlow 	sa_protocol_properties_t propset;
456*4bff34e3Sthurlow 	sa_protocol_properties_t propsect;
457*4bff34e3Sthurlow 	int ret = SA_OK;
458*4bff34e3Sthurlow 	int c;
459*4bff34e3Sthurlow 
460*4bff34e3Sthurlow 	while ((c = getopt(argc, argv, "?h")) != EOF) {
461*4bff34e3Sthurlow 		switch (c) {
462*4bff34e3Sthurlow 		default:
463*4bff34e3Sthurlow 			ret = SA_SYNTAX_ERR;
464*4bff34e3Sthurlow 			/*FALLTHROUGH*/
465*4bff34e3Sthurlow 		case '?':
466*4bff34e3Sthurlow 		case 'h':
467*4bff34e3Sthurlow 			(void) printf(gettext("usage: %s\n"),
468*4bff34e3Sthurlow 			    sc_get_usage(USAGE_CTL_DELSECT));
469*4bff34e3Sthurlow 			return (ret);
470*4bff34e3Sthurlow 		}
471*4bff34e3Sthurlow 		/*NOTREACHED*/
472*4bff34e3Sthurlow 	}
473*4bff34e3Sthurlow 
474*4bff34e3Sthurlow 	section = argv[optind++];
475*4bff34e3Sthurlow 
476*4bff34e3Sthurlow 	if (optind >= argc) {
477*4bff34e3Sthurlow 		(void) printf(gettext("usage: %s\n"),
478*4bff34e3Sthurlow 		    sc_get_usage(USAGE_CTL_DELSECT));
479*4bff34e3Sthurlow 		(void) printf(gettext(
480*4bff34e3Sthurlow 		    "\tsection and protocol must be specified.\n"));
481*4bff34e3Sthurlow 		return (SA_INVALID_PROTOCOL);
482*4bff34e3Sthurlow 	}
483*4bff34e3Sthurlow 
484*4bff34e3Sthurlow 	proto = argv[optind];
485*4bff34e3Sthurlow 	if (!sa_valid_protocol(proto)) {
486*4bff34e3Sthurlow 		(void) printf(gettext("Invalid protocol specified: %s\n"),
487*4bff34e3Sthurlow 		    proto);
488*4bff34e3Sthurlow 		return (SA_INVALID_PROTOCOL);
489*4bff34e3Sthurlow 	}
490*4bff34e3Sthurlow 
491*4bff34e3Sthurlow 	if ((sa_proto_get_featureset(proto) & SA_FEATURE_HAS_SECTIONS) == 0) {
492*4bff34e3Sthurlow 		(void) printf(gettext("Protocol %s does not have sections\n"),
493*4bff34e3Sthurlow 		    section, proto);
494*4bff34e3Sthurlow 		return (SA_NOT_SUPPORTED);
495*4bff34e3Sthurlow 	}
496*4bff34e3Sthurlow 
497*4bff34e3Sthurlow 	propset = sa_proto_get_properties(proto);
498*4bff34e3Sthurlow 	if (propset == NULL) {
499*4bff34e3Sthurlow 		(void) printf(gettext("Cannot get properties for %s\n"),
500*4bff34e3Sthurlow 		    proto);
501*4bff34e3Sthurlow 		return (SA_NO_PROPERTIES);
502*4bff34e3Sthurlow 	}
503*4bff34e3Sthurlow 
504*4bff34e3Sthurlow 	propsect = sa_get_protocol_section(propset, section);
505*4bff34e3Sthurlow 	if (propsect == NULL) {
506*4bff34e3Sthurlow 		(void) printf(gettext("Cannot find section %s for proto %s\n"),
507*4bff34e3Sthurlow 		    section, proto);
508*4bff34e3Sthurlow 		return (SA_NO_SUCH_SECTION);
509*4bff34e3Sthurlow 	}
510*4bff34e3Sthurlow 
511*4bff34e3Sthurlow 	ret = sa_proto_delete_section(proto, section);
512*4bff34e3Sthurlow 
513*4bff34e3Sthurlow 	return (ret);
514*4bff34e3Sthurlow }
515*4bff34e3Sthurlow 
5166185db85Sdougm static sa_command_t commands[] = {
5176185db85Sdougm 	{"get", 0, sc_get, USAGE_CTL_GET},
5186185db85Sdougm 	{"set", 0, sc_set, USAGE_CTL_SET},
5196185db85Sdougm 	{"status", 0, sc_status, USAGE_CTL_STATUS},
520*4bff34e3Sthurlow 	{"delsect", 0, sc_delsect, USAGE_CTL_DELSECT},
5216185db85Sdougm 	{NULL, 0, NULL, 0},
5226185db85Sdougm };
5236185db85Sdougm 
524549ec3ffSdougm /*ARGSUSED*/
5256185db85Sdougm void
5266185db85Sdougm sub_command_help(char *proto)
5276185db85Sdougm {
5286185db85Sdougm 	int i;
5296185db85Sdougm 
5306185db85Sdougm 	(void) printf("\tsub-commands:\n");
5316185db85Sdougm 	for (i = 0; commands[i].cmdname != NULL; i++) {
5326185db85Sdougm 		if (!(commands[i].flags & (CMD_ALIAS|CMD_NODISPLAY)))
5336185db85Sdougm 			(void) printf("\t%s\n",
5346185db85Sdougm 			    sc_get_usage((sc_usage_t)commands[i].cmdidx));
5356185db85Sdougm 	}
5366185db85Sdougm }
5376185db85Sdougm 
5386185db85Sdougm sa_command_t *
5396185db85Sdougm sa_lookup(char *cmd)
5406185db85Sdougm {
5416185db85Sdougm 	int i;
5426185db85Sdougm 	size_t len;
5436185db85Sdougm 
5446185db85Sdougm 	len = strlen(cmd);
5456185db85Sdougm 	for (i = 0; commands[i].cmdname != NULL; i++) {
5466185db85Sdougm 		if (strncmp(cmd, commands[i].cmdname, len) == 0)
5476185db85Sdougm 			return (&commands[i]);
5486185db85Sdougm 	}
5496185db85Sdougm 	return (NULL);
5506185db85Sdougm }
5516185db85Sdougm 
5526185db85Sdougm static int
553549ec3ffSdougm run_command(char *command, int argc, char *argv[], sa_handle_t handle)
5546185db85Sdougm {
5556185db85Sdougm 	sa_command_t *cmdvec;
5566185db85Sdougm 	int ret;
5576185db85Sdougm 
5586185db85Sdougm 	/*
5596185db85Sdougm 	 * To get here, we know there should be a command due to the
5606185db85Sdougm 	 * preprocessing done earlier.  Need to find the protocol
5616185db85Sdougm 	 * that is being affected. If no protocol, then it is ALL
5626185db85Sdougm 	 * protocols.
5636185db85Sdougm 	 *
5646185db85Sdougm 	 * ??? do we really need the protocol at this level? it may be
5656185db85Sdougm 	 * sufficient to let the commands look it up if needed since
5666185db85Sdougm 	 * not all commands do proto specific things
5676185db85Sdougm 	 *
5686185db85Sdougm 	 * Known sub-commands are handled at this level. An unknown
5696185db85Sdougm 	 * command will be passed down to the shared object that
5706185db85Sdougm 	 * actually implements it. We can do this since the semantics
5716185db85Sdougm 	 * of the common sub-commands is well defined.
5726185db85Sdougm 	 */
5736185db85Sdougm 
5746185db85Sdougm 	cmdvec = sa_lookup(command);
5756185db85Sdougm 	if (cmdvec == NULL) {
5766185db85Sdougm 		(void) printf(gettext("command %s not found\n"), command);
5776185db85Sdougm 		exit(1);
5786185db85Sdougm 	}
5796185db85Sdougm 	/*
5806185db85Sdougm 	 * need to check priviledges and restrict what can be done
5816185db85Sdougm 	 * based on least priviledge and sub-command.
5826185db85Sdougm 	 */
583549ec3ffSdougm 	ret = cmdvec->cmdfunc(handle, NULL, argc, argv);
5846185db85Sdougm 	return (ret);
5856185db85Sdougm }
586