2 * Copyright (C) 2009 Martin Willi
3 * Hochschule fuer Technik Rapperswil
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
27 #include <utils/optionsfrom.h>
30 * Registered commands.
32 command_t cmds
[MAX_COMMANDS
];
37 static int active
= 0;
40 * number of registered commands
42 static int registered
= 0;
53 static options_t
*options
;
56 * Global options used by all subcommands
58 static struct option command_opts
[MAX_COMMANDS
> MAX_OPTIONS ?
: MAX_OPTIONS
];
61 * Global optstring used by all subcommands
63 static char command_optstring
[(MAX_COMMANDS
> MAX_OPTIONS ?
: MAX_OPTIONS
) * 3];
66 * Build command_opts/command_optstr for the active command
68 static void build_opts()
72 memset(command_opts
, 0, sizeof(command_opts
));
73 memset(command_optstring
, 0, sizeof(command_optstring
));
74 if (active
== help_idx
)
76 for (i
= 0; cmds
[i
].cmd
; i
++)
78 command_opts
[i
].name
= cmds
[i
].cmd
;
79 command_opts
[i
].val
= cmds
[i
].op
;
80 command_optstring
[i
] = cmds
[i
].op
;
85 for (i
= 0; cmds
[active
].options
[i
].name
; i
++)
87 command_opts
[i
].name
= cmds
[active
].options
[i
].name
;
88 command_opts
[i
].has_arg
= cmds
[active
].options
[i
].arg
;
89 command_opts
[i
].val
= cmds
[active
].options
[i
].op
;
90 command_optstring
[pos
++] = cmds
[active
].options
[i
].op
;
91 switch (cmds
[active
].options
[i
].arg
)
93 case optional_argument
:
94 command_optstring
[pos
++] = ':';
96 case required_argument
:
97 command_optstring
[pos
++] = ':';
108 * getopt_long wrapper
110 int command_getopt(char **arg
)
116 op
= getopt_long(argc
, argv
, command_optstring
, command_opts
, NULL
);
120 if (!options
->from(options
, optarg
, &argc
, &argv
, optind
))
127 dbg_default_set_level(atoi(optarg
));
139 void command_register(command_t command
)
143 cmds
[registered
] = command
;
144 /* append default options, but not to --help */
147 for (i
= 0; i
< countof(cmds
[registered
].options
); i
++)
149 if (cmds
[registered
].options
[i
].name
)
153 cmds
[registered
].options
[i
++] = (command_option_t
) {
154 "debug", 'v', 1, "set debug level, default: 1"
156 cmds
[registered
].options
[i
++] = (command_option_t
) {
157 "options", '+', 1, "read command line options from file"
166 * Print usage text, with an optional error
168 int command_usage(char *error
)
176 fprintf(out
, "Error: %s\n", error
);
178 fprintf(out
, "strongSwan %s PKI tool\n", VERSION
);
179 fprintf(out
, "usage:\n");
180 if (active
== help_idx
)
182 for (i
= 0; cmds
[i
].cmd
; i
++)
184 fprintf(out
, " pki --%-6s (-%c) %s\n",
185 cmds
[i
].cmd
, cmds
[i
].op
, cmds
[i
].description
);
190 for (i
= 0; cmds
[active
].line
[i
]; i
++)
194 fprintf(out
, " pki --%s %s\n",
195 cmds
[active
].cmd
, cmds
[active
].line
[i
]);
199 fprintf(out
, " %s\n", cmds
[active
].line
[i
]);
202 for (i
= 0; cmds
[active
].options
[i
].name
; i
++)
204 fprintf(out
, " --%-8s (-%c) %s\n",
205 cmds
[active
].options
[i
].name
, cmds
[active
].options
[i
].op
,
206 cmds
[active
].options
[i
].desc
);
209 return error
!= NULL
;
214 * Show usage information
216 static int help(int argc
, char *argv
[])
218 return command_usage(NULL
);
222 * Dispatch cleanup hook
224 static void cleanup()
226 options
->destroy(options
);
232 int command_dispatch(int c
, char *v
[])
236 options
= options_create();
238 active
= help_idx
= registered
;
241 command_register((command_t
){help
, 'h', "help", "show usage information"});
244 op
= getopt_long(c
, v
, command_optstring
, command_opts
, NULL
);
245 for (i
= 0; cmds
[i
].cmd
; i
++)
247 if (cmds
[i
].op
== op
)
251 return cmds
[i
].call();
254 return command_usage("invalid operation");