Skip to content

Commit

Permalink
Initial commit, version 1.0
Browse files Browse the repository at this point in the history
Signed-off-by: Adrian 'nex' Schollmeyer <[email protected]>
  • Loading branch information
NexAdn committed Oct 17, 2021
0 parents commit d251a64
Show file tree
Hide file tree
Showing 12 changed files with 654 additions and 0 deletions.
72 changes: 72 additions & 0 deletions .clang-format
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
BasedOnStyle: LLVM # LLVM, Google, Chromium, Mozilla, WebKit
AccessModifierOffset: -4
AlignEscapedNewlinesLeft: true
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: false # None(false), Inline, All(true)
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: false
AlwaysBreakBeforeMultilineStrings: true
AlwaysBreakTemplateDeclarations: true
BinPackParameters: true
BreakBeforeBinaryOperators: NonAssignment # None, NonAssignment, All
BreakBeforeBraces: Custom # Attach, Linux, Stroustrup, Custom, GNU
BraceWrapping:
AfterClass: true
AfterControlStatement: false
AfterEnum: true
AfterFunction: true
AfterNamespace: true
AfterStruct: true
AfterUnion: true
AfterExternBlock: false
BeforeCatch: true
BeforeElse: false
IndentBraces: false
SplitEmptyFunction: false
SplitEmptyNamespace: true
BreakBeforeTernaryOperators: false
BreakConstructorInitializersBeforeComma: true
ColumnLimit: 80
# CommentPragmas
ConstructorInitializerAllOnOneLineOrOnePerLine: true
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 2
Cpp11BracedListStyle: true
DerivePointerAlignment: false
DisableFormat: false
ExperimentalAutoDetectBinPacking: true
# ForEachMacros
IndentCaseLabels: false
IndentWidth: 4
IndentWrappedFunctionNames: false
KeepEmptyLinesAtTheStartOfBlocks: false
Language: Cpp # None, Cpp, JavaScript, Proto
MaxEmptyLinesToKeep: 1
NamespaceIndentation: Inner # None, Inner, All
# ObjCSpaceAfterProperty
# ObjCSpaceBeforeProtocolList
#// PenaltyBreakBeforeFirstCallParameter
#// PenaltyBreakComment
#// PenaltyBreakFirstLessLess
#// PenaltyBreakString
#// PenaltyExcessCharacter
#// PenaltyReturnTypeOnItsOwnLine:
PointerAlignment: Left # Left, Right, Middle
SpaceAfterCStyleCast: true
SpaceBeforeAssignmentOperators: true
SpaceBeforeParens: ControlStatements # Never, ControlStatements, Always
# SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false
SpacesInCStyleCastParentheses: false
SpacesInContainerLiterals: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Cpp11 # Cpp03, Cpp11, Auto
TabWidth: 4
UseTab: ForIndentation # Never(false), ForIndentation, Always(true)
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
build/
compile_commands.json
Release/
6 changes: 6 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
cmake_minimum_required(VERSION 3.0)
project(fakeirc LANGUAGES CXX VERSION 1.0)

set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wall -Werror")

add_subdirectory(src)
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# fakeIRC – a simple IRC-like server to use with netcat

fakeIRC is a simple IRC-like server, implementing a very limited protocol to be used to show participants in a workshop how they can chat using simple tools like netcat.

## Requirements

* Build:
* CMake
* a C++ compiler
* Linux
* Runtime:
* Linux
* a network to chat on


14 changes: 14 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#add_libary(fakeirc-common STATIC
#)

add_executable(fakeirc
main.cpp
vprint.cpp
ConnectionHandler.cpp
ClientHandler.cpp
)
target_compile_features(fakeirc
PUBLIC
cxx_std_17
)

166 changes: 166 additions & 0 deletions src/ClientHandler.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
#include <array>
#include <cstring>
#include <iostream>
#include <string_view>

#include <unistd.h>

#include "ClientHandler.hpp"
#include "ConnectionHandler.hpp"
#include "vprint.hpp"

namespace
{
constexpr size_t READ_BUF_SIZE{4096};

constexpr std::array<const char*, 55> RICKROLL{
"We're no strangers to love",
"You know the rules and so do I",
"A full commitment's what I'm thinking of",
"You wouldn't get this from any other guy",
"I just wanna tell you how I'm feeling",
"Gotta make you understand",
"Never gonna give you up",
"Never gonna let you down",
"Never gonna run around and desert you",
"Never gonna make you cry",
"Never gonna say goodbye",
"Never gonna tell a lie and hurt you",
"We've known each other for so long",
"Your heart's been aching but you're too shy to say it",
"Inside we both know what's been going on",
"We know the game and we're gonna play it",
"And if you ask me how I'm feeling",
"Don't tell me you're too blind to see",
"Never gonna give you up",
"Never gonna let you down",
"Never gonna run around and desert you",
"Never gonna make you cry",
"Never gonna say goodbye",
"Never gonna tell a lie and hurt you",
"Never gonna give you up",
"Never gonna let you down",
"Never gonna run around and desert you",
"Never gonna make you cry",
"Never gonna say goodbye",
"Never gonna tell a lie and hurt you",
"Never gonna give, never gonna give",
"(Give you up)",
"We've known each other for so long",
"Your heart's been aching but you're too shy to say it",
"Inside we both know what's been going on",
"We know the game and we're gonna play it",
"I just wanna tell you how I'm feeling",
"Gotta make you understand",
"Never gonna give you up",
"Never gonna let you down",
"Never gonna run around and desert you",
"Never gonna make you cry",
"Never gonna say goodbye",
"Never gonna tell a lie and hurt you",
"Never gonna give you up",
"Never gonna let you down",
"Never gonna run around and desert you",
"Never gonna make you cry",
"Never gonna say goodbye",
"Never gonna tell a lie and hurt you",
"Never gonna give you up",
"Never gonna let you down",
"Never gonna run around and desert you",
"Never gonna make you cry",
"Never gonna say goodbye"};

bool is_command(std::string_view cmd, std::string_view cmdline)
{
return cmdline.substr(0, cmd.length()) == cmd;
}
} // namespace

void ClientHandler::send_motd() const
{
vprint("Sending MOTD\n");
send_message(motd);
}

void ClientHandler::send_join_announcement() const
{
conn_hdl.broadcast_message("* " + nick + " entered the chat");
}

void ClientHandler::send_message(const std::string& message) const
{
vprint("Sending message:\n", message);
ssize_t res = write(sockfd, message.c_str(), message.length());
size_t ures = static_cast<size_t>(res);

if (res < 0) {
std::clog << "Write error: " << strerror(errno) << '\n';
}

if (ures < message.length()) {
res = write(sockfd, message.c_str() + res, message.length() - res);
ures = static_cast<size_t>(res);
if (res < 0) {
std::clog << "Write error: " << strerror(errno) << '\n';
} else if (ures < message.length() - res) {
std::cout << "Partial write!\n";
}
}
}

void ClientHandler::read_messages()
{
vprint("reading\n");
char read_buf[READ_BUF_SIZE];

ssize_t res = read(sockfd, read_buf, READ_BUF_SIZE);

if (res < 0) {
std::clog << "Read error: " << strerror(errno) << '\n';
return;
}

for (ssize_t i = 0; i < res; ++i) {
if (read_buf[i] == '\n') {
input_line = input_buffer.str();
input_buffer.str("");
input_buffer.clear();
process_input_line();
} else {
input_buffer << read_buf[i];
}
}
}

void ClientHandler::close() const
{
conn_hdl.broadcast_message("* " + nick + " disconnected");
::close(sockfd);
}

void ClientHandler::process_input_line()
{
vprint("Processing input line...\n");
if (input_line.length() == 0)
return;
if (input_line.at(0) == '/' && input_line.length() > 1) {
std::string_view cmdline = std::string_view{input_line}.substr(1);
vprint("Received command: ", cmdline, "\n");

if (is_command("nick ", cmdline)) {
std::string old_nick = std::move(nick);
nick = cmdline.substr(std::string_view{"nick "}.length());
conn_hdl.broadcast_message("* " + old_nick + " is now known as "
+ nick);
} else if (is_command("rick", cmdline)) {
for (const char* msg : RICKROLL)
conn_hdl.broadcast_message(std::string{"* "} + msg);
} else {
send_message("Invalid command line: " + std::string{cmdline}
+ "\n");
}
} else {
vprint("Received message: ", input_line, "\n");
conn_hdl.broadcast_message("<" + nick + "> " + input_line);
}
}
41 changes: 41 additions & 0 deletions src/ClientHandler.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#pragma once

#include <sstream>
#include <string>

#include <netinet/in.h>

class ConnectionHandler;

class ClientHandler
{
public:
ClientHandler(ConnectionHandler& conn_hdl, int sockfd, std::string& motd,
std::string_view initial_nick)
: conn_hdl(conn_hdl), sockfd(sockfd), motd(motd), nick(initial_nick)
{}
ClientHandler(const ClientHandler& other) = delete;
ClientHandler(ClientHandler&&) = default;
~ClientHandler() = default;

void send_motd() const;
void send_join_announcement() const;

void read_messages();

void send_message(const std::string& message) const;

void close() const;

private:
void process_input_line();

ConnectionHandler& conn_hdl;
int sockfd;
std::string& motd;

std::stringstream input_buffer;
std::string input_line;

std::string nick;
};
Loading

0 comments on commit d251a64

Please sign in to comment.