1
0
Fork 0

Compare commits

...

5 Commits

1 changed files with 85 additions and 46 deletions

View File

@ -3,6 +3,7 @@
#include <stdbool.h> #include <stdbool.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <sys/stat.h>
#include "addrbook.h" #include "addrbook.h"
#include "audio.h" #include "audio.h"
@ -24,16 +25,30 @@ int server_handshake(net_t *const n, crypt_session_t *const s, crypt_key_t *cons
struct options { struct options {
const char *addr; const char *addr;
const char *port; const char *port;
const char *addressbook_path; char *addressbook_path;
const char *key_path; char *key_pub_path;
char *key_sec_path;
bool is_alias_passed; bool is_alias_passed;
char command; 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); int parse_argv(int argc, const char **argv, struct options *opts);
void usage(void) { void usage(void) {
fprintf(stderr, "tetatet -vh c|s ADDR PORT -k KEY_PATH -a ADDRESSBOOK_FILE\n"); fprintf(stderr,
"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");
} }
void version(void) { void version(void) {
@ -66,13 +81,13 @@ int main(int argc, const char **argv) {
// if (audio_init_soundsystem() == -1) // if (audio_init_soundsystem() == -1)
// return 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) { if (addrbook_file != NULL) {
addrbook_load(&ab, addrbook_file); addrbook_load(&ab, addrbook_file);
fclose(addrbook_file); fclose(addrbook_file);
} }
if (opts.command == 'c' && opts.is_alias_passed) { if (opts.mode == 'c' && opts.is_alias_passed) {
addrbook_entry_t *aec = addrbook_get_by_alias(&ab, opts.addr); addrbook_entry_t *aec = addrbook_get_by_alias(&ab, opts.addr);
if (aec == NULL) { if (aec == NULL) {
fprintf(stderr, "An alias \"%s\" is not in an addressbook!\n", opts.addr); fprintf(stderr, "An alias \"%s\" is not in an addressbook!\n", opts.addr);
@ -84,8 +99,8 @@ int main(int argc, const char **argv) {
} }
} }
FILE *pkey_file = fopen("tat_own_pub_key", "r"); FILE *pkey_file = fopen(opts.key_pub_path, "r");
FILE *skey_file = fopen("tat_own_sec_key", "r"); FILE *skey_file = fopen(opts.key_sec_path, "r");
if (pkey_file == NULL || skey_file == NULL) { if (pkey_file == NULL || skey_file == NULL) {
if ((result = crypt_key_gen(&ok)) == -1) { if ((result = crypt_key_gen(&ok)) == -1) {
fprintf(stderr, "Failed to generate the keys.\n"); fprintf(stderr, "Failed to generate the keys.\n");
@ -98,8 +113,8 @@ int main(int argc, const char **argv) {
if (skey_file != NULL) if (skey_file != NULL)
fclose(skey_file); fclose(skey_file);
pkey_file = fopen("tat_own_pub_key", "w+"); pkey_file = fopen(opts.key_pub_path, "w+");
skey_file = fopen("tat_own_sec_key", "w+"); skey_file = fopen(opts.key_sec_path, "w+");
if (pkey_file == NULL || skey_file == NULL) { if (pkey_file == NULL || skey_file == NULL) {
fprintf(stderr, "Cannot open tat_own_*_key files to write: %s\n", strerror(errno)); fprintf(stderr, "Cannot open tat_own_*_key files to write: %s\n", strerror(errno));
@ -128,13 +143,13 @@ int main(int argc, const char **argv) {
fclose(skey_file); fclose(skey_file);
} }
(opts.command == 'c') ? (opts.mode == 'c') ?
(result = net_client_init(&n, opts.addr, opts.port)) (result = net_client_init(&n, opts.addr, opts.port))
: (result = net_server_init(&n, opts.addr , opts.port)); : (result = net_server_init(&n, opts.addr , opts.port));
if (result != 0) if (result != 0)
goto cleanup; goto cleanup;
(opts.command == 'c') ? (opts.mode == 'c') ?
(result = client_handshake(&n, &s, &ok, &rk)) (result = client_handshake(&n, &s, &ok, &rk))
: (result = server_handshake(&n, &s, &ok, &rk)); : (result = server_handshake(&n, &s, &ok, &rk));
if (result != 0) if (result != 0)
@ -152,26 +167,26 @@ int main(int argc, const char **argv) {
// audio_init_default(&aud, CHANNELS, SAMPLE_RATE, FRAMES_PER_BUFFFER); // audio_init_default(&aud, CHANNELS, SAMPLE_RATE, FRAMES_PER_BUFFFER);
// (opts.command == 'c') ? // (opts.mode == 'c') ?
// (audio_stream_input_toggle(&aud)) // (audio_stream_input_toggle(&aud))
// : (audio_stream_output_toggle(&aud)); // : (audio_stream_output_toggle(&aud));
// for (size_t i = 0; i < (20 * SAMPLE_RATE)/FRAMES_PER_BUFFFER; ++i) { // for (size_t i = 0; i < (20 * SAMPLE_RATE)/FRAMES_PER_BUFFFER; ++i) {
// if (opts.command == 'c') { // if (opts.mode == 'c') {
// audio_read(&aud, aud_buf, AUDIO_BUF_SIZE); // audio_read(&aud, aud_buf, AUDIO_BUF_SIZE);
// } else { // } else {
// // // //
// } // }
// } // }
// (opts.command == 'c') ? // (opts.mode == 'c') ?
// (audio_stream_input_toggle(&aud)) // (audio_stream_input_toggle(&aud))
// : (audio_stream_output_toggle(&aud)); // : (audio_stream_output_toggle(&aud));
cleanup: cleanup:
if (is_ab_changed) { 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_file != NULL) {
if (addrbook_store(&ab, addrbook_file) == -1) if (addrbook_store(&ab, addrbook_file) == -1)
fprintf(stderr, "Failed to store an addressbook: %s\n", strerror(errno)); fprintf(stderr, "Failed to store an addressbook: %s\n", strerror(errno));
@ -179,6 +194,7 @@ cleanup:
} }
} }
options_destroy(&opts);
addrbook_destroy(&ab); addrbook_destroy(&ab);
audio_destroy(&aud); audio_destroy(&aud);
net_destroy(&n); net_destroy(&n);
@ -281,42 +297,28 @@ int server_handshake(net_t *const n, crypt_session_t *const s, crypt_key_t *cons
int parse_argv(int argc, const char **argv, struct options *opts) { int parse_argv(int argc, const char **argv, struct options *opts) {
if (argc == 1) if (argc == 1)
return -1; return -1;
int command_arg_num = 0; int mode_arg_num = 0;
for (int i = 1; i < argc; ++i) { for (int i = 1; i < argc; ++i) {
if (argv[i][0] == '-') { if (argv[i][0] == '-') {
if (argv[i][1] == '-') { if (argv[i][1] == 'h' || (argv[i][1] == '-' && argv[i][2] == 'h'))
if (strncmp(&argv[i][2], "keys", 4) == 0) { return -3;
opts->key_path = argv[i+1]; else if (argv[i][1] == 'v' || (argv[i][1] == '-' && argv[i][2] == 'v'))
++i; return -2;
} else if (strncmp(&argv[i][2], "addressbook", 11) == 0) { else
opts->addressbook_path = argv[i+1]; return -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;
}
} else { } else {
if (opts->command == 'c' || opts->command == 's') { if (opts->mode == 'c' || opts->mode == 's') {
if (command_arg_num == 0) if (mode_arg_num == 0)
opts->addr = argv[i]; opts->addr = argv[i];
else if (command_arg_num == 1) else if (mode_arg_num == 1)
opts->port = argv[i]; opts->port = argv[i];
++command_arg_num; ++mode_arg_num;
} else { } else {
switch (argv[i][0]) { switch (argv[i][0]) {
case 'c': case 'c':
case 's': case 's':
opts->command = argv[i][0]; opts->mode = argv[i][0];
break; break;
default: return -1; default: return -1;
} }
@ -329,10 +331,47 @@ int parse_argv(int argc, const char **argv, struct options *opts) {
if (r == -1) if (r == -1)
r = inet_pton(AF_INET6, opts->addr, &test); r = inet_pton(AF_INET6, opts->addr, &test);
opts->is_alias_passed = r == 0; opts->is_alias_passed = r == 0;
if (opts->command == '\0' || opts->addr[0] == '\0' if (opts->mode == 's' && opts->is_alias_passed)
return -1;
if (opts->mode == '\0' || opts->addr[0] == '\0'
|| (!opts->is_alias_passed && opts->port == NULL)) || (!opts->is_alias_passed && opts->port == NULL))
return -1; 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; 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;
}