125 lines
4.3 KiB
C++
125 lines
4.3 KiB
C++
#include "Parser.h"
|
|
#include "utils.h"
|
|
#include <iostream>
|
|
#include <boost/optional.hpp>
|
|
|
|
namespace po = boost::program_options;
|
|
using namespace cryfs::program_options;
|
|
using std::pair;
|
|
using std::vector;
|
|
using std::cerr;
|
|
using std::endl;
|
|
using std::string;
|
|
using boost::optional;
|
|
using boost::none;
|
|
|
|
Parser::Parser(int argc, char *argv[])
|
|
:_options(_argsToVector(argc, argv)) {
|
|
}
|
|
|
|
vector<char*> Parser::_argsToVector(int argc, char *argv[]) {
|
|
vector<char*> result;
|
|
for(int i = 0; i < argc; ++i) {
|
|
result.push_back(argv[i]);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
ProgramOptions Parser::parse(const vector<string> &supportedCiphers) const {
|
|
pair<vector<char*>, vector<char*>> options = splitAtDoubleDash(_options);
|
|
po::variables_map vm = _parseOptionsOrShowHelp(options.first, supportedCiphers);
|
|
|
|
string baseDir = vm["base-dir"].as<string>();
|
|
string mountDir = vm["mount-dir"].as<string>();
|
|
optional<string> configfile = none;
|
|
if (vm.count("config")) {
|
|
configfile = vm["config"].as<string>();
|
|
}
|
|
bool foreground = vm.count("foreground");
|
|
optional<string> logfile = none;
|
|
if (vm.count("logfile")) {
|
|
logfile = vm["logfile"].as<string>();
|
|
}
|
|
optional<string> cipher = none;
|
|
if (vm.count("cipher")) {
|
|
cipher = vm["cipher"].as<string>();
|
|
_checkValidCipher(*cipher, supportedCiphers);
|
|
}
|
|
|
|
return ProgramOptions(baseDir, mountDir, configfile, foreground, logfile, cipher, options.second);
|
|
}
|
|
|
|
void Parser::_checkValidCipher(const string &cipher, const vector<string> &supportedCiphers) {
|
|
if (std::find(supportedCiphers.begin(), supportedCiphers.end(), cipher) == supportedCiphers.end()) {
|
|
std::cerr << "Invalid cipher: " << cipher << std::endl;
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
po::variables_map Parser::_parseOptionsOrShowHelp(const vector<char*> options, const vector<string> &supportedCiphers) {
|
|
try {
|
|
return _parseOptions(options, supportedCiphers);
|
|
} catch(const std::exception &e) {
|
|
_showHelpAndExit();
|
|
}
|
|
}
|
|
|
|
po::variables_map Parser::_parseOptions(const vector<char*> options, const vector<string> &supportedCiphers) {
|
|
po::options_description desc;
|
|
po::positional_options_description positional_desc;
|
|
_addAllowedOptions(&desc);
|
|
_addPositionalOptionForBaseDir(&desc, &positional_desc);
|
|
|
|
po::variables_map vm;
|
|
po::store(po::command_line_parser(options.size(), options.data())
|
|
.options(desc).positional(positional_desc).run(), vm);
|
|
if (vm.count("help")) {
|
|
_showHelpAndExit();
|
|
}
|
|
if (vm.count("show-ciphers")) {
|
|
_showCiphersAndExit(supportedCiphers);
|
|
}
|
|
po::notify(vm);
|
|
|
|
return vm;
|
|
}
|
|
|
|
void Parser::_addAllowedOptions(po::options_description *desc) {
|
|
po::options_description options("Allowed options");
|
|
options.add_options()
|
|
("help,h", "show help message")
|
|
("config,c", po::value<string>(), "Configuration file")
|
|
("foreground,f", "Run CryFS in foreground.")
|
|
("cipher", po::value<string>(), "Cipher to use for encryption. See possible values by calling cryfs with --show-ciphers")
|
|
("show-ciphers", "Show list of supported ciphers.")
|
|
("logfile", po::value<string>(), "Specify the file to write log messages to. If this is not specified, log messages will go to stdout, or syslog if CryFS is running in the background.")
|
|
;
|
|
desc->add(options);
|
|
}
|
|
|
|
void Parser::_addPositionalOptionForBaseDir(po::options_description *desc, po::positional_options_description *positional) {
|
|
positional->add("base-dir", 1);
|
|
positional->add("mount-dir", 1);
|
|
po::options_description hidden("Hidden options");
|
|
hidden.add_options()
|
|
("base-dir", po::value<string>()->required(), "Base directory")
|
|
("mount-dir", po::value<string>()->required(), "Mount directory")
|
|
;
|
|
desc->add(hidden);
|
|
}
|
|
|
|
[[noreturn]] void Parser::_showCiphersAndExit(const vector<string> &supportedCiphers) {
|
|
for (const auto &cipher : supportedCiphers) {
|
|
std::cerr << cipher << "\n";
|
|
}
|
|
exit(0);
|
|
}
|
|
|
|
[[noreturn]] void Parser::_showHelpAndExit() {
|
|
cerr << "Usage: cryfs [options] rootDir mountPoint [-- [FUSE Mount Options]]\n";
|
|
po::options_description desc;
|
|
_addAllowedOptions(&desc);
|
|
cerr << desc << endl;
|
|
exit(1);
|
|
}
|