Bit.ASICmon-c/main.cpp

272 lines
6.2 KiB
C++

#include <arpa/inet.h>
#include <fcntl.h>
#include <fstream>
#include <iostream>
#include <netdb.h>
#include <regex>
#include <sys/sendfile.h>
#include <sys/stat.h>
#include "inc/args.hpp"
#include "inc/json.hpp"
#include "inc/macros.hpp"
using namespace std;
using json = nlohmann::json;
int port = 9070;
json asictypes = json::parse(R"([
{"key": "A1066", "value": "Avalon 1066"}
])");
void tcpQuery(char* ip, int port, char* cmd, char* msg, int lenmsg) {
INFO("IP: ", ip)
INFO("Port: ", port)
INFO("Command: ", cmd)
struct hostent* host = gethostbyname(ip);
sockaddr_in sendSockAddr;
bzero((char*)&sendSockAddr, sizeof(sendSockAddr));
sendSockAddr.sin_family = AF_INET;
sendSockAddr.sin_addr.s_addr = inet_addr(inet_ntoa(*(struct in_addr*)*host->h_addr_list));
sendSockAddr.sin_port = htons(port);
int clientSd = socket(AF_INET, SOCK_STREAM, 0);
int status = connect(clientSd, (sockaddr*) &sendSockAddr, sizeof(sendSockAddr));
if(status < 0) {
ERR("Error connecting to socket!")
return;
}
INFO("Connected to the server!")
memset(msg, 0, strlen(msg));
send(clientSd, cmd, sizeof(cmd), 0);
INFO("Awaiting server response...");
recv(clientSd, msg, lenmsg, MSG_WAITALL);
INFO("Server: ", msg)
close(clientSd);
INFO("-------------------------")
}
void getFrom1066(char* ip, char* cmd, char* msg, int lenmsg) {
INFO("------ AVALON 1066 ------")
int port = 4028;
tcpQuery(ip, port, cmd, msg, lenmsg);
}
void httpGetURL(char* url, char* line, const char* symbol) {
char *copy = new char[strlen(line) + 1];
strcpy(copy, line);
char *token = new char[1024];
strcpy(token, strtok(copy, symbol));
int current = 0;
int run = 1;
while(token != nullptr && run) {
token = strtok(nullptr, " ");
if(current == 0) {
strcpy(url, token);
if (url == nullptr) {
strcpy(url, "");
}
run = 0;
}
current = current + 1;
}
delete[] copy;
}
void parseUrl(char* url, char* res) {
res = strtok(url, "/");
while(res) {
INFO(res);
res = strtok(nullptr, "/");
}
}
void getStats(char* stats) {
ifstream f("asics.json");
json data = json::parse(f);
f.close();
json res;
if(data["mode"] == "manual") {
for (json::iterator it = data["asics"].begin(); it != data["asics"].end(); ++it) {
if(strcmp((*it)["type"].get<string>().c_str(), "A1066") == 0) {
int lenmsg = 1024*8;
char* msg = new char[lenmsg];
getFrom1066((char*)((*it)["address"].get<string>().c_str()), (char*)"summary", msg, lenmsg);
res["asics"][it.key()] = msg;
delete[] msg;
}
// INFO(it.key(), ": ", it.value())
}
}
else {
WARN("Not implemented!")
}
strcat(stats, res.dump().c_str());
data.clear();
res.clear();
}
void httpServer(int port) {
char http_header[25] = "HTTP/1.1 200 Ok\r\n";
int server_fd, new_socket, pid;
struct sockaddr_in address;
int addrlen = sizeof(address);
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
CRIT("In sockets")
exit(EXIT_FAILURE);
}
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(port);
memset(address.sin_zero, '\0', sizeof address.sin_zero);
if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {
CRIT("In bind")
close(server_fd);
exit(EXIT_FAILURE);
}
if (listen(server_fd, 10) < 0) {
CRIT("In listen")
exit(EXIT_FAILURE);
}
INFO("HTTP server started on: http://127.0.0.1:", port)
while(1) {
printf("\n+++++++ Waiting for new connection ++++++++\n\n");
if ((new_socket = accept(server_fd, (struct sockaddr*)&address, (socklen_t*)&addrlen)) < 0) {
CRIT("In accept")
exit(EXIT_FAILURE);
}
pid = fork();
if(pid < 0) {
CRIT("Error on fork")
exit(EXIT_FAILURE);
}
if(pid == 0) {
char *url = new char[1024];
char *msg = new char[1024*64];
char *buffer = new char[30000];
char *copy_head = new char[strlen(http_header) + 200];
read(new_socket, buffer, 30000);
strcpy(copy_head, http_header);
httpGetURL(url, buffer, " ");
INFO(url)
if(strstr(url, "/api/"))
strcat(copy_head, "Content-Type: application/json\r\n\r\n");
else if(strstr(url, ".js"))
strcat(copy_head, "Content-Type: text/javascript\r\n\r\n");
else
strcat(copy_head, "Content-Type: text/html\r\n\r\n");
write(new_socket, copy_head, strlen(copy_head));
if(strstr(url, ".js")) {
char *file_path = new char[512];
strcpy(file_path, ".");
strcat(file_path, url);
int file = open(file_path, O_RDONLY);
INFO(file);
if(file < 0){
WARN("Cannot Open file path : ", file_path, " with error ", file)
send(new_socket, R"({"error":"FILE_NOT_EXISTS"})", 27, MSG_DONTWAIT);
}
struct stat stat_buf;
fstat(file, &stat_buf);
sendfile(new_socket, file, nullptr, stat_buf.st_blksize);
delete[] file_path;
}
else if(strcmp(url, "/") == 0) {
strcpy(msg, (char*)R"(<meta charset="UTF-8"><script defer src="/index.js"></script>)");
send(new_socket, msg, strlen(msg), MSG_DONTWAIT);
}
else if(strcmp(url, "/api/getstats") == 0) {
char *stats = new char[1024*64];
getStats(stats);
send(new_socket, stats, strlen(stats), MSG_DONTWAIT);
delete[] stats;
}
else if(strcmp(url, "/api/asictypes") == 0) {
strcpy(msg, asictypes.dump().c_str());
send(new_socket, msg, strlen(msg), MSG_DONTWAIT);
}
else {
strcpy(msg, "");
send(new_socket, msg, strlen(msg), MSG_DONTWAIT);
}
delete[] msg;
delete[] url;
delete[] buffer;
delete[] copy_head;
close(new_socket);
exit(0);
}
else{
printf(">>>>>>>>>>Parent create child with pid: %d <<<<<<<<<", pid);
close(new_socket);
}
}
close(server_fd);
}
int main(int argc, char **argv) {
INFO("Bit.ASICmon started!")
InputParser input(argc, argv);
if(input.cmdOptionExists("-h")) {
INFO("HELP")
exit(0);
}
if(input.cmdOptionExists("-p")) {
const char* aport = input.getCmdOption("-p").c_str();
if (strcmp(aport, "") == 0){
port = atoi(aport);
INFO("Set port: ", port)
}
else {
WARN("Port invalid using default: ", port)
}
delete[] aport;
}
// char* msg = getFrom1066((char*)"128.128.128.56", (char*)"estats");
// char* msg = getFrom1066((char*)"128.128.128.56", (char*)"summary");
// regex re(R"(BOOTBY\[([\d\s\w.]+)\])");
// cmatch m;
// regex_search(msg, m, re);
// delete[] msg;
// INFO(m[1])
httpServer(port);
return 0;
}