|
|
@@ -48,30 +48,6 @@ class XCIShutdownWatcher : public snfXCIServerCommandHandler { |
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
class SignalCatcher : public Thread { // Class to catch a signal.
|
|
|
|
private:
|
|
|
|
sigset_t *MySignalSet;
|
|
|
|
snf_RulebaseHandler *MyRulebase;
|
|
|
|
public:
|
|
|
|
SignalCatcher(sigset_t *Signal_Set, snf_RulebaseHandler* Rulebase) : // Construct.
|
|
|
|
MySignalSet(Signal_Set), // Set of signals to catch.
|
|
|
|
MyRulebase(Rulebase) { // Used for error logging.
|
|
|
|
run(); // Start the thread.
|
|
|
|
}
|
|
|
|
void myTask() {
|
|
|
|
int ReceivedSignal;
|
|
|
|
int Status = sigwait(MySignalSet, &ReceivedSignal);
|
|
|
|
if (0 != Status) {
|
|
|
|
// Log error.
|
|
|
|
ostringstream Temp;
|
|
|
|
Temp << "Error waiting for signal: " << strerror(Status) << ".";
|
|
|
|
MyRulebase->logThisError("Signal Catcher", 1, Temp.str());
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
smfi_stop(); // Stop processing.
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
const int CorrectARGc = 2; // How many arguments we expect.
|
|
|
|
|
|
|
|
void displayHelp() { // Display some help.
|
|
|
@@ -102,28 +78,8 @@ int main(int argc, char* argv[]) { |
|
|
|
cout << "Debug Mode" << endl; // watchers.
|
|
|
|
}
|
|
|
|
|
|
|
|
sigset_t SignalSet; // Set of signals to mask.
|
|
|
|
SignalCatcher *SigCatcher; // Object to catch signal.
|
|
|
|
|
|
|
|
try { // Catch anything that breaks loose.
|
|
|
|
|
|
|
|
int PthreadStatus;
|
|
|
|
|
|
|
|
if ( (0 != sigemptyset(&SignalSet)) || // Mask signal for this thread and
|
|
|
|
// all threads to be created.
|
|
|
|
(0 != sigaddset(&SignalSet, ShutdownSignal)) ) {
|
|
|
|
ostringstream Temp;
|
|
|
|
|
|
|
|
Temp << "Error masking signal on startup: " << strerror(errno) << ".";
|
|
|
|
throw runtime_error(Temp.str());
|
|
|
|
}
|
|
|
|
PthreadStatus = pthread_sigmask(SIG_BLOCK, &SignalSet, 0);
|
|
|
|
if (0 != PthreadStatus) {
|
|
|
|
ostringstream Temp;
|
|
|
|
Temp << "Error masking signal on startup (pthread_sigmask): " << strerror(PthreadStatus) << ".";
|
|
|
|
throw runtime_error(Temp.str());
|
|
|
|
}
|
|
|
|
|
|
|
|
snf_RulebaseHandler* MilterRulebase = new snf_RulebaseHandler(); // Allocate a rulebase handler.
|
|
|
|
MilterRulebase->PlatformVersion(SNF_MILTER_VERSION); // Record our version identification.
|
|
|
|
XCIShutdownWatcher ShutdownWatcher; // Make a server shutdown processor
|
|
|
@@ -133,29 +89,13 @@ int main(int argc, char* argv[]) { |
|
|
|
SNFMilterContextPool* MilterContexts =
|
|
|
|
new SNFMilterContextPool(MilterRulebase); // Create the Milter Context Pool.
|
|
|
|
|
|
|
|
SigCatcher = new SignalCatcher(&SignalSet, MilterRulebase); // Create thread object to catch the signal.
|
|
|
|
|
|
|
|
runLibMilter(MilterContexts, DebugMode); // Run the milter.
|
|
|
|
|
|
|
|
ThreadState const &SigCatcherState = SigCatcher->MyState();
|
|
|
|
if (Thread::ThreadStarted.Name == SigCatcherState.Name) { // Is the signal catcher thread running?
|
|
|
|
PthreadStatus = pthread_kill(SigCatcher->getMyThread(), ShutdownSignal); // Yes. Send it a signal.
|
|
|
|
if (0 == PthreadStatus) {
|
|
|
|
SigCatcher->join(); // Wait for signal catcher to complete.
|
|
|
|
} else {
|
|
|
|
ostringstream Temp;
|
|
|
|
Temp << "Error terminating signal catcher: " << strerror(PthreadStatus) << ".";
|
|
|
|
throw runtime_error(Temp.str());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
delete MilterContexts; // Destroy the context pool.
|
|
|
|
MilterContexts = 0; // Forget it.
|
|
|
|
MilterRulebase->close(); // Close down the rulebase handler.
|
|
|
|
delete MilterRulebase; // Destroy the rulebase.
|
|
|
|
MilterRulebase = 0; // Forget it.
|
|
|
|
delete SigCatcher; // Destroy the signal catcher.
|
|
|
|
SigCatcher = 0; // Forget it.
|
|
|
|
|
|
|
|
} // That's all folks.
|
|
|
|
|