2012-04-20 07:32:29 +00:00
|
|
|
/*
|
2016-10-12 06:38:26 +00:00
|
|
|
Serval DNA command-line parsing
|
|
|
|
Copyright (C) 2014-2015 Serval Project Inc.
|
|
|
|
Copyright (C) 2016 Flinders University
|
2012-02-16 14:05:28 +00:00
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
|
|
modify it under the terms of the GNU General Public License
|
|
|
|
as published by the Free Software Foundation; either version 2
|
|
|
|
of the License, or (at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program; if not, write to the Free Software
|
|
|
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
*/
|
|
|
|
|
2016-10-12 06:38:26 +00:00
|
|
|
#include "commandline.h"
|
2012-12-04 03:42:28 +00:00
|
|
|
#include "conf.h"
|
2016-09-20 04:03:19 +00:00
|
|
|
#include "str.h"
|
2016-10-12 06:38:26 +00:00
|
|
|
#include "cli_stdio.h"
|
2012-02-16 14:05:28 +00:00
|
|
|
|
2016-10-12 06:38:26 +00:00
|
|
|
DEFINE_CMD(app_usage, CLIFLAG_PERMISSIVE_CONFIG,
|
2014-08-18 09:08:05 +00:00
|
|
|
"Display command usage.",
|
|
|
|
"help|-h|--help","...");
|
2016-10-12 06:38:26 +00:00
|
|
|
static int app_usage(const struct cli_parsed *parsed, struct cli_context *UNUSED(context))
|
2013-02-12 07:30:37 +00:00
|
|
|
{
|
2013-03-25 01:35:26 +00:00
|
|
|
return cli_usage_parsed(parsed, XPRINTF_STDIO(stdout));
|
2012-02-16 14:05:28 +00:00
|
|
|
}
|
|
|
|
|
2016-10-12 06:38:26 +00:00
|
|
|
/* Parse the command line and load the configuration. If a command was found then execute the
|
|
|
|
* parsed command and return its return value.
|
|
|
|
*
|
|
|
|
* 'context' controls the command output.
|
|
|
|
*
|
|
|
|
* 'argv0' must be NULL or be a nul-terminated string containing the name or path of the executable.
|
|
|
|
* It is used to emit diagnostic messages.
|
|
|
|
*
|
|
|
|
* 'argc' and 'args' must contain the command-line words to parse.
|
|
|
|
*/
|
|
|
|
int commandline_main(struct cli_context *context, const char *argv0, int argc, const char *const *args)
|
2012-02-16 14:05:28 +00:00
|
|
|
{
|
2012-07-03 05:42:42 +00:00
|
|
|
fd_clearstats();
|
|
|
|
IN();
|
Switch to feature-driven linking
This introduces a new way of linking Serval executables and dynamic
libraries from static libraries like libservald.a -- called
"feature-driven" linking.
The Makefile now links servald and serval-tests from libservald.a,
rather than from an explicit list of object (.o) files. Thanks to the
section-based method for registering functions such as HTTP handlers,
CLI commands and MDP handlers, these object files had become
"stand-alone" and hence were no longer included in the link because
there was no unresolved reference that required them to be linked in.
The new "feature.h" provides the DECLARE_FEATURE(name) macro that each
stand-alone source file uses to declare the named feature(s) it
provides. Each executable can call the USE_FEATURE(name) macro in any
of its explicitly-linked source files to cause the corresponding
object(s) to be included in the link, eg, servald_features.c.
The DEFINE_BINDING() macro has been extended so that every individual
MDP binding is given a feature name based on its port number macro, eg,
"mdp_binding_MDP_PORT_ECHO".
Some features have been factored into their own separate source files so
they can be omitted or included in a build independently of each other:
- the MDP bindings for MDP_PORT_DNALOOKUP, MDP_PORT_ECHO,
MDP_PORT_TRACE, MDP_PORT_KEYMAPREQUEST, MDP_PORT_RHIZOME_xxx,
MDP_PORT_PROBE, MDP_PORT_STUN, MDP_PORT_STUNREQ
- the CLI "log" and "echo" commands
- the CLI "rhizome direct" command
The JNI source files are only compiled if the <jni.h> header is present,
otherwise they are omitted from libservald.so.
2016-10-13 02:58:23 +00:00
|
|
|
|
|
|
|
cf_init();
|
2016-10-17 07:10:28 +00:00
|
|
|
|
2013-02-13 07:13:24 +00:00
|
|
|
struct cli_parsed parsed;
|
2015-08-14 04:23:37 +00:00
|
|
|
int result = cli_parse(argc, args, SECTION_START(commands), SECTION_END(commands), &parsed);
|
2013-04-09 07:48:37 +00:00
|
|
|
switch (result) {
|
|
|
|
case 0:
|
|
|
|
// Do not run the command if the configuration does not load ok.
|
2013-03-25 01:35:26 +00:00
|
|
|
if (((parsed.commands[parsed.cmdi].flags & CLIFLAG_PERMISSIVE_CONFIG) ? cf_reload_permissive() : cf_reload()) != -1)
|
2013-07-03 07:21:27 +00:00
|
|
|
result = cli_invoke(&parsed, context);
|
2012-12-14 01:09:08 +00:00
|
|
|
else {
|
|
|
|
strbuf b = strbuf_alloca(160);
|
|
|
|
strbuf_append_argv(b, argc, args);
|
2013-03-28 13:52:08 +00:00
|
|
|
result = WHYF("configuration defective, not running command: %s", strbuf_str(b));
|
2012-12-14 01:09:08 +00:00
|
|
|
}
|
2013-04-09 07:48:37 +00:00
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
case 2:
|
|
|
|
// Load configuration so that log messages can get out.
|
|
|
|
cf_reload_permissive();
|
|
|
|
NOWHENCE(HINTF("Run \"%s help\" for more information.", argv0 ? argv0 : "servald"));
|
2014-02-19 05:05:08 +00:00
|
|
|
result =-1;
|
2013-04-09 07:48:37 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
// Load configuration so that log error messages can get out.
|
2012-12-14 01:09:08 +00:00
|
|
|
cf_reload_permissive();
|
2013-04-09 07:48:37 +00:00
|
|
|
break;
|
2012-12-04 06:22:49 +00:00
|
|
|
}
|
|
|
|
|
2016-11-11 00:09:50 +00:00
|
|
|
CALL_TRIGGER(cmd_cleanup, context);
|
2016-10-17 07:10:28 +00:00
|
|
|
|
2012-07-03 05:42:42 +00:00
|
|
|
OUT();
|
2016-10-17 07:10:28 +00:00
|
|
|
|
2015-07-06 08:19:49 +00:00
|
|
|
if (IF_DEBUG(timing))
|
2012-07-03 05:42:42 +00:00
|
|
|
fd_showstats();
|
2012-04-30 10:34:07 +00:00
|
|
|
return result;
|
2012-02-16 14:05:28 +00:00
|
|
|
}
|
|
|
|
|
2016-11-11 00:09:50 +00:00
|
|
|
// Put a dummy no-op trigger callback into the "cmd_cleanup" trigger section,
|
|
|
|
// otherwise if no other object provides one, the link will fail with errors like:
|
|
|
|
// undefined reference to `__start_tr_cmd_cleanup'
|
|
|
|
// undefined reference to `__stop_tr_cmd_cleanup'
|
|
|
|
|
|
|
|
static void __dummy_on_cmd_cleanup();
|
|
|
|
DEFINE_TRIGGER(cmd_cleanup, __dummy_on_cmd_cleanup);
|
|
|
|
static void __dummy_on_cmd_cleanup() {}
|
|
|
|
|
2016-10-12 06:38:26 +00:00
|
|
|
int commandline_main_stdio(FILE *output, const char *argv0, int argc, const char *const *args)
|
2012-04-23 07:42:10 +00:00
|
|
|
{
|
2016-10-12 06:38:26 +00:00
|
|
|
struct cli_context_stdio cli_context_stdio = {
|
|
|
|
.fp = output
|
|
|
|
};
|
|
|
|
struct cli_context cli_context = {
|
|
|
|
.vtable = &cli_vtable_stdio,
|
|
|
|
.context = &cli_context_stdio
|
|
|
|
};
|
2012-04-23 07:42:10 +00:00
|
|
|
|
2016-10-12 06:38:26 +00:00
|
|
|
return commandline_main(&cli_context, argv0, argc, args);
|
2012-10-08 06:43:17 +00:00
|
|
|
}
|