-
Notifications
You must be signed in to change notification settings - Fork 767
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
IPC and custom protocol handler for monero://
- Loading branch information
1 parent
02e1663
commit 557294f
Showing
10 changed files
with
288 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
#include <sys/socket.h> | ||
|
||
#include <QCoreApplication> | ||
#include <QLocalSocket> | ||
#include <QLocalServer> | ||
#include <QtNetwork> | ||
#include <QDebug> | ||
|
||
#include "ipc.h" | ||
|
||
// Start listening for incoming IPC commands on UDS (Unix) or named pipe (Windows) | ||
void IPC::bind(){ | ||
QString path = QString(this->m_socketFile.absoluteFilePath()); | ||
qDebug() << path; | ||
|
||
this->m_server = new QLocalServer(this); | ||
this->m_server->setSocketOptions(QLocalServer::UserAccessOption); | ||
|
||
bool restarted = false; | ||
if(!this->m_server->listen(path)){ | ||
// On Unix if the server crashes without closing listen will fail with AddressInUseError. | ||
// To create a new server the file should be removed. On Windows two local servers can listen | ||
// to the same pipe at the same time, but any connections will go to one of the server. | ||
#ifdef Q_OS_UNIX | ||
qDebug() << QString("Unable to start IPC server in \"%1\": \"%2\". Retrying.").arg(path).arg(this->m_server->errorString()); | ||
if(this->m_socketFile.exists()){ | ||
QFile file(path); | ||
file.remove(); | ||
|
||
if(this->m_server->listen(path)){ | ||
restarted = true; | ||
} | ||
} | ||
#endif | ||
if(!restarted) | ||
qDebug() << QString("Unable to start IPC server in \"%1\": \"%2\".").arg(path).arg(this->m_server->errorString()); | ||
} | ||
|
||
connect(this->m_server, &QLocalServer::newConnection, this, &IPC::handleConnection); | ||
} | ||
|
||
// Process incoming IPC command. First check if monero-wallet-gui is | ||
// already running. If it is, send it to that instance instead, if not, | ||
// queue the command for later use inside our QML engine. Returns true | ||
// when queued, false if sent to another instance, at which point we can | ||
// kill the current process. | ||
bool IPC::saveCommand(QString cmdString){ | ||
QLocalSocket ls; | ||
QByteArray buffer; | ||
buffer = buffer.append(cmdString); | ||
QString socketFilePath = this->socketFile().filePath(); | ||
|
||
ls.connectToServer(socketFilePath, QIODevice::WriteOnly); | ||
if(ls.waitForConnected(1000)){ | ||
ls.write(buffer); | ||
if (!ls.waitForBytesWritten(1000)){ | ||
qDebug() << QString("Could not send command \"%1\" over IPC %2: \"%3\"").arg(cmdString, socketFilePath, ls.errorString()); | ||
return false; | ||
} | ||
|
||
qDebug() << QString("Sent command \"%1\" over IPC \"%2\"").arg(cmdString, socketFilePath); | ||
return false; | ||
} | ||
|
||
if(ls.isOpen()) | ||
ls.disconnectFromServer(); | ||
|
||
// Queue for later | ||
this->SetQueuedCmd(cmdString); | ||
return true; | ||
} | ||
|
||
void IPC::handleConnection(){ | ||
QLocalSocket *clientConnection = this->m_server->nextPendingConnection(); | ||
connect(clientConnection, &QLocalSocket::disconnected, | ||
clientConnection, &QLocalSocket::deleteLater); | ||
|
||
clientConnection->waitForReadyRead(2); | ||
QByteArray cmdArray = clientConnection->readAll(); | ||
QString cmdString = QTextCodec::codecForMib(106)->toUnicode(cmdArray); // UTF-8 | ||
qDebug() << cmdString; | ||
|
||
this->parseCommand(cmdString); | ||
|
||
clientConnection->close(); | ||
delete clientConnection; | ||
} | ||
|
||
void IPC::parseCommand(QString cmdString){ | ||
// Detect URI string | ||
if(cmdString.contains(QRegExp("^\\w+:\\/\\/(.*)$"))){ | ||
this->emitUriHandler(cmdString); | ||
} | ||
} | ||
|
||
void IPC::emitUriHandler(QString uriString){ | ||
emit uriHandler(uriString); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
#ifndef IPC_H | ||
#define IPC_H | ||
|
||
#include <QtCore> | ||
#include <QLocalServer> | ||
#include <qt/utils.h> | ||
|
||
class IPC : public QObject | ||
{ | ||
Q_OBJECT | ||
public: | ||
IPC(QObject *parent = 0) : QObject(parent) {} | ||
QFileInfo socketFile() const { return m_socketFile; } | ||
Q_INVOKABLE QString queuedCmd() { return m_queuedCmd; } | ||
void SetQueuedCmd(const QString cmdString) { m_queuedCmd = cmdString; } | ||
|
||
public slots: | ||
void bind(); | ||
void handleConnection(); | ||
bool saveCommand(QString cmdString); | ||
void parseCommand(QString cmdString); | ||
void emitUriHandler(QString uriString); | ||
|
||
signals: | ||
void uriHandler(QString uriString); | ||
|
||
private: | ||
QLocalServer *m_server; | ||
QString m_queuedCmd; | ||
QFileInfo m_socketFile = QFileInfo(QString(QDir::tempPath() + "/monero-wallet-gui_%2.sock").arg(getAccountName())); | ||
}; | ||
|
||
#endif // IPC_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
#include <QtCore> | ||
#include <QApplication> | ||
#include <QFile> | ||
#include <QTextStream> | ||
|
||
#include "mime.h" | ||
#include "utils.h" | ||
|
||
void registerMime(QApplication &app){ | ||
#ifdef Q_OS_LINUX | ||
QString xdg = QString( | ||
"[Desktop Entry]\n" | ||
"Name=Monero GUI\n" | ||
"GenericName=Monero-GUI\n" | ||
"X-GNOME-FullName=Monero-GUI\n" | ||
"Comment=Monero GUI\n" | ||
"Keywords=Monero;\n" | ||
"Exec=%1 --ipc %u\n" | ||
"Terminal=false\n" | ||
"Type=Application\n" | ||
"Icon=monero\n" | ||
"Categories=Network;GNOME;Qt;\n" | ||
"MimeType=x-scheme-handler/monero;x-scheme-handler/moneroseed\n" | ||
"StartupNotify=true\n" | ||
"X-GNOME-Bugzilla-Bugzilla=GNOME\n" | ||
"X-GNOME-UsesNotifications=true\n" | ||
).arg(app.applicationFilePath()); | ||
|
||
QString appPath = QStandardPaths::writableLocation(QStandardPaths::ApplicationsLocation); | ||
QString filePath = QString("%1/monero-gui.desktop").arg(appPath); | ||
|
||
qDebug() << QString("Writing %1").arg(filePath); | ||
QFile file(filePath); | ||
if(file.open(QIODevice::WriteOnly)){ | ||
QTextStream out(&file); out << xdg << endl; | ||
file.close(); | ||
} | ||
else | ||
file.close(); | ||
#endif | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
#ifndef MIME_H | ||
#define MIME_H | ||
|
||
#include <QApplication> | ||
|
||
void registerMime(QApplication &app); | ||
|
||
#endif // MIME_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
#include <QtCore> | ||
#include "utils.h" | ||
|
||
bool fileExists(QString path) { | ||
QFileInfo check_file(path); | ||
// check if file exists and if yes: Is it really a file and no directory? | ||
if (check_file.exists() && check_file.isFile()) { | ||
return true; | ||
} else { | ||
return false; | ||
} | ||
} | ||
|
||
QString getAccountName(){ | ||
QString accountName = qgetenv("USER"); // mac/linux | ||
if (accountName.isEmpty()) | ||
accountName = qgetenv("USERNAME"); // Windows | ||
if (accountName.isEmpty()) | ||
accountName = "My monero Account"; | ||
return accountName; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
#ifndef UTILS_H | ||
#define UTILS_H | ||
|
||
#include <QtCore> | ||
|
||
|
||
bool fileExists(QString path); | ||
QString getAccountName(); | ||
|
||
#endif // UTILS_H |