added tlibtoml submodule
This commit is contained in:
parent
f5169e8a8f
commit
c263d02b36
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -4,3 +4,6 @@
|
||||
[submodule "dependencies/tlibc"]
|
||||
path = dependencies/tlibc
|
||||
url = https://timerix.ddns.net/git/timerix/tlibc.git
|
||||
[submodule "dependencies/tlibtoml"]
|
||||
path = dependencies/tlibtoml
|
||||
url = https://timerix.ddns.net/git/Timerix/tlibtoml.git
|
||||
|
||||
2
.vscode/c_cpp_properties.json
vendored
2
.vscode/c_cpp_properties.json
vendored
@ -7,8 +7,8 @@
|
||||
"src",
|
||||
"include",
|
||||
"dependencies/BearSSL/inc",
|
||||
"dependencies/BearSSL/src",
|
||||
"dependencies/tlibc/include",
|
||||
"dependencies/tlibtoml/include",
|
||||
"${default}"
|
||||
],
|
||||
"cStandard": "c99"
|
||||
|
||||
@ -6,7 +6,10 @@
|
||||
git clone --recurse-submodules --depth 0 https://timerix.ddns.net/git/Timerix/tcp-chat.git
|
||||
```
|
||||
|
||||
2. Install [cbuild](https://timerix.ddns.net/git/Timerix/cbuild) version specified in `project.config`.
|
||||
2. Install [cbuild](https://timerix.ddns.net/git/Timerix/cbuild/releases).
|
||||
Select latest version compatible with the one in `project.config`.
|
||||
Example: For `2.3.0` download latest `2.3.x`.
|
||||
|
||||
|
||||
3. Build executable
|
||||
```
|
||||
@ -23,7 +26,7 @@ cd bin
|
||||
```
|
||||
**Server:**
|
||||
1. ```sh
|
||||
cp tcp-chat-server.config.default bin/tcp-chat-server.config
|
||||
cp tcp-chat-server.toml.default bin/tcp-chat-server.toml
|
||||
```
|
||||
2. Edit config
|
||||
3. ```sh
|
||||
|
||||
2
dependencies/tlibc
vendored
2
dependencies/tlibc
vendored
@ -1 +1 @@
|
||||
Subproject commit 8a40caaf1044f9fe2c327c4d3c60a3310efd6142
|
||||
Subproject commit ea6c20f430f4536631f379697ae56fc8b5fd5d17
|
||||
1
dependencies/tlibtoml
vendored
Submodule
1
dependencies/tlibtoml
vendored
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit a0e280d77b6d8967239b14915609eef422f6ba0b
|
||||
30
dependencies/tlibtoml.config
vendored
Normal file
30
dependencies/tlibtoml.config
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# This is a dependency config.
|
||||
# You can copy it to another project to add tlibtoml dependency.
|
||||
|
||||
DEP_WORKING_DIR="$DEPENDENCIES_DIR/tlibtoml"
|
||||
|
||||
user_config_path="project.config.user"
|
||||
absolute_dep_dir=$(realpath "$DEPENDENCIES_DIR")
|
||||
|
||||
function setup_user_config(){
|
||||
# Set variable `DEPENDENCIES_DIR`` in `tlibtoml/project.config.user`
|
||||
# to the directory where `tlibc`` is installed
|
||||
file_copy_default_if_not_present "$user_config_path" "$user_config_path.default"
|
||||
replace_var_value_in_script "$user_config_path" "DEPENDENCIES_DIR" "$absolute_dep_dir"
|
||||
}
|
||||
|
||||
if [[ "$TASK" = *_dbg ]]; then
|
||||
dep_build_target="build_static_lib_dbg"
|
||||
else
|
||||
dep_build_target="build_static_lib"
|
||||
fi
|
||||
DEP_PRE_BUILD_COMMAND="setup_user_config"
|
||||
DEP_BUILD_COMMAND="cbuild $dep_build_target"
|
||||
DEP_POST_BUILD_COMMAND=""
|
||||
DEP_CLEAN_COMMAND="cbuild clean"
|
||||
DEP_DYNAMIC_OUT_FILES=""
|
||||
DEP_STATIC_OUT_FILES="bin/tlibtoml.a"
|
||||
DEP_OTHER_OUT_FILES=""
|
||||
PRESERVE_OUT_DIRECTORY_STRUCTURE=false
|
||||
@ -5,6 +5,14 @@
|
||||
|
||||
typedef struct Server Server;
|
||||
|
||||
Result(Server*) Server_create(str config_str, void* logger, LogFunction_t log_func);
|
||||
/// @param config_file_content config in toml format
|
||||
/// @param config_file_name to use in error messages
|
||||
/// @param logger some shared data for your log function
|
||||
/// @param log_func log function that you have to implement
|
||||
/// @return
|
||||
Result(Server*) Server_create(str config_file_content, cstr config_file_name,
|
||||
void* logger, LogFunction_t log_func);
|
||||
|
||||
void Server_free(Server* server);
|
||||
|
||||
Result(void) Server_run(Server* server);
|
||||
|
||||
@ -24,7 +24,7 @@ SRC_CPP="$(find src -name '*.cpp')"
|
||||
# See cbuild/example_dependency_configs
|
||||
DEPENDENCY_CONFIGS_DIR='dependencies'
|
||||
# List of dependency config files in DEPENDENCY_CONFIGS_DIR separated by space.
|
||||
ENABLED_DEPENDENCIES='tlibc bearssl'
|
||||
ENABLED_DEPENDENCIES='bearssl tlibc tlibtoml'
|
||||
|
||||
# OBJDIR structure:
|
||||
# ├── objects/ - Compiled object files. Cleans on each call of build task
|
||||
@ -35,7 +35,10 @@ OBJDIR="obj"
|
||||
OUTDIR="bin"
|
||||
STATIC_LIB_FILE="$PROJECT.a"
|
||||
|
||||
INCLUDE="-Isrc -Iinclude -I$DEPENDENCIES_DIR/BearSSL/inc -I$DEPENDENCIES_DIR/tlibc/include"
|
||||
INCLUDE="-Isrc -Iinclude
|
||||
-I$DEPENDENCIES_DIR/BearSSL/inc
|
||||
-I$DEPENDENCIES_DIR/tlibc/include
|
||||
-I$DEPENDENCIES_DIR/tlibtoml/include"
|
||||
|
||||
# OS-specific options
|
||||
case "$OS" in
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
#include "modes/modes.h"
|
||||
|
||||
#define _DEFAULT_CONFIG_PATH_CLIENT "tcp-chat-client.config"
|
||||
#define _DEFAULT_CONFIG_PATH_SERVER "tcp-chat-server.config"
|
||||
#define _DEFAULT_CONFIG_PATH_SERVER "tcp-chat-server.toml"
|
||||
|
||||
#define arg_is(LITERAL) str_equals(arg_str, STR(LITERAL))
|
||||
|
||||
|
||||
@ -67,10 +67,9 @@ Result(void) run_ServerMode(cstr config_path) {
|
||||
Defer(file_close(config_file));
|
||||
|
||||
// read whole file into str
|
||||
Array(u8) config_buf = Array_u8_construct(NULL, 0);
|
||||
try_void(file_readWhole(config_file, &config_buf));
|
||||
Defer(Array_u8_destroy(&config_buf));
|
||||
str config_str = Array_u8_castTo_str(config_buf, false);
|
||||
str config_file_content = str_null;
|
||||
try_void(file_readWholeText(config_file, &config_file_content));
|
||||
Defer(str_destroy(config_file_content));
|
||||
|
||||
// create logger
|
||||
ServerLogger logger;
|
||||
@ -78,14 +77,19 @@ Result(void) run_ServerMode(cstr config_path) {
|
||||
Defer(ServerLogger_destroy(&logger));
|
||||
|
||||
// init server
|
||||
try(Server* server, p, Server_create(config_str, &logger, log_func));
|
||||
try(Server* server, p,
|
||||
Server_create(
|
||||
config_file_content, config_path,
|
||||
&logger, log_func
|
||||
)
|
||||
);
|
||||
Defer(Server_free(server));
|
||||
|
||||
// manually close file and free config_buf
|
||||
file_close(config_file);
|
||||
config_file = NULL;
|
||||
Array_u8_destroy(&config_buf);
|
||||
config_buf.data = NULL;
|
||||
str_destroy(config_file_content);
|
||||
config_file_content.data = NULL;
|
||||
|
||||
// start infinite loop on main thread
|
||||
try_void(Server_run(server));
|
||||
|
||||
34
src/config.c
34
src/config.c
@ -1,34 +0,0 @@
|
||||
#include "config.h"
|
||||
|
||||
Result(void) config_findValue(str config_str, str key, str* value, bool throwNotFoundError){
|
||||
u32 line_n = 0;
|
||||
while(config_str.len > 0){
|
||||
line_n++;
|
||||
i32 line_end = str_seekChar(config_str, '\n', 0);
|
||||
if(line_end < 0)
|
||||
line_end = config_str.len - 1;
|
||||
str line = str_sliceBefore(config_str, line_end);
|
||||
config_str = str_sliceAfter(config_str, line_end + 1);
|
||||
|
||||
i32 sep_pos = str_seekChar(line, '=', 1);
|
||||
if(sep_pos < 0){
|
||||
//not a 'key = value' line
|
||||
continue;
|
||||
}
|
||||
|
||||
str line_key = str_sliceBefore(line, sep_pos - 1);
|
||||
str_trim(&line_key, false);
|
||||
if(str_equals(line_key, key)){
|
||||
str line_value = str_sliceAfter(line, sep_pos + 1);
|
||||
str_trim(&line_value, false);
|
||||
*value = line_value;
|
||||
return RESULT_VOID;
|
||||
}
|
||||
}
|
||||
|
||||
if(throwNotFoundError){
|
||||
char* err_msg = sprintf_malloc("can't find key '"FMT_str"'", key.len, key.data);
|
||||
return RESULT_ERROR(err_msg, true);
|
||||
}
|
||||
return RESULT_VOID;
|
||||
}
|
||||
@ -1,6 +0,0 @@
|
||||
#pragma once
|
||||
#include "tlibc/errors.h"
|
||||
#include "tlibc/string/str.h"
|
||||
|
||||
/// searches for pattern `key = value`
|
||||
Result(void) config_findValue(str config_str, str key, str* value, bool throwNotFoundError);
|
||||
@ -3,9 +3,9 @@
|
||||
#include "tlibc/time.h"
|
||||
#include "tlibc/base64.h"
|
||||
#include "server/server_internal.h"
|
||||
#include "config.h"
|
||||
#include "network/tcp-chat-protocol/v1.h"
|
||||
#include "server/responses/responses.h"
|
||||
#include "tlibtoml.h"
|
||||
|
||||
static void* handleConnection(void* _args);
|
||||
static Result(void) try_handleConnection(ConnectionHandlerArgs* args, cstr log_ctx);
|
||||
@ -36,7 +36,9 @@ void Server_free(Server* self){
|
||||
#define LOG_FUNC log_func
|
||||
#define LOG_CONTEXT log_ctx
|
||||
|
||||
Result(Server*) Server_create(str config_str, void* logger, LogFunction_t log_func){
|
||||
Result(Server*) Server_create(str config_file_content, cstr config_file_name,
|
||||
void* logger, LogFunction_t log_func)
|
||||
{
|
||||
Deferral(16);
|
||||
cstr log_ctx = "ServerInit";
|
||||
|
||||
@ -47,53 +49,48 @@ Result(Server*) Server_create(str config_str, void* logger, LogFunction_t log_fu
|
||||
|
||||
self->logger = logger;
|
||||
self->log_func = log_func;
|
||||
|
||||
logDebug("parsing config");
|
||||
try(TomlTable* config_toml, p, toml_load_str_filename(config_file_content, config_file_name));
|
||||
Defer(TomlTable_free(config_toml));
|
||||
|
||||
// parse name
|
||||
str tmp_str = str_null;
|
||||
try_void(config_findValue(config_str, STR("name"), &tmp_str, true));
|
||||
self->name = str_copy(tmp_str);
|
||||
try(str* v_name, p, TomlTable_get_str(config_toml, STR("name")));
|
||||
self->name = str_copy(*v_name);
|
||||
|
||||
// parse description
|
||||
try_void(config_findValue(config_str, STR("description"), &tmp_str, true));
|
||||
self->description = str_copy(tmp_str);
|
||||
try(str* v_desc, p, TomlTable_get_str(config_toml, STR("description")));
|
||||
self->description = str_copy(*v_desc);
|
||||
|
||||
// parse landing_channel_id
|
||||
try_void(config_findValue(config_str, STR("landing_channel_id"), &tmp_str, true));
|
||||
char* lci_cstr = str_copy(tmp_str).data;
|
||||
Defer(free(lci_cstr));
|
||||
if(sscanf(lci_cstr, FMT_u64, &self->landing_channel_id) != 1){
|
||||
Return RESULT_ERROR("can't parse 'landing_channel_id' value as number", false);
|
||||
}
|
||||
try(i64 v_landing_channel_id, i, TomlTable_get_integer(config_toml, STR("landing_channel_id")));
|
||||
self->landing_channel_id = v_landing_channel_id;
|
||||
|
||||
// parse local_address
|
||||
try_void(config_findValue(config_str, STR("local_address"), &tmp_str, true));
|
||||
char* local_end_cstr = str_copy(tmp_str).data;
|
||||
Defer(free(local_end_cstr));
|
||||
try_void(EndpointIPv4_parse(local_end_cstr, &self->local_end));
|
||||
try(str* v_local_address, p, TomlTable_get_str(config_toml, STR("local_address")));
|
||||
try_assert(v_local_address->isZeroTerminated);
|
||||
try_void(EndpointIPv4_parse(v_local_address->data, &self->local_end));
|
||||
|
||||
// parse rsa_private_key
|
||||
try_void(config_findValue(config_str, STR("rsa_private_key"), &tmp_str, true));
|
||||
char* sk_base64_cstr = str_copy(tmp_str).data;
|
||||
Defer(free(sk_base64_cstr));
|
||||
try(str* v_rsa_sk, p, TomlTable_get_str(config_toml, STR("rsa_private_key")));
|
||||
try_assert(v_rsa_sk->isZeroTerminated);
|
||||
try_void(RSA_parsePrivateKey_base64(v_rsa_sk->data, &self->rsa_sk));
|
||||
|
||||
// parse rsa_public_key
|
||||
try_void(config_findValue(config_str, STR("rsa_public_key"), &tmp_str, true));
|
||||
char* pk_base64_cstr = str_copy(tmp_str).data;
|
||||
Defer(free(pk_base64_cstr));
|
||||
|
||||
try_void(RSA_parsePrivateKey_base64(sk_base64_cstr, &self->rsa_sk));
|
||||
try_void(RSA_parsePublicKey_base64(pk_base64_cstr, &self->rsa_pk));
|
||||
try(str* v_rsa_pk, p, TomlTable_get_str(config_toml, STR("rsa_public_key")));
|
||||
try_assert(v_rsa_pk->isZeroTerminated);
|
||||
try_void(RSA_parsePublicKey_base64(v_rsa_pk->data, &self->rsa_pk));
|
||||
|
||||
// parse db_aes_key
|
||||
try_void(config_findValue(config_str, STR("db_aes_key"), &tmp_str, true));
|
||||
Array(u8) db_aes_key = Array_u8_alloc(base64_decodedSize(tmp_str.data, tmp_str.len));
|
||||
try(str* v_db_aes_key, p, TomlTable_get_str(config_toml, STR("db_aes_key")));
|
||||
str db_aes_key_s = *v_db_aes_key;
|
||||
Array(u8) db_aes_key = Array_u8_alloc(base64_decodedSize(db_aes_key_s.data, db_aes_key_s.len));
|
||||
Defer(free(db_aes_key.data));
|
||||
base64_decode(tmp_str.data, tmp_str.len, db_aes_key.data);
|
||||
base64_decode(db_aes_key_s.data, db_aes_key_s.len, db_aes_key.data);
|
||||
|
||||
// parse db_dir and open db
|
||||
try_void(config_findValue(config_str, STR("db_dir"), &tmp_str, true));
|
||||
try(self->db, p, idb_open(tmp_str, db_aes_key));
|
||||
try(str* v_db_dir, p, TomlTable_get_str(config_toml, STR("db_dir")));
|
||||
try(self->db, p, idb_open(*v_db_dir, db_aes_key));
|
||||
|
||||
// build users cache
|
||||
logDebug("loading users...");
|
||||
|
||||
@ -1,9 +0,0 @@
|
||||
name = test server
|
||||
description = Lorem ipsum labuba aboba
|
||||
landing_channel_id = 0
|
||||
local_address = 127.0.0.1:9988
|
||||
db_dir = server-db
|
||||
db_aes_key = <generate with './tcp-chat --random-bytes-base64 32'>
|
||||
|
||||
rsa_private_key = <generate with './tcp-chat --rsa-gen-random'>
|
||||
rsa_public_key =
|
||||
13
tcp-chat-server.toml.default
Normal file
13
tcp-chat-server.toml.default
Normal file
@ -0,0 +1,13 @@
|
||||
name = "Test Server"
|
||||
description = """\
|
||||
Lorem ipsum labuba aboba.\n\
|
||||
Qqqqq...\
|
||||
"""
|
||||
|
||||
landing_channel_id = 0
|
||||
local_address = '127.0.0.1:9988'
|
||||
db_dir = 'server-db'
|
||||
db_aes_key = '<generate with './tcp-chat --random-bytes-base64 32'>'
|
||||
|
||||
rsa_private_key = '<generate with './tcp-chat --rsa-gen-random'>'
|
||||
rsa_public_key = '<copy from output of command above>'
|
||||
Loading…
Reference in New Issue
Block a user