Changeset 262


Ignore:
Timestamp:
04/08/10 21:48:28 (22 months ago)
Author:
mickem
Message:

2010-04-04 MickeM

  • Reverted "major eventlog change" since it did in fact break to many things + Added new major addition to CheckEventLog CheckEventLog has a compleatly new syntax borrowed from SQL. CheckEventLog MaxWarn=1 MaxCrit=1 "filter=(id = 123 OR id = 321) AND (severity='warning' OR severity='error')" Avalible operators are: =, !=, >, <, >=, <=, eq, ne, gt, lt, ge, le, OR, AND Avalible functions are: convert(<value>) (will try to automatically convert type) Avalible variables are: severity (others may work but this will come in the next week)

2010-03-24 MickeM

+ added a new "option" in conjunction with -c you can now do -m to specify the module to load.

nsclient++ -m CheckDisk.dll -c CheckDriveSize MaxWarn=100 CheckAll?
This prevents socket based modules from loading causing "bind" errors.

2010-03-11 MickeM

  • Fixed MAJOR issue with CheckEventLog and this might actually break "existing" checks so let me know. Problem was I matched filter+ incorrectly. + Added new option debug-threshold to set "after which rule" we will start dumping filter matches (very usefull to ignore first rule) CheckEventLog debug=true debug-threshold=1 (will be alot more usefull then without the threshold)
Location:
branches/stable
Files:
12 added
12 edited

Legend:

Unmodified
Added
Removed
  • branches/stable/AutoBuild.h

    r261 r262  
    33// change the FALSE to TRUE for autoincrement of build number 
    44#define INCREMENT_VERSION TRUE 
    5 #define FILEVER        0,3,8,27 
    6 #define PRODUCTVER     0,3,8,27 
    7 #define STRFILEVER     _T("0.3.8.27") 
    8 #define STRPRODUCTVER  _T("0.3.8.27") 
    9 #define STRPRODUCTDATE  _T("2010-03-08") 
     5#define FILEVER        0,3,8,33 
     6#define PRODUCTVER     0,3,8,33 
     7#define STRFILEVER     _T("0.3.8.33") 
     8#define STRPRODUCTVER  _T("0.3.8.33") 
     9#define STRPRODUCTDATE  _T("2010-04-08") 
    1010#endif // AUTOBUILD_H 
  • branches/stable/NSClient++.cpp

    r193 r262  
    378378      mainClient.exitCore(true); 
    379379      return nRetCode; 
    380     } else if ( _wcsicmp( _T("c"), argv[1]+1 ) == 0 ) { 
     380    } else if ( (_wcsicmp( _T("c"), argv[1]+1 ) == 0) || (_wcsicmp( _T("m"), argv[1]+1 ) == 0)) { 
     381      std::wstring module, command, args, msg, perf; 
     382      int arg_start; 
     383      if ( _wcsicmp( _T("m"), argv[1]+1 ) == 0) { 
     384        if ((argc < 4) || (_wcsicmp( _T("c"), argv[3]+1) != 0)) { 
     385          std::wcout << _T("missing argument"); 
     386          return -1; 
     387        } 
     388        module = argv[2]; 
     389        command = argv[4]; 
     390        arg_start = 5; 
     391      } else { 
     392        if (argc > 2) 
     393          command = argv[2]; 
     394        arg_start = 3; 
     395      } 
    381396      // Run command from command line (like NRPE) 
    382397      g_bConsoleLog = true; 
    383398      mainClient.enableDebug(false); 
    384       mainClient.initCore(true); 
    385       std::wstring command, args, msg, perf; 
    386       if (argc > 2) 
    387         command = argv[2]; 
    388       for (int i=3;i<argc;i++) { 
    389         if (i!=3) args += _T(" "); 
     399      mainClient.initCore(true, module); 
     400      for (int i=arg_start;i<argc;i++) { 
     401        if (i!=arg_start) args += _T(" "); 
    390402        args += argv[i]; 
    391403      } 
     
    530542 * @author mickem 
    531543 */ 
    532 bool NSClientT::initCore(bool boot) { 
     544bool NSClientT::initCore(bool boot, std::wstring module) { 
    533545  LOG_DEBUG(_T("Attempting to start NSCLient++ - " SZVERSION)); 
    534546  try { 
     
    609621  if (boot) { 
    610622    try { 
    611       settings_base::sectionList list = Settings::getInstance()->getSection(_T("modules")); 
    612       for (settings_base::sectionList::iterator it = list.begin(); it != list.end(); it++) { 
     623      if (module.empty()) { 
     624        settings_base::sectionList list = Settings::getInstance()->getSection(_T("modules")); 
     625        for (settings_base::sectionList::iterator it = list.begin(); it != list.end(); it++) { 
     626          try { 
     627            loadPlugin(getBasePath() + _T("modules\\") + (*it)); 
     628          } catch(const NSPluginException& e) { 
     629            LOG_ERROR_STD(_T("Exception raised: ") + e.error_ + _T(" in module: ") + e.file_); 
     630            //return false; 
     631          } catch (std::exception e) { 
     632            LOG_ERROR_STD(_T("exception loading plugin: ") + (*it) + strEx::string_to_wstring(e.what())); 
     633            return false; 
     634          } catch (...) { 
     635            LOG_ERROR_STD(_T("Unknown exception loading plugin: ") + (*it)); 
     636            return false; 
     637          } 
     638        } 
     639      } else { 
    613640        try { 
    614           loadPlugin(getBasePath() + _T("modules\\") + (*it)); 
     641          loadPlugin(getBasePath() + _T("modules\\") + module); 
    615642        } catch(const NSPluginException& e) { 
    616643          LOG_ERROR_STD(_T("Exception raised: ") + e.error_ + _T(" in module: ") + e.file_); 
    617644          //return false; 
    618645        } catch (std::exception e) { 
    619           LOG_ERROR_STD(_T("exception loading plugin: ") + (*it) + strEx::string_to_wstring(e.what())); 
     646          LOG_ERROR_STD(_T("exception loading plugin: ") + module + strEx::string_to_wstring(e.what())); 
    620647          return false; 
    621648        } catch (...) { 
    622           LOG_ERROR_STD(_T("Unknown exception loading plugin: ") + (*it)); 
     649          LOG_ERROR_STD(_T("Unknown exception loading plugin: ") + module); 
    623650          return false; 
    624651        } 
  • branches/stable/NSClient++.h

    r173 r262  
    113113  bool InitiateService(); 
    114114  void TerminateService(void); 
    115   bool initCore(bool boot); 
     115  bool initCore(bool boot, std::wstring module = _T("")); 
    116116  bool exitCore(bool boot); 
    117117  static void WINAPI service_main_dispatch(DWORD dwArgc, LPTSTR *lpszArgv); 
  • branches/stable/changelog

    r261 r262  
    77 * Fix RtlStringFromGUID problem on NT4 
    88 
    9 2009-03-08 MickeM 
     92010-04-04 MickeM 
     10 - Reverted "major eventlog change" since it did in fact break to many things 
     11 + Added new major addition to CheckEventLog 
     12   CheckEventLog has a compleatly new syntax borrowed from SQL. 
     13   CheckEventLog MaxWarn=1 MaxCrit=1 "filter=(id = 123 OR id = 321) AND (severity='warning' OR severity='error')" 
     14   Avalible operators are: =, !=, >, <, >=, <=, eq, ne, gt, lt, ge, le, OR, AND 
     15   Avalible functions are: convert(<value>) (will try to automatically convert type) 
     16   Avalible variables are: severity (others may work but this will come in the next week) 
     17 
     182010-03-24 MickeM 
     19 + added a new "option" in conjunction with -c you can now do -m to specify the module to load. 
     20   nsclient++ -m CheckDisk.dll -c CheckDriveSize MaxWarn=100 CheckAll 
     21   This prevents socket based modules from loading causing "bind" errors. 
     22 
     232010-03-11 MickeM 
     24 * Fixed MAJOR issue with CheckEventLog and this might actually break "existing" checks so let me know. 
     25   Problem was I matched filter+ incorrectly. 
     26 + Added new option debug-threshold to set "after which rule" we will start dumping filter matches (very usefull to ignore first rule) 
     27   CheckEventLog debug=true debug-threshold=1 (will be alot more usefull then without the threshold) 
     28 
     292010-03-08 MickeM 
    1030 + Added new option append-filter-<key>=<value> to CheckEventLog to allow "and" of filter rules. 
    1131   CheckEventLog file=application file=system filter=out MaxWarn=1 MaxCrit=1 filter-eventID=ne:1 filter-eventID=eq:1 append-filter-eventSource==SecurityCenter truncate=1023 unique descriptions "syntax=%source%: %id% (%count%)" 
     
    1434 + Added so "global" ([Settings] password=...) passwords are read from the NSCA module 
    1535  
    16 2009-02-26 MickeM 
     362010-02-26 MickeM 
    1737 * Changed fo missing files and such generate an error 
    1838 * Added option to return error messages to the client [CheckDisk] show_errors=1 (defauilt is off 0) 
     
    2040 * Fixed major issue with date mathing in CheckFile* which was not working at all. 
    2141 
    22 2009-01-24 MickeM 
     422010-01-24 MickeM 
    2343 * Fixed so files locked for reading can be chcked (basic checks) 
    2444 * Improved speed of file chyecking (does not check file data twice) 
    2545 
    26 2009-01-23 MickeM 
     462010-01-23 MickeM 
    2747 + Added checks for missing path and missing filter on CheckFile2 thus 
    2848    CheckFile2 without paths and/or filters will have status unknown. 
  • branches/stable/helpers/UploadBinaries

    • Property svn:ignore
      •  

        old new  
        11*.user 
         2x64 
  • branches/stable/helpers/installer_dll_fw

    • Property svn:ignore
      •  

        old new  
        11Debug 
        22*.user 
         3x64 
  • branches/stable/include/checkHelpers.hpp

    r261 r262  
    10381038      } else { 
    10391039        NSC_LOG_MESSAGE_STD(_T("Missing bounds for: ") + alias); 
     1040        return _T(""); 
    10401041      } 
    10411042    } 
  • branches/stable/include/strEx.h

    r240 r262  
    212212 
    213213  inline void strip_CRLF(wchar_t *string) { 
    214     int len = wcslen(string); 
    215     for (int i=0;i<len;i++) { 
     214    size_t len = wcslen(string); 
     215    for (size_t i=0;i<len;i++) { 
    216216      if (string[i] == 10 || string[i] == 13) 
    217217        string[i] = L' '; 
     
    253253    return ss.str(); 
    254254  } 
     255  inline std::wstring itos(long long i) { 
     256    std::wstringstream ss; 
     257    ss << i; 
     258    return ss.str(); 
     259  } 
     260  /* 
    255261  inline std::wstring itos(__int64 i) { 
    256262    std::wstringstream ss; 
     
    258264    return ss.str(); 
    259265  } 
     266  */ 
    260267  inline std::wstring itos(unsigned long i) { 
    261268    std::wstringstream ss; 
  • branches/stable/modules/CheckEventLog/CheckEventLog-2005.vcproj

    r261 r262  
    292292      <Tool 
    293293        Name="VCCLCompilerTool" 
     294        AdditionalOptions="-Zm300" 
    294295        Optimization="0" 
    295296        AdditionalIncludeDirectories="../include;../../include" 
     
    300301        UsePrecompiledHeader="2" 
    301302        WarningLevel="3" 
    302         Detect64BitPortabilityProblems="false" 
     303        Detect64BitPortabilityProblems="true" 
    303304        DebugInformationFormat="3" 
    304305      /> 
     
    15511552      </File> 
    15521553      <File 
     1554        RelativePath="..\..\include\parsers\ast.cpp" 
     1555        > 
     1556        <FileConfiguration 
     1557          Name="Debug|x64" 
     1558          > 
     1559          <Tool 
     1560            Name="VCCLCompilerTool" 
     1561            UsePrecompiledHeader="0" 
     1562          /> 
     1563        </FileConfiguration> 
     1564      </File> 
     1565      <File 
    15531566        RelativePath=".\CheckEventLog.cpp" 
    15541567        > 
    15551568      </File> 
    15561569      <File 
     1570        RelativePath="..\..\include\parsers\grammar.cpp" 
     1571        > 
     1572        <FileConfiguration 
     1573          Name="Debug|x64" 
     1574          > 
     1575          <Tool 
     1576            Name="VCCLCompilerTool" 
     1577            UsePrecompiledHeader="0" 
     1578          /> 
     1579        </FileConfiguration> 
     1580      </File> 
     1581      <File 
    15571582        RelativePath="..\..\include\NSCHelper.cpp" 
    15581583        > 
     
    18521877      </File> 
    18531878      <File 
     1879        RelativePath=".\test.cpp" 
     1880        > 
     1881      </File> 
     1882      <File 
    18541883        RelativePath="..\..\include\utils.cpp" 
    18551884        > 
     
    20052034            UsePrecompiledHeader="0" 
    20062035            PrecompiledHeaderThrough="" 
     2036          /> 
     2037        </FileConfiguration> 
     2038      </File> 
     2039      <File 
     2040        RelativePath="..\..\include\parsers\where.cpp" 
     2041        > 
     2042        <FileConfiguration 
     2043          Name="Debug|x64" 
     2044          > 
     2045          <Tool 
     2046            Name="VCCLCompilerTool" 
     2047            UsePrecompiledHeader="0" 
    20072048          /> 
    20082049        </FileConfiguration> 
     
    20142055      UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" 
    20152056      > 
     2057      <File 
     2058        RelativePath="..\..\include\parsers\ast.hpp" 
     2059        > 
     2060      </File> 
    20162061      <File 
    20172062        RelativePath=".\CheckEventLog.h" 
     
    20232068      </File> 
    20242069      <File 
     2070        RelativePath="..\..\include\parsers\eval.hpp" 
     2071        > 
     2072      </File> 
     2073      <File 
     2074        RelativePath=".\eventlog_filter.hpp" 
     2075        > 
     2076      </File> 
     2077      <File 
     2078        RelativePath=".\eventlog_record.hpp" 
     2079        > 
     2080      </File> 
     2081      <File 
    20252082        RelativePath="..\..\include\filter_framework.hpp" 
     2083        > 
     2084      </File> 
     2085      <File 
     2086        RelativePath="..\..\include\parsers\grammar.hpp" 
    20262087        > 
    20272088      </File> 
     
    20322093      <File 
    20332094        RelativePath=".\stdafx.h" 
     2095        > 
     2096      </File> 
     2097      <File 
     2098        RelativePath="..\..\include\parsers\where.hpp" 
    20342099        > 
    20352100      </File> 
  • branches/stable/modules/CheckEventLog/CheckEventLog.cpp

    r261 r262  
    3232#include <vector> 
    3333 
     34#include <boost/bind.hpp> 
     35#include <boost/assign.hpp> 
     36 
     37#include <parsers/where.hpp> 
     38 
     39#include "simple_registry.hpp" 
     40#include "eventlog_record.hpp" 
     41#include "eventlog_filter.hpp" 
     42 
    3443CheckEventLog gCheckEventLog; 
     44 
     45 
     46class simple_timer { 
     47  unsigned long long start_time; 
     48public: 
     49  simple_timer() { 
     50    start(); 
     51  } 
     52 
     53  void start() { 
     54    start_time = getFT(); 
     55  } 
     56  unsigned long long stop() { 
     57    unsigned int  ret = getFT() - start_time; 
     58    start(); 
     59    return ret/1000; 
     60  } 
     61 
     62private: 
     63  unsigned long long getFT() { 
     64    SYSTEMTIME systemTime; 
     65    GetSystemTime( &systemTime ); 
     66    FILETIME fileTime; 
     67    SystemTimeToFileTime( &systemTime, &fileTime ); 
     68    return  static_cast<unsigned long long>(fileTime.dwHighDateTime) << 32 | fileTime.dwLowDateTime; 
     69  } 
     70 
     71}; 
    3572 
    3673BOOL APIENTRY DllMain( HANDLE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved) 
     
    4481CheckEventLog::~CheckEventLog() { 
    4582} 
    46  
     83struct parse_exception { 
     84  parse_exception(std::wstring) {} 
     85}; 
     86 
     87#include <parsers/where.cpp> 
     88#include <parsers/grammar.cpp> 
     89#include <parsers/ast.cpp> 
     90 
     91namespace filter { 
     92  namespace where { 
     93    struct type_obj : public parsers::where::varible_handler<type_obj> { 
     94      typedef parsers::where::varible_handler<type_obj> handler; 
     95      typedef std::list<std::wstring> error_type; 
     96      typedef std::map<std::wstring,parsers::where::value_type> types_type; 
     97      types_type types; 
     98      error_type errors; 
     99      static const parsers::where::value_type type_custom_severity = parsers::where::type_custom_int_1; 
     100      EventLogRecord *record; 
     101      type_obj() : record(NULL) { 
     102        using namespace boost::assign; 
     103        using namespace parsers::where; 
     104        insert(types) 
     105          (_T("id"), (type_string)) 
     106          (_T("source"), (type_string)) 
     107          (_T("type"), (type_int)) 
     108          (_T("severity"), (type_custom_severity)) 
     109          (_T("message"), (type_string)) 
     110          (_T("strings"), (type_string)) 
     111          (_T("written"), (type_date)) 
     112          (_T("generated"), (type_date)); 
     113      } 
     114      type_obj(EventLogRecord *record) : record(record) {} 
     115      bool has_variable(std::wstring key) { 
     116        return types.find(key) != types.end(); 
     117      } 
     118      parsers::where::value_type get_type(std::wstring key) { 
     119        types_type::const_iterator cit = types.find(key); 
     120        if (cit == types.end()) 
     121          return parsers::where::type_invalid; 
     122        return cit->second; 
     123      } 
     124      bool can_convert(parsers::where::value_type from, parsers::where::value_type to) { 
     125        if ((from == parsers::where::type_string)&&(to == type_custom_severity)) 
     126          return true; 
     127        return false; 
     128      } 
     129      void error(std::wstring err) { 
     130        errors.push_back(err); 
     131      } 
     132      bool has_error() { 
     133        return !errors.empty(); 
     134      } 
     135      long long get_id() { 
     136        if (record == NULL) throw _T("Whoops"); return record->eventID();  
     137      } 
     138      std::wstring get_source() { 
     139        if (record == NULL) throw _T("Whoops"); return record->eventSource();  
     140      } 
     141      long long get_el_type() { 
     142        if (record == NULL) throw _T("Whoops"); return record->eventType();  
     143      } 
     144      long long get_severity() { 
     145        if (record == NULL) throw _T("Whoops");  
     146        //NSC_DEBUG_MSG_STD(_T("Severity: ") + strEx::itos(record->severity())); 
     147        return record->severity(); 
     148      } 
     149      std::wstring get_message() { 
     150        if (record == NULL) throw _T("Whoops"); return record->render_message();  
     151      } 
     152      std::wstring get_strings() { 
     153        if (record == NULL) throw _T("Whoops"); return record->enumStrings();  
     154      } 
     155      long long get_written() { 
     156        if (record == NULL) throw _T("Whoops"); return record->timeWritten();  
     157      } 
     158      long long get_generated() { 
     159        if (record == NULL) throw _T("Whoops"); return record->timeGenerated();  
     160      } 
     161 
     162      handler::bound_string_type bind_string(std::wstring key) { 
     163        handler::bound_string_type ret; 
     164        if (key == _T("source")) 
     165          ret = &type_obj::get_source; 
     166        if (key == _T("message")) 
     167          ret = &type_obj::get_message; 
     168        if (key == _T("strings")) 
     169          ret = &type_obj::get_strings; 
     170        return ret; 
     171      } 
     172      handler::bound_int_type bind_int(std::wstring key) { 
     173        handler::bound_int_type ret; 
     174        if (key == _T("id")) 
     175          ret = &type_obj::get_id; 
     176        if (key == _T("type")) 
     177          ret = &type_obj::get_el_type; 
     178        if (key == _T("severity")) 
     179          ret = &type_obj::get_severity; 
     180        if (key == _T("generated")) 
     181          ret = &type_obj::get_generated; 
     182        if (key == _T("written")) 
     183          ret = &type_obj::get_written; 
     184        return ret; 
     185      } 
     186 
     187      bool has_function(parsers::where::value_type to, std::wstring name, parsers::where::expression_ast<type_obj> subject) { 
     188        if (to == type_custom_severity) 
     189          return true; 
     190        return false; 
     191      } 
     192      handler::bound_function_type bind_function(parsers::where::value_type to, std::wstring name, parsers::where::expression_ast<type_obj> subject) { 
     193        handler::bound_function_type ret; 
     194        if (to == type_custom_severity) 
     195          ret = &type_obj::fun_convert_severity; 
     196        return ret; 
     197      } 
     198 
     199      parsers::where::expression_ast<type_obj> fun_convert_severity(parsers::where::value_type target_type, parsers::where::expression_ast<type_obj> const& subject) { 
     200        return parsers::where::expression_ast<type_obj>(parsers::where::int_value(convert_severity(subject.get_string(*this)))); 
     201      } 
     202      int convert_severity(std::wstring str) { 
     203        if (str == _T("success") || str == _T("ok")) 
     204          return 0; 
     205        if (str == _T("informational") || str == _T("info")) 
     206          return 1; 
     207        if (str == _T("warning") || str == _T("warn")) 
     208          return 2; 
     209        if (str == _T("error") || str == _T("err")) 
     210          return 3; 
     211        error(_T("Invalid severity: ") + str); 
     212        return strEx::stoi(str); 
     213      } 
     214 
     215 
     216      std::wstring get_error() { 
     217        std::wstring ret; 
     218        BOOST_FOREACH(std::wstring s, errors) { 
     219          if (!ret.empty()) ret += _T(", "); 
     220          ret += s; 
     221        } 
     222        return ret; 
     223      } 
     224    }; 
     225  } 
     226} 
     227 
     228 
     229 
     230 
     231struct filter_container { 
     232  enum filter_types { 
     233    filter_plus = 1, 
     234    filter_minus = 2, 
     235    filter_normal = 3 
     236  }; 
     237  typedef std::pair<int,eventlog_filter> filteritem_type; 
     238  typedef std::list<filteritem_type > filterlist_type; 
     239 
     240  filterlist_type filters; 
     241 
     242  bool bFilterAll; 
     243  bool bFilterIn; 
     244 
     245  bool bDebug; 
     246  int debugThreshold; 
     247 
     248  bool bShowDescriptions; 
     249  std::wstring syntax; 
     250 
     251  std::wstring filter; 
     252 
     253  filter_container(std::wstring syntax, bool debug) : bDebug(debug), debugThreshold(0), bFilterIn(true), bFilterAll(false), bShowDescriptions(false), syntax(syntax) {} 
     254 
     255}; 
     256 
     257struct any_mode_filter { 
     258  virtual bool boot() = 0; 
     259  virtual bool validate(std::wstring &message) = 0; 
     260  virtual bool match(EventLogRecord &record) = 0; 
     261  virtual std::wstring get_name() = 0; 
     262}; 
     263 
     264struct first_mode_filter : public any_mode_filter { 
     265  typedef filter_container::filterlist_type::const_iterator filter_iterator; 
     266  filter_container &data; 
     267  first_mode_filter(filter_container &data) : data(data) {} 
     268  bool boot() {return true;} 
     269  bool validate(std::wstring &message) { 
     270    if (data.filters.empty()) { 
     271      message = _T("No filters specified try adding: filter+generated=>2d"); 
     272      return false; 
     273    } 
     274    return true; 
     275  } 
     276 
     277  virtual bool match(EventLogRecord &record) { 
     278    bool bMatch = !data.bFilterIn; 
     279    for (filter_iterator cit3 = data.filters.begin(); cit3 != data.filters.end(); ++cit3) { 
     280      std::wstring reason; 
     281      int mode = (*cit3).first; 
     282      bool bTmpMatched = (*cit3).second.matchFilter(record); 
     283      if (data.bFilterAll) { 
     284        if (!bTmpMatched) { 
     285          bMatch = false; 
     286          break; 
     287        } 
     288      } else { 
     289        if (bTmpMatched) { 
     290          bMatch = true; 
     291          break; 
     292        } 
     293      } 
     294    } 
     295    if ((data.bFilterIn&&bMatch)||(!data.bFilterIn&&!bMatch)) { 
     296      return true; 
     297    } 
     298    return false; 
     299 
     300  } 
     301  std::wstring get_name() { 
     302    return _T("deprecated"); 
     303  } 
     304 
     305}; 
     306struct second_mode_filter : public any_mode_filter  { 
     307  typedef filter_container::filterlist_type::const_iterator filter_iterator; 
     308 
     309  filter_container &data; 
     310  second_mode_filter(filter_container &data) : data(data) {} 
     311  bool boot() {return true;} 
     312  bool validate(std::wstring &message) { 
     313    if (data.filters.empty()) { 
     314      message = _T("No filters specified try adding: filter+generated=>2d"); 
     315      return false; 
     316    } 
     317    return true; 
     318  } 
     319 
     320  virtual bool match(EventLogRecord &record) { 
     321    bool bMatch = !data.bFilterIn; 
     322    int i=0; 
     323    for (filter_iterator cit3 = data.filters.begin(); cit3 != data.filters.end(); ++cit3, i++ ) { 
     324      std::wstring reason; 
     325      int mode = (*cit3).first; 
     326      bool bTmpMatched = (*cit3).second.matchFilter(record); 
     327      if ((mode == filter_container::filter_minus)&&(bTmpMatched)) { 
     328        // a -<filter> hit so thrash item and bail out! 
     329        if (data.bDebug && (i>data.debugThreshold)) 
     330          NSC_DEBUG_MSG_STD(_T("[") + strEx::itos(i) + _T("] Matched: - ") + (*cit3).second.to_string() + _T(" for: ") + record.render(data.bShowDescriptions, data.syntax)); 
     331        return false; 
     332      } else if ((mode == filter_container::filter_plus)&&(!bTmpMatched)) { 
     333        // a +<filter> hit so keep item and bail out! 
     334        if (data.bDebug && (i>data.debugThreshold)) 
     335          NSC_DEBUG_MSG_STD(_T("[") + strEx::itos(i) + _T("] Matched: + ") + (*cit3).second.to_string() + _T(" for: ") + record.render(data.bShowDescriptions, data.syntax)); 
     336        return true; 
     337      } else if (bTmpMatched) { 
     338        if (data.bDebug && (i>data.debugThreshold)) 
     339          NSC_DEBUG_MSG_STD(_T("[") + strEx::itos(i) + _T("] Matched: . ") + (*cit3).second.to_string() + _T(" for: ") + record.render(data.bShowDescriptions, data.syntax)); 
     340        bMatch = true; 
     341      } 
     342    } 
     343    return bMatch; 
     344  } 
     345  std::wstring get_name() { 
     346    return _T("old"); 
     347  } 
     348}; 
     349 
     350struct where_mode_filter : public any_mode_filter { 
     351  filter_container &data; 
     352  std::string message; 
     353  parsers::where::parser<filter::where::type_obj> ast_parser; 
     354  filter::where::type_obj dummy; 
     355 
     356  where_mode_filter(filter_container &data) : data(data) {} 
     357  bool boot() {return true; } 
     358 
     359  bool validate(std::wstring &message) { 
     360    if (data.bDebug) 
     361      NSC_DEBUG_MSG_STD(_T("Parsing: ") + data.filter); 
     362 
     363    if (!ast_parser.parse(data.filter)) { 
     364      NSC_LOG_ERROR_STD(_T("Parsing failed of '") + data.filter + _T("' at: ") + ast_parser.rest); 
     365      message = _T("Parsing failed: ") + ast_parser.rest; 
     366      return false; 
     367    } 
     368    if (data.bDebug) 
     369      NSC_DEBUG_MSG_STD(_T("Parsing succeeded: ") + ast_parser.result_as_tree()); 
     370 
     371    if (!ast_parser.derive_types(dummy) || dummy.has_error()) { 
     372      message = _T("Invalid types: ") + dummy.get_error(); 
     373      return false; 
     374    } 
     375    if (data.bDebug) 
     376      NSC_DEBUG_MSG_STD(_T("Type resolution succeeded: ") + ast_parser.result_as_tree()); 
     377 
     378    if (!ast_parser.static_eval(dummy) || dummy.has_error()) { 
     379      message = _T("Static evaluation failed: ") + dummy.get_error(); 
     380      return false; 
     381    } 
     382    if (data.bDebug) 
     383      NSC_DEBUG_MSG_STD(_T("Static evaluation succeeded: ") + ast_parser.result_as_tree()); 
     384 
     385    if (!ast_parser.bind(dummy) || dummy.has_error()) { 
     386      message = _T("Variable and function binding failed: ") + dummy.get_error(); 
     387      return false; 
     388    } 
     389    if (data.bDebug) 
     390      NSC_DEBUG_MSG_STD(_T("Binding succeeded: ") + ast_parser.result_as_tree()); 
     391    return true; 
     392  } 
     393  virtual bool match(EventLogRecord &record) { 
     394    filter::where::type_obj obj(&record); 
     395    //NSC_DEBUG_MSG_STD(_T("Evaluating: ") + ast_parser.result_as_tree() + _T(": ") + strEx::itos(record.severity()) + _T(" >> ") + strEx::itos(ast_parser.evaluate(obj))); 
     396    bool ret = ast_parser.evaluate(obj); 
     397    if (obj.has_error()) { 
     398      NSC_LOG_ERROR_STD(_T("Error: ") + obj.get_error()); 
     399 
     400    } 
     401    return ret; 
     402  } 
     403  std::wstring get_name() { 
     404    return _T("where"); 
     405  } 
     406}; 
     407 
     408 
     409 
     410void CheckEventLog::parse(std::wstring expr) { 
     411//return false; 
     412/* 
     413  my_type_obj obj1(123); 
     414  std::wcout << _T("Result (001): ") << ast_parser.evaluate(obj1) << std::endl; 
     415  my_type_obj obj2(321); 
     416  std::wcout << _T("Result (002): ") << ast_parser.evaluate(obj2) << std::endl; 
     417  */ 
     418} 
    47419 
    48420bool CheckEventLog::loadModule() { 
     
    58430    NSC_LOG_ERROR_STD(_T("Failed to register command.")); 
    59431  } 
     432  parse(_T("321 = 123")); 
     433  parse(_T("123 = 123")); 
     434  parse(_T("id = 123")); 
     435  parse(_T("id = 321")); 
     436 
     437  parse(_T("id = '123'")); 
     438  parse(_T("id = '321'")); 
     439 
     440  parse(_T("id = convert(123)")); 
     441  parse(_T("id = convert(321)")); 
     442 
     443  parse(_T("id = 123 AND 123 = 123 AND id = 123x")); 
     444  parse(_T("id = 123 AND 123 = 321 OR 123 = 456 OR 123 = 123")); 
     445   
     446  parse(_T("foo")); 
     447  parse(_T("1")); 
     448  parse(_T("foo = ")); 
     449  parse(_T("foo = 1")); 
     450  parse(_T("'foo' = 1")); 
     451  parse(_T("foo = '1'")); 
     452  parse(_T("'hello'='world'")); 
     453 
     454  parse(_T("foo = bar")); 
     455  parse(_T("foo = bar AND bar = foo")); 
     456  parse(_T("foo = bar AND bar = 1")); 
     457  parse(_T("foo = bar AND bar = foo OR foo = bar")); 
     458  parse(_T("foo = bar AND bar = 1 OR foo = 1")); 
     459  parse(_T(" foo = bar AND ( test > 120 OR foo < 123) OR ugh IN (123, 456, 789)")); 
     460 
     461  parse(_T("aaa = 111 OR bbb = 222 OR ccc = 333")); 
     462  parse(_T("(aaa = 111) OR bbb = 222 OR ccc = 333")); 
     463  parse(_T("(aaa = 111 OR bbb = 222) OR ccc = 333")); 
     464  parse(_T("(aaa = 111 OR bbb = 222 OR ccc = 333)")); 
     465  parse(_T("aaa = 111 OR (bbb = 222 OR ccc = 333)")); 
     466  parse(_T("aaa = 111 OR bbb = 222 OR (ccc = 333)")); 
     467  parse(_T("ccc = -333")); 
     468  parse(_T("ccc = -333 AND ccc = to_date('AABBCC', 1234)")); 
     469  parse(_T("aaa = 111 OR bbb = 222 OR (ccc = -333)")); 
     470  parse(_T("ccc = -333 AND ccc = to_date('AABBCC', 1234) OR aaa = 123x")); 
     471  parse(_T("ccc = -333 AND ccc = to_date('AABBCC', 1234) OR aaa = 123x OR 123r = foo123")); 
     472 
    60473  return true; 
    61474} 
     
    71484} 
    72485 
    73 namespace simple_registry { 
    74   class registry_exception { 
    75     std::wstring what_; 
    76   public: 
    77     registry_exception(std::wstring what) : what_(what) {} 
    78     registry_exception(std::wstring path, std::wstring what) : what_(path + _T(" -- ") + what) {} 
    79     registry_exception(std::wstring path, std::wstring key, std::wstring what) : what_(path + _T(".") + key + _T(" -- ") + what) {} 
    80     std::wstring what() { 
    81       return what_; 
    82     } 
    83   }; 
    84   class registry_key { 
    85     HKEY hKey_; 
    86     std::wstring path_; 
    87     BYTE *bData_; 
    88     TCHAR *buffer_; 
    89   public: 
    90     registry_key(HKEY hRootKey, std::wstring path) : path_(path), hKey_(NULL), bData_(NULL), buffer_(NULL) { 
    91       LONG lRet = ERROR_SUCCESS; 
    92       if (lRet = RegOpenKeyEx(hRootKey, path.c_str(), 0, KEY_QUERY_VALUE|KEY_READ, &hKey_) != ERROR_SUCCESS) 
    93         throw registry_exception(path, _T("Failed to open key: ") + error::format::from_system(lRet)); 
    94     } 
    95     ~registry_key() { 
    96       if (hKey_ != NULL) 
    97         RegCloseKey(hKey_); 
    98       delete [] bData_; 
    99       delete [] buffer_; 
    100     } 
    101     std::wstring get_string(std::wstring key, DWORD buffer_length = 2048) { 
    102       DWORD type; 
    103       std::wstring ret; 
    104       DWORD cbData = buffer_length; 
    105       delete [] bData_; 
    106       bData_ = new BYTE[cbData+2]; 
    107       // TODO: add get size here ! 
    108       LONG lRet = RegQueryValueEx(hKey_, key.c_str(), NULL, &type, bData_, &cbData); 
    109       if (lRet != ERROR_SUCCESS) 
    110         throw registry_exception(path_, key, _T("Failed to get value: ") + error::format::from_system(lRet)); 
    111       if (cbData >= buffer_length || cbData < 0) 
    112         throw registry_exception(path_, key, _T("Failed to get value: buffer to small")); 
    113       bData_[cbData] = 0; 
    114       if (type == REG_SZ) { 
    115         ret = reinterpret_cast<LPCTSTR>(bData_); 
    116       } else if (type == REG_EXPAND_SZ) { 
    117         std::wstring s = reinterpret_cast<LPCTSTR>(bData_); 
    118         delete [] buffer_; 
    119         buffer_ = new TCHAR[buffer_length+1]; 
    120         DWORD expRet = ExpandEnvironmentStrings(s.c_str(), buffer_, buffer_length); 
    121         if (expRet >= buffer_length) 
    122           throw registry_exception(path_, key, _T("Buffer to small (expand)")); 
    123         else 
    124           ret = buffer_; 
    125       } else { 
    126         throw registry_exception(path_, key, _T("Unknown type (not a string)")); 
    127       } 
    128       return ret; 
    129     } 
    130     DWORD get_int(std::wstring key) { 
    131       DWORD type; 
    132       DWORD cbData = sizeof(DWORD); 
    133       DWORD ret = 0; 
    134       LONG lRet = RegQueryValueEx(hKey_, key.c_str(), NULL, &type, reinterpret_cast<LPBYTE>(&ret), &cbData); 
    135       if (lRet != ERROR_SUCCESS) 
    136         throw registry_exception(path_, key, _T("Failed to get value: ") + error::format::from_system(lRet)); 
    137       if (type != REG_DWORD) 
    138         throw registry_exception(path_, key, _T("Unknown type (not a DWORD)")); 
    139       return ret; 
    140     } 
    141  
    142     std::list<std::wstring> get_keys(DWORD buffer_length = 2048) { 
    143       std::list<std::wstring> ret; 
    144       DWORD cSubKeys=0; 
    145       DWORD cMaxKeyLen; 
    146       // Get the class name and the value count.  
    147       LONG lRet = RegQueryInfoKey(hKey_,NULL,NULL,NULL,&cSubKeys,&cMaxKeyLen,NULL,NULL,NULL,NULL,NULL,NULL); 
    148       if (lRet != ERROR_SUCCESS) 
    149         throw registry_exception(path_, _T("Failed to query key info: ") + error::format::from_system(lRet)); 
    150       if (cSubKeys == 0) 
    151         return ret; 
    152       delete [] buffer_; 
    153       buffer_ = new TCHAR[cMaxKeyLen+20]; 
    154       for (unsigned int i=0; i<cSubKeys; i++) { 
    155         lRet = RegEnumKey(hKey_, i, buffer_, cMaxKeyLen+10); 
    156         if (lRet != ERROR_SUCCESS) { 
    157           throw registry_exception(path_, _T("Failed to enumerate: ") + error::lookup::last_error(lRet)); 
    158         } 
    159         std::wstring str = buffer_; 
    160         ret.push_back(str); 
    161       } 
    162       return ret; 
    163     } 
    164  
    165   }; 
    166    
    167   std::wstring get_string(HKEY hKey, std::wstring path, std::wstring key) { 
    168     registry_key reg(hKey, path); 
    169     return reg.get_string(key); 
    170   } 
    171 } 
    172486 
    173487std::wstring find_eventlog_name(std::wstring name) { 
     
    186500        if (real_name == name) 
    187501          return *cit; 
    188       } catch (simple_registry::registry_exception &e) {} 
     502      } catch (simple_registry::registry_exception &e) { e;} 
    189503    } 
    190504    return name; 
     
    198512} 
    199513 
    200 class EventLogRecord { 
    201   EVENTLOGRECORD *pevlr_; 
    202   __int64 currentTime_; 
    203   std::wstring file_; 
    204 public: 
    205   EventLogRecord(std::wstring file, EVENTLOGRECORD *pevlr, __int64 currentTime) : file_(file), pevlr_(pevlr), currentTime_(currentTime) { 
    206   } 
    207   inline __int64 timeGenerated() const { 
    208     return (currentTime_-pevlr_->TimeGenerated)*1000; 
    209   } 
    210   inline __int64 timeWritten() const { 
    211     return (currentTime_-pevlr_->TimeWritten)*1000; 
    212   } 
    213   inline std::wstring eventSource() const { 
    214     return reinterpret_cast<WCHAR*>(reinterpret_cast<LPBYTE>(pevlr_) + sizeof(EVENTLOGRECORD)); 
    215   } 
    216   inline DWORD eventID() const { 
    217     return (pevlr_->EventID&0xffff); 
    218   } 
    219   inline DWORD severity() const { 
    220     return (pevlr_->EventID>>30); 
    221   } 
    222  
    223   inline DWORD eventType() const { 
    224     return pevlr_->EventType; 
    225   } 
    226  
    227   std::wstring userSID() const { 
    228     if (pevlr_->UserSidOffset == 0) 
    229       return _T(""); 
    230     PSID p = reinterpret_cast<PSID>(reinterpret_cast<LPBYTE>(pevlr_) + + pevlr_->UserSidOffset); 
    231     DWORD userLen = 0; 
    232     DWORD domainLen = 0; 
    233     SID_NAME_USE sidName; 
    234  
    235     LookupAccountSid(NULL, p, NULL, &userLen, NULL, &domainLen, &sidName); 
    236     LPTSTR user = new TCHAR[userLen+10]; 
    237     LPTSTR domain = new TCHAR[domainLen+10]; 
    238  
    239     LookupAccountSid(NULL, p, user, &userLen, domain, &domainLen, &sidName); 
    240     user[userLen] = 0; 
    241     domain[domainLen] = 0; 
    242     std::wstring ustr = user; 
    243     std::wstring dstr = domain; 
    244     delete [] user; 
    245     delete [] domain; 
    246     if (!dstr.empty()) 
    247       dstr = dstr + _T("\\"); 
    248     if (ustr.empty() && dstr.empty()) 
    249       return _T("missing"); 
    250  
    251     return dstr + ustr; 
    252   } 
    253  
    254   std::wstring enumStrings() const { 
    255     std::wstring ret; 
    256     TCHAR* p = reinterpret_cast<TCHAR*>(reinterpret_cast<LPBYTE>(pevlr_) + pevlr_->StringOffset); 
    257     for (unsigned int i =0;i<pevlr_->NumStrings;i++) { 
    258       std::wstring s = p; 
    259       if (!s.empty()) 
    260         s += _T(", "); 
    261       ret += s; 
    262       p+= wcslen(p)+1; 
    263     } 
    264     return ret; 
    265   } 
    266  
    267   static DWORD appendType(DWORD dwType, std::wstring sType) { 
    268     return dwType | translateType(sType); 
    269   } 
    270   static DWORD subtractType(DWORD dwType, std::wstring sType) { 
    271     return dwType & (!translateType(sType)); 
    272   } 
    273   static DWORD translateType(std::wstring sType) { 
    274     if (sType == _T("error")) 
    275       return EVENTLOG_ERROR_TYPE; 
    276     if (sType == _T("warning")) 
    277       return EVENTLOG_WARNING_TYPE; 
    278     if (sType == _T("info")) 
    279       return EVENTLOG_INFORMATION_TYPE; 
    280     if (sType == _T("auditSuccess")) 
    281       return EVENTLOG_AUDIT_SUCCESS; 
    282     if (sType == _T("auditFailure")) 
    283       return EVENTLOG_AUDIT_FAILURE; 
    284     return strEx::stoi(sType); 
    285   } 
    286   static std::wstring translateType(DWORD dwType) { 
    287     if (dwType == EVENTLOG_ERROR_TYPE) 
    288       return _T("error"); 
    289     if (dwType == EVENTLOG_WARNING_TYPE) 
    290       return _T("warning"); 
    291     if (dwType == EVENTLOG_INFORMATION_TYPE) 
    292       return _T("info"); 
    293     if (dwType == EVENTLOG_AUDIT_SUCCESS) 
    294       return _T("auditSuccess"); 
    295     if (dwType == EVENTLOG_AUDIT_FAILURE) 
    296       return _T("auditFailure"); 
    297     return strEx::itos(dwType); 
    298   } 
    299   static DWORD translateSeverity(std::wstring sType) { 
    300     if (sType == _T("success")) 
    301       return 0; 
    302     if (sType == _T("informational")) 
    303       return 1; 
    304     if (sType == _T("warning")) 
    305       return 2; 
    306     if (sType == _T("error")) 
    307       return 3; 
    308     return strEx::stoi(sType); 
    309   } 
    310   static std::wstring translateSeverity(DWORD dwType) { 
    311     if (dwType == 0) 
    312       return _T("success"); 
    313     if (dwType == 1) 
    314       return _T("informational"); 
    315     if (dwType == 2) 
    316       return _T("warning"); 
    317     if (dwType == 3) 
    318       return _T("error"); 
    319     return strEx::itos(dwType); 
    320   } 
    321   std::wstring get_dll() { 
    322     try { 
    323       return simple_registry::get_string(HKEY_LOCAL_MACHINE, _T("SYSTEM\\CurrentControlSet\\Services\\EventLog\\") + file_ + (std::wstring)_T("\\") + eventSource(), _T("EventMessageFile")); 
    324     } catch (simple_registry::registry_exception &e) { 
    325       NSC_LOG_ERROR_STD(_T("Could not extract DLL for eventsource: ") + eventSource() + _T(": ") + e.what()); 
    326       return _T(""); 
    327     } 
    328   } 
    329  
    330   std::wstring render_message() { 
    331     std::vector<std::wstring> args; 
    332     TCHAR* *pArgs = new TCHAR*[pevlr_->NumStrings+1]; 
    333     TCHAR* p = reinterpret_cast<TCHAR*>(reinterpret_cast<LPBYTE>(pevlr_) + pevlr_->StringOffset); 
    334     for (unsigned int i =0;i<pevlr_->NumStrings;i++) { 
    335       args.push_back(p); 
    336       pArgs[i] = p; 
    337       DWORD len = wcslen(p); 
    338       p = &(p[len+1]); 
    339       //p += len+1; 
    340     } 
    341  
    342     std::wstring ret; 
    343     strEx::splitList dlls = strEx::splitEx(get_dll(), _T(";")); 
    344     for (strEx::splitList::const_iterator cit = dlls.begin(); cit != dlls.end(); ++cit) { 
    345       //std::wstring msg = error::format::message::from_module((*cit), eventID(), _sz); 
    346       std::wstring msg; 
    347       try { 
    348         msg = error::format::message::from_module_x64((*cit), eventID(), pArgs, pevlr_->NumStrings); 
    349         if (msg.empty()) { 
    350           msg = error::format::message::from_module_x64((*cit), pevlr_->EventID, pArgs, pevlr_->NumStrings); 
    351         } 
    352       } catch (...) { 
    353         msg = _T("Unknown exception getting message"); 
    354       } 
    355       strEx::replace(msg, _T("\n"), _T(" ")); 
    356       strEx::replace(msg, _T("\t"), _T(" ")); 
    357       std::string::size_type pos = msg.find_last_not_of(_T("\n\t ")); 
    358       if (pos != std::string::npos) { 
    359         msg = msg.substr(0,pos); 
    360       } 
    361       if (!msg.empty()) { 
    362         if (!ret.empty()) 
    363           ret += _T(", "); 
    364         ret += msg; 
    365       } 
    366     } 
    367     delete [] pArgs; 
    368     return ret; 
    369   } 
    370   SYSTEMTIME get_time(DWORD time) { 
    371     FILETIME FileTime, LocalFileTime; 
    372     SYSTEMTIME SysTime; 
    373     __int64 lgTemp; 
    374     __int64 SecsTo1970 = 116444736000000000; 
    375  
    376     lgTemp = Int32x32To64(time,10000000) + SecsTo1970; 
    377  
    378     FileTime.dwLowDateTime = (DWORD) lgTemp; 
    379     FileTime.dwHighDateTime = (DWORD)(lgTemp >> 32); 
    380  
    381     FileTimeToLocalFileTime(&FileTime, &LocalFileTime); 
    382     FileTimeToSystemTime(&LocalFileTime, &SysTime); 
    383     return SysTime; 
    384   } 
    385  
    386   SYSTEMTIME get_time_generated() { 
    387     return get_time(pevlr_->TimeGenerated); 
    388   } 
    389   SYSTEMTIME get_time_written() { 
    390     return get_time(pevlr_->TimeWritten); 
    391   } 
    392  
    393   std::wstring render(bool propper, std::wstring syntax, std::wstring date_format = DATE_FORMAT) { 
    394     if (propper) { 
    395       // To obtain the appropriate message string from the message file, load the message file with the LoadLibrary function and use the FormatMessage function 
    396       strEx::replace(syntax, _T("%message%"), render_message()); 
    397     } else { 
    398       strEx::replace(syntax, _T("%message%"), _T("%message% needs the descriptions flag set!")); 
    399     } 
    400  
    401     strEx::replace(syntax, _T("%source%"), eventSource()); 
    402     strEx::replace(syntax, _T("%generated%"), strEx::format_date(get_time_generated(), date_format)); 
    403     strEx::replace(syntax, _T("%written%"), strEx::format_date(get_time_written(), date_format)); 
    404     strEx::replace(syntax, _T("%type%"), translateType(eventType())); 
    405     strEx::replace(syntax, _T("%severity%"), translateSeverity(severity())); 
    406     strEx::replace(syntax, _T("%strings%"), enumStrings()); 
    407     strEx::replace(syntax, _T("%id%"), strEx::itos(eventID())); 
    408     strEx::replace(syntax, _T("%user%"), userSID()); 
    409     return syntax; 
    410   } 
    411 }; 
    412 /* 
    413 return (pevlr_->EventID&0xffff); 
    414 } 
    415 inline DWORD severity() const { 
    416 return (pevlr_->EventID>>30); 
    417 */ 
     514 
     515 
    418516class uniq_eventlog_record { 
    419517  DWORD ID; 
     
    433531 
    434532 
    435 struct eventlog_filter { 
    436   filters::filter_all_strings eventSource; 
    437   filters::filter_all_numeric<unsigned int, filters::handlers::eventtype_handler> eventType; 
    438   filters::filter_all_numeric<unsigned int, filters::handlers::eventseverity_handler> eventSeverity; 
    439   filters::filter_all_strings message; 
    440   filters::filter_all_times timeWritten; 
    441   filters::filter_all_times timeGenerated; 
    442   filters::filter_all_numeric<DWORD, filters::handlers::eventtype_handler> eventID; 
    443   std::wstring value_; 
    444  
    445   inline bool hasFilter() { 
    446     return eventSource.hasFilter() || eventType.hasFilter() || eventID.hasFilter() || eventSeverity.hasFilter() || message.hasFilter() ||  
    447       timeWritten.hasFilter() || timeGenerated.hasFilter(); 
    448   } 
    449  
    450 #define NSCP_EL_DEBUG(key) if (key.hasFilter()) strEx::append_list(str, std::wstring(_T( # key )) + _T(" ") + key.to_string(), _T(",")); 
    451   std::wstring to_string() const { 
    452     std::wstring str; 
    453     NSCP_EL_DEBUG(eventSource); 
    454     NSCP_EL_DEBUG(eventType); 
    455     NSCP_EL_DEBUG(eventSeverity); 
    456     NSCP_EL_DEBUG(eventID); 
    457     NSCP_EL_DEBUG(message); 
    458     NSCP_EL_DEBUG(timeWritten); 
    459     NSCP_EL_DEBUG(timeGenerated); 
    460     return str; 
    461   } 
    462   bool matchFilter(const EventLogRecord &value) const { 
    463     bool ret = false; 
    464     if ((eventSource.hasFilter())&&(eventSource.matchFilter(value.eventSource()))) 
    465       ret = true; 
    466     else if (eventSource.hasFilter()) 
    467       return false; 
    468     else if ((eventType.hasFilter())&&(eventType.matchFilter(value.eventType()))) 
    469       ret = true; 
    470     else if (eventType.hasFilter()) 
    471       return false; 
    472     else if ((eventSeverity.hasFilter())&&(eventSeverity.matchFilter(value.severity()))) 
    473       ret = true; 
    474     else if (eventSeverity.hasFilter()) 
    475       return false; 
    476     else if ((eventID.hasFilter())&&(eventID.matchFilter(value.eventID())))  
    477       ret = true; 
    478     else if (eventID.hasFilter()) 
    479       return false; 
    480     else if ((message.hasFilter())&&(message.matchFilter(value.enumStrings()))) 
    481       ret = true; 
    482     else if (message.hasFilter()) 
    483       return false; 
    484     else if ((timeWritten.hasFilter())&&(timeWritten.matchFilter(value.timeWritten()))) 
    485       ret = true; 
    486     else if (timeWritten.hasFilter()) 
    487       return false; 
    488     else if ((timeGenerated.hasFilter())&&(timeGenerated.matchFilter(value.timeGenerated()))) 
    489       ret = true; 
    490     else if (timeGenerated.hasFilter()) 
    491       return false; 
    492     return ret; 
    493   } 
    494 }; 
     533 
    495534 
    496535 
    497536#define MAP_FILTER(value, obj, filtermode) \ 
    498       else if (p__.first == value) { filter.obj = p__.second; if (bPush) { filter_chain.push_back(filteritem_type(filtermode, filter)); filter = eventlog_filter(); } } 
     537      else if (p__.first == value) { filter.obj = p__.second; if (bPush) { data.filters.push_back(filter_container::filteritem_type(filtermode, filter)); filter = eventlog_filter(); } } 
    499538#define MAP_FILTER_LAST(value, obj) \ 
    500       else if (p__.first == value) { filter_chain.front().second.obj = p__.second; } 
     539      else if (p__.first == value) { data.filters.front().second.obj = p__.second; } 
    501540 
    502541struct event_log_buffer { 
     
    520559  if (command != _T("CheckEventLog")) 
    521560    return NSCAPI::returnIgnored; 
     561  simple_timer time; 
    522562  typedef checkHolders::CheckContainer<checkHolders::MaxMinBoundsULongInteger> EventLogQuery1Container; 
    523563  typedef checkHolders::CheckContainer<checkHolders::ExactBoundsULongInteger> EventLogQuery2Container; 
    524564   
    525   typedef std::pair<int,eventlog_filter> filteritem_type; 
    526   typedef std::list<filteritem_type > filterlist_type; 
    527565  NSCAPI::nagiosReturn returnCode = NSCAPI::returnOK; 
    528566  std::list<std::wstring> stl_args = arrayBuffer::arrayBuffer2list(argLen, char_args); 
    529567 
    530568  std::list<std::wstring> files; 
    531   filterlist_type filter_chain; 
    532569  EventLogQuery1Container query1; 
    533570  EventLogQuery2Container query2; 
    534571 
     572 
     573  filter_container data(syntax_, debug_); 
     574 
    535575  bool bPerfData = true; 
    536   bool bFilterIn = true; 
    537   bool bFilterAll = false; 
    538576  bool bFilterNew = true; 
    539   bool bShowDescriptions = false; 
    540577  bool unique = false; 
    541578  unsigned int truncate = 0; 
    542   std::wstring syntax = syntax_; 
    543   const int filter_plus = 1; 
    544   const int filter_minus = 2; 
    545   const int filter_normal = 3; 
    546   const int filter_compat = 3; 
    547579  event_log_buffer buffer(buffer_length_); 
    548580  bool bPush = true; 
    549   bool bDebug = debug_; 
    550581  eventlog_filter filter; 
    551582  /* 
     
    564595      MAP_OPTIONS_STR2INT(_T("truncate"), truncate) 
    565596      MAP_OPTIONS_BOOL_TRUE(_T("unique"), unique) 
    566       MAP_OPTIONS_BOOL_TRUE(_T("descriptions"), bShowDescriptions) 
     597      MAP_OPTIONS_BOOL_TRUE(_T("descriptions"), data.bShowDescriptions) 
    567598      MAP_OPTIONS_PUSH(_T("file"), files) 
    568599      MAP_OPTIONS_BOOL_FALSE(IGNORE_PERFDATA, bPerfData) 
    569600      MAP_OPTIONS_BOOL_EX(_T("filter"), bFilterNew, _T("new"), _T("old")) 
    570       MAP_OPTIONS_BOOL_EX(_T("filter"), bFilterIn, _T("in"), _T("out")) 
    571       MAP_OPTIONS_BOOL_EX(_T("filter"), bFilterAll, _T("all"), _T("any")) 
    572       MAP_OPTIONS_BOOL_EX(_T("auto-push"), bPush, _T("true"), _T("false")) 
    573       MAP_OPTIONS_BOOL_EX(_T("debug"), bDebug, _T("true"), _T("false")) 
    574       MAP_OPTIONS_STR(_T("syntax"), syntax) 
     601      MAP_OPTIONS_BOOL_EX(_T("filter"), data.bFilterIn, _T("in"), _T("out")) 
     602      MAP_OPTIONS_BOOL_EX(_T("filter"), data.bFilterAll, _T("all"), _T("any")) 
     603      MAP_OPTIONS_BOOL_EX(_T("debug"), data.bDebug, _T("true"), _T("false")) 
     604      MAP_OPTIONS_STR2INT(_T("debug-threshold"), data.debugThreshold) 
     605      MAP_OPTIONS_STR(_T("syntax"), data.syntax) 
    575606      /* 
    576607      MAP_FILTER_OLD("filter-eventType", eventType) 
     
    582613      MAP_FILTER_OLD("filter-message", message) 
    583614*/ 
    584       MAP_FILTER(_T("filter+eventType"), eventType, filter_plus) 
    585       MAP_FILTER(_T("filter+severity"), eventSeverity, filter_plus) 
    586       MAP_FILTER(_T("filter+eventID"), eventID, filter_plus) 
    587       MAP_FILTER(_T("filter+eventSource"), eventSource, filter_plus) 
    588       MAP_FILTER(_T("filter+generated"), timeGenerated, filter_plus) 
    589       MAP_FILTER(_T("filter+written"), timeWritten, filter_plus) 
    590       MAP_FILTER(_T("filter+message"), message, filter_plus) 
    591  
    592       MAP_FILTER(_T("filter.eventType"), eventType, filter_normal) 
    593       MAP_FILTER(_T("filter.severity"), eventSeverity, filter_normal) 
    594       MAP_FILTER(_T("filter.eventID"), eventID, filter_normal) 
    595       MAP_FILTER(_T("filter.eventSource"), eventSource, filter_normal) 
    596       MAP_FILTER(_T("filter.generated"), timeGenerated, filter_normal) 
    597       MAP_FILTER(_T("filter.written"), timeWritten, filter_normal) 
    598       MAP_FILTER(_T("filter.message"), message, filter_normal) 
    599  
    600       MAP_FILTER(_T("filter-eventType"), eventType, filter_minus) 
    601       MAP_FILTER(_T("filter-severity"), eventSeverity, filter_minus) 
    602       MAP_FILTER(_T("filter-eventID"), eventID, filter_minus) 
    603       MAP_FILTER(_T("filter-eventSource"), eventSource, filter_minus) 
    604       MAP_FILTER(_T("filter-generated"), timeGenerated, filter_minus) 
    605       MAP_FILTER(_T("filter-written"), timeWritten, filter_minus) 
    606       MAP_FILTER(_T("filter-message"), message, filter_minus) 
     615      MAP_FILTER(_T("filter+eventType"), eventType, filter_container::filter_plus) 
     616      MAP_FILTER(_T("filter+severity"), eventSeverity, filter_container::filter_plus) 
     617      MAP_FILTER(_T("filter+eventID"), eventID, filter_container::filter_plus) 
     618      MAP_FILTER(_T("filter+eventSource"), eventSource, filter_container::filter_plus) 
     619      MAP_FILTER(_T("filter+generated"), timeGenerated, filter_container::filter_plus) 
     620      MAP_FILTER(_T("filter+written"), timeWritten, filter_container::filter_plus) 
     621      MAP_FILTER(_T("filter+message"), message, filter_container::filter_plus) 
     622 
     623      MAP_FILTER(_T("filter.eventType"), eventType, filter_container::filter_normal) 
     624      MAP_FILTER(_T("filter.severity"), eventSeverity, filter_container::filter_normal) 
     625      MAP_FILTER(_T("filter.eventID"), eventID, filter_container::filter_normal) 
     626      MAP_FILTER(_T("filter.eventSource"), eventSource, filter_container::filter_normal) 
     627      MAP_FILTER(_T("filter.generated"), timeGenerated, filter_container::filter_normal) 
     628      MAP_FILTER(_T("filter.written"), timeWritten, filter_container::filter_normal) 
     629      MAP_FILTER(_T("filter.message"), message, filter_container::filter_normal) 
     630 
     631      MAP_FILTER(_T("filter-eventType"), eventType, filter_container::filter_minus) 
     632      MAP_FILTER(_T("filter-severity"), eventSeverity, filter_container::filter_minus) 
     633      MAP_FILTER(_T("filter-eventID"), eventID, filter_container::filter_minus) 
     634      MAP_FILTER(_T("filter-eventSource"), eventSource, filter_container::filter_minus) 
     635      MAP_FILTER(_T("filter-generated"), timeGenerated, filter_container::filter_minus) 
     636      MAP_FILTER(_T("filter-written"), timeWritten, filter_container::filter_minus) 
     637      MAP_FILTER(_T("filter-message"), message, filter_container::filter_minus) 
    607638 
    608639      MAP_FILTER_LAST(_T("append-filter-eventType"), eventType) 
     
    614645      MAP_FILTER_LAST(_T("append-filter-message"), message) 
    615646 
     647      MAP_OPTIONS_STR(_T("filter"), data.filter) 
    616648 
    617649      MAP_OPTIONS_MISSING(message, _T("Unknown argument: ")) 
     
    637669  } 
    638670  bool buffer_error_reported = false; 
    639   if (bDebug) { 
     671 
     672  if (data.bDebug) { 
    640673    std::wstring str; 
    641     BOOST_FOREACH(filteritem_type item, filter_chain) { 
    642       if (item.first == filter_normal) 
     674    BOOST_FOREACH(filter_container::filteritem_type item, data.filters) { 
     675      if (item.first == filter_container::filter_normal) 
    643676        str += _T(". {"); 
    644       else if (item.first == filter_plus) 
     677      else if (item.first == filter_container::filter_plus) 
    645678        str += _T("+ {"); 
    646       else if (item.first == filter_minus) 
     679      else if (item.first == filter_container::filter_minus) 
    647680        str += _T("- {"); 
    648681      else  
     
    654687  } 
    655688 
    656   bDebug = false; 
     689  boost::shared_ptr<any_mode_filter> filter_impl; 
     690  if (bFilterNew) { 
     691    filter_impl = boost::shared_ptr<any_mode_filter>(new second_mode_filter(data)); 
     692  } else { 
     693    filter_impl = boost::shared_ptr<any_mode_filter>(new second_mode_filter(data)); 
     694  } if (!data.filter.empty()) { 
     695    filter_impl = boost::shared_ptr<any_mode_filter>(new where_mode_filter(data)); 
     696  } 
     697 
     698  if (!filter_impl) { 
     699    message = _T("Failed to initialize filter subsystem."); 
     700    return NSCAPI::returnUNKNOWN; 
     701  } 
     702 
     703  filter_impl->boot(); 
     704 
     705  NSC_DEBUG_MSG_STD(_T("Using: ") + filter_impl->get_name()); 
     706 
     707  if (!filter_impl->validate(message)) { 
     708    return NSCAPI::returnUNKNOWN; 
     709  } 
     710 
     711  NSC_DEBUG_MSG_STD(_T("Boot time: ") + strEx::itos(time.stop())); 
     712 
    657713  for (std::list<std::wstring>::const_iterator cit2 = files.begin(); cit2 != files.end(); ++cit2) { 
    658714    std::wstring name = *cit2; 
     
    672728    //DWORD dwThisRecord; 
    673729    DWORD dwRead, dwNeeded; 
    674  
    675730 
    676731    __time64_t ltime; 
     
    700755      EVENTLOGRECORD *pevlr = buffer.getBufferUnsafe();  
    701756      while (dwRead > 0) {  
    702         //bool bMatch = bFilterAll; 
    703         bool bMatch = !bFilterIn; 
    704757        EventLogRecord record((*cit2), pevlr, ltime); 
    705  
    706         if (filter_chain.empty()) { 
    707           message = _T("No filters specified try adding: filter+generated=>2d"); 
    708           return NSCAPI::returnUNKNOWN; 
    709         } 
    710  
    711  
    712         for (filterlist_type::const_iterator cit3 = filter_chain.begin(); cit3 != filter_chain.end(); ++cit3 ) { 
    713           std::wstring reason; 
    714           int mode = (*cit3).first; 
    715           bool bTmpMatched = (*cit3).second.matchFilter(record); 
    716           if (!bFilterNew) { 
    717             if (bFilterAll) { 
    718               if (!bTmpMatched) { 
    719                 bMatch = false; 
    720                 break; 
    721               } 
    722             } else { 
    723               if (bTmpMatched) { 
    724                 bMatch = true; 
    725                 break; 
    726               } 
    727             } 
    728           } else { 
    729             if ((mode == filter_minus)&&(bTmpMatched)) { 
    730               // a -<filter> hit so thrash item and bail out! 
    731               if (bDebug) 
    732                 NSC_DEBUG_MSG_STD(_T("Matched: - ") + (*cit3).second.to_string() + _T(" for: ") + record.render(bShowDescriptions, syntax)); 
    733               bMatch = false; 
    734               break; 
    735             } else if ((mode == filter_plus)&&(!bTmpMatched)) { 
    736               // a +<filter> missed hit so thrash item and bail out! 
    737               if (bDebug) 
    738                 NSC_DEBUG_MSG_STD(_T("Matched: + ") + (*cit3).second.to_string() + _T(" for: ") + record.render(bShowDescriptions, syntax)); 
    739               bMatch = false; 
    740               break; 
    741             } else if (bTmpMatched) { 
    742               if (bDebug) 
    743                 NSC_DEBUG_MSG_STD(_T("Matched: . (contiunue): ") + (*cit3).second.to_string() + _T(" for: ") + record.render(bShowDescriptions, syntax)); 
    744               bMatch = true; 
    745             } 
    746           } 
    747         } 
    748         bool match = false; 
    749         if ((!bFilterNew)&&((bFilterIn&&bMatch)||(!bFilterIn&&!bMatch))) { 
    750           match = true; 
    751         } else if (bFilterNew&&bMatch) { 
    752           match = true; 
    753         } 
     758        bool match = filter_impl->match(record); 
    754759        if (match&&unique) { 
    755760          match = false; 
     
    761766          } 
    762767          else { 
    763             if (!syntax.empty()) { 
    764               uniq_record.message = record.render(bShowDescriptions, syntax); 
    765             } else if (!bShowDescriptions) { 
     768            if (!data.syntax.empty()) { 
     769              uniq_record.message = record.render(data.bShowDescriptions, data.syntax); 
     770            } else if (!data.bShowDescriptions) { 
    766771              uniq_record.message = record.eventSource(); 
    767772            } else { 
     
    776781          hit_count++; 
    777782        } else if (match) { 
    778           if (!syntax.empty()) { 
    779             strEx::append_list(message, record.render(bShowDescriptions, syntax)); 
    780           } else if (!bShowDescriptions) { 
     783          if (!data.syntax.empty()) { 
     784            strEx::append_list(message, record.render(data.bShowDescriptions, data.syntax)); 
     785          } else if (!data.bShowDescriptions) { 
    781786            strEx::append_list(message, record.eventSource()); 
    782787          } else { 
     
    799804    } 
    800805  } 
     806  NSC_DEBUG_MSG_STD(_T("Evaluation time: ") + strEx::itos(time.stop())); 
    801807 
    802808  if (!bPerfData) { 
  • branches/stable/modules/CheckEventLog/CheckEventLog.h

    r170 r262  
    5252  } 
    5353 
     54  void parse(std::wstring expr); 
    5455 
    5556  bool hasCommandHandler(); 
  • branches/stable/modules/CheckEventLog/Jamfile

    r174 r262  
    88  ../../include/NSCHelper.cpp 
    99  ../../include/arrayBuffer.cpp 
     10 
     11 
     12  ../../include/parsers/ast.cpp 
     13  ../../include/parsers/grammar.cpp 
     14  ../../include/parsers/where.cpp 
    1015 
    1116  : # requirements 
Note: See TracChangeset for help on using the changeset viewer.