// 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) { ext::String config("spectre.xml"), pid("spectre.pid"); 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 == matcher("^-pid=(.*)$")) pid = matcher[1]; else if (*arg == "-D") Spectre2::debug = true; else { api::Cerr << "Usage: " << Spectre2::program << " [-config=config] [-fork] [-pid=pid] [-D]" << ios::NewLine; return 1; } } if (fork && api::Posix::CheckError(::fork())) return 0; api::Cerr << "Here!" << ios::NewLine; Spectre2(config, pid); 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 ext::String& config, const ext::String& pid) : pid(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(); } }