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:
		
							
								
								
									
										61
									
								
								qswiki.cpp
									
									
									
									
									
								
							
							
						
						
									
										61
									
								
								qswiki.cpp
									
									
									
									
									
								
							| @@ -25,6 +25,7 @@ SOFTWARE. | ||||
| #include <unistd.h> | ||||
| #include <sys/types.h> | ||||
| #include <filesystem> | ||||
| #include <getopt.h> | ||||
| #include "gateway/gatewayinterface.h" | ||||
| #include "gateway/gatewayfactory.h" | ||||
| #include "handlers/handlerfactory.h" | ||||
| @@ -37,6 +38,10 @@ SOFTWARE. | ||||
| #include "requestworker.h" | ||||
| #include "cache/fscache.h" | ||||
| #include "sandbox/sandboxfactory.h" | ||||
| #include "cli.h" | ||||
| #include "cliconsole.h" | ||||
| #include "cliserver.h" | ||||
|  | ||||
| void sigterm_handler(int arg) | ||||
| { | ||||
| 	// TODO: proper shutdown. | ||||
| @@ -56,6 +61,10 @@ void setup_signal_handlers() | ||||
| 	} | ||||
| } | ||||
|  | ||||
| #define OPT_PRINT_VERSION 23 | ||||
|  | ||||
| static struct option long_options[] = {{"cli", no_argument, 0, 'c'}, {"version", no_argument, 0, OPT_PRINT_VERSION}}; | ||||
|  | ||||
| std::unique_ptr<ICache> createCache(const ConfigVariableResolver &resolver) | ||||
| { | ||||
|  | ||||
| @@ -63,13 +72,48 @@ std::unique_ptr<ICache> createCache(const ConfigVariableResolver &resolver) | ||||
|  | ||||
| 	return std::make_unique<FsCache>(path); | ||||
| } | ||||
|  | ||||
| std::string get_version_string() | ||||
| { | ||||
| 	return "master"; | ||||
| } | ||||
|  | ||||
| int main(int argc, char **argv) | ||||
| { | ||||
|  | ||||
| 	char *configfilepath = NULL; | ||||
| 	int option; | ||||
| 	int option_index; | ||||
| 	bool cli_mode = false; | ||||
|  | ||||
| 	if(geteuid() == 0) | ||||
| 	{ | ||||
| 		std::cerr << "Do not run this as root!" << std::endl; | ||||
| 		return 1; | ||||
| 	} | ||||
|  | ||||
| 	while((option = getopt_long(argc, argv, "cv", long_options, &option_index)) != -1) | ||||
| 	{ | ||||
| 		switch(option) | ||||
| 		{ | ||||
| 		case 'c': | ||||
| 			cli_mode = true; | ||||
| 			break; | ||||
| 		case OPT_PRINT_VERSION: | ||||
| 			std::cout << get_version_string() << std::endl; | ||||
| 			exit(EXIT_SUCCESS); | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if(optind == argc) | ||||
| 	{ | ||||
| 		std::cerr << "Missing config path" << std::endl; | ||||
| 		return 1; | ||||
| 	} | ||||
|  | ||||
| 	configfilepath = argv[optind++]; | ||||
|  | ||||
| 	auto sandbox = createSandbox(); | ||||
| 	// TODO: do we want to keep it mandatory or configurable? | ||||
| 	if(!sandbox->supported()) | ||||
| @@ -82,7 +126,7 @@ int main(int argc, char **argv) | ||||
| 		std::cerr << "no path to config file provided" << std::endl; | ||||
| 		return 1; | ||||
| 	} | ||||
| 	std::string configpath = std::filesystem::absolute(argv[1]).string(); | ||||
| 	std::string configpath = std::filesystem::absolute(configfilepath).string(); | ||||
| 	if(!sandbox->enableForInit()) | ||||
| 	{ | ||||
| 		Logger::error() << "Sandboxing for init mode could not be activated."; | ||||
| @@ -113,6 +157,21 @@ int main(int argc, char **argv) | ||||
| 		Logger::setStream(&logstream); | ||||
|  | ||||
| 		auto database = createDatabase(config); | ||||
| 		std::string socketPath = config.configVarResolver.getConfig("socketpath"); | ||||
| 		CLIHandler cliHandler(config, *database); | ||||
|  | ||||
| 		if(cli_mode) | ||||
| 		{ | ||||
| 			CLIConsole console{cliHandler, socketPath}; | ||||
| 			console.startInteractive(); | ||||
| 			return 0; | ||||
| 		} | ||||
| 		CLIServer cliServer{cliHandler}; | ||||
| 		if(!cliServer.detachServer(socketPath)) | ||||
| 		{ | ||||
| 			Logger::error() << "Error: Failed to detach unix socket server"; | ||||
| 			return 1; | ||||
| 		} | ||||
|  | ||||
| 		// TODO: quite ugly, anon-handling must be rethought | ||||
| 		auto userdao = database->createUserDao(); | ||||
|   | ||||
		Viittaa uudesa ongelmassa
	
	Block a user