|
@@ -1,17 +1,97 @@
|
|
|
|
+#include <csignal>
|
|
|
|
+#include <cstdio>
|
|
|
|
+#include <cstdlib>
|
|
|
|
+#include <iostream>
|
|
|
|
+#include <poll.h>
|
|
|
|
+#include <sys/prctl.h>
|
|
|
|
+#include <sys/wait.h>
|
|
|
|
+#include <thread>
|
|
|
|
+#include <unistd.h>
|
|
|
|
+
|
|
#include "qmlhandler.h"
|
|
#include "qmlhandler.h"
|
|
|
|
+#include <boost/asio.hpp>
|
|
|
|
+#include <iostream>
|
|
|
|
+#include <json/json.h>
|
|
|
|
+
|
|
|
|
+using boost::asio::buffer;
|
|
|
|
+
|
|
|
|
+using namespace std;
|
|
|
|
+
|
|
|
|
+int inpipefd[2];
|
|
|
|
+int outpipefd[2];
|
|
|
|
+char buf[1024];
|
|
|
|
+
|
|
|
|
+void QMLHandler::handleJSON(string buffer) {
|
|
|
|
+ Json::Value root;
|
|
|
|
+ Json::Reader reader;
|
|
|
|
+
|
|
|
|
+ bool parsingSuccessful = reader.parse(buffer, root);
|
|
|
|
+ qInfo() << parsingSuccessful;
|
|
|
|
+ if (!parsingSuccessful) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ const Json::Value command = root["command"];
|
|
|
|
+ string cmd = command.asString();
|
|
|
|
+
|
|
|
|
+ if (cmd == "status") {
|
|
|
|
+ emit footerSetStatus(root["response"].asString().c_str());
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ else if (cmd == "close") {
|
|
|
|
+ exit(0);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void QMLHandler::readPipeLoop() {
|
|
|
|
+ unsigned int readOffset = 0;
|
|
|
|
+ unsigned int pollCount = 0;
|
|
|
|
+ struct pollfd inPipeStatus;
|
|
|
|
+ inPipeStatus.fd = inpipefd[0];
|
|
|
|
+ inPipeStatus.events = POLLIN;
|
|
|
|
+
|
|
|
|
+ while (true) {
|
|
|
|
+ poll(&inPipeStatus, 1, 100);
|
|
|
|
+
|
|
|
|
+ if (inPipeStatus.revents & POLLIN) {
|
|
|
|
+ readOffset += read(inpipefd[0], buf + readOffset, 1024);
|
|
|
|
+
|
|
|
|
+ pollCount = 0;
|
|
|
|
+
|
|
|
|
+ buf[1023] = 0;
|
|
|
|
+ buf[strlen(buf)] = 0;
|
|
|
|
+ } else {
|
|
|
|
+ pollCount++;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (pollCount > 9 && buf[0]) {
|
|
|
|
+ string cleanBuffer = buf + strcspn(buf, "\n") + 1;
|
|
|
|
+ string receivedData = cleanBuffer.substr(0, cleanBuffer.size() - 1);
|
|
|
|
+
|
|
|
|
+ emit log(QString::fromStdString(receivedData));
|
|
|
|
+ qInfo() << QString::fromStdString(receivedData);
|
|
|
|
+ handleJSON(receivedData);
|
|
|
|
+ memset(buf, 0, 1024);
|
|
|
|
+ pollCount = 0;
|
|
|
|
+ readOffset = 0;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
|
|
QMLHandler::QMLHandler(QObject *parent) : QObject(parent) {}
|
|
QMLHandler::QMLHandler(QObject *parent) : QObject(parent) {}
|
|
|
|
|
|
|
|
+// Main
|
|
|
|
+void QMLHandler::onClosing() {
|
|
|
|
+ qInfo() << "Closing";
|
|
|
|
+ write(outpipefd[1], "disconnect\n", strlen("disconnect\n"));
|
|
|
|
+}
|
|
|
|
+
|
|
// Sending
|
|
// Sending
|
|
void QMLHandler::onSendingSelectFileButton(QUrl url) {
|
|
void QMLHandler::onSendingSelectFileButton(QUrl url) {
|
|
- qInfo() << "File Selected: " << url.toString();
|
|
|
|
|
|
+ emit log("File Selected: " + url.toString());
|
|
emit sendingSetFileUrlText("Selected File: " + url.toString());
|
|
emit sendingSetFileUrlText("Selected File: " + url.toString());
|
|
}
|
|
}
|
|
|
|
|
|
-void QMLHandler::onSendingSendFileButton() {
|
|
|
|
- qInfo() << "Sending File";
|
|
|
|
- emit log("Sending File");
|
|
|
|
-}
|
|
|
|
|
|
+void QMLHandler::onSendingSendFileButton() { emit log("Sending File !"); }
|
|
|
|
|
|
// Receiving
|
|
// Receiving
|
|
|
|
|
|
@@ -25,10 +105,43 @@ void QMLHandler::onSettingsSwitchServerButton() {
|
|
|
|
|
|
// Ip Popup
|
|
// Ip Popup
|
|
void QMLHandler::onIpPopupEnterIp(QString ip) {
|
|
void QMLHandler::onIpPopupEnterIp(QString ip) {
|
|
- qInfo() << "Connecting to " << ip;
|
|
|
|
|
|
+ pid_t pid = 0;
|
|
|
|
+
|
|
|
|
+ pipe(inpipefd);
|
|
|
|
+ pipe(outpipefd);
|
|
|
|
+ pid = fork();
|
|
|
|
+ if (pid == 0) {
|
|
|
|
+ // Child
|
|
|
|
+ dup2(outpipefd[0], STDIN_FILENO);
|
|
|
|
+ dup2(inpipefd[1], STDOUT_FILENO);
|
|
|
|
+ dup2(inpipefd[1], STDERR_FILENO);
|
|
|
|
+
|
|
|
|
+ // ask kernel to deliver SIGTERM in case the parent dies
|
|
|
|
+ prctl(PR_SET_PDEATHSIG, SIGTERM);
|
|
|
|
+
|
|
|
|
+ // Set the path to the CLI - pass argument h (help) for now
|
|
|
|
+ // TODO: Change hardcoded path
|
|
|
|
+ execl("../../cli/build/ccats-cli", "ccats-cli", ip.toUtf8().constData(),
|
|
|
|
+ "--machine", (char *)NULL);
|
|
|
|
+
|
|
|
|
+ exit(1);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // TODO: Not hardcoded
|
|
|
|
+ emit footerSetStatus("Connected to " + ip);
|
|
|
|
+
|
|
|
|
+ close(outpipefd[0]);
|
|
|
|
+ close(inpipefd[1]);
|
|
|
|
+
|
|
|
|
+ std::thread(&QMLHandler::readPipeLoop, this).detach();
|
|
}
|
|
}
|
|
|
|
|
|
// Switch Popup
|
|
// Switch Popup
|
|
void QMLHandler::onSwitchPopupEnterIp(QString ip) {
|
|
void QMLHandler::onSwitchPopupEnterIp(QString ip) {
|
|
qInfo() << "Switching to " << ip;
|
|
qInfo() << "Switching to " << ip;
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+// Footer
|
|
|
|
+void QMLHandler::onFooterGetStatusButton() {
|
|
|
|
+ write(outpipefd[1], "status\n", strlen("status\n"));
|
|
|
|
+}
|