Introduce CLI
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
This commit is contained in:
77
cliserver.cpp
Normal file
77
cliserver.cpp
Normal file
@ -0,0 +1,77 @@
|
||||
#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;
|
||||
}
|
مرجع در شماره جدید
Block a user