diff options
author | Thomas Preud'homme <robotux@debian.org> | 2018-03-01 22:42:01 +0000 |
---|---|---|
committer | Thomas Preud'homme <robotux@debian.org> | 2018-03-01 22:42:01 +0000 |
commit | 3958fa914c8a524ed4b6a5b035b794e12708fa1d (patch) | |
tree | 417868397f3c2c7386773f55096a9aa5f8856990 /plugins/Listener |
Import ultracopier_1.4.0.4.orig.tar.xz
[dgit import orig ultracopier_1.4.0.4.orig.tar.xz]
Diffstat (limited to 'plugins/Listener')
17 files changed, 1779 insertions, 0 deletions
diff --git a/plugins/Listener/catchcopy-v0002/DebugEngineMacro.h b/plugins/Listener/catchcopy-v0002/DebugEngineMacro.h new file mode 100644 index 0000000..4582010 --- /dev/null +++ b/plugins/Listener/catchcopy-v0002/DebugEngineMacro.h @@ -0,0 +1,28 @@ +/** \file DebugEngineMacro.h +\brief Define the macro for the debug +\author alpha_one_x86 +\licence GPL3, see the file COPYING */ + +#ifndef DEBUGENGINEMACRO_H +#define DEBUGENGINEMACRO_H + +#ifdef WIN32 +# define __func__ __FUNCTION__ +#endif + +/// \brief Macro for the debug log +#ifdef ULTRACOPIER_PLUGIN_DEBUG + #if defined (__FILE__) && defined (__LINE__) + #define ULTRACOPIER_DEBUGCONSOLE(a,b) emit debugInformation(a,__func__,b,__FILE__,__LINE__) + #else + #define ULTRACOPIER_DEBUGCONSOLE(a,b) emit debugInformation(a,__func__,b) + #endif +#else // ULTRACOPIER_DEBUG + #define ULTRACOPIER_DEBUGCONSOLE(a,b) void() +#endif // ULTRACOPIER_DEBUG + +#endif // DEBUGENGINEMACRO_H + + + + diff --git a/plugins/Listener/catchcopy-v0002/Environment.h b/plugins/Listener/catchcopy-v0002/Environment.h new file mode 100644 index 0000000..265a5a6 --- /dev/null +++ b/plugins/Listener/catchcopy-v0002/Environment.h @@ -0,0 +1,10 @@ +/** \file Environment.h
+\brief Define the environment variable and global function
+\author alpha_one_x86
+\licence GPL3, see the file COPYING */
+
+#include "Variable.h"
+/// \brief The global include
+#include "StructEnumDefinition.h"
+#include "DebugEngineMacro.h"
+
diff --git a/plugins/Listener/catchcopy-v0002/StructEnumDefinition.h b/plugins/Listener/catchcopy-v0002/StructEnumDefinition.h new file mode 100644 index 0000000..c1758f4 --- /dev/null +++ b/plugins/Listener/catchcopy-v0002/StructEnumDefinition.h @@ -0,0 +1 @@ +#include "../../../StructEnumDefinition.h" diff --git a/plugins/Listener/catchcopy-v0002/Variable.h b/plugins/Listener/catchcopy-v0002/Variable.h new file mode 100644 index 0000000..963d0c8 --- /dev/null +++ b/plugins/Listener/catchcopy-v0002/Variable.h @@ -0,0 +1,15 @@ +/** \file Variable.h
+\brief Define the environment variable
+\author alpha_one_x86
+\licence GPL3, see the file COPYING */
+
+#ifndef VARIABLE_H
+#define VARIABLE_H
+
+//Un-comment this next line to put ultracopier plugin in debug mode
+#define ULTRACOPIER_PLUGIN_DEBUG
+
+#endif // VARIABLE_H
+
+
+
diff --git a/plugins/Listener/catchcopy-v0002/catchcopy-api-0002/ClientCatchcopy.cpp b/plugins/Listener/catchcopy-v0002/catchcopy-api-0002/ClientCatchcopy.cpp new file mode 100644 index 0000000..c466630 --- /dev/null +++ b/plugins/Listener/catchcopy-v0002/catchcopy-api-0002/ClientCatchcopy.cpp @@ -0,0 +1,379 @@ +/** \file ClientCatchcopy.cpp +\brief Define the catchcopy client +\author alpha_one_x86 */ + +#include "ClientCatchcopy.h" +#include "VariablesCatchcopy.h" +#include "ExtraSocketCatchcopy.h" + +#include <QDataStream> + +ClientCatchcopy::ClientCatchcopy() +{ + disconnectedFromSocket(); + error_string="Unknown error"; + detectTimeOut.setSingleShot(true); + detectTimeOut.setInterval(CATCHCOPY_COMMUNICATION_TIMEOUT); // the max time to without send packet + connect(&socket, SIGNAL(connected()), this, SIGNAL(connected())); + connect(&socket, SIGNAL(disconnected()), this, SIGNAL(disconnected())); + connect(&socket, SIGNAL(disconnected()), this, SLOT(disconnectedFromSocket())); + connect(&socket, SIGNAL(stateChanged(QLocalSocket::LocalSocketState)), this, SIGNAL(stateChanged(QLocalSocket::LocalSocketState))); + connect(&socket, SIGNAL(error(QLocalSocket::LocalSocketError)), this, SIGNAL(errorSocket(QLocalSocket::LocalSocketError))); + connect(&socket, SIGNAL(readyRead()), this, SLOT(readyRead())); + connect(&detectTimeOut, SIGNAL(timeout()), this, SLOT(checkTimeOut())); + connect(&socket, SIGNAL(connected()), this, SLOT(socketIsConnected())); +} + +void ClientCatchcopy::checkTimeOut() +{ + if(haveData) + { + error_string="The server is too long to send the next part of the reply"; + emit error(error_string); + disconnectFromServer(); + } +} + +const QString ClientCatchcopy::errorString() +{ + return error_string; +} + +void ClientCatchcopy::socketIsConnected() +{ + orderIdFirstSendProtocol=sendProtocol(); +} + +void ClientCatchcopy::connectToServer() +{ + socket.connectToServer(QString::fromStdString(ExtraSocketCatchcopy::pathSocket())); +} + +void ClientCatchcopy::disconnectFromServer() +{ + socket.abort(); + socket.disconnectFromServer(); +} + +const QString ClientCatchcopy::errorStringSocket() +{ + return socket.errorString(); +} + +/// \brief to send stream of string list +quint32 ClientCatchcopy::sendRawOrderList(const QStringList & order) +{ + if(!socket.isValid()) + { + error_string="Socket is not valid, try send: "+order.join(";"); + emit error(error_string); + return -1; + } + if(socket.state()!=QLocalSocket::ConnectedState) + { + error_string="Socket is not connected "+QString::number(socket.state()); + emit error(error_string); + return -1; + } + do + { + idNextOrder++; + if(idNextOrder>2000000000) + idNextOrder=0; + } while(notRepliedQuery.contains(idNextOrder)); + notRepliedQuery << idNextOrder; + QByteArray block; + QDataStream out(&block, QIODevice::WriteOnly); + out.setVersion(QDataStream::Qt_4_4); + out << int(0); + out << idNextOrder; + out << order; + out.device()->seek(0); + out << block.size(); + if(idNextOrder!=1) // drop if internal protocol send + { + emit dataSend(idNextOrder,block); + emit dataSend(idNextOrder,order); + } + do //cut string list and send it as block of 32KB + { + QByteArray blockToSend; + int byteWriten; + blockToSend=block.left(32*1024);//32KB + block.remove(0,blockToSend.size()); + byteWriten = socket.write(blockToSend); + if(!socket.isValid()) + { + error_string="Socket is not valid"; + emit error(error_string); + return -1; + } + if(socket.errorString()!="Unknown error" && socket.errorString()!="") + { + error_string=socket.errorString(); + emit error(error_string); + return -1; + } + if(blockToSend.size()!=byteWriten) + { + error_string="All the bytes have not be written"; + emit error(error_string); + return -1; + } + } + while(block.size()); + return idNextOrder; +} + +void ClientCatchcopy::readyRead() +{ + while(socket.bytesAvailable()>0) + { + if(!haveData) + { + if(socket.bytesAvailable()<(int)sizeof(int))//int of size cuted + { + /* error_string="Bytes available is not sufficient to do a int"; + emit error(error_string); + disconnectFromServer();*/ + return; + } + QDataStream in(&socket); + in.setVersion(QDataStream::Qt_4_4); + in >> dataSize; + dataSize-=sizeof(int); + if(dataSize>64*1024*1024) // 64MB + { + error_string="Reply size is >64MB, seam corrupted"; + emit error(error_string); + disconnectFromServer(); + return; + } + if(dataSize<(int)(sizeof(int) //orderId + + sizeof(quint32) //returnCode + + sizeof(quint32) //string list size + )) + { + error_string="Reply size is too small to have correct code"; + emit error(error_string); + disconnectFromServer(); + return; + } + } + if(dataSize<(data.size()+socket.bytesAvailable())) + data.append(socket.read(dataSize-data.size())); + else + data.append(socket.readAll()); + if(dataSize==data.size()) + { + if(!checkDataIntegrity(data)) + { + data.clear(); + qWarning() << "Data of the reply is wrong"; + return; + } + QStringList returnList; + quint32 orderId; + quint32 returnCode; + QDataStream in(data); + in.setVersion(QDataStream::Qt_4_4); + in >> orderId; + in >> returnCode; + in >> returnList; + data.clear(); + if(orderId!=orderIdFirstSendProtocol) + { + if(!notRepliedQuery.contains(orderId)) + qWarning() << "Unknown query not replied:" << orderId; + else + { + if(!parseReply(orderId,returnCode,returnList)) + emit unknowReply(orderId); + emit newReply(orderId,returnCode,returnList); + } + } + else + { + if(!sendProtocolReplied) + { + sendProtocolReplied=true; + if(returnCode!=1000) + { + error_string="Protocol not supported"; + emit error(error_string); + disconnectFromServer(); + return; + } + } + else + { + error_string=QStringLiteral("First send protocol send with the query id %1 have been already previously replied").arg(orderIdFirstSendProtocol); + emit error(error_string); + disconnectFromServer(); + return; + } + } + } + } + if(haveData) + detectTimeOut.start(); + else + detectTimeOut.stop(); +} + +bool ClientCatchcopy::checkDataIntegrity(QByteArray data) +{ + quint32 orderId; + qint32 replyCode; + qint32 listSize; + QDataStream in(data); + in.setVersion(QDataStream::Qt_4_4); + in >> orderId; + in >> replyCode; + in >> listSize; + if(listSize>65535) + { + emit error("List size is wrong"); + qWarning() << "List size is wrong"; + return false; + } + int index=0; + while(index<listSize) + { + qint32 stringSize; + in >> stringSize; + if(stringSize>65535) + { + emit error("String size is wrong"); + qWarning() << "String size is wrong"; + return false; + } + if(stringSize>(in.device()->size()-in.device()->pos())) + { + emit error(QStringLiteral("String size is greater than the data: %1>(%2-%3)").arg(stringSize).arg(in.device()->size()).arg(in.device()->pos())); + qWarning() << QStringLiteral("String size is greater than the data: %1>(%2-%3)").arg(stringSize).arg(in.device()->size()).arg(in.device()->pos()); + return false; + } + in.device()->seek(in.device()->pos()+stringSize); + index++; + } + if(in.device()->size()!=in.device()->pos()) + { + emit error("Remaining data after string list parsing"); + qWarning() << "Remaining data after string list parsing"; + return false; + } + return true; +} + +QLocalSocket::LocalSocketState ClientCatchcopy::state() +{ + return socket.state(); +} + +void ClientCatchcopy::disconnectedFromSocket() +{ + haveData = false; + orderIdFirstSendProtocol= 0; + idNextOrder = 0; + sendProtocolReplied = false; + notRepliedQuery.clear(); +} + +/// \brief to send the protocol version used +quint32 ClientCatchcopy::sendProtocol() +{ + return sendRawOrderList(QStringList() << "protocol" << CATCHCOPY_PROTOCOL_VERSION); +} + +quint32 ClientCatchcopy::askServerName() +{ + return sendRawOrderList(QStringList() << "server" << "name?"); +} + +quint32 ClientCatchcopy::setClientName(const QString & name) +{ + return sendRawOrderList(QStringList() << "client" << name); +} + +quint32 ClientCatchcopy::checkProtocolExtension(const QString & name) +{ + return sendRawOrderList(QStringList() << "protocol extension" << name); +} + +quint32 ClientCatchcopy::checkProtocolExtension(const QString & name,const QString & version) +{ + return sendRawOrderList(QStringList() << "protocol extension" << name << version); +} + +quint32 ClientCatchcopy::addCopyWithDestination(const QStringList & sources,const QString & destination) +{ + return sendRawOrderList(QStringList() << "cp" << sources << destination); +} + +quint32 ClientCatchcopy::addCopyWithoutDestination(const QStringList & sources) +{ + return sendRawOrderList(QStringList() << "cp-?" << sources); +} + +quint32 ClientCatchcopy::addMoveWithDestination(const QStringList & sources,const QString & destination) +{ + return sendRawOrderList(QStringList() << "mv" << sources << destination); +} + +quint32 ClientCatchcopy::addMoveWithoutDestination(const QStringList & sources) +{ + return sendRawOrderList(QStringList() << "mv-?" << sources); +} + +bool ClientCatchcopy::parseReply(quint32 orderId,quint32 returnCode,QStringList returnList) +{ + switch(returnCode) + { + case 1000: + emit protocolSupported(orderId); + break; + case 1001: + case 1002: + if(returnCode==1001) + emit protocolExtensionSupported(orderId,true); + else + emit protocolExtensionSupported(orderId,false); + break; + case 1003: + emit clientRegistered(orderId); + break; + case 1004: + if(returnList.size()!=1) + emit unknowOrder(orderId); + else + emit serverName(orderId,returnList.last()); + break; + case 1005: + case 1006: + if(returnCode==1005) + emit copyFinished(orderId,false); + else + emit copyFinished(orderId,true); + break; + case 1007: + emit copyCanceled(orderId); + break; + case 5000: + emit incorrectArgumentListSize(orderId); + break; + case 5001: + emit incorrectArgument(orderId); + break; + case 5002: + emit unknowOrder(orderId); //the server have not understand the order + break; + case 5003: + emit protocolNotSupported(orderId); + break; + default: + return false; + } + return true; +} + diff --git a/plugins/Listener/catchcopy-v0002/catchcopy-api-0002/ClientCatchcopy.h b/plugins/Listener/catchcopy-v0002/catchcopy-api-0002/ClientCatchcopy.h new file mode 100644 index 0000000..4c15890 --- /dev/null +++ b/plugins/Listener/catchcopy-v0002/catchcopy-api-0002/ClientCatchcopy.h @@ -0,0 +1,113 @@ +/** \file ClientCatchcopy.h +\brief Define the catchcopy client +\author alpha_one_x86 +\licence GPL3, see the file COPYING */ + +#ifndef CLIENTCATCHCOPY_H +#define CLIENTCATCHCOPY_H + +#include <QObject> +#include <QLocalSocket> +#include <QStringList> +#include <QString> +#include <QByteArray> +#include <QTimer> + +/// \brief Define the catchcopy client +class ClientCatchcopy : public QObject +{ + Q_OBJECT + public: + ClientCatchcopy(); + /// \brief get the socket stat + QLocalSocket::LocalSocketState state(); + /// \brief error string about the socket + const QString errorStringSocket(); + /// \brief general error string + const QString errorString(); + public slots: + void connectToServer(); + void disconnectFromServer(); + //to test and internal use + /// \brief to send order + quint32 sendProtocol(); + /// \brief ask the server name + quint32 askServerName(); + /// \brief set the client name + quint32 setClientName(const QString & name); + /// \brief check protocol extension + quint32 checkProtocolExtension(const QString & name); + /// \brief check protocol extension and version + quint32 checkProtocolExtension(const QString & name,const QString & version); + /// \brief add copy with destination + quint32 addCopyWithDestination(const QStringList & sources,const QString & destination); + /// \brief add copy without destination + quint32 addCopyWithoutDestination(const QStringList & sources); + /// \brief add move with destination + quint32 addMoveWithDestination(const QStringList & sources,const QString & destination); + /// \brief add move without destination + quint32 addMoveWithoutDestination(const QStringList & sources); + /// \brief to send stream of string list + quint32 sendRawOrderList(const QStringList & order); + signals: + /// \brief is connected + void connected(); + /// \brief is disconnected + void disconnected(); + /// \brief the socket state have changed + void stateChanged(QLocalSocket::LocalSocketState socketState); + /// \brief send the error string + void error(QString error); + /// \brief send socket error + void errorSocket(QLocalSocket::LocalSocketError socketError); + /// \brief have new reply + void newReply(quint32 orderId,quint32 returnCode,QStringList returnList); + /// \brief have data send + void dataSend(quint32 orderId,QByteArray data); + /// \brief have data send by string list + void dataSend(quint32 orderId,QStringList data); + /// \brief have unknow reply + void unknowReply(quint32 orderId); + //reply + /// \brief protocol is supported + void protocolSupported(quint32 orderId); + /// \brief incorrect argument list size + void incorrectArgumentListSize(quint32 orderId); + /// \brief incorrect argument + void incorrectArgument(quint32 orderId); + /// \brief protocol not supported + void protocolNotSupported(quint32 orderId); + /// \brief protocol extension supported + void protocolExtensionSupported(quint32 orderId,bool isSupported); + /// \brief client is registred + void clientRegistered(quint32 orderId); + /// \brief have the server name + void serverName(quint32 orderId,QString name); + /// \brief copy finished + void copyFinished(quint32 orderId,bool withError); + /// \brief copy canceled + void copyCanceled(quint32 orderId); + /// \brief have unknow order + void unknowOrder(quint32 orderId); //the server have not understand the order + private: + QLocalSocket socket; + QString error_string; + quint32 idNextOrder; + QByteArray data; + bool haveData; + int dataSize; + quint32 orderIdFirstSendProtocol; + QTimer detectTimeOut; + bool sendProtocolReplied; + QList<quint32> notRepliedQuery; + bool checkDataIntegrity(QByteArray data); + private slots: + void readyRead(); + void disconnectedFromSocket(); + void socketIsConnected(); + void checkTimeOut(); + protected: + bool parseReply(quint32 orderId,quint32 returnCode,QStringList returnList); +}; + +#endif // CLIENTCATCHCOPY_H diff --git a/plugins/Listener/catchcopy-v0002/catchcopy-api-0002/ExtraSocketCatchcopy.cpp b/plugins/Listener/catchcopy-v0002/catchcopy-api-0002/ExtraSocketCatchcopy.cpp new file mode 100644 index 0000000..9cd8373 --- /dev/null +++ b/plugins/Listener/catchcopy-v0002/catchcopy-api-0002/ExtraSocketCatchcopy.cpp @@ -0,0 +1,38 @@ +/** \file ExtraSocketCatchcopy.cpp +\brief Define the socket of catchcopy +\author alpha_one_x86 */ + +#include "ExtraSocketCatchcopy.h" + +#include <stdio.h> + +const std::string ExtraSocketCatchcopy::pathSocket() +{ +#ifdef Q_OS_UNIX + return "advanced-copier-"+std::to_string(getuid()); +#else + QString userName; + char uname[1024]; + DWORD len=1023; + if(GetUserNameA(uname, &len)!=FALSE) + userName=QString::fromLatin1(toHex(uname)); + return "advanced-copier-"+userName.toStdString(); +#endif +} + +char * ExtraSocketCatchcopy::toHex(const char *str) +{ + char *p, *sz; + size_t len; + if (str==NULL) + return NULL; + len= strlen(str); + p = sz = (char *) malloc((len+1)*4); + for (size_t i=0; i<len; i++) + { + sprintf(p, "%.2x00", str[i]); + p+=4; + } + *p=0; + return sz; +} diff --git a/plugins/Listener/catchcopy-v0002/catchcopy-api-0002/ExtraSocketCatchcopy.h b/plugins/Listener/catchcopy-v0002/catchcopy-api-0002/ExtraSocketCatchcopy.h new file mode 100644 index 0000000..fb4201c --- /dev/null +++ b/plugins/Listener/catchcopy-v0002/catchcopy-api-0002/ExtraSocketCatchcopy.h @@ -0,0 +1,31 @@ +/** \file ExtraSocketCatchcopy.h +\brief Define the socket of catchcopy +\author alpha_one_x86 +\licence GPL3, see the file COPYING */ + +#ifndef EXTRASOCKETCATCHCOPY_H +#define EXTRASOCKETCATCHCOPY_H + +#include <string> +#include <QString> + +#ifdef Q_OS_UNIX + #include <unistd.h> + #include <sys/types.h> +#else + #ifndef NOMINMAX + #define NOMINMAX + #endif + #include <windows.h> +#endif + +/// \brief to have extra socket function +class ExtraSocketCatchcopy +{ +public: + /// \brief to get the socket path + static const std::string pathSocket(); + static char * toHex(const char *str); +}; + +#endif // EXTRASOCKETCATCHCOPY_H diff --git a/plugins/Listener/catchcopy-v0002/catchcopy-api-0002/ServerCatchcopy.cpp b/plugins/Listener/catchcopy-v0002/catchcopy-api-0002/ServerCatchcopy.cpp new file mode 100644 index 0000000..6fd1172 --- /dev/null +++ b/plugins/Listener/catchcopy-v0002/catchcopy-api-0002/ServerCatchcopy.cpp @@ -0,0 +1,740 @@ +/** \file ServerCatchcopy.cpp +\brief Define the server of catchcopy +\author alpha_one_x86*/ + +#include "ServerCatchcopy.h" +#include "VariablesCatchcopy.h" +#include "ExtraSocketCatchcopy.h" + +#include <QFile> +#include <QDataStream> +#include <queue> +#include <vector> +#include <string> + +std::string stringimplode2(const std::vector<std::string>& elems, const std::string &delim) +{ + std::string newString; + for (std::vector<std::string>::const_iterator ii = elems.begin(); ii != elems.cend(); ++ii) + { + newString += (*ii); + if ( ii + 1 != elems.end() ) { + newString += delim; + } + } + return newString; +} + +ServerCatchcopy::ServerCatchcopy() +{ + name="Default avanced copier"; + idNextClient=0; + error_string="Unknown error"; + connect(&server, &QLocalServer::newConnection, this, &ServerCatchcopy::newConnection); +} + +ServerCatchcopy::~ServerCatchcopy() +{ + close(); +} + +bool ServerCatchcopy::isListening() const +{ + return server.isListening(); +} + +void ServerCatchcopy::setName(const std::string & name) +{ + this->name=name; +} + +std::string ServerCatchcopy::getName() const +{ + return name; +} + +/// \brief to get a client list +std::vector<std::string> ServerCatchcopy::clientsList() const +{ + std::vector<std::string> clients; + int index=0; + int size=clientList.size(); + while(index<size) + { + clients.push_back(clientList[index].name); + index++; + } + return clients; +} + +bool ServerCatchcopy::listen() +{ + QLocalSocket socketTestConnection; + pathSocket=ExtraSocketCatchcopy::pathSocket(); + socketTestConnection.connectToServer(QString::fromStdString(pathSocket)); + if(socketTestConnection.waitForConnected(CATCHCOPY_COMMUNICATION_TIMEOUT)) + { + error_string="Other server is listening"; + emit error(error_string); + return false; + } + else + { + if(!server.removeServer(QString::fromStdString(pathSocket))) + { + error_string="Unable to remove the old server"; + emit error(error_string); + } + #ifndef Q_OS_MAC + server.setSocketOptions(QLocalServer::UserAccessOption); + #endif + if(server.listen(QString::fromStdString(pathSocket))) + return true; + else + { + error_string=QStringLiteral("Unable to listen %1: %2").arg(QString::fromStdString(pathSocket)).arg(server.errorString()).toStdString(); + emit error(error_string); + return false; + } + } +} + +void ServerCatchcopy::close() +{ + if(server.isListening()) + { + int index=0; + while(index<clientList.size()) + { + clientList.at(index).socket->disconnectFromServer(); + index++; + } + server.close(); + if(!server.removeServer(QString::fromStdString(pathSocket))) + { + error_string="Unable to remove the old server"; + emit error(error_string); + } + } +} + +const std::string ServerCatchcopy::errorStringServer() const +{ + return server.errorString().toStdString(); +} + +const std::string ServerCatchcopy::errorString() const +{ + return error_string; +} + +/// \brief New connexion +void ServerCatchcopy::newConnection() +{ + while(server.hasPendingConnections()) + { + QLocalSocket *clientSocket = server.nextPendingConnection(); + if(clientSocket!=NULL) + { + do + { + idNextClient++; + if(idNextClient>2000000000) + idNextClient=0; + } while(clientIdFound(idNextClient)); + Client newClient; + newClient.id = idNextClient; + newClient.socket = clientSocket; + newClient.haveData = false; + newClient.firstProtocolReplied = false; + newClient.detectTimeOut = new QTimer(this); + newClient.detectTimeOut->setSingleShot(true); + newClient.detectTimeOut->setInterval(CATCHCOPY_COMMUNICATION_TIMEOUT); + newClient.name="Unknown"; + connect(newClient.socket, static_cast<void(QLocalSocket::*)(QLocalSocket::LocalSocketError)>(&QLocalSocket::error), this, &ServerCatchcopy::connectionError,Qt::QueuedConnection); + connect(newClient.socket, &QIODevice::readyRead, this, &ServerCatchcopy::readyRead,Qt::QueuedConnection); + connect(newClient.socket, &QLocalSocket::disconnected, this, &ServerCatchcopy::disconnected,Qt::QueuedConnection); + connect(newClient.detectTimeOut,&QTimer::timeout, this, &ServerCatchcopy::checkTimeOut,Qt::QueuedConnection); + clientList << newClient; + emit connectedClient(newClient.id); + } + } +} + +bool ServerCatchcopy::clientIdFound(const uint32_t &id) const +{ + int index=0; + while(index<clientList.size()) + { + if(clientList.at(index).id==id) + return true; + index++; + } + return false; +} + +/// \brief new error at connexion +void ServerCatchcopy::connectionError(const QLocalSocket::LocalSocketError &error) +{ + QLocalSocket *socket=qobject_cast<QLocalSocket *>(QObject::sender()); + if(socket==NULL) + { + qWarning() << "Unlocated client socket!"; + return; + } + int index=0; + while(index<clientList.size()) + { + if(clientList.at(index).socket==socket) + { + if(error!=QLocalSocket::PeerClosedError) + { + qWarning() << "error detected for the client: " << index << ", type: " << error; + clientList.at(index).socket->disconnectFromServer(); + } + return; + } + index++; + } +} + +void ServerCatchcopy::disconnected() +{ + QLocalSocket *socket=qobject_cast<QLocalSocket *>(QObject::sender()); + if(socket==NULL) + { + qWarning() << "Unlocated client socket!"; + return; + } + int index=0; + while(index<clientList.size()) + { + if(clientList.at(index).socket==socket) + { + const uint32_t &id=clientList.at(index).id; + //ClientList.at(index).socket->disconnectFromServer();//already disconnected + delete clientList.at(index).detectTimeOut; + clientList.at(index).socket->deleteLater(); + clientList.removeAt(index); + emit disconnectedClient(id); + return; + } + index++; + } + qWarning() << "Unlocated client!"; +} + +void ServerCatchcopy::disconnectClient(const uint32_t &id) +{ + int index=0; + while(index<clientList.size()) + { + if(clientList.at(index).id==id) + { + clientList.at(index).socket->disconnectFromServer(); + return; + } + index++; + } + qWarning() << "Unlocated client!"; +} + +void ServerCatchcopy::readyRead() +{ + QLocalSocket *socket=qobject_cast<QLocalSocket *>(QObject::sender()); + if(socket==NULL) + { + qWarning() << "Unlocated client socket!"; + return; + } + int index=0; + while(index<clientList.size()) + { + if(clientList.at(index).socket==socket) + { + while(socket->bytesAvailable()>0) + { + if(!clientList.at(index).haveData) + { + if(socket->bytesAvailable()<(int)sizeof(int))//ignore because first int is cuted! + { + /*error_string="Bytes available is not sufficient to do a int"; + emit error(error_string); + disconnectClient(ClientList.at(index).id);*/ + return; + } + QDataStream in(socket); + in.setVersion(QDataStream::Qt_4_4); + in >> clientList[index].dataSize; + clientList[index].dataSize-=sizeof(int); + if(clientList.at(index).dataSize>64*1024*1024) // 64MB + { + error_string="Reply size is >64MB, seam corrupted"; + emit communicationError(error_string); + disconnectClient(clientList.at(index).id); + return; + } + if(clientList.at(index).dataSize<(int)(sizeof(int) //orderId + + sizeof(uint32_t) //returnCode + + sizeof(uint32_t) //string list size + )) + { + error_string="Reply size is too small to have correct code"; + emit communicationError(error_string); + disconnectClient(clientList.at(index).id); + return; + } + clientList[index].haveData=true; + } + if(clientList.at(index).dataSize<(clientList.at(index).data.size()+socket->bytesAvailable())) + clientList[index].data.append(socket->read(clientList.at(index).dataSize-clientList.at(index).data.size())); + else + clientList[index].data.append(socket->readAll()); + if(clientList.at(index).dataSize==(uint32_t)clientList.at(index).data.size()) + { + if(!checkDataIntegrity(clientList.at(index).data)) + { + emit communicationError("Data integrity wrong: "+QString(clientList.at(index).data.toHex()).toStdString()); + clientList[index].data.clear(); + clientList[index].haveData=false; + qWarning() << "Data integrity wrong"; + return; + } + std::vector<std::string> returnList; + QStringList returnListQt; + uint32_t orderId; + QDataStream in(clientList.at(index).data); + in.setVersion(QDataStream::Qt_4_4); + in >> orderId; + in >> returnListQt; + { + int index=0; + while(index<returnListQt.size()) + { + returnList.push_back(returnListQt.at(index).toStdString()); + index++; + } + } + clientList[index].data.clear(); + clientList[index].haveData=false; + if(clientList.at(index).queryNoReplied.contains(orderId)) + { + emit communicationError("Duplicate query id"); + qWarning() << "Duplicate query id"; + return; + } + clientList[index].queryNoReplied << orderId; + if(!clientList.at(index).firstProtocolReplied && returnList.size()==2 && returnList.front()=="protocol") + { + clientList[index].firstProtocolReplied=true; + protocolSupported(clientList.at(index).id,orderId,(returnList.back()==CATCHCOPY_PROTOCOL_VERSION)); + } + else + parseInput(clientList.at(index).id,orderId,returnList); + } + } + if(clientList.at(index).haveData) + clientList.at(index).detectTimeOut->start(); + else + clientList.at(index).detectTimeOut->stop(); + return; + } + index++; + } + emit error("Unallocated client!"); + qWarning() << "Unallocated client!"; +} + +bool ServerCatchcopy::checkDataIntegrity(const QByteArray &data) +{ + uint32_t orderId; + qint32 listSize; + QDataStream in(data); + in.setVersion(QDataStream::Qt_4_4); + in >> orderId; + in >> listSize; + if(listSize>65535) + { + emit error("List size is wrong"); + qWarning() << "List size is wrong"; + return false; + } + int index=0; + while(index<listSize) + { + qint32 stringSize; + in >> stringSize; + if(stringSize>65535) + { + emit error("String size is wrong"); + return false; + } + if(stringSize>(in.device()->size()-in.device()->pos())) + { + emit error(QStringLiteral("String size is greater than the data: %1>(%2-%3)").arg(stringSize).arg(in.device()->size()).arg(in.device()->pos()).toStdString()); + return false; + } + in.device()->seek(in.device()->pos()+stringSize); + index++; + } + if(in.device()->size()!=in.device()->pos()) + { + emit error("Remaining data after string list parsing"); + return false; + } + return true; +} + +void ServerCatchcopy::parseInput(const uint32_t &client,const uint32_t &orderId,const std::vector<std::string> &returnList) +{ + const ServerCatchcopy::inputReturnType returnVal=parseInputCurrentProtocol(client,orderId,returnList); + switch(returnVal) + { + case Ok: + emit newQuery(client,orderId,returnList); + break; + case Replied: + break; + case ExtensionWrong: + //protocolExtensionSupported(client,orderId,false); + break; + case WrongArgument: + incorrectArgument(client,orderId); + break; + case WrongArgumentListSize: + incorrectArgumentListSize(client,orderId); + break; + case UnknowOrder: + emit error("Unknown query: "+std::to_string(returnVal)+", with client: "+std::to_string(client)+", orderId: "+std::to_string(orderId)+", returnList: "+stringimplode2(returnList,", ")); + qWarning() << "Unknown query"; + unknowOrder(client,orderId); + break; + } +} + +ServerCatchcopy::inputReturnType ServerCatchcopy::parseInputCurrentProtocol(const uint32_t &client,const uint32_t &orderId,const std::vector<std::string> &returnList) +{ + if(returnList.size()==0) + return WrongArgumentListSize; + //if is supported + std::string firstArgument=returnList.front(); + if(firstArgument=="protocol") + { + if(returnList.size()!=2) + return WrongArgumentListSize; + emit askProtocolCompatibility(client,orderId,returnList.back()); + return Ok; + } + else if(firstArgument=="protocol extension") + { + if(returnList.size()>3 || returnList.size()<2) + return WrongArgumentListSize; + return ExtensionWrong; + } + else if(firstArgument=="client") + { + if(returnList.size()!=2) + return WrongArgumentListSize; + int index=0; + int size=clientList.size(); + while(index<size) + { + if(clientList.at(index).id==client) + { + clientList[index].name=returnList.back(); + break; + } + index++; + } + emit clientName(client,returnList.back()); + clientRegistered(client,orderId); + return Replied; + } + else if(firstArgument=="server") + { + if(returnList.size()!=2) + return WrongArgumentListSize; + if(returnList.back()!="name?") + return WrongArgument; + serverName(client,orderId,name); + return Replied; + } + else if(firstArgument=="cp") + { + if(returnList.size()<3) + return WrongArgumentListSize; + std::vector<std::string> sourceList=returnList; + sourceList.erase(sourceList.cbegin()); + sourceList.pop_back(); + emitNewCopy(client,orderId,sourceList,returnList.back()); + return Ok; + } + else if(firstArgument=="cp-?") + { + if(returnList.size()<2) + return WrongArgumentListSize; + std::vector<std::string> sourceList=returnList; + sourceList.erase(sourceList.cbegin()); + emitNewCopyWithoutDestination(client,orderId,sourceList); + return Ok; + } + else if(firstArgument=="mv") + { + if(returnList.size()<3) + return WrongArgumentListSize; + std::vector<std::string> sourceList=returnList; + sourceList.erase(sourceList.cbegin()); + sourceList.pop_back(); + emitNewMove(client,orderId,sourceList,returnList.back()); + return Ok; + } + else if(firstArgument=="mv-?") + { + if(returnList.size()<2) + return WrongArgumentListSize; + std::vector<std::string> sourceList=returnList; + sourceList.erase(sourceList.cbegin()); + emitNewMoveWithoutDestination(client,orderId,sourceList); + return Ok; + } + else //if is not supported + return UnknowOrder; +} + +void ServerCatchcopy::emitNewCopyWithoutDestination(const uint32_t &client,const uint32_t &orderId,const std::vector<std::string> &sources) +{ + LinkGlobalToLocalClient newAssociation; + newAssociation.idClient=client; + newAssociation.orderId=orderId; + newAssociation.globalOrderId=incrementOrderId(); + LinkGlobalToLocalClientList << newAssociation; + emit newCopyWithoutDestination(newAssociation.globalOrderId,sources); +} + +void ServerCatchcopy::emitNewCopy(const uint32_t &client,const uint32_t &orderId,const std::vector<std::string> &sources,const std::string &destination) +{ + LinkGlobalToLocalClient newAssociation; + newAssociation.idClient=client; + newAssociation.orderId=orderId; + newAssociation.globalOrderId=incrementOrderId(); + LinkGlobalToLocalClientList << newAssociation; + emit newCopy(newAssociation.globalOrderId,sources,destination); +} + +void ServerCatchcopy::emitNewMoveWithoutDestination(const uint32_t &client,const uint32_t &orderId,const std::vector<std::string> &sources) +{ + LinkGlobalToLocalClient newAssociation; + newAssociation.idClient=client; + newAssociation.orderId=orderId; + newAssociation.globalOrderId=incrementOrderId(); + LinkGlobalToLocalClientList << newAssociation; + emit newMoveWithoutDestination(newAssociation.globalOrderId,sources); +} + +void ServerCatchcopy::emitNewMove(const uint32_t &client,const uint32_t &orderId,const std::vector<std::string> &sources,const std::string &destination) +{ + LinkGlobalToLocalClient newAssociation; + newAssociation.idClient=client; + newAssociation.orderId=orderId; + newAssociation.globalOrderId=incrementOrderId(); + LinkGlobalToLocalClientList << newAssociation; + emit newMove(newAssociation.globalOrderId,sources,destination); +} + +void ServerCatchcopy::copyFinished(const uint32_t &globalOrderId,const bool &withError) +{ + int index=0; + while(index<LinkGlobalToLocalClientList.size()) + { + if(LinkGlobalToLocalClientList.at(index).globalOrderId==globalOrderId) + { + copyFinished(LinkGlobalToLocalClientList.at(index).idClient,LinkGlobalToLocalClientList.at(index).orderId,withError); + LinkGlobalToLocalClientList.removeAt(index); + orderList.removeOne(globalOrderId); + return; + } + index++; + } +} + +void ServerCatchcopy::copyCanceled(const uint32_t &globalOrderId) +{ + int index=0; + while(index<LinkGlobalToLocalClientList.size()) + { + if(LinkGlobalToLocalClientList.at(index).globalOrderId==globalOrderId) + { + copyCanceled(LinkGlobalToLocalClientList.at(index).idClient,LinkGlobalToLocalClientList.at(index).orderId); + LinkGlobalToLocalClientList.removeAt(index); + orderList.removeOne(globalOrderId); + return; + } + index++; + } +} + +void ServerCatchcopy::reply(const uint32_t &client,const uint32_t &orderId,const uint32_t &returnCode,const std::string &returnString) +{ + std::vector<std::string> returnList; + returnList.push_back(returnString); + reply(client,orderId,returnCode,returnList); +} + +void ServerCatchcopy::reply(const uint32_t &client,const uint32_t &orderId,const uint32_t &returnCode,const std::vector<std::string> &returnList) +{ + int index=0; + while(index<clientList.size()) + { + if(clientList.at(index).id==client) + { + if(clientList.at(index).socket->isValid() && clientList.at(index).socket->state()==QLocalSocket::ConnectedState) + { + if(!clientList.at(index).queryNoReplied.contains(orderId)) + { + qWarning() << "Reply to missing query or previously replied"; + return; + } + clientList[index].queryNoReplied.removeOne(orderId); + //cut string list and send it as block of 32KB + QByteArray block; + QDataStream out(&block, QIODevice::WriteOnly); + out.setVersion(QDataStream::Qt_4_4); + out << int(0); + out << orderId; + out << returnCode; + QStringList returnListQt; + { + unsigned int index=0; + while(index<returnList.size()) + { + returnListQt << QString::fromStdString(returnList.at(index)); + index++; + } + } + out << returnListQt; + out.device()->seek(0); + out << block.size(); + do + { + QByteArray blockToSend; + int byteWriten; + blockToSend=block.left(32*1024);//32KB + block.remove(0,blockToSend.size()); + byteWriten = clientList[index].socket->write(blockToSend); + if(!clientList[index].socket->isValid()) + { + error_string="Socket is not valid"; + emit error(error_string); + return; + } + if(clientList[index].socket->error()!=QLocalSocket::UnknownSocketError && clientList[index].socket->error()!=QLocalSocket::PeerClosedError) + { + error_string="Error with socket: "+clientList[index].socket->errorString().toStdString(); + emit error(error_string); + return; + } + if(blockToSend.size()!=byteWriten) + { + error_string="All the bytes have not be written"; + emit error(error_string); + return; + } + } + while(block.size()); + } + else + { + error_string="Socket is not valid or not connected"; + emit error(error_string); + } + return; + } + index++; + } + qWarning() << "Client id not found:" << client; +} + +void ServerCatchcopy::protocolSupported(const uint32_t &client,const uint32_t &orderId,const bool &value) +{ + if(value) + reply(client,orderId,1000,"protocol supported"); + else + reply(client,orderId,5003,"protocol not supported"); +} + +void ServerCatchcopy::incorrectArgumentListSize(const uint32_t &client,const uint32_t &orderId) +{ + reply(client,orderId,5000,"incorrect argument list size"); +} + +void ServerCatchcopy::incorrectArgument(const uint32_t &client,const uint32_t &orderId) +{ + reply(client,orderId,5001,"incorrect argument"); +} + +void ServerCatchcopy::clientRegistered(const uint32_t &client,const uint32_t &orderId) +{ + reply(client,orderId,1003,"client registered"); +} + +void ServerCatchcopy::serverName(const uint32_t &client,const uint32_t &orderId,const std::string &name) +{ + reply(client,orderId,1004,name); +} + +void ServerCatchcopy::copyFinished(const uint32_t &client,const uint32_t &orderId,const bool &withError) +{ + if(!withError) + reply(client,orderId,1005,"finished"); + else + reply(client,orderId,1006,"finished with error(s)"); +} + +void ServerCatchcopy::copyCanceled(const uint32_t &client,const uint32_t &orderId) +{ + reply(client,orderId,1007,"canceled"); +} + +void ServerCatchcopy::unknowOrder(const uint32_t &client,const uint32_t &orderId) +{ + reply(client,orderId,5002,"unknown order"); +} + +void ServerCatchcopy::checkTimeOut() +{ + QTimer *timer=qobject_cast<QTimer *>(QObject::sender()); + if(timer==NULL) + { + qWarning() << "Unallocated client timer!"; + return; + } + int index=0; + while(index<clientList.size()) + { + if(clientList.at(index).detectTimeOut==timer) + { + clientList.at(index).detectTimeOut->stop(); + if(clientList.at(index).haveData) + { + error_string="The client is too long to send the next part of the reply: "+QString(clientList.at(index).data.toHex()).toStdString(); + clientList[index].haveData=false; + clientList[index].data.clear(); + clientList.at(index).socket->disconnectFromServer(); + emit error(error_string); + } + return; + } + index++; + } +} + +uint32_t ServerCatchcopy::incrementOrderId() +{ + do + { + nextOrderId++; + if(nextOrderId>2000000) + nextOrderId=0; + } while(orderList.contains(nextOrderId)); + return nextOrderId; +} diff --git a/plugins/Listener/catchcopy-v0002/catchcopy-api-0002/ServerCatchcopy.h b/plugins/Listener/catchcopy-v0002/catchcopy-api-0002/ServerCatchcopy.h new file mode 100644 index 0000000..85acff9 --- /dev/null +++ b/plugins/Listener/catchcopy-v0002/catchcopy-api-0002/ServerCatchcopy.h @@ -0,0 +1,144 @@ +/** \file ServerCatchcopy.h +\brief Define the server of catchcopy +\author alpha_one_x86 +\licence GPL3, see the file COPYING */ + +#ifndef SERVERCATCHCOPY_H +#define SERVERCATCHCOPY_H + +#include <QObject> +#include <QLocalSocket> +#include <QLocalServer> +#include <vector> +#include <string> +#include <QByteArray> +#include <QTimer> + +/// \brief Define the server of catchcopy +class ServerCatchcopy : public QObject +{ + Q_OBJECT + public: + ServerCatchcopy(); + ~ServerCatchcopy(); + /// \brief return if is listening + bool isListening() const; + /// \brief try listen + bool listen(); + /// \brief try close the server + void close(); + /// \brief get the error string on the QLocalServer + const std::string errorStringServer() const; + /// \brief get the general error string + const std::string errorString() const; + /// \brief set the name of the server + void setName(const std::string & name); + /// \brief get the name + std::string getName() const; + /// \brief to get a client list + std::vector<std::string> clientsList() const; + private: + std::string pathSocket; + std::string name; + std::string error_string; + QLocalServer server; + uint32_t idNextClient; + struct Client + { + uint32_t id; + QLocalSocket *socket; + QByteArray data; + bool haveData; + uint32_t dataSize; + bool firstProtocolReplied; + QList<uint32_t> queryNoReplied; + QTimer *detectTimeOut; + std::string name; + }; + QList<Client> clientList; + struct LinkGlobalToLocalClient + { + uint32_t idClient; + uint32_t orderId; + uint32_t globalOrderId; + }; + QList<LinkGlobalToLocalClient> LinkGlobalToLocalClientList; + enum inputReturnType{Ok,Replied,ExtensionWrong,WrongArgument,WrongArgumentListSize,UnknowOrder}; + inputReturnType parseInputCurrentProtocol(const uint32_t &client,const uint32_t &orderId,const std::vector<std::string> &returnList); + bool clientIdFound(const uint32_t &id) const; + uint32_t nextOrderId; + QList<uint32_t> orderList; + uint32_t incrementOrderId(); + void emitNewCopyWithoutDestination(const uint32_t &client,const uint32_t &orderId,const std::vector<std::string> &sources); + void emitNewCopy(const uint32_t &client,const uint32_t &orderId,const std::vector<std::string> &sources,const std::string &destination); + void emitNewMoveWithoutDestination(const uint32_t &client,const uint32_t &orderId,const std::vector<std::string> &sources); + void emitNewMove(const uint32_t &client,const uint32_t &orderId,const std::vector<std::string> &sources,const std::string &destination); + bool checkDataIntegrity(const QByteArray &data); + protected: + void parseInput(const uint32_t &client,const uint32_t &orderId,const std::vector<std::string> &returnList); + private slots: + void newConnection(); + void connectionError(const QLocalSocket::LocalSocketError &error); + void disconnected(); + void readyRead(); + void checkTimeOut(); + public slots: + /// \brief disconnect one client + void disconnectClient(const uint32_t &id); + /// \brief reply to a client with std::vector<std::string> + void reply(const uint32_t &client,const uint32_t &orderId,const uint32_t &returnCode,const std::vector<std::string> &returnList); + /// \brief reply to a client + void reply(const uint32_t &client,const uint32_t &orderId,const uint32_t &returnCode,const std::string &returnString); + //reply + /// \brief send if the protocol is supported + void protocolSupported(const uint32_t &client,const uint32_t &orderId,const bool &value); + /// \brief send incorrect arguement list size + void incorrectArgumentListSize(const uint32_t &client,const uint32_t &orderId); + /// \brief send incorrect arguement + void incorrectArgument(const uint32_t &client,const uint32_t &orderId); + /// \brief the client is registred + void clientRegistered(const uint32_t &client,const uint32_t &orderId); + /// \brief send the server name + void serverName(const uint32_t &client,const uint32_t &orderId,const std::string &name); + /// \brief send the copy is finished + void copyFinished(const uint32_t &client,const uint32_t &orderId,const bool &withError); + /// \brief send the copy is canceled + void copyCanceled(const uint32_t &client,const uint32_t &orderId); + /// \brief send the copy is finished by global is order + void copyFinished(const uint32_t &globalOrderId,const bool &withError); + /// \brief send copy cancel by global is order + void copyCanceled(const uint32_t &globalOrderId); + /// \brief send the unknow order + void unknowOrder(const uint32_t &client,const uint32_t &orderId); + signals: + /// \brief send connected client + void connectedClient(const uint32_t &id); + /// \brief send disconnect client + void disconnectedClient(const uint32_t &id); + /// \brief have new query + void newQuery(const uint32_t &client,const uint32_t &orderId,const std::vector<std::string> &returnList); + /// \brief have new error + void error(const std::string &error); + void communicationError(const std::string &error); + //query + /// \brief ask the protocol compatility + void askProtocolCompatibility(const uint32_t &client,const uint32_t &orderId,const std::string &version); + /// \brief ask protocol extension + void askProtocolExtension(const uint32_t &client,const uint32_t &orderId,const std::string &extension); + /// \brief ask protocol extension with version + void askProtocolExtension(const uint32_t &client,const uint32_t &orderId,const std::string &extension,const std::string &version); + /// \brief send the client name, without query id + void clientName(const uint32_t &client,const std::string &name); + /// \brief send the client have ask the server name + void askServerName(const uint32_t &client,const uint32_t &orderId); + /// \brief copy is send, by globalOrderId, without destination + void newCopyWithoutDestination(const uint32_t &globalOrderId,const std::vector<std::string> &sources); + /// \brief copy is send, by globalOrderId, with destination + void newCopy(const uint32_t &globalOrderId,const std::vector<std::string> &sources,const std::string &destination); + /// \brief move is send, by globalOrderId, without destination + void newMoveWithoutDestination(const uint32_t &globalOrderId,const std::vector<std::string> &sources); + /// \brief move is send, by globalOrderId, with destination + void newMove(const uint32_t &globalOrderId,const std::vector<std::string> &sources,const std::string &destination); +}; + +#endif // SERVERCATCHCOPY_H diff --git a/plugins/Listener/catchcopy-v0002/catchcopy-api-0002/VariablesCatchcopy.h b/plugins/Listener/catchcopy-v0002/catchcopy-api-0002/VariablesCatchcopy.h new file mode 100644 index 0000000..135c087 --- /dev/null +++ b/plugins/Listener/catchcopy-v0002/catchcopy-api-0002/VariablesCatchcopy.h @@ -0,0 +1,13 @@ +/** \file VariablesCatchcopy.h +\brief Define the variable for catchcopy +\author alpha_one_x86 +\licence GPL3, see the file COPYING */ + +#ifndef VARIABLECATCHCOPY_H +#define VARIABLECATCHCOPY_H + +#define CATCHCOPY_PROTOCOL_VERSION "0002" +#define CATCHCOPY_COMMUNICATION_TIMEOUT 200 + +#endif // VARIABLECATCHCOPY_H + diff --git a/plugins/Listener/catchcopy-v0002/documentation.dox b/plugins/Listener/catchcopy-v0002/documentation.dox new file mode 100644 index 0000000..51aa937 --- /dev/null +++ b/plugins/Listener/catchcopy-v0002/documentation.dox @@ -0,0 +1,32 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- **/ + +/* + This file contains NO source code, just some documentation for doxygen to + parse. +*/ + +/*! + \mainpage catchcopy-v0002 + + \section mainpage_overview Overview + + Is the default listener to wait a copy/move. It use the catchcopy protocol.\n + More informations on <a href="http://ultracopier-wiki.first-world.info/">the wiki of ultracopier</a>. + + \section mainpage_platforms Platforms + + Ultracopier might be usable in all environments where you find Qt 5.\n + Ultracopier requires Qt 5.0 or newer. Tested on Qt 5.0. + + \section mainpage_downloads Downloads + + You can find the link on <a href="http://ultracopier.first-world.info/">Ultracopier</a> project page, via git, snapshot sources, ... + + \section mainpage_algorithm Protocol + + The protocol in version 0.0.0.2 is used, you can see the documentation on <a href="http://catchcopy.first-world.info/">Catchcopy web site</a> + + \section license GPL Version 3 + The code source is under GPL3. The image is extacted from Oxygen icon pack of KDE4. + +*/ diff --git a/plugins/Listener/catchcopy-v0002/informations.xml b/plugins/Listener/catchcopy-v0002/informations.xml new file mode 100644 index 0000000..9efc7ce --- /dev/null +++ b/plugins/Listener/catchcopy-v0002/informations.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<package> + <title xml:lang="en"><![CDATA[Listener for catchcopy v0002]]></title><!-- english is required --> + <title xml:lang="fr"><![CDATA[Écouteur pour catchcopy v0002]]></title> + <!-- What kind of plugin this is --> + <category>Listener</category> + <!-- Who wrote this plugin --> + <author><![CDATA[BRULE Herman, alpha_one_x86 (alpha_one_x86@first-world.info)]]></author> + <!-- URL of page or site for this plugin (may provide additional information, bug reports, feature requests). --> + <website xml:lang="en"><![CDATA[http://ultracopier.first-world.info/]]></website><!-- not required --> + <website xml:lang="fr"><![CDATA[http://ultracopier-fr.first-world.info/]]></website><!-- not required --> + <!-- the date-time format should be in timestamps format --> + <pubDate>1287496800</pubDate> + <!-- the architecture code of this plugin, found PlatformMacro.h into ultracopier source --> + <architecture>windows-x86</architecture> + <!-- Detailed description --> + <description xml:lang="en"><![CDATA[Listener for catchcopy v0002. Allow to receive copy list from plugin/explorer compatible with catchcopy.]]></description> + <description xml:lang="fr"><![CDATA[Écouteur pour catchcopy v0002. Permet de recevoir un liste de copie venant d'un plugin/explorateur avec catchcopy.]]></description> + <!-- Version of this release of this plugin, need be like that's: A.B.C.D, where A, B, C and D is number --> + <version>1.4.0.4</version> + <!-- This internal name should never change, because it is used to detect when a particular plugin is updated. It must comprise only lower case ASCII characters (a-z), numerical digits (0-9), "-", "." or "_", and it must be be unique within the category. And have size lower than 64 char. --> + <name>catchcopy-v0002</name> + <!-- Dependency checking. This is used to check when a plugin may not be compatible with an updated version of either Ultracopier or another plugin. This example only checks Ultracopier. --> + <dependencies><![CDATA[ + ]]></dependencies> +</package>
\ No newline at end of file diff --git a/plugins/Listener/catchcopy-v0002/listener.cpp b/plugins/Listener/catchcopy-v0002/listener.cpp new file mode 100644 index 0000000..e45a08b --- /dev/null +++ b/plugins/Listener/catchcopy-v0002/listener.cpp @@ -0,0 +1,123 @@ +#include "listener.h" +#include "catchcopy-api-0002/ExtraSocketCatchcopy.h" +#include "../../../cpp11addition.h" + +Listener::Listener() +{ + server.setName(tr("Ultracopier").toStdString()); + connect(&server,&ServerCatchcopy::newCopyWithoutDestination, this,&Listener::copyWithoutDestination); + connect(&server,&ServerCatchcopy::newCopy, this,&Listener::copy); + connect(&server,&ServerCatchcopy::newMoveWithoutDestination, this,&Listener::moveWithoutDestination); + connect(&server,&ServerCatchcopy::newMove, this,&Listener::move); + connect(&server,&ServerCatchcopy::error, this,&Listener::errorInternal); + connect(&server,&ServerCatchcopy::communicationError, this,&Listener::communicationErrorInternal); + connect(&server,&ServerCatchcopy::clientName, this,&Listener::clientName); + connect(&server,&ServerCatchcopy::clientName, this,&Listener::newClientList); + connect(&server,&ServerCatchcopy::connectedClient, this,&Listener::newClientList); + connect(&server,&ServerCatchcopy::disconnectedClient, this,&Listener::newClientList); + +} + +void Listener::listen() +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start: "+ExtraSocketCatchcopy::pathSocket()); + if(server.listen()) + emit newState(Ultracopier::FullListening); + else + emit newState(Ultracopier::NotListening); +} + +void Listener::close() +{ + server.close(); + emit newState(Ultracopier::NotListening); +} + +const std::string Listener::errorString() const +{ + return server.errorString(); +} + +void Listener::setResources(OptionInterface * options, const std::string &writePath, const std::string &pluginPath, const bool &portableVersion) +{ + Q_UNUSED(options); + Q_UNUSED(writePath); + Q_UNUSED(pluginPath); + Q_UNUSED(portableVersion); +} + +/// \brief to get the options widget, NULL if not have +QWidget * Listener::options() +{ + return NULL; +} + +/// \brief to get a client list +std::vector<std::string> Listener::clientsList() const +{ + return server.clientsList(); +} + +void Listener::transferFinished(const uint32_t &orderId, const bool &withError) +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start, orderId: "+std::to_string(orderId)+", withError: "+std::to_string(withError)); + server.copyFinished(orderId,withError); +} + +void Listener::transferCanceled(const uint32_t &orderId) +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start, orderId: "+std::to_string(orderId)); + server.copyCanceled(orderId); +} + +/// \brief to reload the translation, because the new language have been loaded +void Listener::newLanguageLoaded() +{ +} + +void Listener::errorInternal(const std::string &string) +{ + Q_UNUSED(string); + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"warning emited from Catchcopy lib: "+string); +} + +void Listener::communicationErrorInternal(const std::string &string) +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"warning emited from Catchcopy lib: "+string); + emit error(string); +} + +void Listener::clientName(uint32_t client,std::string name) +{ + Q_UNUSED(client); + Q_UNUSED(name); + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Information,QStringLiteral("clientName: %1, for the id: %2").arg(QString::fromStdString(name)).arg(client).toStdString()); +} + +void Listener::copyWithoutDestination(const uint32_t &orderId,const std::vector<std::string> &sources) +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Information,QStringLiteral("copyWithoutDestination(%1,%2)") + .arg(orderId) + .arg(QString::fromStdString(stringimplode(sources,";"))) + .toStdString() + ); + emit newCopyWithoutDestination(orderId,sources); +} + +void Listener::copy(const uint32_t &orderId,const std::vector<std::string> &sources,const std::string &destination) +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Information,QStringLiteral("copy(%1,%2,%3)").arg(orderId).arg(QString::fromStdString(stringimplode(sources,";")).arg(QString::fromStdString(destination))).toStdString()); + emit newCopy(orderId,sources,destination); +} + +void Listener::moveWithoutDestination(const uint32_t &orderId,const std::vector<std::string> &sources) +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Information,QStringLiteral("moveWithoutDestination(%1,%2)").arg(orderId).arg(QString::fromStdString(stringimplode(sources,";"))).toStdString()); + emit newMoveWithoutDestination(orderId,sources); +} + +void Listener::move(const uint32_t &orderId,const std::vector<std::string> &sources,const std::string &destination) +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Information,QStringLiteral("move(%1,%2,%3)").arg(orderId).arg(QString::fromStdString(stringimplode(sources,";")).arg(QString::fromStdString(destination))).toStdString()); + emit newMove(orderId,sources,destination); +} diff --git a/plugins/Listener/catchcopy-v0002/listener.h b/plugins/Listener/catchcopy-v0002/listener.h new file mode 100644 index 0000000..8cab248 --- /dev/null +++ b/plugins/Listener/catchcopy-v0002/listener.h @@ -0,0 +1,59 @@ +/** \file listener.h +\brief Define the server compatible with Ultracopier interface +\author alpha_one_x86 +\licence GPL3, see the file COPYING */ + +#ifndef SERVER_H +#define SERVER_H + +#include <string> +#ifndef ULTRACOPIER_PLUGIN_ALL_IN_ONE_DIRECT +#include <QtPlugin> +#endif + +#include "Environment.h" +#include "../../../interface/PluginInterface_Listener.h" +#include "catchcopy-api-0002/ServerCatchcopy.h" + +/// \brief Define the server compatible with Ultracopier interface +class Listener : public PluginInterface_Listener +{ + Q_OBJECT + #ifndef ULTRACOPIER_PLUGIN_ALL_IN_ONE_DIRECT + Q_PLUGIN_METADATA(IID "first-world.info.ultracopier.PluginInterface.Listener/1.0.0.0" FILE "plugin.json") + Q_INTERFACES(PluginInterface_Listener) + #endif +public: + Listener(); + /// \brief try listen the copy/move + void listen(); + /// \brief stop listen to copy/move + void close(); + /// \brief return the error strong + const std::string errorString() const; + /// \brief set resources for this plugins + void setResources(OptionInterface * options,const std::string &writePath,const std::string &pluginPath,const bool &portableVersion); + /// \brief to get the options widget, NULL if not have + QWidget * options(); + /// \brief to get a client list + std::vector<std::string> clientsList() const; +public slots: + /// \brief say to the client that's the copy/move is finished + void transferFinished(const uint32_t &orderId,const bool &withError); + /// \brief say to the client that's the copy/move is finished + void transferCanceled(const uint32_t &orderId); + /// \brief to reload the translation, because the new language have been loaded + void newLanguageLoaded(); +private: + ServerCatchcopy server; +private slots: + void errorInternal(const std::string &string); + void communicationErrorInternal(const std::string &string); + void clientName(uint32_t client,std::string name); + void copyWithoutDestination(const uint32_t &orderId,const std::vector<std::string> &sources); + void copy(const uint32_t &orderId,const std::vector<std::string> &sources,const std::string &destination); + void moveWithoutDestination(const uint32_t &orderId,const std::vector<std::string> &sources); + void move(const uint32_t &orderId,const std::vector<std::string> &sources,const std::string &destination); +}; + +#endif // SERVER_H diff --git a/plugins/Listener/catchcopy-v0002/listener.pro b/plugins/Listener/catchcopy-v0002/listener.pro new file mode 100644 index 0000000..b21289a --- /dev/null +++ b/plugins/Listener/catchcopy-v0002/listener.pro @@ -0,0 +1,26 @@ +CONFIG += c++11 +QMAKE_CXXFLAGS+="-std=c++0x -Wall -Wextra" +mac:QMAKE_CXXFLAGS+="-stdlib=libc++" + +TEMPLATE = lib +CONFIG += plugin +QT += network +win32:LIBS += -ladvapi32 +HEADERS = \ + $$PWD/listener.h \ + $$PWD/catchcopy-api-0002/VariablesCatchcopy.h \ + $$PWD/catchcopy-api-0002/ServerCatchcopy.h \ + $$PWD/catchcopy-api-0002/ExtraSocketCatchcopy.h \ + $$PWD/Environment.h \ + $$PWD/Variable.h \ + $$PWD/DebugEngineMacro.h \ + $$PWD/StructEnumDefinition.h \ + $$PWD/../../../interface/PluginInterface_Listener.h \ + $$PWD/../../../cpp11addition.h +SOURCES = \ + $$PWD/listener.cpp \ + $$PWD/catchcopy-api-0002/ServerCatchcopy.cpp \ + $$PWD/catchcopy-api-0002/ExtraSocketCatchcopy.cpp \ + $$PWD/../../../cpp11addition.cpp \ + $$PWD/../../../cpp11additionstringtointcpp.cpp +TARGET = $$qtLibraryTarget(listener) diff --git a/plugins/Listener/catchcopy-v0002/plugin.json b/plugins/Listener/catchcopy-v0002/plugin.json new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/plugins/Listener/catchcopy-v0002/plugin.json @@ -0,0 +1 @@ +{}
\ No newline at end of file |