4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 * Copyright 2012 Milan Jurik. All rights reserved.
26 * Copyright 2016 Nexenta Systems, Inc.
43 static int run_command(char *, int, char **, sa_handle_t
);
44 static void sub_command_help(char *proto
);
49 (void) printf(gettext("usage: sharectl <subcommand> [<options>]\n"));
50 sub_command_help(NULL
);
54 main(int argc
, char *argv
[])
63 * make sure locale and gettext domain is setup
65 (void) setlocale(LC_ALL
, "");
66 (void) textdomain(TEXT_DOMAIN
);
68 handle
= sa_init(SA_INIT_CONTROL_API
);
70 while ((c
= getopt(argc
, argv
, "h?")) != EOF
) {
77 (void) printf(gettext("Invalid option: %c\n"), c
);
80 if (optind
== argc
|| help
) {
88 * now have enough to parse rest of command line
90 command
= argv
[optind
];
91 rval
= run_command(command
, argc
- optind
, argv
+ optind
, handle
);
98 sc_get_usage(sc_usage_t index
)
103 case USAGE_CTL_DELSECT
:
104 ret
= gettext("delsect\t<section> <proto>");
107 ret
= gettext("get\t[-p <property>]... <proto>");
110 ret
= gettext("set\t{-p <property>=<value>}... <proto>");
112 case USAGE_CTL_STATUS
:
113 ret
= gettext("status\t[<proto>]...");
121 sc_get(sa_handle_t handle
, int flags
, int argc
, char *argv
[])
124 struct options
*optlist
= NULL
;
127 sa_protocol_properties_t propset
, propsect
;
129 char *section
, *value
, *name
;
132 while ((c
= getopt(argc
, argv
, "?hp:")) != EOF
) {
135 ret
= add_opt(&optlist
, optarg
, 1);
137 (void) printf(gettext(
138 "Problem with property: %s\n"), optarg
);
139 return (SA_NO_MEMORY
);
143 (void) printf(gettext("usage: %s\n"),
144 sc_get_usage(USAGE_CTL_GET
));
145 return (SA_SYNTAX_ERR
);
148 (void) printf(gettext("usage: %s\n"),
149 sc_get_usage(USAGE_CTL_GET
));
154 if (optind
>= argc
) {
155 (void) printf(gettext("usage: %s\n"),
156 sc_get_usage(USAGE_CTL_GET
));
157 (void) printf(gettext("\tprotocol must be specified.\n"));
158 return (SA_INVALID_PROTOCOL
);
161 proto
= argv
[optind
];
162 if (!sa_valid_protocol(proto
)) {
163 (void) printf(gettext("Invalid protocol specified: %s\n"),
165 return (SA_INVALID_PROTOCOL
);
167 propset
= sa_proto_get_properties(proto
);
171 if (optlist
== NULL
) {
172 /* Display all known properties for this protocol */
173 for (propsect
= sa_get_protocol_section(propset
, NULL
);
175 propsect
= sa_get_next_protocol_section(propsect
, NULL
)) {
176 section
= sa_get_property_attr(propsect
,
179 * If properties are organized into sections, as
180 * in the SMB client, print the section name.
182 if (sa_proto_get_featureset(proto
) &
183 SA_FEATURE_HAS_SECTIONS
) {
187 (void) printf("[%s]\n",
188 section
!= NULL
? section
: "");
191 sa_free_attr_string(section
);
193 /* Display properties for this section */
194 for (prop
= sa_get_protocol_property(propsect
, NULL
);
196 prop
= sa_get_next_protocol_property(prop
, NULL
)) {
198 /* get and display the property and value */
199 name
= sa_get_property_attr(prop
, "type");
201 value
= sa_get_property_attr(prop
,
203 (void) printf(gettext("%s=%s\n"), name
,
204 value
!= NULL
? value
: "");
207 sa_free_attr_string(value
);
209 sa_free_attr_string(name
);
215 /* list the specified option(s) */
216 for (opt
= optlist
; opt
!= NULL
; opt
= opt
->next
) {
219 for (propsect
= sa_get_protocol_section(propset
, NULL
);
221 propsect
= sa_get_next_protocol_section(propsect
,
224 section
= sa_get_property_attr(propsect
,
226 for (prop
= sa_get_protocol_property(propsect
,
229 prop
= sa_get_next_protocol_property(
230 propsect
, opt
->optname
)) {
231 value
= sa_get_property_attr(prop
,
233 if (sa_proto_get_featureset(proto
) &
234 SA_FEATURE_HAS_SECTIONS
) {
236 gettext("[%s] %s=%s\n"),
238 section
: "", opt
->optname
,
239 value
!= NULL
? value
: "");
244 value
!= NULL
? value
: "");
247 sa_free_attr_string(value
);
251 sa_free_attr_string(section
);
254 (void) printf(gettext("%s: not defined\n"),
256 ret
= SA_NO_SUCH_PROP
;
265 sc_set(sa_handle_t handle
, int flags
, int argc
, char *argv
[])
268 struct options
*optlist
= NULL
;
269 sa_protocol_properties_t propsect
;
273 sa_protocol_properties_t propset
;
276 while ((c
= getopt(argc
, argv
, "?hp:")) != EOF
) {
279 ret
= add_opt(&optlist
, optarg
, 0);
281 (void) printf(gettext(
282 "Problem with property: %s\n"), optarg
);
283 return (SA_NO_MEMORY
);
287 (void) printf(gettext("usage: %s\n"),
288 sc_get_usage(USAGE_CTL_SET
));
289 return (SA_SYNTAX_ERR
);
292 (void) printf(gettext("usage: %s\n"),
293 sc_get_usage(USAGE_CTL_SET
));
298 if (optind
>= argc
) {
299 (void) printf(gettext("usage: %s\n"),
300 sc_get_usage(USAGE_CTL_SET
));
301 (void) printf(gettext("\tprotocol must be specified.\n"));
302 return (SA_INVALID_PROTOCOL
);
305 proto
= argv
[optind
];
306 if (!sa_valid_protocol(proto
)) {
307 (void) printf(gettext("Invalid protocol specified: %s\n"),
309 return (SA_INVALID_PROTOCOL
);
311 propset
= sa_proto_get_properties(proto
);
315 if (optlist
== NULL
) {
316 (void) printf(gettext("usage: %s\n"),
317 sc_get_usage(USAGE_CTL_SET
));
318 (void) printf(gettext(
319 "\tat least one property and value "
320 "must be specified\n"));
323 char *section
= NULL
;
324 /* fetch and change the specified option(s) */
325 for (opt
= optlist
; opt
!= NULL
; opt
= opt
->next
) {
326 if (strncmp("section", opt
->optname
, 7) == 0) {
329 section
= strdup(opt
->optvalue
);
332 if (sa_proto_get_featureset(proto
) &
333 SA_FEATURE_HAS_SECTIONS
) {
334 propsect
= sa_get_protocol_section(propset
,
336 prop
= sa_get_protocol_property(propsect
,
339 prop
= sa_get_protocol_property(propset
,
342 if (prop
== NULL
&& sa_proto_get_featureset(proto
) &
343 SA_FEATURE_ADD_PROPERTIES
) {
345 sect
= sa_create_section(section
, NULL
);
346 sa_set_section_attr(sect
, "type", proto
);
347 (void) sa_add_protocol_property(propset
, sect
);
348 prop
= sa_create_property(
349 opt
->optname
, opt
->optvalue
);
350 (void) sa_add_protocol_property(sect
, prop
);
354 * "err" is used in order to prevent
355 * setting ret to SA_OK if there has
356 * been a real error. We want to be
357 * able to return an error status on
358 * exit in that case. Error messages
359 * are printed for each error, so we
360 * only care on exit that there was an
361 * error and not the specific error
364 err
= sa_set_protocol_property(prop
, section
,
367 (void) printf(gettext(
368 "Could not set property"
370 opt
->optname
, sa_errorstr(err
));
374 (void) printf(gettext("%s: not defined\n"),
376 ret
= SA_NO_SUCH_PROP
;
384 show_status(char *proto
)
389 status
= sa_get_protocol_status(proto
);
390 features
= sa_proto_get_featureset(proto
);
391 (void) printf("%s\t%s", proto
, status
? gettext(status
) : "-");
395 * Need to flag a client only protocol so test suites can
396 * remove it from consideration.
398 if (!(features
& SA_FEATURE_SERVER
))
399 (void) printf(" client");
404 valid_proto(char **protos
, int num
, char *proto
)
407 for (i
= 0; i
< num
; i
++)
408 if (strcmp(protos
[i
], proto
) == 0)
415 sc_status(sa_handle_t handle
, int flags
, int argc
, char *argv
[])
424 while ((c
= getopt(argc
, argv
, "?hv")) != EOF
) {
431 (void) printf(gettext("usage: %s\n"),
432 sc_get_usage(USAGE_CTL_STATUS
));
435 (void) printf(gettext("usage: %s\n"),
436 sc_get_usage(USAGE_CTL_STATUS
));
437 return (SA_SYNTAX_ERR
);
441 num_proto
= sa_get_protocols(&protos
);
442 if (optind
== argc
) {
443 /* status for all protocols */
444 for (i
= 0; i
< num_proto
; i
++) {
445 show_status(protos
[i
]);
448 for (i
= optind
; i
< argc
; i
++) {
449 if (valid_proto(protos
, num_proto
, argv
[i
])) {
450 show_status(argv
[i
]);
452 (void) printf(gettext("Invalid protocol: %s\n"),
454 ret
= SA_INVALID_PROTOCOL
;
465 sc_delsect(sa_handle_t handle
, int flags
, int argc
, char *argv
[])
468 char *section
= NULL
;
469 sa_protocol_properties_t propset
;
470 sa_protocol_properties_t propsect
;
474 while ((c
= getopt(argc
, argv
, "?h")) != EOF
) {
481 (void) printf(gettext("usage: %s\n"),
482 sc_get_usage(USAGE_CTL_DELSECT
));
488 section
= argv
[optind
++];
490 if (optind
>= argc
) {
491 (void) printf(gettext("usage: %s\n"),
492 sc_get_usage(USAGE_CTL_DELSECT
));
493 (void) printf(gettext(
494 "\tsection and protocol must be specified.\n"));
495 return (SA_INVALID_PROTOCOL
);
498 proto
= argv
[optind
];
499 if (!sa_valid_protocol(proto
)) {
500 (void) printf(gettext("Invalid protocol specified: %s\n"),
502 return (SA_INVALID_PROTOCOL
);
505 if ((sa_proto_get_featureset(proto
) & SA_FEATURE_HAS_SECTIONS
) == 0) {
506 (void) printf(gettext("Protocol %s does not have sections\n"),
508 return (SA_NOT_SUPPORTED
);
511 propset
= sa_proto_get_properties(proto
);
512 if (propset
== NULL
) {
513 (void) printf(gettext("Cannot get properties for %s\n"),
515 return (SA_NO_PROPERTIES
);
518 propsect
= sa_get_protocol_section(propset
, section
);
519 if (propsect
== NULL
) {
520 (void) printf(gettext("Cannot find section %s for proto %s\n"),
522 return (SA_NO_SUCH_SECTION
);
525 ret
= sa_proto_delete_section(proto
, section
);
530 static sa_command_t commands
[] = {
531 {"delsect", 0, sc_delsect
, USAGE_CTL_DELSECT
},
532 {"get", 0, sc_get
, USAGE_CTL_GET
},
533 {"set", 0, sc_set
, USAGE_CTL_SET
},
534 {"status", 0, sc_status
, USAGE_CTL_STATUS
},
540 sub_command_help(char *proto
)
544 for (i
= 0; commands
[i
].cmdname
!= NULL
; i
++) {
545 if (!(commands
[i
].flags
& (CMD_ALIAS
|CMD_NODISPLAY
)))
546 (void) printf("\t%s\n",
547 sc_get_usage((sc_usage_t
)commands
[i
].cmdidx
));
558 for (i
= 0; commands
[i
].cmdname
!= NULL
; i
++) {
559 if (strncmp(cmd
, commands
[i
].cmdname
, len
) == 0)
560 return (&commands
[i
]);
566 run_command(char *command
, int argc
, char *argv
[], sa_handle_t handle
)
568 sa_command_t
*cmdvec
;
572 * To get here, we know there should be a command due to the
573 * preprocessing done earlier. Need to find the protocol
574 * that is being affected. If no protocol, then it is ALL
577 * ??? do we really need the protocol at this level? it may be
578 * sufficient to let the commands look it up if needed since
579 * not all commands do proto specific things
581 * Known sub-commands are handled at this level. An unknown
582 * command will be passed down to the shared object that
583 * actually implements it. We can do this since the semantics
584 * of the common sub-commands is well defined.
587 cmdvec
= sa_lookup(command
);
588 if (cmdvec
== NULL
) {
589 (void) printf(gettext("command %s not found\n"), command
);
593 * need to check priviledges and restrict what can be done
594 * based on least priviledge and sub-command.
596 ret
= cmdvec
->cmdfunc(handle
, NULL
, argc
, argv
);