forked from scott/threaded_network_chat
151 lines
3.1 KiB
C++
151 lines
3.1 KiB
C++
#include <fstream>
|
|
#include <string>
|
|
|
|
#include <arpa/inet.h>
|
|
#include <bits/types/struct_timeval.h>
|
|
#include <curses.h>
|
|
#include <netdb.h>
|
|
#include <netinet/in.h>
|
|
#include <pthread.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <sys/select.h>
|
|
#include <sys/socket.h>
|
|
#include <sys/time.h>
|
|
#include <unistd.h>
|
|
|
|
#include "chat.h"
|
|
|
|
typedef enum { NO_MODE = 0, SERVER_MODE = 1, CLIENT_MODE = 2 } chatmode_t;
|
|
|
|
chatmode_t mode = NO_MODE;
|
|
|
|
int line_position = 0;
|
|
|
|
struct timeval time_start;
|
|
struct timeval time_end;
|
|
int bytes_read;
|
|
int bytes_written;
|
|
|
|
int listen_port = 9999;
|
|
std::string listen_ip_address = "127.0.0.1";
|
|
|
|
std::string log_path;
|
|
|
|
int socket_descriptor_server;
|
|
int socket_descriptor_client;
|
|
|
|
pthread_t client_wait_thread;
|
|
|
|
int
|
|
main(int argc, char *argv[])
|
|
{
|
|
int err = 0;
|
|
char *usr_in = new char[1024];
|
|
bool quit = false;
|
|
|
|
if (argc > 1 && (!strcmp(argv[1], "client")))
|
|
mode = CLIENT_MODE;
|
|
else
|
|
mode = SERVER_MODE;
|
|
|
|
initscr();
|
|
use_default_colors();
|
|
|
|
line_position = count_lines(log_path) - LOG_LENGTH + 1;
|
|
|
|
switch (mode) {
|
|
case CLIENT_MODE:
|
|
log_append(log_path, "CLIENT MODE");
|
|
client_start(listen_ip_address, listen_port, &socket_descriptor_client, log_path,
|
|
&client_wait_thread);
|
|
break;
|
|
case SERVER_MODE:
|
|
log_append(log_path, "SERVER MODE");
|
|
err = server_start(listen_port, &socket_descriptor_server, log_path,
|
|
&client_wait_thread, &time_start);
|
|
if (err)
|
|
goto panic_no_server_sock;
|
|
break;
|
|
default:
|
|
goto panic_no_mode;
|
|
break;
|
|
}
|
|
|
|
while (!quit) {
|
|
file_disp(log_path, line_position, LOG_LENGTH);
|
|
|
|
if (count_lines(log_path) > LOG_LENGTH)
|
|
line_position++;
|
|
|
|
/* prompt for input */
|
|
move(CURSOR_DEFAULT_POSITION_Y, 0);
|
|
printw("> ");
|
|
|
|
/* await input */
|
|
getstr(usr_in);
|
|
log_append(log_path, usr_in);
|
|
send(socket_descriptor_client, (char *)usr_in, strlen(usr_in), 0);
|
|
}
|
|
|
|
/* Final exit point if everything goes OK */
|
|
|
|
endwin();
|
|
|
|
switch (mode) {
|
|
case CLIENT_MODE:
|
|
client_stop(&time_start, &time_end, &socket_descriptor_client, &bytes_read,
|
|
&bytes_written);
|
|
break;
|
|
case SERVER_MODE:
|
|
server_stop(&time_start, &time_end, &socket_descriptor_server, &bytes_read,
|
|
&bytes_written);
|
|
break;
|
|
default:
|
|
goto panic_no_mode;
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
|
|
panic_no_mode:
|
|
big_panic_msg();
|
|
|
|
if (mode == NO_MODE)
|
|
fprintf(stderr, "Fatal: Mode was not set!\n");
|
|
else
|
|
fprintf(stderr, "Fatal: Mode was set to invalid enum %i\n", mode);
|
|
|
|
return 1;
|
|
|
|
panic_no_server_sock:
|
|
big_panic_msg();
|
|
|
|
fprintf(stderr, "Fatal: Could not establish server socket!\n");
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
* For when things go really really bad.
|
|
* Check if there is a window and if so, close it.
|
|
* Spit out a really loud obnoxious error afterwards.
|
|
*/
|
|
void
|
|
big_panic_msg(void)
|
|
{
|
|
if (!isendwin())
|
|
endwin();
|
|
|
|
fprintf(stderr, "-----FATAL ERROR, THIS SHOULD NEVER HAPPEN-----\n");
|
|
usleep(400 * 1000);
|
|
fprintf(stderr, "You may ask yourself... how do I work this?\n");
|
|
putchar(7);
|
|
usleep(400 * 1000);
|
|
fprintf(stderr, "And you may find yourself... past the point of return 0;!\n");
|
|
putchar(7);
|
|
usleep(400 * 1000);
|
|
fprintf(stderr, "And you may ask yourself... well, how did I get here?\n");
|
|
putchar(7);
|
|
}
|