Files
C-IPC/util/util.c
T

122 lines
3.9 KiB
C

#include "fcntl.h"
#include "unistd.h"
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libconfig.h>
#include "util.h"
static char alphs[] = {'-', '_', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e',
'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '\0'};
// Generate an id used for messages.
// Could be less than 16 chars, but thats what fits into the `command` field of `msgbuf_t`.
void get_id(char *id_buf) {
int alph_size = strlen(alphs) - 1;
for (int i = 0; i < 16; i++) {
int random_num;
do {
random_num = rand();
} while (random_num >= (RAND_MAX - RAND_MAX % alph_size));
random_num %= alph_size;
id_buf[i] = alphs[random_num];
}
id_buf[15] = '\0';
}
// Load configuration using libconfig
void load_config(server_config_t *cfg, const char *path) {
config_t config;
config_init(&config);
if (!config_read_file(&config, path)) {
fprintf(stderr, "Error reading config file %s:%d - %s\n",
config_error_file(&config),
config_error_line(&config),
config_error_text(&config));
config_destroy(&config);
exit(1);
}
// Read clients
config_setting_t *clients = config_lookup(&config, "clients");
if (!clients) {
fprintf(stderr, "No 'clients' section found in config file\n");
config_destroy(&config);
exit(1);
}
int client_count = config_setting_length(clients);
cfg->client_count = client_count;
cfg->clients = malloc(sizeof(client_config_t) * client_count);
for (int i = 0; i < client_count; i++) {
config_setting_t *client = config_setting_get_elem(clients, i);
const char *client_id, *nickname;
if (!config_setting_lookup_string(client, "client_id", &client_id) ||
!config_setting_lookup_string(client, "nickname", &nickname)) {
fprintf(stderr, "Error reading client %d configuration\n", i);
config_destroy(&config);
exit(1);
}
strncpy(cfg->clients[i].client_id, client_id, COMMAND_LENGTH - 1);
cfg->clients[i].client_id[COMMAND_LENGTH - 1] = '\0';
strncpy(cfg->clients[i].nickname, nickname, COMMAND_LENGTH - 1);
cfg->clients[i].nickname[COMMAND_LENGTH - 1] = '\0';
}
// Read groups
config_setting_t *groups = config_lookup(&config, "groups");
if (!groups) {
fprintf(stderr, "No 'groups' section found in config file\n");
config_destroy(&config);
exit(1);
}
int group_count = config_setting_length(groups);
cfg->group_count = group_count;
cfg->groups = malloc(sizeof(group_config_t) * group_count);
for (int i = 0; i < group_count; i++) {
config_setting_t *group = config_setting_get_elem(groups, i);
const char *name;
config_setting_t *members;
if (!config_setting_lookup_string(group, "name", &name)) {
fprintf(stderr, "Error reading group %d name\n", i);
config_destroy(&config);
exit(1);
}
strncpy(cfg->groups[i].name, name, COMMAND_LENGTH - 2);
cfg->groups[i].name[COMMAND_LENGTH - 2] = '\0';
members = config_setting_get_member(group, "members");
if (!members) {
fprintf(stderr, "Error reading group %d members\n", i);
config_destroy(&config);
exit(1);
}
int member_count = config_setting_length(members);
cfg->groups[i].member_count = member_count;
for (int j = 0; j < member_count; j++) {
const char *member_id = config_setting_get_string_elem(members, j);
cfg->groups[i].member_ids[j] = malloc(COMMAND_LENGTH);
strncpy(cfg->groups[i].member_ids[j], member_id, COMMAND_LENGTH - 1);
cfg->groups[i].member_ids[j][COMMAND_LENGTH - 1] = '\0';
}
}
config_destroy(&config);
}