]>
git.ipfire.org Git - thirdparty/strongswan.git/blob - src/swanctl/command.c
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
26 #include <utils/debug.h>
27 #include <utils/optionsfrom.h>
30 * Registered commands.
32 static command_t cmds
[MAX_COMMANDS
];
37 static int active
= 0;
40 * number of registered commands
42 static int registered
= 0;
52 static char *uri
= NULL
;
58 static options_t
*options
;
61 * Global options used by all subcommands
63 static struct option command_opts
[MAX_COMMANDS
> MAX_OPTIONS
?
64 MAX_COMMANDS
: MAX_OPTIONS
];
67 * Global optstring used by all subcommands
69 static char command_optstring
[(MAX_COMMANDS
> MAX_OPTIONS
?
70 MAX_COMMANDS
: MAX_OPTIONS
) * 3];
73 * Build command_opts/command_optstr for the active command
75 static void build_opts()
79 memset(command_opts
, 0, sizeof(command_opts
));
80 memset(command_optstring
, 0, sizeof(command_optstring
));
81 if (active
== help_idx
)
83 for (i
= 0; i
< MAX_COMMANDS
&& cmds
[i
].cmd
; i
++)
85 command_opts
[i
].name
= cmds
[i
].cmd
;
86 command_opts
[i
].val
= cmds
[i
].op
;
87 command_optstring
[i
] = cmds
[i
].op
;
92 for (i
= 0; cmds
[active
].options
[i
].name
; i
++)
94 command_opts
[i
].name
= cmds
[active
].options
[i
].name
;
95 command_opts
[i
].has_arg
= cmds
[active
].options
[i
].arg
;
96 command_opts
[i
].val
= cmds
[active
].options
[i
].op
;
97 command_optstring
[pos
++] = cmds
[active
].options
[i
].op
;
98 switch (cmds
[active
].options
[i
].arg
)
100 case optional_argument
:
101 command_optstring
[pos
++] = ':';
103 case required_argument
:
104 command_optstring
[pos
++] = ':';
115 * getopt_long wrapper
117 int command_getopt(char **arg
)
123 op
= getopt_long(argc
, argv
, command_optstring
, command_opts
, NULL
);
140 void command_register(command_t command
)
144 if (registered
== MAX_COMMANDS
)
146 fprintf(stderr
, "unable to register command, please increase "
151 cmds
[registered
] = command
;
152 /* append default options, but not to --help */
155 for (i
= 0; i
< countof(cmds
[registered
].options
) - 1; i
++)
157 if (!cmds
[registered
].options
[i
].name
)
162 if (i
> countof(cmds
[registered
].options
) - 3)
164 fprintf(stderr
, "command '%s' registered too many options, please "
165 "increase MAX_OPTIONS\n", command
.cmd
);
169 cmds
[registered
].options
[i
++] = (command_option_t
) {
170 "debug", 'v', 1, "set debug level, default: 1"
172 cmds
[registered
].options
[i
++] = (command_option_t
) {
173 "options", '+', 1, "read command line options from file"
175 cmds
[registered
].options
[i
++] = (command_option_t
) {
176 "uri", 'u', 1, "service URI to connect to"
184 * Print usage text, with an optional error
186 int command_usage(char *error
, ...)
195 fprintf(out
, "Error: ");
196 va_start(args
, error
);
197 vfprintf(out
, error
, args
);
201 fprintf(out
, "strongSwan %s swanctl\n", VERSION
);
203 if (active
== help_idx
)
205 fprintf(out
, "loaded plugins: %s\n",
206 lib
->plugins
->loaded_plugins(lib
->plugins
));
209 fprintf(out
, "usage:\n");
210 if (active
== help_idx
)
212 for (i
= 0; i
< MAX_COMMANDS
&& cmds
[i
].cmd
; i
++)
214 fprintf(out
, " swanctl --%-16s (-%c) %s\n",
215 cmds
[i
].cmd
, cmds
[i
].op
, cmds
[i
].description
);
220 for (i
= 0; cmds
[active
].line
[i
]; i
++)
224 fprintf(out
, " swanctl --%s %s\n",
225 cmds
[active
].cmd
, cmds
[active
].line
[i
]);
229 fprintf(out
, " %s\n", cmds
[active
].line
[i
]);
232 for (i
= 0; cmds
[active
].options
[i
].name
; i
++)
234 fprintf(out
, " --%-15s (-%c) %s\n",
235 cmds
[active
].options
[i
].name
, cmds
[active
].options
[i
].op
,
236 cmds
[active
].options
[i
].desc
);
239 return error
!= NULL
;
243 * Dispatch cleanup hook
245 static void cleanup()
247 options
->destroy(options
);
251 * Process options common for all commands
253 static bool process_common_opts()
257 switch (getopt_long(argc
, argv
, command_optstring
, command_opts
, NULL
))
260 if (!options
->from(options
, optarg
, &argc
, &argv
, optind
))
266 dbg_default_set_level(atoi(optarg
));
282 * Open vici connection, call a command
284 static int call_command(command_t
*cmd
)
289 conn
= vici_connect(uri
);
293 command_usage("connecting to '%s' URI failed: %s",
294 uri
?: "default", strerror(errno
));
297 ret
= cmd
->call(conn
);
298 vici_disconnect(conn
);
305 int command_dispatch(int c
, char *v
[])
309 options
= options_create();
311 active
= help_idx
= registered
;
314 command_register((command_t
){NULL
, 'h', "help", "show usage information"});
317 op
= getopt_long(c
, v
, command_optstring
, command_opts
, NULL
);
318 for (i
= 0; i
< MAX_COMMANDS
&& cmds
[i
].cmd
; i
++)
320 if (cmds
[i
].op
== op
)
326 return command_usage(NULL
);
328 if (!process_common_opts())
330 return command_usage("invalid options");
333 return call_command(&cmds
[i
]);
336 return command_usage(c
> 1 ? "invalid operation" : NULL
);