Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/keepassxreboot/keepassxc.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwundrweapon <wundrweapon@users.noreply.github.com>2021-05-15 16:48:59 +0300
committerJonathan White <support@dmapps.us>2021-05-30 15:44:09 +0300
commitaaf8f188521a1742ded2fbd104cd594191d43a75 (patch)
tree569037f06f47f59a928b9dd2232c7596042bf67c
parent29de94b65674559b55102b8ec4ddbaf06364a274 (diff)
Add command line option to lock open databases (#6511)
Closes #6126
-rw-r--r--src/gui/Application.cpp70
-rw-r--r--src/gui/Application.h1
-rw-r--r--src/main.cpp19
3 files changed, 79 insertions, 11 deletions
diff --git a/src/gui/Application.cpp b/src/gui/Application.cpp
index 784528294..973e29032 100644
--- a/src/gui/Application.cpp
+++ b/src/gui/Application.cpp
@@ -286,13 +286,26 @@ void Application::socketReadyRead()
}
QStringList fileNames;
- in >> fileNames;
- for (const QString& fileName : asConst(fileNames)) {
- const QFileInfo fInfo(fileName);
- if (fInfo.isFile() && fInfo.suffix().toLower() == "kdbx") {
- emit openFile(fileName);
+ quint32 id;
+ in >> id;
+
+ // TODO: move constants to enum
+ switch (id) {
+ case 1:
+ in >> fileNames;
+ for (const QString& fileName : asConst(fileNames)) {
+ const QFileInfo fInfo(fileName);
+ if (fInfo.isFile() && fInfo.suffix().toLower() == "kdbx") {
+ emit openFile(fileName);
+ }
}
+
+ break;
+ case 2:
+ getMainWindow()->lockAllDatabases();
+ break;
}
+
socket->deleteLater();
}
@@ -305,6 +318,12 @@ bool Application::isAlreadyRunning() const
return config()->get(Config::SingleInstance).toBool() && m_alreadyRunning;
}
+/**
+ * Send to-open file names to the running UI instance
+ *
+ * @param fileNames - list of file names to open
+ * @return true if all operations succeeded (connection made, data sent, connection closed)
+ */
bool Application::sendFileNamesToRunningInstance(const QStringList& fileNames)
{
QLocalSocket client;
@@ -317,13 +336,48 @@ bool Application::sendFileNamesToRunningInstance(const QStringList& fileNames)
QByteArray data;
QDataStream out(&data, QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_5_0);
- out << quint32(0) << fileNames;
+ out << quint32(0); // reserve space for block size
+ out << quint32(1); // ID for file name send. TODO: move to enum
+ out << fileNames; // send file names to be opened
+ out.device()->seek(0);
+ out << quint32(data.size() - sizeof(quint32)); // replace the previous constant 0 with block size
+
+ const bool writeOk = client.write(data) != -1 && client.waitForBytesWritten(WaitTimeoutMSec);
+ client.disconnectFromServer();
+ const bool disconnected =
+ client.state() == QLocalSocket::UnconnectedState || client.waitForDisconnected(WaitTimeoutMSec);
+ return writeOk && disconnected;
+}
+
+/**
+ * Locks all open databases in the running instance
+ *
+ * @return true if the "please lock" signal was sent successfully
+ */
+bool Application::sendLockToInstance()
+{
+ // Make a connection to avoid SIGSEGV
+ QLocalSocket client;
+ client.connectToServer(m_socketName);
+ const bool connected = client.waitForConnected(WaitTimeoutMSec);
+ if (!connected) {
+ return false;
+ }
+
+ // Send lock signal
+ QByteArray data;
+ QDataStream out(&data, QIODevice::WriteOnly);
+ out.setVersion(QDataStream::Qt_5_0);
+ out << quint32(0); // reserve space for block size
+ out << quint32(2); // ID for database lock. TODO: move to enum
out.device()->seek(0);
- out << quint32(data.size() - sizeof(quint32));
+ out << quint32(data.size() - sizeof(quint32)); // replace the previous constant 0 with block size
+ // Finish gracefully
const bool writeOk = client.write(data) != -1 && client.waitForBytesWritten(WaitTimeoutMSec);
client.disconnectFromServer();
- const bool disconnected = client.waitForDisconnected(WaitTimeoutMSec);
+ const bool disconnected =
+ client.state() == QLocalSocket::UnconnectedState || client.waitForConnected(WaitTimeoutMSec);
return writeOk && disconnected;
}
diff --git a/src/gui/Application.h b/src/gui/Application.h
index 9f694f8c3..f6c35a037 100644
--- a/src/gui/Application.h
+++ b/src/gui/Application.h
@@ -48,6 +48,7 @@ public:
bool isDarkTheme() const;
bool sendFileNamesToRunningInstance(const QStringList& fileNames);
+ bool sendLockToInstance();
void restart();
diff --git a/src/main.cpp b/src/main.cpp
index b88dc41e0..43f9d0992 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -64,6 +64,7 @@ int main(int argc, char** argv)
QCommandLineOption configOption("config", QObject::tr("path to a custom config file"), "config");
QCommandLineOption localConfigOption(
"localconfig", QObject::tr("path to a custom local config file"), "localconfig");
+ QCommandLineOption lockOption("lock", QObject::tr("lock all open databases"));
QCommandLineOption keyfileOption("keyfile", QObject::tr("key file of the database"), "keyfile");
QCommandLineOption pwstdinOption("pw-stdin", QObject::tr("read password of the database from stdin"));
@@ -72,6 +73,7 @@ int main(int argc, char** argv)
QCommandLineOption debugInfoOption(QStringList() << "debug-info", QObject::tr("Displays debugging information."));
parser.addOption(configOption);
parser.addOption(localConfigOption);
+ parser.addOption(lockOption);
parser.addOption(keyfileOption);
parser.addOption(pwstdinOption);
parser.addOption(debugInfoOption);
@@ -96,12 +98,23 @@ int main(int argc, char** argv)
}
// Process single instance and early exit if already running
+ // FIXME: this is a *mess* and it is entirely my fault. --wundrweapon
const QStringList fileNames = parser.positionalArguments();
if (app.isAlreadyRunning()) {
- if (!fileNames.isEmpty()) {
- app.sendFileNamesToRunningInstance(fileNames);
+ if (parser.isSet(lockOption)) {
+ if (app.sendLockToInstance()) {
+ qInfo() << QObject::tr("Locked databases.").toUtf8().constData();
+ } else {
+ qWarning() << QObject::tr("Database failed to lock.").toUtf8().constData();
+ return EXIT_FAILURE;
+ }
+ } else {
+ if (!fileNames.isEmpty()) {
+ app.sendFileNamesToRunningInstance(fileNames);
+ }
+
+ qWarning() << QObject::tr("Another instance of KeePassXC is already running.").toUtf8().constData();
}
- qWarning() << QObject::tr("Another instance of KeePassXC is already running.").toUtf8().constData();
return EXIT_SUCCESS;
}