tcp-chat/src/client/client.c

124 lines
3.8 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// readline.h doesn't include stdio.h
// This bug is older than me)))
#include "client.h"
#include <stdio.h>
#include <readline/readline.h>
#include <readline/history.h>
#include "term.h"
static const str greeting_art = STR(
" ^,,^ |\n"
" ( •·•) Meum! (o.o`7\n"
" / ` | Meum... |`˜ \\\n"
"\\(_,J J L l`,)/\n"
);
static const str farewell_art = STR(
" ^,,^ |\n"
" ( -.-) (>,<`7\n"
" / ` | Goodbye! |`˜ \\\n"
"\\(_,J J L l`,)/\n"
);
static ClientCredential* _client_credential = NULL;
static ServerConnection* _server_connection = NULL;
static Result(void) commandExec(str command, bool* stop);
static Result(void) askUserNameAndPassword(ClientCredential** cred){
Deferral(8);
printf("username: ");
char username[1024];
fgets(username, sizeof(username), stdin);
printf("password: ");
char password[1024];
// TODO: hide password
fgets(password, sizeof(password), stdin);
try(*cred, p, ClientCredential_create(str_from_cstr(username), str_from_cstr(password)));
Return RESULT_VOID;
}
Result(void) client_run() {
Deferral(32);
if(!term_init()){
Return RESULT_ERROR("can't init terminal", false);
}
using_history();
fputs(greeting_art.data, stdout);
try_void(askUserNameAndPassword(&_client_credential));
char* command_input_prev = NULL;
char* command_input_raw = NULL;
Defer(rl_free(command_input_prev));
str command_input = str_null;
bool stop = false;
while((command_input_raw = readline("> ")) && !stop){
rl_free(command_input_prev);
command_input_prev = command_input_raw;
command_input = str_from_cstr(command_input_raw);
str_trim(&command_input, true);
if(command_input.size == 0)
continue;
add_history(command_input.data);
Result(void) com_result = commandExec(command_input, &stop);
if(com_result.error){
str e_str = Error_toStr(com_result.error);
printfe("%s\n", e_str.data);
free(e_str.data);
Error_free(com_result.error);
}
}
ClientCredential_free(_client_credential);
ServerConnection_close(_server_connection);
Return RESULT_VOID;
}
#define is_alias(LITERAL) str_equals(command, STR(LITERAL))
static Result(void) commandExec(str command, bool* stop){
Deferral(64);
char answer_buf[512];
const u32 answer_buf_size = sizeof(answer_buf);
if(is_alias("q") || is_alias("quit") || is_alias("exit")){
fputs(farewell_art.data, stdout);
*stop = true;
}
else if(is_alias("clear")){
term_clear();
}
else if(is_alias("h") || is_alias("help")){
puts(
"COMMANDS:\n"
"q, quit, exit Close the program.\n"
"clear Clear the screen.\n"
"j, join Join a server.\n"
"c, connect Connect to a server you joined.\n"
);
}
else if (is_alias("j") || is_alias("join")){
puts("Enter server address (ip:port): ");
fgets(answer_buf, answer_buf_size, stdin);
str new_server_link = str_from_cstr(answer_buf);
str_trim(&new_server_link, true);
ServerConnection_close(_server_connection);
try(_server_connection, p, ServerConnection_open(_client_credential, new_server_link.data));
}
else if(is_alias("c") || is_alias("connect")){
// TODO: read saved servers from database
}
else {
Return RESULT_ERROR_FMT("unknown kommand: '%s'\n"
"Use 'h' to see list of avaliable commands\n",
command.data);
}
Return RESULT_VOID;
}