78 baris
		
	
	
		
			1.7 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			78 baris
		
	
	
		
			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 = [this, s]
 | |
| 	{
 | |
| 		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;
 | |
| }
 |