mirror of
https://github.com/keepassxreboot/keepassxc.git
synced 2025-01-14 08:50:08 -05:00
parent
cc6f5c3226
commit
60adcacaaa
@ -307,13 +307,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();
|
||||
}
|
||||
|
||||
@ -326,6 +339,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;
|
||||
@ -338,13 +357,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));
|
||||
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.waitForDisconnected(WaitTimeoutMSec);
|
||||
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)); // 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.state() == QLocalSocket::UnconnectedState || client.waitForConnected(WaitTimeoutMSec);
|
||||
return writeOk && disconnected;
|
||||
}
|
||||
|
||||
|
@ -50,6 +50,7 @@ public:
|
||||
bool isDarkTheme() const;
|
||||
|
||||
bool sendFileNamesToRunningInstance(const QStringList& fileNames);
|
||||
bool sendLockToInstance();
|
||||
|
||||
void restart();
|
||||
|
||||
|
19
src/main.cpp
19
src/main.cpp
@ -71,6 +71,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"));
|
||||
QCommandLineOption allowScreenCaptureOption("allow-screencapture",
|
||||
@ -81,6 +82,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);
|
||||
@ -110,12 +112,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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user