diff --git a/src/main.c b/src/main.c index fa6ee56..5fe5ef9 100644 --- a/src/main.c +++ b/src/main.c @@ -3,6 +3,7 @@ #include #include #include +#include #include "addrbook.h" #include "audio.h" @@ -24,23 +25,27 @@ int server_handshake(net_t *const n, crypt_session_t *const s, crypt_key_t *cons struct options { const char *addr; const char *port; - const char *addressbook_path; - const char *key_path; + char *addressbook_path; + char *key_pub_path; + char *key_sec_path; bool is_alias_passed; char mode; }; +void options_destroy(struct options *opts) { + free(opts->key_pub_path); + free(opts->key_sec_path); + free(opts->addressbook_path); +} + +char *get_config_dir(void); int parse_argv(int argc, const char **argv, struct options *opts); void usage(void) { fprintf(stderr, - "tetatet -vh c|s (ADDR PORT | ALIAS for c) [-K,--keys KEY_PATH] [-A,--addressbook ADDRESSBOOK_FILE]\n" - " -v show version\n" - " -h show this help\n\n" - " -K,--keys KEYS_PATH path to where your public and secret (tat_own_pub_key\n" - " and tat_own_sec_key) keys are stored (~/.config/tetatet by default).\n" - " -A,--addressbook ADDRESSBOOK_FILE path to an addressbook file.\n" - " (~/.config/tetatet/addressbook by default)\n\n" + "tetatet -vh c|s (ADDR PORT | ALIAS for c)\n" + " -v,--version show version\n" + " -h,--help show this help\n\n" " c (ADDR PORT | ALIAS) is a client mode. You can specify ADDR and PORT or use\n" " an ALIAS that will use the last ADDR and PORT stored in an addressbook.\n" " s ADDR PORT is a server mode. Specify ADDR and PORT to listen on.\n"); @@ -76,7 +81,7 @@ int main(int argc, const char **argv) { // if (audio_init_soundsystem() == -1) // return 1; - FILE *addrbook_file = fopen((opts.addressbook_path == NULL) ? "addressbook" : opts.addressbook_path, "r"); + FILE *addrbook_file = fopen(opts.addressbook_path, "r"); if (addrbook_file != NULL) { addrbook_load(&ab, addrbook_file); fclose(addrbook_file); @@ -94,8 +99,8 @@ int main(int argc, const char **argv) { } } - FILE *pkey_file = fopen("tat_own_pub_key", "r"); - FILE *skey_file = fopen("tat_own_sec_key", "r"); + FILE *pkey_file = fopen(opts.key_pub_path, "r"); + FILE *skey_file = fopen(opts.key_sec_path, "r"); if (pkey_file == NULL || skey_file == NULL) { if ((result = crypt_key_gen(&ok)) == -1) { fprintf(stderr, "Failed to generate the keys.\n"); @@ -108,8 +113,8 @@ int main(int argc, const char **argv) { if (skey_file != NULL) fclose(skey_file); - pkey_file = fopen("tat_own_pub_key", "w+"); - skey_file = fopen("tat_own_sec_key", "w+"); + pkey_file = fopen(opts.key_pub_path, "w+"); + skey_file = fopen(opts.key_sec_path, "w+"); if (pkey_file == NULL || skey_file == NULL) { fprintf(stderr, "Cannot open tat_own_*_key files to write: %s\n", strerror(errno)); @@ -181,7 +186,7 @@ int main(int argc, const char **argv) { cleanup: if (is_ab_changed) { - addrbook_file = fopen((opts.addressbook_path == NULL) ? "addressbook" : opts.addressbook_path, "w+"); + addrbook_file = fopen(opts.addressbook_path, "w+"); if (addrbook_file != NULL) { if (addrbook_store(&ab, addrbook_file) == -1) fprintf(stderr, "Failed to store an addressbook: %s\n", strerror(errno)); @@ -189,6 +194,7 @@ cleanup: } } + options_destroy(&opts); addrbook_destroy(&ab); audio_destroy(&aud); net_destroy(&n); @@ -295,26 +301,12 @@ int parse_argv(int argc, const char **argv, struct options *opts) { for (int i = 1; i < argc; ++i) { if (argv[i][0] == '-') { - if (argv[i][1] == '-') { - if (strncmp(&argv[i][2], "keys", 4) == 0) { - opts->key_path = argv[i+1]; - ++i; - } else if (strncmp(&argv[i][2], "addressbook", 11) == 0) { - opts->addressbook_path = argv[i+1]; - ++i; - } else { - return -1; - } - continue; - } - - switch (argv[i][1]) { - case 'K': opts->key_path = argv[i+1]; ++i; continue; - case 'A': opts->addressbook_path = argv[i+1]; ++i; continue; - case 'v': return -2; - case 'h': return -3; - default: return -1; - } + if (argv[i][1] == 'h' || (argv[i][1] == '-' && argv[i][2] == 'h')) + return -3; + else if (argv[i][1] == 'v' || (argv[i][1] == '-' && argv[i][2] == 'v')) + return -2; + else + return -1; } else { if (opts->mode == 'c' || opts->mode == 's') { if (mode_arg_num == 0) @@ -325,7 +317,7 @@ int parse_argv(int argc, const char **argv, struct options *opts) { } else { switch (argv[i][0]) { case 'c': - case 's': + case 's': opts->mode = argv[i][0]; break; default: return -1; @@ -347,5 +339,39 @@ int parse_argv(int argc, const char **argv, struct options *opts) { || (!opts->is_alias_passed && opts->port == NULL)) return -1; + char *config_dir = get_config_dir(); + int config_dir_len = strlen(config_dir); + + if ((mkdir(config_dir, 0700) == -1) && (errno != EEXIST)) { + fprintf(stderr, "Cannot create a config dir %s: %s\n", config_dir, strerror(errno)); + free(config_dir); + return 1; + } + + opts->addressbook_path = (char *)malloc(config_dir_len + 11 + 1); + strncpy(opts->addressbook_path, config_dir, config_dir_len); + strcat(opts->addressbook_path, "addressbook"); + + opts->key_pub_path = (char *)malloc(config_dir_len + 11 + 1); + strncpy(opts->key_pub_path, config_dir, config_dir_len); + strcat(opts->key_pub_path, "own_pub_key"); + + opts->key_sec_path = (char *)malloc(config_dir_len + 11 + 1); + strncpy(opts->key_sec_path, config_dir, config_dir_len); + strcat(opts->key_sec_path, "own_sec_key"); + + free(config_dir); + return 0; } + +char *get_config_dir(void) { + const char *home_dir = getenv("HOME"); + + char *config_dir = (char *)malloc(strlen(home_dir) + 16 + 1); + + strncpy(config_dir, home_dir, strlen(home_dir)); + strcat(config_dir, "/.config/tetatet"); + + return config_dir; +}