From e5bb323a2f904b3fa09587d1823ac6185d9bfe94 Mon Sep 17 00:00:00 2001 From: "jazz (gitea)" Date: Sun, 8 Mar 2026 13:34:11 -0500 Subject: [PATCH] ugh --- Makefile | 6 +- chat.cc | 273 ------------------------------------------------- chat.h | 39 ------- main.cc | 302 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 302 insertions(+), 318 deletions(-) delete mode 100644 chat.cc diff --git a/Makefile b/Makefile index dad0be0..0c83d1e 100644 --- a/Makefile +++ b/Makefile @@ -2,13 +2,13 @@ CXX = g++ CXXFLAGS = -pthread -Wall -Wextra -O2 -std=c++17 LDFLAGS = -lcurses TARGET = ct -CXX_SRCS = main.cc chat.cc +CXX_SRCS = main.cc CXX_OBJS = $(CXX_SRCS:.cc=.o) all: $(TARGET) $(TARGET): $(CXX_OBJS) - $(CXX) $(CXXFLAGS) $(CXX_OBJS) -o $(TARGET) $(LDFLAGS) + $(CXX) $(CXXFLAGS) $(LDFLAGS) $(CXX_OBJS) -o $(TARGET) $(LDFLAGS) %.o: %.cc $(CXX) $(CXXFLAGS) -c $< -o $@ @@ -16,5 +16,5 @@ $(TARGET): $(CXX_OBJS) .PHONY: clean clean: - rm -f $(CXX_OBJS) $(TARGET) + rm -f *.o $(TARGET) diff --git a/chat.cc b/chat.cc deleted file mode 100644 index b51de7c..0000000 --- a/chat.cc +++ /dev/null @@ -1,273 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "chat.h" - -void -clear_rows(int s, int e) -{ - /* preserve cursor location */ - int x_bef; - int y_bef; - - getyx(stdscr, y_bef, x_bef); - - for (int i = s; i < e; i++) { - move(i, 0); - clrtoeol(); - } - - move(y_bef, x_bef); -} - -int -file_disp(std::string p, int lnstart, int lncount) -{ - std::ifstream f(p); - - if (!f) - return 1; - - int i = 0; - int ln_no = 0; - std::string ln; - - clear_rows(0, lncount + 1); /* clear chat window */ - - while (getline(f, ln) && i <= ln_no + lnstart + 1) { - if (i >= lnstart) { - move(ln_no, 0); - printw("%s", ln.c_str()); - ln_no++; - } - i++; - } - - move(CURSOR_DEFAULT_POSITION_Y, CURSOR_DEFAULT_POSITION_X); - refresh(); - return 0; -} - -int -count_lines(std::string p) -{ - int c = 0; - - std::ifstream f(p); - if (!f) - return c; - - /* Apparently this is the most efficient way to count all lines in a file. How revolting! */ - c = std::count(std::istreambuf_iterator(f), std::istreambuf_iterator(), '\n'); - - return c; -} - -void * -await_client(void *a) -{ - wclient_args_t *args = static_cast(a); - - socket_descriptor_client = accept(socket_descriptor_server, (sockaddr *)&args->new_addr, &args->new_addr_siz); - - if (socket_descriptor_client >= 0) { - log_append(log_path, "client connected"); - - if (count_lines(log_path) > LOG_LENGTH) - line_position++; - - file_disp(log_path, line_position, LOG_LENGTH); - } - - delete args; - - return poll_client(); -} - -void * -poll_client(void) -{ - char msg[1024]; - for (;;) { - /* listen for msg from client */ - memset(&msg, 0, sizeof(msg)); /* clear buf */ - bytes_read += recv(socket_descriptor_client, (char *)&msg, sizeof(msg), 0); - log_append(log_path, msg); - - if (count_lines(log_path) > LOG_LENGTH) - line_position++; - - file_disp(log_path, line_position, LOG_LENGTH); - } - - return nullptr; -} - -void -server_start(int port) -{ - auto *a = new wclient_args_t{}; - sockaddr_in srv_addr; - sockaddr_in newsock; - socklen_t newsock_siz = sizeof(newsock); - int bstat; - int rc; - - /* set up socket and connection tools */ - bzero((char *)&srv_addr, sizeof(srv_addr)); - srv_addr.sin_family = AF_INET; - srv_addr.sin_addr.s_addr = htonl(INADDR_ANY); - srv_addr.sin_port = htons(port); - - /* open stream-oriented socket w inet addr and track sock descriptor */ - socket_descriptor_server = socket(AF_INET, SOCK_STREAM, 0); - if (socket_descriptor_server < 0) - goto panic_if_no_server_sock; - - /* bind sock to its local addr */ - bstat = bind(socket_descriptor_server, (struct sockaddr *)&srv_addr, sizeof(srv_addr)); - if (bstat < 0) - goto panic_if_no_server_sock; - - log_append(log_path, "Waiting for a client to connect..."); - - /* listen for up to 5 simultaneous requests */ - listen(socket_descriptor_server, 5); - a->new_addr = newsock; - a->new_addr_siz = newsock_siz; - - rc = pthread_create(&client_wait_thread, nullptr, await_client, a); - - pthread_detach(client_wait_thread); - - log_append(log_path, "Server started successfully."); - - gettimeofday(&time_start, NULL); - - return; - -panic_if_no_server_sock: - endwin(); - fprintf(stderr, "Fatal: Could not establish server socket!\n"); - exit(1); -} - -void -server_stop(void) -{ - long e = time_end.tv_sec - time_start.tv_sec; - - gettimeofday(&time_end, NULL); - close(socket_descriptor_server); - - /* Don't just die silently */ - puts("********Session********"); - printf("Bytes written: %i\nBytes Read: %i\n", bytes_written, bytes_read); - printf("Elapsed time: %ld\n secs\n", e); - puts("Connection closed..."); -} - -void -client_stop(void) -{ - long e = time_end.tv_sec - time_start.tv_sec; - - gettimeofday(&time_end, NULL); - close(socket_descriptor_client); - puts("********Session********"); - printf("Bytes written: %i\nBytes read: %i\n", bytes_written, bytes_read); - printf("Elapsed time: %ld\n secs\n", e); - puts("Connection closed..."); -} - -void * -poll_server(void *args) -{ - wclient_args_t *a = static_cast(args); - int sock_desc = (int)a->aux; - char msg[1024]; - - for (;;) { - memset(&msg, 0, sizeof(msg)); - bytes_read += recv(sock_desc, (char *)&msg, sizeof(msg), 0); - - log_append(log_path, msg); - - if (count_lines(log_path) > LOG_LENGTH) - line_position++; - - file_disp(log_path, line_position, LOG_LENGTH); - } -} - -void -client_start(void) -{ - char msg[1024]; - int bread; - int bwrit; - int rc; - sockaddr_in send_addr; - - struct timeval time_start; - struct timeval time_end; - struct hostent *host = gethostbyname(listen_ip_address.c_str()); - - auto *a = new wclient_args_t{}; - - bzero((char *)&send_addr, sizeof(send_addr)); - send_addr.sin_family = AF_INET; - send_addr.sin_addr.s_addr = inet_addr(inet_ntoa(*(struct in_addr *)*host->h_addr_list)); - send_addr.sin_port = htons(listen_port); - socket_descriptor_client = socket(AF_INET, SOCK_STREAM, 0); - -attempt_client_connection: - int stat = connect(socket_descriptor_client, (sockaddr *)&send_addr, sizeof(send_addr)); - if (stat < 0) { - log_append(log_path, "Error connecting to socket, retrying..."); - goto attempt_client_connection; - } - - log_append(log_path, "Connected to the server!"); - bread = bwrit = 0; - - gettimeofday(&time_start, NULL); - - a->aux = socket_descriptor_client; - rc = pthread_create(&client_wait_thread, nullptr, poll_server, a); - pthread_detach(client_wait_thread); -} - -int -log_append(std::string p, std::string ln) -{ - std::ofstream f; - - f.open(p, std::ios_base::app); - if (!f.is_open()) - return 1; - - f << ln << std::endl; - - f.close(); - - // "this probably would help but theres too much broken stuff right now to be sure" - scott - // bool inclnum should be added to function if we do decide to use this block: - //if (inclnum) - // line_position++; - - return 0; -} diff --git a/chat.h b/chat.h index 0c542e3..2b53d1a 100644 --- a/chat.h +++ b/chat.h @@ -1,46 +1,7 @@ #ifndef CHAT_H #define CHAT_H -#ifndef _GLIBCXX_STRING #include -#endif - -#ifndef _NETINET_IN_H -#include -#endif - -typedef enum { - NO_MODE = 0, - SERVER_MODE = 1, - CLIENT_MODE = 2 -} chatmode_t; - -typedef struct { - sockaddr_in new_addr; - socklen_t new_addr_siz; - int aux; -}wclient_args_t; - -const int CURSOR_DEFAULT_POSITION_X = 2; -const int CURSOR_DEFAULT_POSITION_Y = 12; - -const int LOG_LENGTH = 10; -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; void *await_client(void *a); void clear_rows(int s, int e); diff --git a/main.cc b/main.cc index 221b9e8..8e1f16d 100644 --- a/main.cc +++ b/main.cc @@ -1,16 +1,56 @@ +#include +#include +#include +#include #include +#include #include #include +#include +#include +#include #include #include #include +#include +#include +#include #include #include "chat.h" +typedef enum { NO_MODE = 0, SERVER_MODE = 1, CLIENT_MODE = 2 } chatmode_t; + +typedef struct { + sockaddr_in new_addr; + socklen_t new_addr_siz; + int aux; +} wclient_args_t; + chatmode_t mode = NO_MODE; +const int LOG_LENGTH = 10; +int line_position = 0; + +const int CURSOR_DEFAULT_POSITION_X = 2; +const int CURSOR_DEFAULT_POSITION_Y = 12; + +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[]) { @@ -48,7 +88,7 @@ main(int argc, char *argv[]) line_position++; /* prompt for input */ - move(12, 0); + move(CURSOR_DEFAULT_POSITION_Y, 0); printw("> "); /* await input */ @@ -60,7 +100,7 @@ main(int argc, char *argv[]) /* Final exit point if everything goes OK */ endwin(); - + switch (mode) { case CLIENT_MODE: client_stop(); @@ -72,7 +112,7 @@ main(int argc, char *argv[]) goto panic_no_mode; break; } - + return 0; panic_no_mode: @@ -88,3 +128,259 @@ panic_no_mode: return 1; } + +void +clear_rows(int s, int e) +{ + /* preserve cursor location */ + int x_bef; + int y_bef; + + getyx(stdscr, y_bef, x_bef); + + for (int i = s; i < e; i++) { + move(i, 0); + clrtoeol(); + } + + move(y_bef, x_bef); +} + +int +file_disp(std::string p, int lnstart, int lncount) +{ + std::ifstream f(p); + + if (!f) + return 1; + + int i = 0; + int ln_no = 0; + std::string ln; + + clear_rows(0, lncount + 1); /* clear chat window */ + + while (getline(f, ln) && i <= ln_no + lnstart + 1) { + if (i >= lnstart) { + move(ln_no, 0); + printw("%s", ln.c_str()); + ln_no++; + } + i++; + } + + move(CURSOR_DEFAULT_POSITION_Y, CURSOR_DEFAULT_POSITION_X); + refresh(); + return 0; +} + +int +count_lines(std::string p) +{ + int c = 0; + + std::ifstream f(p); + if (!f) + return c; + + /* Apparently this is the most efficient way to count all lines in a file. How revolting! */ + c = std::count(std::istreambuf_iterator(f), std::istreambuf_iterator(), '\n'); + + return c; +} + +void * +await_client(void *a) +{ + wclient_args_t *args = static_cast(a); + + socket_descriptor_client = accept(socket_descriptor_server, (sockaddr *)&args->new_addr, &args->new_addr_siz); + + if (socket_descriptor_client >= 0) { + log_append(log_path, "client connected"); + + if (count_lines(log_path) > LOG_LENGTH) + line_position++; + + file_disp(log_path, line_position, LOG_LENGTH); + } + + delete args; + + return poll_client(); +} + +void * +poll_client(void) +{ + char msg[1024]; + for (;;) { + /* listen for msg from client */ + memset(&msg, 0, sizeof(msg)); /* clear buf */ + bytes_read += recv(socket_descriptor_client, (char *)&msg, sizeof(msg), 0); + log_append(log_path, msg); + + if (count_lines(log_path) > LOG_LENGTH) + line_position++; + + file_disp(log_path, line_position, LOG_LENGTH); + } + + return nullptr; +} + +void +server_start(int port) +{ + auto *a = new wclient_args_t{}; + sockaddr_in srv_addr; + sockaddr_in newsock; + socklen_t newsock_siz = sizeof(newsock); + int bstat; + int rc; + + /* set up socket and connection tools */ + bzero((char *)&srv_addr, sizeof(srv_addr)); + srv_addr.sin_family = AF_INET; + srv_addr.sin_addr.s_addr = htonl(INADDR_ANY); + srv_addr.sin_port = htons(port); + + /* open stream-oriented socket w inet addr and track sock descriptor */ + socket_descriptor_server = socket(AF_INET, SOCK_STREAM, 0); + if (socket_descriptor_server < 0) + goto panic_if_no_server_sock; + + /* bind sock to its local addr */ + bstat = bind(socket_descriptor_server, (struct sockaddr *)&srv_addr, sizeof(srv_addr)); + if (bstat < 0) + goto panic_if_no_server_sock; + + log_append(log_path, "Waiting for a client to connect..."); + + /* listen for up to 5 simultaneous requests */ + listen(socket_descriptor_server, 5); + a->new_addr = newsock; + a->new_addr_siz = newsock_siz; + + rc = pthread_create(&client_wait_thread, nullptr, await_client, a); + + pthread_detach(client_wait_thread); + + log_append(log_path, "Server started successfully."); + + gettimeofday(&time_start, NULL); + + return; + +panic_if_no_server_sock: + endwin(); + fprintf(stderr, "Fatal: Could not establish server socket!\n"); + exit(1); +} + +void +server_stop(void) +{ + long e = time_end.tv_sec - time_start.tv_sec; + + gettimeofday(&time_end, NULL); + close(socket_descriptor_server); + + /* Don't just die silently */ + puts("********Session********"); + printf("Bytes written: %i\nBytes Read: %i\n", bytes_written, bytes_read); + printf("Elapsed time: %ld\n secs\n", e); + puts("Connection closed..."); +} + +void +client_stop(void) +{ + long e = time_end.tv_sec - time_start.tv_sec; + + gettimeofday(&time_end, NULL); + close(socket_descriptor_client); + puts("********Session********"); + printf("Bytes written: %i\nBytes read: %i\n", bytes_written, bytes_read); + printf("Elapsed time: %ld\n secs\n", e); + puts("Connection closed..."); +} + +void * +poll_server(void *args) +{ + wclient_args_t *a = static_cast(args); + int sock_desc = (int)a->aux; + char msg[1024]; + + for (;;) { + memset(&msg, 0, sizeof(msg)); + bytes_read += recv(sock_desc, (char *)&msg, sizeof(msg), 0); + + log_append(log_path, msg); + + if (count_lines(log_path) > LOG_LENGTH) + line_position++; + + file_disp(log_path, line_position, LOG_LENGTH); + } +} + +void +client_start(void) +{ + char msg[1024]; + int bread; + int bwrit; + int rc; + sockaddr_in send_addr; + + struct timeval time_start; + struct timeval time_end; + struct hostent *host = gethostbyname(listen_ip_address.c_str()); + + auto *a = new wclient_args_t{}; + + bzero((char *)&send_addr, sizeof(send_addr)); + send_addr.sin_family = AF_INET; + send_addr.sin_addr.s_addr = inet_addr(inet_ntoa(*(struct in_addr *)*host->h_addr_list)); + send_addr.sin_port = htons(listen_port); + socket_descriptor_client = socket(AF_INET, SOCK_STREAM, 0); + +attempt_client_connection: + int stat = connect(socket_descriptor_client, (sockaddr *)&send_addr, sizeof(send_addr)); + if (stat < 0) { + log_append(log_path, "Error connecting to socket, retrying..."); + goto attempt_client_connection; + } + + log_append(log_path, "Connected to the server!"); + bread = bwrit = 0; + + gettimeofday(&time_start, NULL); + + a->aux = socket_descriptor_client; + rc = pthread_create(&client_wait_thread, nullptr, poll_server, a); + pthread_detach(client_wait_thread); +} + +int +log_append(std::string p, std::string ln) +{ + std::ofstream f; + + f.open(p, std::ios_base::app); + if (!f.is_open()) + return 1; + + f << ln << std::endl; + + f.close(); + + // "this probably would help but theres too much broken stuff right now to be sure" - scott + // bool inclnum should be added to function if we do decide to use this block: + // if (inclnum) + // line_position++; + + return 0; +}