xref: /onnv-gate/usr/src/cmd/dfs.cmds/sharectl/sharectl.c (revision 6007:d57e38e8fdd1)
13034Sdougm /*
23034Sdougm  * CDDL HEADER START
33034Sdougm  *
43034Sdougm  * The contents of this file are subject to the terms of the
53034Sdougm  * Common Development and Distribution License (the "License").
63034Sdougm  * You may not use this file except in compliance with the License.
73034Sdougm  *
83034Sdougm  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
93034Sdougm  * or http://www.opensolaris.org/os/licensing.
103034Sdougm  * See the License for the specific language governing permissions
113034Sdougm  * and limitations under the License.
123034Sdougm  *
133034Sdougm  * When distributing Covered Code, include this CDDL HEADER in each
143034Sdougm  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
153034Sdougm  * If applicable, add the following below this CDDL HEADER, with the
163034Sdougm  * fields enclosed by brackets "[]" replaced with your own identifying
173034Sdougm  * information: Portions Copyright [yyyy] [name of copyright owner]
183034Sdougm  *
193034Sdougm  * CDDL HEADER END
203034Sdougm  */
213034Sdougm 
223034Sdougm /*
23*6007Sthurlow  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
243034Sdougm  * Use is subject to license terms.
253034Sdougm  */
263034Sdougm 
273034Sdougm #pragma ident	"%Z%%M%	%I%	%E% SMI"
283034Sdougm 
293034Sdougm #include <stdlib.h>
303034Sdougm #include <stdio.h>
313034Sdougm #include <string.h>
323034Sdougm #include <ctype.h>
333034Sdougm #include <unistd.h>
343034Sdougm #include <getopt.h>
353034Sdougm #include <libgen.h>
363034Sdougm 
373034Sdougm #include "libshare.h"
383034Sdougm #include <sharemgr.h>
393034Sdougm 
403034Sdougm #include <libintl.h>
413034Sdougm #include <locale.h>
423034Sdougm 
433910Sdougm static int run_command(char *, int, char **, sa_handle_t);
443034Sdougm static void sub_command_help(char *proto);
453034Sdougm 
463034Sdougm static void
473034Sdougm global_help()
483034Sdougm {
493034Sdougm 	(void) printf(gettext("usage: sharectl <command> [options]\n"));
503034Sdougm 	sub_command_help(NULL);
513034Sdougm }
523034Sdougm 
533034Sdougm int
543034Sdougm main(int argc, char *argv[])
553034Sdougm {
563034Sdougm 	int c;
573034Sdougm 	int help = 0;
583034Sdougm 	int rval;
593034Sdougm 	char *command;
603910Sdougm 	sa_handle_t handle;
613034Sdougm 
623034Sdougm 	/*
633034Sdougm 	 * make sure locale and gettext domain is setup
643034Sdougm 	 */
653034Sdougm 	(void) setlocale(LC_ALL, "");
663034Sdougm 	(void) textdomain(TEXT_DOMAIN);
673034Sdougm 
683910Sdougm 	handle = sa_init(SA_INIT_CONTROL_API);
693034Sdougm 
703034Sdougm 	while ((c = getopt(argc, argv, "h?")) != EOF) {
714653Sdougm 		switch (c) {
724653Sdougm 		case '?':
734653Sdougm 		case 'h':
744653Sdougm 			help = 1;
754653Sdougm 			break;
764653Sdougm 		default:
774653Sdougm 			(void) printf(gettext("Invalid option: %c\n"), c);
784653Sdougm 		}
793034Sdougm 	}
803034Sdougm 	if (optind == argc || help) {
814653Sdougm 		/* no subcommand */
824653Sdougm 		global_help();
834653Sdougm 		exit(0);
843034Sdougm 	}
853034Sdougm 	optind = 1;
863034Sdougm 
873034Sdougm 	/*
883034Sdougm 	 * now have enough to parse rest of command line
893034Sdougm 	 */
903034Sdougm 	command = argv[optind];
913910Sdougm 	rval = run_command(command, argc - optind, argv + optind, handle);
923034Sdougm 
933910Sdougm 	sa_fini(handle);
943034Sdougm 	return (rval);
953034Sdougm }
963034Sdougm 
973034Sdougm char *
983034Sdougm sc_get_usage(sc_usage_t index)
993034Sdougm {
1003034Sdougm 	char *ret = NULL;
1013034Sdougm 
1023034Sdougm 	switch (index) {
1033034Sdougm 	case USAGE_CTL_GET:
1044653Sdougm 		ret = gettext("get [-h | -p property ...] proto");
1054653Sdougm 		break;
1063034Sdougm 	case USAGE_CTL_SET:
1074653Sdougm 		ret = gettext("set [-h] -p property=value ... proto");
1084653Sdougm 		break;
1093034Sdougm 	case USAGE_CTL_STATUS:
1104653Sdougm 		ret = gettext("status [-h | proto ...]");
1114653Sdougm 		break;
112*6007Sthurlow 	case USAGE_CTL_DELSECT:
113*6007Sthurlow 		ret = gettext("delsect [-h] section proto");
114*6007Sthurlow 		break;
1153034Sdougm 	}
1163034Sdougm 	return (ret);
1173034Sdougm }
1183034Sdougm 
1193910Sdougm /*ARGSUSED*/
1203034Sdougm static int
1213910Sdougm sc_get(sa_handle_t handle, int flags, int argc, char *argv[])
1223034Sdougm {
1233034Sdougm 	char *proto = NULL;
1243034Sdougm 	struct options *optlist = NULL;
1253034Sdougm 	int ret = SA_OK;
1263034Sdougm 	int c;
127*6007Sthurlow 	sa_protocol_properties_t propset, propsect;
128*6007Sthurlow 	sa_property_t prop;
129*6007Sthurlow 	char *section, *value, *name;
130*6007Sthurlow 	int first = 1;
1313034Sdougm 
1323034Sdougm 	while ((c = getopt(argc, argv, "?hp:")) != EOF) {
1334653Sdougm 		switch (c) {
1344653Sdougm 		case 'p':
1354653Sdougm 			ret = add_opt(&optlist, optarg, 1);
1364653Sdougm 			if (ret != SA_OK) {
1374653Sdougm 				(void) printf(gettext(
1384653Sdougm 				    "Problem with property: %s\n"), optarg);
1394653Sdougm 				return (SA_NO_MEMORY);
1404653Sdougm 			}
1414653Sdougm 			break;
1424653Sdougm 		default:
1434653Sdougm 			(void) printf(gettext("usage: %s\n"),
1444653Sdougm 			    sc_get_usage(USAGE_CTL_GET));
1454653Sdougm 			return (SA_SYNTAX_ERR);
1464653Sdougm 		case '?':
1474653Sdougm 		case 'h':
1484653Sdougm 			(void) printf(gettext("usage: %s\n"),
1494653Sdougm 			    sc_get_usage(USAGE_CTL_GET));
1504653Sdougm 			return (SA_OK);
1514653Sdougm 			break;
1523034Sdougm 		}
1533034Sdougm 	}
1543034Sdougm 
1553034Sdougm 	if (optind >= argc) {
1564653Sdougm 		(void) printf(gettext("usage: %s\n"),
1574653Sdougm 		    sc_get_usage(USAGE_CTL_GET));
1584653Sdougm 		(void) printf(gettext("\tprotocol must be specified.\n"));
1594653Sdougm 		return (SA_INVALID_PROTOCOL);
1603034Sdougm 	}
1613034Sdougm 
1623034Sdougm 	proto = argv[optind];
163*6007Sthurlow 	if (!sa_valid_protocol(proto)) {
164*6007Sthurlow 		(void) printf(gettext("Invalid protocol specified: %s\n"),
165*6007Sthurlow 		    proto);
166*6007Sthurlow 		return (SA_INVALID_PROTOCOL);
167*6007Sthurlow 	}
168*6007Sthurlow 	propset = sa_proto_get_properties(proto);
169*6007Sthurlow 	if (propset == NULL)
170*6007Sthurlow 		return (ret);
1713034Sdougm 
172*6007Sthurlow 	if (optlist == NULL) {
173*6007Sthurlow 		/* Display all known properties for this protocol */
174*6007Sthurlow 		for (propsect = sa_get_protocol_section(propset, NULL);
175*6007Sthurlow 		    propsect != NULL;
176*6007Sthurlow 		    propsect = sa_get_next_protocol_section(propsect, NULL)) {
177*6007Sthurlow 			section = sa_get_property_attr(propsect,
178*6007Sthurlow 			    "name");
179*6007Sthurlow 			/*
180*6007Sthurlow 			 * If properties are organized into sections, as
181*6007Sthurlow 			 * in the SMB client, print the section name.
182*6007Sthurlow 			 */
183*6007Sthurlow 			if (sa_proto_get_featureset(proto) &
184*6007Sthurlow 			    SA_FEATURE_HAS_SECTIONS) {
185*6007Sthurlow 				if (!first)
186*6007Sthurlow 					(void) printf("\n");
187*6007Sthurlow 				first = 0;
188*6007Sthurlow 				(void) printf("[%s]\n", section);
189*6007Sthurlow 			}
190*6007Sthurlow 			/* Display properties for this section */
191*6007Sthurlow 			for (prop = sa_get_protocol_property(propsect, NULL);
192*6007Sthurlow 			    prop != NULL;
193*6007Sthurlow 			    prop = sa_get_next_protocol_property(prop, NULL)) {
194*6007Sthurlow 
195*6007Sthurlow 				/* get and display the property and value */
196*6007Sthurlow 				name = sa_get_property_attr(prop, "type");
197*6007Sthurlow 				if (name != NULL) {
198*6007Sthurlow 					value = sa_get_property_attr(prop,
199*6007Sthurlow 					    "value");
200*6007Sthurlow 					(void) printf(gettext("%s=%s\n"), name,
201*6007Sthurlow 					    value != NULL ? value : "");
2024653Sdougm 				}
203*6007Sthurlow 				if (value != NULL)
204*6007Sthurlow 					sa_free_attr_string(value);
205*6007Sthurlow 				if (name != NULL)
206*6007Sthurlow 					sa_free_attr_string(name);
2073034Sdougm 			}
2083034Sdougm 		}
2093034Sdougm 	} else {
210*6007Sthurlow 		struct options *opt;
211*6007Sthurlow 
212*6007Sthurlow 		/* list the specified option(s) */
213*6007Sthurlow 		for (opt = optlist; opt != NULL; opt = opt->next) {
214*6007Sthurlow 			int printed = 0;
215*6007Sthurlow 
216*6007Sthurlow 			for (propsect = sa_get_protocol_section(propset, NULL);
217*6007Sthurlow 			    propsect != NULL;
218*6007Sthurlow 			    propsect = sa_get_next_protocol_section(propsect,
219*6007Sthurlow 			    NULL)) {
220*6007Sthurlow 
221*6007Sthurlow 				section = sa_get_property_attr(propsect,
222*6007Sthurlow 				    "name");
223*6007Sthurlow 				for (prop = sa_get_protocol_property(propsect,
224*6007Sthurlow 				    opt->optname);
225*6007Sthurlow 				    prop != NULL;
226*6007Sthurlow 				    prop = sa_get_next_protocol_property(
227*6007Sthurlow 				    propsect, opt->optname)) {
228*6007Sthurlow 					value = sa_get_property_attr(prop,
229*6007Sthurlow 					    "value");
230*6007Sthurlow 					if (sa_proto_get_featureset(proto) &
231*6007Sthurlow 					    SA_FEATURE_HAS_SECTIONS) {
232*6007Sthurlow 						(void) printf(
233*6007Sthurlow 						    gettext("[%s] %s=%s\n"),
234*6007Sthurlow 						    section, opt->optname,
235*6007Sthurlow 						    value != NULL ? value : "");
236*6007Sthurlow 						sa_free_attr_string(section);
237*6007Sthurlow 					} else {
238*6007Sthurlow 						(void) printf(
239*6007Sthurlow 						    gettext("%s=%s\n"),
240*6007Sthurlow 						    opt->optname,
241*6007Sthurlow 						    value != NULL ? value : "");
242*6007Sthurlow 					}
243*6007Sthurlow 					sa_free_attr_string(value);
244*6007Sthurlow 					printed = 1;
245*6007Sthurlow 				}
246*6007Sthurlow 			}
247*6007Sthurlow 			if (!printed) {
248*6007Sthurlow 				(void) printf(gettext("%s: not defined\n"),
249*6007Sthurlow 				    opt->optname);
250*6007Sthurlow 				ret = SA_NO_SUCH_PROP;
251*6007Sthurlow 			}
252*6007Sthurlow 		}
2533034Sdougm 	}
2543034Sdougm 	return (ret);
2553034Sdougm }
2563034Sdougm 
2573910Sdougm /*ARGSUSED*/
2583034Sdougm static int
2593910Sdougm sc_set(sa_handle_t handle, int flags, int argc, char *argv[])
2603034Sdougm {
2613034Sdougm 	char *proto = NULL;
2623034Sdougm 	struct options *optlist = NULL;
263*6007Sthurlow 	sa_protocol_properties_t propsect;
2643034Sdougm 	int ret = SA_OK;
2653034Sdougm 	int c;
266*6007Sthurlow 	int err;
2674653Sdougm 	sa_protocol_properties_t propset;
268*6007Sthurlow 	sa_property_t prop;
2693034Sdougm 
2703034Sdougm 	while ((c = getopt(argc, argv, "?hp:")) != EOF) {
2714653Sdougm 		switch (c) {
2724653Sdougm 		case 'p':
2734653Sdougm 			ret = add_opt(&optlist, optarg, 0);
2744653Sdougm 			if (ret != SA_OK) {
2754653Sdougm 				(void) printf(gettext(
2764653Sdougm 				    "Problem with property: %s\n"), optarg);
2774653Sdougm 				return (SA_NO_MEMORY);
2784653Sdougm 			}
2794653Sdougm 			break;
2804653Sdougm 		default:
2814653Sdougm 			(void) printf(gettext("usage: %s\n"),
2824653Sdougm 			    sc_get_usage(USAGE_CTL_SET));
2834653Sdougm 			return (SA_SYNTAX_ERR);
2844653Sdougm 		case '?':
2854653Sdougm 		case 'h':
2864653Sdougm 			(void) printf(gettext("usage: %s\n"),
2874653Sdougm 			    sc_get_usage(USAGE_CTL_SET));
2884653Sdougm 			return (SA_OK);
2894653Sdougm 			break;
2903034Sdougm 		}
2913034Sdougm 	}
2923034Sdougm 
2933034Sdougm 	if (optind >= argc) {
2944653Sdougm 		(void) printf(gettext("usage: %s\n"),
2954653Sdougm 		    sc_get_usage(USAGE_CTL_SET));
2964653Sdougm 		(void) printf(gettext("\tprotocol must be specified.\n"));
2974653Sdougm 		return (SA_INVALID_PROTOCOL);
2983034Sdougm 	}
2993034Sdougm 
3003034Sdougm 	proto = argv[optind];
3014653Sdougm 	if (!sa_valid_protocol(proto)) {
3024653Sdougm 		(void) printf(gettext("Invalid protocol specified: %s\n"),
3034653Sdougm 		    proto);
3044653Sdougm 		return (SA_INVALID_PROTOCOL);
3054653Sdougm 	}
3064653Sdougm 	propset = sa_proto_get_properties(proto);
307*6007Sthurlow 	if (propset == NULL)
308*6007Sthurlow 		return (ret);
309*6007Sthurlow 
310*6007Sthurlow 	if (optlist == NULL) {
311*6007Sthurlow 		(void) printf(gettext("usage: %s\n"),
312*6007Sthurlow 		    sc_get_usage(USAGE_CTL_SET));
313*6007Sthurlow 		(void) printf(gettext(
314*6007Sthurlow 		    "\tat least one property and value "
315*6007Sthurlow 		    "must be specified\n"));
316*6007Sthurlow 	} else {
317*6007Sthurlow 		struct options *opt;
318*6007Sthurlow 		char *section = NULL;
319*6007Sthurlow 		/* fetch and change the specified option(s) */
320*6007Sthurlow 		for (opt = optlist; opt != NULL; opt = opt->next) {
321*6007Sthurlow 			if (strncmp("section", opt->optname, 7) == 0) {
322*6007Sthurlow 				if (section != NULL)
323*6007Sthurlow 					free(section);
324*6007Sthurlow 				section = strdup(opt->optvalue);
325*6007Sthurlow 				continue;
326*6007Sthurlow 			}
327*6007Sthurlow 			if (sa_proto_get_featureset(proto) &
328*6007Sthurlow 			    SA_FEATURE_HAS_SECTIONS) {
329*6007Sthurlow 				propsect = sa_get_protocol_section(propset,
330*6007Sthurlow 				    section);
331*6007Sthurlow 				prop = sa_get_protocol_property(propsect,
332*6007Sthurlow 				    opt->optname);
333*6007Sthurlow 			} else {
334*6007Sthurlow 				prop = sa_get_protocol_property(propset,
335*6007Sthurlow 				    opt->optname);
336*6007Sthurlow 			}
337*6007Sthurlow 			if (prop == NULL && sa_proto_get_featureset(proto) &
338*6007Sthurlow 			    SA_FEATURE_ADD_PROPERTIES) {
339*6007Sthurlow 				sa_property_t sect;
340*6007Sthurlow 				sect = sa_create_section(section, NULL);
341*6007Sthurlow 				sa_set_section_attr(sect, "type", proto);
342*6007Sthurlow 				(void) sa_add_protocol_property(propset, sect);
343*6007Sthurlow 				prop = sa_create_property(
344*6007Sthurlow 				    opt->optname, opt->optvalue);
345*6007Sthurlow 				(void) sa_add_protocol_property(sect, prop);
346*6007Sthurlow 			}
347*6007Sthurlow 			if (prop != NULL) {
348*6007Sthurlow 				/*
349*6007Sthurlow 				 * "err" is used in order to prevent
350*6007Sthurlow 				 * setting ret to SA_OK if there has
351*6007Sthurlow 				 * been a real error. We want to be
352*6007Sthurlow 				 * able to return an error status on
353*6007Sthurlow 				 * exit in that case. Error messages
354*6007Sthurlow 				 * are printed for each error, so we
355*6007Sthurlow 				 * only care on exit that there was an
356*6007Sthurlow 				 * error and not the specific error
357*6007Sthurlow 				 * value.
358*6007Sthurlow 				 */
359*6007Sthurlow 				err = sa_set_protocol_property(prop, section,
360*6007Sthurlow 				    opt->optvalue);
361*6007Sthurlow 				if (err != SA_OK) {
3624653Sdougm 					(void) printf(gettext(
363*6007Sthurlow 					    "Could not set property"
364*6007Sthurlow 					    " %s: %s\n"),
365*6007Sthurlow 					    opt->optname, sa_errorstr(err));
366*6007Sthurlow 					ret = err;
3674653Sdougm 				}
368*6007Sthurlow 			} else {
369*6007Sthurlow 				(void) printf(gettext("%s: not defined\n"),
370*6007Sthurlow 				    opt->optname);
371*6007Sthurlow 				ret = SA_NO_SUCH_PROP;
3723034Sdougm 			}
3733034Sdougm 		}
3743034Sdougm 	}
3753034Sdougm 	return (ret);
3763034Sdougm }
3773034Sdougm 
3783034Sdougm static void
3793034Sdougm show_status(char *proto)
3803034Sdougm {
3813034Sdougm 	char *status;
3824653Sdougm 
3833034Sdougm 	status = sa_get_protocol_status(proto);
3843034Sdougm 	(void) printf("%s\t%s\n", proto, status ? gettext(status) : "-");
3853034Sdougm 	if (status != NULL)
3864653Sdougm 		free(status);
3873034Sdougm }
3883034Sdougm 
3893034Sdougm static int
3903034Sdougm valid_proto(char **protos, int num, char *proto)
3913034Sdougm {
3923034Sdougm 	int i;
3933034Sdougm 	for (i = 0; i < num; i++)
3944653Sdougm 		if (strcmp(protos[i], proto) == 0)
3954653Sdougm 			return (1);
3963034Sdougm 	return (0);
3973034Sdougm }
3983034Sdougm 
3993910Sdougm /*ARGSUSED*/
4003034Sdougm static int
4013910Sdougm sc_status(sa_handle_t handle, int flags, int argc, char *argv[])
4023034Sdougm {
4033034Sdougm 	char **protos;
4043034Sdougm 	int ret = SA_OK;
4053034Sdougm 	int c;
4063034Sdougm 	int i;
4073034Sdougm 	int num_proto;
4083034Sdougm 	int verbose = 0;
4093034Sdougm 
4103034Sdougm 	while ((c = getopt(argc, argv, "?hv")) != EOF) {
4114653Sdougm 		switch (c) {
4124653Sdougm 		case 'v':
4134653Sdougm 			verbose++;
4144653Sdougm 			break;
4154653Sdougm 		case '?':
4164653Sdougm 		case 'h':
4174653Sdougm 			(void) printf(gettext("usage: %s\n"),
4184653Sdougm 			    sc_get_usage(USAGE_CTL_STATUS));
4194653Sdougm 			return (SA_OK);
4204653Sdougm 		default:
4214653Sdougm 			(void) printf(gettext("usage: %s\n"),
4224653Sdougm 			    sc_get_usage(USAGE_CTL_STATUS));
4234653Sdougm 			return (SA_SYNTAX_ERR);
4244653Sdougm 		}
4253034Sdougm 	}
4263034Sdougm 
4273034Sdougm 	num_proto = sa_get_protocols(&protos);
4283034Sdougm 	if (optind == argc) {
4294653Sdougm 		/* status for all protocols */
4304653Sdougm 		for (i = 0; i < num_proto; i++) {
4314653Sdougm 			show_status(protos[i]);
4324653Sdougm 		}
4333034Sdougm 	} else {
4344653Sdougm 		for (i = optind; i < argc; i++) {
4354653Sdougm 			if (valid_proto(protos, num_proto, argv[i])) {
4364653Sdougm 				show_status(argv[i]);
4374653Sdougm 			} else {
4384653Sdougm 				(void) printf(gettext("Invalid protocol: %s\n"),
4394653Sdougm 				    argv[i]);
4404653Sdougm 				ret = SA_INVALID_PROTOCOL;
4414653Sdougm 			}
4423034Sdougm 		}
4433034Sdougm 	}
4443034Sdougm 	if (protos != NULL)
4454653Sdougm 		free(protos);
4463034Sdougm 	return (ret);
4473034Sdougm }
4483034Sdougm 
449*6007Sthurlow /*ARGSUSED*/
450*6007Sthurlow static int
451*6007Sthurlow sc_delsect(sa_handle_t handle, int flags, int argc, char *argv[])
452*6007Sthurlow {
453*6007Sthurlow 	char *proto = NULL;
454*6007Sthurlow 	char *section = NULL;
455*6007Sthurlow 	sa_protocol_properties_t propset;
456*6007Sthurlow 	sa_protocol_properties_t propsect;
457*6007Sthurlow 	int ret = SA_OK;
458*6007Sthurlow 	int c;
459*6007Sthurlow 
460*6007Sthurlow 	while ((c = getopt(argc, argv, "?h")) != EOF) {
461*6007Sthurlow 		switch (c) {
462*6007Sthurlow 		default:
463*6007Sthurlow 			ret = SA_SYNTAX_ERR;
464*6007Sthurlow 			/*FALLTHROUGH*/
465*6007Sthurlow 		case '?':
466*6007Sthurlow 		case 'h':
467*6007Sthurlow 			(void) printf(gettext("usage: %s\n"),
468*6007Sthurlow 			    sc_get_usage(USAGE_CTL_DELSECT));
469*6007Sthurlow 			return (ret);
470*6007Sthurlow 		}
471*6007Sthurlow 		/*NOTREACHED*/
472*6007Sthurlow 	}
473*6007Sthurlow 
474*6007Sthurlow 	section = argv[optind++];
475*6007Sthurlow 
476*6007Sthurlow 	if (optind >= argc) {
477*6007Sthurlow 		(void) printf(gettext("usage: %s\n"),
478*6007Sthurlow 		    sc_get_usage(USAGE_CTL_DELSECT));
479*6007Sthurlow 		(void) printf(gettext(
480*6007Sthurlow 		    "\tsection and protocol must be specified.\n"));
481*6007Sthurlow 		return (SA_INVALID_PROTOCOL);
482*6007Sthurlow 	}
483*6007Sthurlow 
484*6007Sthurlow 	proto = argv[optind];
485*6007Sthurlow 	if (!sa_valid_protocol(proto)) {
486*6007Sthurlow 		(void) printf(gettext("Invalid protocol specified: %s\n"),
487*6007Sthurlow 		    proto);
488*6007Sthurlow 		return (SA_INVALID_PROTOCOL);
489*6007Sthurlow 	}
490*6007Sthurlow 
491*6007Sthurlow 	if ((sa_proto_get_featureset(proto) & SA_FEATURE_HAS_SECTIONS) == 0) {
492*6007Sthurlow 		(void) printf(gettext("Protocol %s does not have sections\n"),
493*6007Sthurlow 		    section, proto);
494*6007Sthurlow 		return (SA_NOT_SUPPORTED);
495*6007Sthurlow 	}
496*6007Sthurlow 
497*6007Sthurlow 	propset = sa_proto_get_properties(proto);
498*6007Sthurlow 	if (propset == NULL) {
499*6007Sthurlow 		(void) printf(gettext("Cannot get properties for %s\n"),
500*6007Sthurlow 		    proto);
501*6007Sthurlow 		return (SA_NO_PROPERTIES);
502*6007Sthurlow 	}
503*6007Sthurlow 
504*6007Sthurlow 	propsect = sa_get_protocol_section(propset, section);
505*6007Sthurlow 	if (propsect == NULL) {
506*6007Sthurlow 		(void) printf(gettext("Cannot find section %s for proto %s\n"),
507*6007Sthurlow 		    section, proto);
508*6007Sthurlow 		return (SA_NO_SUCH_SECTION);
509*6007Sthurlow 	}
510*6007Sthurlow 
511*6007Sthurlow 	ret = sa_proto_delete_section(proto, section);
512*6007Sthurlow 
513*6007Sthurlow 	return (ret);
514*6007Sthurlow }
515*6007Sthurlow 
5163034Sdougm static sa_command_t commands[] = {
5173034Sdougm 	{"get", 0, sc_get, USAGE_CTL_GET},
5183034Sdougm 	{"set", 0, sc_set, USAGE_CTL_SET},
5193034Sdougm 	{"status", 0, sc_status, USAGE_CTL_STATUS},
520*6007Sthurlow 	{"delsect", 0, sc_delsect, USAGE_CTL_DELSECT},
5213034Sdougm 	{NULL, 0, NULL, 0},
5223034Sdougm };
5233034Sdougm 
5243910Sdougm /*ARGSUSED*/
5253034Sdougm void
5263034Sdougm sub_command_help(char *proto)
5273034Sdougm {
5283034Sdougm 	int i;
5293034Sdougm 
5303034Sdougm 	(void) printf("\tsub-commands:\n");
5313034Sdougm 	for (i = 0; commands[i].cmdname != NULL; i++) {
5323034Sdougm 		if (!(commands[i].flags & (CMD_ALIAS|CMD_NODISPLAY)))
5333034Sdougm 			(void) printf("\t%s\n",
5344653Sdougm 			    sc_get_usage((sc_usage_t)commands[i].cmdidx));
5353034Sdougm 	}
5363034Sdougm }
5373034Sdougm 
5383034Sdougm sa_command_t *
5393034Sdougm sa_lookup(char *cmd)
5403034Sdougm {
5413034Sdougm 	int i;
5423034Sdougm 	size_t len;
5433034Sdougm 
5443034Sdougm 	len = strlen(cmd);
5453034Sdougm 	for (i = 0; commands[i].cmdname != NULL; i++) {
5463034Sdougm 		if (strncmp(cmd, commands[i].cmdname, len) == 0)
5473034Sdougm 			return (&commands[i]);
5483034Sdougm 	}
5493034Sdougm 	return (NULL);
5503034Sdougm }
5513034Sdougm 
5523034Sdougm static int
5533910Sdougm run_command(char *command, int argc, char *argv[], sa_handle_t handle)
5543034Sdougm {
5553034Sdougm 	sa_command_t *cmdvec;
5563034Sdougm 	int ret;
5573034Sdougm 
5583034Sdougm 	/*
5593034Sdougm 	 * To get here, we know there should be a command due to the
5603034Sdougm 	 * preprocessing done earlier.  Need to find the protocol
5613034Sdougm 	 * that is being affected. If no protocol, then it is ALL
5623034Sdougm 	 * protocols.
5633034Sdougm 	 *
5643034Sdougm 	 * ??? do we really need the protocol at this level? it may be
5653034Sdougm 	 * sufficient to let the commands look it up if needed since
5663034Sdougm 	 * not all commands do proto specific things
5673034Sdougm 	 *
5683034Sdougm 	 * Known sub-commands are handled at this level. An unknown
5693034Sdougm 	 * command will be passed down to the shared object that
5703034Sdougm 	 * actually implements it. We can do this since the semantics
5713034Sdougm 	 * of the common sub-commands is well defined.
5723034Sdougm 	 */
5733034Sdougm 
5743034Sdougm 	cmdvec = sa_lookup(command);
5753034Sdougm 	if (cmdvec == NULL) {
5763034Sdougm 		(void) printf(gettext("command %s not found\n"), command);
5773034Sdougm 		exit(1);
5783034Sdougm 	}
5793034Sdougm 	/*
5803034Sdougm 	 * need to check priviledges and restrict what can be done
5813034Sdougm 	 * based on least priviledge and sub-command.
5823034Sdougm 	 */
5833910Sdougm 	ret = cmdvec->cmdfunc(handle, NULL, argc, argv);
5843034Sdougm 	return (ret);
5853034Sdougm }
586