Albert S
3d0fce590b
main: Parse args using getopt_long() in main(). Begin implementation of a CLI. It can be launched using ./qswiki config --cli. Allow connecting to another instance using "attach" command. This uses Unix domain sockets, and in the future can be used to drop caches, reload template, etc. Closes: #21
78 rindas
1.7 KiB
C++
78 rindas
1.7 KiB
C++
#include <sys/socket.h>
|
|
#include <sys/un.h>
|
|
#include <unistd.h>
|
|
#include "cliserver.h"
|
|
#include "logger.h"
|
|
CLIServer::CLIServer(CLIHandler &handler)
|
|
{
|
|
this->handler = &handler;
|
|
}
|
|
|
|
bool CLIServer::detachServer(std::string socketpath)
|
|
{
|
|
struct sockaddr_un name;
|
|
const int max_socket_length = sizeof(name.sun_path) - 1;
|
|
if(socketpath.size() > max_socket_length)
|
|
{
|
|
perror("socket path too long");
|
|
return false;
|
|
}
|
|
int s = socket(AF_UNIX, SOCK_DGRAM, 0);
|
|
if(s == -1)
|
|
{
|
|
perror("socket");
|
|
return false;
|
|
}
|
|
|
|
memset(&name, 0, sizeof(name));
|
|
name.sun_family = AF_UNIX;
|
|
memcpy(&name.sun_path, socketpath.c_str(), socketpath.size());
|
|
|
|
unlink(socketpath.c_str());
|
|
int ret = bind(s, (const struct sockaddr *)&name, sizeof(name));
|
|
if(ret == -1)
|
|
{
|
|
perror("bind");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
auto worker = [=]
|
|
{
|
|
while(true)
|
|
{
|
|
char buffer[1024] = {0};
|
|
struct sockaddr_un peer;
|
|
socklen_t peerlen = sizeof(peer);
|
|
|
|
int ret = recvfrom(s, buffer, sizeof(buffer) - 1, 0, (struct sockaddr *)&peer, &peerlen);
|
|
if(ret == -1)
|
|
{
|
|
Logger::error() << "Error during recvfrom in CLI server: " << strerror(errno);
|
|
return false;
|
|
}
|
|
|
|
std::string input{buffer};
|
|
|
|
auto pair = CLIHandler::splitCommand(input);
|
|
|
|
auto result = handler->processCommand(pair.first, pair.second);
|
|
char resultCode = '0';
|
|
if(result.first)
|
|
{
|
|
resultCode = '1';
|
|
}
|
|
std::string resultString;
|
|
resultString += resultCode;
|
|
resultString += result.second;
|
|
ret = sendto(s, resultString.c_str(), resultString.size(), 0, (struct sockaddr *)&peer, peerlen);
|
|
if(ret == -1)
|
|
{
|
|
Logger::error() << "Error during sendto in CLI server: " << strerror(errno);
|
|
}
|
|
}
|
|
};
|
|
std::thread t1{worker};
|
|
t1.detach();
|
|
return true;
|
|
}
|