diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/clienthandler.cpp | 19 | ||||
| -rw-r--r-- | src/daemon_clients/clienthandler.h | 10 | ||||
| -rw-r--r-- | src/daemon_clients/clitoolhandler.h | 13 | ||||
| -rw-r--r-- | src/daemon_clients/cocohandler.h | 3 | ||||
| -rw-r--r-- | src/daemon_clients/squishhandler.h | 55 | ||||
| -rw-r--r-- | src/daemon_clients/squishidehandler.h | 3 | ||||
| -rw-r--r-- | src/httpclient.cpp | 31 | ||||
| -rw-r--r-- | src/jsonhandler.cpp | 2 | ||||
| -rw-r--r-- | src/licenser.cpp | 94 | ||||
| -rw-r--r-- | src/tcpserver.cpp | 6 | ||||
| -rw-r--r-- | src/utils.cpp | 32 |
11 files changed, 172 insertions, 96 deletions
diff --git a/src/clienthandler.cpp b/src/clienthandler.cpp index 789176b..c60d730 100644 --- a/src/clienthandler.cpp +++ b/src/clienthandler.cpp @@ -44,27 +44,28 @@ bool ClientHandler::checkLicenseExpiryTime(std::string &reply) int ClientHandler::parseRequest() { // First find out the command (and operation for longterm case) + std::string cmd = utils::trimStr(params[0]); - m_request.type = RequestType::no_request; + m_request.reqType = RequestType::no_request; if (cmd == LICENSE_REQUEST_CMD) { - m_request.type = RequestType::license_request; - } else if (cmd == LONGTERM_REQUEST_CMD) { - m_request.type = RequestType::long_term_request; + m_request.reqType = RequestType::license_request; + } else if (cmd.substr(0, std::string(PERMANENT_REQUEST_CMD).length()) == PERMANENT_REQUEST_CMD) { + m_request.reqType = RequestType::long_term_request; // find either 'add' or 'remove' - std::string op = utils::trimStr(cmd.substr(8, cmd.length() -1)); + std::string op = utils::trimStr(cmd.substr(std::string(PERMANENT_REQUEST_CMD).length(), cmd.length() -1)); if (op != OP_ADD_RESERVATION && op != OP_REMOVE_RESERVATION) { - std::cout << "Invalid longterm operation: " << op; + std::cout << "Invalid operation for permanent request: " << op; return e_bad_request; } m_request.operation = op; } else if (cmd == SERVER_VERSION_CMD) { - m_request.type = RequestType::server_version; + m_request.reqType = RequestType::server_version; buildRequestJson(); return 0; } else if (cmd == DAEMON_VERSION_CMD) { - m_request.type = RequestType::daemon_version; + m_request.reqType = RequestType::daemon_version; } else if (cmd == RESERVATION_QUERY_CMD) { - m_request.type = RequestType::reservation_query; + m_request.reqType = RequestType::reservation_query; } else { std::cout << "Invalid command: " << cmd << std::endl; return e_bad_request; diff --git a/src/daemon_clients/clienthandler.h b/src/daemon_clients/clienthandler.h index 1181294..695847e 100644 --- a/src/daemon_clients/clienthandler.h +++ b/src/daemon_clients/clienthandler.h @@ -21,8 +21,6 @@ class ClientHandler { } virtual ~ClientHandler() { } - // If this client is using a floating model, it needs to be cached - // (Squish, Coco - Socket is alive until client stops working): Set this to true std::vector<std::string> params; @@ -30,15 +28,17 @@ class ClientHandler virtual bool isLicenseRequestDue() = 0; virtual int parseAndSaveResponse(std::string &response) = 0; virtual void buildRequestJson() = 0; + virtual void prepareRelease() { return; } + virtual void resetTimer() { return; } bool hasFloatingLicense() { return m_floatingLicense; } + bool hasParent() { return m_hasParent; } void updateLicense(const std::string &responseJson); int parseRequest(); RequestInfo getRequest() {return m_request;} int getSocketId() { return m_request.socketId; } - RequestType getRequestType() { return m_request.type; } + RequestType getRequestType() { return m_request.reqType; } int getClientType() { return (int)m_request.client; } - virtual void release() { return; } protected: License m_license; @@ -46,6 +46,7 @@ class ClientHandler LicdSetup m_settings;; uint64_t m_updateInterval; bool m_floatingLicense = false; + bool m_hasParent = false; bool checkLicenseExpiryTime(std::string &reply); bool checkLeewayTime(std::string &reply); @@ -57,6 +58,7 @@ static std::map<RequestReply, std::string> replyString { {e_license_rejected, "No valid license acquired"}, {e_no_conn_leeway, "License granted with warning: No server connection. Leeway time left: "}, {e_license_pool_full, "All licenses in use. No more license available on the server."}, + {e_no_permanent_to_release, "No permanent reservations available to be released"}, {e_bad_connection, "No connection to server. Try again later."} }; diff --git a/src/daemon_clients/clitoolhandler.h b/src/daemon_clients/clitoolhandler.h index a63dd40..c9446d1 100644 --- a/src/daemon_clients/clitoolhandler.h +++ b/src/daemon_clients/clitoolhandler.h @@ -19,10 +19,11 @@ class CliToolHandler : public virtual ClientHandler { void buildRequestJson() override { - if (m_request.type == RequestType::server_version) { + if (m_request.reqType == RequestType::server_version) { m_request.payload = ""; return; } + // Permanent operation: std::stringstream pay; pay << "{"; pay<< "\"license_number\":" << "\"" << m_request.licenseId << "\","; @@ -36,22 +37,22 @@ class CliToolHandler : public virtual ClientHandler { { JsonHandler json(response); std::stringstream ss; - std::cout << json.dump(4); - if (m_request.type == RequestType::long_term_request) { + if (m_request.reqType == RequestType::long_term_request) { // long-term request: Have "message" field from response JSON directly as a reply to the user response = json.get("message"); if (json.get("status") != "true" ) { - if (json.get("message") == "License fully reserved") { + if (response == "License fully reserved") { response = replyString[e_license_pool_full]; + } else if (response.find("cannot be early released") != std::string::npos) { + response = replyString[e_no_permanent_to_release]; } else { response = replyString[e_license_rejected]; } // Do not touch the license file, just return return 1; } - } else if (m_request.type == RequestType::server_version) { - std::cout << "Parsing server version response\n"; + } else if (m_request.reqType == RequestType::server_version) { response = "Qt License Server v"; response += json.get("version"); return 0; // Do not touch cached license files pls. diff --git a/src/daemon_clients/cocohandler.h b/src/daemon_clients/cocohandler.h index d25b36c..d4a32d9 100644 --- a/src/daemon_clients/cocohandler.h +++ b/src/daemon_clients/cocohandler.h @@ -13,13 +13,14 @@ class CocoHandler : public ClientHandler { : ClientHandler(request, settings) { m_updateInterval = utils::strToInt(m_settings.get("coco_report_interval")); + m_floatingLicense = true; } bool isLicenseRequestDue() override { return true; } bool isCachedReservationValid(std::string &reply) override {return true;} int parseAndSaveResponse(std::string &response) override { return 0; } void buildRequestJson() override {return;} - void release() override + void prepareRelease() override { // TODO return; diff --git a/src/daemon_clients/squishhandler.h b/src/daemon_clients/squishhandler.h index 366c624..24c5aed 100644 --- a/src/daemon_clients/squishhandler.h +++ b/src/daemon_clients/squishhandler.h @@ -15,26 +15,32 @@ class SquishHandler : public ClientHandler { m_updateInterval = utils::strToInt(m_settings.get("squish_report_interval")); m_request.operation = OP_ADD_RESERVATION; m_request.startTimestamp = utils::getTimestampNow(); + m_license.last_timestamp = 0; + m_floatingLicense = true; } - bool isLicenseRequestDue() override { return true; } - bool isCachedReservationValid(std::string &reply) override { return true; } + bool isCachedReservationValid(std::string &reply) override { return false; } void buildRequestJson() override { std::stringstream pay; pay << "{"; - pay<< "\"license_number\":" << "\"" << m_request.licenseId << "\","; - pay << "\"user_id\":" << "\"" << m_request.userId << "\","; - pay << "\"hw_id\":" << "\"" << m_settings.get("hw_id") << "\","; - pay << "\"operation\":" << "\"" << m_request.operation << "\","; - pay << "\"src\":" << "\"" << m_request.appName << "\","; - pay << "\"host_os\":" << "\"" << m_settings.get("host_os") << "\","; - pay << "\"src_version\":" << "\"" << m_request.appVersion << "\","; - pay << "\"email\":" << "\"" << m_request.email << "\""; + pay << "\"license_number\":\"" << m_request.licenseId << "\","; + pay << "\"user_id\":\"" << m_request.userId << "\","; + pay << "\"hw_id\":\"" << m_settings.get("hw_id") << "\","; + pay << "\"operation\":\"" << m_request.operation << "\","; + pay << "\"type\":\"" << m_request.runnerType << "\","; + pay << "\"src\":\"" << m_request.appName << "\","; + pay << "\"host_os\":\"" << m_settings.get("host_os") << "\","; + pay << "\"src_version\":\"" << m_request.appVersion << "\","; + pay << "\"reservation_id\":\"" << m_request.parentReservationId << "\","; + pay << "\"email\":\"" << m_request.email << "\""; + if (m_request.operation == OP_QA_RELEASE_RESERVATION) { + pay << "\"custom_duration\":\"" << m_request.stopTimestamp + - m_request.startTimestamp << "\","; + } pay << "}"; m_request.payload = pay.str(); - m_floatingLicense = true; } int parseAndSaveResponse(std::string &response) override @@ -43,8 +49,6 @@ class SquishHandler : public ClientHandler { // response JSON is converted to a reply string to the client from now on std::stringstream ss; m_license.status = (json.get("status") == "true") ? true : false; - - if (m_license.status) { ss << replyString[e_license_granted]; ss << " expiry_date=" << json.get("expiry_date"); @@ -65,15 +69,11 @@ class SquishHandler : public ClientHandler { m_license.user_id = json.get("user_id"); m_license.reservation_id = json.get("reservation_id"); m_license.license_key = json.get("license_key"); - m_license.parent_reservation_id = json.get("parent_reservvation_id"); - m_license.operation = "add"; // Add timestamp into license JSON - struct timeval tp; - gettimeofday(&tp, NULL); - uint64_t timeNow = tp.tv_sec; + m_license.last_timestamp = utils::getTimestampNow(); // Save the JSON, adding timestamp - json.add("last_timestamp", timeNow); + json.add("last_timestamp", m_license.last_timestamp); int result = utils::writeToFile(m_request.licenseFile, json.dump(4)); if (result != 0) { std::cout << "ERROR saving license file: '" << m_request.licenseFile << "': " << strerror(result) << std::endl; @@ -81,10 +81,23 @@ class SquishHandler : public ClientHandler { return 0; } - void release() override + void prepareRelease() override { - m_request.operation = OP_REMOVE_RESERVATION; + m_request.operation = OP_QA_RELEASE_RESERVATION; m_request.stopTimestamp = utils::getTimestampNow(); buildRequestJson(); } + + void resetTimer() override + { + m_license.last_timestamp = utils::getTimestampNow(); + } + + bool isLicenseRequestDue() override { + uint64_t now = utils::getTimestampNow(); + if (m_license.last_timestamp == 0) return true; // startup + if ((now - m_license.last_timestamp) > m_updateInterval) + return true; + return false; + } };
\ No newline at end of file diff --git a/src/daemon_clients/squishidehandler.h b/src/daemon_clients/squishidehandler.h index a17b2db..8f08e0c 100644 --- a/src/daemon_clients/squishidehandler.h +++ b/src/daemon_clients/squishidehandler.h @@ -14,13 +14,14 @@ class SquishIdeHandler : public ClientHandler { { m_updateInterval = utils::strToInt(m_settings.get("squish_report_interval")); m_request.operation = OP_ADD_RESERVATION; + m_floatingLicense = true; } bool isLicenseRequestDue() override { return true; } bool isCachedReservationValid(std::string &reply) override {return true;} void buildRequestJson() override {return;} int parseAndSaveResponse(std::string &response) override { return 0; } - void release() override + void prepareRelease() override { // TODO return; diff --git a/src/httpclient.cpp b/src/httpclient.cpp index 730b310..0682be8 100644 --- a/src/httpclient.cpp +++ b/src/httpclient.cpp @@ -7,18 +7,18 @@ size_t WriteCallback(char *contents, size_t size, size_t nmemb, void *userp) { - std::cout << "Reading data\n"; + //std::cout << "Reading data\n"; ((std::string *)userp)->append(contents, size * nmemb); return size * nmemb; } HttpClient::HttpClient( const std::string &serverUrl, const std::string &requestAccessPoint, - const std::string &longtermAccessPoint, + const std::string &permanentAccessPoint, const std::string &versionAccessPoint) : m_serverUrl(serverUrl), m_requestAccessPoint(requestAccessPoint), - m_longtermAccessPoint(longtermAccessPoint), + m_permanentAccessPoint(permanentAccessPoint), m_versionAccessPoint(versionAccessPoint) { m_userAgent += DAEMON_VERSION; @@ -32,6 +32,8 @@ int HttpClient::sendRequest(std::string &reply, const std::string &payload, /* specify URL to POST */ request.url = server; + request.payload = payload; + if (server.empty()) { // If server URL is not given as param, we use the default request.url = m_serverUrl; @@ -39,30 +41,26 @@ int HttpClient::sendRequest(std::string &reply, const std::string &payload, if (!authKey.empty()) { // normal request request.url += m_requestAccessPoint; + std::string auth = "Authorization: " + authKey; + //std::cout << "Setting authorization: " << auth << std::endl; + request.headers = curl_slist_append(request.headers, auth.c_str()); } else { if (payload.empty()) { // version query request.url += m_versionAccessPoint; } else { - // long-term request - request.url += m_longtermAccessPoint; + // permanentrequest + request.url += m_permanentAccessPoint; } } - request.authKey = authKey; - request.payload = payload; - if (!request.authKey.empty()) { - // Set authorization only if applicable - std::string auth = "Authorization: " + request.authKey; - request.headers = curl_slist_append(request.headers, auth.c_str()); - } std::string agent = "User-Agent: " + m_userAgent; request.headers = curl_slist_append(request.headers, agent.c_str()); request.headers = curl_slist_append(request.headers, "Accept: */*"); request.headers = curl_slist_append(request.headers, "Content-Type: application/json"); request.headers = curl_slist_append(request.headers, "charset: utf-8"); - std::cout << "HTTPClient() -- server URL " << request.url << std::endl; + //std::cout << "HTTPClient() -- server URL " << request.url << std::endl; int retVal = 0; @@ -78,8 +76,8 @@ int HttpClient::sendRequest(std::string &reply, const std::string &payload, retVal = 1; } if (retVal == 0) { - std::cout << request.reply.length() << " bytes retrieved from license server:\n"; - std::cout << request.reply << std::endl; + std::cout << request.reply.length() << " bytes retrieved from license server\n"; + //std::cout << request.reply << std::endl; } else { std::cout << m_lastError << std::endl; } @@ -112,6 +110,9 @@ int HttpClient::doRequest(CURL *curl, HttpRequest &request) else { curl_easy_setopt(curl, CURLOPT_HTTPGET, 1); } + if(curl_easy_setopt(curl, CURLOPT_USE_SSL, (long)CURLUSESSL_ALL) != CURLE_OK) { + std::cout << "Warning! No SSL support available\n"; + } curl_easy_setopt(curl, CURLOPT_TIMEOUT, SERVER_CONN_TIMEOUT); // get it diff --git a/src/jsonhandler.cpp b/src/jsonhandler.cpp index f46fd72..18430c1 100644 --- a/src/jsonhandler.cpp +++ b/src/jsonhandler.cpp @@ -76,10 +76,10 @@ std::string JsonHandler::dump(uint8_t indent) top << "{"; if (indent > 0) { res << ind << "\"reservation\": {" << std::endl; - top << std::endl; } else { res << "\"reservation\":{"; } + top << std::endl; uint8_t count = 0; for (auto const &item : m_items) { diff --git a/src/licenser.cpp b/src/licenser.cpp index 66c4c2d..0b3cc48 100644 --- a/src/licenser.cpp +++ b/src/licenser.cpp @@ -10,7 +10,7 @@ Licenser::Licenser(uint16_t tcpPort) // Init daemon settings settings = new LicdSetup(e_set_type_daemon); - // Check if our setup already has some hw id - generate it if not + // Check if our setup already has some hw id - generate one if not if (settings->get("hw_id").empty()) { setHwId(); } @@ -22,7 +22,7 @@ Licenser::Licenser(uint16_t tcpPort) // Start the HTTP client m_http = new HttpClient(settings->get("server_addr"), settings->get("reservation_access_point"), - settings->get("long-term_access_point"), + settings->get("permanent_access_point"), settings->get("version_query_access_point")); // Start the TCP/IP server m_server = new TcpServer(tcpPort); @@ -37,7 +37,6 @@ Licenser::~Licenser() std::cout << "Daemon stopped." << std::endl; } - int Licenser::listen() { m_infoString = ""; @@ -45,31 +44,32 @@ int Licenser::listen() std::string input = m_server->listenToClients(socket); input = utils::trimStr(input); if (input.empty()) { + if (m_floatingClients.size() > 0) { + checkReportsDue(); + } return 0; //continue; } if (input == CLIENT_CLOSED_MSG) { std::cout << "Client disconnected, socket id " << socket << std::endl; - // Now to check if the client had a floating license: - clientDisconnected(socket); + removeClient(socket); return 0; } - std::cout << "Got an request: " << input << std::endl; + + std::cout << "Got a request: " << input << std::endl; std::string reply = ""; // Holds server response first (if got any). After parsing, holds reply to the client int clientType = parseInputAndCreateCLient(socket, input); - std::cout << "Client type: " << clientType << std::endl; if (clientType != (int)ClientType::client_undefined) { if (m_currentClient->parseRequest() != e_bad_request) { RequestType reqType = m_currentClient->getRequestType(); - std::string payload = ""; if (reqType == RequestType::reservation_query) { reply = checkReservations(); } else if (reqType == RequestType::daemon_version) { reply = getDaemonVersion(); } else { - std::cout << "Initiating request to server\n"; + std::cout << "Initiating a request to the server\n"; if (m_currentClient->isLicenseRequestDue()) { if (sendServerRequest(reply) == e_bad_connection) { // Bad server connection: Check the existing license file for expiry date @@ -92,7 +92,8 @@ int Licenser::listen() } if (m_currentClient->hasFloatingLicense()) { - // QA tool, Coco or Squish (cLient with floating license): Store it in cache + // QA tool, Coco or Squish (client with floating license): Store it in cache + std::cout << "Storing client in cache\n"; m_floatingClients.push_back(m_currentClient); } @@ -104,17 +105,23 @@ int Licenser::listen() if (m_floatingClients.size() > 0) { checkReportsDue(); } + std::cout << "Current clients in cache: " << m_floatingClients.size() << std::endl; return 0; } + int Licenser::checkReportsDue() { // Check if there's any floating clients which has periodic reports due - // TODO!! ClientHandler *client; for (int i = 0 ; i < m_floatingClients.size(); i++) { client = m_floatingClients[i]; if (client->isLicenseRequestDue()) { - // TODO Ping server (Req Json might need updating here) + std::string reply; + //std::cout << "Reporting to server (socket ID " << client->getSocketId() << std::endl; + if (sendServerRequest(reply) != e_bad_connection) { + std::cout << "Reported alive floating reservation with socket ID " << client->getSocketId() << std::endl; + client->resetTimer(); + } } } return 0; @@ -127,6 +134,7 @@ int Licenser::parseInputAndCreateCLient(uint16_t socketId, const std::string &in // to initiate into m_currentClient member RequestInfo request; request.socketId = socketId; + // Find out which class of client is calling ClientType retVal = ClientType::client_undefined; std::vector<std::string> paramList = utils::splitStr(incoming, '-'); @@ -180,14 +188,20 @@ int Licenser::parseInputAndCreateCLient(uint16_t socketId, const std::string &in int Licenser::sendServerRequest(std::string &reply) { - std::string authKey; + std::string auth; RequestInfo request = m_currentClient->getRequest(); if (request.client != ClientType::client_CLI) { // Generate auth hash for HTTP headers (CLI tool does not need it) - doHmacHashSha256(request.payload, settings->get("server_secret"), authKey); // 19755982232ff7b6f6d0f3c57ffc1c0e4f03060e7175d478f7b146fb1e000507"; + std::string hash; + doHmacHashSha256(request.payload, settings->get("server_secret"), hash); // 19755982232ff7b6f6d0f3c57ffc1c0e4f03060e7175d478f7b146fb1e000507"; + // Bearer is the same hash (?) + auth = "apikey " + hash; + //auth += ", Bearer " + hash; } + // Send the request - if (m_http->sendRequest(reply, request.payload, request.serverAddr, authKey) != 0) { + std::cout << "Sending request: " << request.payload << std::endl; + if (m_http->sendRequest(reply, request.payload, request.serverAddr, auth) != 0) { return e_bad_connection; } return e_got_response; @@ -196,7 +210,7 @@ int Licenser::sendServerRequest(std::string &reply) void Licenser::doHmacHashSha256(const std::string &payload, const std::string &secret, std::string &authKey) { std::stringstream ss_result; - ss_result << "apikey "; + ss_result << ""; // Allocate memory for the HMAC std::vector<uint8_t> out(SHA256_HASH_SIZE); @@ -213,10 +227,6 @@ void Licenser::doHmacHashSha256(const std::string &payload, const std::string &s authKey = ss_result.str(); JsonHandler pay(payload); - // Print out the result - std::cout << "Message: " << pay.dump(4) << std::endl; - std::cout << "Key: " << secret << std::endl; - std::cout << "HMAC: " << authKey << std::endl; } std::string Licenser::checkReservations() @@ -246,7 +256,8 @@ std::string Licenser::checkReservations() return reply.str(); } -void Licenser::clientDisconnected(int socketId) { +void Licenser::removeClient(int socketId) { + // Check if the client had a floating license: int index = -1; ClientHandler *client; for (int i = 0; i < m_floatingClients.size(); i++) { @@ -257,13 +268,23 @@ void Licenser::clientDisconnected(int socketId) { break; } } - if (index != -1 && m_currentClient->hasFloatingLicense()) { - m_currentClient->release(); // not implemented yet - // m_floatingClients.erase(index); // TODO don't erase yet, server might be down + if (index == -1 ) { + // non-floating + return; } + // Client has a floating license - need to release the reservation now -} + m_currentClient->prepareRelease(); + std::string reply; + if (sendServerRequest(reply) != e_bad_connection) { + // if connection succeeds, we can forget about that client + std::cout << "Removing floating reservation with socket ID " << m_currentClient->getSocketId() << std::endl; + m_floatingClients.erase(m_floatingClients.begin() + index); + } + + return; +} std::string Licenser::getDaemonVersion() { @@ -273,8 +294,23 @@ std::string Licenser::getDaemonVersion() } void Licenser::setHwId() { - - // TODO calculate hwid hash out of MAC, uname etc... - // Edit the qtlicd.ini to make it permanent + std::cout << "No HW ID found, generating it ... "; + std::string hwInfo = utils::getSystemHwInfoString(); + std::string hash; + doHmacHashSha256(hwInfo, settings->get("server_secret"), hash); + std::string settingsString; + utils::readFile(settingsString, DAEMON_SETTINGS_FILE); + std::vector<std::string> lines = utils::splitStr(settingsString, '\n'); + settingsString = ""; + std::string wanted = "hw_id="; + for (std::string line : lines) { + if (line.substr(0, wanted.length()) == wanted) { + line = wanted + hash; + } + line += '\n'; + settingsString += line; + } + utils::writeToFile(DAEMON_SETTINGS_FILE, settingsString); + settings->set("hw_id", hash); return; -}
\ No newline at end of file +} diff --git a/src/tcpserver.cpp b/src/tcpserver.cpp index b1205ba..ebbdf63 100644 --- a/src/tcpserver.cpp +++ b/src/tcpserver.cpp @@ -34,7 +34,7 @@ TcpServer::TcpServer(uint16_t serverPort) perror("setsockopt failed"); exit(EXIT_FAILURE); } - timeval tv {2, 0}; //t.tv_sec = 2; t.tv_usec = 0; + timeval tv {1, 0}; //t.tv_sec = 2; t.tv_usec = 0; int ret = setsockopt(m_masterSocket, SOL_SOCKET, SO_RCVTIMEO, (char*)&tv, sizeof(timeval)); if (ret < 0) { @@ -105,7 +105,7 @@ std::string TcpServer::listenToClients(int &socket) max_sd = sd; } // timeout - timeval tv{2, 0}; //t.tv_sec = 2; t.tv_usec = 0; + timeval tv{1, 0}; //t.tv_sec = 2; t.tv_usec = 0; // Wait for an activity on one of the sockets. int activity = select((int)max_sd + 1, &m_readfds, NULL, NULL, &tv); @@ -125,6 +125,7 @@ std::string TcpServer::listenToClients(int &socket) // If position is free if (m_clientSocket[i] == 0) { m_clientSocket[i] = new_socket; + socket = i; std::cout << "New connection - adding to list of sockets with id " << i << std::endl; break; } @@ -147,6 +148,7 @@ std::string TcpServer::listenToClients(int &socket) getpeername(sd, (struct sockaddr *)&m_address, (socklen_t *)&m_addrlen); // Close the socket and mark as 0 in list for reuse + socket = i; doCloseSocket(sd); m_clientSocket[i] = 0; data = "closed"; diff --git a/src/utils.cpp b/src/utils.cpp index cb68829..1fa48f7 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -158,7 +158,7 @@ int readFile(std::string &str, const std::string &filepath) if (file.is_open()) { std::string line; while (getline(file, line)) { - ss << line; + ss << line << std::endl; } file.close(); } else { @@ -237,13 +237,13 @@ std::vector<std::string> getDirListing(const std::string &directory, const std:: int deleteFile(const std::string &filepath) { - std::remove(filepath.c_str()); // delete file - bool failed = !std::ifstream("file1.txt"); - if(failed) { - std::perror("Error deleting file"); - return 1; + if (fileExists(filepath)) { + std::remove(filepath.c_str()); // delete file + return 0; } - return 0; + std::cout << "No file " << filepath << " found to delete\n"; + + return 1; } std::string getOsName() @@ -263,6 +263,24 @@ std::string getOsName() #endif } +std::string getSystemHwInfoString() { + // Trying to get individual HW string, using network parameters and current time (epoch) + std::stringstream hwInfo; + std::string ip_mac; +#if _WIN32 + system("ipconfig > hw.txt"); +#elif __APPLE__ || __MACH__ + system("ifconfig > hw.txt"); +#elif __linux__ + system("ip addr > hw.txt"); +#endif + readFile(ip_mac, "hw.txt"); + hwInfo << getTimestampNow() << std::endl << ip_mac; + deleteFile("hw.txt"); + return hwInfo.str(); +} + + #if _WIN32 /* * Windows implementation of missing POSIX strptime() |
