From 6889e2d66b710c241b3884fc28610a9e6be4e610 Mon Sep 17 00:00:00 2001
From: Matt Strapp <matt@mattstrapp.net>
Date: Mon, 25 Apr 2022 17:48:52 -0500
Subject: A

---
 include/client.hpp |  17 +++++++
 include/comms.hpp  |  32 ++++++++++++
 include/server.hpp |  27 ++++++++++
 include/util.hpp   | 141 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 217 insertions(+)
 create mode 100644 include/client.hpp
 create mode 100644 include/comms.hpp
 create mode 100644 include/server.hpp
 create mode 100644 include/util.hpp

(limited to 'include')

diff --git a/include/client.hpp b/include/client.hpp
new file mode 100644
index 0000000..dfc3e0c
--- /dev/null
+++ b/include/client.hpp
@@ -0,0 +1,17 @@
+#ifndef client_H
+#define client_H
+
+#include "comms.hpp"
+
+void RemoveConnection(int i);
+int Send_Blocking(int sockFD, const BYTE *data, int len);
+
+void DoClient(const char *svrIP, int svrPort, const char *fileName);
+
+void doClientCommand(int i);
+
+void prepareSend(int i, Header header);
+int processReception(int i);
+void printMessage(int i);
+
+#endif
diff --git a/include/comms.hpp b/include/comms.hpp
new file mode 100644
index 0000000..1b2a942
--- /dev/null
+++ b/include/comms.hpp
@@ -0,0 +1,32 @@
+#ifndef COMM_UTIL_H
+#define COMM_UTIL_H
+#include "util.hpp"
+
+struct CONN_STAT {
+  int id;          // Unique id to identify a client instance
+  bool isLoggedIn; // Used by server to identify that this connection is logged
+                   // in
+  struct timeb lastTime;  // Last time this connection was used (used to detect
+                          // s2c closure)
+  bool recInitHeader;     // False until initial header is recieved
+  bool expectingHeader;   // The message to be read is a header (irrelevent for
+                          // senders)
+  enum LinkType linkType; // MESSAGE_LINK (persistent) or FILE_LINK (one off)
+  enum Direction direction; // C2S or S2C
+  char name[9];             // The user this connection is with
+  int nBuffered;            // number of bytes in the buffer
+  int messageLen; // size of the current message being sent (includes header)
+  int nToDo; // num bytes to do before current messsage is completed (message
+             // len --> 0)
+  bool changeDirection; // Flag to change the direction of the connection once
+                        // the current communication finishes
+  bool shouldClose;          // Flag to destroy this connection
+};
+
+int Send_NonBlocking(int sockFD, BYTE *data, struct CONN_STAT *pStat,
+                     struct pollfd *pPeer);
+int Recv_NonBlocking(int sockFD, BYTE *data, struct CONN_STAT *pStat,
+                     struct pollfd *pPeer);
+void SetNonBlockIO(int fd);
+
+#endif
diff --git a/include/server.hpp b/include/server.hpp
new file mode 100644
index 0000000..ab77ad8
--- /dev/null
+++ b/include/server.hpp
@@ -0,0 +1,27 @@
+#ifndef server_H
+#define server_H
+
+// Comms includes util.hpp
+#include "comms.hpp"
+
+void SetNonBlockIO(int fd);
+void RemoveConnection(int i);
+
+int Send_NonBlocking(int sockFD, BYTE *data, struct CONN_STAT *pStat,
+                     struct pollfd *pPeer);
+int Recv_NonBlocking(int sockFD, BYTE *data, struct CONN_STAT *pStat,
+                     struct pollfd *pPeer);
+
+int processReception(int i);
+void doServerCommand(int i);
+void sendMessageToId(int id, bool reqLoggedIn, Header header, char *message);
+void sendMessageToAllLoggedIn(Header header, char *message);
+void sendMessageToAllLoggedInExceptSender(int senderID, Header header,
+                                          char *message);
+void sendMessageToName(char *name, Header header, char *message);
+void prepareMessage(int i, Header header, char *message);
+void printServerCommand(int i);
+
+void DoServer(int svrPort);
+
+#endif
diff --git a/include/util.hpp b/include/util.hpp
new file mode 100644
index 0000000..10887df
--- /dev/null
+++ b/include/util.hpp
@@ -0,0 +1,141 @@
+#ifndef UTIL_H
+#define UTIL_H
+
+// Get your libraries here
+#include <arpa/inet.h>
+#include <dirent.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <poll.h>
+#include <signal.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/timeb.h>
+#include <sys/wait.h>
+#include <time.h>
+#include <unistd.h>
+
+#define NAME "SERVER"
+#define ANON "Anonymous"
+#define LINE_SIZE 5000 // overkill
+
+#define BUF_LEN 12000000 // overkill
+#define MAX_REQUEST_SIZE 10000000
+#define MIN_USERNAME_LEN 4
+#define MAX_USERNAME_LEN 8
+#define MIN_PASSWORD_LEN 4
+#define MAX_PASSWORD_LEN 8
+
+enum Command {
+  REGISTER = 0, // [username] [password] Register a new account
+  LOGIN = 1,  // [username] [password] Log in with an existing account and enter
+              // the chat room
+  LOGOUT = 2, // Log out and leave the chat room
+  SEND = 3,   // [msg] Send a public message
+  SEND2 = 4,  // [username] [msg] Send a private message to a user
+  SENDA = 5,  // [msg] Send an anonymous public message
+  SENDA2 = 6, // [username] [msg] Send an anonymous private message to a user
+  SENDF = 7,  // [local file] Send a file publicly
+  SENDF2 = 8, // [username] [local file] Send a file to a user privately
+  LIST = 9,   // List all online users
+  DELAY = 10, // [N] A special command that delays for N seconds before
+              // executing the next command in the script
+
+  GETF = 11,    // [filename] Server telling clinet to request a file, clinet
+                // requesting a file
+  PING = 12,    // Check that connection is still there (nop)
+  CONNECT = 13, // [unique id] Allows the server to identify specific users when
+                // they are logged in multiple times
+
+  INVALID = 15 // Used when no valid command is found
+};
+
+enum LinkType { MESSAGE_LINK, FILE_LINK };
+
+typedef unsigned char BYTE;
+typedef unsigned int DWORD;
+typedef unsigned short WORD;
+
+enum Command parse_command(char *line);
+bool isValidUsername(char *username);
+bool isValidPassword(char *password);
+
+void Error(const char *format, ...);
+void Log(const char *format, ...);
+
+void buf2i(BYTE *buf, int &i);
+void i2buf(int &i, BYTE *buf);
+
+const char *com2str(enum Command command);
+
+double timeDifference(struct timeb a, struct timeb b);
+
+int getNumEntries(const char *databse);
+bool loginQuery(const char *database, char *username, char *password);
+bool usernameQuery(const char *database, char *username);
+
+void recordEntry(const char *database, char *key, char *value);
+void clearDatabase(const char *database);
+
+int buf2file(BYTE *buf, int nbytes, char *filename);
+int file2buf(char *filename, BYTE *buf);
+
+#define HEADER_LEN 13 // number of bytes in a message header
+
+enum Direction { C2S, S2C };  // client to server, server to client
+enum Flag { SUCCESS, FAIL };  // success, failure
+enum Recipient { PUB, PRIV }; // send to all, send to one
+enum Trace { SIGN, ANNON };   // send publically, send anonymously
+
+class Header {
+public:
+  enum Direction m_direction;
+  enum Flag m_flag;
+  enum Recipient m_recipient;
+  enum Trace m_trace;
+  enum Command m_command;
+
+  BYTE m_name[9];
+
+  int m_size;
+
+  Header(); // constructor
+
+  void encode(BYTE *buf); // encode message to buffer
+  void decode(BYTE *buf); // decode buffer to message
+
+  void setFlags(enum Direction direction, enum Flag flag,
+                enum Recipient recipient, enum Trace trace);
+
+  void displayContents(bool tab); // helper to print contents of class
+};
+
+inline bool operator==(const Header &lfs, const Header &rhs) {
+  bool result = true;
+
+  result &= lfs.m_direction == rhs.m_direction;
+  result &= lfs.m_flag == rhs.m_flag;
+  result &= lfs.m_recipient == rhs.m_recipient;
+  result &= lfs.m_trace == rhs.m_trace;
+  result &= lfs.m_command == rhs.m_command;
+
+  for (int i = 0; i < MAX_USERNAME_LEN; i++)
+    result &= lfs.m_name[i] == rhs.m_name[i];
+
+  result &= lfs.m_size == rhs.m_size;
+
+  return result;
+}
+
+inline bool operator!=(const Header &lhs, const Header &rhs) {
+  return !(lhs == rhs);
+}
+
+#endif
-- 
cgit v1.2.3