1 /*
2  * CDDL HEADER START
3  *
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.
7  *
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.
12  *
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]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #include <stdlib.h>
28 #include <stdio.h>
29 #include <string.h>
30 #include <ctype.h>
31 #include <unistd.h>
32 #include <getopt.h>
33 #include <libgen.h>
34 
35 #include <libshare.h>
36 #include "sharemgr.h"
37 #include <libintl.h>
38 #include <locale.h>
39 
40 char *protocol = NULL;
41 static int help = 0;
42 
43 static int run_command(char *, int, char **, char *, sa_handle_t);
44 extern sa_command_t *sa_lookup(char *, char *);
45 extern void sub_command_help(char *proto);
46 
47 static void
global_help()48 global_help()
49 {
50 	(void) printf(gettext("usage: sharemgr [-h | <command> [options]]\n"));
51 	sub_command_help(NULL);
52 }
53 
54 int
main(int argc,char * argv[])55 main(int argc, char *argv[])
56 {
57 	int c;
58 	int rval;
59 	char *command = NULL;
60 	sa_handle_t handle;
61 
62 	/*
63 	 * make sure locale and gettext domain is setup
64 	 */
65 	(void) setlocale(LC_ALL, "");
66 	(void) textdomain(TEXT_DOMAIN);
67 
68 	/*
69 	 * parse enough of command line to get protocol, if any.
70 	 * Note that options need to come "after" the subcommand.
71 	 */
72 	command = basename(argv[0]);
73 	if (strcmp(command, "share") != 0 && strcmp(command, "unshare") != 0) {
74 		while ((c = getopt(argc, argv, "h?")) != EOF) {
75 			switch (c) {
76 			default:
77 			case 'h':
78 			case '?':
79 				help = 1;
80 				break;
81 			}
82 		}
83 		if (argc == 1)
84 			help = 1;
85 	}
86 
87 	if (strcmp(command, "sharemgr") == 0) {
88 		command = argv[optind];
89 		argv++;
90 		argc--;
91 	}
92 
93 	if (help) {
94 		/* no subcommand */
95 		global_help();
96 		exit(SA_OK);
97 	}
98 
99 	/*
100 	 * now have enough to parse rest of command line
101 	 *
102 	 * First, initialize the plugin architecture.
103 	 * Plugins are needed in the event of a global help
104 	 * request.
105 	 *
106 	 * reset optind to 1 so the parsing that takes place in
107 	 * sa_init() will work correctly.
108 	 */
109 
110 	optind = 1;
111 	handle = sa_init(SA_INIT_SHARE_API);
112 
113 	/*
114 	 * reset optind again since we will start parsing all over in
115 	 * the sub-commands.
116 	 */
117 	optind = 1;
118 	rval = run_command(command, argc, argv, protocol, handle);
119 
120 	sa_fini(handle);
121 	return (rval);
122 }
123 
124 static int
run_command(char * command,int argc,char * argv[],char * proto,sa_handle_t handle)125 run_command(char *command, int argc, char *argv[], char *proto,
126 		sa_handle_t handle)
127 {
128 	sa_command_t *cmdvec;
129 	int ret;
130 
131 	/*
132 	 * To get here, we know there should be a command due to the
133 	 * preprocessing done earlier.  Need to find the protocol
134 	 * that is being affected. If no protocol, then it is ALL
135 	 * protocols.
136 	 *
137 	 * We don't currently use the protocol here at this point. It
138 	 * is left in as a placeholder for the future addition of
139 	 * protocol specific sub-commands.
140 	 *
141 	 * Known sub-commands are handled at this level. An unknown
142 	 * command will be passed down to the shared object that
143 	 * actually implements it. We can do this since the semantics
144 	 * of the common sub-commands is well defined.
145 	 */
146 
147 	cmdvec = sa_lookup(command, proto);
148 	if (cmdvec == NULL) {
149 		(void) printf(gettext("command %s not found\n"), command);
150 		exit(1);
151 	}
152 	/*
153 	 * need to check priviledges and restrict what can be done
154 	 * based on least priviledge and sub-command so pass this in
155 	 * as a flag.
156 	 */
157 	ret = cmdvec->cmdfunc(handle, cmdvec->priv, argc, argv);
158 	return (ret);
159 }
160