// Spectre 2 // // Douglas Thrift // // $Id$ #include "Mounter.hpp" #include "Unmounter.hpp" #include "Matcher/Matcher.hpp" #include #include #include #include int Main(const app::Options& options) { api::Path config(Spectre2::prefix + "/etc/spectre.xml"); bool fork(false); _foreach (const app::ArgumentList, arg, app::GetArguments()) { Matcher matcher; if (*arg == matcher("^-config=(.*)$")) config = matcher[1]; else if (*arg == "-fork") fork = true; else if (*arg == "-D") Spectre2::debug = true; else { api::Cerr << "Usage: " << Spectre2::program << " [-config=config] [-fork] [-D]" << ios::NewLine; return 1; } } if (!config.Exists()) { api::Cerr << Spectre2::program << ": configuration file " << config.GetPath() << " does not exist." << ios::NewLine; return 2; } if (fork && api::Posix::CheckError(::fork())) return 0; Spectre2 spectre(config); return 0; } extern "C" { void reload(int signal, ::siginfo_t* info, void* uap); void stop(int signal, ::siginfo_t* info, void* uap); } Spectre2::Spectre2(const api::Path& config) { { _H document(xml::Parse(config.GetPath())); pid = *document/"spectre"/"pid"; } { api::FileWriter out(pid); ios::FormatWriter fout(out); fout << ::getpid() << ios::NewLine; } Mounter mounter(config); Unmounter unmounter(config); daemons.InsertLast(dynamic_cast(&mounter)); daemons.InsertLast(dynamic_cast(&unmounter)); { struct ::sigaction action; action.sa_sigaction = reload; action.sa_flags = SA_SIGINFO; api::Posix::CheckError(::sigemptyset(&action.sa_mask)); api::Posix::CheckError(::sigaction(SIGUSR1, &action, NULL)); action.sa_sigaction = stop; api::Posix::CheckError(::sigaction(SIGTERM, &action, NULL)); } _foreach (ext::Vector, daemon, daemons) (*daemon)->start(); _foreach (ext::Vector, daemon, daemons) (*daemon)->wait(); } Spectre2::~Spectre2() { api::Posix::CheckError(::unlink(pid.NullTerminate())); } ext::String Spectre2::program(api::GetExecutablePath().GetName()), Spectre2::prefix(_Spectre2_prefix_), Spectre2::root(_Spectre2_root_); bool Spectre2::debug(false); ext::Vector Spectre2::daemons; extern "C" { void reload(int signal, ::siginfo_t* info, void* uap) { _foreach (ext::Vector, daemon, Spectre2::daemons) (*daemon)->reload(); } void stop(int signal, ::siginfo_t* info, void* uap) { _foreach (ext::Vector, daemon, Spectre2::daemons) (*daemon)->stop(); } }