We should output to stderr on EXIT_FAILURE (#2558)

Making sure we use stderr to output the help
message when there is an invalid number of
arguments, or when there's any error related
to the arguments.
This commit is contained in:
louib 2019-01-16 12:32:06 -05:00 committed by Jonathan White
parent d09ca076dc
commit 726bbb2d94
12 changed files with 80 additions and 82 deletions

View file

@ -83,7 +83,7 @@ int Add::execute(const QStringList& arguments)
const QStringList args = parser.positionalArguments(); const QStringList args = parser.positionalArguments();
if (args.size() != 2) { if (args.size() != 2) {
outputTextStream << parser.helpText().replace("keepassxc-cli", "keepassxc-cli add"); errorTextStream << parser.helpText().replace("keepassxc-cli", "keepassxc-cli add");
return EXIT_FAILURE; return EXIT_FAILURE;
} }

View file

@ -42,7 +42,7 @@ Clip::~Clip()
int Clip::execute(const QStringList& arguments) int Clip::execute(const QStringList& arguments)
{ {
TextStream out(Utils::STDOUT); TextStream errorTextStream(Utils::STDERR, QIODevice::WriteOnly);
QCommandLineParser parser; QCommandLineParser parser;
parser.setApplicationDescription(description); parser.setApplicationDescription(description);
@ -62,7 +62,7 @@ int Clip::execute(const QStringList& arguments)
const QStringList args = parser.positionalArguments(); const QStringList args = parser.positionalArguments();
if (args.size() != 2 && args.size() != 3) { if (args.size() != 2 && args.size() != 3) {
out << parser.helpText().replace("keepassxc-cli", "keepassxc-cli clip"); errorTextStream << parser.helpText().replace("keepassxc-cli", "keepassxc-cli clip");
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -83,11 +83,11 @@ int Clip::clipEntry(QSharedPointer<Database> database,
bool clipTotp, bool clipTotp,
bool silent) bool silent)
{ {
TextStream err(Utils::STDERR); TextStream errorTextStream(Utils::STDERR);
int timeoutSeconds = 0; int timeoutSeconds = 0;
if (!timeout.isEmpty() && !timeout.toInt()) { if (!timeout.isEmpty() && !timeout.toInt()) {
err << QObject::tr("Invalid timeout value %1.").arg(timeout) << endl; errorTextStream << QObject::tr("Invalid timeout value %1.").arg(timeout) << endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} else if (!timeout.isEmpty()) { } else if (!timeout.isEmpty()) {
timeoutSeconds = timeout.toInt(); timeoutSeconds = timeout.toInt();
@ -96,14 +96,14 @@ int Clip::clipEntry(QSharedPointer<Database> database,
TextStream outputTextStream(silent ? Utils::DEVNULL : Utils::STDOUT, QIODevice::WriteOnly); TextStream outputTextStream(silent ? Utils::DEVNULL : Utils::STDOUT, QIODevice::WriteOnly);
Entry* entry = database->rootGroup()->findEntryByPath(entryPath); Entry* entry = database->rootGroup()->findEntryByPath(entryPath);
if (!entry) { if (!entry) {
err << QObject::tr("Entry %1 not found.").arg(entryPath) << endl; errorTextStream << QObject::tr("Entry %1 not found.").arg(entryPath) << endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
QString value; QString value;
if (clipTotp) { if (clipTotp) {
if (!entry->hasTotp()) { if (!entry->hasTotp()) {
err << QObject::tr("Entry with path %1 has no TOTP set up.").arg(entryPath) << endl; errorTextStream << QObject::tr("Entry with path %1 has no TOTP set up.").arg(entryPath) << endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }

View file

@ -38,8 +38,8 @@ Diceware::~Diceware()
int Diceware::execute(const QStringList& arguments) int Diceware::execute(const QStringList& arguments)
{ {
TextStream in(Utils::STDIN, QIODevice::ReadOnly); TextStream outputTextStream(Utils::STDOUT, QIODevice::WriteOnly);
TextStream out(Utils::STDOUT, QIODevice::WriteOnly); TextStream errorTextStream(Utils::STDERR, QIODevice::WriteOnly);
QCommandLineParser parser; QCommandLineParser parser;
parser.setApplicationDescription(description); parser.setApplicationDescription(description);
@ -58,7 +58,7 @@ int Diceware::execute(const QStringList& arguments)
const QStringList args = parser.positionalArguments(); const QStringList args = parser.positionalArguments();
if (!args.isEmpty()) { if (!args.isEmpty()) {
out << parser.helpText().replace("keepassxc-cli", "keepassxc-cli diceware"); errorTextStream << parser.helpText().replace("keepassxc-cli", "keepassxc-cli diceware");
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -78,12 +78,12 @@ int Diceware::execute(const QStringList& arguments)
} }
if (!dicewareGenerator.isValid()) { if (!dicewareGenerator.isValid()) {
out << parser.helpText().replace("keepassxc-cli", "keepassxc-cli diceware"); outputTextStream << parser.helpText().replace("keepassxc-cli", "keepassxc-cli diceware");
return EXIT_FAILURE; return EXIT_FAILURE;
} }
QString password = dicewareGenerator.generatePassphrase(); QString password = dicewareGenerator.generatePassphrase();
out << password << endl; outputTextStream << password << endl;
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }

View file

@ -41,9 +41,8 @@ Edit::~Edit()
int Edit::execute(const QStringList& arguments) int Edit::execute(const QStringList& arguments)
{ {
TextStream in(Utils::STDIN, QIODevice::ReadOnly); TextStream outputTextStream(Utils::STDOUT, QIODevice::WriteOnly);
TextStream out(Utils::STDOUT, QIODevice::WriteOnly); TextStream errorTextStream(Utils::STDERR, QIODevice::WriteOnly);
TextStream err(Utils::STDERR, QIODevice::WriteOnly);
QCommandLineParser parser; QCommandLineParser parser;
parser.setApplicationDescription(description); parser.setApplicationDescription(description);
@ -88,7 +87,7 @@ int Edit::execute(const QStringList& arguments)
const QStringList args = parser.positionalArguments(); const QStringList args = parser.positionalArguments();
if (args.size() != 2) { if (args.size() != 2) {
out << parser.helpText().replace("keepassxc-cli", "keepassxc-cli edit"); errorTextStream << parser.helpText().replace("keepassxc-cli", "keepassxc-cli edit");
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -105,19 +104,19 @@ int Edit::execute(const QStringList& arguments)
QString passwordLength = parser.value(length); QString passwordLength = parser.value(length);
if (!passwordLength.isEmpty() && !passwordLength.toInt()) { if (!passwordLength.isEmpty() && !passwordLength.toInt()) {
err << QObject::tr("Invalid value for password length: %1").arg(passwordLength) << endl; errorTextStream << QObject::tr("Invalid value for password length: %1").arg(passwordLength) << endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
Entry* entry = db->rootGroup()->findEntryByPath(entryPath); Entry* entry = db->rootGroup()->findEntryByPath(entryPath);
if (!entry) { if (!entry) {
err << QObject::tr("Could not find entry with path %1.").arg(entryPath) << endl; errorTextStream << QObject::tr("Could not find entry with path %1.").arg(entryPath) << endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
if (parser.value("username").isEmpty() && parser.value("url").isEmpty() && parser.value("title").isEmpty() if (parser.value("username").isEmpty() && parser.value("url").isEmpty() && parser.value("title").isEmpty()
&& !parser.isSet(prompt) && !parser.isSet(generate)) { && !parser.isSet(prompt) && !parser.isSet(generate)) {
err << QObject::tr("Not changing any field for entry %1.").arg(entryPath) << endl; errorTextStream << QObject::tr("Not changing any field for entry %1.").arg(entryPath) << endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -137,7 +136,7 @@ int Edit::execute(const QStringList& arguments)
if (parser.isSet(prompt)) { if (parser.isSet(prompt)) {
if (!parser.isSet(Command::QuietOption)) { if (!parser.isSet(Command::QuietOption)) {
out << QObject::tr("Enter new password for entry: ") << flush; outputTextStream << QObject::tr("Enter new password for entry: ") << flush;
} }
QString password = Utils::getPassword(parser.isSet(Command::QuietOption) ? Utils::DEVNULL : Utils::STDOUT); QString password = Utils::getPassword(parser.isSet(Command::QuietOption) ? Utils::DEVNULL : Utils::STDOUT);
entry->setPassword(password); entry->setPassword(password);
@ -160,12 +159,12 @@ int Edit::execute(const QStringList& arguments)
QString errorMessage; QString errorMessage;
if (!db->save(databasePath, &errorMessage, true, false)) { if (!db->save(databasePath, &errorMessage, true, false)) {
err << QObject::tr("Writing the database failed: %1").arg(errorMessage) << endl; errorTextStream << QObject::tr("Writing the database failed: %1").arg(errorMessage) << endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
if (!parser.isSet(Command::QuietOption)) { if (!parser.isSet(Command::QuietOption)) {
out << QObject::tr("Successfully edited entry %1.").arg(entry->title()) << endl; outputTextStream << QObject::tr("Successfully edited entry %1.").arg(entry->title()) << endl;
} }
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }

View file

@ -156,8 +156,8 @@ static void estimate(const char* pwd, bool advanced)
int Estimate::execute(const QStringList& arguments) int Estimate::execute(const QStringList& arguments)
{ {
TextStream in(Utils::STDIN, QIODevice::ReadOnly); TextStream inputTextStream(Utils::STDIN, QIODevice::ReadOnly);
TextStream out(Utils::STDOUT, QIODevice::WriteOnly); TextStream errorTextStream(Utils::STDERR, QIODevice::WriteOnly);
QCommandLineParser parser; QCommandLineParser parser;
parser.setApplicationDescription(description); parser.setApplicationDescription(description);
@ -171,7 +171,7 @@ int Estimate::execute(const QStringList& arguments)
const QStringList args = parser.positionalArguments(); const QStringList args = parser.positionalArguments();
if (args.size() > 1) { if (args.size() > 1) {
out << parser.helpText().replace("keepassxc-cli", "keepassxc-cli estimate"); errorTextStream << parser.helpText().replace("keepassxc-cli", "keepassxc-cli estimate");
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -179,7 +179,7 @@ int Estimate::execute(const QStringList& arguments)
if (args.size() == 1) { if (args.size() == 1) {
password = args.at(0); password = args.at(0);
} else { } else {
password = in.readLine(); password = inputTextStream.readLine();
} }
estimate(password.toLatin1(), parser.isSet(advancedOption)); estimate(password.toLatin1(), parser.isSet(advancedOption));

View file

@ -43,8 +43,8 @@ Extract::~Extract()
int Extract::execute(const QStringList& arguments) int Extract::execute(const QStringList& arguments)
{ {
TextStream out(Utils::STDOUT, QIODevice::WriteOnly); TextStream outputTextStream(Utils::STDOUT, QIODevice::WriteOnly);
TextStream err(Utils::STDERR, QIODevice::WriteOnly); TextStream errorTextStream(Utils::STDERR, QIODevice::WriteOnly);
QCommandLineParser parser; QCommandLineParser parser;
parser.setApplicationDescription(description); parser.setApplicationDescription(description);
@ -56,12 +56,12 @@ int Extract::execute(const QStringList& arguments)
const QStringList args = parser.positionalArguments(); const QStringList args = parser.positionalArguments();
if (args.size() != 1) { if (args.size() != 1) {
out << parser.helpText().replace("keepassxc-cli", "keepassxc-cli extract"); errorTextStream << parser.helpText().replace("keepassxc-cli", "keepassxc-cli extract");
return EXIT_FAILURE; return EXIT_FAILURE;
} }
if (!parser.isSet(Command::QuietOption)) { if (!parser.isSet(Command::QuietOption)) {
out << QObject::tr("Insert password to unlock %1: ").arg(args.at(0)) << flush; outputTextStream << QObject::tr("Insert password to unlock %1: ").arg(args.at(0)) << flush;
} }
auto compositeKey = QSharedPointer<CompositeKey>::create(); auto compositeKey = QSharedPointer<CompositeKey>::create();
@ -77,12 +77,12 @@ int Extract::execute(const QStringList& arguments)
auto fileKey = QSharedPointer<FileKey>::create(); auto fileKey = QSharedPointer<FileKey>::create();
QString errorMsg; QString errorMsg;
if (!fileKey->load(keyFilePath, &errorMsg)) { if (!fileKey->load(keyFilePath, &errorMsg)) {
err << QObject::tr("Failed to load key file %1: %2").arg(keyFilePath, errorMsg) << endl; errorTextStream << QObject::tr("Failed to load key file %1: %2").arg(keyFilePath, errorMsg) << endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
if (fileKey->type() != FileKey::Hashed) { if (fileKey->type() != FileKey::Hashed) {
err << QObject::tr("WARNING: You are using a legacy key file format which may become\n" errorTextStream << QObject::tr("WARNING: You are using a legacy key file format which may become\n"
"unsupported in the future.\n\n" "unsupported in the future.\n\n"
"Please consider generating a new key file.") "Please consider generating a new key file.")
<< endl; << endl;
@ -95,11 +95,11 @@ int Extract::execute(const QStringList& arguments)
const QString& databaseFilename = args.at(0); const QString& databaseFilename = args.at(0);
QFile dbFile(databaseFilename); QFile dbFile(databaseFilename);
if (!dbFile.exists()) { if (!dbFile.exists()) {
err << QObject::tr("File %1 does not exist.").arg(databaseFilename) << endl; errorTextStream << QObject::tr("File %1 does not exist.").arg(databaseFilename) << endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
if (!dbFile.open(QIODevice::ReadOnly)) { if (!dbFile.open(QIODevice::ReadOnly)) {
err << QObject::tr("Unable to open file %1.").arg(databaseFilename) << endl; errorTextStream << QObject::tr("Unable to open file %1.").arg(databaseFilename) << endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -112,14 +112,14 @@ int Extract::execute(const QStringList& arguments)
if (reader.hasError()) { if (reader.hasError()) {
if (xmlData.isEmpty()) { if (xmlData.isEmpty()) {
err << QObject::tr("Error while reading the database:\n%1").arg(reader.errorString()) << endl; errorTextStream << QObject::tr("Error while reading the database:\n%1").arg(reader.errorString()) << endl;
} else { } else {
err << QObject::tr("Error while parsing the database:\n%1").arg(reader.errorString()) << endl; errorTextStream << QObject::tr("Error while parsing the database:\n%1").arg(reader.errorString()) << endl;
} }
return EXIT_FAILURE; return EXIT_FAILURE;
} }
out << xmlData.constData() << endl; outputTextStream << xmlData.constData() << endl;
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }

View file

@ -38,8 +38,8 @@ Generate::~Generate()
int Generate::execute(const QStringList& arguments) int Generate::execute(const QStringList& arguments)
{ {
TextStream in(Utils::STDIN, QIODevice::ReadOnly); TextStream outputTextStream(Utils::STDOUT, QIODevice::WriteOnly);
TextStream out(Utils::STDOUT, QIODevice::WriteOnly); TextStream errorTextStream(Utils::STDERR, QIODevice::WriteOnly);
QCommandLineParser parser; QCommandLineParser parser;
parser.setApplicationDescription(description); parser.setApplicationDescription(description);
@ -84,7 +84,7 @@ int Generate::execute(const QStringList& arguments)
const QStringList args = parser.positionalArguments(); const QStringList args = parser.positionalArguments();
if (!args.isEmpty()) { if (!args.isEmpty()) {
out << parser.helpText().replace("keepassxc-cli", "keepassxc-cli generate"); errorTextStream << parser.helpText().replace("keepassxc-cli", "keepassxc-cli generate");
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -128,12 +128,12 @@ int Generate::execute(const QStringList& arguments)
passwordGenerator.setExcludedChars(parser.value(exclude)); passwordGenerator.setExcludedChars(parser.value(exclude));
if (!passwordGenerator.isValid()) { if (!passwordGenerator.isValid()) {
out << parser.helpText().replace("keepassxc-cli", "keepassxc-cli generate"); errorTextStream << parser.helpText().replace("keepassxc-cli", "keepassxc-cli generate");
return EXIT_FAILURE; return EXIT_FAILURE;
} }
QString password = passwordGenerator.generatePassword(); QString password = passwordGenerator.generatePassword();
out << password << endl; outputTextStream << password << endl;
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }

View file

@ -40,7 +40,7 @@ List::~List()
int List::execute(const QStringList& arguments) int List::execute(const QStringList& arguments)
{ {
TextStream out(Utils::STDOUT); TextStream errorTextStream(Utils::STDERR, QIODevice::WriteOnly);
QCommandLineParser parser; QCommandLineParser parser;
parser.setApplicationDescription(description); parser.setApplicationDescription(description);
@ -58,7 +58,7 @@ int List::execute(const QStringList& arguments)
const QStringList args = parser.positionalArguments(); const QStringList args = parser.positionalArguments();
if (args.size() != 1 && args.size() != 2) { if (args.size() != 1 && args.size() != 2) {
out << parser.helpText().replace("keepassxc-cli", "keepassxc-cli ls"); errorTextStream << parser.helpText().replace("keepassxc-cli", "keepassxc-cli ls");
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -80,20 +80,20 @@ int List::execute(const QStringList& arguments)
int List::listGroup(Database* database, bool recursive, const QString& groupPath) int List::listGroup(Database* database, bool recursive, const QString& groupPath)
{ {
TextStream out(Utils::STDOUT, QIODevice::WriteOnly); TextStream outputTextStream(Utils::STDOUT, QIODevice::WriteOnly);
TextStream err(Utils::STDERR, QIODevice::WriteOnly); TextStream errorTextStream(Utils::STDERR, QIODevice::WriteOnly);
if (groupPath.isEmpty()) { if (groupPath.isEmpty()) {
out << database->rootGroup()->print(recursive) << flush; outputTextStream << database->rootGroup()->print(recursive) << flush;
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
Group* group = database->rootGroup()->findGroupByPath(groupPath); Group* group = database->rootGroup()->findGroupByPath(groupPath);
if (!group) { if (!group) {
err << QObject::tr("Cannot find group %1.").arg(groupPath) << endl; errorTextStream << QObject::tr("Cannot find group %1.").arg(groupPath) << endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
out << group->print(recursive) << flush; outputTextStream << group->print(recursive) << flush;
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }

View file

@ -42,7 +42,7 @@ Locate::~Locate()
int Locate::execute(const QStringList& arguments) int Locate::execute(const QStringList& arguments)
{ {
TextStream out(Utils::STDOUT, QIODevice::WriteOnly); TextStream errorTextStream(Utils::STDERR, QIODevice::WriteOnly);
QCommandLineParser parser; QCommandLineParser parser;
parser.setApplicationDescription(description); parser.setApplicationDescription(description);
@ -55,7 +55,7 @@ int Locate::execute(const QStringList& arguments)
const QStringList args = parser.positionalArguments(); const QStringList args = parser.positionalArguments();
if (args.size() != 2) { if (args.size() != 2) {
out << parser.helpText().replace("keepassxc-cli", "keepassxc-cli locate"); errorTextStream << parser.helpText().replace("keepassxc-cli", "keepassxc-cli locate");
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -72,17 +72,17 @@ int Locate::execute(const QStringList& arguments)
int Locate::locateEntry(Database* database, const QString& searchTerm) int Locate::locateEntry(Database* database, const QString& searchTerm)
{ {
TextStream out(Utils::STDOUT, QIODevice::WriteOnly); TextStream outputTextStream(Utils::STDOUT, QIODevice::WriteOnly);
TextStream err(Utils::STDERR, QIODevice::WriteOnly); TextStream errorTextStream(Utils::STDERR, QIODevice::WriteOnly);
QStringList results = database->rootGroup()->locate(searchTerm); QStringList results = database->rootGroup()->locate(searchTerm);
if (results.isEmpty()) { if (results.isEmpty()) {
err << "No results for that search term." << endl; errorTextStream << "No results for that search term." << endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
for (const QString& result : asConst(results)) { for (const QString& result : asConst(results)) {
out << result << endl; outputTextStream << result << endl;
} }
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }

View file

@ -38,8 +38,8 @@ Merge::~Merge()
int Merge::execute(const QStringList& arguments) int Merge::execute(const QStringList& arguments)
{ {
TextStream out(Utils::STDOUT, QIODevice::WriteOnly); TextStream outputTextStream(Utils::STDOUT, QIODevice::WriteOnly);
TextStream err(Utils::STDERR, QIODevice::WriteOnly); TextStream errorTextStream(Utils::STDERR, QIODevice::WriteOnly);
QCommandLineParser parser; QCommandLineParser parser;
parser.setApplicationDescription(description); parser.setApplicationDescription(description);
@ -64,7 +64,7 @@ int Merge::execute(const QStringList& arguments)
const QStringList args = parser.positionalArguments(); const QStringList args = parser.positionalArguments();
if (args.size() != 2) { if (args.size() != 2) {
out << parser.helpText().replace("keepassxc-cli", "keepassxc-cli merge"); errorTextStream << parser.helpText().replace("keepassxc-cli", "keepassxc-cli merge");
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -83,7 +83,7 @@ int Merge::execute(const QStringList& arguments)
db2 = QSharedPointer<Database>::create(); db2 = QSharedPointer<Database>::create();
QString errorMessage; QString errorMessage;
if (!db2->open(args.at(1), db1->key(), &errorMessage, false)) { if (!db2->open(args.at(1), db1->key(), &errorMessage, false)) {
err << QObject::tr("Error reading merge file:\n%1").arg(errorMessage); errorTextStream << QObject::tr("Error reading merge file:\n%1").arg(errorMessage);
return EXIT_FAILURE; return EXIT_FAILURE;
} }
} }
@ -94,14 +94,14 @@ int Merge::execute(const QStringList& arguments)
if (databaseChanged) { if (databaseChanged) {
QString errorMessage; QString errorMessage;
if (!db1->save(args.at(0), &errorMessage, true, false)) { if (!db1->save(args.at(0), &errorMessage, true, false)) {
err << QObject::tr("Unable to save database to file : %1").arg(errorMessage) << endl; errorTextStream << QObject::tr("Unable to save database to file : %1").arg(errorMessage) << endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
if (!parser.isSet(Command::QuietOption)) { if (!parser.isSet(Command::QuietOption)) {
out << "Successfully merged the database files." << endl; outputTextStream << "Successfully merged the database files." << endl;
} }
} else if (!parser.isSet(Command::QuietOption)) { } else if (!parser.isSet(Command::QuietOption)) {
out << "Database was not modified by merge operation." << endl; outputTextStream << "Database was not modified by merge operation." << endl;
} }
return EXIT_SUCCESS; return EXIT_SUCCESS;

View file

@ -44,7 +44,7 @@ Remove::~Remove()
int Remove::execute(const QStringList& arguments) int Remove::execute(const QStringList& arguments)
{ {
TextStream out(Utils::STDERR, QIODevice::WriteOnly); TextStream errorTextStream(Utils::STDERR, QIODevice::WriteOnly);
QCommandLineParser parser; QCommandLineParser parser;
parser.setApplicationDescription(QCoreApplication::tr("main", "Remove an entry from the database.")); parser.setApplicationDescription(QCoreApplication::tr("main", "Remove an entry from the database."));
@ -57,7 +57,7 @@ int Remove::execute(const QStringList& arguments)
const QStringList args = parser.positionalArguments(); const QStringList args = parser.positionalArguments();
if (args.size() != 2) { if (args.size() != 2) {
out << parser.helpText().replace("keepassxc-cli", "keepassxc-cli rm"); errorTextStream << parser.helpText().replace("keepassxc-cli", "keepassxc-cli rm");
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -74,12 +74,12 @@ int Remove::execute(const QStringList& arguments)
int Remove::removeEntry(Database* database, const QString& databasePath, const QString& entryPath, bool quiet) int Remove::removeEntry(Database* database, const QString& databasePath, const QString& entryPath, bool quiet)
{ {
TextStream out(quiet ? Utils::DEVNULL : Utils::STDOUT, QIODevice::WriteOnly); TextStream outputTextStream(quiet ? Utils::DEVNULL : Utils::STDOUT, QIODevice::WriteOnly);
TextStream err(Utils::STDERR, QIODevice::WriteOnly); TextStream errorTextStream(Utils::STDERR, QIODevice::WriteOnly);
QPointer<Entry> entry = database->rootGroup()->findEntryByPath(entryPath); QPointer<Entry> entry = database->rootGroup()->findEntryByPath(entryPath);
if (!entry) { if (!entry) {
err << QObject::tr("Entry %1 not found.").arg(entryPath) << endl; errorTextStream << QObject::tr("Entry %1 not found.").arg(entryPath) << endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -95,14 +95,14 @@ int Remove::removeEntry(Database* database, const QString& databasePath, const Q
QString errorMessage; QString errorMessage;
if (!database->save(databasePath, &errorMessage, true, false)) { if (!database->save(databasePath, &errorMessage, true, false)) {
err << QObject::tr("Unable to save database to file: %1").arg(errorMessage) << endl; errorTextStream << QObject::tr("Unable to save database to file: %1").arg(errorMessage) << endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
if (recycled) { if (recycled) {
out << QObject::tr("Successfully recycled entry %1.").arg(entryTitle) << endl; outputTextStream << QObject::tr("Successfully recycled entry %1.").arg(entryTitle) << endl;
} else { } else {
out << QObject::tr("Successfully deleted entry %1.").arg(entryTitle) << endl; outputTextStream << QObject::tr("Successfully deleted entry %1.").arg(entryTitle) << endl;
} }
return EXIT_SUCCESS; return EXIT_SUCCESS;

View file

@ -41,7 +41,7 @@ Show::~Show()
int Show::execute(const QStringList& arguments) int Show::execute(const QStringList& arguments)
{ {
TextStream out(Utils::STDOUT); TextStream errorTextStream(Utils::STDERR, QIODevice::WriteOnly);
QCommandLineParser parser; QCommandLineParser parser;
parser.setApplicationDescription(description); parser.setApplicationDescription(description);
@ -67,7 +67,7 @@ int Show::execute(const QStringList& arguments)
const QStringList args = parser.positionalArguments(); const QStringList args = parser.positionalArguments();
if (args.size() != 2) { if (args.size() != 2) {
out << parser.helpText().replace("keepassxc-cli", "keepassxc-cli show"); errorTextStream << parser.helpText().replace("keepassxc-cli", "keepassxc-cli show");
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -84,18 +84,17 @@ int Show::execute(const QStringList& arguments)
int Show::showEntry(Database* database, QStringList attributes, bool showTotp, const QString& entryPath) int Show::showEntry(Database* database, QStringList attributes, bool showTotp, const QString& entryPath)
{ {
TextStream in(Utils::STDIN, QIODevice::ReadOnly); TextStream outputTextStream(Utils::STDOUT, QIODevice::WriteOnly);
TextStream out(Utils::STDOUT, QIODevice::WriteOnly); TextStream errorTextStream(Utils::STDERR, QIODevice::WriteOnly);
TextStream err(Utils::STDERR, QIODevice::WriteOnly);
Entry* entry = database->rootGroup()->findEntryByPath(entryPath); Entry* entry = database->rootGroup()->findEntryByPath(entryPath);
if (!entry) { if (!entry) {
err << QObject::tr("Could not find entry with path %1.").arg(entryPath) << endl; errorTextStream << QObject::tr("Could not find entry with path %1.").arg(entryPath) << endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
if (showTotp && !entry->hasTotp()) { if (showTotp && !entry->hasTotp()) {
err << QObject::tr("Entry with path %1 has no TOTP set up.").arg(entryPath) << endl; errorTextStream << QObject::tr("Entry with path %1 has no TOTP set up.").arg(entryPath) << endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -110,20 +109,20 @@ int Show::showEntry(Database* database, QStringList attributes, bool showTotp, c
for (const QString& attribute : asConst(attributes)) { for (const QString& attribute : asConst(attributes)) {
if (!entry->attributes()->contains(attribute)) { if (!entry->attributes()->contains(attribute)) {
sawUnknownAttribute = true; sawUnknownAttribute = true;
err << QObject::tr("ERROR: unknown attribute %1.").arg(attribute) << endl; errorTextStream << QObject::tr("ERROR: unknown attribute %1.").arg(attribute) << endl;
continue; continue;
} }
if (showAttributeNames) { if (showAttributeNames) {
out << attribute << ": "; outputTextStream << attribute << ": ";
} }
out << entry->resolveMultiplePlaceholders(entry->attributes()->value(attribute)) << endl; outputTextStream << entry->resolveMultiplePlaceholders(entry->attributes()->value(attribute)) << endl;
} }
if (showTotp) { if (showTotp) {
if (showAttributeNames) { if (showAttributeNames) {
out << "TOTP: "; outputTextStream << "TOTP: ";
} }
out << entry->totp() << endl; outputTextStream << entry->totp() << endl;
} }
return sawUnknownAttribute ? EXIT_FAILURE : EXIT_SUCCESS; return sawUnknownAttribute ? EXIT_FAILURE : EXIT_SUCCESS;