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 466185db85Sdougm global_help() 476185db85Sdougm { 486185db85Sdougm (void) printf(gettext("usage: sharectl <command> [options]\n")); 496185db85Sdougm sub_command_help(NULL); 506185db85Sdougm } 516185db85Sdougm 526185db85Sdougm int 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 * 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 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 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 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 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 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 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 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 * 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 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