|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192 |
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <ctime>
- #include <cstring>
-
- #include <iostream>
- #include <iomanip>
- #include <fstream>
- #include <sstream>
- #include <string>
- #include <queue>
- #include <cmath>
- #include <exception>
- #include <stdexcept>
- #include "unistd.h"
- #include "timing.hpp"
- #include "threading.hpp"
- #include "networking.hpp"
- #include "SNFMulti.hpp"
- #include "snf_xci.hpp"
- #include "snf_sync.hpp"
-
- #include "config.h"
-
- // temporary - proving base64codec
-
- #include "base64codec.hpp"
-
- //#include "../nvwa-0.6/nvwa/debug_new.h"
- using namespace std; // Introduce standard namespace.
-
- const char* SERVER_VERSION_INFO = "SNF Server Version " PACKAGE_VERSION " Build: " __DATE__ " " __TIME__;
-
- static const string XCIShutdownResponse =
- "<snf><xci><server><response message=\'shutdown in progress\' code=\'0\'/></server></xci></snf>\n";
-
- class XCIShutdownWatcher : public snfXCIServerCommandHandler { // Shutdown watcher.
- public:
- XCIShutdownWatcher():TimeToStop(false){} // Construct with shutdown flag false.
- bool TimeToStop; // Here is the flag.
- string processXCIRequest(snf_xci& X) { // Here is how we process requests.
- if(0 == X.xci_server_command.find("shutdown")) { // If we find shutdown then
- TimeToStop = true; // set the shutdown flag
- return XCIShutdownResponse; // and let them know we got it.
- } // If we get some other request
- return XCIErrorResponse; // return the error response.
- }
- };
-
- // Thread Status Analysis For Debugging.
-
- void ThreadStatusToCout() { // Produce a thread status list.
- ThreadStatusReport R = Threads.StatusReport(); // Get a report from Threads.
- cout << endl; // Break the line.
- for(
- ThreadStatusReport::iterator iR = R.begin(); // Loop through the report.
- iR != R.end(); iR++
- ) {
- ThreadStatusRecord& S = (*iR); // Take each status report and
- cout // send it to cout on it's own line.
- << S.getName() << " (" << S.getPointer() << "), "
- << S.getType().Name << ", "
- << S.getState().Name << ", "
- << ((S.getRunning()) ? "Running, " : "Not Running, ")
- << ((S.getBad()) ? "Broken, " : "Ok, ")
- << S.getFault()
- << endl;
- }
- cout << endl; // Leave a blank line at the end.
- }
-
- // Here in the main thread is where we get executive tasks done.
-
- int go(int argc, char* argv[]) { //// go() stands in for main(). main() catches any unhandled exceptions.
-
- // Check for debug mode.
-
- bool DebugMode = false; // This will be our debug mode.
- string argv0(argv[0]); // Capture how we were called.
- if(
- string::npos != argv0.find("Debug") || // If we find "Debug" or
- string::npos != argv0.find("debug") // "debug" in our command path
- ) { // then we are in DebugMode.
- DebugMode = true; // Set the flag and tell the
- cout << "Debug Mode" << endl; // watchers.
- }
-
- // DebugMode = true; // Force it when needed.
-
- // Announce Version / Build Info.
-
- cout << SERVER_VERSION_INFO << endl; // Shout out our version.
- cout << SNF_ENGINE_VERSION << endl; // Shout out the engine version.
-
- // Sanity checks before we get going.
-
- if(2 != argc) { // Check the command line args.
- cout << "Use: SNFServer <path-to-config-file>" << endl; // If wrong, say how we work.
- return 0;
- }
- if(0 != access(argv[1], R_OK)) { // Check the config file path.
- cout << "Can't read " << argv[1] << endl; // If it's not accessible, punt.
- return 0;
- }
- cout << "Launching with " << argv[1] << endl; // Tell them we're going.
- snf_RulebaseHandler MyRulebase; // Create a rulebase manager.
- MyRulebase.PlatformVersion(SERVER_VERSION_INFO); // Set the Platform version string.
- XCIShutdownWatcher ShutdownWatcher; // Make a server shutdown processor
- MyRulebase.XCIServerCommandHandler(ShutdownWatcher); // and register it with the engine.
- MyRulebase.open(argv[1], "", ""); // Open a configured rulebase.
-
- Sleeper WaitATic(1000); // Learn to wait a second.
-
- cout << "Running." << endl << endl; // Tell them we're running.
- char Tic = '\\'; // Tic/Toc indicator.
- while(false == ShutdownWatcher.TimeToStop) { // While running, update the screen.
- WaitATic(); // One second between updates.
-
- // Animate the Tick/Toc Indicator
-
- switch(Tic) {
- case '\\': Tic = '|'; break;
- case '|': Tic = '/'; break;
- case '/': Tic = '-'; break;
- default: Tic = '\\'; break;
- }
-
- // Format and output the screen update. At the end post a \r so that
- // the line appears to update in place.
-
- cout
- << "M/min: " << setw(4) << (int) MyRulebase.MyLOGmgr.MessagesPerMinute() << " "
- << "SP: " << setw(6) << setprecision(2) << setiosflags(ios::fixed) <<
- ((0 < MyRulebase.MyLOGmgr.MessagesPerMinute()) ?
- (100 * MyRulebase.MyLOGmgr.SpamPerMinute() / MyRulebase.MyLOGmgr.MessagesPerMinute()) : 0.0) << "% "
- << "LR:" << setw(7) << MyRulebase.MyLOGmgr.LatestRuleID()
- << " ["
- << MyRulebase.MyXCImgr.pollClientCount() << "/"
- << MyRulebase.MyXCImgr.pollLoopCount() << " "
- << Tic << " " << (int) MyRulebase.MyXCImgr.TotalQueue() << "] "
- << "W:" << (int) MyRulebase.MyLOGmgr.WhitePerMinute() << " "
- << "C:" << (int) MyRulebase.MyLOGmgr.CautionPerMinute() << " "
- << "B:" << (int) MyRulebase.MyLOGmgr.BlackPerMinute() << " "
- << "T:" << (int) MyRulebase.MyLOGmgr.TruncatePerMinute() << " "
- << "S:" << (int) MyRulebase.MyLOGmgr.SamplePerMinute()
- << " \r" << flush;
-
- if(DebugMode) ThreadStatusToCout(); // Debug? Show Thread Status Report.
-
- }
- cout << endl << endl << "Shutdown Received." << endl;
-
- // When this loop fails it is time to shut down.
- // All the rest happens via XCI now.
-
- cout << "Closing Rulebase Handler..." << endl;
-
- MyRulebase.close();
-
- // All done...
-
- cout << "Bye bye." << endl;
-
- return 0;
- }
-
- /*
- class DebugExceptionHandler { // Hand wrapper for exception handler.
- public:
- DebugExceptionHandler() {
- LoadLibrary("exchndl.dll");
- }
- };
-
- static DebugExceptionHandler TheDebugExceptionHandler; // Global exception handler.
-
- */
-
- int main(int argc, char* argv[]) {
-
- try {
- go(argc, argv);
- }
- catch(exception& e) {
- cout << "Unhandled Exception: " << e.what() << " Thrown!" << endl;
- }
- catch(...) {
- cout << "Unknown, Unhandled Exception Discovered!" << endl;
- }
- return 0;
- }
-
|