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*11337SWilliam.Krier@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
243034Sdougm * Use is subject to license terms.
253034Sdougm */
263034Sdougm
273034Sdougm #include <stdlib.h>
283034Sdougm #include <stdio.h>
293034Sdougm #include <string.h>
303034Sdougm #include <ctype.h>
313034Sdougm #include <unistd.h>
323034Sdougm #include <getopt.h>
333034Sdougm #include <libgen.h>
343034Sdougm
353034Sdougm #include "libshare.h"
363034Sdougm #include <sharemgr.h>
373034Sdougm
383034Sdougm #include <libintl.h>
393034Sdougm #include <locale.h>
403034Sdougm
413910Sdougm static int run_command(char *, int, char **, sa_handle_t);
423034Sdougm static void sub_command_help(char *proto);
433034Sdougm
443034Sdougm static void
global_help()453034Sdougm global_help()
463034Sdougm {
473034Sdougm (void) printf(gettext("usage: sharectl <command> [options]\n"));
483034Sdougm sub_command_help(NULL);
493034Sdougm }
503034Sdougm
513034Sdougm int
main(int argc,char * argv[])523034Sdougm main(int argc, char *argv[])
533034Sdougm {
543034Sdougm int c;
553034Sdougm int help = 0;
563034Sdougm int rval;
573034Sdougm char *command;
583910Sdougm sa_handle_t handle;
593034Sdougm
603034Sdougm /*
613034Sdougm * make sure locale and gettext domain is setup
623034Sdougm */
633034Sdougm (void) setlocale(LC_ALL, "");
643034Sdougm (void) textdomain(TEXT_DOMAIN);
653034Sdougm
663910Sdougm handle = sa_init(SA_INIT_CONTROL_API);
673034Sdougm
683034Sdougm while ((c = getopt(argc, argv, "h?")) != EOF) {
694653Sdougm switch (c) {
704653Sdougm case '?':
714653Sdougm case 'h':
724653Sdougm help = 1;
734653Sdougm break;
744653Sdougm default:
754653Sdougm (void) printf(gettext("Invalid option: %c\n"), c);
764653Sdougm }
773034Sdougm }
783034Sdougm if (optind == argc || help) {
794653Sdougm /* no subcommand */
804653Sdougm global_help();
814653Sdougm exit(0);
823034Sdougm }
833034Sdougm optind = 1;
843034Sdougm
853034Sdougm /*
863034Sdougm * now have enough to parse rest of command line
873034Sdougm */
883034Sdougm command = argv[optind];
893910Sdougm rval = run_command(command, argc - optind, argv + optind, handle);
903034Sdougm
913910Sdougm sa_fini(handle);
923034Sdougm return (rval);
933034Sdougm }
943034Sdougm
953034Sdougm char *
sc_get_usage(sc_usage_t index)963034Sdougm sc_get_usage(sc_usage_t index)
973034Sdougm {
983034Sdougm char *ret = NULL;
993034Sdougm
1003034Sdougm switch (index) {
1013034Sdougm case USAGE_CTL_GET:
1024653Sdougm ret = gettext("get [-h | -p property ...] proto");
1034653Sdougm break;
1043034Sdougm case USAGE_CTL_SET:
1054653Sdougm ret = gettext("set [-h] -p property=value ... proto");
1064653Sdougm break;
1073034Sdougm case USAGE_CTL_STATUS:
1084653Sdougm ret = gettext("status [-h | proto ...]");
1094653Sdougm break;
1106007Sthurlow case USAGE_CTL_DELSECT:
1116007Sthurlow ret = gettext("delsect [-h] section proto");
1126007Sthurlow break;
1133034Sdougm }
1143034Sdougm return (ret);
1153034Sdougm }
1163034Sdougm
1173910Sdougm /*ARGSUSED*/
1183034Sdougm static int
sc_get(sa_handle_t handle,int flags,int argc,char * argv[])1193910Sdougm sc_get(sa_handle_t handle, int flags, int argc, char *argv[])
1203034Sdougm {
1213034Sdougm char *proto = NULL;
1223034Sdougm struct options *optlist = NULL;
1233034Sdougm int ret = SA_OK;
1243034Sdougm int c;
1256007Sthurlow sa_protocol_properties_t propset, propsect;
1266007Sthurlow sa_property_t prop;
1276007Sthurlow char *section, *value, *name;
1286007Sthurlow int first = 1;
1293034Sdougm
1303034Sdougm while ((c = getopt(argc, argv, "?hp:")) != EOF) {
1314653Sdougm switch (c) {
1324653Sdougm case 'p':
1334653Sdougm ret = add_opt(&optlist, optarg, 1);
1344653Sdougm if (ret != SA_OK) {
1354653Sdougm (void) printf(gettext(
1364653Sdougm "Problem with property: %s\n"), optarg);
1374653Sdougm return (SA_NO_MEMORY);
1384653Sdougm }
1394653Sdougm break;
1404653Sdougm default:
1414653Sdougm (void) printf(gettext("usage: %s\n"),
1424653Sdougm sc_get_usage(USAGE_CTL_GET));
1434653Sdougm return (SA_SYNTAX_ERR);
1444653Sdougm case '?':
1454653Sdougm case 'h':
1464653Sdougm (void) printf(gettext("usage: %s\n"),
1474653Sdougm sc_get_usage(USAGE_CTL_GET));
1484653Sdougm return (SA_OK);
1494653Sdougm break;
1503034Sdougm }
1513034Sdougm }
1523034Sdougm
1533034Sdougm if (optind >= argc) {
1544653Sdougm (void) printf(gettext("usage: %s\n"),
1554653Sdougm sc_get_usage(USAGE_CTL_GET));
1564653Sdougm (void) printf(gettext("\tprotocol must be specified.\n"));
1574653Sdougm return (SA_INVALID_PROTOCOL);
1583034Sdougm }
1593034Sdougm
1603034Sdougm proto = argv[optind];
1616007Sthurlow if (!sa_valid_protocol(proto)) {
1626007Sthurlow (void) printf(gettext("Invalid protocol specified: %s\n"),
1636007Sthurlow proto);
1646007Sthurlow return (SA_INVALID_PROTOCOL);
1656007Sthurlow }
1666007Sthurlow propset = sa_proto_get_properties(proto);
1676007Sthurlow if (propset == NULL)
1686007Sthurlow return (ret);
1693034Sdougm
1706007Sthurlow if (optlist == NULL) {
1716007Sthurlow /* Display all known properties for this protocol */
1726007Sthurlow for (propsect = sa_get_protocol_section(propset, NULL);
1736007Sthurlow propsect != NULL;
1746007Sthurlow propsect = sa_get_next_protocol_section(propsect, NULL)) {
1756007Sthurlow section = sa_get_property_attr(propsect,
1766007Sthurlow "name");
1776007Sthurlow /*
1786007Sthurlow * If properties are organized into sections, as
1796007Sthurlow * in the SMB client, print the section name.
1806007Sthurlow */
1816007Sthurlow if (sa_proto_get_featureset(proto) &
1826007Sthurlow SA_FEATURE_HAS_SECTIONS) {
1836007Sthurlow if (!first)
1846007Sthurlow (void) printf("\n");
1856007Sthurlow first = 0;
186*11337SWilliam.Krier@Sun.COM (void) printf("[%s]\n",
187*11337SWilliam.Krier@Sun.COM section != NULL ? section : "");
1886007Sthurlow }
189*11337SWilliam.Krier@Sun.COM if (section != NULL)
190*11337SWilliam.Krier@Sun.COM sa_free_attr_string(section);
191*11337SWilliam.Krier@Sun.COM
1926007Sthurlow /* Display properties for this section */
1936007Sthurlow for (prop = sa_get_protocol_property(propsect, NULL);
1946007Sthurlow prop != NULL;
1956007Sthurlow prop = sa_get_next_protocol_property(prop, NULL)) {
1966007Sthurlow
1976007Sthurlow /* get and display the property and value */
1986007Sthurlow name = sa_get_property_attr(prop, "type");
1996007Sthurlow if (name != NULL) {
2006007Sthurlow value = sa_get_property_attr(prop,
2016007Sthurlow "value");
2026007Sthurlow (void) printf(gettext("%s=%s\n"), name,
2036007Sthurlow value != NULL ? value : "");
2044653Sdougm }
2056007Sthurlow if (value != NULL)
2066007Sthurlow sa_free_attr_string(value);
2076007Sthurlow if (name != NULL)
2086007Sthurlow sa_free_attr_string(name);
2093034Sdougm }
2103034Sdougm }
2113034Sdougm } else {
2126007Sthurlow struct options *opt;
2136007Sthurlow
2146007Sthurlow /* list the specified option(s) */
2156007Sthurlow for (opt = optlist; opt != NULL; opt = opt->next) {
2166007Sthurlow int printed = 0;
2176007Sthurlow
2186007Sthurlow for (propsect = sa_get_protocol_section(propset, NULL);
2196007Sthurlow propsect != NULL;
2206007Sthurlow propsect = sa_get_next_protocol_section(propsect,
2216007Sthurlow NULL)) {
2226007Sthurlow
2236007Sthurlow section = sa_get_property_attr(propsect,
2246007Sthurlow "name");
2256007Sthurlow for (prop = sa_get_protocol_property(propsect,
2266007Sthurlow opt->optname);
2276007Sthurlow prop != NULL;
2286007Sthurlow prop = sa_get_next_protocol_property(
2296007Sthurlow propsect, opt->optname)) {
2306007Sthurlow value = sa_get_property_attr(prop,
2316007Sthurlow "value");
2326007Sthurlow if (sa_proto_get_featureset(proto) &
2336007Sthurlow SA_FEATURE_HAS_SECTIONS) {
2346007Sthurlow (void) printf(
2356007Sthurlow gettext("[%s] %s=%s\n"),
236*11337SWilliam.Krier@Sun.COM section != NULL ?
237*11337SWilliam.Krier@Sun.COM section : "", opt->optname,
2386007Sthurlow value != NULL ? value : "");
2396007Sthurlow } else {
2406007Sthurlow (void) printf(
2416007Sthurlow gettext("%s=%s\n"),
2426007Sthurlow opt->optname,
2436007Sthurlow value != NULL ? value : "");
2446007Sthurlow }
245*11337SWilliam.Krier@Sun.COM if (value != NULL)
246*11337SWilliam.Krier@Sun.COM sa_free_attr_string(value);
2476007Sthurlow printed = 1;
2486007Sthurlow }
249*11337SWilliam.Krier@Sun.COM if (section != NULL)
250*11337SWilliam.Krier@Sun.COM sa_free_attr_string(section);
2516007Sthurlow }
2526007Sthurlow if (!printed) {
2536007Sthurlow (void) printf(gettext("%s: not defined\n"),
2546007Sthurlow opt->optname);
2556007Sthurlow ret = SA_NO_SUCH_PROP;
2566007Sthurlow }
2576007Sthurlow }
2583034Sdougm }
2593034Sdougm return (ret);
2603034Sdougm }
2613034Sdougm
2623910Sdougm /*ARGSUSED*/
2633034Sdougm static int
sc_set(sa_handle_t handle,int flags,int argc,char * argv[])2643910Sdougm sc_set(sa_handle_t handle, int flags, int argc, char *argv[])
2653034Sdougm {
2663034Sdougm char *proto = NULL;
2673034Sdougm struct options *optlist = NULL;
2686007Sthurlow sa_protocol_properties_t propsect;
2693034Sdougm int ret = SA_OK;
2703034Sdougm int c;
2716007Sthurlow int err;
2724653Sdougm sa_protocol_properties_t propset;
2736007Sthurlow sa_property_t prop;
2743034Sdougm
2753034Sdougm while ((c = getopt(argc, argv, "?hp:")) != EOF) {
2764653Sdougm switch (c) {
2774653Sdougm case 'p':
2784653Sdougm ret = add_opt(&optlist, optarg, 0);
2794653Sdougm if (ret != SA_OK) {
2804653Sdougm (void) printf(gettext(
2814653Sdougm "Problem with property: %s\n"), optarg);
2824653Sdougm return (SA_NO_MEMORY);
2834653Sdougm }
2844653Sdougm break;
2854653Sdougm default:
2864653Sdougm (void) printf(gettext("usage: %s\n"),
2874653Sdougm sc_get_usage(USAGE_CTL_SET));
2884653Sdougm return (SA_SYNTAX_ERR);
2894653Sdougm case '?':
2904653Sdougm case 'h':
2914653Sdougm (void) printf(gettext("usage: %s\n"),
2924653Sdougm sc_get_usage(USAGE_CTL_SET));
2934653Sdougm return (SA_OK);
2944653Sdougm break;
2953034Sdougm }
2963034Sdougm }
2973034Sdougm
2983034Sdougm if (optind >= argc) {
2994653Sdougm (void) printf(gettext("usage: %s\n"),
3004653Sdougm sc_get_usage(USAGE_CTL_SET));
3014653Sdougm (void) printf(gettext("\tprotocol must be specified.\n"));
3024653Sdougm return (SA_INVALID_PROTOCOL);
3033034Sdougm }
3043034Sdougm
3053034Sdougm proto = argv[optind];
3064653Sdougm if (!sa_valid_protocol(proto)) {
3074653Sdougm (void) printf(gettext("Invalid protocol specified: %s\n"),
3084653Sdougm proto);
3094653Sdougm return (SA_INVALID_PROTOCOL);
3104653Sdougm }
3114653Sdougm propset = sa_proto_get_properties(proto);
3126007Sthurlow if (propset == NULL)
3136007Sthurlow return (ret);
3146007Sthurlow
3156007Sthurlow if (optlist == NULL) {
3166007Sthurlow (void) printf(gettext("usage: %s\n"),
3176007Sthurlow sc_get_usage(USAGE_CTL_SET));
3186007Sthurlow (void) printf(gettext(
3196007Sthurlow "\tat least one property and value "
3206007Sthurlow "must be specified\n"));
3216007Sthurlow } else {
3226007Sthurlow struct options *opt;
3236007Sthurlow char *section = NULL;
3246007Sthurlow /* fetch and change the specified option(s) */
3256007Sthurlow for (opt = optlist; opt != NULL; opt = opt->next) {
3266007Sthurlow if (strncmp("section", opt->optname, 7) == 0) {
3276007Sthurlow if (section != NULL)
3286007Sthurlow free(section);
3296007Sthurlow section = strdup(opt->optvalue);
3306007Sthurlow continue;
3316007Sthurlow }
3326007Sthurlow if (sa_proto_get_featureset(proto) &
3336007Sthurlow SA_FEATURE_HAS_SECTIONS) {
3346007Sthurlow propsect = sa_get_protocol_section(propset,
3356007Sthurlow section);
3366007Sthurlow prop = sa_get_protocol_property(propsect,
3376007Sthurlow opt->optname);
3386007Sthurlow } else {
3396007Sthurlow prop = sa_get_protocol_property(propset,
3406007Sthurlow opt->optname);
3416007Sthurlow }
3426007Sthurlow if (prop == NULL && sa_proto_get_featureset(proto) &
3436007Sthurlow SA_FEATURE_ADD_PROPERTIES) {
3446007Sthurlow sa_property_t sect;
3456007Sthurlow sect = sa_create_section(section, NULL);
3466007Sthurlow sa_set_section_attr(sect, "type", proto);
3476007Sthurlow (void) sa_add_protocol_property(propset, sect);
3486007Sthurlow prop = sa_create_property(
3496007Sthurlow opt->optname, opt->optvalue);
3506007Sthurlow (void) sa_add_protocol_property(sect, prop);
3516007Sthurlow }
3526007Sthurlow if (prop != NULL) {
3536007Sthurlow /*
3546007Sthurlow * "err" is used in order to prevent
3556007Sthurlow * setting ret to SA_OK if there has
3566007Sthurlow * been a real error. We want to be
3576007Sthurlow * able to return an error status on
3586007Sthurlow * exit in that case. Error messages
3596007Sthurlow * are printed for each error, so we
3606007Sthurlow * only care on exit that there was an
3616007Sthurlow * error and not the specific error
3626007Sthurlow * value.
3636007Sthurlow */
3646007Sthurlow err = sa_set_protocol_property(prop, section,
3656007Sthurlow opt->optvalue);
3666007Sthurlow if (err != SA_OK) {
3674653Sdougm (void) printf(gettext(
3686007Sthurlow "Could not set property"
3696007Sthurlow " %s: %s\n"),
3706007Sthurlow opt->optname, sa_errorstr(err));
3716007Sthurlow ret = err;
3724653Sdougm }
3736007Sthurlow } else {
3746007Sthurlow (void) printf(gettext("%s: not defined\n"),
3756007Sthurlow opt->optname);
3766007Sthurlow ret = SA_NO_SUCH_PROP;
3773034Sdougm }
3783034Sdougm }
3793034Sdougm }
3803034Sdougm return (ret);
3813034Sdougm }
3823034Sdougm
3833034Sdougm static void
show_status(char * proto)3843034Sdougm show_status(char *proto)
3853034Sdougm {
3863034Sdougm char *status;
3876088Sdougm uint64_t features;
3884653Sdougm
3893034Sdougm status = sa_get_protocol_status(proto);
3906088Sdougm features = sa_proto_get_featureset(proto);
3916088Sdougm (void) printf("%s\t%s", proto, status ? gettext(status) : "-");
3923034Sdougm if (status != NULL)
3934653Sdougm free(status);
3946088Sdougm /*
3956088Sdougm * Need to flag a client only protocol so test suites can
3966088Sdougm * remove it from consideration.
3976088Sdougm */
3986088Sdougm if (!(features & SA_FEATURE_SERVER))
3996088Sdougm (void) printf(" client");
4006088Sdougm (void) printf("\n");
4013034Sdougm }
4023034Sdougm
4033034Sdougm static int
valid_proto(char ** protos,int num,char * proto)4043034Sdougm valid_proto(char **protos, int num, char *proto)
4053034Sdougm {
4063034Sdougm int i;
4073034Sdougm for (i = 0; i < num; i++)
4084653Sdougm if (strcmp(protos[i], proto) == 0)
4094653Sdougm return (1);
4103034Sdougm return (0);
4113034Sdougm }
4123034Sdougm
4133910Sdougm /*ARGSUSED*/
4143034Sdougm static int
sc_status(sa_handle_t handle,int flags,int argc,char * argv[])4153910Sdougm sc_status(sa_handle_t handle, int flags, int argc, char *argv[])
4163034Sdougm {
4173034Sdougm char **protos;
4183034Sdougm int ret = SA_OK;
4193034Sdougm int c;
4203034Sdougm int i;
4213034Sdougm int num_proto;
4223034Sdougm int verbose = 0;
4233034Sdougm
4243034Sdougm while ((c = getopt(argc, argv, "?hv")) != EOF) {
4254653Sdougm switch (c) {
4264653Sdougm case 'v':
4274653Sdougm verbose++;
4284653Sdougm break;
4294653Sdougm case '?':
4304653Sdougm case 'h':
4314653Sdougm (void) printf(gettext("usage: %s\n"),
4324653Sdougm sc_get_usage(USAGE_CTL_STATUS));
4334653Sdougm return (SA_OK);
4344653Sdougm default:
4354653Sdougm (void) printf(gettext("usage: %s\n"),
4364653Sdougm sc_get_usage(USAGE_CTL_STATUS));
4374653Sdougm return (SA_SYNTAX_ERR);
4384653Sdougm }
4393034Sdougm }
4403034Sdougm
4413034Sdougm num_proto = sa_get_protocols(&protos);
4423034Sdougm if (optind == argc) {
4434653Sdougm /* status for all protocols */
4444653Sdougm for (i = 0; i < num_proto; i++) {
4454653Sdougm show_status(protos[i]);
4464653Sdougm }
4473034Sdougm } else {
4484653Sdougm for (i = optind; i < argc; i++) {
4494653Sdougm if (valid_proto(protos, num_proto, argv[i])) {
4504653Sdougm show_status(argv[i]);
4514653Sdougm } else {
4524653Sdougm (void) printf(gettext("Invalid protocol: %s\n"),
4534653Sdougm argv[i]);
4544653Sdougm ret = SA_INVALID_PROTOCOL;
4554653Sdougm }
4563034Sdougm }
4573034Sdougm }
4583034Sdougm if (protos != NULL)
4594653Sdougm free(protos);
4603034Sdougm return (ret);
4613034Sdougm }
4623034Sdougm
4636007Sthurlow /*ARGSUSED*/
4646007Sthurlow static int
sc_delsect(sa_handle_t handle,int flags,int argc,char * argv[])4656007Sthurlow sc_delsect(sa_handle_t handle, int flags, int argc, char *argv[])
4666007Sthurlow {
4676007Sthurlow char *proto = NULL;
4686007Sthurlow char *section = NULL;
4696007Sthurlow sa_protocol_properties_t propset;
4706007Sthurlow sa_protocol_properties_t propsect;
4716007Sthurlow int ret = SA_OK;
4726007Sthurlow int c;
4736007Sthurlow
4746007Sthurlow while ((c = getopt(argc, argv, "?h")) != EOF) {
4756007Sthurlow switch (c) {
4766007Sthurlow default:
4776007Sthurlow ret = SA_SYNTAX_ERR;
4786007Sthurlow /*FALLTHROUGH*/
4796007Sthurlow case '?':
4806007Sthurlow case 'h':
4816007Sthurlow (void) printf(gettext("usage: %s\n"),
4826007Sthurlow sc_get_usage(USAGE_CTL_DELSECT));
4836007Sthurlow return (ret);
4846007Sthurlow }
4856007Sthurlow /*NOTREACHED*/
4866007Sthurlow }
4876007Sthurlow
4886007Sthurlow section = argv[optind++];
4896007Sthurlow
4906007Sthurlow if (optind >= argc) {
4916007Sthurlow (void) printf(gettext("usage: %s\n"),
4926007Sthurlow sc_get_usage(USAGE_CTL_DELSECT));
4936007Sthurlow (void) printf(gettext(
4946007Sthurlow "\tsection and protocol must be specified.\n"));
4956007Sthurlow return (SA_INVALID_PROTOCOL);
4966007Sthurlow }
4976007Sthurlow
4986007Sthurlow proto = argv[optind];
4996007Sthurlow if (!sa_valid_protocol(proto)) {
5006007Sthurlow (void) printf(gettext("Invalid protocol specified: %s\n"),
5016007Sthurlow proto);
5026007Sthurlow return (SA_INVALID_PROTOCOL);
5036007Sthurlow }
5046007Sthurlow
5056007Sthurlow if ((sa_proto_get_featureset(proto) & SA_FEATURE_HAS_SECTIONS) == 0) {
5066007Sthurlow (void) printf(gettext("Protocol %s does not have sections\n"),
5076007Sthurlow section, proto);
5086007Sthurlow return (SA_NOT_SUPPORTED);
5096007Sthurlow }
5106007Sthurlow
5116007Sthurlow propset = sa_proto_get_properties(proto);
5126007Sthurlow if (propset == NULL) {
5136007Sthurlow (void) printf(gettext("Cannot get properties for %s\n"),
5146007Sthurlow proto);
5156007Sthurlow return (SA_NO_PROPERTIES);
5166007Sthurlow }
5176007Sthurlow
5186007Sthurlow propsect = sa_get_protocol_section(propset, section);
5196007Sthurlow if (propsect == NULL) {
5206007Sthurlow (void) printf(gettext("Cannot find section %s for proto %s\n"),
5216007Sthurlow section, proto);
5226007Sthurlow return (SA_NO_SUCH_SECTION);
5236007Sthurlow }
5246007Sthurlow
5256007Sthurlow ret = sa_proto_delete_section(proto, section);
5266007Sthurlow
5276007Sthurlow return (ret);
5286007Sthurlow }
5296007Sthurlow
5303034Sdougm static sa_command_t commands[] = {
5313034Sdougm {"get", 0, sc_get, USAGE_CTL_GET},
5323034Sdougm {"set", 0, sc_set, USAGE_CTL_SET},
5333034Sdougm {"status", 0, sc_status, USAGE_CTL_STATUS},
5346007Sthurlow {"delsect", 0, sc_delsect, USAGE_CTL_DELSECT},
5353034Sdougm {NULL, 0, NULL, 0},
5363034Sdougm };
5373034Sdougm
5383910Sdougm /*ARGSUSED*/
5393034Sdougm void
sub_command_help(char * proto)5403034Sdougm sub_command_help(char *proto)
5413034Sdougm {
5423034Sdougm int i;
5433034Sdougm
5443034Sdougm (void) printf("\tsub-commands:\n");
5453034Sdougm for (i = 0; commands[i].cmdname != NULL; i++) {
5463034Sdougm if (!(commands[i].flags & (CMD_ALIAS|CMD_NODISPLAY)))
5473034Sdougm (void) printf("\t%s\n",
5484653Sdougm sc_get_usage((sc_usage_t)commands[i].cmdidx));
5493034Sdougm }
5503034Sdougm }
5513034Sdougm
5523034Sdougm sa_command_t *
sa_lookup(char * cmd)5533034Sdougm sa_lookup(char *cmd)
5543034Sdougm {
5553034Sdougm int i;
5563034Sdougm size_t len;
5573034Sdougm
5583034Sdougm len = strlen(cmd);
5593034Sdougm for (i = 0; commands[i].cmdname != NULL; i++) {
5603034Sdougm if (strncmp(cmd, commands[i].cmdname, len) == 0)
5613034Sdougm return (&commands[i]);
5623034Sdougm }
5633034Sdougm return (NULL);
5643034Sdougm }
5653034Sdougm
5663034Sdougm static int
run_command(char * command,int argc,char * argv[],sa_handle_t handle)5673910Sdougm run_command(char *command, int argc, char *argv[], sa_handle_t handle)
5683034Sdougm {
5693034Sdougm sa_command_t *cmdvec;
5703034Sdougm int ret;
5713034Sdougm
5723034Sdougm /*
5733034Sdougm * To get here, we know there should be a command due to the
5743034Sdougm * preprocessing done earlier. Need to find the protocol
5753034Sdougm * that is being affected. If no protocol, then it is ALL
5763034Sdougm * protocols.
5773034Sdougm *
5783034Sdougm * ??? do we really need the protocol at this level? it may be
5793034Sdougm * sufficient to let the commands look it up if needed since
5803034Sdougm * not all commands do proto specific things
5813034Sdougm *
5823034Sdougm * Known sub-commands are handled at this level. An unknown
5833034Sdougm * command will be passed down to the shared object that
5843034Sdougm * actually implements it. We can do this since the semantics
5853034Sdougm * of the common sub-commands is well defined.
5863034Sdougm */
5873034Sdougm
5883034Sdougm cmdvec = sa_lookup(command);
5893034Sdougm if (cmdvec == NULL) {
5903034Sdougm (void) printf(gettext("command %s not found\n"), command);
5913034Sdougm exit(1);
5923034Sdougm }
5933034Sdougm /*
5943034Sdougm * need to check priviledges and restrict what can be done
5953034Sdougm * based on least priviledge and sub-command.
5963034Sdougm */
5973910Sdougm ret = cmdvec->cmdfunc(handle, NULL, argc, argv);
5983034Sdougm return (ret);
5993034Sdougm }
600