#include #include #include #include #include #include "logger.c" #define BACKLOG 10 struct Client { int fd; struct sockaddr_in addr; }; void sig_handler(int signo) { log_warn("Signal %d received, shutting down data server", signo); exit(0); } void respond_name(int client_fd) { log_info("Client requested simulation name"); struct json_object *sim_name = json_object_new_object(); json_object_object_add(sim_name, "name", json_object_new_string(NAME)); json_object_to_fd(client_fd, sim_name, JSON_C_TO_STRING_PRETTY); json_object_put(sim_name); } void respond_opts(int client_fd) { log_info("Client requested simulation options"); struct json_object *sim_opts = json_object_from_file(SIM_OPTS); json_object_to_fd(client_fd, sim_opts, JSON_C_TO_STRING_PRETTY); json_object_put(sim_opts); } void respond_hash(int client_fd) { log_info("Client requested git hash"); char buff[41] = { 0 }; FILE *pipe = popen("git rev-parse HEAD", "r"); fread(buff, sizeof(char), 40, pipe); pclose(pipe); struct json_object *git_hash = json_object_new_object(); json_object_object_add(git_hash, "hash", json_object_new_string(buff)); json_object_to_fd(client_fd, git_hash, JSON_C_TO_STRING_PRETTY); json_object_put(git_hash); } void respond_data(int client_fd, struct json_object *request_json) { assert(request_json); (void)client_fd; } int handle_client(struct Client *client) { assert(client); char client_ip[INET_ADDRSTRLEN]; inet_ntop(AF_INET, &client->addr.sin_addr, client_ip, INET_ADDRSTRLEN); log_info("Client connected: %s:%d", client_ip, ntohs(client->addr.sin_port)); struct json_object *request_json = json_object_from_fd(client->fd); struct json_object *request_str = NULL; if (!json_object_object_get_ex(request_json, "request", &request_str)) assert(false); const char *request = json_object_get_string(request_str); assert(request); if (!strcmp(request, "name")) { respond_name(client->fd); } else if (!strcmp(request, "opts")) { respond_opts(client->fd); } else if (!strcmp(request, "hash")) { respond_hash(client->fd); } else if (!strcmp(request, "data")) { respond_data(client->fd, request_json); } else { assert(false); } json_object_put(request_json); log_info("Client disconnected: %s:%d", client_ip, ntohs(client->addr.sin_port)); close(client->fd); free(client); return 0; } int main(void) { signal(SIGINT, sig_handler); signal(SIGTERM, sig_handler); log_info("Initializing salis data server"); int opt = 1; int server_fd = socket(AF_INET, SOCK_STREAM, 0); setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); log_info("Binding to port: %d", PORT); struct sockaddr_in server_addr = { 0 }; server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = INADDR_ANY; server_addr.sin_port = htons(PORT); bind(server_fd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr_in)); log_info("Listening..."); listen(server_fd, BACKLOG); while (true) { struct Client *client = calloc(1, sizeof(struct Client)); socklen_t client_len = sizeof(struct sockaddr_in); client->fd = accept(server_fd, (struct sockaddr *)&client->addr, &client_len); thrd_t thrd; thrd_create(&thrd, (thrd_start_t)handle_client, client); thrd_detach(thrd); } close(server_fd); return 0; }