#include "Server.hpp" bool Server::_signal = false; Server::Server() {} Server::~Server() {} void Server::parseArgs(int ac, char **av) { if (ac != 3) throw std::runtime_error("Usage: ./ircserv "); std::string port(av[1]); std::string pwd(av[2]); if (port.empty() || port.find_first_not_of("0123456789") != std::string::npos) throw std::runtime_error("Error: Invalid arguments"); long _port = atol(av[1]); if (!(_port >= 1 && _port <= 65535)) throw std::runtime_error("Error: Invalid arguments"); if (pwd.empty()) throw std::runtime_error("Error: Invalid arguments"); this->_port = _port; this->_password = pwd; } void Server::receiveSignal(int signum) { _signal = true; (void)signum; } void Server::init() { signal(SIGINT, receiveSignal); signal(SIGQUIT, receiveSignal); createServerSocket(); std::cout << ">>> SERVER STARTED <<<" << std::endl; std::cout << "Waiting for connections..." << std::endl; } void Server::run() { while (!_signal) { int ret = poll(&_fds[0], _fds.size(), -1); if (ret == -1) throw std::runtime_error("Error: poll() failed"); for (size_t i = 0; i < _fds.size(); ++i) { if (_fds[i].revents & POLLIN) { if (_fds[i].fd == _serverSocketFd) // handle new client connection here continue; else // handle existing client incoming data here continue; } } } } void Server::createServerSocket() { _serverSocketFd = socket(AF_INET, SOCK_STREAM, 0); if (_serverSocketFd == -1) throw std::runtime_error("Error: failed to create socket"); int optval = 1; if (setsockopt(_serverSocketFd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) == -1) throw std::runtime_error("Error: setsockopt() failed"); if (fcntl(_serverSocketFd, F_SETFL, O_NONBLOCK) == -1) throw std::runtime_error("Error: fcntl() failed"); bindServerSocket(); if (listen(_serverSocketFd, SOMAXCONN) == -1) throw std::runtime_error("Error: listen() failed"); addPollfd(_serverSocketFd, POLLIN, 0); } void Server::bindServerSocket() { struct sockaddr_in sa; sa.sin_family = AF_INET; sa.sin_port = htons(_port); sa.sin_addr.s_addr = INADDR_ANY; if (bind(_serverSocketFd, (struct sockaddr*)&sa, sizeof(sa)) == -1) { throw std::runtime_error("Error: failed to bind socket"); } } void Server::addPollfd(int fd, short events, short revents) { struct pollfd newPollfd; newPollfd.fd = fd; newPollfd.events = events; newPollfd.revents = revents; _fds.push_back(newPollfd); }