Build the array of console commands by using linkage tricks

This commit is contained in:
Jeremy Lakeman 2014-08-18 18:38:05 +09:30
parent 7e1fbe8c76
commit 2ec63b371a
14 changed files with 301 additions and 233 deletions

53
cli.c
View File

@ -30,40 +30,44 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "strbuf_helpers.h"
#include "dataformats.h"
int cli_usage(const struct cli_schema *commands, XPRINTF xpf)
int cli_usage(const struct cli_schema *commands, const struct cli_schema *end_commands, XPRINTF xpf)
{
return cli_usage_args(0, NULL, commands, xpf);
return cli_usage_args(0, NULL, commands, end_commands, xpf);
}
int cli_usage_parsed(const struct cli_parsed *parsed, XPRINTF xpf)
{
if (parsed->varargi == -1)
return cli_usage(parsed->commands, xpf);
return cli_usage_args(parsed->argc - parsed->varargi, &parsed->args[parsed->varargi], parsed->commands, xpf);
return cli_usage(parsed->commands, parsed->end_commands, xpf);
return cli_usage_args(parsed->argc - parsed->varargi, &parsed->args[parsed->varargi],
parsed->commands, parsed->end_commands, xpf);
}
int cli_usage_args(const int argc, const char *const *args, const struct cli_schema *commands, XPRINTF xpf)
static int cli_usage_print(const int argc, const char *const *args, const struct cli_schema *command, XPRINTF xpf)
{
int opt;
const char *word;
for (opt = 0; opt < argc && (word = command->words[opt]); ++opt)
if (strncmp(word, args[opt], strlen(args[opt])) != 0)
return 0;
for (opt = 0; (word = command->words[opt]); ++opt) {
if (word[0] == '|')
++word;
xprintf(xpf, " %s", word);
}
xputc('\n', xpf);
if (command->description && command->description[0])
xprintf(xpf, " %s\n", command->description);
return 1;
}
int cli_usage_args(const int argc, const char *const *args, const struct cli_schema *commands, const struct cli_schema *end_commands, XPRINTF xpf)
{
unsigned cmd;
int matched_any = 0;
for (cmd = 0; commands[cmd].function; ++cmd) {
int opt;
const char *word;
int matched = 1;
for (opt = 0; matched && opt < argc && (word = commands[cmd].words[opt]); ++opt)
if (strncmp(word, args[opt], strlen(args[opt])) != 0)
matched = 0;
if (matched) {
for (cmd = 0; (!end_commands || &commands[cmd] < end_commands) && commands[cmd].function; ++cmd) {
if (cli_usage_print(argc,args,&commands[cmd],xpf)==1)
matched_any = 1;
for (opt = 0; (word = commands[cmd].words[opt]); ++opt) {
if (word[0] == '|')
++word;
xprintf(xpf, " %s", word);
}
xputc('\n', xpf);
if (commands[cmd].description && commands[cmd].description[0])
xprintf(xpf, " %s\n", commands[cmd].description);
}
}
if (!matched_any && argc) {
strbuf b = strbuf_alloca(160);
@ -87,15 +91,16 @@ int cli_usage_args(const int argc, const char *const *args, const struct cli_sch
*
* @author Andrew Bettison <andrew@servalproject.com>
*/
int cli_parse(const int argc, const char *const *args, const struct cli_schema *commands, struct cli_parsed *parsed)
int cli_parse(const int argc, const char *const *args, const struct cli_schema *commands, const struct cli_schema *end_commands, struct cli_parsed *parsed)
{
int ambiguous = 0;
int matched_cmd = -1;
int cmd;
for (cmd = 0; commands[cmd].function; ++cmd) {
for (cmd = 0; (!end_commands || &commands[cmd] < end_commands) && commands[cmd].function; ++cmd) {
struct cli_parsed cmdpa;
memset(&cmdpa, 0, sizeof cmdpa);
cmdpa.commands = commands;
cmdpa.end_commands = end_commands;
cmdpa.cmdi = cmd;
cmdpa.args = args;
cmdpa.argc = argc;

9
cli.h
View File

@ -27,7 +27,7 @@
#include "xprintf.h"
#include "log.h"
#define COMMAND_LINE_MAX_LABELS (32)
#define COMMAND_LINE_MAX_LABELS (16)
struct cli_parsed;
struct cli_context{
@ -52,6 +52,7 @@ struct cli_schema {
struct cli_parsed {
const struct cli_schema *commands;
const struct cli_schema *end_commands;
unsigned int cmdi;
struct labelv {
const char *label;
@ -68,10 +69,10 @@ void _debug_cli_parsed(struct __sourceloc __whence, const struct cli_parsed *par
#define DEBUG_cli_parsed(parsed) _debug_cli_parsed(__WHENCE__, parsed)
int cli_usage(const struct cli_schema *commands, XPRINTF xpf);
int cli_usage_args(const int argc, const char *const *args, const struct cli_schema *commands, XPRINTF xpf);
int cli_usage(const struct cli_schema *commands, const struct cli_schema *end_commands, XPRINTF xpf);
int cli_usage_args(const int argc, const char *const *args, const struct cli_schema *commands, const struct cli_schema *end_commands, XPRINTF xpf);
int cli_usage_parsed(const struct cli_parsed *parsed, XPRINTF xpf);
int cli_parse(const int argc, const char *const *args, const struct cli_schema *commands, struct cli_parsed *parsed);
int cli_parse(const int argc, const char *const *args, const struct cli_schema *commands, const struct cli_schema *end_commands, struct cli_parsed *parsed);
int cli_invoke(const struct cli_parsed *parsed, struct cli_context *context);
int _cli_arg(struct __sourceloc __whence, const struct cli_parsed *parsed, char *label, const char **dst, int (*validator)(const char *arg), char *defaultvalue);

View File

@ -75,16 +75,21 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "overlay_buffer.h"
#include "keyring.h"
#include "dataformats.h"
#include "commandline.h"
extern struct cli_schema command_line_options[];
int commandline_usage(const struct cli_parsed *parsed, struct cli_context *UNUSED(context))
DEFINE_CMD(commandline_usage,CLIFLAG_PERMISSIVE_CONFIG,
"Display command usage.",
"help|-h|--help","...");
static int commandline_usage(const struct cli_parsed *parsed, struct cli_context *UNUSED(context))
{
printf("Serval DNA version %s\nUsage:\n", version_servald);
return cli_usage_parsed(parsed, XPRINTF_STDIO(stdout));
}
int version_message(const struct cli_parsed *UNUSED(parsed), struct cli_context *UNUSED(context))
DEFINE_CMD(version_message,CLIFLAG_PERMISSIVE_CONFIG,
"Display copyright information.",
"version|copyright");
static int version_message(const struct cli_parsed *UNUSED(parsed), struct cli_context *UNUSED(context))
{
printf("Serval DNA version %s\n%s\n", version_servald, copyright_servald);
printf("\
@ -271,7 +276,7 @@ int parseCommandLine(struct cli_context *context, const char *argv0, int argc, c
IN();
struct cli_parsed parsed;
int result = cli_parse(argc, args, command_line_options, &parsed);
int result = cli_parse(argc, args, __start_commands, __stop_commands, &parsed);
switch (result) {
case 0:
// Do not run the command if the configuration does not load ok.
@ -619,7 +624,10 @@ static void cli_put_manifest(struct cli_context *context, const rhizome_manifest
cli_put_long(context, m->inserttime, "\n");
}
int app_echo(const struct cli_parsed *parsed, struct cli_context *context)
DEFINE_CMD(app_echo,CLIFLAG_PERMISSIVE_CONFIG,
"Output the supplied string.",
"echo","[-e]","[--]","...");
static int app_echo(const struct cli_parsed *parsed, struct cli_context *context)
{
if (config.debug.verbose)
DEBUG_cli_parsed(parsed);
@ -640,7 +648,10 @@ int app_echo(const struct cli_parsed *parsed, struct cli_context *context)
return 0;
}
int app_log(const struct cli_parsed *parsed, struct cli_context *UNUSED(context))
DEFINE_CMD(app_log,CLIFLAG_PERMISSIVE_CONFIG,
"Log the supplied message at given level.",
"log","error|warn|hint|info|debug","<message>");
static int app_log(const struct cli_parsed *parsed, struct cli_context *UNUSED(context))
{
if (config.debug.verbose)
DEBUG_cli_parsed(parsed);
@ -691,7 +702,10 @@ static void lookup_send_request(int mdp_sockfd, const sid_t *srcsid, int srcport
}
}
int app_dna_lookup(const struct cli_parsed *parsed, struct cli_context *context)
DEFINE_CMD(app_dna_lookup, 0,
"Lookup the subscribers (SID) with the supplied telephone number (DID).",
"dna","lookup","<did>","[<timeout>]");
static int app_dna_lookup(const struct cli_parsed *parsed, struct cli_context *context)
{
int mdp_sockfd;
if (config.debug.verbose)
@ -818,7 +832,10 @@ int app_dna_lookup(const struct cli_parsed *parsed, struct cli_context *context)
return 0;
}
int app_server_start(const struct cli_parsed *parsed, struct cli_context *context)
DEFINE_CMD(app_server_start, 0,
"Start daemon with instance path from SERVALINSTANCE_PATH environment variable.",
"start" KEYRING_PIN_OPTIONS, "[foreground|exec <path>]");
static int app_server_start(const struct cli_parsed *parsed, struct cli_context *context)
{
IN();
if (config.debug.verbose)
@ -993,7 +1010,10 @@ exit:
OUT();
}
int app_server_stop(const struct cli_parsed *parsed, struct cli_context *context)
DEFINE_CMD(app_server_stop,CLIFLAG_PERMISSIVE_CONFIG,
"Stop a running daemon with instance path from SERVALINSTANCE_PATH environment variable.",
"stop");
static int app_server_stop(const struct cli_parsed *parsed, struct cli_context *context)
{
if (config.debug.verbose)
DEBUG_cli_parsed(parsed);
@ -1044,6 +1064,9 @@ int app_server_stop(const struct cli_parsed *parsed, struct cli_context *context
return 0;
}
DEFINE_CMD(app_server_status,CLIFLAG_PERMISSIVE_CONFIG,
"Display information about running daemon.",
"status");
int app_server_status(const struct cli_parsed *parsed, struct cli_context *context)
{
if (config.debug.verbose)
@ -1093,7 +1116,11 @@ static ssize_t mdp_poll_recv(int mdp_sock, time_ms_t deadline, struct mdp_header
return len;
}
int app_mdp_ping(const struct cli_parsed *parsed, struct cli_context *context)
DEFINE_CMD(app_mdp_ping, 0,
"Attempts to ping specified node via Mesh Datagram Protocol (MDP).",
"mdp","ping","[--interval=<ms>]","[--timeout=<seconds>]","[--wait-for-duplicates]",
"<SID>|broadcast","[<count>]");
static int app_mdp_ping(const struct cli_parsed *parsed, struct cli_context *context)
{
int mdp_sockfd;
if (config.debug.verbose)
@ -1312,7 +1339,10 @@ int app_mdp_ping(const struct cli_parsed *parsed, struct cli_context *context)
return ret;
}
int app_trace(const struct cli_parsed *parsed, struct cli_context *context)
DEFINE_CMD(app_trace, 0,
"Trace through the network to the specified node via MDP.",
"mdp","trace","<SID>");
static int app_trace(const struct cli_parsed *parsed, struct cli_context *context)
{
int mdp_sockfd;
const char *sidhex;
@ -1385,7 +1415,10 @@ int app_trace(const struct cli_parsed *parsed, struct cli_context *context)
return ret;
}
int app_config_schema(const struct cli_parsed *parsed, struct cli_context *context)
DEFINE_CMD(app_config_schema, CLIFLAG_PERMISSIVE_CONFIG,
"Display configuration schema.",
"config", "schema");
static int app_config_schema(const struct cli_parsed *parsed, struct cli_context *context)
{
if (config.debug.verbose)
DEBUG_cli_parsed(parsed);
@ -1404,7 +1437,10 @@ int app_config_schema(const struct cli_parsed *parsed, struct cli_context *conte
return 0;
}
int app_config_dump(const struct cli_parsed *parsed, struct cli_context *context)
DEFINE_CMD(app_config_dump, CLIFLAG_PERMISSIVE_CONFIG,
"Dump configuration settings.",
"config","dump","[--full]");
static int app_config_dump(const struct cli_parsed *parsed, struct cli_context *context)
{
if (config.debug.verbose)
DEBUG_cli_parsed(parsed);
@ -1455,7 +1491,16 @@ static int mdp_client_sync_config(time_ms_t timeout)
return 0;
}
int app_config_set(const struct cli_parsed *parsed, struct cli_context *UNUSED(context))
DEFINE_CMD(app_config_set, CLIFLAG_PERMISSIVE_CONFIG,
"Set and del specified configuration variables.",
"config","set","<variable>","<value>","...");
DEFINE_CMD(app_config_set, CLIFLAG_PERMISSIVE_CONFIG,
"Del and set specified configuration variables.",
"config","del","<variable>","...");
DEFINE_CMD(app_config_set, CLIFLAG_PERMISSIVE_CONFIG,
"Synchronise with the daemon's configuration.",
"config","sync","...");
static int app_config_set(const struct cli_parsed *parsed, struct cli_context *UNUSED(context))
{
if (config.debug.verbose)
DEBUG_cli_parsed(parsed);
@ -1539,7 +1584,10 @@ int app_config_set(const struct cli_parsed *parsed, struct cli_context *UNUSED(c
return 0;
}
int app_config_get(const struct cli_parsed *parsed, struct cli_context *context)
DEFINE_CMD(app_config_get, CLIFLAG_PERMISSIVE_CONFIG,
"Get specified configuration variable.",
"config","get","[<variable>]");
static int app_config_get(const struct cli_parsed *parsed, struct cli_context *context)
{
if (config.debug.verbose)
DEBUG_cli_parsed(parsed);
@ -1570,7 +1618,10 @@ int app_config_get(const struct cli_parsed *parsed, struct cli_context *context)
return 0;
}
int app_config_paths(const struct cli_parsed *parsed, struct cli_context *context)
DEFINE_CMD(app_config_paths, CLIFLAG_PERMISSIVE_CONFIG,
"Dump file and directory paths.",
"config", "paths");
static int app_config_paths(const struct cli_parsed *parsed, struct cli_context *context)
{
if (config.debug.verbose)
DEBUG_cli_parsed(parsed);
@ -1616,7 +1667,10 @@ int app_config_paths(const struct cli_parsed *parsed, struct cli_context *contex
return 0;
}
int app_rhizome_hash_file(const struct cli_parsed *parsed, struct cli_context *context)
DEFINE_CMD(app_rhizome_hash_file, 0,
"Compute the Rhizome hash of a file",
"rhizome","hash","file","<filepath>");
static int app_rhizome_hash_file(const struct cli_parsed *parsed, struct cli_context *context)
{
if (config.debug.verbose)
DEBUG_cli_parsed(parsed);
@ -1632,7 +1686,13 @@ int app_rhizome_hash_file(const struct cli_parsed *parsed, struct cli_context *c
return 0;
}
int app_rhizome_add_file(const struct cli_parsed *parsed, struct cli_context *context)
DEFINE_CMD(app_rhizome_add_file, 0,
"Add a file to Rhizome and optionally write its manifest to the given path",
"rhizome","add","file" KEYRING_PIN_OPTIONS,"[--force-new]","<author_sid>","<filepath>","[<manifestpath>]","[<bsk>]");
DEFINE_CMD(app_rhizome_add_file, 0,
"Append content to a journal bundle",
"rhizome", "journal", "append" KEYRING_PIN_OPTIONS, "<author_sid>", "<manifestid>", "<filepath>", "[<bsk>]");
static int app_rhizome_add_file(const struct cli_parsed *parsed, struct cli_context *context)
{
if (config.debug.verbose)
DEBUG_cli_parsed(parsed);
@ -1830,7 +1890,10 @@ int app_rhizome_add_file(const struct cli_parsed *parsed, struct cli_context *co
return status;
}
int app_rhizome_import_bundle(const struct cli_parsed *parsed, struct cli_context *context)
DEFINE_CMD(app_rhizome_import_bundle, 0,
"Import a payload/manifest pair into Rhizome",
"rhizome","import","bundle","<filepath>","<manifestpath>");
static int app_rhizome_import_bundle(const struct cli_parsed *parsed, struct cli_context *context)
{
if (config.debug.verbose)
DEBUG_cli_parsed(parsed);
@ -1864,7 +1927,10 @@ int app_rhizome_import_bundle(const struct cli_parsed *parsed, struct cli_contex
return status;
}
int app_rhizome_append_manifest(const struct cli_parsed *parsed, struct cli_context *UNUSED(context))
DEFINE_CMD(app_rhizome_append_manifest, 0,
"Append a manifest to the end of the file it belongs to.",
"rhizome", "append", "manifest", "<filepath>", "<manifestpath>");
static int app_rhizome_append_manifest(const struct cli_parsed *parsed, struct cli_context *UNUSED(context))
{
if (config.debug.verbose)
DEBUG_cli_parsed(parsed);
@ -1887,7 +1953,13 @@ int app_rhizome_append_manifest(const struct cli_parsed *parsed, struct cli_cont
return ret;
}
int app_rhizome_delete(const struct cli_parsed *parsed, struct cli_context *UNUSED(context))
DEFINE_CMD(app_rhizome_delete, 0,
"Remove the manifest, or payload, or both for the given Bundle ID from the Rhizome store",
"rhizome","delete","manifest|payload|bundle","<manifestid>");
DEFINE_CMD(app_rhizome_delete, 0,
"Remove the file with the given hash from the Rhizome store",
"rhizome","delete","|file","<fileid>");
static int app_rhizome_delete(const struct cli_parsed *parsed, struct cli_context *UNUSED(context))
{
if (config.debug.verbose)
DEBUG_cli_parsed(parsed);
@ -1946,7 +2018,10 @@ int app_rhizome_delete(const struct cli_parsed *parsed, struct cli_context *UNUS
return ret;
}
int app_rhizome_clean(const struct cli_parsed *parsed, struct cli_context *context)
DEFINE_CMD(app_rhizome_clean, 0,
"Remove stale and orphaned content from the Rhizome store",
"rhizome","clean","[verify]");
static int app_rhizome_clean(const struct cli_parsed *parsed, struct cli_context *context)
{
if (config.debug.verbose)
DEBUG_cli_parsed(parsed);
@ -1974,7 +2049,23 @@ int app_rhizome_clean(const struct cli_parsed *parsed, struct cli_context *conte
return 0;
}
int app_rhizome_extract(const struct cli_parsed *parsed, struct cli_context *context)
DEFINE_CMD(app_rhizome_extract, 0,
"Export a manifest and payload file to the given paths, without decrypting.",
"rhizome","export","bundle" KEYRING_PIN_OPTIONS,
"<manifestid>","[<manifestpath>]","[<filepath>]");
DEFINE_CMD(app_rhizome_extract, 0,
"Export a manifest from Rhizome and write it to the given path",
"rhizome","export","manifest" KEYRING_PIN_OPTIONS,
"<manifestid>","[<manifestpath>]");
DEFINE_CMD(app_rhizome_extract, 0,
"Extract and decrypt a manifest and file to the given paths.",
"rhizome","extract","bundle" KEYRING_PIN_OPTIONS,
"<manifestid>","[<manifestpath>]","[<filepath>]","[<bsk>]");
DEFINE_CMD(app_rhizome_extract, 0,
"Extract and decrypt a file from Rhizome and write it to the given path",
"rhizome","extract","file" KEYRING_PIN_OPTIONS,
"<manifestid>","[<filepath>]","[<bsk>]");
static int app_rhizome_extract(const struct cli_parsed *parsed, struct cli_context *context)
{
if (config.debug.verbose)
DEBUG_cli_parsed(parsed);
@ -2086,7 +2177,10 @@ int app_rhizome_extract(const struct cli_parsed *parsed, struct cli_context *con
return ret;
}
int app_rhizome_export_file(const struct cli_parsed *parsed, struct cli_context *context)
DEFINE_CMD(app_rhizome_export_file, 0,
"Export a file from Rhizome and write it to the given path without attempting decryption",
"rhizome","export","file","<fileid>","[<filepath>]");
static int app_rhizome_export_file(const struct cli_parsed *parsed, struct cli_context *context)
{
if (config.debug.verbose)
DEBUG_cli_parsed(parsed);
@ -2126,7 +2220,11 @@ int app_rhizome_export_file(const struct cli_parsed *parsed, struct cli_context
return 0;
}
int app_rhizome_list(const struct cli_parsed *parsed, struct cli_context *context)
DEFINE_CMD(app_rhizome_list, 0,
"List all manifests and files in Rhizome",
"rhizome","list" KEYRING_PIN_OPTIONS,
"[<service>]","[<name>]","[<sender_sid>]","[<recipient_sid>]","[<offset>]","[<limit>]");
static int app_rhizome_list(const struct cli_parsed *parsed, struct cli_context *context)
{
if (config.debug.verbose)
DEBUG_cli_parsed(parsed);
@ -2227,7 +2325,10 @@ int app_rhizome_list(const struct cli_parsed *parsed, struct cli_context *contex
return 0;
}
int app_keyring_create(const struct cli_parsed *parsed, struct cli_context *UNUSED(context))
DEFINE_CMD(app_keyring_create, 0,
"Create a new keyring file.",
"keyring","create");
static int app_keyring_create(const struct cli_parsed *parsed, struct cli_context *UNUSED(context))
{
if (config.debug.verbose)
DEBUG_cli_parsed(parsed);
@ -2238,7 +2339,10 @@ int app_keyring_create(const struct cli_parsed *parsed, struct cli_context *UNUS
return 0;
}
int app_keyring_dump(const struct cli_parsed *parsed, struct cli_context *UNUSED(context))
DEFINE_CMD(app_keyring_dump, 0,
"Dump all keyring identities that can be accessed using the specified PINs",
"keyring","dump" KEYRING_PIN_OPTIONS,"[--secret]","[<file>]");
static int app_keyring_dump(const struct cli_parsed *parsed, struct cli_context *UNUSED(context))
{
if (config.debug.verbose)
DEBUG_cli_parsed(parsed);
@ -2265,7 +2369,10 @@ int app_keyring_dump(const struct cli_parsed *parsed, struct cli_context *UNUSED
return ret;
}
int app_keyring_load(const struct cli_parsed *parsed, struct cli_context *UNUSED(context))
DEFINE_CMD(app_keyring_load, 0,
"Load identities from the given dump text and insert them into the keyring using the specified entry PINs",
"keyring","load" KEYRING_PIN_OPTIONS,"<file>","[<keyring-pin>]","[<entry-pin>]...");
static int app_keyring_load(const struct cli_parsed *parsed, struct cli_context *UNUSED(context))
{
if (config.debug.verbose)
DEBUG_cli_parsed(parsed);
@ -2308,7 +2415,10 @@ int app_keyring_load(const struct cli_parsed *parsed, struct cli_context *UNUSED
return 0;
}
int app_keyring_list(const struct cli_parsed *parsed, struct cli_context *context)
DEFINE_CMD(app_keyring_list, 0,
"List identities that can be accessed using the supplied PINs",
"keyring","list" KEYRING_PIN_OPTIONS);
static int app_keyring_list(const struct cli_parsed *parsed, struct cli_context *context)
{
if (config.debug.verbose)
DEBUG_cli_parsed(parsed);
@ -2384,7 +2494,10 @@ static void cli_output_identity(struct cli_context *context, const keyring_ident
}
}
int app_keyring_add(const struct cli_parsed *parsed, struct cli_context *context)
DEFINE_CMD(app_keyring_add, 0,
"Create a new identity in the keyring protected by the supplied PIN (empty PIN if not given)",
"keyring","add" KEYRING_PIN_OPTIONS,"[<pin>]");
static int app_keyring_add(const struct cli_parsed *parsed, struct cli_context *context)
{
if (config.debug.verbose)
DEBUG_cli_parsed(parsed);
@ -2417,7 +2530,10 @@ int app_keyring_add(const struct cli_parsed *parsed, struct cli_context *context
return 0;
}
int app_keyring_set_did(const struct cli_parsed *parsed, struct cli_context *context)
DEFINE_CMD(app_keyring_set_did, 0,
"Set the DID for the specified SID (must supply PIN to unlock the SID record in the keyring)",
"keyring", "set","did" KEYRING_PIN_OPTIONS,"<sid>","<did>","<name>");
static int app_keyring_set_did(const struct cli_parsed *parsed, struct cli_context *context)
{
if (config.debug.verbose)
DEBUG_cli_parsed(parsed);
@ -2462,6 +2578,9 @@ int app_keyring_set_did(const struct cli_parsed *parsed, struct cli_context *con
return r;
}
DEFINE_CMD(app_keyring_set_tag, 0,
"Set a named tag for the specified SID (must supply PIN to unlock the SID record in the keyring)",
"keyring", "set","tag" KEYRING_PIN_OPTIONS,"<sid>","<tag>","<value>");
static int app_keyring_set_tag(const struct cli_parsed *parsed, struct cli_context *context)
{
const char *sidhex, *tag, *value;
@ -2562,17 +2681,29 @@ end:
return ret;
}
DEFINE_CMD(app_revoke_pin, 0,
"Unload any identities protected by this pin and drop all routes to them",
"id", "relinquish", "pin", "<entry-pin>");
DEFINE_CMD(app_revoke_pin, 0,
"Unload a specific identity and drop all routes to it",
"id", "relinquish", "sid", "<sid>");
int app_revoke_pin(const struct cli_parsed *parsed, struct cli_context *context)
{
return handle_pins(parsed, context, 1);
}
int app_id_pin(const struct cli_parsed *parsed, struct cli_context *context)
DEFINE_CMD(app_id_pin, 0,
"Unlock any pin protected identities and enable routing packets to them",
"id", "enter", "pin", "<entry-pin>");
static int app_id_pin(const struct cli_parsed *parsed, struct cli_context *context)
{
return handle_pins(parsed, context, 0);
}
int app_id_list(const struct cli_parsed *parsed, struct cli_context *context)
DEFINE_CMD(app_id_list, 0,
"Search unlocked identities based on an optional tag and value",
"id", "list", "[<tag>]", "[<value>]");
static int app_id_list(const struct cli_parsed *parsed, struct cli_context *context)
{
const char *tag, *value;
if (cli_arg(parsed, "tag", &tag, NULL, "") == -1 ||
@ -2637,7 +2768,10 @@ end:
return ret;
}
int app_id_self(const struct cli_parsed *parsed, struct cli_context *context)
DEFINE_CMD(app_id_self, 0,
"Return identity(s) as URIs of own node, or of known routable peers, or all known peers",
"id","self|peers|allpeers");
static int app_id_self(const struct cli_parsed *parsed, struct cli_context *context)
{
int mdp_sockfd;
if (config.debug.verbose)
@ -2697,7 +2831,10 @@ int app_id_self(const struct cli_parsed *parsed, struct cli_context *context)
return 0;
}
int app_count_peers(const struct cli_parsed *parsed, struct cli_context *context)
DEFINE_CMD(app_count_peers, 0,
"Return a count of routable peers on the network",
"peer","count");
static int app_count_peers(const struct cli_parsed *parsed, struct cli_context *context)
{
int mdp_sockfd;
if (config.debug.verbose)
@ -2722,7 +2859,10 @@ int app_count_peers(const struct cli_parsed *parsed, struct cli_context *context
return 0;
}
int app_byteorder_test(const struct cli_parsed *UNUSED(parsed), struct cli_context *UNUSED(context))
DEFINE_CMD(app_byteorder_test, 0,
"Run byte order handling test",
"test","byteorder");
static int app_byteorder_test(const struct cli_parsed *UNUSED(parsed), struct cli_context *UNUSED(context))
{
uint64_t in=0x1234;
uint64_t out;
@ -2738,7 +2878,10 @@ int app_byteorder_test(const struct cli_parsed *UNUSED(parsed), struct cli_conte
return -1;
}
int app_crypt_test(const struct cli_parsed *parsed, struct cli_context *context)
DEFINE_CMD(app_crypt_test, 0,
"Run cryptography speed test",
"test","crypt");
static int app_crypt_test(const struct cli_parsed *parsed, struct cli_context *context)
{
if (config.debug.verbose)
DEBUG_cli_parsed(parsed);
@ -2897,7 +3040,10 @@ int app_crypt_test(const struct cli_parsed *parsed, struct cli_context *context)
return 0;
}
int app_route_print(const struct cli_parsed *parsed, struct cli_context *context)
DEFINE_CMD(app_route_print, 0,
"Print the routing table",
"route","print");
static int app_route_print(const struct cli_parsed *parsed, struct cli_context *context)
{
int mdp_sockfd;
if (config.debug.verbose)
@ -2966,7 +3112,10 @@ int app_route_print(const struct cli_parsed *parsed, struct cli_context *context
return 0;
}
int app_reverse_lookup(const struct cli_parsed *parsed, struct cli_context *context)
DEFINE_CMD(app_reverse_lookup, 0,
"Lookup the phone number (DID) and name of a given subscriber (SID)",
"reverse", "lookup", "<sid>", "[<timeout>]");
static int app_reverse_lookup(const struct cli_parsed *parsed, struct cli_context *context)
{
int mdp_sockfd;
if (config.debug.verbose)
@ -3072,7 +3221,10 @@ int app_reverse_lookup(const struct cli_parsed *parsed, struct cli_context *cont
}
void context_switch_test(int);
int app_mem_test(const struct cli_parsed *UNUSED(parsed), struct cli_context *UNUSED(context))
DEFINE_CMD(app_mem_test, 0,
"Run memory speed test",
"test","memory");
static int app_mem_test(const struct cli_parsed *UNUSED(parsed), struct cli_context *UNUSED(context))
{
size_t mem_size;
size_t addr;
@ -3123,7 +3275,10 @@ int app_mem_test(const struct cli_parsed *UNUSED(parsed), struct cli_context *UN
return 0;
}
int app_network_scan(const struct cli_parsed *parsed, struct cli_context *context)
DEFINE_CMD(app_network_scan, 0,
"Scan the network for serval peers. If no argument is supplied, all local addresses will be scanned.",
"scan","[<address>]");
static int app_network_scan(const struct cli_parsed *parsed, struct cli_context *context)
{
int mdp_sockfd;
if (config.debug.verbose)
@ -3154,141 +3309,3 @@ int app_network_scan(const struct cli_parsed *parsed, struct cli_context *contex
cli_put_string(context, mdp.error.message, "\n");
return mdp.error.error;
}
/* See cli_parse() for details of command specification syntax.
*/
#define KEYRING_PIN_OPTION ,"[--keyring-pin=<pin>]"
#define KEYRING_ENTRY_PIN_OPTION ,"[--entry-pin=<pin>]"
#define KEYRING_PIN_OPTIONS KEYRING_PIN_OPTION KEYRING_ENTRY_PIN_OPTION "..."
struct cli_schema command_line_options[]={
{commandline_usage,{"help|-h|--help","...",NULL},CLIFLAG_PERMISSIVE_CONFIG,
"Display command usage."},
{version_message,{"version|copyright"},CLIFLAG_PERMISSIVE_CONFIG,
"Display copyright information."},
{app_echo,{"echo","[-e]","[--]","...",NULL},CLIFLAG_PERMISSIVE_CONFIG,
"Output the supplied string."},
{app_log,{"log","error|warn|hint|info|debug","<message>",NULL},CLIFLAG_PERMISSIVE_CONFIG,
"Log the supplied message at given level."},
{app_server_start,{"start" KEYRING_PIN_OPTIONS, "[foreground|exec <path>]",NULL}, 0,
"Start daemon with instance path from SERVALINSTANCE_PATH environment variable."},
{app_server_stop,{"stop",NULL},CLIFLAG_PERMISSIVE_CONFIG,
"Stop a running daemon with instance path from SERVALINSTANCE_PATH environment variable."},
{app_server_status,{"status",NULL},CLIFLAG_PERMISSIVE_CONFIG,
"Display information about running daemon."},
{app_mdp_ping,{"mdp","ping","[--interval=<ms>]","[--timeout=<seconds>]","[--wait-for-duplicates]","<SID>|broadcast","[<count>]",NULL}, 0,
"Attempts to ping specified node via Mesh Datagram Protocol (MDP)."},
{app_trace,{"mdp","trace","<SID>",NULL}, 0,
"Trace through the network to the specified node via MDP."},
{app_config_schema,{"config","schema",NULL},CLIFLAG_PERMISSIVE_CONFIG,
"Display configuration schema."},
{app_config_dump,{"config","dump","[--full]",NULL},CLIFLAG_PERMISSIVE_CONFIG,
"Dump configuration settings."},
{app_config_set,{"config","set","<variable>","<value>","...",NULL},CLIFLAG_PERMISSIVE_CONFIG,
"Set and del specified configuration variables."},
{app_config_set,{"config","del","<variable>","...",NULL},CLIFLAG_PERMISSIVE_CONFIG,
"Del and set specified configuration variables."},
{app_config_set,{"config","sync","...",NULL},CLIFLAG_PERMISSIVE_CONFIG,
"Synchronise with the daemon's configuration."},
{app_config_get,{"config","get","[<variable>]",NULL},CLIFLAG_PERMISSIVE_CONFIG,
"Get specified configuration variable."},
{app_config_paths,{"config","paths",NULL},CLIFLAG_PERMISSIVE_CONFIG,
"Dump file and directory paths."},
{app_vomp_console,{"console",NULL}, 0,
"Test phone call life-cycle from the console"},
{app_meshms_conversations,{"meshms","list","conversations" KEYRING_PIN_OPTIONS, "<sid>","[<offset>]","[<count>]",NULL},0,
"List MeshMS threads that include <sid>"},
{app_meshms_list_messages,{"meshms","list","messages" KEYRING_PIN_OPTIONS, "<sender_sid>","<recipient_sid>",NULL},0,
"List MeshMS messages between <sender_sid> and <recipient_sid>"},
{app_meshms_send_message,{"meshms","send","message" KEYRING_PIN_OPTIONS, "<sender_sid>", "<recipient_sid>", "<payload>",NULL},0,
"Send a MeshMS message from <sender_sid> to <recipient_sid>"},
{app_meshms_mark_read,{"meshms","read","messages" KEYRING_PIN_OPTIONS, "<sender_sid>", "[<recipient_sid>]", "[<offset>]",NULL},0,
"Mark incoming messages from this recipient as read."},
{app_rhizome_append_manifest, {"rhizome", "append", "manifest", "<filepath>", "<manifestpath>", NULL}, 0,
"Append a manifest to the end of the file it belongs to."},
{app_rhizome_hash_file,{"rhizome","hash","file","<filepath>",NULL}, 0,
"Compute the Rhizome hash of a file"},
{app_rhizome_add_file,{"rhizome","add","file" KEYRING_PIN_OPTIONS,"[--force-new]","<author_sid>","<filepath>","[<manifestpath>]","[<bsk>]",NULL}, 0,
"Add a file to Rhizome and optionally write its manifest to the given path"},
{app_rhizome_add_file, {"rhizome", "journal", "append" KEYRING_PIN_OPTIONS, "<author_sid>", "<manifestid>", "<filepath>", "[<bsk>]", NULL}, 0,
"Append content to a journal bundle"},
{app_rhizome_import_bundle,{"rhizome","import","bundle","<filepath>","<manifestpath>",NULL}, 0,
"Import a payload/manifest pair into Rhizome"},
{app_rhizome_list,{"rhizome","list" KEYRING_PIN_OPTIONS,
"[<service>]","[<name>]","[<sender_sid>]","[<recipient_sid>]","[<offset>]","[<limit>]",NULL}, 0,
"List all manifests and files in Rhizome"},
{app_rhizome_extract,{"rhizome","export","bundle" KEYRING_PIN_OPTIONS,
"<manifestid>","[<manifestpath>]","[<filepath>]",NULL}, 0,
"Export a manifest and payload file to the given paths, without decrypting."},
{app_rhizome_extract,{"rhizome","export","manifest" KEYRING_PIN_OPTIONS,
"<manifestid>","[<manifestpath>]",NULL}, 0,
"Export a manifest from Rhizome and write it to the given path"},
{app_rhizome_export_file,{"rhizome","export","file","<fileid>","[<filepath>]",NULL}, 0,
"Export a file from Rhizome and write it to the given path without attempting decryption"},
{app_rhizome_extract,{"rhizome","extract","bundle" KEYRING_PIN_OPTIONS,
"<manifestid>","[<manifestpath>]","[<filepath>]","[<bsk>]",NULL}, 0,
"Extract and decrypt a manifest and file to the given paths."},
{app_rhizome_extract,{"rhizome","extract","file" KEYRING_PIN_OPTIONS,
"<manifestid>","[<filepath>]","[<bsk>]",NULL}, 0,
"Extract and decrypt a file from Rhizome and write it to the given path"},
{app_rhizome_delete,{"rhizome","delete","manifest|payload|bundle","<manifestid>",NULL}, 0,
"Remove the manifest, or payload, or both for the given Bundle ID from the Rhizome store"},
{app_rhizome_delete,{"rhizome","delete","|file","<fileid>",NULL}, 0,
"Remove the file with the given hash from the Rhizome store"},
{app_rhizome_direct_sync,{"rhizome","direct","sync","[<url>]",NULL}, 0,
"Synchronise with the specified Rhizome Direct server. Return when done."},
{app_rhizome_direct_sync,{"rhizome","direct","push","[<url>]",NULL}, 0,
"Deliver all new content to the specified Rhizome Direct server. Return when done."},
{app_rhizome_direct_sync,{"rhizome","direct","pull","[<url>]",NULL}, 0,
"Fetch all new content from the specified Rhizome Direct server. Return when done."},
{app_rhizome_clean,{"rhizome","clean","[verify]",NULL}, 0,
"Remove stale and orphaned content from the Rhizome store"},
{app_keyring_create,{"keyring","create",NULL}, 0,
"Create a new keyring file."},
{app_keyring_dump,{"keyring","dump" KEYRING_PIN_OPTIONS,"[--secret]","[<file>]",NULL}, 0,
"Dump all keyring identities that can be accessed using the specified PINs"},
{app_keyring_load,{"keyring","load" KEYRING_PIN_OPTIONS,"<file>","[<keyring-pin>]","[<entry-pin>]...",NULL}, 0,
"Load identities from the given dump text and insert them into the keyring using the specified entry PINs"},
{app_keyring_list,{"keyring","list" KEYRING_PIN_OPTIONS,NULL}, 0,
"List identities that can be accessed using the supplied PINs"},
{app_keyring_add,{"keyring","add" KEYRING_PIN_OPTIONS,"[<pin>]",NULL}, 0,
"Create a new identity in the keyring protected by the supplied PIN (empty PIN if not given)"},
{app_keyring_set_did,{"keyring", "set","did" KEYRING_PIN_OPTIONS,"<sid>","<did>","<name>",NULL}, 0,
"Set the DID for the specified SID (must supply PIN to unlock the SID record in the keyring)"},
{app_keyring_set_tag,{"keyring", "set","tag" KEYRING_PIN_OPTIONS,"<sid>","<tag>","<value>",NULL}, 0,
"Set a named tag for the specified SID (must supply PIN to unlock the SID record in the keyring)"},
{app_id_list, {"id", "list", "[<tag>]", "[<value>]", NULL}, 0,
"Search unlocked identities based on an optional tag and value"},
{app_id_self,{"id","self|peers|allpeers",NULL}, 0,
"Return identity(s) as URIs of own node, or of known routable peers, or all known peers"},
{app_id_pin, {"id", "enter", "pin", "<entry-pin>", NULL}, 0,
"Unlock any pin protected identities and enable routing packets to them"},
{app_revoke_pin, {"id", "relinquish", "pin", "<entry-pin>", NULL}, 0,
"Unload any identities protected by this pin and drop all routes to them"},
{app_revoke_pin, {"id", "relinquish", "sid", "<sid>", NULL}, 0,
"Unload a specific identity and drop all routes to it"},
{app_route_print, {"route","print",NULL}, 0,
"Print the routing table"},
{app_network_scan, {"scan","[<address>]",NULL}, 0,
"Scan the network for serval peers. If no argument is supplied, all local addresses will be scanned."},
{app_count_peers,{"peer","count",NULL}, 0,
"Return a count of routable peers on the network"},
{app_dna_lookup,{"dna","lookup","<did>","[<timeout>]",NULL}, 0,
"Lookup the subscribers (SID) with the supplied telephone number (DID)."},
{app_reverse_lookup, {"reverse", "lookup", "<sid>", "[<timeout>]", NULL}, 0,
"Lookup the phone number (DID) and name of a given subscriber (SID)"},
{app_monitor_cli,{"monitor",NULL}, 0,
"Interactive servald monitor interface."},
{app_crypt_test,{"test","crypt",NULL}, 0,
"Run cryptography speed test"},
{app_nonce_test,{"test","nonce",NULL}, 0,
"Run nonce generation test"},
{app_mem_test,{"test","memory",NULL}, 0,
"Run memory speed test"},
{app_byteorder_test,{"test","byteorder",NULL}, 0,
"Run byte order handling test"},
{app_msp_connection,{"msp", "listen", "[--once]", "[--forward=<local_port>]", "[--service=<service_name>]", "<port>", NULL}, 0,
"Listen for incoming connections"},
{app_msp_connection,{"msp", "connect", "[--once]", "[--forward=<local_port>]", "<sid>", "<port>", NULL}, 0,
"Connect to a remote party"},
{NULL,{NULL},0,NULL}
};

View File

@ -41,7 +41,7 @@ static void process_command(char *line, struct cli_schema *cli_commands){
int argc = parse_argv(line, ' ', argv, 16);
struct cli_parsed parsed;
switch (cli_parse(argc, (const char *const*)argv, cli_commands, &parsed)) {
switch (cli_parse(argc, (const char *const*)argv, cli_commands, NULL, &parsed)) {
case 0:
cli_invoke(&parsed, NULL);
break;

View File

@ -3,6 +3,7 @@ HDRS= fifo.h \
overlay_address.h \
overlay_packet.h \
overlay_interface.h \
commandline.h \
limit.h \
rhizome.h \
httpd.h \

View File

@ -28,6 +28,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "strlcpy.h"
#include "keyring.h"
#include "dataformats.h"
#include "commandline.h"
#define MESHMS_BLOCK_TYPE_ACK 0x01
#define MESHMS_BLOCK_TYPE_MESSAGE 0x02 // NUL-terminated UTF8 string
@ -1024,7 +1025,10 @@ end:
}
// output the list of existing conversations for a given local identity
int app_meshms_conversations(const struct cli_parsed *parsed, struct cli_context *context)
DEFINE_CMD(app_meshms_conversations, 0,
"List MeshMS threads that include <sid>",
"meshms","list","conversations" KEYRING_PIN_OPTIONS, "<sid>","[<offset>]","[<count>]");
static int app_meshms_conversations(const struct cli_parsed *parsed, struct cli_context *context)
{
const char *sidhex, *offset_str, *count_str;
if (cli_arg(parsed, "sid", &sidhex, str_is_subscriber_id, "") == -1
@ -1084,7 +1088,10 @@ int app_meshms_conversations(const struct cli_parsed *parsed, struct cli_context
return 0;
}
int app_meshms_send_message(const struct cli_parsed *parsed, struct cli_context *UNUSED(context))
DEFINE_CMD(app_meshms_send_message, 0,
"Send a MeshMS message from <sender_sid> to <recipient_sid>",
"meshms","send","message" KEYRING_PIN_OPTIONS, "<sender_sid>", "<recipient_sid>", "<payload>");
static int app_meshms_send_message(const struct cli_parsed *parsed, struct cli_context *UNUSED(context))
{
const char *my_sidhex, *their_sidhex, *message;
if (cli_arg(parsed, "sender_sid", &my_sidhex, str_is_subscriber_id, "") == -1
@ -1114,7 +1121,10 @@ int app_meshms_send_message(const struct cli_parsed *parsed, struct cli_context
return meshms_failed(status) ? status : 0;
}
int app_meshms_list_messages(const struct cli_parsed *parsed, struct cli_context *context)
DEFINE_CMD(app_meshms_list_messages, 0,
"List MeshMS messages between <sender_sid> and <recipient_sid>",
"meshms","list","messages" KEYRING_PIN_OPTIONS, "<sender_sid>","<recipient_sid>");
static int app_meshms_list_messages(const struct cli_parsed *parsed, struct cli_context *context)
{
const char *my_sidhex, *their_sidhex;
if (cli_arg(parsed, "sender_sid", &my_sidhex, str_is_subscriber_id, "") == -1
@ -1230,7 +1240,10 @@ static unsigned mark_read(struct meshms_conversations *conv, const sid_t *their_
return ret;
}
int app_meshms_mark_read(const struct cli_parsed *parsed, struct cli_context *UNUSED(context))
DEFINE_CMD(app_meshms_mark_read, 0,
"Mark incoming messages from this recipient as read.",
"meshms","read","messages" KEYRING_PIN_OPTIONS, "<sender_sid>", "[<recipient_sid>]", "[<offset>]");
static int app_meshms_mark_read(const struct cli_parsed *parsed, struct cli_context *UNUSED(context))
{
const char *my_sidhex, *their_sidhex, *offset_str;
if (cli_arg(parsed, "sender_sid", &my_sidhex, str_is_subscriber_id, "") == -1

View File

@ -30,6 +30,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "conf.h"
#include "cli.h"
#include "monitor-client.h"
#include "commandline.h"
int remote_print(char *cmd, int argc, char **argv, unsigned char *data, int dataLen, void *UNUSED(context))
{
@ -49,7 +50,10 @@ struct monitor_command_handler monitor_handlers[]={
{.command="", .handler=remote_print},
};
int app_monitor_cli(const struct cli_parsed *UNUSED(parsed), struct cli_context *UNUSED(context))
DEFINE_CMD(app_monitor_cli, 0,
"Interactive servald monitor interface.",
"monitor");
static int app_monitor_cli(const struct cli_parsed *UNUSED(parsed), struct cli_context *UNUSED(context))
{
struct pollfd fds[2];
struct monitor_state *state;

View File

@ -596,17 +596,17 @@ int monitor_process_command(struct monitor_context *c)
struct cli_parsed parsed;
struct cli_context context={.context=c};
if (cli_parse(argc, (const char *const*)argv, monitor_commands, &parsed) || cli_invoke(&parsed, &context))
if (cli_parse(argc, (const char *const*)argv, monitor_commands, NULL, &parsed) || cli_invoke(&parsed, &context))
return monitor_write_error(c, "Invalid command");
return 0;
}
static int monitor_help(const struct cli_parsed *UNUSED(parsed), struct cli_context *context)
static int monitor_help(const struct cli_parsed *parsed, struct cli_context *context)
{
struct monitor_context *c=context->context;
strbuf b = strbuf_alloca(16384);
strbuf_puts(b, "\nINFO:Usage\n");
cli_usage(monitor_commands, XPRINTF_STRBUF(b));
cli_usage_parsed(parsed, XPRINTF_STRBUF(b));
(void)write_all(c->alarm.poll.fd, strbuf_str(b), strbuf_len(b));
return 0;
}

View File

@ -31,6 +31,7 @@
#include "dataformats.h"
#include "socket.h"
#include "conf.h"
#include "commandline.h"
struct buffer{
size_t position;
@ -561,7 +562,13 @@ void sigQuit(int UNUSED(signal))
quit=1;
}
int app_msp_connection(const struct cli_parsed *parsed, struct cli_context *UNUSED(context))
DEFINE_CMD(app_msp_connection, 0,
"Listen for incoming connections",
"msp", "listen", "[--once]", "[--forward=<local_port>]", "[--service=<service_name>]", "<port>");
DEFINE_CMD(app_msp_connection, 0,
"Connect to a remote party",
"msp", "connect", "[--once]", "[--forward=<local_port>]", "<sid>", "<port>");
static int app_msp_connection(const struct cli_parsed *parsed, struct cli_context *UNUSED(context))
{
const char *sidhex, *port_string, *local_port_string;
once = cli_arg(parsed, "--once", NULL, NULL, NULL) == 0;

View File

@ -20,6 +20,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "cli.h"
#include "constants.h"
#include "os.h"
#include "commandline.h"
int nonce_initialised=0;
unsigned char nonce_buffer[128];
@ -51,7 +52,10 @@ int generate_nonce(unsigned char *nonce,int bytes)
return 0;
}
int app_nonce_test(const struct cli_parsed *UNUSED(parsed), struct cli_context *context)
DEFINE_CMD(app_nonce_test, 0,
"Run nonce generation test",
"test","nonce");
static int app_nonce_test(const struct cli_parsed *UNUSED(parsed), struct cli_context *context)
{
int i,j;
unsigned char nonces[0x10001][32];

View File

@ -111,6 +111,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "conf.h"
#include "rhizome.h"
#include "str.h"
#include "commandline.h"
#include <assert.h>
rhizome_direct_sync_request *rd_sync_handles[RHIZOME_DIRECT_MAX_SYNC_HANDLES];
@ -502,7 +503,10 @@ static int rhizome_sync_with_peers(int mode, int peer_count, const struct config
return 0;
}
int app_rhizome_direct_sync(const struct cli_parsed *parsed, struct cli_context *UNUSED(context))
DEFINE_CMD(app_rhizome_direct_sync, 0,
"Synchronise with the specified Rhizome Direct server.",
"rhizome","direct","push|pull|sync","[<url>]");
static int app_rhizome_direct_sync(const struct cli_parsed *parsed, struct cli_context *UNUSED(context))
{
if (config.debug.verbose)
DEBUG_cli_parsed(parsed);

View File

@ -260,16 +260,6 @@ void monitor_get_all_supported_codecs(unsigned char *codecs);
int directory_registration();
int directory_service_init();
int app_nonce_test(const struct cli_parsed *parsed, struct cli_context *context);
int app_rhizome_direct_sync(const struct cli_parsed *parsed, struct cli_context *context);
int app_monitor_cli(const struct cli_parsed *parsed, struct cli_context *context);
int app_vomp_console(const struct cli_parsed *parsed, struct cli_context *context);
int app_meshms_conversations(const struct cli_parsed *parsed, struct cli_context *context);
int app_meshms_send_message(const struct cli_parsed *parsed, struct cli_context *context);
int app_meshms_list_messages(const struct cli_parsed *parsed, struct cli_context *context);
int app_meshms_mark_read(const struct cli_parsed *parsed, struct cli_context *context);
int app_msp_connection(const struct cli_parsed *parsed, struct cli_context *context);
int monitor_get_fds(struct pollfd *fds,int *fdcount,int fdmax);
int monitor_setup_sockets();

View File

@ -279,4 +279,22 @@ test_InterfaceDropDgramIncompatible() {
--error-pattern='config file.*loaded despite defects.*incompatible'
}
#TODO move to another test script?
doc_CmdUsage="Show help usage"
test_CmdUsage() {
executeOk_servald help
tfw_cat --stdout
executeOk_servald help rhizome
tfw_cat --stdout
executeOk_servald help unknown command
tfw_cat --stdout
#TODO assert output?
}
doc_CmdUnknown="Unknown command"
test_CmdUnknown() {
execute $servald unknown command
assertExitStatus '==' 255
tfw_cat --stdout --stderr
}
runTests "$@"

View File

@ -64,6 +64,7 @@
#include "constants.h"
#include "strbuf.h"
#include "strbuf_helpers.h"
#include "commandline.h"
static int console_dial(const struct cli_parsed *parsed, struct cli_context *context);
static int console_answer(const struct cli_parsed *parsed, struct cli_context *context);
@ -363,9 +364,9 @@ static int console_audio(const struct cli_parsed *parsed, struct cli_context *UN
return 0;
}
static int console_usage(const struct cli_parsed *UNUSED(parsed), struct cli_context *UNUSED(context))
static int console_usage(const struct cli_parsed *parsed, struct cli_context *UNUSED(context))
{
cli_usage(console_commands, XPRINTF_STDIO(stdout));
cli_usage_parsed(parsed, XPRINTF_STDIO(stdout));
fflush(stdout);
return 0;
}
@ -381,7 +382,10 @@ static void monitor_read(struct sched_ent *alarm){
}
}
int app_vomp_console(const struct cli_parsed *parsed, struct cli_context *UNUSED(context))
DEFINE_CMD(app_vomp_console, 0,
"Test phone call life-cycle from the console",
"console");
static int app_vomp_console(const struct cli_parsed *parsed, struct cli_context *UNUSED(context))
{
if (config.debug.verbose)
DEBUG_cli_parsed(parsed);