From aa4d426b4d3527d7e166df1a05058c9a4a0f6683 Mon Sep 17 00:00:00 2001 From: Wojtek Kosior Date: Fri, 30 Apr 2021 00:33:56 +0200 Subject: initial/final commit --- config.c | 287 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 287 insertions(+) create mode 100644 config.c (limited to 'config.c') diff --git a/config.c b/config.c new file mode 100644 index 0000000..7dd0c1e --- /dev/null +++ b/config.c @@ -0,0 +1,287 @@ +/* C */ +#include +#include +#include +#include +#include +#include + +/* Losedows */ +#include + +/* local */ +#include "utilities.h" +#include "iniparser.h" + +#define BUFSIZE 4096 + +static const char *get_string(dictionary *ini, const char *key) +{ + const char *value; + char *new_string; + size_t length; + + value = iniparser_getstring(ini, key, NULL); + if (!value) + return NULL; + + length = strlen(value); + new_string = dirtyalloc(length + 1); + memcpy(new_string, value, length + 1); + return new_string; +} + +static enum bool_param get_bool(dictionary *ini, const char *key) +{ + int value = iniparser_getboolean(ini, key, 2); + + return value == 2 ? PARAM_NOT_GIVEN : + value == 1 ? PARAM_YES : PARAM_NO; +} + +static size_t get_msg(dictionary *ini, const char **dest) +{ + int nkeys, i; + const char **keys; + const char *line; + size_t msg_size = 0; + char *msg, *msg_pos; + + nkeys = iniparser_getsecnkeys(ini, "MSG"); + if (nkeys == 0) { + *dest = NULL; + return 0; + } + + keys = dirtyalloc(nkeys * sizeof(const char*)); + iniparser_getseckeys(ini, "MSG", keys); + + for (i = 0; i < nkeys; i++) + msg_size += strlen(iniparser_getstring(ini, keys[i], "")) + 1; + + msg = dirtyalloc(msg_size); + msg_pos = msg; + + for (i = 0; i < nkeys; i++) { + line = iniparser_getstring(ini, keys[i], ""); + while (*line) + *(msg_pos++) = *(line++); + *(msg_pos++) = '\n'; + } + + free(keys); + *(msg_pos - 1) = '\0'; + *dest = msg; + + /* Exclude terminating null byte from returned size */ + return msg_size - 1; +} + +static size_t get_list(dictionary *ini, const char *section, + const char ***dest) +{ + int nkeys, i; + const char **keys, **items; + const char *line; + char *copied_line; + size_t length; + + nkeys = iniparser_getsecnkeys(ini, section); + + if (nkeys == 0) { + *dest = NULL; + return 0; + } + + keys = dirtyalloc(nkeys * sizeof(const char *)); + items = dirtyalloc(nkeys * sizeof(const char *)); + iniparser_getseckeys(ini, section, keys); + + for (i = 0; i < nkeys; i++) { + line = iniparser_getstring(ini, keys[i], ""); + length = strlen(line) + 1; + copied_line = dirtyalloc(length); + memcpy(copied_line, line, length); + items[i] = copied_line; + } + + free(keys); + *dest = items; + return nkeys; +} + +static dictionary *check_file_and_load_ini(const char *filename) +{ + int retval; + char full_pathname[BUFSIZE]; + dictionary *ini; + + retval = GetFullPathName(filename, BUFSIZE, full_pathname, NULL); + + if (retval == 0) + FAIL(MSG_CONF_PATH_EXPAND_FAIL, filename); + + if (access(full_pathname, F_OK) != 0) + FAIL(MSG_CONF_NOT_EXIST, full_pathname); + + if (access(full_pathname, R_OK) != 0) + FAIL(MSG_CONF_NOT_READABLE, full_pathname); + + ini = iniparser_load(full_pathname); + + if (!ini) + FAIL(MSG_INVALID_INI_FILE, full_pathname); + + return ini; +} + +void print_config(struct config *config); + +void read_config(const char *filename, struct config *config) +{ + dictionary *ini; + + ini = check_file_and_load_ini(filename); + + memset(config, '\0', sizeof(struct config)); /* not really needed */ + + config->host = get_string(ini, "SERVER:host"); + config->login = get_string(ini, "SERVER:login"); + config->password = get_string(ini, "SERVER:password"); + config->dest_dir = get_string(ini, "SERVER:outputdir"); + + config->reply_to = get_string(ini, "MAIL:replyto"); + config->from = get_string(ini, "MAIL:from"); + + if (!config->reply_to) + config->reply_to = get_string(ini, "SERVER:replyto"); + if (!config->from) + config->from = get_string(ini, "SERVER:from"); + + config->subject = get_string(ini, "MAIL:subject"); + + config->use_SSL = get_bool(ini, "SERVER:ssl"); + config->use_AUTH = get_bool(ini, "SERVER:auth"); + config->del_msgs = get_bool(ini, "SERVER:delete_msg"); + config->save_body = get_bool(ini, "SERVER:save_body"); + config->save_subj = get_bool(ini, "SERVER:save_subject"); + config->port_POP3 = iniparser_getint(ini, "SERVER:port_pop3", -1); + config->port_SMTP = iniparser_getint(ini, "SERVER:port_smtp", -1); + config->timeout = iniparser_getint(ini, "SERVER:timeout", 1000000); + config->nfiles = get_list(ini, "FILES", &config->files); + config->nto = get_list(ini, "CC", &config->to); + config->msg_size = get_msg (ini, &config->msg_body); + + iniparser_freedict(ini); + + /* print_config(config); */ +} + +void get_config(int argc, const char **argv, struct config *config) +{ + int config_arg_idx = 1; + + if (argc < 2) + goto bad_args; + + if (strcmp(argv[1], "--wide-chars") == 0) { + config_arg_idx = 2; + iniparser_set_fgetc_impl(provisional_wide_char_fgetc); + } + + if (argc <= config_arg_idx) + goto bad_args; + + iniparser_set_error_callback(dummy_errback); + iniparser_set_process_multiline(false); + read_config(argv[config_arg_idx], config); + return; + +bad_args: + FAIL(MSG_BAD_ARGS_NUM, argv[0]); +} + +void free_config(struct config *config) +{ + //TODO +} + +void print_config(struct config *config) +{ + size_t i; + + if (config->host) + printf("host: %s\n", config->host); + else + puts("host not set"); + + if (config->login) + printf("login: %s\n", config->login); + else + puts("login not set"); + + if (config->password) + printf("password: %s\n", config->password); + else + puts("password not set"); + + if (config->reply_to) + printf("reply_to: %s\n", config->reply_to); + else + puts("reply_to not set"); + + if (config->from) + printf("from: %s\n", config->from); + else + puts("from not set"); + + if (config->dest_dir) + printf("dest_dir: %s\n", config->dest_dir); + else + puts("dest_dir not set"); + + if (config->subject) + printf("subject: %s\n", config->subject); + else + puts("subject not set"); + + printf("SSL: %s\n", config->use_SSL ? "True" : "False"); + + printf("AUTH: %s\n", config->use_AUTH ? "True" : "False"); + + printf("port_POP3: %d\n", config->port_POP3); + + printf("port_SMTP: %d\n", config->port_SMTP); + + printf("timeout: %d\n", config->timeout); + + printf("delete: %s\n", config->del_msgs ? "True" : "False"); + + printf("save_body: %s\n", config->save_body ? "True" : "False"); + + printf("save_subject: %s\n", config->save_subj ? "True" : "False"); + + if (config->nfiles) { + puts("files:"); + for (i = 0; i < config->nfiles; i++) + printf(" %s\n", config->files[i]); + } else { + puts("no files"); + } + + if (config->nto) { + puts("recipients:"); + for (i = 0; i < config->nto; i++) + printf(" %s\n", config->to[i]); + } else { + puts("no recipients"); + } + + if (config->msg_body) { + printf("message (length %lu):\n", + (unsigned long)config->msg_size); + puts(config->msg_body); + } else { + puts("no message"); + } +} -- cgit v1.2.3