initial commit
This commit is contained in:
commit
2bc3e27906
6 changed files with 306 additions and 0 deletions
4
.gitmodules
vendored
Normal file
4
.gitmodules
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
[submodule "src/3rdparty/qxmpp"]
|
||||
path = src/3rdparty/qxmpp
|
||||
url = https://github.com/qxmpp-project/qxmpp.git
|
||||
branch = 1.4
|
27
CMakeLists.txt
Normal file
27
CMakeLists.txt
Normal file
|
@ -0,0 +1,27 @@
|
|||
cmake_minimum_required(VERSION 3.7)
|
||||
|
||||
project(xmppbot LANGUAGES CXX)
|
||||
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
|
||||
set(CMAKE_AUTOUIC ON)
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_AUTORCC ON)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED)
|
||||
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Network REQUIRED)
|
||||
|
||||
add_subdirectory(src/3rdparty/qxmpp)
|
||||
add_executable(xmppbot
|
||||
src/xmppbot/main.cpp
|
||||
src/xmppbot/unixsocket.cpp
|
||||
src/xmppbot/unixsocket.h
|
||||
)
|
||||
add_dependencies(xmppbot qxmpp)
|
||||
|
||||
target_link_libraries(xmppbot Qt${QT_VERSION_MAJOR}::Network qxmpp)
|
||||
|
||||
install(TARGETS xmppbot DESTINATION bin)
|
1
src/3rdparty/qxmpp
vendored
Submodule
1
src/3rdparty/qxmpp
vendored
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit 6d778d84fd2faac6a899a1c70f2dcb9bd4e0b164
|
183
src/xmppbot/main.cpp
Normal file
183
src/xmppbot/main.cpp
Normal file
|
@ -0,0 +1,183 @@
|
|||
/*****************************************************************************
|
||||
* xmppbot Simple unix socket based XMPP bot
|
||||
* Copyright (C) 2021 Syping
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* This software is provided as-is, no warranties are given to you, we are not
|
||||
* responsible for anything with use of the software, you are self responsible.
|
||||
*****************************************************************************/
|
||||
|
||||
#include <QCommandLineParser>
|
||||
#include <QCoreApplication>
|
||||
#include <QLocalServer>
|
||||
#include <QLocalSocket>
|
||||
#include <QTextStream>
|
||||
#include <QSettings>
|
||||
#include <QProcess>
|
||||
#include <QFile>
|
||||
|
||||
#include "unixsocket.h"
|
||||
#include "QXmppClient.h"
|
||||
#include "QXmppMessage.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QCoreApplication app(argc, argv);
|
||||
app.setApplicationName("xmppbot");
|
||||
app.setApplicationVersion("0.1");
|
||||
|
||||
QCommandLineParser commandLineParser;
|
||||
commandLineParser.addPositionalArgument("config", QCoreApplication::translate("xmppbot", "Configuration file."));
|
||||
commandLineParser.addHelpOption();
|
||||
commandLineParser.addVersionOption();
|
||||
commandLineParser.process(app);
|
||||
|
||||
QString settingsPath = QLatin1String("settings.ini");
|
||||
const QStringList args = commandLineParser.positionalArguments();
|
||||
if (args.length() == 1) {
|
||||
const QString a_settingsPath = args.at(0);
|
||||
if (QFile::exists(a_settingsPath)) {
|
||||
settingsPath = a_settingsPath;
|
||||
}
|
||||
else {
|
||||
QTextStream(stderr) << "xmppbot: " << a_settingsPath << " not found!" << Qt::endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
QXmppClient client;
|
||||
|
||||
bool loginSet = false;
|
||||
QString jid, jpw;
|
||||
QHash<QString, QString> h_msg;
|
||||
QHash<QString, QString> h_run;
|
||||
if (QFile::exists(settingsPath)) {
|
||||
QSettings settings(settingsPath, QSettings::IniFormat);
|
||||
for (const QString &group : settings.childGroups()) {
|
||||
settings.beginGroup(group);
|
||||
for (const QString &key : settings.childKeys()) {
|
||||
if (key == "Password") {
|
||||
if (!loginSet) {
|
||||
jid = group;
|
||||
jpw = settings.value(key, QString()).toString();
|
||||
loginSet = true;
|
||||
}
|
||||
else {
|
||||
QTextStream(stderr) << "xmppbot: Login password can only be set once!" << Qt::endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (key == "UnixSocket") {
|
||||
UnixSocket *unixSocket = new UnixSocket(&client, jid, group);
|
||||
const QString permission = settings.value("SocketPermission", QString()).toString();
|
||||
if (permission == "UG" || permission == "UserGroup") {
|
||||
unixSocket->setSocketOptions(QLocalServer::UserAccessOption | QLocalServer::GroupAccessOption);
|
||||
}
|
||||
if (permission == "UO" || permission == "UserOther") {
|
||||
unixSocket->setSocketOptions(QLocalServer::UserAccessOption | QLocalServer::OtherAccessOption);
|
||||
}
|
||||
if (permission == "U" || permission == "User") {
|
||||
unixSocket->setSocketOptions(QLocalServer::UserAccessOption);
|
||||
}
|
||||
if (permission == "GO" || permission == "GroupOther") {
|
||||
unixSocket->setSocketOptions(QLocalServer::GroupAccessOption | QLocalServer::OtherAccessOption);
|
||||
}
|
||||
if (permission == "G" || permission == "Group") {
|
||||
unixSocket->setSocketOptions(QLocalServer::GroupAccessOption);
|
||||
}
|
||||
if (permission == "O" || permission == "Other") {
|
||||
unixSocket->setSocketOptions(QLocalServer::OtherAccessOption);
|
||||
}
|
||||
if (permission == "A" || permission == "All" || permission == "UGO" || permission == "UserGroupOther") {
|
||||
unixSocket->setSocketOptions(QLocalServer::WorldAccessOption);
|
||||
}
|
||||
const QString socketPath = settings.value(key, QString()).toString();
|
||||
bool listen = unixSocket->listen(socketPath);
|
||||
#ifdef Q_OS_UNIX
|
||||
if (!listen) {
|
||||
QLocalServer::removeServer(socketPath);
|
||||
listen = unixSocket->listen(socketPath);
|
||||
}
|
||||
#endif
|
||||
if (listen) {
|
||||
QTextStream(stderr) << "xmppbot: Account socket " << group << " initialised" << Qt::endl;
|
||||
const QString incoming = settings.value("Incoming", QString()).toString();
|
||||
if (incoming.startsWith("message:")) {
|
||||
QTextStream(stderr) << "xmppbot: Account message incoming " << group << " initialised" << Qt::endl;
|
||||
h_msg.insert(group, incoming.mid(8));
|
||||
}
|
||||
if (incoming.startsWith("run:")) {
|
||||
QTextStream(stderr) << "xmppbot: Account run incoming " << group << " initialised" << Qt::endl;
|
||||
h_run.insert(group, incoming.mid(4));
|
||||
}
|
||||
}
|
||||
else {
|
||||
delete unixSocket;
|
||||
}
|
||||
}
|
||||
}
|
||||
settings.endGroup();
|
||||
}
|
||||
}
|
||||
else {
|
||||
QTextStream(stderr) << "xmppbot: Can't initialise without settings.ini!" << Qt::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (jid.isEmpty() || jpw.isEmpty()) {
|
||||
QTextStream(stderr) << "xmppbot: Can't initialise without XMPP account!" << Qt::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
QObject::connect(&client, &QXmppClient::connected, [&]() {
|
||||
QTextStream(stderr) << "xmppbot: Account " << jid << " connected" << Qt::endl;
|
||||
QXmppPresence xmppPresence(QXmppPresence::Available);
|
||||
client.setClientPresence(xmppPresence);
|
||||
});
|
||||
|
||||
QObject::connect(&client, &QXmppClient::disconnected, [&]() {
|
||||
QTextStream(stderr) << "xmppbot: Account " << jid << " disconnected" << Qt::endl;
|
||||
client.connectToServer(jid, jpw);
|
||||
});
|
||||
|
||||
QObject::connect(&client, &QXmppClient::messageReceived, [&](const QXmppMessage &xmppMessage) {
|
||||
const QString body = xmppMessage.body();
|
||||
if (body.isEmpty())
|
||||
return;
|
||||
const QString from = xmppMessage.from();
|
||||
QString from_jid;
|
||||
for (const QChar &val : from) {
|
||||
if (val == '/')
|
||||
break;
|
||||
from_jid += val;
|
||||
}
|
||||
const QString msg = h_msg.value(from_jid, QString());
|
||||
if (!msg.isEmpty()) {
|
||||
QXmppMessage xmppMessage(jid, from, msg);
|
||||
client.sendPacket(xmppMessage);
|
||||
}
|
||||
const QString run = h_run.value(from_jid, QString());
|
||||
if (!run.isEmpty()) {
|
||||
qint64 pid;
|
||||
bool isStarted = QProcess::startDetached(run, QStringList() << from << xmppMessage.to() << xmppMessage.body(), QString(), &pid);
|
||||
if (isStarted) {
|
||||
QTextStream(stderr) << "xmppbot: Account " << from_jid << " executed pid " << pid << Qt::endl;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
client.connectToServer(jid, jpw);
|
||||
|
||||
QTextStream(stderr) << "xmppbot: Account login " << jid << " initialised" << Qt::endl;
|
||||
|
||||
return app.exec();
|
||||
}
|
46
src/xmppbot/unixsocket.cpp
Normal file
46
src/xmppbot/unixsocket.cpp
Normal file
|
@ -0,0 +1,46 @@
|
|||
/*****************************************************************************
|
||||
* xmppbot Simple unix socket based XMPP bot
|
||||
* Copyright (C) 2021 Syping
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* This software is provided as-is, no warranties are given to you, we are not
|
||||
* responsible for anything with use of the software, you are self responsible.
|
||||
*****************************************************************************/
|
||||
|
||||
#include <QLocalSocket>
|
||||
|
||||
#include "unixsocket.h"
|
||||
#include "QXmppMessage.h"
|
||||
|
||||
UnixSocket::UnixSocket(QXmppClient *client, const QString &from, const QString &to) : client(client), from(from), to(to)
|
||||
{
|
||||
}
|
||||
|
||||
void UnixSocket::readyRead()
|
||||
{
|
||||
QLocalSocket *localSocket = qobject_cast<QLocalSocket*>(sender());
|
||||
if (localSocket) {
|
||||
const QString message = QString::fromUtf8(localSocket->readAll());
|
||||
if (!message.isEmpty()) {
|
||||
QXmppMessage xmppMessage(from, to, message);
|
||||
client->sendPacket(xmppMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UnixSocket::incomingConnection(quintptr socketDescriptor)
|
||||
{
|
||||
QLocalSocket *localSocket = new QLocalSocket(this);
|
||||
localSocket->setSocketDescriptor(socketDescriptor);
|
||||
QObject::connect(localSocket, &QLocalSocket::readyRead, this, &UnixSocket::readyRead);
|
||||
QObject::connect(localSocket, &QLocalSocket::disconnected, localSocket, &QLocalSocket::deleteLater);
|
||||
}
|
45
src/xmppbot/unixsocket.h
Normal file
45
src/xmppbot/unixsocket.h
Normal file
|
@ -0,0 +1,45 @@
|
|||
/*****************************************************************************
|
||||
* xmppbot Simple unix socket based XMPP bot
|
||||
* Copyright (C) 2021 Syping
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* This software is provided as-is, no warranties are given to you, we are not
|
||||
* responsible for anything with use of the software, you are self responsible.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef UNIXSOCKET_H
|
||||
#define UNIXSOCKET_H
|
||||
|
||||
#include <QLocalServer>
|
||||
#include <QObject>
|
||||
|
||||
#include "QXmppClient.h"
|
||||
|
||||
class UnixSocket : public QLocalServer
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
UnixSocket(QXmppClient *client, const QString &from, const QString &to);
|
||||
|
||||
private slots:
|
||||
void readyRead();
|
||||
|
||||
private:
|
||||
QXmppClient *client;
|
||||
QString from;
|
||||
QString to;
|
||||
|
||||
protected:
|
||||
void incomingConnection(quintptr socketDescriptor);
|
||||
};
|
||||
|
||||
#endif // UNIXSOCKET_H
|
Loading…
Reference in a new issue