#include #include #include #include #include #include #include #include #include #include #include "qmlhandler.h" #include #include #include using boost::asio::buffer; using namespace std; int inpipefd[2]; int outpipefd[2]; char buf[1024]; bool programActive = true; void QMLHandler::onExit() { write(outpipefd[1], "disconnect\n", strlen("disconnect\n")); } void QMLHandler::handleJSON(string buffer) { Json::Value root; Json::CharReaderBuilder builder; Json::CharReader * reader = builder.newCharReader(); string jsonError; bool parsingSuccessful = reader->parse(buffer.c_str(), buffer.c_str() + buffer.size(), &root, &jsonError); 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") { programActive = false; } } void QMLHandler::readPipeLoop() { unsigned int readOffset = 0; unsigned int pollCount = 0; struct pollfd inPipeStatus; inPipeStatus.fd = inpipefd[0]; inPipeStatus.events = POLLIN; while (programActive) { 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) {} // Sending void QMLHandler::onSendingSelectFileButton(QUrl url) { emit log("File Selected: " + url.toString()); emit sendingSetFileUrlText("Selected File: " + url.toString()); } void QMLHandler::onSendingSendFileButton() { emit log("Sending File !"); } // Receiving // Messages void QMLHandler::onMessagesSendButton(QString msg) { emit message(msg); } // Settings void QMLHandler::onSettingsSwitchServerButton() { emit settingsOpenSwitchServerPopup(); } // Ip Popup void QMLHandler::onIpPopupEnterIp(QString 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 void QMLHandler::onSwitchPopupEnterIp(QString ip) { qInfo() << "Switching to " << ip; } // Footer void QMLHandler::onFooterGetStatusButton() { write(outpipefd[1], "status\n", strlen("status\n")); }