/* C */ #include <string.h> #include <unistd.h> #include <stdio.h> #include <ctype.h> #include <limits.h> #include <stdlib.h> /* Losedows */ #include <fileapi.h> /* 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"); } }