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 /* 236007Sthurlow * 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; 1126007Sthurlow case USAGE_CTL_DELSECT: 1136007Sthurlow ret = gettext("delsect [-h] section proto"); 1146007Sthurlow 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; 1276007Sthurlow sa_protocol_properties_t propset, propsect; 1286007Sthurlow sa_property_t prop; 1296007Sthurlow char *section, *value, *name; 1306007Sthurlow 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]; 1636007Sthurlow if (!sa_valid_protocol(proto)) { 1646007Sthurlow (void) printf(gettext("Invalid protocol specified: %s\n"), 1656007Sthurlow proto); 1666007Sthurlow return (SA_INVALID_PROTOCOL); 1676007Sthurlow } 1686007Sthurlow propset = sa_proto_get_properties(proto); 1696007Sthurlow if (propset == NULL) 1706007Sthurlow return (ret); 1713034Sdougm 1726007Sthurlow if (optlist == NULL) { 1736007Sthurlow /* Display all known properties for this protocol */ 1746007Sthurlow for (propsect = sa_get_protocol_section(propset, NULL); 1756007Sthurlow propsect != NULL; 1766007Sthurlow propsect = sa_get_next_protocol_section(propsect, NULL)) { 1776007Sthurlow section = sa_get_property_attr(propsect, 1786007Sthurlow "name"); 1796007Sthurlow /* 1806007Sthurlow * If properties are organized into sections, as 1816007Sthurlow * in the SMB client, print the section name. 1826007Sthurlow */ 1836007Sthurlow if (sa_proto_get_featureset(proto) & 1846007Sthurlow SA_FEATURE_HAS_SECTIONS) { 1856007Sthurlow if (!first) 1866007Sthurlow (void) printf("\n"); 1876007Sthurlow first = 0; 1886007Sthurlow (void) printf("[%s]\n", section); 1896007Sthurlow } 1906007Sthurlow /* Display properties for this section */ 1916007Sthurlow for (prop = sa_get_protocol_property(propsect, NULL); 1926007Sthurlow prop != NULL; 1936007Sthurlow prop = sa_get_next_protocol_property(prop, NULL)) { 1946007Sthurlow 1956007Sthurlow /* get and display the property and value */ 1966007Sthurlow name = sa_get_property_attr(prop, "type"); 1976007Sthurlow if (name != NULL) { 1986007Sthurlow value = sa_get_property_attr(prop, 1996007Sthurlow "value"); 2006007Sthurlow (void) printf(gettext("%s=%s\n"), name, 2016007Sthurlow value != NULL ? value : ""); 2024653Sdougm } 2036007Sthurlow if (value != NULL) 2046007Sthurlow sa_free_attr_string(value); 2056007Sthurlow if (name != NULL) 2066007Sthurlow sa_free_attr_string(name); 2073034Sdougm } 2083034Sdougm } 2093034Sdougm } else { 2106007Sthurlow struct options *opt; 2116007Sthurlow 2126007Sthurlow /* list the specified option(s) */ 2136007Sthurlow for (opt = optlist; opt != NULL; opt = opt->next) { 2146007Sthurlow int printed = 0; 2156007Sthurlow 2166007Sthurlow for (propsect = sa_get_protocol_section(propset, NULL); 2176007Sthurlow propsect != NULL; 2186007Sthurlow propsect = sa_get_next_protocol_section(propsect, 2196007Sthurlow NULL)) { 2206007Sthurlow 2216007Sthurlow section = sa_get_property_attr(propsect, 2226007Sthurlow "name"); 2236007Sthurlow for (prop = sa_get_protocol_property(propsect, 2246007Sthurlow opt->optname); 2256007Sthurlow prop != NULL; 2266007Sthurlow prop = sa_get_next_protocol_property( 2276007Sthurlow propsect, opt->optname)) { 2286007Sthurlow value = sa_get_property_attr(prop, 2296007Sthurlow "value"); 2306007Sthurlow if (sa_proto_get_featureset(proto) & 2316007Sthurlow SA_FEATURE_HAS_SECTIONS) { 2326007Sthurlow (void) printf( 2336007Sthurlow gettext("[%s] %s=%s\n"), 2346007Sthurlow section, opt->optname, 2356007Sthurlow value != NULL ? value : ""); 2366007Sthurlow sa_free_attr_string(section); 2376007Sthurlow } else { 2386007Sthurlow (void) printf( 2396007Sthurlow gettext("%s=%s\n"), 2406007Sthurlow opt->optname, 2416007Sthurlow value != NULL ? value : ""); 2426007Sthurlow } 2436007Sthurlow sa_free_attr_string(value); 2446007Sthurlow printed = 1; 2456007Sthurlow } 2466007Sthurlow } 2476007Sthurlow if (!printed) { 2486007Sthurlow (void) printf(gettext("%s: not defined\n"), 2496007Sthurlow opt->optname); 2506007Sthurlow ret = SA_NO_SUCH_PROP; 2516007Sthurlow } 2526007Sthurlow } 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; 2636007Sthurlow sa_protocol_properties_t propsect; 2643034Sdougm int ret = SA_OK; 2653034Sdougm int c; 2666007Sthurlow int err; 2674653Sdougm sa_protocol_properties_t propset; 2686007Sthurlow 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); 3076007Sthurlow if (propset == NULL) 3086007Sthurlow return (ret); 3096007Sthurlow 3106007Sthurlow if (optlist == NULL) { 3116007Sthurlow (void) printf(gettext("usage: %s\n"), 3126007Sthurlow sc_get_usage(USAGE_CTL_SET)); 3136007Sthurlow (void) printf(gettext( 3146007Sthurlow "\tat least one property and value " 3156007Sthurlow "must be specified\n")); 3166007Sthurlow } else { 3176007Sthurlow struct options *opt; 3186007Sthurlow char *section = NULL; 3196007Sthurlow /* fetch and change the specified option(s) */ 3206007Sthurlow for (opt = optlist; opt != NULL; opt = opt->next) { 3216007Sthurlow if (strncmp("section", opt->optname, 7) == 0) { 3226007Sthurlow if (section != NULL) 3236007Sthurlow free(section); 3246007Sthurlow section = strdup(opt->optvalue); 3256007Sthurlow continue; 3266007Sthurlow } 3276007Sthurlow if (sa_proto_get_featureset(proto) & 3286007Sthurlow SA_FEATURE_HAS_SECTIONS) { 3296007Sthurlow propsect = sa_get_protocol_section(propset, 3306007Sthurlow section); 3316007Sthurlow prop = sa_get_protocol_property(propsect, 3326007Sthurlow opt->optname); 3336007Sthurlow } else { 3346007Sthurlow prop = sa_get_protocol_property(propset, 3356007Sthurlow opt->optname); 3366007Sthurlow } 3376007Sthurlow if (prop == NULL && sa_proto_get_featureset(proto) & 3386007Sthurlow SA_FEATURE_ADD_PROPERTIES) { 3396007Sthurlow sa_property_t sect; 3406007Sthurlow sect = sa_create_section(section, NULL); 3416007Sthurlow sa_set_section_attr(sect, "type", proto); 3426007Sthurlow (void) sa_add_protocol_property(propset, sect); 3436007Sthurlow prop = sa_create_property( 3446007Sthurlow opt->optname, opt->optvalue); 3456007Sthurlow (void) sa_add_protocol_property(sect, prop); 3466007Sthurlow } 3476007Sthurlow if (prop != NULL) { 3486007Sthurlow /* 3496007Sthurlow * "err" is used in order to prevent 3506007Sthurlow * setting ret to SA_OK if there has 3516007Sthurlow * been a real error. We want to be 3526007Sthurlow * able to return an error status on 3536007Sthurlow * exit in that case. Error messages 3546007Sthurlow * are printed for each error, so we 3556007Sthurlow * only care on exit that there was an 3566007Sthurlow * error and not the specific error 3576007Sthurlow * value. 3586007Sthurlow */ 3596007Sthurlow err = sa_set_protocol_property(prop, section, 3606007Sthurlow opt->optvalue); 3616007Sthurlow if (err != SA_OK) { 3624653Sdougm (void) printf(gettext( 3636007Sthurlow "Could not set property" 3646007Sthurlow " %s: %s\n"), 3656007Sthurlow opt->optname, sa_errorstr(err)); 3666007Sthurlow ret = err; 3674653Sdougm } 3686007Sthurlow } else { 3696007Sthurlow (void) printf(gettext("%s: not defined\n"), 3706007Sthurlow opt->optname); 3716007Sthurlow 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; 382*6088Sdougm uint64_t features; 3834653Sdougm 3843034Sdougm status = sa_get_protocol_status(proto); 385*6088Sdougm features = sa_proto_get_featureset(proto); 386*6088Sdougm (void) printf("%s\t%s", proto, status ? gettext(status) : "-"); 3873034Sdougm if (status != NULL) 3884653Sdougm free(status); 389*6088Sdougm /* 390*6088Sdougm * Need to flag a client only protocol so test suites can 391*6088Sdougm * remove it from consideration. 392*6088Sdougm */ 393*6088Sdougm if (!(features & SA_FEATURE_SERVER)) 394*6088Sdougm (void) printf(" client"); 395*6088Sdougm (void) printf("\n"); 3963034Sdougm } 3973034Sdougm 3983034Sdougm static int 3993034Sdougm valid_proto(char **protos, int num, char *proto) 4003034Sdougm { 4013034Sdougm int i; 4023034Sdougm for (i = 0; i < num; i++) 4034653Sdougm if (strcmp(protos[i], proto) == 0) 4044653Sdougm return (1); 4053034Sdougm return (0); 4063034Sdougm } 4073034Sdougm 4083910Sdougm /*ARGSUSED*/ 4093034Sdougm static int 4103910Sdougm sc_status(sa_handle_t handle, int flags, int argc, char *argv[]) 4113034Sdougm { 4123034Sdougm char **protos; 4133034Sdougm int ret = SA_OK; 4143034Sdougm int c; 4153034Sdougm int i; 4163034Sdougm int num_proto; 4173034Sdougm int verbose = 0; 4183034Sdougm 4193034Sdougm while ((c = getopt(argc, argv, "?hv")) != EOF) { 4204653Sdougm switch (c) { 4214653Sdougm case 'v': 4224653Sdougm verbose++; 4234653Sdougm break; 4244653Sdougm case '?': 4254653Sdougm case 'h': 4264653Sdougm (void) printf(gettext("usage: %s\n"), 4274653Sdougm sc_get_usage(USAGE_CTL_STATUS)); 4284653Sdougm return (SA_OK); 4294653Sdougm default: 4304653Sdougm (void) printf(gettext("usage: %s\n"), 4314653Sdougm sc_get_usage(USAGE_CTL_STATUS)); 4324653Sdougm return (SA_SYNTAX_ERR); 4334653Sdougm } 4343034Sdougm } 4353034Sdougm 4363034Sdougm num_proto = sa_get_protocols(&protos); 4373034Sdougm if (optind == argc) { 4384653Sdougm /* status for all protocols */ 4394653Sdougm for (i = 0; i < num_proto; i++) { 4404653Sdougm show_status(protos[i]); 4414653Sdougm } 4423034Sdougm } else { 4434653Sdougm for (i = optind; i < argc; i++) { 4444653Sdougm if (valid_proto(protos, num_proto, argv[i])) { 4454653Sdougm show_status(argv[i]); 4464653Sdougm } else { 4474653Sdougm (void) printf(gettext("Invalid protocol: %s\n"), 4484653Sdougm argv[i]); 4494653Sdougm ret = SA_INVALID_PROTOCOL; 4504653Sdougm } 4513034Sdougm } 4523034Sdougm } 4533034Sdougm if (protos != NULL) 4544653Sdougm free(protos); 4553034Sdougm return (ret); 4563034Sdougm } 4573034Sdougm 4586007Sthurlow /*ARGSUSED*/ 4596007Sthurlow static int 4606007Sthurlow sc_delsect(sa_handle_t handle, int flags, int argc, char *argv[]) 4616007Sthurlow { 4626007Sthurlow char *proto = NULL; 4636007Sthurlow char *section = NULL; 4646007Sthurlow sa_protocol_properties_t propset; 4656007Sthurlow sa_protocol_properties_t propsect; 4666007Sthurlow int ret = SA_OK; 4676007Sthurlow int c; 4686007Sthurlow 4696007Sthurlow while ((c = getopt(argc, argv, "?h")) != EOF) { 4706007Sthurlow switch (c) { 4716007Sthurlow default: 4726007Sthurlow ret = SA_SYNTAX_ERR; 4736007Sthurlow /*FALLTHROUGH*/ 4746007Sthurlow case '?': 4756007Sthurlow case 'h': 4766007Sthurlow (void) printf(gettext("usage: %s\n"), 4776007Sthurlow sc_get_usage(USAGE_CTL_DELSECT)); 4786007Sthurlow return (ret); 4796007Sthurlow } 4806007Sthurlow /*NOTREACHED*/ 4816007Sthurlow } 4826007Sthurlow 4836007Sthurlow section = argv[optind++]; 4846007Sthurlow 4856007Sthurlow if (optind >= argc) { 4866007Sthurlow (void) printf(gettext("usage: %s\n"), 4876007Sthurlow sc_get_usage(USAGE_CTL_DELSECT)); 4886007Sthurlow (void) printf(gettext( 4896007Sthurlow "\tsection and protocol must be specified.\n")); 4906007Sthurlow return (SA_INVALID_PROTOCOL); 4916007Sthurlow } 4926007Sthurlow 4936007Sthurlow proto = argv[optind]; 4946007Sthurlow if (!sa_valid_protocol(proto)) { 4956007Sthurlow (void) printf(gettext("Invalid protocol specified: %s\n"), 4966007Sthurlow proto); 4976007Sthurlow return (SA_INVALID_PROTOCOL); 4986007Sthurlow } 4996007Sthurlow 5006007Sthurlow if ((sa_proto_get_featureset(proto) & SA_FEATURE_HAS_SECTIONS) == 0) { 5016007Sthurlow (void) printf(gettext("Protocol %s does not have sections\n"), 5026007Sthurlow section, proto); 5036007Sthurlow return (SA_NOT_SUPPORTED); 5046007Sthurlow } 5056007Sthurlow 5066007Sthurlow propset = sa_proto_get_properties(proto); 5076007Sthurlow if (propset == NULL) { 5086007Sthurlow (void) printf(gettext("Cannot get properties for %s\n"), 5096007Sthurlow proto); 5106007Sthurlow return (SA_NO_PROPERTIES); 5116007Sthurlow } 5126007Sthurlow 5136007Sthurlow propsect = sa_get_protocol_section(propset, section); 5146007Sthurlow if (propsect == NULL) { 5156007Sthurlow (void) printf(gettext("Cannot find section %s for proto %s\n"), 5166007Sthurlow section, proto); 5176007Sthurlow return (SA_NO_SUCH_SECTION); 5186007Sthurlow } 5196007Sthurlow 5206007Sthurlow ret = sa_proto_delete_section(proto, section); 5216007Sthurlow 5226007Sthurlow return (ret); 5236007Sthurlow } 5246007Sthurlow 5253034Sdougm static sa_command_t commands[] = { 5263034Sdougm {"get", 0, sc_get, USAGE_CTL_GET}, 5273034Sdougm {"set", 0, sc_set, USAGE_CTL_SET}, 5283034Sdougm {"status", 0, sc_status, USAGE_CTL_STATUS}, 5296007Sthurlow {"delsect", 0, sc_delsect, USAGE_CTL_DELSECT}, 5303034Sdougm {NULL, 0, NULL, 0}, 5313034Sdougm }; 5323034Sdougm 5333910Sdougm /*ARGSUSED*/ 5343034Sdougm void 5353034Sdougm sub_command_help(char *proto) 5363034Sdougm { 5373034Sdougm int i; 5383034Sdougm 5393034Sdougm (void) printf("\tsub-commands:\n"); 5403034Sdougm for (i = 0; commands[i].cmdname != NULL; i++) { 5413034Sdougm if (!(commands[i].flags & (CMD_ALIAS|CMD_NODISPLAY))) 5423034Sdougm (void) printf("\t%s\n", 5434653Sdougm sc_get_usage((sc_usage_t)commands[i].cmdidx)); 5443034Sdougm } 5453034Sdougm } 5463034Sdougm 5473034Sdougm sa_command_t * 5483034Sdougm sa_lookup(char *cmd) 5493034Sdougm { 5503034Sdougm int i; 5513034Sdougm size_t len; 5523034Sdougm 5533034Sdougm len = strlen(cmd); 5543034Sdougm for (i = 0; commands[i].cmdname != NULL; i++) { 5553034Sdougm if (strncmp(cmd, commands[i].cmdname, len) == 0) 5563034Sdougm return (&commands[i]); 5573034Sdougm } 5583034Sdougm return (NULL); 5593034Sdougm } 5603034Sdougm 5613034Sdougm static int 5623910Sdougm run_command(char *command, int argc, char *argv[], sa_handle_t handle) 5633034Sdougm { 5643034Sdougm sa_command_t *cmdvec; 5653034Sdougm int ret; 5663034Sdougm 5673034Sdougm /* 5683034Sdougm * To get here, we know there should be a command due to the 5693034Sdougm * preprocessing done earlier. Need to find the protocol 5703034Sdougm * that is being affected. If no protocol, then it is ALL 5713034Sdougm * protocols. 5723034Sdougm * 5733034Sdougm * ??? do we really need the protocol at this level? it may be 5743034Sdougm * sufficient to let the commands look it up if needed since 5753034Sdougm * not all commands do proto specific things 5763034Sdougm * 5773034Sdougm * Known sub-commands are handled at this level. An unknown 5783034Sdougm * command will be passed down to the shared object that 5793034Sdougm * actually implements it. We can do this since the semantics 5803034Sdougm * of the common sub-commands is well defined. 5813034Sdougm */ 5823034Sdougm 5833034Sdougm cmdvec = sa_lookup(command); 5843034Sdougm if (cmdvec == NULL) { 5853034Sdougm (void) printf(gettext("command %s not found\n"), command); 5863034Sdougm exit(1); 5873034Sdougm } 5883034Sdougm /* 5893034Sdougm * need to check priviledges and restrict what can be done 5903034Sdougm * based on least priviledge and sub-command. 5913034Sdougm */ 5923910Sdougm ret = cmdvec->cmdfunc(handle, NULL, argc, argv); 5933034Sdougm return (ret); 5943034Sdougm } 595