Ejemplo n.º 1
0
	fl::configuration get_freelan_configuration(const fscp::logger& logger, const service_configuration& configuration)
	{
		namespace po = boost::program_options;

		po::options_description configuration_options("Configuration");
		configuration_options.add(get_server_options());
		configuration_options.add(get_client_options());
		configuration_options.add(get_fscp_options());
		configuration_options.add(get_security_options());
		configuration_options.add(get_tap_adapter_options());
		configuration_options.add(get_switch_options());
		configuration_options.add(get_router_options());

		fl::configuration fl_configuration;
		po::variables_map vm;
		const fs::path configuration_file = configuration.configuration_file;
		const fs::path root_directory = configuration_file.parent_path();
		fs::basic_ifstream<char> ifs(configuration_file);

		if (!ifs)
		{
			throw po::reading_file(configuration_file.string().c_str());
		}

		po::store(po::parse_config_file(ifs, configuration_options, true), vm);
		make_paths_absolute(vm, root_directory);
		po::notify(vm);

		setup_configuration(logger, fl_configuration, vm);

		return fl_configuration;
	}
Ejemplo n.º 2
0
bool parse_options(fscp::logger& logger, int argc, char** argv, cli_configuration& configuration)
{
	namespace po = boost::program_options;

	po::options_description visible_options;
	po::options_description all_options;

	po::options_description generic_options("Generic options");
	generic_options.add_options()
	("help,h", "Produce help message.")
	("version,v", "Get the program version.")
	("debug,d", "Enables debug output.")
	("threads,t", po::value<unsigned int>(&configuration.thread_count)->default_value(0), "The number of threads to use.")
	("configuration_file,c", po::value<std::string>(), "The configuration file to use.")
	;

	visible_options.add(generic_options);
	all_options.add(generic_options);

	po::options_description configuration_options("Configuration");
	configuration_options.add(get_server_options());
	configuration_options.add(get_client_options());
	configuration_options.add(get_fscp_options());
	configuration_options.add(get_security_options());
	configuration_options.add(get_tap_adapter_options());
	configuration_options.add(get_switch_options());
	configuration_options.add(get_router_options());

	visible_options.add(configuration_options);
	all_options.add(configuration_options);

#ifdef WINDOWS
	po::options_description service_options("Service");
	service_options.add_options()
	("install", "Install the service.")
	("uninstall", "Uninstall the service.")
	("reinstall", "Reinstall the service.")
	;

	visible_options.add(service_options);
	all_options.add(service_options);
#else
	po::options_description daemon_options("Daemon");
	daemon_options.add_options()
	("foreground,f", "Do not run as a daemon.")
	("pid_file,p", po::value<std::string>(), "A pid file to use.")
	;

	visible_options.add(daemon_options);
	all_options.add(daemon_options);

	po::options_description misc_options("Miscellaneous");
	misc_options.add_options()
	("nocolor", "Disable color output.")
	;

	visible_options.add(misc_options);
	all_options.add(misc_options);
#endif

	po::variables_map vm;
	po::store(po::parse_command_line(argc, argv, all_options), vm);
	make_paths_absolute(vm, fs::current_path());

	if (vm.count("help"))
	{
		std::cout << visible_options << std::endl;

		return false;
	}

	if (vm.count("version"))
	{
		std::cout << FREELAN_NAME << " " << FREELAN_VERSION_STRING << " " << FREELAN_DATE << std::endl;

		return false;
	}

#ifdef WINDOWS
	if (vm.count("install"))
	{
		if (vm.count("uninstall"))
		{
			throw std::runtime_error("Cannot specify both --install and --uninstall options. Use --reinstall instead.");
		}
		else
		{
			if (windows::install_service())
			{
				logger(fscp::log_level::important) << "Service installed.";
			}
			else
			{
				logger(fscp::log_level::error) << "The service was already installed.";
			}

			return false;
		}
	}
	else if (vm.count("uninstall"))
	{
		if (windows::uninstall_service())
		{
			logger(fscp::log_level::important) << "Service uninstalled.";
		}
		else
		{
			logger(fscp::log_level::error) << "The service has already been deleted.";
		}

		return false;
	}
	else if (vm.count("reinstall"))
	{
		if (windows::uninstall_service())
		{
			logger(fscp::log_level::important) << "Service uninstalled.";
		}
		else
		{
			logger(fscp::log_level::error) << "The service has already been deleted.";
		}

		if (windows::install_service())
		{
			logger(fscp::log_level::important) << "Service installed.";
		}
		else
		{
			logger(fscp::log_level::error) << "The service was already installed.";
		}

		return false;
	}
#else
	configuration.foreground = (vm.count("foreground") > 0);

	if (vm.count("nocolor") > 0)
	{
		// This is a global variable. Not really nice but does its job in this case.
		DISABLE_COLOR = true;
	}

	if (vm.count("pid_file"))
	{
		configuration.pid_file = fs::absolute(vm["pid_file"].as<std::string>());
	}
	else
	{
		char* val = getenv("FREELAN_PID_FILE");

		if (val)
		{
			configuration.pid_file = fs::absolute(std::string(val));
		}
	}
#endif

	fs::path configuration_file;

	if (vm.count("configuration_file"))
	{
		configuration_file = fs::absolute(vm["configuration_file"].as<std::string>());
	}
	else
	{
#ifdef _MSC_VER
#ifdef UNICODE
		std::wstring value(4096, L'\0');

		const DWORD value_size = GetEnvironmentVariable(L"FREELAN_CONFIGURATION_FILE", &value[0], static_cast<DWORD>(value.size()));
#else
		std::string value(4096, '\0');

		const DWORD value_size = GetEnvironmentVariable("FREELAN_CONFIGURATION_FILE", &value[0], static_cast<DWORD>(value.size()));
#endif

		if (value_size > 0)
		{
			value.resize(value_size);

			configuration_file = fs::absolute(value);
		}
#else
		const char* val = getenv("FREELAN_CONFIGURATION_FILE");

		if (val)
		{
			configuration_file = fs::absolute(std::string(val));
		}
#endif
	}

	if (!configuration_file.empty())
	{
		logger(fscp::log_level::information) << "Reading configuration file at: " << configuration_file;

		fs::basic_ifstream<char> ifs(configuration_file);

		if (!ifs)
		{
			throw po::reading_file(configuration_file.string().c_str());
		}

		po::store(po::parse_config_file(ifs, configuration_options, true), vm);
	}
	else
	{
		bool configuration_read = false;

		const std::vector<fs::path> configuration_files = get_configuration_files();

		BOOST_FOREACH(const fs::path& conf, configuration_files)
		{
			fs::basic_ifstream<char> ifs(conf);

			if (ifs)
			{
				logger(fscp::log_level::information) << "Reading configuration file at: " << conf << std::endl;

				po::store(po::parse_config_file(ifs, configuration_options, true), vm);

				configuration_file = fs::absolute(conf);

				configuration_read = true;

				break;
			}
		}

		if (!configuration_read)
		{
			logger(fscp::log_level::warning) << "Warning ! No configuration file specified and none found in the environment.";
			logger(fscp::log_level::warning) << "Looked up locations were:";

			for (auto&& conf : configuration_files)
			{
				logger(fscp::log_level::warning) << "- "  << conf;
			}
		}
	}