init rewrite

This commit is contained in:
Tobias Reisinger 2020-05-05 11:42:02 +02:00
parent 9a44bc494e
commit 6d828fcffc
100 changed files with 50541 additions and 2707 deletions

52
helpers/bind_server.c Normal file
View file

@ -0,0 +1,52 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <netdb.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <errno.h>
#include <logger.h>
#include <helpers.h>
int
helper_bind_tcp_server(char* addr, uint16_t port, int max_client_backlog)
{
char port_str[6];
sprintf(port_str, "%d", port);
struct addrinfo hints, *res;
int fd;
int status;
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE;
if ((status = getaddrinfo(addr, port_str, &hints, &res)) != 0)
{
LOG_ERROR("getaddrinfo: %s\n", gai_strerror(status));
return -1;
}
fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if ((status = bind(fd, res->ai_addr, res->ai_addrlen)) == -1)
{
LOG_ERROR("error binding socket: %s\n", strerror(errno));
freeaddrinfo(res);
return -1;
}
if ((status = listen(fd, max_client_backlog)) == -1)
{
LOG_ERROR("error setting up listener: %s\n", strerror(errno));
freeaddrinfo(res);
return -1;
}
freeaddrinfo(res);
return fd;
}

View file

@ -1,43 +0,0 @@
#include <netdb.h>
#include <trantor/utils/Logger.h>
#include <helpers.h>
#include "config.h"
int
helpers::bind_tcp_server(const char *addr, const char *port, int max_client_backlog)
{
struct addrinfo hints{}, *res;
int fd;
int status;
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE;
if ((status = getaddrinfo(addr, port, &hints, &res)) != 0)
{
LOG_ERROR << "Error getting address info: " << gai_strerror(status);
}
fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if ((status = bind(fd, res->ai_addr, res->ai_addrlen)) == -1)
{
LOG_ERROR << "Error binding socket. " << status;
freeaddrinfo(res);
return -1;
}
if ((status = listen(fd, max_client_backlog)) == -1)
{
LOG_ERROR << "Error setting up listener. " << status;
freeaddrinfo(res);
return -1;
}
freeaddrinfo(res);
return fd;
}

39
helpers/connect_server.c Normal file
View file

@ -0,0 +1,39 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <netdb.h>
#include <sys/socket.h>
#include <logger.h>
#include <helpers.h>
int
helper_connect_tcp_server(char* host, uint16_t port)
{
char port_str[6];
sprintf(port_str, "%d", port);
int s, status;
struct addrinfo hints, *res;
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_INET; //set IP Protocol flag (IPv4 or IPv6 - we don't care)
hints.ai_socktype = SOCK_STREAM; //set socket flag
if ((status = getaddrinfo(host, port_str, &hints, &res)) != 0) { //getaddrinfo() will evaluate the given address, using the hints-flags and port, and return an IP address and other server infos
LOG_ERROR("getaddrinfo: %s\n", gai_strerror(status));
return -1;
}
//res got filled out by getaddrinfo() for us
s = socket(res->ai_family, res->ai_socktype, res->ai_protocol); //creating Socket
if ((status = connect(s, res->ai_addr, res->ai_addrlen)) != 0) {
LOG_ERROR("connect() failed\n");
freeaddrinfo(res);
return -1;
}
freeaddrinfo(res);
return s;
}

View file

@ -1,58 +0,0 @@
#include <helpers.h>
#include <drogon/drogon.h>
#include <globals.h>
sqlite3_stmt*
helpers::create_sql_filtered_query(const char *sql, sql_filter_builder **filters)
{
char *old_query = (char*)sql;
char *new_query;
sql_filter_builder *filter;
int filter_count = 0;
do
{
filter = filters[filter_count];
filter_count++;
asprintf(&new_query, " %s %s=?%d %s", old_query, filter->col_name, filter_count, filter->logic);
if(old_query != sql)
{
free(old_query);
}
old_query = new_query;
} while(filter->logic[0] != ';');
sqlite3_stmt *stmt;
sqlite3_prepare_v2(globals::db, new_query, -1, &stmt, nullptr);
free(new_query);
for(int i = 0; i < filter_count; i++)
{
filter = filters[i];
if(filter->bind_func == (intptr_t)&sqlite3_bind_int)
{
sqlite3_bind_int(stmt, i + 1, (int)(intptr_t)filter->value);
}
if(filter->bind_func == (intptr_t)&sqlite3_bind_text)
{
sqlite3_bind_text(stmt, i + 1, (char*)filter->value, -1, SQLITE_STATIC);
}
}
return stmt;
}
helpers::sql_filter_builder::sql_filter_builder(const char *col_name, const void *value, intptr_t bind_func,
const char *logic)
{
this->col_name = col_name;
this->value = value;
this->bind_func = bind_func;
this->logic = logic;
}

12
helpers/get_day_of_week.c Normal file
View file

@ -0,0 +1,12 @@
#include <time.h>
#include <helpers.h>
int
helper_get_weekday(const time_t timestamp_now)
{
struct tm *now = localtime(&timestamp_now);
int wday_sun_sat = now->tm_wday;
int wday_mon_sun = (wday_sun_sat + 6) % 7;
return wday_mon_sun;
}

24
helpers/get_port.c Normal file
View file

@ -0,0 +1,24 @@
#include <sys/socket.h>
#include <arpa/inet.h>
#include <stdint.h>
#include <errno.h>
#include <string.h>
#include <helpers.h>
#include <logger.h>
uint16_t
helper_get_port(int sock)
{
struct sockaddr_in sin;
socklen_t len = sizeof(sin);
if (getsockname(sock, (struct sockaddr *)&sin, &len) == -1)
{
LOG_ERROR("could not get socket name for port: %s\n", strerror(errno));
return 0;
}
else
{
return ntohs(sin.sin_port);
}
}

View file

@ -1,18 +0,0 @@
#include <netdb.h>
#include <helpers.h>
int
helpers::get_server_port(int fd)
{
if(fd == -1)
{
return -1;
}
struct sockaddr_in sin{};
socklen_t addr_len = sizeof(sin);
if(getsockname(fd, (struct sockaddr *)&sin, &addr_len) == 0)
{
return ntohs(sin.sin_port);
}
return -1;
}

View file

@ -1,63 +0,0 @@
#include <helpers.h>
#include <globals.h>
#include <drogon/trantor/trantor/utils/Logger.h>
#include <config.h>
#include <sql/migration_0.h>
int
helpers::migrate_sql()
{
uint16_t version_num = 0;
int s, rc;
sqlite3_stmt *stmt;
sqlite3_prepare_v2(globals::db, "SELECT version_num FROM meta LIMIT 1;", -1, &stmt, nullptr);
s = sqlite3_step(stmt);
if (s == SQLITE_ROW)
{
version_num = sqlite3_column_int(stmt, 0);
}
else
{
version_num = 0;
}
uint16_t new_version_num = version_num;
char* err_msg;
char* sql;
sqlite3_finalize(stmt);
switch(version_num)
{
case 0:
rc = sqlite3_exec(globals::db, (const char *)sql_migration_0_sql, nullptr, nullptr, &err_msg);
if(rc != 0)
{
LOG_FATAL << "Couldn't migrate LEVEL 0 (" << err_msg << ")";
break;
}
new_version_num = 1;
default:
break;
}
if(version_num == 0)
{
sqlite3_prepare_v2(globals::db, "INSERT INTO meta (version_num) VALUES (?1);", -1, &stmt, nullptr);
}
else
{
sqlite3_prepare_v2(globals::db, "UPDATE meta SET version_num=?1;", -1, &stmt, nullptr);
}
sqlite3_bind_int(stmt, 1, new_version_num);
rc = sqlite3_step(stmt);
if (rc != SQLITE_DONE)
{
LOG_FATAL << "Couldn't write new Schema Version";
}
return rc == SQLITE_DONE;
}

View file

@ -0,0 +1,57 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <netdb.h>
#include <sys/socket.h>
#include <logger.h>
#include <helpers.h>
int
helper_open_discovery_socket(uint16_t discovery_port)
{
struct addrinfo hints, *res;
int fd, status;
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_INET; // use ipv4
hints.ai_socktype = SOCK_DGRAM; //set socket flag
hints.ai_flags = AI_PASSIVE; // get my IP
char discovery_port_str[6];
sprintf(discovery_port_str, "%u", discovery_port);
//get connection info for our computer
if ((status = getaddrinfo(NULL, discovery_port_str, &hints, &res)) != 0)
{
LOG_FATAL("getaddrinfo: %s\n", gai_strerror(status));
freeaddrinfo(res);
exit(EXIT_FAILURE);
}
//creating socket
fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
int yes = 1;
// lose the pesky "Address already in use" error message
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) == -1)
{
LOG_FATAL("setsockopt: %s\n", strerror(errno));
freeaddrinfo(res);
exit(EXIT_FAILURE);
}
if (bind(fd, res->ai_addr, res->ai_addrlen) == -1)
{
LOG_FATAL("bind: %s\n", strerror(errno));
freeaddrinfo(res);
exit(EXIT_FAILURE);
}
freeaddrinfo(res);
LOG_INFO("opened discovery socket on port %u\n", discovery_port);
return fd;
}

View file

@ -1,33 +0,0 @@
#include <helpers.h>
#include <netdb.h>
#include <trantor/utils/Logger.h>
int
helpers::open_tcp_connection(char *host, char *port)
{
int s, status;
struct addrinfo hints{}, *res;
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
if ((status = getaddrinfo(host, port, &hints, &res)) != 0)
{
LOG_ERROR << "Error getting address info: " << gai_strerror(status);
freeaddrinfo(res);
return 0;
}
s = socket(res->ai_family, res->ai_socktype, res->ai_protocol); //creating Socket
if ((status = connect(s, res->ai_addr, res->ai_addrlen)) != 0)
{
LOG_ERROR << "Error opening connection " << status;
freeaddrinfo(res);
return 0;
}
freeaddrinfo(res);
return s;
}

62
helpers/parse_cli.c Normal file
View file

@ -0,0 +1,62 @@
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <argparse.h>
#include <config.h>
#include <logger.h>
#include <helpers.h>
static const char *const usage[] = {
"controller [options] [[--] args]",
"controller [options]",
NULL,
};
#define PERM_READ (1<<0)
#define PERM_WRITE (1<<1)
#define PERM_EXEC (1<<2)
void
helper_parse_cli(int argc, const char **argv, config_t *config)
{
struct argparse_option options[] =
{
OPT_HELP(),
OPT_GROUP("Basic options"),
OPT_STRING('c', "config", &config->file, "path to config file", NULL, 0, OPT_NONEG),
OPT_END(),
};
struct argparse argparse;
argparse_init(&argparse, options, usage, 0);
argparse_describe(
&argparse,
"\nA brief description of what the program does and how it works.",
"\nAdditional description of the program after the description of the arguments."
);
argc = argparse_parse(&argparse, argc, argv);
if(argc == 1)
{
if(strcmp(argv[0], "start") == 0)
{
config->run_type = RUN_TYPE_START;
return;
}
if(strcmp(argv[0], "test") == 0)
{
config->run_type = RUN_TYPE_TEST;
return;
}
LOG_FATAL("bad action '%s' given ('start', 'test')\n", argv[0]);
exit(1);
}
else
{
LOG_FATAL("no action given ('start', 'test')\n");
exit(1);
}
return;
}

View file

@ -1,68 +0,0 @@
#include <helpers.h>
#include <drogon/drogon.h>
#include <models/period_list.h>
static int
parse_HHMM(const char *begin, uint16_t *h, uint16_t *m)
{
uint16_t tmp_h, tmp_m;
char *check = nullptr;
tmp_h = (uint16_t)strtol(begin, &check, 10);
if(begin == check)
{
return 1;
}
begin = check + 1;
tmp_m = (uint16_t)strtol(begin, &check, 10);
if(begin == check)
{
return 1;
}
*h = tmp_h;
*m = tmp_m;
return 0;
}
period_list*
helpers::parse_periods(Json::Value periods_json)
{
auto result = new period_list();
for (Json::Value::ArrayIndex i = 0; i != periods_json.size(); i++)
{
Json::Value p = periods_json[i];
if(!(p.isMember("start") && p.isMember("end")))
{
continue;
}
const char *start_str = p["start"].asCString();
const char *end_str = p["end"].asCString();
uint16_t h, m, start, end;
if(parse_HHMM(start_str, &h, &m))
{
continue;
}
start = (uint16_t)((h * 60) + m);
if(parse_HHMM(end_str, &h, &m))
{
continue;
}
end = (uint16_t)((h * 60) + m);
if(start < 0 || start > 24 * 60 || end < 0 || end > 24 * 60)
{
continue;
}
result->add_period(start, end);
}
return result;
}

View file

@ -1,39 +0,0 @@
#include <arpa/inet.h>
#include <trantor/utils/Logger.h>
#include "config.h"
#include <unistd.h>
#include <helpers.h>
int
helpers::send_udp_broadcast(const char *addr, uint16_t port, const char* message)
{
struct sockaddr_in their_addr{};
int fd;
if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
{
LOG_ERROR << "Error creating socket";
return -1;
}
int broadcast = 1;
if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof broadcast) < 0)
{
LOG_ERROR << "Error setting broadcast";
return -1;
}
memset(&their_addr, 0, sizeof(their_addr));
their_addr.sin_family = AF_INET;
their_addr.sin_port = htons(port);
their_addr.sin_addr.s_addr = inet_addr(addr);
if(sendto(fd, message, strlen(message), 0, (struct sockaddr *)&their_addr, sizeof(their_addr)) < 0)
{
LOG_ERROR << "Error sending broadcast " << errno << " " << strerror(errno);
return -1;
}
close(fd);
return 0;
}