From b7398afc056ee2ce3ce820fb333a06724eb9d0d9 Mon Sep 17 00:00:00 2001 From: Brad Arant Date: Wed, 11 Aug 2021 21:38:22 -0700 Subject: [PATCH] It works!!! --- Command.cpp | 2 +- Command.h | 2 +- ConsoleServer.cpp | 2 +- ConsoleSession.cpp | 89 +++++++++++++++-------------------------- ConsoleSession.h | 20 +++++----- EPoll.cpp | 11 +----- INotify.cpp | 2 +- INotify.h | 2 +- Socket.cpp | 99 ++++++++++++++++++++++------------------------ Socket.h | 22 +++++------ TCPSession.cpp | 71 +++++++++++++++++---------------- TCPSession.h | 8 ++-- TCPSocket.cpp | 17 ++++---- TLSSession.cpp | 4 +- TLSSession.h | 4 +- compile | 2 +- 16 files changed, 160 insertions(+), 197 deletions(-) diff --git a/Command.cpp b/Command.cpp index af3f10d..6505ffd 100644 --- a/Command.cpp +++ b/Command.cpp @@ -12,7 +12,7 @@ namespace core { out << "Write your own command description here for the help system." << std::endl; } - bool Command::check(coreutils::ZString request) { + bool Command::check(coreutils::ZString &request) { return request[0].equals(name); } diff --git a/Command.h b/Command.h index 6915256..3b162b8 100644 --- a/Command.h +++ b/Command.h @@ -37,7 +37,7 @@ namespace core { /// on this command. /// - virtual bool check(coreutils::ZString request); + virtual bool check(coreutils::ZString &request); /// /// This method is used to implement the functionality of the requested command. diff --git a/ConsoleServer.cpp b/ConsoleServer.cpp index 3bbacd4..16cdc4f 100644 --- a/ConsoleServer.cpp +++ b/ConsoleServer.cpp @@ -5,7 +5,7 @@ namespace core { - ConsoleServer::ConsoleServer(EPoll &ePoll, IPAddress address) : TCPServer(ePoll, address, "Console") { + ConsoleServer::ConsoleServer(EPoll &ePoll, IPAddress address) : TCPServer(ePoll, address, " ", "Console") { coreutils::Log(this); } diff --git a/ConsoleSession.cpp b/ConsoleSession.cpp index 6ac48e8..72c728f 100644 --- a/ConsoleSession.cpp +++ b/ConsoleSession.cpp @@ -2,103 +2,76 @@ #include "Log.h" namespace core { - - ConsoleSession::ConsoleSession(EPoll &ePoll, TCPServer &server) : TerminalSession(ePoll, server) { - coreutils::Log(coreutils::LOG_DEBUG_2) << "Constructing ConsoleSession..."; - } - - ConsoleSession::~ConsoleSession() {} - - void ConsoleSession::protocol(coreutils::ZString data) { - coreutils::Log(coreutils::LOG_DEBUG_1) << "ConsoleSession protocol " << status; + ConsoleSession::ConsoleSession(EPoll &ePoll, TCPServer &server) : TerminalSession(ePoll, server) {} + + ConsoleSession::~ConsoleSession() {} + + void ConsoleSession::protocol(coreutils::ZString &data) { + + coreutils::ZString blank(""); + switch (status) { - + case WELCOME: - setBackColor(BG_BLACK); - clear(); - setCursorLocation(1, 1); - setBackColor(BG_BLUE); - clearEOL(); - out << "ConsoleSession"; - setCursorLocation(2, 1); - setBackColor(BG_BLACK); status = LOGIN; - protocol((char*)""); + protocol(blank); break; - + case LOGIN: - setCursorLocation(3, 3); - out << "Enter User Profile: "; + out << "User: "; status = WAIT_USER_PROFILE; break; - + case WAIT_USER_PROFILE: status = PASSWORD; - protocol((char*)""); + protocol(blank); break; - + case PASSWORD: - setCursorLocation(4, 7); - out << "Enter Password: "; + out << "Password: "; status = WAIT_PASSWORD; break; - case WAIT_PASSWORD: - setBackColor(BG_BLACK); - clear(); - setCursorLocation(1, 1); - setBackColor(BG_BLUE); - clearEOL(); - out << "ConsoleSession"; - setCursorLocation(2, 1); - setBackColor(BG_BLACK); - scrollArea(2, 16); status = PROMPT; - protocol((char*)""); + protocol(blank); break; - + case PROMPT: - setCursorLocation(17, 1); - clearEOL(); - out << ("--> "); + out << (": "); status = INPUT; break; - + case INPUT: command = data; status = PROCESS; - protocol((char*)""); + protocol(blank); break; - + case PROCESS: doCommand(command); status = command.equals((char *)"exit") ? DONE: PROMPT; - protocol((char*)""); - break; - + protocol(blank); + break; + case DONE: out << "Done." << std::endl; break; - + default: out << "Unrecognized status code: ERROR."; break; } } - + void ConsoleSession::writeLog(std::string data) { saveCursor(); setCursorLocation(16, 1); restoreCursor(); } - - void ConsoleSession::doCommand(coreutils::ZString request) { - saveCursor(); - setCursorLocation(16, 1); - out << "--> " << request << std::endl; + + void ConsoleSession::doCommand(coreutils::ZString &request) { server.commands.processRequest(request, *this); - restoreCursor(); - } - + } + } diff --git a/ConsoleSession.h b/ConsoleSession.h index 330c178..18caef5 100644 --- a/ConsoleSession.h +++ b/ConsoleSession.h @@ -10,28 +10,28 @@ namespace core { /// /// ConsoleSession /// - /// Extends the session parameters for this TCPSocket derived object. + /// Extends the session parameters for this TCPSocket derived object. /// Extend the protocol() method in order to define the behavior and /// protocol interaction for this socket which is a console session. - /// + /// class ConsoleSession : public TerminalSession { - + public: ConsoleSession(EPoll &ePoll, TCPServer &server); - ~ConsoleSession(); - + ~ConsoleSession(); + void writeLog(std::string data); protected: - void protocol(coreutils::ZString data) override; - + void protocol(coreutils::ZString &data) override; + private: enum Status {WELCOME, LOGIN, WAIT_USER_PROFILE, PASSWORD, WAIT_PASSWORD, PROMPT, INPUT, PROCESS, DONE}; - Status status = WELCOME; - void doCommand(coreutils::ZString request); + Status status = WELCOME; + void doCommand(coreutils::ZString &request); coreutils::ZString command; - + }; } diff --git a/EPoll.cpp b/EPoll.cpp index 5cccb96..db7bad6 100644 --- a/EPoll.cpp +++ b/EPoll.cpp @@ -7,16 +7,14 @@ namespace core { EPoll::EPoll() : Command() { - coreutils::Log(coreutils::LOG_DEBUG_2) << "EPoll object being constructed."; + coreutils::Log(coreutils::LOG_DEBUG_2) << "EPoll starting."; maxSockets = 1000; epfd = epoll_create1(0); terminateThreads = false; } - EPoll::~EPoll() { - coreutils::Log(coreutils::LOG_DEBUG_2) << "BMAEPoll destructed."; - } + EPoll::~EPoll() {} bool EPoll::start(int numberOfThreads, int maxSockets) { @@ -69,13 +67,11 @@ namespace core { } bool EPoll::registerSocket(Socket *socket) { - coreutils::Log(coreutils::LOG_DEBUG_3) << "Registering socket " << socket->getDescriptor() << "."; enableSocket(socket); return true; } bool EPoll::unregisterSocket(Socket *socket) { - coreutils::Log(coreutils::LOG_DEBUG_3) << "Unregistering socket " << socket->getDescriptor() << "."; disableSocket(socket); return true; } @@ -95,7 +91,6 @@ namespace core { } void EPoll::enableSocket(Socket *socket) { - coreutils::Log(coreutils::LOG_DEBUG_4) << "Enabling socket " << socket->getDescriptor() << " for events."; struct epoll_event event; event.data.ptr = socket; event.events = EPOLLIN | EPOLLONESHOT | EPOLLRDHUP | EPOLLET; @@ -103,12 +98,10 @@ namespace core { } void EPoll::disableSocket(Socket *socket) { - coreutils::Log(coreutils::LOG_DEBUG_4) << "Disabling socket " << socket->getDescriptor() << " from events."; epoll_ctl(epfd, EPOLL_CTL_DEL, socket->getDescriptor(), NULL); } void EPoll::resetSocket(Socket *socket) { - coreutils::Log(coreutils::LOG_DEBUG_4) << "Resetting socket " << socket->getDescriptor() << " for read."; struct epoll_event event; event.data.ptr = socket; event.events = EPOLLIN | EPOLLONESHOT | EPOLLRDHUP | EPOLLET; diff --git a/INotify.cpp b/INotify.cpp index 1b4034e..da82e79 100644 --- a/INotify.cpp +++ b/INotify.cpp @@ -19,7 +19,7 @@ namespace core { inotify_rm_watch(getDescriptor(), wd); } - void INotify::onDataReceived(coreutils::ZString buffer) { + void INotify::onDataReceived(coreutils::ZString &buffer) { const struct inotify_event *event; char *ptr; for (ptr = buffer.getData(); ptr < buffer.getData() + buffer.getLength(); diff --git a/INotify.h b/INotify.h index a2e9650..b63abf9 100644 --- a/INotify.h +++ b/INotify.h @@ -15,7 +15,7 @@ namespace core { int addWatch(std::string watch); void removeWatch(int wd); - void onDataReceived(coreutils::ZString data) override; + void onDataReceived(coreutils::ZString &data) override; virtual void inAccess(std::string name) {} virtual void inAttrib(std::string name) {} diff --git a/Socket.cpp b/Socket.cpp index ca719e9..844185c 100644 --- a/Socket.cpp +++ b/Socket.cpp @@ -14,17 +14,17 @@ namespace core { Socket::~Socket() { free(buffer); if(descriptor == -1) - return; + return; onUnregister(); ePoll.unregisterSocket(this); coreutils::Log(coreutils::LOG_DEBUG_3) << "Socket destroyed for socket " << descriptor << "."; close(descriptor); } - + void Socket::setDescriptor(int descriptor) { if((descriptor == -1) && (errno == 24)) { - shutdown("Too many files open"); - coreutils::Exception("Too many files open. Refusing connection.");; + shutdown("Too many files open"); + throw coreutils::Exception("Too many files open. Refusing connection."); } lock.lock(); coreutils::Log(coreutils::LOG_DEBUG_3) << "Descriptor set to " << descriptor << " for Socket."; @@ -44,6 +44,7 @@ namespace core { void Socket::setBufferSize(int length) { this->length = length; buffer = (char *)realloc(buffer, length); + } int Socket::getBufferSize() { @@ -53,15 +54,15 @@ namespace core { void Socket::onRegister() {} void Socket::onRegistered() {} - + void Socket::onUnregister() {} void Socket::onUnregistered() {} - + bool Socket::eventReceived(struct epoll_event event) { - + lock.lock(); - + if(event.events & EPOLLRDHUP) { readHangup = true; shutdown("hangup received"); @@ -70,9 +71,10 @@ namespace core { } if(event.events & EPOLLIN) { - receiveData(buffer); + coreutils::ZString zbuffer(buffer, length); + receiveData(zbuffer); } - + if(event.events & EPOLLWRNORM) { writeSocket(); } @@ -85,90 +87,85 @@ namespace core { lock.unlock(); - reset = true; + reset = true; return reset; } - + void Socket::onDataReceived(std::string data) { throw coreutils::Exception("Need to override onDataReceived.", __FILE__, __LINE__, -1); } - - void Socket::onDataReceived(coreutils::ZString data) { - onDataReceived(std::string(data.getData(), data.getLength())); + + void Socket::onDataReceived(coreutils::ZString &data) { + onDataReceived(std::string(data.getData(), data.getLength())); } - - void Socket::receiveData(coreutils::ZString buffer) { - + + void Socket::receiveData(coreutils::ZString &buffer) { + if(buffer.getLength() <= 0) throw coreutils::Exception("Request to receive data with a zero buffer length.", __FILE__, __LINE__, -1); - + int len; int error = -1; - - if((len = ::read(getDescriptor(), buffer.getData(), buffer.getLength())) >= 0) { - onDataReceived(buffer); + + if((len = ::read(getDescriptor(), buffer.getData(), buffer.getLength())) >= 0) { + coreutils::ZString zbuffer(buffer.getData(), len); + onDataReceived(zbuffer); } else { - + error = errno; - + switch (error) { - - // When a listening socket receives a connection + + // When a listening socket receives a connection // request we get one of these. - // - case ENOTCONN: - onDataReceived(std::string(buffer.getData(), 0)); + // + case ENOTCONN: + onDataReceived(std::string(buffer.getData(), 0)); break; - case ECONNRESET: break; - + default: throw coreutils::Exception("Error in read of data from socket.", __FILE__, __LINE__, error); } } } - - void Socket::writeSocket() { + + void Socket::writeSocket() { if(fifo.size() > 0) { - outlock.lock(); - coreutils::Log(coreutils::LOG_DEBUG_3) << "Writing data to socket " << getDescriptor() << " [" << fifo.front() << "]."; + outlock.lock(); ::write(descriptor, fifo.front().c_str(), fifo.front().length()); fifo.pop(); - if(shutDown && !needsToWrite()) - delete this; - outlock.unlock(); + if(shutDown && !needsToWrite()) + delete this; + outlock.unlock(); } } - + int Socket::write(std::string data) { - coreutils::Log(coreutils::LOG_DEBUG_3) << "Writing data to socket " << getDescriptor() << " buffer [" << data << "]."; outlock.lock(); - fifo.emplace(data); - coreutils::Log(coreutils::LOG_DEBUG_4) << "Enabling write on socket " << getDescriptor() << " with " << fifo.size() << " entries to write."; + fifo.emplace(data); outlock.unlock(); ePoll.resetSocket(this); return 1; } - + void Socket::output(std::stringstream &out) { out << "|" << descriptor << "|"; } bool Socket::needsToWrite() { - coreutils::Log(coreutils::LOG_DEBUG_4) << "Socket " << getDescriptor() << " needs to write is " << (fifo.size() > 0) << "."; return fifo.size() > 0; - } - + } + void Socket::shutdown(std::string text) { coreutils::Log(coreutils::LOG_DEBUG_2) << "Shutdown requested on socket " << descriptor << " with reason " << text << "."; shutDown = true; reset = false; - if(!needsToWrite()) { - delete this; - } - + if(!needsToWrite()) + delete this; + } - + } diff --git a/Socket.h b/Socket.h index 87e799a..1a12608 100644 --- a/Socket.h +++ b/Socket.h @@ -13,41 +13,41 @@ namespace core { /// Socket /// /// The core component to managing a socket. - /// + /// /// Hooks into the EPoll through the registration and unregistration process and provides a /// communication socket of the specified protocol type. This object provides for all receiving /// data threading through use of the EPoll object and also provides buffering for output data - /// requests to the socket. + /// requests to the socket. /// /// A program using a socket object can request to open a socket (network or device) and - /// communicate through the streambuffer interface of the socket object. + /// communicate through the streambuffer interface of the socket object. /// /// The socket side of the Socket accepts EPOLLIN event and will maintain the data in a buffer - /// for the stream readers to read. A onDataReceived event is then sent with the data received in + /// for the stream readers to read. A onDataReceived event is then sent with the data received in /// the buffer that can be read through the stream. Only sockets that send events to epoll can be /// used with this object. /// /// When writing to the stream the data is written into a buffer and a EPOLLOUT is scheduled. Upon - /// receiving the EPOLLOUT event then the buffer is written to the socket output. + /// receiving the EPOLLOUT event then the buffer is written to the socket output. /// class Socket : public core::Object { - + public: /// /// Constructor /// - /// @param ePoll The EPoll socket descriptor. + /// @param ePoll The EPoll socket descriptor. /// @param text A title for this socket. /// - + Socket(EPoll &ePoll, std::string text = ""); /// /// Destructor /// - + ~Socket(); /// @@ -151,14 +151,14 @@ namespace core { /// /// - virtual void onDataReceived(coreutils::ZString data); + virtual void onDataReceived(coreutils::ZString &data); /// /// receiveData will read the data from the socket and place it in the socket buffer. /// TLS layer overrides this to be able to read from SSL. /// - virtual void receiveData(coreutils::ZString buffer); + virtual void receiveData(coreutils::ZString &buffer); private: diff --git a/TCPSession.cpp b/TCPSession.cpp index d52b09f..1b1b7fd 100644 --- a/TCPSession.cpp +++ b/TCPSession.cpp @@ -14,7 +14,7 @@ namespace core { data << "|" << ipAddress.getClientAddressAndPort(); } - void TCPSession::protocol(coreutils::ZString data) { + void TCPSession::protocol(coreutils::ZString &data) { if(!server.commands.processRequest(data, *this)) if(data.getLength() != 0) server.sessionErrorHandler("Invalid data received.", out); @@ -22,7 +22,8 @@ namespace core { void TCPSession::onRegistered() { onConnected(); - protocol(coreutils::ZString("")); + coreutils::ZString nothing(""); + protocol(nothing); send(); if(term) shutdown("termination requested"); @@ -30,50 +31,50 @@ namespace core { void TCPSession::onConnected() {} - void TCPSession::onDataReceived(coreutils::ZString data) { + void TCPSession::onDataReceived(coreutils::ZString &data) { if(data.getLength() > 0) { - lineBuffer = (char *)realloc(lineBuffer, lineBufferSize + data.getLength()); - memcpy(lineBuffer + lineBufferSize, data.getData(), data.getLength()); - lineBufferSize += data.getLength(); - while(lineBufferSize > 0) { - if(blockSize == 0) { - lineLength = strcspn(lineBuffer, "\r\n"); - if(lineLength == lineBufferSize) - break; - onLineReceived(coreutils::ZString(lineBuffer, lineLength)); - if(lineBuffer[lineLength] == '\r') - ++lineLength; - if(lineBuffer[lineLength] == '\n') - ++lineLength; - lineBufferSize -= lineLength; - if(lineBufferSize > 0) - memmove(lineBuffer, lineBuffer + lineLength, lineBufferSize); - lineBuffer = (char *)realloc(lineBuffer, lineBufferSize); - } else { - if(lineBufferSize >= blockLength) { - onBlockReceived(coreutils::ZString(lineBuffer, blockLength)); - lineBufferSize -= blockLength; - if(lineBufferSize > 0) - memmove(lineBuffer, lineBuffer + blockLength, lineBufferSize); - lineBuffer = (char *)realloc(lineBuffer, lineBufferSize); - } - } - } - } + lineBuffer = (char *)realloc(lineBuffer, lineBufferSize + data.getLength()); + memcpy(lineBuffer + lineBufferSize, data.getData(), data.getLength()); + lineBufferSize += data.getLength(); + while(lineBufferSize > 0) { + if(blockSize == 0) { + lineLength = strcspn(lineBuffer, "\r\n"); + if(lineLength == lineBufferSize) + break; + coreutils::ZString zLine(lineBuffer, lineLength); + onLineReceived(zLine); + if(lineBuffer[lineLength] == '\r') + ++lineLength; + if(lineBuffer[lineLength] == '\n') + ++lineLength; + lineBufferSize -= lineLength; + if(lineBufferSize > 0) + memmove(lineBuffer, lineBuffer + lineLength, lineBufferSize); + lineBuffer = (char *)realloc(lineBuffer, lineBufferSize); + } else if(lineBufferSize >= blockLength) { + coreutils::ZString zBlock(lineBuffer, blockLength); + onBlockReceived(zBlock); + lineBufferSize -= blockLength; + if(lineBufferSize > 0) + memmove(lineBuffer, lineBuffer + blockLength, lineBufferSize); + lineBuffer = (char *)realloc(lineBuffer, lineBufferSize); + } + } + } } - + void TCPSession::setBlockSize(int blockSize) { this->blockSize = blockSize; } - - void TCPSession::onLineReceived(coreutils::ZString line) { + + void TCPSession::onLineReceived(coreutils::ZString &line) { protocol(line); send(); if(term) shutdown("termination requested"); } - void TCPSession::onBlockReceived(coreutils::ZString block) { + void TCPSession::onBlockReceived(coreutils::ZString &block) { coreutils::Log(coreutils::LOG_DEBUG_3) << "[" << block.getLength() << "]"; if(term) shutdown("termination requested"); diff --git a/TCPSession.h b/TCPSession.h index b0e7be4..aee1db8 100644 --- a/TCPSession.h +++ b/TCPSession.h @@ -79,7 +79,7 @@ namespace core { /// received. If you need data split by line termination characters then /// override the onLineReceived method instead. /// - virtual void onDataReceived(coreutils::ZString data) override; + virtual void onDataReceived(coreutils::ZString &data) override; /// /// Override the onLineReceived method to receive a string of characters that @@ -88,7 +88,7 @@ namespace core { /// this method explicitly using the class and member name. /// - virtual void onLineReceived(coreutils::ZString line); + virtual void onLineReceived(coreutils::ZString &line); /// /// Override the onBlockReceived method to receive a string of characters that @@ -97,7 +97,7 @@ namespace core { /// calls this method explicitly using the class and member name. /// - virtual void onBlockReceived(coreutils::ZString block); + virtual void onBlockReceived(coreutils::ZString &block); /// /// This method is called from within the protocol method when protocol is called @@ -117,7 +117,7 @@ namespace core { /// data through the protocol method: LINE or BLOCK. /// - virtual void protocol(coreutils::ZString data); + virtual void protocol(coreutils::ZString &data); /// /// Use setBlockSize to set the amount of data that should be read at once from the diff --git a/TCPSocket.cpp b/TCPSocket.cpp index 3ac3606..3345032 100644 --- a/TCPSocket.cpp +++ b/TCPSocket.cpp @@ -4,23 +4,22 @@ #include "Exception.h" namespace core { - + TCPSocket::TCPSocket(EPoll &ePoll) : Socket(ePoll) {} TCPSocket::TCPSocket(EPoll &ePoll, std::string text) : Socket(ePoll, text) {} - + TCPSocket::~TCPSocket() {} - + void TCPSocket::connect(IPAddress &address) { setDescriptor(socket(AF_INET, SOCK_STREAM, 0)); - if(::connect(getDescriptor(), (struct sockaddr *)&address.addr, address.addressLength) == -1) - throw coreutils::Exception("Error on connect to TCP socket."); - + if(::connect(getDescriptor(), (struct sockaddr *)&address.addr, address.addressLength) == -1) + throw coreutils::Exception("Error on connect to TCP socket."); } - + void TCPSocket::output(std::stringstream &out) { - out << "|" << ipAddress.getClientAddressAndPort(); + out << "|" << ipAddress.getClientAddressAndPort(); } - + } diff --git a/TLSSession.cpp b/TLSSession.cpp index 52094e0..54e0a8a 100644 --- a/TLSSession.cpp +++ b/TLSSession.cpp @@ -80,9 +80,9 @@ namespace core { TLSSession::~TLSSession() {} - void TLSSession::protocol(coreutils::ZString data) {} + void TLSSession::protocol(coreutils::ZString &data) {} - void TLSSession::receiveData(coreutils::ZString buffer) { + void TLSSession::receiveData(coreutils::ZString &buffer) { int len; // int error = -1; diff --git a/TLSSession.h b/TLSSession.h index 715d34e..741a0f7 100644 --- a/TLSSession.h +++ b/TLSSession.h @@ -35,10 +35,10 @@ namespace core { /// virtual void output(std::stringstream &out); - virtual void protocol(coreutils::ZString data) override; + virtual void protocol(coreutils::ZString &data) override; protected: - void receiveData(coreutils::ZString buffer) override; + void receiveData(coreutils::ZString &buffer) override; void onRegister(); void onRegistered(); diff --git a/compile b/compile index a07a0ec..2864623 100755 --- a/compile +++ b/compile @@ -5,7 +5,7 @@ do filename="${file%.*}" list="$list $filename.o" echo -n "Compiling $filename..." - g++ -g -c -I../CoreUtils $file + g++ -g -c -I../CoreUtils $file & if [ $? = '0' ] then echo "OK"