summaryrefslogtreecommitdiffstats
path: root/comm/third_party/botan/src/cli/cli.h
diff options
context:
space:
mode:
Diffstat (limited to 'comm/third_party/botan/src/cli/cli.h')
-rw-r--r--comm/third_party/botan/src/cli/cli.h219
1 files changed, 219 insertions, 0 deletions
diff --git a/comm/third_party/botan/src/cli/cli.h b/comm/third_party/botan/src/cli/cli.h
new file mode 100644
index 0000000000..6ddf34d025
--- /dev/null
+++ b/comm/third_party/botan/src/cli/cli.h
@@ -0,0 +1,219 @@
+/*
+* (C) 2015 Jack Lloyd
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#ifndef BOTAN_CLI_H_
+#define BOTAN_CLI_H_
+
+#include <botan/build.h>
+#include <functional>
+#include <ostream>
+#include <map>
+#include <memory>
+#include <string>
+#include <vector>
+#include "cli_exceptions.h"
+
+namespace Botan {
+
+class RandomNumberGenerator;
+
+}
+
+namespace Botan_CLI {
+
+class Argument_Parser;
+
+/* Declared in cli_rng.cpp */
+std::unique_ptr<Botan::RandomNumberGenerator>
+cli_make_rng(const std::string& type = "", const std::string& hex_drbg_seed = "");
+
+class Command
+ {
+ public:
+
+ /**
+ * Get a registered command
+ */
+ static std::unique_ptr<Command> get_cmd(const std::string& name);
+
+ static std::vector<std::string> registered_cmds();
+
+ /**
+ * The spec string specifies the format of the command line, eg for
+ * a somewhat complicated command:
+ * cmd_name --flag --option1= --option2=opt2val input1 input2 *rest
+ *
+ * By default this is the value returned by help_text()
+ *
+ * The first value is always the command name. Options may appear
+ * in any order. Named arguments are taken from the command line
+ * in the order they appear in the spec.
+ *
+ * --flag can optionally be specified, and takes no value.
+ * Check for it in go() with flag_set()
+ *
+ * --option1 is an option whose default value (if the option
+ * does not appear on the command line) is the empty string.
+ *
+ * --option2 is an option whose default value is opt2val
+ * Read the values in go() using get_arg or get_arg_sz.
+ *
+ * The values input1 and input2 specify named arguments which must
+ * be provided. They are also access via get_arg/get_arg_sz
+ * Because options and arguments for a single command share the same
+ * namespace you can't have a spec like:
+ * cmd --input input
+ * but you hopefully didn't want to do that anyway.
+ *
+ * The leading '*' on '*rest' specifies that all remaining arguments
+ * should be packaged in a list which is available as get_arg_list("rest").
+ * This can only appear on a single value and should be the final
+ * named argument.
+ *
+ * Every command has implicit flags --help, --verbose and implicit
+ * options --output= and --error-output= which override the default
+ * use of std::cout and std::cerr.
+ *
+ * Use of --help is captured in run() and returns help_text().
+ * Use of --verbose can be checked with verbose() or flag_set("verbose")
+ */
+ explicit Command(const std::string& cmd_spec);
+
+ virtual ~Command();
+
+ int run(const std::vector<std::string>& params);
+
+ virtual std::string group() const = 0;
+
+ virtual std::string description() const = 0;
+
+ virtual std::string help_text() const;
+
+ const std::string& cmd_spec() const
+ {
+ return m_spec;
+ }
+
+ std::string cmd_name() const;
+
+ protected:
+
+ /*
+ * The actual functionality of the cli command implemented in subclass.
+ * The return value from main will be zero.
+ */
+ virtual void go() = 0;
+
+ void set_return_code(int rc) { m_return_code = rc; }
+
+ std::ostream& output();
+
+ std::ostream& error_output();
+
+ bool verbose() const
+ {
+ return flag_set("verbose");
+ }
+
+ std::string get_passphrase(const std::string& prompt);
+
+ bool flag_set(const std::string& flag_name) const;
+
+ static std::string format_blob(const std::string& format, const uint8_t bits[], size_t len);
+
+ template<typename Alloc>
+ static std::string format_blob(const std::string& format,
+ const std::vector<uint8_t, Alloc>& vec)
+ {
+ return format_blob(format, vec.data(), vec.size());
+ }
+
+ std::string get_arg(const std::string& opt_name) const;
+
+ /**
+ * Like get_arg but if the value is '-' then reads a passphrase from
+ * the terminal with echo suppressed.
+ */
+ std::string get_passphrase_arg(const std::string& prompt,
+ const std::string& opt_name);
+
+ /*
+ * Like get_arg() but if the argument was not specified or is empty, returns otherwise
+ */
+ std::string get_arg_or(const std::string& opt_name, const std::string& otherwise) const;
+
+ size_t get_arg_sz(const std::string& opt_name) const;
+
+ uint16_t get_arg_u16(const std::string& opt_name) const;
+
+ uint32_t get_arg_u32(const std::string& opt_name) const;
+
+ std::vector<std::string> get_arg_list(const std::string& what) const;
+
+ /*
+ * Read an entire file into memory and return the contents
+ */
+ std::vector<uint8_t> slurp_file(const std::string& input_file,
+ size_t buf_size = 0) const;
+
+ std::string slurp_file_as_str(const std::string& input_file,
+ size_t buf_size = 0) const;
+
+ /*
+ * Read a file calling consumer_fn() with the inputs
+ */
+ void read_file(const std::string& input_file,
+ std::function<void (uint8_t[], size_t)> consumer_fn,
+ size_t buf_size = 0) const;
+
+
+ void do_read_file(std::istream& in,
+ std::function<void (uint8_t[], size_t)> consumer_fn,
+ size_t buf_size = 0) const;
+
+ template<typename Alloc>
+ void write_output(const std::vector<uint8_t, Alloc>& vec)
+ {
+ output().write(reinterpret_cast<const char*>(vec.data()), vec.size());
+ }
+
+ Botan::RandomNumberGenerator& rng();
+
+ private:
+ typedef std::function<Command* ()> cmd_maker_fn;
+ static std::map<std::string, cmd_maker_fn>& global_registry();
+
+ void parse_spec();
+
+ // set in constructor
+ std::string m_spec;
+
+ std::unique_ptr<Argument_Parser> m_args;
+ std::unique_ptr<std::ostream> m_output_stream;
+ std::unique_ptr<std::ostream> m_error_output_stream;
+
+ std::unique_ptr<Botan::RandomNumberGenerator> m_rng;
+
+ // possibly set by calling set_return_code()
+ int m_return_code = 0;
+
+ public:
+ // the registry interface:
+
+ class Registration final
+ {
+ public:
+ Registration(const std::string& name, cmd_maker_fn maker_fn);
+ };
+ };
+
+#define BOTAN_REGISTER_COMMAND(name, CLI_Class) \
+ Botan_CLI::Command::Registration reg_cmd_ ## CLI_Class(name, \
+ []() -> Botan_CLI::Command* { return new CLI_Class; })
+
+}
+
+#endif