xref: /titanic_52/usr/src/cmd/dfs.cmds/sharectl/sharectl.c (revision 6185db853e024a486ff8837e6784dd290d866112)
1*6185db85Sdougm /*
2*6185db85Sdougm  * CDDL HEADER START
3*6185db85Sdougm  *
4*6185db85Sdougm  * The contents of this file are subject to the terms of the
5*6185db85Sdougm  * Common Development and Distribution License (the "License").
6*6185db85Sdougm  * You may not use this file except in compliance with the License.
7*6185db85Sdougm  *
8*6185db85Sdougm  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*6185db85Sdougm  * or http://www.opensolaris.org/os/licensing.
10*6185db85Sdougm  * See the License for the specific language governing permissions
11*6185db85Sdougm  * and limitations under the License.
12*6185db85Sdougm  *
13*6185db85Sdougm  * When distributing Covered Code, include this CDDL HEADER in each
14*6185db85Sdougm  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*6185db85Sdougm  * If applicable, add the following below this CDDL HEADER, with the
16*6185db85Sdougm  * fields enclosed by brackets "[]" replaced with your own identifying
17*6185db85Sdougm  * information: Portions Copyright [yyyy] [name of copyright owner]
18*6185db85Sdougm  *
19*6185db85Sdougm  * CDDL HEADER END
20*6185db85Sdougm  */
21*6185db85Sdougm 
22*6185db85Sdougm /*
23*6185db85Sdougm  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
24*6185db85Sdougm  * Use is subject to license terms.
25*6185db85Sdougm  */
26*6185db85Sdougm 
27*6185db85Sdougm #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*6185db85Sdougm 
29*6185db85Sdougm #include <stdlib.h>
30*6185db85Sdougm #include <stdio.h>
31*6185db85Sdougm #include <string.h>
32*6185db85Sdougm #include <ctype.h>
33*6185db85Sdougm #include <unistd.h>
34*6185db85Sdougm #include <getopt.h>
35*6185db85Sdougm #include <libgen.h>
36*6185db85Sdougm 
37*6185db85Sdougm #include "libshare.h"
38*6185db85Sdougm #include <sharemgr.h>
39*6185db85Sdougm 
40*6185db85Sdougm #include <libintl.h>
41*6185db85Sdougm #include <locale.h>
42*6185db85Sdougm 
43*6185db85Sdougm static int run_command(char *, int, char **);
44*6185db85Sdougm static void sub_command_help(char *proto);
45*6185db85Sdougm 
46*6185db85Sdougm static void
47*6185db85Sdougm global_help()
48*6185db85Sdougm {
49*6185db85Sdougm 	(void) printf(gettext("usage: sharectl <command> [options]\n"));
50*6185db85Sdougm 	sub_command_help(NULL);
51*6185db85Sdougm }
52*6185db85Sdougm 
53*6185db85Sdougm int
54*6185db85Sdougm main(int argc, char *argv[])
55*6185db85Sdougm {
56*6185db85Sdougm 	int c;
57*6185db85Sdougm 	int help = 0;
58*6185db85Sdougm 	int rval;
59*6185db85Sdougm 	char *command;
60*6185db85Sdougm 
61*6185db85Sdougm 	/*
62*6185db85Sdougm 	 * make sure locale and gettext domain is setup
63*6185db85Sdougm 	 */
64*6185db85Sdougm 	(void) setlocale(LC_ALL, "");
65*6185db85Sdougm 	(void) textdomain(TEXT_DOMAIN);
66*6185db85Sdougm 
67*6185db85Sdougm 	sa_init(SA_INIT_CONTROL_API);
68*6185db85Sdougm 
69*6185db85Sdougm 	while ((c = getopt(argc, argv, "h?")) != EOF) {
70*6185db85Sdougm 	    switch (c) {
71*6185db85Sdougm 	    case '?':
72*6185db85Sdougm 	    case 'h':
73*6185db85Sdougm 		help = 1;
74*6185db85Sdougm 		break;
75*6185db85Sdougm 	    default:
76*6185db85Sdougm 		(void) printf(gettext("Invalid option: %c\n"), c);
77*6185db85Sdougm 	    }
78*6185db85Sdougm 	}
79*6185db85Sdougm 	if (optind == argc || help) {
80*6185db85Sdougm 	    /* no subcommand */
81*6185db85Sdougm 	    global_help();
82*6185db85Sdougm 	    exit(0);
83*6185db85Sdougm 	}
84*6185db85Sdougm 	optind = 1;
85*6185db85Sdougm 
86*6185db85Sdougm 	/*
87*6185db85Sdougm 	 * now have enough to parse rest of command line
88*6185db85Sdougm 	 */
89*6185db85Sdougm 	command = argv[optind];
90*6185db85Sdougm 	rval = run_command(command, argc - optind, argv + optind);
91*6185db85Sdougm 
92*6185db85Sdougm 	sa_fini();
93*6185db85Sdougm 	return (rval);
94*6185db85Sdougm }
95*6185db85Sdougm 
96*6185db85Sdougm char *
97*6185db85Sdougm sc_get_usage(sc_usage_t index)
98*6185db85Sdougm {
99*6185db85Sdougm 	char *ret = NULL;
100*6185db85Sdougm 
101*6185db85Sdougm 	switch (index) {
102*6185db85Sdougm 	case USAGE_CTL_GET:
103*6185db85Sdougm 	    ret = gettext("get [-h] -p property ... proto");
104*6185db85Sdougm 	    break;
105*6185db85Sdougm 	case USAGE_CTL_SET:
106*6185db85Sdougm 	    ret = gettext("set [-h] -p property=value ... proto");
107*6185db85Sdougm 	    break;
108*6185db85Sdougm 	case USAGE_CTL_STATUS:
109*6185db85Sdougm 	    ret = gettext("status -h | proto...");
110*6185db85Sdougm 	    break;
111*6185db85Sdougm 	}
112*6185db85Sdougm 	return (ret);
113*6185db85Sdougm }
114*6185db85Sdougm 
115*6185db85Sdougm static int
116*6185db85Sdougm sc_get(int flags, int argc, char *argv[])
117*6185db85Sdougm {
118*6185db85Sdougm 	char *proto = NULL;
119*6185db85Sdougm 	struct options *optlist = NULL;
120*6185db85Sdougm 	int ret = SA_OK;
121*6185db85Sdougm 	int c;
122*6185db85Sdougm #ifdef lint
123*6185db85Sdougm 	flags = flags;
124*6185db85Sdougm #endif
125*6185db85Sdougm 
126*6185db85Sdougm 	while ((c = getopt(argc, argv, "?hp:")) != EOF) {
127*6185db85Sdougm 	    switch (c) {
128*6185db85Sdougm 	    case 'p':
129*6185db85Sdougm 		ret = add_opt(&optlist, optarg, 1);
130*6185db85Sdougm 		if (ret != SA_OK) {
131*6185db85Sdougm 		    (void) printf(gettext("Problem with property: %s\n"),
132*6185db85Sdougm 						optarg);
133*6185db85Sdougm 		    return (SA_NO_MEMORY);
134*6185db85Sdougm 		}
135*6185db85Sdougm 		break;
136*6185db85Sdougm 	    default:
137*6185db85Sdougm 		(void) printf(gettext("usage: %s\n"),
138*6185db85Sdougm 				sc_get_usage(USAGE_CTL_GET));
139*6185db85Sdougm 		return (SA_SYNTAX_ERR);
140*6185db85Sdougm 	    case '?':
141*6185db85Sdougm 	    case 'h':
142*6185db85Sdougm 		(void) printf(gettext("usage: %s\n"),
143*6185db85Sdougm 				sc_get_usage(USAGE_CTL_GET));
144*6185db85Sdougm 		return (SA_OK);
145*6185db85Sdougm 		break;
146*6185db85Sdougm 	    }
147*6185db85Sdougm 	}
148*6185db85Sdougm 
149*6185db85Sdougm 	if (optind >= argc) {
150*6185db85Sdougm 	    (void) printf(gettext("usage: %s\n"), sc_get_usage(USAGE_CTL_GET));
151*6185db85Sdougm 	    (void) printf(gettext("\tprotocol must be specified.\n"));
152*6185db85Sdougm 	    return (SA_INVALID_PROTOCOL);
153*6185db85Sdougm 	}
154*6185db85Sdougm 
155*6185db85Sdougm 	proto = argv[optind];
156*6185db85Sdougm 	if (sa_valid_protocol(proto)) {
157*6185db85Sdougm 	    sa_protocol_properties_t propset;
158*6185db85Sdougm 	    propset = sa_proto_get_properties(proto);
159*6185db85Sdougm 	    if (propset != NULL) {
160*6185db85Sdougm 		sa_property_t prop;
161*6185db85Sdougm 		char *value;
162*6185db85Sdougm 		char *name;
163*6185db85Sdougm 		if (optlist == NULL) {
164*6185db85Sdougm 		    /* display all known properties for this protocol */
165*6185db85Sdougm 		    for (prop = sa_get_protocol_property(propset, NULL);
166*6185db85Sdougm 			prop != NULL;
167*6185db85Sdougm 			prop = sa_get_next_protocol_property(prop)) {
168*6185db85Sdougm 
169*6185db85Sdougm 			/* get and display the property and value */
170*6185db85Sdougm 			name = sa_get_property_attr(prop, "type");
171*6185db85Sdougm 			if (name != NULL) {
172*6185db85Sdougm 			    value = sa_get_property_attr(prop, "value");
173*6185db85Sdougm 			    (void) printf(gettext("%s=%s\n"), name,
174*6185db85Sdougm 						value != NULL ? value : "");
175*6185db85Sdougm 			}
176*6185db85Sdougm 			if (value != NULL)
177*6185db85Sdougm 			    sa_free_attr_string(value);
178*6185db85Sdougm 			if (name != NULL)
179*6185db85Sdougm 			    sa_free_attr_string(name);
180*6185db85Sdougm 		    }
181*6185db85Sdougm 		} else {
182*6185db85Sdougm 		    struct options *opt;
183*6185db85Sdougm 		    /* list the specified option(s) */
184*6185db85Sdougm 		    for (opt = optlist; opt != NULL; opt = opt->next) {
185*6185db85Sdougm 			prop = sa_get_protocol_property(propset, opt->optname);
186*6185db85Sdougm 			if (prop != NULL) {
187*6185db85Sdougm 			    value = sa_get_property_attr(prop, "value");
188*6185db85Sdougm 			    (void) printf(gettext("%s=%s\n"), opt->optname,
189*6185db85Sdougm 					value != NULL ? value : "");
190*6185db85Sdougm 			    sa_free_attr_string(value);
191*6185db85Sdougm 			} else {
192*6185db85Sdougm 			    (void) printf(gettext("%s: not defined\n"),
193*6185db85Sdougm 						opt->optname);
194*6185db85Sdougm 			}
195*6185db85Sdougm 		    }
196*6185db85Sdougm 		}
197*6185db85Sdougm 	    }
198*6185db85Sdougm 	} else {
199*6185db85Sdougm 	    (void) printf(gettext("Invalid protocol specified: %s\n"), proto);
200*6185db85Sdougm 	    ret = SA_INVALID_PROTOCOL;
201*6185db85Sdougm 	}
202*6185db85Sdougm 	return (ret);
203*6185db85Sdougm }
204*6185db85Sdougm 
205*6185db85Sdougm static int
206*6185db85Sdougm sc_set(int flags, int argc, char *argv[])
207*6185db85Sdougm {
208*6185db85Sdougm 	char *proto = NULL;
209*6185db85Sdougm 	struct options *optlist = NULL;
210*6185db85Sdougm 	int ret = SA_OK;
211*6185db85Sdougm 	int c;
212*6185db85Sdougm #ifdef lint
213*6185db85Sdougm 	flags = flags;
214*6185db85Sdougm #endif
215*6185db85Sdougm 
216*6185db85Sdougm 	while ((c = getopt(argc, argv, "?hp:")) != EOF) {
217*6185db85Sdougm 	    switch (c) {
218*6185db85Sdougm 	    case 'p':
219*6185db85Sdougm 		ret = add_opt(&optlist, optarg, 0);
220*6185db85Sdougm 		if (ret != SA_OK) {
221*6185db85Sdougm 		    (void) printf(gettext("Problem with property: %s\n"),
222*6185db85Sdougm 					optarg);
223*6185db85Sdougm 		    return (SA_NO_MEMORY);
224*6185db85Sdougm 		}
225*6185db85Sdougm 		break;
226*6185db85Sdougm 	    default:
227*6185db85Sdougm 		(void) printf(gettext("usage: %s\n"),
228*6185db85Sdougm 				sc_get_usage(USAGE_CTL_SET));
229*6185db85Sdougm 		return (SA_SYNTAX_ERR);
230*6185db85Sdougm 	    case '?':
231*6185db85Sdougm 	    case 'h':
232*6185db85Sdougm 		(void) printf(gettext("usage: %s\n"),
233*6185db85Sdougm 				sc_get_usage(USAGE_CTL_SET));
234*6185db85Sdougm 		return (SA_OK);
235*6185db85Sdougm 		break;
236*6185db85Sdougm 	    }
237*6185db85Sdougm 	}
238*6185db85Sdougm 
239*6185db85Sdougm 	if (optind >= argc) {
240*6185db85Sdougm 	    (void) printf(gettext("usage: %s\n"),
241*6185db85Sdougm 				sc_get_usage(USAGE_CTL_SET));
242*6185db85Sdougm 	    (void) printf(gettext("\tprotocol must be specified.\n"));
243*6185db85Sdougm 	    return (SA_INVALID_PROTOCOL);
244*6185db85Sdougm 	}
245*6185db85Sdougm 
246*6185db85Sdougm 	proto = argv[optind];
247*6185db85Sdougm 	if (sa_valid_protocol(proto)) {
248*6185db85Sdougm 	    sa_protocol_properties_t propset;
249*6185db85Sdougm 	    propset = sa_proto_get_properties(proto);
250*6185db85Sdougm 	    if (propset != NULL) {
251*6185db85Sdougm 		sa_property_t prop;
252*6185db85Sdougm 
253*6185db85Sdougm 		if (optlist == NULL) {
254*6185db85Sdougm 		    (void) printf(gettext("usage: %s\n"),
255*6185db85Sdougm 				sc_get_usage(USAGE_CTL_SET));
256*6185db85Sdougm 		    (void) printf(gettext("\tat least one property and value "
257*6185db85Sdougm 				    "must be specified\n"));
258*6185db85Sdougm 		} else {
259*6185db85Sdougm 		    struct options *opt;
260*6185db85Sdougm 		    /* list the specified option(s) */
261*6185db85Sdougm 		    for (opt = optlist; opt != NULL; opt = opt->next) {
262*6185db85Sdougm 			prop = sa_get_protocol_property(propset, opt->optname);
263*6185db85Sdougm 			if (prop != NULL) {
264*6185db85Sdougm 			    ret = sa_set_protocol_property(prop, opt->optvalue);
265*6185db85Sdougm 			    if (ret != SA_OK) {
266*6185db85Sdougm 				(void) printf(gettext("Could not set property"
267*6185db85Sdougm 						" %s: %s\n"),
268*6185db85Sdougm 					opt->optname, sa_errorstr(ret));
269*6185db85Sdougm 			    }
270*6185db85Sdougm 			} else {
271*6185db85Sdougm 			    (void) printf(gettext("%s: not defined\n"),
272*6185db85Sdougm 						opt->optname);
273*6185db85Sdougm 			}
274*6185db85Sdougm 		    }
275*6185db85Sdougm 		}
276*6185db85Sdougm 	    }
277*6185db85Sdougm 	} else {
278*6185db85Sdougm 	    (void) printf(gettext("Invalid protocol specified: %s\n"), proto);
279*6185db85Sdougm 	    ret = SA_INVALID_PROTOCOL;
280*6185db85Sdougm 	}
281*6185db85Sdougm 	return (ret);
282*6185db85Sdougm }
283*6185db85Sdougm 
284*6185db85Sdougm static void
285*6185db85Sdougm show_status(char *proto)
286*6185db85Sdougm {
287*6185db85Sdougm 	char *status;
288*6185db85Sdougm 	status = sa_get_protocol_status(proto);
289*6185db85Sdougm 	(void) printf("%s\t%s\n", proto, status ? gettext(status) : "-");
290*6185db85Sdougm 	if (status != NULL)
291*6185db85Sdougm 	    free(status);
292*6185db85Sdougm }
293*6185db85Sdougm 
294*6185db85Sdougm static int
295*6185db85Sdougm valid_proto(char **protos, int num, char *proto)
296*6185db85Sdougm {
297*6185db85Sdougm 	int i;
298*6185db85Sdougm 	for (i = 0; i < num; i++)
299*6185db85Sdougm 	    if (strcmp(protos[i], proto) == 0)
300*6185db85Sdougm 		return (1);
301*6185db85Sdougm 	return (0);
302*6185db85Sdougm }
303*6185db85Sdougm 
304*6185db85Sdougm static int
305*6185db85Sdougm sc_status(int flags, int argc, char *argv[])
306*6185db85Sdougm {
307*6185db85Sdougm 	char **protos;
308*6185db85Sdougm 	int ret = SA_OK;
309*6185db85Sdougm 	int c;
310*6185db85Sdougm 	int i;
311*6185db85Sdougm 	int num_proto;
312*6185db85Sdougm 	int verbose = 0;
313*6185db85Sdougm #ifdef lint
314*6185db85Sdougm 	flags = flags;
315*6185db85Sdougm #endif
316*6185db85Sdougm 
317*6185db85Sdougm 	while ((c = getopt(argc, argv, "?hv")) != EOF) {
318*6185db85Sdougm 	    switch (c) {
319*6185db85Sdougm 	    case 'v':
320*6185db85Sdougm 		verbose++;
321*6185db85Sdougm 		break;
322*6185db85Sdougm 	    case '?':
323*6185db85Sdougm 	    case 'h':
324*6185db85Sdougm 		(void) printf(gettext("usage: %s\n"),
325*6185db85Sdougm 				sc_get_usage(USAGE_CTL_SET));
326*6185db85Sdougm 		return (SA_OK);
327*6185db85Sdougm 	    default:
328*6185db85Sdougm 		(void) printf(gettext("usage: %s\n"),
329*6185db85Sdougm 				sc_get_usage(USAGE_CTL_SET));
330*6185db85Sdougm 		return (SA_SYNTAX_ERR);
331*6185db85Sdougm 	    }
332*6185db85Sdougm 	}
333*6185db85Sdougm 
334*6185db85Sdougm 	num_proto = sa_get_protocols(&protos);
335*6185db85Sdougm 	if (optind == argc) {
336*6185db85Sdougm 	    /* status for all protocols */
337*6185db85Sdougm 	    for (i = 0; i < num_proto; i++) {
338*6185db85Sdougm 		show_status(protos[i]);
339*6185db85Sdougm 	    }
340*6185db85Sdougm 	} else {
341*6185db85Sdougm 	    for (i = optind; i < argc; i++) {
342*6185db85Sdougm 		if (valid_proto(protos, num_proto, argv[i])) {
343*6185db85Sdougm 		    show_status(argv[i]);
344*6185db85Sdougm 		} else {
345*6185db85Sdougm 		    (void) printf(gettext("Invalid protocol: %s\n"), argv[i]);
346*6185db85Sdougm 		    ret = SA_INVALID_PROTOCOL;
347*6185db85Sdougm 		}
348*6185db85Sdougm 	    }
349*6185db85Sdougm 	}
350*6185db85Sdougm 	if (protos != NULL)
351*6185db85Sdougm 	    free(protos);
352*6185db85Sdougm 	return (ret);
353*6185db85Sdougm }
354*6185db85Sdougm 
355*6185db85Sdougm static sa_command_t commands[] = {
356*6185db85Sdougm 	{"get", 0, sc_get, USAGE_CTL_GET},
357*6185db85Sdougm 	{"set", 0, sc_set, USAGE_CTL_SET},
358*6185db85Sdougm 	{"status", 0, sc_status, USAGE_CTL_STATUS},
359*6185db85Sdougm 	{NULL, 0, NULL, 0},
360*6185db85Sdougm };
361*6185db85Sdougm 
362*6185db85Sdougm void
363*6185db85Sdougm sub_command_help(char *proto)
364*6185db85Sdougm {
365*6185db85Sdougm 	int i;
366*6185db85Sdougm #ifdef lint
367*6185db85Sdougm 	proto = proto;
368*6185db85Sdougm #endif
369*6185db85Sdougm 
370*6185db85Sdougm 	(void) printf("\tsub-commands:\n");
371*6185db85Sdougm 	for (i = 0; commands[i].cmdname != NULL; i++) {
372*6185db85Sdougm 		if (!(commands[i].flags & (CMD_ALIAS|CMD_NODISPLAY)))
373*6185db85Sdougm 			(void) printf("\t%s\n",
374*6185db85Sdougm 				sc_get_usage((sc_usage_t)commands[i].cmdidx));
375*6185db85Sdougm 	}
376*6185db85Sdougm }
377*6185db85Sdougm 
378*6185db85Sdougm sa_command_t *
379*6185db85Sdougm sa_lookup(char *cmd)
380*6185db85Sdougm {
381*6185db85Sdougm 	int i;
382*6185db85Sdougm 	size_t len;
383*6185db85Sdougm 
384*6185db85Sdougm 	len = strlen(cmd);
385*6185db85Sdougm 	for (i = 0; commands[i].cmdname != NULL; i++) {
386*6185db85Sdougm 		if (strncmp(cmd, commands[i].cmdname, len) == 0)
387*6185db85Sdougm 			return (&commands[i]);
388*6185db85Sdougm 	}
389*6185db85Sdougm 	return (NULL);
390*6185db85Sdougm }
391*6185db85Sdougm 
392*6185db85Sdougm static int
393*6185db85Sdougm run_command(char *command, int argc, char *argv[])
394*6185db85Sdougm {
395*6185db85Sdougm 	sa_command_t *cmdvec;
396*6185db85Sdougm 	int ret;
397*6185db85Sdougm 
398*6185db85Sdougm 	/*
399*6185db85Sdougm 	 * To get here, we know there should be a command due to the
400*6185db85Sdougm 	 * preprocessing done earlier.  Need to find the protocol
401*6185db85Sdougm 	 * that is being affected. If no protocol, then it is ALL
402*6185db85Sdougm 	 * protocols.
403*6185db85Sdougm 	 *
404*6185db85Sdougm 	 * ??? do we really need the protocol at this level? it may be
405*6185db85Sdougm 	 * sufficient to let the commands look it up if needed since
406*6185db85Sdougm 	 * not all commands do proto specific things
407*6185db85Sdougm 	 *
408*6185db85Sdougm 	 * Known sub-commands are handled at this level. An unknown
409*6185db85Sdougm 	 * command will be passed down to the shared object that
410*6185db85Sdougm 	 * actually implements it. We can do this since the semantics
411*6185db85Sdougm 	 * of the common sub-commands is well defined.
412*6185db85Sdougm 	 */
413*6185db85Sdougm 
414*6185db85Sdougm 	cmdvec = sa_lookup(command);
415*6185db85Sdougm 	if (cmdvec == NULL) {
416*6185db85Sdougm 		(void) printf(gettext("command %s not found\n"), command);
417*6185db85Sdougm 		exit(1);
418*6185db85Sdougm 	}
419*6185db85Sdougm 	/*
420*6185db85Sdougm 	 * need to check priviledges and restrict what can be done
421*6185db85Sdougm 	 * based on least priviledge and sub-command.
422*6185db85Sdougm 	 */
423*6185db85Sdougm 	ret = cmdvec->cmdfunc(NULL, argc, argv);
424*6185db85Sdougm 	return (ret);
425*6185db85Sdougm }
426