xref: /illumos-gate/usr/src/cmd/iscsiadm/cmdparse.h (revision c9eab9d4e096bb9b983e9b007577edfa73c32eff)
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  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #ifndef	_CMDPARSE_H
27 #define	_CMDPARSE_H
28 
29 
30 #ifdef	__cplusplus
31 extern "C" {
32 #endif
33 
34 #include <getopt.h>
35 
36 /* subcommands must have a single bit on and must have exclusive values */
37 #define	SUBCOMMAND_BASE  1
38 #define	SUBCOMMAND(x)  (SUBCOMMAND_BASE << x)
39 
40 #define	OBJECT_BASE  1
41 #define	OBJECT(x) (OBJECT_BASE << x)
42 
43 /* maximum length of an option argument */
44 #define	MAXOPTARGLEN   256
45 
46 
47 /*
48  * Add objects here
49  *
50  * EXAMPLE:
51  *	object_t object[] = {
52  *	    {"target", TARGET},
53  *	    {NULL, 0}
54  *	};
55  */
56 typedef struct _object {
57 	char *name;
58 	uint_t value;
59 } object_t;
60 
61 /*
62  * This structure is passed into the caller's callback function and
63  * will contain a list of all options entered and their associated
64  * option arguments if applicable
65  */
66 typedef struct _cmdOptions {
67 	int optval;
68 	char optarg[MAXOPTARGLEN + 1];
69 } cmdOptions_t;
70 
71 
72 /*
73  * list of objects, subcommands, valid short options, required flag and
74  * exlusive option string
75  *
76  * objectValue -> object
77  * subcommandValue -> subcommand value
78  * optionProp.optionString -> short options that are valid
79  * optionProp.required -> flag indicating whether at least one option is
80  *                        required
81  * optionProp.exclusive -> short options that are required to be exclusively
82  *                         entered
83  *
84  *
85  * If it's not here, there are no options for that object.
86  *
87  * The long options table specifies whether an option argument is required.
88  *
89  *
90  * EXAMPLE:
91  *
92  * Based on DISCOVERY entry below:
93  *
94  *  MODIFY DISCOVERY accepts -i, -s, -t and -l
95  *  MODIFY DISCOVERY requires at least one option
96  *  MODIFY DISCOVERY has no exclusive options
97  *
98  *
99  *	optionRules_t optionRules[] = {
100  *	    {DISCOVERY, MODIFY, "istl", B_TRUE, NULL},
101  *	    {0, 0, NULL, 0, NULL}
102  *	};
103  */
104 typedef struct _optionProp {
105 	char *optionString;
106 	boolean_t required;
107 	char *exclusive;
108 } optionProp_t;
109 
110 typedef struct _optionRules {
111 	uint_t objectValue;
112 	uint_t subcommandValue;
113 	optionProp_t	optionProp;
114 } optionRules_t;
115 
116 /*
117  * Rules for subcommands and object operands
118  *
119  * Every object requires an entry
120  *
121  * value, reqOpCmd, optOpCmd, noOpCmd, invCmd, multOpCmd
122  *
123  * value -> numeric value of object
124  *
125  * The following five fields are comprised of values that are
126  * a bitwise OR of the subcommands related to the object
127  *
128  * reqOpCmd -> subcommands that must have an operand
129  * optOpCmd -> subcommands that may have an operand
130  * noOpCmd -> subcommands that will have no operand
131  * invCmd -> subcommands that are invalid
132  * multOpCmd -> subcommands that can accept multiple operands
133  * operandDefinition -> Usage definition for the operand of this object
134  *
135  *
136  * EXAMPLE:
137  *
138  * based on TARGET entry below:
139  *  MODIFY and DELETE subcomamnds require an operand
140  *  LIST optionally requires an operand
141  *  There are no subcommands that requires that no operand is specified
142  *  ADD and REMOVE are invalid subcommands for this operand
143  *  DELETE can accept multiple operands
144  *
145  *	objectRules_t objectRules[] = {
146  *	    {TARGET, MODIFY|DELETE, LIST, 0, ADD|REMOVE, DELETE,
147  *	    "target-name"},
148  *	    {0, 0, 0, 0, 0, NULL}
149  *	};
150  */
151 typedef struct _opCmd {
152 	uint_t reqOpCmd;
153 	uint_t optOpCmd;
154 	uint_t noOpCmd;
155 	uint_t invOpCmd;
156 	uint_t multOpCmd;
157 } opCmd_t;
158 
159 typedef struct _objectRules {
160 	uint_t value;
161 	opCmd_t opCmd;
162 	char *operandDefinition;
163 } objectRules_t;
164 
165 
166 /*
167  * subcommand callback function
168  *
169  * argc - number of arguments in argv
170  * argv - operand arguments
171  * options - options entered on command line
172  * callData - pointer to caller data to be passed to subcommand function
173  */
174 typedef int (*handler_t)(int argc, char *argv[], int, cmdOptions_t *options,
175     void *callData, int *funtRet);
176 
177 /*
178  * Add new subcommands here
179  *
180  * EXAMPLE:
181  *	subcommand_t subcommands[] = {
182  *	    {"add", ADD, addFunc},
183  *	    {NULL, 0, NULL}
184  *	};
185  */
186 typedef struct _subcommand {
187 	char *name;
188 	uint_t value;
189 	handler_t handler;
190 } subcommand_t;
191 
192 #define	required_arg	required_argument
193 #define	no_arg		no_argument
194 
195 /*
196  * Add short options and long options here
197  *
198  *  name -> long option name
199  *  has_arg -> required_arg, no_arg
200  *  val -> short option character
201  *  argDesc -> description of option argument
202  *
203  * Note: This structure may not be used if your CLI has no
204  * options. However, -?, --help and -V, --version will still be supported
205  * as they are standard for every CLI.
206  *
207  * EXAMPLE:
208  *
209  *	optionTbl_t options[] = {
210  *	    {"filename", arg_required, 'f', "out-filename"},
211  *	    {NULL, 0, 0}
212  *	};
213  *
214  */
215 typedef struct _optionTbl {
216 	char *name;
217 	int has_arg;
218 	int val;
219 	char *argDesc;
220 } optionTbl_t;
221 
222 /*
223  * After tables are set, assign them to this structure
224  * for passing into cmdparse()
225  */
226 typedef struct _synTables {
227 	char *versionString;
228 	optionTbl_t *longOptionTbl;
229 	subcommand_t *subcommandTbl;
230 	object_t *objectTbl;
231 	objectRules_t *objectRulesTbl;
232 	optionRules_t *optionRulesTbl;
233 } synTables_t;
234 
235 /*
236  * cmdParse is a parser that checks syntax of the input command against
237  * various rules tables.
238  *
239  * When syntax is successfully validated, the function associated with the
240  * subcommand is called using the subcommands table functions.
241  *
242  * Syntax for the command is as follows:
243  *
244  *	command subcommand [<options>] object [<operand ...>]
245  *
246  *
247  * There are two standard short and long options assumed:
248  *	-?, --help	Provides usage on a command or subcommand
249  *			and stops further processing of the arguments
250  *
251  *	-V, --version	Provides version information on the command
252  *			and stops further processing of the arguments
253  *
254  *	These options are loaded by this function.
255  *
256  * input:
257  *  argc, argv from main
258  *  syntax rules tables (synTables_t structure)
259  *  callArgs - void * passed by caller to be passed to subcommand function
260  *
261  * output:
262  *  funcRet - pointer to int that holds subcommand function return value
263  *
264  * Returns:
265  *
266  *     zero on successful syntax parse and function call
267  *
268  *     1 on unsuccessful syntax parse (no function has been called)
269  *		This could be due to a version or help call or simply a
270  *		general usage call.
271  *
272  *     -1 check errno, call failed
273  *
274  */
275 int cmdParse(int numOperands, char *operands[], synTables_t synTables,
276     void *callerArgs, int *funcRet);
277 
278 #ifdef	__cplusplus
279 }
280 #endif
281 
282 #endif	/* _CMDPARSE_H */
283