/* * Copyright (C) 2019 KeePassXC Team * * 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 or (at your option) * version 3 of the License. * * 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, see . */ #include "Add.h" #include "AddGroup.h" #include "Analyze.h" #include "AttachmentExport.h" #include "AttachmentImport.h" #include "AttachmentRemove.h" #include "Clip.h" #include "Close.h" #include "DatabaseCreate.h" #include "DatabaseEdit.h" #include "DatabaseInfo.h" #include "Diceware.h" #include "Edit.h" #include "Estimate.h" #include "Exit.h" #include "Export.h" #include "Generate.h" #include "Help.h" #include "Import.h" #include "List.h" #include "Merge.h" #include "Move.h" #include "Open.h" #include "Remove.h" #include "RemoveGroup.h" #include "Search.h" #include "Show.h" #include "Utils.h" #include #include #include const QCommandLineOption Command::HelpOption = QCommandLineOption(QStringList() #ifdef Q_OS_WIN << QStringLiteral("?") #endif << QStringLiteral("h") << QStringLiteral("help"), QObject::tr("Display this help.")); const QCommandLineOption Command::QuietOption = QCommandLineOption(QStringList() << "q" << "quiet", QObject::tr("Silence password prompt and other secondary outputs.")); const QCommandLineOption Command::KeyFileOption = QCommandLineOption(QStringList() << "k" << "key-file", QObject::tr("Key file of the database."), QObject::tr("path")); const QCommandLineOption Command::NoPasswordOption = QCommandLineOption(QStringList() << "no-password", QObject::tr("Deactivate password key for the database.")); const QCommandLineOption Command::YubiKeyOption = QCommandLineOption(QStringList() << "y" << "yubikey", QObject::tr("Yubikey slot and optional serial used to access the database (e.g., 1:7370001)."), QObject::tr("slot[:serial]")); namespace { QSharedPointer buildParser(Command* command) { auto parser = QSharedPointer(new QCommandLineParser()); parser->setApplicationDescription(command->description); for (const CommandLineArgument& positionalArgument : command->positionalArguments) { parser->addPositionalArgument( positionalArgument.name, positionalArgument.description, positionalArgument.syntax); } for (const CommandLineArgument& optionalArgument : command->optionalArguments) { parser->addPositionalArgument(optionalArgument.name, optionalArgument.description, optionalArgument.syntax); } for (const QCommandLineOption& option : command->options) { parser->addOption(option); } parser->addOption(Command::HelpOption); return parser; } } // namespace Command::Command() : currentDatabase(nullptr) { options.append(Command::QuietOption); } Command::~Command() = default; QString Command::getDescriptionLine() { QString response = name; QString space(" "); QString spaces = space.repeated(20 - name.length()); response = response.append(spaces); response = response.append(description); response = response.append("\n"); return response; } QString Command::getHelpText() { auto help = buildParser(this)->helpText(); // Fix spacing of options parameter help.replace(QStringLiteral("[options]"), name + QStringLiteral(" [options]")); // Remove application directory from command line example auto appname = QFileInfo(QCoreApplication::applicationFilePath()).fileName(); auto regex = QRegularExpression(QStringLiteral(" .*%1").arg(QRegularExpression::escape(appname))); help.replace(regex, appname.prepend(" ")); return help; } QSharedPointer Command::getCommandLineParser(const QStringList& arguments) { auto& err = Utils::STDERR; QSharedPointer parser = buildParser(this); if (!parser->parse(arguments)) { err << parser->errorText() << "\n\n"; err << getHelpText(); return {}; } if (parser->positionalArguments().size() < positionalArguments.size()) { err << QObject::tr("Missing positional argument(s).") << "\n\n"; err << getHelpText(); return {}; } if (parser->positionalArguments().size() > (positionalArguments.size() + optionalArguments.size())) { err << QObject::tr("Too many arguments provided.") << "\n\n"; err << getHelpText(); return {}; } if (parser->isSet(HelpOption)) { err << getHelpText(); return {}; } return parser; } namespace Commands { QMap> s_commands; void setupCommands(bool interactive) { s_commands.clear(); s_commands.insert(QStringLiteral("add"), QSharedPointer(new Add())); s_commands.insert(QStringLiteral("analyze"), QSharedPointer(new Analyze())); s_commands.insert(QStringLiteral("attachment-export"), QSharedPointer(new AttachmentExport())); s_commands.insert(QStringLiteral("attachment-import"), QSharedPointer(new AttachmentImport())); s_commands.insert(QStringLiteral("attachment-rm"), QSharedPointer(new AttachmentRemove())); s_commands.insert(QStringLiteral("clip"), QSharedPointer(new Clip())); s_commands.insert(QStringLiteral("close"), QSharedPointer(new Close())); s_commands.insert(QStringLiteral("db-create"), QSharedPointer(new DatabaseCreate())); s_commands.insert(QStringLiteral("db-edit"), QSharedPointer(new DatabaseEdit())); s_commands.insert(QStringLiteral("db-info"), QSharedPointer(new DatabaseInfo())); s_commands.insert(QStringLiteral("diceware"), QSharedPointer(new Diceware())); s_commands.insert(QStringLiteral("edit"), QSharedPointer(new Edit())); s_commands.insert(QStringLiteral("estimate"), QSharedPointer(new Estimate())); s_commands.insert(QStringLiteral("generate"), QSharedPointer(new Generate())); s_commands.insert(QStringLiteral("help"), QSharedPointer(new Help())); s_commands.insert(QStringLiteral("ls"), QSharedPointer(new List())); s_commands.insert(QStringLiteral("merge"), QSharedPointer(new Merge())); s_commands.insert(QStringLiteral("mkdir"), QSharedPointer(new AddGroup())); s_commands.insert(QStringLiteral("mv"), QSharedPointer(new Move())); s_commands.insert(QStringLiteral("open"), QSharedPointer(new Open())); s_commands.insert(QStringLiteral("rm"), QSharedPointer(new Remove())); s_commands.insert(QStringLiteral("rmdir"), QSharedPointer(new RemoveGroup())); s_commands.insert(QStringLiteral("search"), QSharedPointer(new Search())); s_commands.insert(QStringLiteral("show"), QSharedPointer(new Show())); if (interactive) { s_commands.insert(QStringLiteral("exit"), QSharedPointer(new Exit("exit"))); s_commands.insert(QStringLiteral("quit"), QSharedPointer(new Exit("quit"))); } else { s_commands.insert(QStringLiteral("export"), QSharedPointer(new Export())); s_commands.insert(QStringLiteral("import"), QSharedPointer(new Import())); } } QList> getCommands() { return s_commands.values(); } QSharedPointer getCommand(const QString& commandName) { return s_commands.value(commandName); } } // namespace Commands