Select Git revision
main.cpp 4.55 KiB
/*
* File: main.cpp
* Author: Eckl, Máté<ecklm94@gmail.com>
*
* Created on 2016. április 19., 12:59
*/
#include <string.h>
#include <string>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <pwd.h>
#include <signal.h>
#include "include/general_sockaddr_wp.h"
#include "include/dns_server.h"
#include "include/exceptions/db_exception.h"
#include "include/logger.h"
#include "include/IPC_US_communicator.h"
#include "include/command.h"
#define WORKING_DIR "/home/mate/Dokumentumok/Egyetem/Tárgyak/2016 tavasz/Linux programozás/HF/DNS_server"
#define COMM_SOCK_PATH "/var/run/ecklm-dns/"
logger log_on_demand;
bool verbose = false;
void kill_handler(int);
void print_help();
int main(int argc, char *argv[])
{
int cli_option;
bool run_as_daemon = false;
std::vector<command> command_list;
while((cli_option = getopt (argc, argv, "dmskvh")) != -1)
{
switch(cli_option)
{
case 'd':
run_as_daemon = true;
break;
case 'm':
command_list.push_back(MONITOR);
break;
case 's':
command_list.push_back(STATISTICS);
break;
case 'k':
command_list.push_back(KILL);
break;
case 'v':
verbose = true;
break;
case 'h':
print_help();
exit(EXIT_SUCCESS);
case '?':
print_help();
exit(EXIT_FAILURE);
break;
default:
break;
}
}
if(!run_as_daemon)
{
log_on_demand = stdlog_on_demand;
}
else
{
openlog("ecklm-dns", LOG_PID, LOG_DAEMON);
log_on_demand = syslog_on_demand;
#ifdef DEBUG // ezt az egész mókát parancssori paraméterektől kell majd függővé tenni
if(daemon(0,1) < 0)
#else
if(daemon(0,0) < 0)
#endif
{
PERROR_ON_DEMAND("daemon");
exit(EXIT_FAILURE);
}
}
if(getuid() != 0)
{
log_on_demand(LOG_ERR, "You should run with root privileges!");
exit(EXIT_FAILURE);
}
log_on_demand(LOG_INFO, "Server started on pid %d", getpid()); // Enélkül nem hajlandó sudo után logolni.
struct passwd *new_uid = getpwnam("dnsuser");
if(chroot(WORKING_DIR) < 0)
{
PERROR_ON_DEMAND("chroot");
exit(EXIT_SUCCESS);
}
log_on_demand(LOG_INFO, "Chrooted to \"%s\"", WORKING_DIR);
if(chdir("/") < 0)
{
PERROR_ON_DEMAND("chdir");
exit(EXIT_FAILURE);
}
setgid(new_uid->pw_gid);
setuid(new_uid->pw_uid);
IPC_US_communicator comm_link(COMM_SOCK_PATH, run_as_daemon);
if(!run_as_daemon)
{
if(command_list.empty())
{
log_on_demand(LOG_ERR, "In this mode you must specify at least one command!");
exit(EXIT_FAILURE);
}
for(command c : command_list)
{
comm_link.send_data(get_readable_command(c));
log_on_demand(LOG_INFO, "Answer received: %s", comm_link.recv_data().c_str());
}
exit(EXIT_SUCCESS);
}
struct sigaction killer;
sigemptyset(&killer.sa_mask);
killer.sa_flags = 0;
killer.sa_handler = kill_handler;
killer.sa_restorer = NULL;
if(sigaction(SIGTERM, &killer, NULL) < 0)
{
PERROR_ON_DEMAND("sigaction");
exit(EXIT_FAILURE);
}
// --------------- INIT ---------------------
dns_server server;
try
{
server.connect_db("dns.db");
}
catch(db_exception ex)
{
log_on_demand(LOG_ERR, ex.what());
exit(EXIT_FAILURE);
}
// Init server
struct in6_addr in6_addr_any = IN6ADDR_ANY_INIT; //IN6ADDR_LOOPBACK_INIT;
struct sockaddr_in6 server_address;
memset(&server_address, 0, sizeof(server_address));
server_address.sin6_family = AF_INET6;
server_address.sin6_addr = in6_addr_any;
server_address.sin6_port = htons(10053);
server.init(general_sockaddr_wp((sockaddr *) &server_address, sizeof(server_address)));
if(verbose)
{
static char addr[INET6_ADDRSTRLEN];
inet_ntop(server_address.sin6_family, &server_address.sin6_addr, addr, INET6_ADDRSTRLEN);
log_on_demand(LOG_DEBUG, "Server started serving on: %s",addr);
}
// ----------------- INIT END --------------------------
// ------------------ SERVE ----------------------------
while(true)
{
server.serve_one_request();
if(comm_link.recv_data() == "kill")
{
comm_link.send_data("go to hell!");
log_on_demand(LOG_DEBUG, "Raising SIGTERM");
raise(SIGTERM);
}
else
comm_link.send_data("nothing has happened");
}
// ---------------- SERVE END -------------------------
// ------------------- SHUTDOWN -------------------------
server.shutdown();
// ----------------- SHUTDOWN END -----------------------
exit(EXIT_SUCCESS);
}
void print_help() {
printf(R"(Usage: Runs in foreground mode by default.
For more info look at the man page.
Options:
-d Run as daemon
-m Monitor daemon
-s Statistics from daemon
-k Kill daemon
-v Verbose
-h help
)");
}
void kill_handler(int x) {
log_on_demand(LOG_INFO, "SIGTERM received");
exit(EXIT_SUCCESS);
}