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 /*
23fe1c642dSBill Krier * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
246185db85Sdougm * Use is subject to license terms.
25*33f5ff17SMilan Jurik * Copyright 2012 Milan Jurik. All rights reserved.
266185db85Sdougm */
276185db85Sdougm
286185db85Sdougm #include <stdlib.h>
296185db85Sdougm #include <stdio.h>
306185db85Sdougm #include <string.h>
316185db85Sdougm #include <ctype.h>
326185db85Sdougm #include <unistd.h>
336185db85Sdougm #include <getopt.h>
346185db85Sdougm #include <libgen.h>
356185db85Sdougm
366185db85Sdougm #include "libshare.h"
376185db85Sdougm #include <sharemgr.h>
386185db85Sdougm
396185db85Sdougm #include <libintl.h>
406185db85Sdougm #include <locale.h>
416185db85Sdougm
42549ec3ffSdougm static int run_command(char *, int, char **, sa_handle_t);
436185db85Sdougm static void sub_command_help(char *proto);
446185db85Sdougm
456185db85Sdougm static void
global_help()466185db85Sdougm global_help()
476185db85Sdougm {
486185db85Sdougm (void) printf(gettext("usage: sharectl <command> [options]\n"));
496185db85Sdougm sub_command_help(NULL);
506185db85Sdougm }
516185db85Sdougm
526185db85Sdougm int
main(int argc,char * argv[])536185db85Sdougm main(int argc, char *argv[])
546185db85Sdougm {
556185db85Sdougm int c;
566185db85Sdougm int help = 0;
576185db85Sdougm int rval;
586185db85Sdougm char *command;
59549ec3ffSdougm sa_handle_t handle;
606185db85Sdougm
616185db85Sdougm /*
626185db85Sdougm * make sure locale and gettext domain is setup
636185db85Sdougm */
646185db85Sdougm (void) setlocale(LC_ALL, "");
656185db85Sdougm (void) textdomain(TEXT_DOMAIN);
666185db85Sdougm
67549ec3ffSdougm handle = sa_init(SA_INIT_CONTROL_API);
686185db85Sdougm
696185db85Sdougm while ((c = getopt(argc, argv, "h?")) != EOF) {
706185db85Sdougm switch (c) {
716185db85Sdougm case '?':
726185db85Sdougm case 'h':
736185db85Sdougm help = 1;
746185db85Sdougm break;
756185db85Sdougm default:
766185db85Sdougm (void) printf(gettext("Invalid option: %c\n"), c);
776185db85Sdougm }
786185db85Sdougm }
796185db85Sdougm if (optind == argc || help) {
806185db85Sdougm /* no subcommand */
816185db85Sdougm global_help();
826185db85Sdougm exit(0);
836185db85Sdougm }
846185db85Sdougm optind = 1;
856185db85Sdougm
866185db85Sdougm /*
876185db85Sdougm * now have enough to parse rest of command line
886185db85Sdougm */
896185db85Sdougm command = argv[optind];
90549ec3ffSdougm rval = run_command(command, argc - optind, argv + optind, handle);
916185db85Sdougm
92549ec3ffSdougm sa_fini(handle);
936185db85Sdougm return (rval);
946185db85Sdougm }
956185db85Sdougm
966185db85Sdougm char *
sc_get_usage(sc_usage_t index)976185db85Sdougm sc_get_usage(sc_usage_t index)
986185db85Sdougm {
996185db85Sdougm char *ret = NULL;
1006185db85Sdougm
1016185db85Sdougm switch (index) {
1026185db85Sdougm case USAGE_CTL_GET:
1033472f5dcSdougm ret = gettext("get [-h | -p property ...] proto");
1046185db85Sdougm break;
1056185db85Sdougm case USAGE_CTL_SET:
1066185db85Sdougm ret = gettext("set [-h] -p property=value ... proto");
1076185db85Sdougm break;
1086185db85Sdougm case USAGE_CTL_STATUS:
1093472f5dcSdougm ret = gettext("status [-h | proto ...]");
1106185db85Sdougm break;
1114bff34e3Sthurlow case USAGE_CTL_DELSECT:
1124bff34e3Sthurlow ret = gettext("delsect [-h] section proto");
1134bff34e3Sthurlow break;
1146185db85Sdougm }
1156185db85Sdougm return (ret);
1166185db85Sdougm }
1176185db85Sdougm
118549ec3ffSdougm /*ARGSUSED*/
1196185db85Sdougm static int
sc_get(sa_handle_t handle,int flags,int argc,char * argv[])120549ec3ffSdougm sc_get(sa_handle_t handle, int flags, int argc, char *argv[])
1216185db85Sdougm {
1226185db85Sdougm char *proto = NULL;
1236185db85Sdougm struct options *optlist = NULL;
1246185db85Sdougm int ret = SA_OK;
1256185db85Sdougm int c;
1264bff34e3Sthurlow sa_protocol_properties_t propset, propsect;
1274bff34e3Sthurlow sa_property_t prop;
1284bff34e3Sthurlow char *section, *value, *name;
1294bff34e3Sthurlow int first = 1;
1306185db85Sdougm
1316185db85Sdougm while ((c = getopt(argc, argv, "?hp:")) != EOF) {
1326185db85Sdougm switch (c) {
1336185db85Sdougm case 'p':
1346185db85Sdougm ret = add_opt(&optlist, optarg, 1);
1356185db85Sdougm if (ret != SA_OK) {
13625a68471Sdougm (void) printf(gettext(
13725a68471Sdougm "Problem with property: %s\n"), optarg);
1386185db85Sdougm return (SA_NO_MEMORY);
1396185db85Sdougm }
1406185db85Sdougm break;
1416185db85Sdougm default:
1426185db85Sdougm (void) printf(gettext("usage: %s\n"),
1436185db85Sdougm sc_get_usage(USAGE_CTL_GET));
1446185db85Sdougm return (SA_SYNTAX_ERR);
1456185db85Sdougm case '?':
1466185db85Sdougm case 'h':
1476185db85Sdougm (void) printf(gettext("usage: %s\n"),
1486185db85Sdougm sc_get_usage(USAGE_CTL_GET));
1496185db85Sdougm return (SA_OK);
1506185db85Sdougm }
1516185db85Sdougm }
1526185db85Sdougm
1536185db85Sdougm if (optind >= argc) {
15425a68471Sdougm (void) printf(gettext("usage: %s\n"),
15525a68471Sdougm sc_get_usage(USAGE_CTL_GET));
1566185db85Sdougm (void) printf(gettext("\tprotocol must be specified.\n"));
1576185db85Sdougm return (SA_INVALID_PROTOCOL);
1586185db85Sdougm }
1596185db85Sdougm
1606185db85Sdougm proto = argv[optind];
1614bff34e3Sthurlow if (!sa_valid_protocol(proto)) {
1624bff34e3Sthurlow (void) printf(gettext("Invalid protocol specified: %s\n"),
1634bff34e3Sthurlow proto);
1644bff34e3Sthurlow return (SA_INVALID_PROTOCOL);
1654bff34e3Sthurlow }
1666185db85Sdougm propset = sa_proto_get_properties(proto);
1674bff34e3Sthurlow if (propset == NULL)
1684bff34e3Sthurlow return (ret);
1696185db85Sdougm
17025a68471Sdougm if (optlist == NULL) {
1714bff34e3Sthurlow /* Display all known properties for this protocol */
1724bff34e3Sthurlow for (propsect = sa_get_protocol_section(propset, NULL);
1734bff34e3Sthurlow propsect != NULL;
1744bff34e3Sthurlow propsect = sa_get_next_protocol_section(propsect, NULL)) {
1754bff34e3Sthurlow section = sa_get_property_attr(propsect,
1764bff34e3Sthurlow "name");
17725a68471Sdougm /*
1784bff34e3Sthurlow * If properties are organized into sections, as
1794bff34e3Sthurlow * in the SMB client, print the section name.
18025a68471Sdougm */
1814bff34e3Sthurlow if (sa_proto_get_featureset(proto) &
1824bff34e3Sthurlow SA_FEATURE_HAS_SECTIONS) {
1834bff34e3Sthurlow if (!first)
1844bff34e3Sthurlow (void) printf("\n");
1854bff34e3Sthurlow first = 0;
186fe1c642dSBill Krier (void) printf("[%s]\n",
187fe1c642dSBill Krier section != NULL ? section : "");
1884bff34e3Sthurlow }
189fe1c642dSBill Krier if (section != NULL)
190fe1c642dSBill Krier sa_free_attr_string(section);
191fe1c642dSBill Krier
1924bff34e3Sthurlow /* Display properties for this section */
1934bff34e3Sthurlow for (prop = sa_get_protocol_property(propsect, NULL);
19425a68471Sdougm prop != NULL;
1954bff34e3Sthurlow prop = sa_get_next_protocol_property(prop, NULL)) {
19625a68471Sdougm
1974bff34e3Sthurlow /* get and display the property and value */
1984bff34e3Sthurlow name = sa_get_property_attr(prop, "type");
1996185db85Sdougm if (name != NULL) {
2004bff34e3Sthurlow value = sa_get_property_attr(prop,
2014bff34e3Sthurlow "value");
2024bff34e3Sthurlow (void) printf(gettext("%s=%s\n"), name,
2036185db85Sdougm value != NULL ? value : "");
2046185db85Sdougm }
2056185db85Sdougm if (value != NULL)
2066185db85Sdougm sa_free_attr_string(value);
2076185db85Sdougm if (name != NULL)
2086185db85Sdougm sa_free_attr_string(name);
2096185db85Sdougm }
2104bff34e3Sthurlow }
2116185db85Sdougm } else {
2126185db85Sdougm struct options *opt;
2134bff34e3Sthurlow
2146185db85Sdougm /* list the specified option(s) */
2154bff34e3Sthurlow for (opt = optlist; opt != NULL; opt = opt->next) {
2164bff34e3Sthurlow int printed = 0;
2174bff34e3Sthurlow
2184bff34e3Sthurlow for (propsect = sa_get_protocol_section(propset, NULL);
2194bff34e3Sthurlow propsect != NULL;
2204bff34e3Sthurlow propsect = sa_get_next_protocol_section(propsect,
2214bff34e3Sthurlow NULL)) {
2224bff34e3Sthurlow
2234bff34e3Sthurlow section = sa_get_property_attr(propsect,
2244bff34e3Sthurlow "name");
2254bff34e3Sthurlow for (prop = sa_get_protocol_property(propsect,
2264bff34e3Sthurlow opt->optname);
2274bff34e3Sthurlow prop != NULL;
2284bff34e3Sthurlow prop = sa_get_next_protocol_property(
2294bff34e3Sthurlow propsect, opt->optname)) {
2304bff34e3Sthurlow value = sa_get_property_attr(prop,
2314bff34e3Sthurlow "value");
2324bff34e3Sthurlow if (sa_proto_get_featureset(proto) &
2334bff34e3Sthurlow SA_FEATURE_HAS_SECTIONS) {
2344bff34e3Sthurlow (void) printf(
2354bff34e3Sthurlow gettext("[%s] %s=%s\n"),
236fe1c642dSBill Krier section != NULL ?
237fe1c642dSBill Krier section : "", opt->optname,
2384bff34e3Sthurlow value != NULL ? value : "");
2396185db85Sdougm } else {
2404bff34e3Sthurlow (void) printf(
2414bff34e3Sthurlow gettext("%s=%s\n"),
2424bff34e3Sthurlow opt->optname,
2434bff34e3Sthurlow value != NULL ? value : "");
2444bff34e3Sthurlow }
245fe1c642dSBill Krier if (value != NULL)
2464bff34e3Sthurlow sa_free_attr_string(value);
2474bff34e3Sthurlow printed = 1;
2484bff34e3Sthurlow }
249fe1c642dSBill Krier if (section != NULL)
250fe1c642dSBill Krier sa_free_attr_string(section);
2514bff34e3Sthurlow }
2524bff34e3Sthurlow if (!printed) {
2534bff34e3Sthurlow (void) printf(gettext("%s: not defined\n"),
2546185db85Sdougm opt->optname);
2553472f5dcSdougm ret = SA_NO_SUCH_PROP;
2566185db85Sdougm }
2576185db85Sdougm }
2586185db85Sdougm }
2596185db85Sdougm return (ret);
2606185db85Sdougm }
2616185db85Sdougm
262549ec3ffSdougm /*ARGSUSED*/
2636185db85Sdougm static int
sc_set(sa_handle_t handle,int flags,int argc,char * argv[])264549ec3ffSdougm sc_set(sa_handle_t handle, int flags, int argc, char *argv[])
2656185db85Sdougm {
2666185db85Sdougm char *proto = NULL;
2676185db85Sdougm struct options *optlist = NULL;
2684bff34e3Sthurlow sa_protocol_properties_t propsect;
2696185db85Sdougm int ret = SA_OK;
2706185db85Sdougm int c;
2714bff34e3Sthurlow int err;
27225a68471Sdougm sa_protocol_properties_t propset;
2734bff34e3Sthurlow sa_property_t prop;
2746185db85Sdougm
2756185db85Sdougm while ((c = getopt(argc, argv, "?hp:")) != EOF) {
2766185db85Sdougm switch (c) {
2776185db85Sdougm case 'p':
2786185db85Sdougm ret = add_opt(&optlist, optarg, 0);
2796185db85Sdougm if (ret != SA_OK) {
28025a68471Sdougm (void) printf(gettext(
28125a68471Sdougm "Problem with property: %s\n"), optarg);
2826185db85Sdougm return (SA_NO_MEMORY);
2836185db85Sdougm }
2846185db85Sdougm break;
2856185db85Sdougm default:
2866185db85Sdougm (void) printf(gettext("usage: %s\n"),
2876185db85Sdougm sc_get_usage(USAGE_CTL_SET));
2886185db85Sdougm return (SA_SYNTAX_ERR);
2896185db85Sdougm case '?':
2906185db85Sdougm case 'h':
2916185db85Sdougm (void) printf(gettext("usage: %s\n"),
2926185db85Sdougm sc_get_usage(USAGE_CTL_SET));
2936185db85Sdougm return (SA_OK);
2946185db85Sdougm }
2956185db85Sdougm }
2966185db85Sdougm
2976185db85Sdougm if (optind >= argc) {
2986185db85Sdougm (void) printf(gettext("usage: %s\n"),
2996185db85Sdougm sc_get_usage(USAGE_CTL_SET));
3006185db85Sdougm (void) printf(gettext("\tprotocol must be specified.\n"));
3016185db85Sdougm return (SA_INVALID_PROTOCOL);
3026185db85Sdougm }
3036185db85Sdougm
3046185db85Sdougm proto = argv[optind];
30525a68471Sdougm if (!sa_valid_protocol(proto)) {
30625a68471Sdougm (void) printf(gettext("Invalid protocol specified: %s\n"),
30725a68471Sdougm proto);
30825a68471Sdougm return (SA_INVALID_PROTOCOL);
30925a68471Sdougm }
3106185db85Sdougm propset = sa_proto_get_properties(proto);
3114bff34e3Sthurlow if (propset == NULL)
3124bff34e3Sthurlow return (ret);
3134bff34e3Sthurlow
3146185db85Sdougm if (optlist == NULL) {
3156185db85Sdougm (void) printf(gettext("usage: %s\n"),
3166185db85Sdougm sc_get_usage(USAGE_CTL_SET));
31725a68471Sdougm (void) printf(gettext(
31825a68471Sdougm "\tat least one property and value "
3196185db85Sdougm "must be specified\n"));
3206185db85Sdougm } else {
3216185db85Sdougm struct options *opt;
3224bff34e3Sthurlow char *section = NULL;
3234bff34e3Sthurlow /* fetch and change the specified option(s) */
3244bff34e3Sthurlow for (opt = optlist; opt != NULL; opt = opt->next) {
3254bff34e3Sthurlow if (strncmp("section", opt->optname, 7) == 0) {
3264bff34e3Sthurlow if (section != NULL)
3274bff34e3Sthurlow free(section);
3284bff34e3Sthurlow section = strdup(opt->optvalue);
3294bff34e3Sthurlow continue;
3304bff34e3Sthurlow }
3314bff34e3Sthurlow if (sa_proto_get_featureset(proto) &
3324bff34e3Sthurlow SA_FEATURE_HAS_SECTIONS) {
3334bff34e3Sthurlow propsect = sa_get_protocol_section(propset,
3344bff34e3Sthurlow section);
3354bff34e3Sthurlow prop = sa_get_protocol_property(propsect,
3364bff34e3Sthurlow opt->optname);
3374bff34e3Sthurlow } else {
3384bff34e3Sthurlow prop = sa_get_protocol_property(propset,
3394bff34e3Sthurlow opt->optname);
3404bff34e3Sthurlow }
3414bff34e3Sthurlow if (prop == NULL && sa_proto_get_featureset(proto) &
3424bff34e3Sthurlow SA_FEATURE_ADD_PROPERTIES) {
3434bff34e3Sthurlow sa_property_t sect;
3444bff34e3Sthurlow sect = sa_create_section(section, NULL);
3454bff34e3Sthurlow sa_set_section_attr(sect, "type", proto);
3464bff34e3Sthurlow (void) sa_add_protocol_property(propset, sect);
3474bff34e3Sthurlow prop = sa_create_property(
3484bff34e3Sthurlow opt->optname, opt->optvalue);
3494bff34e3Sthurlow (void) sa_add_protocol_property(sect, prop);
3504bff34e3Sthurlow }
3516185db85Sdougm if (prop != NULL) {
3523472f5dcSdougm /*
3534bff34e3Sthurlow * "err" is used in order to prevent
3544bff34e3Sthurlow * setting ret to SA_OK if there has
3554bff34e3Sthurlow * been a real error. We want to be
3564bff34e3Sthurlow * able to return an error status on
3574bff34e3Sthurlow * exit in that case. Error messages
3584bff34e3Sthurlow * are printed for each error, so we
3594bff34e3Sthurlow * only care on exit that there was an
3604bff34e3Sthurlow * error and not the specific error
3614bff34e3Sthurlow * value.
3623472f5dcSdougm */
3634bff34e3Sthurlow err = sa_set_protocol_property(prop, section,
3644bff34e3Sthurlow opt->optvalue);
3653472f5dcSdougm if (err != SA_OK) {
36625a68471Sdougm (void) printf(gettext(
36725a68471Sdougm "Could not set property"
3686185db85Sdougm " %s: %s\n"),
3694bff34e3Sthurlow opt->optname, sa_errorstr(err));
3703472f5dcSdougm ret = err;
3716185db85Sdougm }
3726185db85Sdougm } else {
3734bff34e3Sthurlow (void) printf(gettext("%s: not defined\n"),
3746185db85Sdougm opt->optname);
3753472f5dcSdougm ret = SA_NO_SUCH_PROP;
3766185db85Sdougm }
3776185db85Sdougm }
3786185db85Sdougm }
3796185db85Sdougm return (ret);
3806185db85Sdougm }
3816185db85Sdougm
3826185db85Sdougm static void
show_status(char * proto)3836185db85Sdougm show_status(char *proto)
3846185db85Sdougm {
3856185db85Sdougm char *status;
3869e5da854Sdougm uint64_t features;
38725a68471Sdougm
3886185db85Sdougm status = sa_get_protocol_status(proto);
3899e5da854Sdougm features = sa_proto_get_featureset(proto);
3909e5da854Sdougm (void) printf("%s\t%s", proto, status ? gettext(status) : "-");
3916185db85Sdougm if (status != NULL)
3926185db85Sdougm free(status);
3939e5da854Sdougm /*
3949e5da854Sdougm * Need to flag a client only protocol so test suites can
3959e5da854Sdougm * remove it from consideration.
3969e5da854Sdougm */
3979e5da854Sdougm if (!(features & SA_FEATURE_SERVER))
3989e5da854Sdougm (void) printf(" client");
3999e5da854Sdougm (void) printf("\n");
4006185db85Sdougm }
4016185db85Sdougm
4026185db85Sdougm static int
valid_proto(char ** protos,int num,char * proto)4036185db85Sdougm valid_proto(char **protos, int num, char *proto)
4046185db85Sdougm {
4056185db85Sdougm int i;
4066185db85Sdougm for (i = 0; i < num; i++)
4076185db85Sdougm if (strcmp(protos[i], proto) == 0)
4086185db85Sdougm return (1);
4096185db85Sdougm return (0);
4106185db85Sdougm }
4116185db85Sdougm
412549ec3ffSdougm /*ARGSUSED*/
4136185db85Sdougm static int
sc_status(sa_handle_t handle,int flags,int argc,char * argv[])414549ec3ffSdougm sc_status(sa_handle_t handle, int flags, int argc, char *argv[])
4156185db85Sdougm {
4166185db85Sdougm char **protos;
4176185db85Sdougm int ret = SA_OK;
4186185db85Sdougm int c;
4196185db85Sdougm int i;
4206185db85Sdougm int num_proto;
4216185db85Sdougm int verbose = 0;
4226185db85Sdougm
4236185db85Sdougm while ((c = getopt(argc, argv, "?hv")) != EOF) {
4246185db85Sdougm switch (c) {
4256185db85Sdougm case 'v':
4266185db85Sdougm verbose++;
4276185db85Sdougm break;
4286185db85Sdougm case '?':
4296185db85Sdougm case 'h':
4306185db85Sdougm (void) printf(gettext("usage: %s\n"),
4313472f5dcSdougm sc_get_usage(USAGE_CTL_STATUS));
4326185db85Sdougm return (SA_OK);
4336185db85Sdougm default:
4346185db85Sdougm (void) printf(gettext("usage: %s\n"),
4353472f5dcSdougm sc_get_usage(USAGE_CTL_STATUS));
4366185db85Sdougm return (SA_SYNTAX_ERR);
4376185db85Sdougm }
4386185db85Sdougm }
4396185db85Sdougm
4406185db85Sdougm num_proto = sa_get_protocols(&protos);
4416185db85Sdougm if (optind == argc) {
4426185db85Sdougm /* status for all protocols */
4436185db85Sdougm for (i = 0; i < num_proto; i++) {
4446185db85Sdougm show_status(protos[i]);
4456185db85Sdougm }
4466185db85Sdougm } else {
4476185db85Sdougm for (i = optind; i < argc; i++) {
4486185db85Sdougm if (valid_proto(protos, num_proto, argv[i])) {
4496185db85Sdougm show_status(argv[i]);
4506185db85Sdougm } else {
45125a68471Sdougm (void) printf(gettext("Invalid protocol: %s\n"),
45225a68471Sdougm argv[i]);
4536185db85Sdougm ret = SA_INVALID_PROTOCOL;
4546185db85Sdougm }
4556185db85Sdougm }
4566185db85Sdougm }
4576185db85Sdougm if (protos != NULL)
4586185db85Sdougm free(protos);
4596185db85Sdougm return (ret);
4606185db85Sdougm }
4616185db85Sdougm
4624bff34e3Sthurlow /*ARGSUSED*/
4634bff34e3Sthurlow static int
sc_delsect(sa_handle_t handle,int flags,int argc,char * argv[])4644bff34e3Sthurlow sc_delsect(sa_handle_t handle, int flags, int argc, char *argv[])
4654bff34e3Sthurlow {
4664bff34e3Sthurlow char *proto = NULL;
4674bff34e3Sthurlow char *section = NULL;
4684bff34e3Sthurlow sa_protocol_properties_t propset;
4694bff34e3Sthurlow sa_protocol_properties_t propsect;
4704bff34e3Sthurlow int ret = SA_OK;
4714bff34e3Sthurlow int c;
4724bff34e3Sthurlow
4734bff34e3Sthurlow while ((c = getopt(argc, argv, "?h")) != EOF) {
4744bff34e3Sthurlow switch (c) {
4754bff34e3Sthurlow default:
4764bff34e3Sthurlow ret = SA_SYNTAX_ERR;
4774bff34e3Sthurlow /*FALLTHROUGH*/
4784bff34e3Sthurlow case '?':
4794bff34e3Sthurlow case 'h':
4804bff34e3Sthurlow (void) printf(gettext("usage: %s\n"),
4814bff34e3Sthurlow sc_get_usage(USAGE_CTL_DELSECT));
4824bff34e3Sthurlow return (ret);
4834bff34e3Sthurlow }
4844bff34e3Sthurlow /*NOTREACHED*/
4854bff34e3Sthurlow }
4864bff34e3Sthurlow
4874bff34e3Sthurlow section = argv[optind++];
4884bff34e3Sthurlow
4894bff34e3Sthurlow if (optind >= argc) {
4904bff34e3Sthurlow (void) printf(gettext("usage: %s\n"),
4914bff34e3Sthurlow sc_get_usage(USAGE_CTL_DELSECT));
4924bff34e3Sthurlow (void) printf(gettext(
4934bff34e3Sthurlow "\tsection and protocol must be specified.\n"));
4944bff34e3Sthurlow return (SA_INVALID_PROTOCOL);
4954bff34e3Sthurlow }
4964bff34e3Sthurlow
4974bff34e3Sthurlow proto = argv[optind];
4984bff34e3Sthurlow if (!sa_valid_protocol(proto)) {
4994bff34e3Sthurlow (void) printf(gettext("Invalid protocol specified: %s\n"),
5004bff34e3Sthurlow proto);
5014bff34e3Sthurlow return (SA_INVALID_PROTOCOL);
5024bff34e3Sthurlow }
5034bff34e3Sthurlow
5044bff34e3Sthurlow if ((sa_proto_get_featureset(proto) & SA_FEATURE_HAS_SECTIONS) == 0) {
5054bff34e3Sthurlow (void) printf(gettext("Protocol %s does not have sections\n"),
5064bff34e3Sthurlow section, proto);
5074bff34e3Sthurlow return (SA_NOT_SUPPORTED);
5084bff34e3Sthurlow }
5094bff34e3Sthurlow
5104bff34e3Sthurlow propset = sa_proto_get_properties(proto);
5114bff34e3Sthurlow if (propset == NULL) {
5124bff34e3Sthurlow (void) printf(gettext("Cannot get properties for %s\n"),
5134bff34e3Sthurlow proto);
5144bff34e3Sthurlow return (SA_NO_PROPERTIES);
5154bff34e3Sthurlow }
5164bff34e3Sthurlow
5174bff34e3Sthurlow propsect = sa_get_protocol_section(propset, section);
5184bff34e3Sthurlow if (propsect == NULL) {
5194bff34e3Sthurlow (void) printf(gettext("Cannot find section %s for proto %s\n"),
5204bff34e3Sthurlow section, proto);
5214bff34e3Sthurlow return (SA_NO_SUCH_SECTION);
5224bff34e3Sthurlow }
5234bff34e3Sthurlow
5244bff34e3Sthurlow ret = sa_proto_delete_section(proto, section);
5254bff34e3Sthurlow
5264bff34e3Sthurlow return (ret);
5274bff34e3Sthurlow }
5284bff34e3Sthurlow
5296185db85Sdougm static sa_command_t commands[] = {
5306185db85Sdougm {"get", 0, sc_get, USAGE_CTL_GET},
5316185db85Sdougm {"set", 0, sc_set, USAGE_CTL_SET},
5326185db85Sdougm {"status", 0, sc_status, USAGE_CTL_STATUS},
5334bff34e3Sthurlow {"delsect", 0, sc_delsect, USAGE_CTL_DELSECT},
5346185db85Sdougm {NULL, 0, NULL, 0},
5356185db85Sdougm };
5366185db85Sdougm
537549ec3ffSdougm /*ARGSUSED*/
5386185db85Sdougm void
sub_command_help(char * proto)5396185db85Sdougm sub_command_help(char *proto)
5406185db85Sdougm {
5416185db85Sdougm int i;
5426185db85Sdougm
5436185db85Sdougm (void) printf("\tsub-commands:\n");
5446185db85Sdougm for (i = 0; commands[i].cmdname != NULL; i++) {
5456185db85Sdougm if (!(commands[i].flags & (CMD_ALIAS|CMD_NODISPLAY)))
5466185db85Sdougm (void) printf("\t%s\n",
5476185db85Sdougm sc_get_usage((sc_usage_t)commands[i].cmdidx));
5486185db85Sdougm }
5496185db85Sdougm }
5506185db85Sdougm
5516185db85Sdougm sa_command_t *
sa_lookup(char * cmd)5526185db85Sdougm sa_lookup(char *cmd)
5536185db85Sdougm {
5546185db85Sdougm int i;
5556185db85Sdougm size_t len;
5566185db85Sdougm
5576185db85Sdougm len = strlen(cmd);
5586185db85Sdougm for (i = 0; commands[i].cmdname != NULL; i++) {
5596185db85Sdougm if (strncmp(cmd, commands[i].cmdname, len) == 0)
5606185db85Sdougm return (&commands[i]);
5616185db85Sdougm }
5626185db85Sdougm return (NULL);
5636185db85Sdougm }
5646185db85Sdougm
5656185db85Sdougm static int
run_command(char * command,int argc,char * argv[],sa_handle_t handle)566549ec3ffSdougm run_command(char *command, int argc, char *argv[], sa_handle_t handle)
5676185db85Sdougm {
5686185db85Sdougm sa_command_t *cmdvec;
5696185db85Sdougm int ret;
5706185db85Sdougm
5716185db85Sdougm /*
5726185db85Sdougm * To get here, we know there should be a command due to the
5736185db85Sdougm * preprocessing done earlier. Need to find the protocol
5746185db85Sdougm * that is being affected. If no protocol, then it is ALL
5756185db85Sdougm * protocols.
5766185db85Sdougm *
5776185db85Sdougm * ??? do we really need the protocol at this level? it may be
5786185db85Sdougm * sufficient to let the commands look it up if needed since
5796185db85Sdougm * not all commands do proto specific things
5806185db85Sdougm *
5816185db85Sdougm * Known sub-commands are handled at this level. An unknown
5826185db85Sdougm * command will be passed down to the shared object that
5836185db85Sdougm * actually implements it. We can do this since the semantics
5846185db85Sdougm * of the common sub-commands is well defined.
5856185db85Sdougm */
5866185db85Sdougm
5876185db85Sdougm cmdvec = sa_lookup(command);
5886185db85Sdougm if (cmdvec == NULL) {
5896185db85Sdougm (void) printf(gettext("command %s not found\n"), command);
5906185db85Sdougm exit(1);
5916185db85Sdougm }
5926185db85Sdougm /*
5936185db85Sdougm * need to check priviledges and restrict what can be done
5946185db85Sdougm * based on least priviledge and sub-command.
5956185db85Sdougm */
596549ec3ffSdougm ret = cmdvec->cmdfunc(handle, NULL, argc, argv);
5976185db85Sdougm return (ret);
5986185db85Sdougm }
599