An IRC server written in C++98 using TCP sockets and poll(2) (42 school project).
This repository contains:
mandatory/— the IRC server (ircserv)bonus/— a simple IRC bot (Bot) that can reply with quotes
- Multiple clients handled with a single-threaded event loop (
poll) - Basic IRC registration flow (
PASS,NICK,USER) - Channels and messaging (
JOIN,PRIVMSG) - Channel moderation & management (
KICK,TOPIC,MODE,INVITE) - Graceful shutdown handling (SIGINT / SIGTERM)
- Bonus: bot that connects to the server and responds to
!quote
c++compiler with C++98 supportmake- An IRC client (recommended):
irssi,weechat,hexchat - Or
nc/telnetfor quick manual testing
cd mandatory
makeBinary output:
mandatory/ircserv
cd bonus
makeBinary output:
bonus/Bot
From mandatory/:
./ircserv <port><password>Example:
./ircserv 6667 secretNotes:
- Port must be between 1 and 65535.
- Password must be non-empty.
Using irssi (example):
/connect 127.0.0.1 6667 secret
/nick mynick
/user myuser 0 * :Real Name
/join #general
Quick connectivity test:
nc 127.0.0.1 6667The server reads commands line-by-line and accepts both \r\n and \n as line endings.
Recognized commands:
PASSNICKUSERJOINPRIVMSGKICKTOPICMODEINVITE
Unknown commands return:
421 <nick> <command> :Unknown command.
Clients must authenticate first, then register.
Authenticate using the server password (the one passed to ./ircserv <port> <password>).
- Must be called before registration.
- If the password is wrong, authentication fails.
Example:
PASS secret
Set (or change) your nickname.
Rules implemented:
- Requires authentication (
PASS) first; otherwise you getERR_NOTREGISTERED. - Nickname cannot start with:
#,:, space, or a digit. - Nickname must be unique.
Example:
NICK aragragu
If you change nick after being registered, the nick change is broadcast.
Set your username and real name and complete registration.
Rules implemented:
- Requires authentication (
PASS) first. - Refused if already registered.
- Realname can contain spaces when prefixed by
:.
Example:
USER aragragu 0 * :Anas Rag
Join one or more channels. Channels are comma-separated; passwords (if needed) can also be comma-separated.
Checks implemented:
- You must be registered.
- Channel name must start with
#and not be just#. - If channel is invite-only (
+i), you must have been invited. - If channel has a key (
+k), you must provide the correct password. - If channel has a user limit (
+l), you cannot join if it is full.
Examples:
JOIN #general
JOIN #private mykey
JOIN #chan1,#chan2 pass1,pass2
When you join, the server sends JOIN + topic info (or “No topic is set”) and a names-style list (operators are prefixed with @ in that listing).
Send a private message to a user or a channel.
Rules implemented:
- You must be registered.
- You must provide a target and a message.
- If target is a channel, you must be a member of that channel; otherwise you get
ERR_CANNOTSENDTOCHAN.
Examples:
PRIVMSG aragragu :hello!
PRIVMSG #general :hi everyone
Kick one or multiple users from a channel.
Rules implemented:
- You must be registered.
- You must be in the channel.
- You must be a channel operator to kick.
- The target user(s) must exist and be in the channel.
Examples:
KICK #general bob
KICK #general bob :spamming
KICK #general bob,alice :cleanup
If the channel becomes empty after removals, it is deleted.
Get or set the topic of a channel.
Rules implemented:
- Getting the topic:
TOPIC #general - Setting the topic:
- requires you to be registered
- requires you to be in the channel
- if the channel has
+tenabled, only channel operators can change the topic
Examples:
TOPIC #general :Welcome to #general
TOPIC #general
Invite a user to a channel.
Rules implemented:
- You must be registered.
- The target nick must exist.
- The channel must exist.
- You must be a member of the channel.
- If the channel is invite-only (
+i), you must be a channel operator to invite. - You cannot invite a user already in the channel.
Example:
INVITE bob #private
Query or set channel modes.
MODE #general
The server replies with a 324 numeric containing a mode string like:
+iinvite-only+ttopic restricted to operators+kkey/password set+luser limit set
Only channel operators can change modes.
Supported flags (as implemented):
+i/-i— invite-only+t/-t— only operators can change topic+k <key>/-k— set/unset channel key+krequires a parameter- if a key is already set, it returns an error
+l <limit>/-l— set/unset user limit+lrequires a numeric limit > 0
+o <nick>/-o <nick>— give/remove operator- target must exist and be in the channel
Examples:
MODE #general +i
MODE #general +t
MODE #general +k supersecret
MODE #general -k
MODE #general +l 10
MODE #general -l
MODE #general +o bob
MODE #general -o bob
When a mode change is applied, the server broadcasts:
:<setterNick> MODE #channel <modes> [params...]
to all channel members.
The bot connects to the server, registers, and joins #general automatically.
Build:
cd bonus && makeRun:
./Bot <server_ip><port><password>Example:
./Bot 127.0.0.1 6667 secretIn #general, type:
!quote!quote programming!quote music!quote adventure!quote life
.
├── mandatory/
│ ├── Makefile
│ ├── main.cpp
│ ├── Server.*
│ ├── Client.*
│ ├── channel.*
│ └── (handlers: Join/Pass/Nick/User/Privmsg/Kick/Topic/Mode/Invite/...)
└── bonus/
├── Makefile
└── Bot.*
Both mandatory/Makefile and bonus/Makefile provide:
make
make clean
make fclean
make reNo license file is included in this repository.