ag/osm_ag_insmanager.cpp

       1  // -*- C++ -*-
          // -----------------------------------------------------------------------------
          
          /*
           * Osmius and its code is copyright of Peopleware S.L. Spain.
           * http://www.peopleware.es
           *
           * This program is free software; you can redistribute it and/or modify
           * it under the terms of the GNU General Public License as published by
           * the Free Software Foundation; either version 2 of the License,   or
           * (  at your option ) any later version.
           *
           * This program is distributed in the hope that it will be useful,  
           * but WITHOUT ANY WARRANTY; without even the implied warranty of
           * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
           * GNU General Public License for more details.
           *
           * You should have received a copy of the GNU General Public License
           * along with this program; if not,   write to the Free Software
           * Foundation,   Inc.,   59 Temple Place,   Suite 330,   Boston,   MA 02111-1307 USA
           */
          
          // -----------------------------------------------------------------------------
          /**
          * @file osm_ag_insmanager.cpp
          * @brief Implementation file for instance and event manager for every agent.
          * Osmius - Peopleware.
          *
          * @author Jose Luis Marina <joseluis.marina@peopleware.es>
          * @date 01-APR-2006.
          *
          */
          // -----------------------------------------------------------------------------
          #include "osm_ag_insmanager.h"
          #include "../cm/osm_cfgmanager.h"
          
          //#include <ace/Log_Msg.h>
          
          #if defined (  ACE_WIN32 )
          #include <ace/OS.h>
          #endif /* (  ACE_WIN32 ) */
          
          // Specific module includes.
          #include <ace/Get_Opt.h>
          #include <ace/ARGV.h>
          //#include <ace/Recursive_Thread_Mutex.h>
          
          
          // -----------------------------------------------------------------------------
          // Forwarded declaration CREATE_OSMIUS_INSTANCE
          // -----------------------------------------------------------------------------
          /**
           * This funtion is used to create the appropiate instance type.
           * @param instance_name Input - Instance Name.
           * @param instance_type Input - Type of the instance - to be checked.
           * @param conn_info Input - If needed is a string used in the connect(   ) method.
           * @param instance Output - This funtion will make a new over this pointer.
           * @retval -1 in case of error. 0 for success.
           */
      60  extern int CREATE_OSMIUS_INSTANCE(  const ACE_TCHAR* instance_name,  
           const ACE_TCHAR* instance_type,  
           const ACE_TCHAR* conn_info ,  
           OSM_Instance_Base* &instance );
          
          // -----------------------------------------------------------------------------
          // Forwarded declaration CREATE_OSMIUS_EVENT
          // -----------------------------------------------------------------------------
          /**
           * This funtion is used to create the appropiate events and associated actions.
           * @param event_name Input - Name checked.
           * @param instance_type Input - Type of the instance - to be checked.
           * @param event_parameters Input - Parameters read from the config file.
           * @param seconds Input - Seconds to be called.
           * @param event Output - This funtion will make a new over this pointer.
           * @retval -1 in case of error. 0 for success.
           */
      77  extern int CREATE_OSMIUS_EVENT (  const ACE_TCHAR* event_name ,  
           const ACE_TCHAR* instance_type ,  
           const ACE_TCHAR* event_parameters,  
           int seconds ,  
           OSM_Event* &event );
          
          /*----------------------------------------------------------------------------*/
          /* OSM_Action_Base Implementation */
          /*----------------------------------------------------------------------------*/
          
          // OSM_Action_Base is an abstract class.
          // User (  programmer ) must implement execute(   ) and check_cmd_line(   ).
          
          /*----------------------------------------------------------------------------*/
          /* OSM_Event Implementation */
          /*----------------------------------------------------------------------------*/
          int
      94  OSM_Event::handle_timeout (  const ACE_Time_Value &tv,   const void * )
          {
           //if (  OSM_CfgManager::instance(   )->debug_mode(   ) )
           //{
           // ACE_DEBUG(  (  LM_DEBUG,  
           // ACE_TEXT(  "(  %P|%T ) OSM_Event: %s.%s.handle_timeout(  %d )\n" ),  
           // this->osm_instance_->idn_instance(   ),  this->typ_event_,   this->interval_ ) );
           //}
           ACE_Time_Value time_before = ACE_OS::gettimeofday(   );
           ACE_TCHAR aux_text[BUFSIZ+1]="" ;
           int value=0 ;
           OSM_Message* osmius_message=0 ;
           ACE_OS::last_error(  0 );
           // If something goes bad we must free this memory. Otherwise the msg_manager
           // must do it we it finish sending the message.
           ACE_NEW_NORETURN (  osmius_message,   OSM_Message );
           if (  0 != ACE_OS::last_error(   ) )
           {
           ACE_ERROR(  (  LM_ERROR,  
           ACE_TEXT(  
           "OSM_Event: handle_timeout(   ) Could not create new message. [%d]\n" ),  
           ACE_OS::last_error(   ) ) );
           return -1;
           }
           // ---------------------------------------------------------------------------
           // Form the new message field by field.
           // ---------------------------------------------------------------------------
           // -> TYP_MESSAGE
           osmius_message->typ_alarm(  OSM_TYP_ALARM_INFO );
          
           /// Typ_Agent is now the same as TYP_INSTANCE
           osmius_message->typ_agent (  this->osm_instance_->typ_instance(   ),   ACE_OS::strlen(  this->osm_instance_->typ_instance(   ) ) );
          
           // -> COD_MASTER
           if (  -1 == OSM_CfgManager::instance(   )->get_value_str(  "CODMST",  aux_text,  BUFSIZ ) )
           {
           ACE_ERROR_RETURN(  (  LM_ERROR,  
           ACE_TEXT(  "OSM_AG_Main: handle_timeout(   ) Could not get CODMST\n" ) ),  
           -1 );
           }
           osmius_message->idn_master (  aux_text,   ACE_OS::strlen(  aux_text ) );
          
           // -> COD_INSTANCE
           osmius_message->idn_instance (  this->osm_instance_->idn_instance(   ),   ACE_OS::strlen(  this->osm_instance_->idn_instance(   ) ) );
          
           // -> TYP_INSTANCE
           osmius_message->typ_instance (  this->osm_instance_->typ_instance(   ),   ACE_OS::strlen(  this->osm_instance_->typ_instance(   ) ) );
          
           // -> COD_MESSAGE
           osmius_message->typ_event (  this->typ_event_,   ACE_OS::strlen(  this->typ_event_ ) );
          
           // -> DAT_INIEVENT
           osmius_message->dti_inievent (  time_before );
          
           // -> VAL_MESSAGE
           osmius_message->num_value (  "",  0 );
          
           // -> VAL_TXT
           osmius_message->txt_message (  "NULL",  0 );
          
           ACE_Time_Value time_after;
           if (  0 == this->action_ )
           {
           ACE_ERROR(  (  LM_ERROR,  ACE_TEXT(  "OSM_Event: Action NOT DEFINED: %s [%s]\n" ),  
           this->typ_event_,  
           this->osm_instance_->idn_instance(   ) ) );
           delete osmius_message;
           return -1;
           }
          
           ACE_TCHAR event_text[OSM_MSG_MAXTXTLEN]="";
           ACE_TCHAR val_text[OSM_MSG_MAXTXTLEN]="";
           int val_len=OSM_MSG_MAXTXTLEN-1;
           char user_text[OSM_MSG_MAXLENGTH]="-";
          
           if (  -1 == this->osm_instance_->connect(   ) )
           {
           value = -1;
           time_after = ACE_OS::gettimeofday(   );
           osmius_message->dti_finevent(  time_after );
           osmius_message->typ_alarm (  OSM_TYP_ALARM_ERRO );
           const ACE_TCHAR failed[]="NO_CONNECT - Connection Failed";
          
           osmius_message->txt_message (  ACE_TEXT(  failed ),  sizeof(  ACE_TEXT(  failed ) ) );
           ACE_OS::sprintf(  aux_text,  "%d",  value );
           osmius_message->num_value (  aux_text,  ACE_OS::strlen(  aux_text ) );
           }
           else
           {
           int res=0;
           int recover = 0;
           if (  -1 == this->action_->execute(  this->cmd_line_ ,  
           ACE_OS::strlen(  this->cmd_line_ ) ,  
           this->timeout_ ,  
           val_text ,  
           val_len ,  
           value  ) )
           {
           res = -1;
           OSM_CfgManager::instance(   )->get_value_int(  "RECVRY",  &recover );
           if (  recover ) // Try to execute once again.
           {
           osm_instance_->disconnect(  1 );
           res = osm_instance_->connect(   );
           if (  -1 != res )
           {
           val_text[0]='\0';
           res = this->action_->execute(  this->cmd_line_ ,  
           ACE_OS::strlen(  this->cmd_line_ ),  
           this->timeout_ ,  
           val_text ,  
           val_len ,  
           value  );
           }
           }
           }
           if (  -1 == res )
           {
           ACE_ERROR(  (  LM_ERROR,  ACE_TEXT(  "OSM_Event: execute action failed: %s [%s] Instance=[%s]\n" ),  
           this->cmd_line_,  
           val_text,  
           this->osm_instance_->idn_instance(   ) ) );
           time_after = ACE_OS::gettimeofday(   );
           osmius_message->dti_finevent(  time_after );
           if (  this->is_code(  "AVAILABL" ) )
           {
           osmius_message->typ_alarm (  OSM_TYP_ALARM_CRIT );
           }
           else
           {
           osmius_message->typ_alarm (  OSM_TYP_ALARM_ERRO );
           }
           osmius_message->txt_message (  ACE_TEXT(  val_text ),  val_len );
           ACE_OS::sprintf(  aux_text,  "%d",  value );
           osmius_message->num_value (  aux_text,  ACE_OS::strlen(  aux_text ) );
           osm_instance_->disconnect(  1 ); // Force disconnection and free resources.
           }
           else
           {
           ACE_Time_Value time_after = ACE_OS::gettimeofday(   );
           time_after = ACE_OS::gettimeofday(   );
           osmius_message->dti_finevent(  time_after );
          
           event_text[0] = '\0';
           ACE_OS::sprintf(  aux_text,  "%d",  value );
           osmius_message->num_value (  aux_text,  ACE_OS::strlen(  aux_text ) );
           OSM_CfgManager::instance(   )->get_param (  (  const ACE_TCHAR* ) this->action(   )->ev_parameters(   ),   'T',  user_text,  OSM_MSG_MAXLENGTH -10 );
           if (  ACE_OS::strlen(  user_text ) )
           {
           ACE_OS::sprintf(  event_text,  "%s[%d] %s (  w:%d a:%d s:%d t:%d )",  user_text,  value,  val_text,  this->warn_limit_,  this->crit_limit_,  this->silent_mode_,  this->interval_ );
           }
           else
           {
           ACE_OS::sprintf(  event_text,  "%s:[%d] %s (  w:%d a:%d s:%d t:%d )",  this->action(   )->name(   ),  value,  val_text,  this->warn_limit_,  this->crit_limit_,  this->silent_mode_,  this->interval_ );
           }
           osmius_message->txt_message (  event_text,  ACE_OS::strlen(  ACE_TEXT(  event_text ) ) );
           }
           }
           this->last_value_ = value;
          
           //Try to disconnect
           if (  -1 == this->osm_instance_->disconnect(   ) )
           {
           ACE_ERROR(  (  LM_ERROR,  ACE_TEXT(  "OSM_Event: DISCONNECTION FAILED\n" ) ) );
           }
          
           // --------------------------------------------------------------------
           // Get the event criticity.
           // --------------------------------------------------------------------
           int cmp=1;
           int cri=OSM_TYP_ALARM_ERRO;
          
           if (  OSM_TYP_ALARM_ERRO != ACE_OS::atoi(  osmius_message->typ_alarm(   ) ) )
           {
           cri=OSM_TYP_ALARM_INFO;
           if (  -1 != this->compare_mode_ ) // We have limits to check.
           {
           if (  OSM_COMPARE_GREATER == this->compare_mode_ )
           {
           cmp =1;
           }
           else
           {
           cmp =-1;
           }
          
           if (  cmp*this->crit_limit_ <= cmp*value )
           {
           cri = OSM_TYP_ALARM_CRIT;
           }
           else
           {
           if (  cmp*this->warn_limit_ <= cmp*value )
           {
           cri = OSM_TYP_ALARM_WARN;
           }
           }
           }
           }
           osmius_message->typ_alarm(  cri );
           if (  (  this->silent_mode_ ) && (  cri == this->last_alarm_type_ ) ) //Last time we were also critical or warning or info or error
           {
           delete osmius_message;
           return 0;
           }
          
           this->last_alarm_type_ = cri;
          
          
           // Prepare the message to be sent.
           osmius_message->encode(   );
          
           // Only for debugging.
           // osmius_message->print(   );
          
           // Wrap the OSM_Message into ACE_Message_Block
           ACE_Message_Block* mblk=0;
           ACE_NEW_NORETURN(  mblk,  ACE_Message_Block(  (  char* )osmius_message,   sizeof(  osmius_message ) ) );
          
           // This is important!!
           // We must set the write pointer to the end of data so length(   ) could return
           // the correct value.
           mblk->wr_ptr(   sizeof(  OSM_MessageHeader )
           + ACE_OS::strlen(  osmius_message->net_message_.data_ ) );
           // The message manager is now the responsible for the message.
           // The pointer to the instance manager is in our osm_instance owner.
           if (  -1==this->osm_instance_->ins_manager(   )->put(  mblk,  0 ) )
           {
           ACE_ERROR(  (  LM_ERROR,  
           ACE_TEXT(  "OSM_Event: Could not put Message into Ins_Manager\n" ) ) );
           delete osmius_message;
           delete mblk;
           }
           return 0;
          };
          
          /*----------------------------------------------------------------------------*/
          int
     332  OSM_Event::open(  const ACE_TCHAR* name ,   OSM_Instance_Base* instance ,  
           const int interval ,  
           const int i_delay ,  
           const int timeout ,  
           const int mode ,  
           const int warn ,  
           const int alar ,  
           const int silent ,  
     340   const ACE_TCHAR* ev_params )
          {
           if (  OSM_CfgManager::instance(   )->debug_mode(   ) )
           {
           ACE_DEBUG(  (  LM_DEBUG,  
           ACE_TEXT(  "(  %P|%T ) OSM_Event: open(   ) Instance:[%s] - Event [%s]\n" ),  
           instance->idn_instance(   ),   name ) );
           }
           this->last_alarm_type_ = -1;
           ACE_OS::strncpy(  this->typ_event_,   name,  OSM_Message::CODLEN );
           this->typ_event_[OSM_Message::CODLEN]=0;
           this->osm_instance_ = instance;
          
           if (  interval > 0 )
           this->interval_ = interval;
           else
           this->interval_ = 1;
          
           if (  i_delay > 0 )
           this->initial_delay_ = i_delay;
           else
           this->initial_delay_ = 1;
          
           if (  timeout < 0 )
           this->timeout_=0;
           else
           this->timeout_=timeout;
          
           if (  0 != ev_params )
           this->action_->ev_parameters(  ev_params );
          
           this->compare_mode_ = mode;
           this->warn_limit_ = warn;
           this->crit_limit_ = alar;
           this->warn_limit_ = warn;
           this->silent_mode_ = silent;
           // Register ourselves with the Reactor.
           ACE_Time_Value tv_interval(  this->interval_ );
           ACE_Time_Value tv_delay(  this->initial_delay_ );
           if (  -1 == (  this->timer_id_ =
           this->reactor(   )->schedule_timer(  this,   0,   tv_delay,  tv_interval ) ) )
           {
           ACE_ERROR(  (  LM_ERROR,  
           ACE_TEXT(  "OSM_Event: open(   ) Could not schedule timer: %s\n" ),  
           name ) );
           return -1;
           }
          
           this->action(   )->set_name(  name );
          
           return 0;
          }
          /*----------------------------------------------------------------------------*/
          int
     394  OSM_Event::close(  void )
          {
           if (  OSM_CfgManager::instance(   )->debug_mode(   ) )
           {
           ACE_DEBUG(  (  LM_DEBUG,  
           ACE_TEXT(  "(  %P|%T ) OSM_Event: close(   ) Instance:[%s] - Event [%s]\n" ),  
           this->osm_instance_->idn_instance(   ),   this->typ_event_ ) );
           }
           // Third param -> Dont_Call_Handle_Close
           if (  -1 == this->reactor(   )->cancel_timer(  this->timer_id_,  0,  0 ) )
           {
           ACE_ERROR(  (  LM_ERROR,  
           ACE_TEXT(  "OSM_Event: close(   ) Could not cancel timer: %d\n" ),  
           this->timer_id_ ) );
           }
          
           delete this->action_;
           this->action_=0;
          
           return 0;
          }
          
          /*----------------------------------------------------------------------------*/
          /* OSM_AG_InsManager Implementation */
          /*----------------------------------------------------------------------------*/
          // Static initialization.
          OSM_AG_InsManager *OSM_AG_InsManager::instance_ = 0;
          
          /*----------------------------------------------------------------------------*/
     423  OSM_AG_InsManager* OSM_AG_InsManager::instance (  void )
          {
           if (  0 == OSM_AG_InsManager::instance_ )
           ACE_NEW_RETURN (  OSM_AG_InsManager::instance_,   OSM_AG_InsManager(  OSM_AG_MsgManager::instance(   ) ),   0 );
           return OSM_AG_InsManager::instance_;
          }
          
          /*----------------------------------------------------------------------------*/
          int
     432  OSM_AG_InsManager::create_instances(  void )
          {
           const ACE_TCHAR ins_section[]="OSMIUS_INSTANCES";
          
           ACE_OS::last_error(  0 );
           ACE_Ini_ImpExp import_cfg(  this->cfg_ );
          
           if (  import_cfg.import_config(  ACE_TEXT(  this->config_file_ ) ) )
           {
           ACE_ERROR_RETURN (  (  LM_ERROR,  ACE_TEXT (  
           "INS_Manager: create_instances(  %s ) import_config failed\n" ),  
           this->config_file_ ),  -1 );
           }
           if (  cfg_.open_section(  cfg_.root_section(   ),   ACE_TEXT(  ins_section ),  
           0 ,   this->cfg_section_ ) )
           {
           ACE_ERROR_RETURN (  (  LM_ERROR,  
           ACE_TEXT (  "INS_Manager: create_instances(  %s ) open_sectionfailed )\n" ),  
           ins_section ),  -1 );
           }
          
           // Count instances.
           int s1=0;
           ACE_TString buff;
           while (  !this->cfg_.enumerate_sections(  this->cfg_section_,  s1,  buff ) )
           {
           s1++;
           }
          // ACE_DEBUG(  (  LM_DEBUG,  ACE_TEXT(  
          // "(  %P|%T ) INS_Manager - create_instances(   ): Number of Detected Instances: %d \n" ),  s1 ) );
          
           // Create the instance array container with the number of elements equal to
           // the number of instances read from the configuration file.
           this->osm_instance_array_ = 0;
           this->osm_instance_array_ = new OSM_Instance_Base*[s1];
           if (  0 == this->osm_instance_array_ )
           {
           ACE_ERROR_RETURN (  (  LM_ERROR,  
           ACE_TEXT (  "INS_Manager: Could not create Instance Array [%d]\n" ),  
           s1 ),  -1 );
           }
           this->osm_instance_number_ = 0;
          
           int ii;
           for (  ii=0;ii < s1;ii++ ) this->osm_instance_array_[ii]=0;
          
           ACE_Configuration_Section_Key instance_section;
           ACE_TString type_buff;
           ACE_TString conn_buff;
          
           // Start reading from the begining.
           int s2 = 0;
           while (  !this->cfg_.enumerate_sections(  this->cfg_section_,  s2,  buff ) )
           {
           s2++;
           if (  s2 > s1 ) break; // More instances than the first time?
           // -------------------------------------------------------------------------
           // Get the instance Type and Connection info from the config_file
           // [OSMIUS_INSTANCES]->[INSTANCENAME]->TYPE=XXXXXXXX,   CONNECTION_INFO=XXXXX
           // BLACKOUT=XXXXXXXXXXXX
           // -------------------------------------------------------------------------
           if (  cfg_.open_section(  this->cfg_section_,   ACE_TEXT(  buff.c_str(   ) ),  
           0 ,  instance_section ) )
           {
           ACE_ERROR_RETURN(  (  LM_ERROR,  
           ACE_TEXT (  "INS_Manager: Could not open [%s] section!!\n" ),  
           buff.c_str(   ) ),  -1 );
           }
           if (  -1== this->cfg_.get_string_value (  instance_section,  ACE_TEXT(  "TYPE" ),  
           type_buff ) )
           {
           ACE_ERROR_RETURN (  (  LM_ERROR,  
           ACE_TEXT (  "INS_Manager: Could not get TYPE for [%s].\n" ),  
           buff.c_str(   ) ),  -1 );
           }
          
           if (  -1== this->cfg_.get_string_value (  instance_section,  
           ACE_TEXT(  "CONNECTION_INFO" ),  
           conn_buff ) )
           {
           ACE_ERROR_RETURN (  (  LM_ERROR,  
           ACE_TEXT (  "INS_Manager: Could not get CONNECTION_INFO for [%s].\n" ),  
           buff.c_str(   ) ),  -1 );
           }
           if (  OSM_CfgManager::instance(   )->debug_mode(   ) )
           {
           ACE_DEBUG(  (  LM_DEBUG,  ACE_TEXT(  "\t[%s] - %s\n" ),  
           buff.c_str(   ),  type_buff.c_str(   ) ) );
           }
           this->osm_instance_array_[this->osm_instance_number_] = 0;
          
           if (  -1 == CREATE_OSMIUS_INSTANCE(  
           buff.c_str(   ) ,  
           type_buff.c_str(   ) ,  
           conn_buff.c_str(   ) ,  
           this->osm_instance_array_[this->osm_instance_number_] ) )
           {
           ACE_ERROR_RETURN(  (  LM_ERROR,  
           ACE_TEXT (  "INS_Manager: Could not create instance %d [%s] type [%s]\n" ),  
           s2,  buff.c_str(   ),  type_buff.c_str(   ) ),  -1 );
           }
          
           // -------------------------------------------------------------------------
           // Open the instance
           // -------------------------------------------------------------------------
           int num_events=0;
           if (  -1 == this->osm_instance_array_[this->osm_instance_number_]->open(  
           this->config_file_ ,  
           buff.c_str(   ) ,  
           type_buff.c_str(   ) ,  
           conn_buff.c_str(   ) ,  
           this ,  
           &num_events ) )
           {
           ACE_ERROR_RETURN(  (  LM_ERROR,  
           ACE_TEXT (  "INS_Manager: Could not open instance %d [%s] type\n" ),  
           s2,  buff.c_str(   ) ),  -1 );
           }
          
           this->osm_instance_number_ = s2;
           }
          
           if (  s1 != s2  )
           {
           ACE_ERROR (  (  LM_ERROR,  ACE_TEXT (  
           "INS_Manager - create_instances(   ) Initial instances: %d End: %d\n" ),  
           s1,   s2 ) );
           }
          
           return 0;
          }
          
          
          /*----------------------------------------------------------------------------*/
          int
     567  OSM_AG_InsManager::destroy_instances(  void )
          {
           int i;
           int result=0;
          
           for (  i=0;i<this->osm_instance_number_;i++ )
           {
           if (  OSM_CfgManager::instance(   )->debug_mode(   ) )
           {
           ACE_DEBUG(  (  LM_DEBUG,  ACE_TEXT(  
           "(  %P|%T ) INS_Manager - destroy_instances(   ): index[%d] [%s]-[%s]\n" ),  
           i,  
           this->osm_instance_array_[i]->idn_instance(   ),  
           this->osm_instance_array_[i]->typ_instance(   ) ) );
           }
          
           if (  -1 == this->osm_instance_array_[i]->close(   ) )
           {
           result = -1;
           ACE_ERROR (  (  LM_ERROR,  ACE_TEXT (  
           "INS_Manager - destroy_instances(   ) Error closing: %d [%s]\n" ),  
           i,   this->osm_instance_array_[i]->idn_instance(   ) ) );
           }
           if (  0 != this->osm_instance_array_[i] )
           {
           delete this->osm_instance_array_[i];
           this->osm_instance_array_[i] = 0;
           }
           }
           if (  this->osm_instance_number_ )
           {
           delete [] this->osm_instance_array_;
           }
           this->osm_instance_number_ = 0;
          
           return result;
          }
          /*----------------------------------------------------------------------------*/
          int
     606  OSM_AG_InsManager::init (  int argc,   ACE_TCHAR *argv[] )
          {
           // ---------------------------------------------------------------------------
           // Parse Command Line.
           // ---------------------------------------------------------------------------
           ACE_Get_Opt get_opt (  argc,   argv,   ACE_TEXT (  "c:" ),   0 );
           get_opt.long_option (  ACE_TEXT (  "config_file" ),   'c',  
           ACE_Get_Opt::ARG_REQUIRED );
          
           for (  int c; (  c = get_opt (   ) ) != -1; )
           {
           switch (  c )
           {
           case 'c':
           ACE_OS::strsncpy(  this->config_file_,   get_opt.opt_arg (   ),   MAXPATHLEN );
           break;
           }
           }
          
           if (  OSM_CfgManager::instance(   )->debug_mode(   ) )
           {
           ACE_DEBUG(  (  LM_DEBUG,  ACE_TEXT(  
           "(  %P|%T ) INS_Manager - init(   ) Conf File: [%s]\n" ),  this->config_file_ ) );
           }
          
           if (  -1 == this->cfg_.open(   ) )
           {
           ACE_ERROR_RETURN(  (  LM_ERROR,  
           ACE_TEXT(  "INS_Manager - init_work(   )open(  [%s] )\n" ),  
           this->config_file_ ),  -1 );
           }
           // ---------------------------------------------------------------------------
           // Create instances objects reading from config_file.
           // ---------------------------------------------------------------------------
           if (  -1 == this->create_instances(   ) )
           {
           destroy_instances(   );
           return -1;
           }
          
           if (  OSM_CfgManager::instance(   )->debug_mode(   ) )
           {
           ACE_DEBUG(  (  LM_DEBUG,  ACE_TEXT(  
           "(  %P|%T ) INS_Manager- init_work(   ) Osmius Instances Created: %d\n" ),  
           this->osm_instance_number_ ) );
           }
          
           return 0;
          }
          
          /*----------------------------------------------------------------------------*/
          int
     658  OSM_AG_InsManager::fini (   )
          {
           if (  OSM_CfgManager::instance(   )->debug_mode(   ) )
           {
           ACE_DEBUG(  (  LM_DEBUG,  
           ACE_TEXT(  "(  %P|%T ) INS_Manager - fini(   ). Exit service......\n" ) ) );
           }
           if (  -1 == this->destroy_instances(   ) )
           {
           return -1;
           }
          
           return 0;
          }
          
          /*----------------------------------------------------------------------------*/
          int
     675  OSM_AG_InsManager::reload (   )
          {
           if (  OSM_CfgManager::instance(   )->debug_mode(   ) )
           {
           ACE_DEBUG(  (  LM_DEBUG,  ACE_TEXT(  "(  %P|%T ) INS_Manager - reload(   )...........\n" ) ) );
           }
           if (  -1 == this->destroy_instances(   ) )
           {
           return -1;
           }
           if (  -1 == this->create_instances(   ) )
           {
           return -1;
           }
           if (  OSM_CfgManager::instance(   )->debug_mode(   ) )
           {
           ACE_DEBUG(  (  LM_DEBUG,  ACE_TEXT(  "(  %P|%T ) INS_Manager - reload(   ) Ok.\n" ) ) );
           }
           return 0;
          
          }
          
          /*----------------------------------------------------------------------------*/
          /* OSM_Instance_Base Implementation */
          /*----------------------------------------------------------------------------*/
          int
     701  OSM_Instance_Base::open(  const ACE_TCHAR* config_file ,  
     702   const ACE_TCHAR* idn_instance ,  
     703   const ACE_TCHAR* typ_instance ,  
     704   const ACE_TCHAR* conn_info ,  
     705   OSM_AG_InsManager* ins_man ,  
           int* event_num )
          {
          
           this->event_array_ = 0;
           this->event_number_ = 0;
          
           if (  OSM_CfgManager::instance(   )->debug_mode(   ) )
           {
           ACE_DEBUG(  (  LM_DEBUG,  ACE_TEXT(  
           "(  %P|%T ) INS_Base - open(   ) Config File: [%s] Instance: [%s]-[%s]...\n" ),  
           config_file,  idn_instance,  typ_instance ) );
           }
           if (  0 == ins_man )
           {
           ACE_ERROR_RETURN(  (  LM_ERROR,  
           ACE_TEXT(  "INS_Base - open(   ) Bad Instance Manager Pointer\n" ) ),  -1 );
           }
           this->ins_manager_ = ins_man;
          
           this->event_number_ = 0;
          
           if (  ACE_OS::strlen(  idn_instance ) > OSM_Message::CODLEN )
           {
           ACE_ERROR_RETURN(  (  LM_ERROR,  
           ACE_TEXT(  "INS_Base - open(   ) Bad instance code length\n" ) ),  -1 );
           }
          
           ACE_OS::strcpy(  this->idn_instance_,  idn_instance );
           ACE_OS::strcpy(  this->config_file_,  config_file );
           if (  ACE_OS::strlen(  conn_info ) > BUFSIZ )
           {
           ACE_ERROR_RETURN(  (  LM_ERROR,  
           ACE_TEXT(  "INS_Base - open(   ) Bad Connection info length\n" ) ),  -1 );
           }
          
           ACE_OS::strcpy(  this->connection_info_,  conn_info );
          
           if (  ACE_OS::strlen(  typ_instance ) > OSM_Message::TYPLEN )
           {
           ACE_ERROR_RETURN(  (  LM_ERROR,  
           ACE_TEXT(  "INS_Base - open(   ) Bad Instance Type length\n" ) ),  -1 );
           }
           ACE_OS::strcpy(  this->typ_instance_,  typ_instance );
           // ---------------------------------------------------------------------------
           // Create event objects reading from config_file.
           // ---------------------------------------------------------------------------
           if (  -1 == this->create_events(   ) )
           {
           destroy_events(   );
           return -1;
           }
          
           if (  OSM_CfgManager::instance(   )->debug_mode(   ) )
           {
           ACE_DEBUG(  (  LM_DEBUG,  ACE_TEXT(  
           "(  %P|%T ) INS_Base - open(   ) Osmius Events Created: %d\n" ),  
           this->event_number_ ) );
           }
          
           *event_num = this->event_number_;
          
           return 0;
          }
          
          /*----------------------------------------------------------------------------*/
          int
     772  OSM_Instance_Base::destroy_events(  void )
          {
           int i;
           int result=0;
           for (  i=0;i<this->event_number_;i++ )
           {
           if (  OSM_CfgManager::instance(   )->debug_mode(   ) )
           {
           ACE_DEBUG(  (  LM_DEBUG,  ACE_TEXT(  
           "(  %P|%T ) INS_Base - destroy_events(   ): %d [%s]\n" ),  
           i,  
           this->event_array_[i]->typ_event(   ) ) );
           }
          
           if (  -1 == this->event_array_[i]->close(   ) )
           {
           result = -1;
           ACE_ERROR (  (  LM_ERROR,  ACE_TEXT (  
           "INS_Base - destroy_events(   ) Error closing: %d [%s]\n" ),  
           i,   this->event_array_[i]->typ_event(   ) ) );
           }
           if (  0 != this->event_array_[i] )
           {
           delete this->event_array_[i];
           this->event_array_[i] = 0;
           }
           }
           delete [] this->event_array_;
           this->event_number_ = 0;
          
           return result;
          }
          
          /*----------------------------------------------------------------------------*/
          int
     807  OSM_Instance_Base::create_events(  void )
          {
           ACE_Configuration_Heap cfg;
           ACE_Configuration_Section_Key cfg_section;
          
           ACE_OS::last_error(  0 );
          
           if (  0 != cfg.open(   ) )
           {
           ACE_ERROR_RETURN (  (  LM_ERROR,  ACE_TEXT (  
           "INS_Base: open cfg failed - %d\n" ),  
           ACE_OS::last_error(   ) ),  -1 );
           }
          
           ACE_Ini_ImpExp import_cfg(  cfg );
          
           if (  import_cfg.import_config(  ACE_TEXT(  this->config_file_ ) ) )
           {
           ACE_ERROR_RETURN (  (  LM_ERROR,  ACE_TEXT (  
           "INS_Base: open(  %s ) import_config failed\n" ),  
           this->config_file_ ),  -1 );
           }
           // Open OSMIUS_INSTANCE section.
           if (  cfg.open_section(  cfg.root_section(   ),   ACE_TEXT(  "OSMIUS_INSTANCES" ),  
           0 ,   cfg_section ) )
           {
           ACE_ERROR_RETURN (  (  LM_ERROR,  
           ACE_TEXT (  "INS_Base: create_events(   ) open_section [root] failed )\n" ) ),  -1 );
           }
           // Open idn_instance section (  inside OSMIUS_INSTANCES )
           if (  cfg.open_section(  cfg_section,   ACE_TEXT(  this->idn_instance_ ),  
           0 ,   cfg_section ) )
           {
           ACE_ERROR_RETURN (  (  LM_ERROR,  
           ACE_TEXT (  "INS_Base: open(   ) open_section [%s]failed\n" ),  
           this->idn_instance_ ),  -1 );
           }
           // Open EVENTS section (  inside [OSMIUS_INSTANCES]->[COD_INSTANCE]->[EVENTS] )
           if (  cfg.open_section(  cfg_section,   ACE_TEXT(  "EVENTS" ),  
           0 ,   cfg_section ) )
           {
           ACE_ERROR_RETURN (  (  LM_ERROR,  
           ACE_TEXT (  "INS_Base: open(   ) open_section [%s]->[EVENTS]failed\n" ),  
           this->idn_instance_ ),  -1 );
           }
           ACE_Configuration::VALUETYPE type;
           u_int index1 = 0;
           ACE_TString s_name;
          
           // Get the events and create the array.
           while (  !cfg.enumerate_values(  cfg_section,  index1,  s_name,  type ) )
           {
           index1++;
           //if (  OSM_CfgManager::instance(   )->debug_mode(   ) )
           //{
           // ACE_DEBUG(  (  LM_DEBUG,  ACE_TEXT(  
           // "(  %P|%T ) INS_Base EVENT %d : [%s]\n" ),  index1,  s_name.c_str(   ) ) );
           //}
           }
          
           if (  OSM_CfgManager::instance(   )->debug_mode(   ) )
           {
           ACE_DEBUG(  (  LM_DEBUG,  ACE_TEXT(  
           "(  %P|%T ) INS_Base - create_events(   ) Number of Detected Events: %d\n" ),  
           index1 ) );
           }
           // Create the event array container with the number of elements equal to
           // the number of events read from the configuration file.
           this->event_array_ = 0;
           this->event_array_ = new OSM_Event*[index1];
           if (  0 == this->event_array_ )
           {
           ACE_ERROR_RETURN (  (  LM_ERROR,  
           ACE_TEXT (  "INS_Base: Could not create Event Array [%d]\n" ),  
           index1 ),  -1 );
           }
           this->event_number_ = 0;
           u_int ii;
           for (  ii=0;ii<index1;ii++ ) this->event_array_[ii]=0;
          
           // Start reading from the begining.
           u_int index2 = 0;
           int i_value=0;
           int i_mode=-1;
           int i_warning=0;
           int i_alarm=0;
           int i_silent=0;
          
           ACE_TString s_value;
          
           while (  !cfg.enumerate_values(  cfg_section,  index2,  s_name,  type ) )
           {
           index2++;
           if (  index2 > index1 ) break; // More events than the first time?
           // -------------------------------------------------------------------------
           // Get event value.
           // -------------------------------------------------------------------------
           if (  -1== cfg.get_string_value (  cfg_section,  
           ACE_TEXT(  s_name.c_str(   ) ),  
           s_value ) )
           {
           ACE_ERROR_RETURN (  (  LM_ERROR,  
           ACE_TEXT (  "INS_Manager: Could not get value for [%s].\n" ),  
           s_name.c_str(   ) ),  -1 );
           }
          
           if (  -1==this->parse_event_cmdline(  s_value.c_str(   ),  i_value,  i_mode,  i_warning,   i_alarm,   i_silent ) )
           {
           ACE_ERROR_RETURN (  (  LM_ERROR,  
           ACE_TEXT (  "INS_Manager: Could not parse this string(  %s ) for [%s].\n" ),  
           s_value.c_str(   ),  s_name.c_str(   ) ),  -1 );
           }
          
           this->event_array_[this->event_number_] = 0;
           if (  -1 == CREATE_OSMIUS_EVENT(  
           s_name.c_str(   ) ,  
           this->typ_instance_ ,  
           s_value.c_str(   ) ,  
           i_value ,  
           this->event_array_[this->event_number_] ) )
           {
           ACE_ERROR_RETURN(  (  LM_ERROR,  
           ACE_TEXT (  "INS_Base: Could not create event %d [%s] type [%s]:%d\n" ),  
           index2,  s_name.c_str(   ),  this->typ_instance_,  i_value ),  -1 );
           }
           // -------------------------------------------------------------------------
           // Open the event
           // -------------------------------------------------------------------------
           // int open(  const ACE_TCHAR* name ,   const OSM_Instance_Base* ins,  
           // const int interval,   const int i_delay,  
           // const int timeout ,  
           // const int up_limit=0 ,  const int lw_limit=0 )
           int initial_delay = i_value;
           if (  i_value > 299 ) // Five minutes
           {
           initial_delay = 1 + (  int ) (  300.0 * (  ACE_OS::rand(   ) / (  RAND_MAX + 1.0 ) ) );
           }
           if (  -1 == this->event_array_[this->event_number_]->open(  
           s_name.c_str(   ) ,  
           this ,  
           i_value ,  
           initial_delay ,  
           i_value ,  
           i_mode ,  
           i_warning ,  
           i_alarm ,  
           i_silent ,  
           s_value.c_str(   ) ) )
           {
           ACE_ERROR_RETURN(  (  LM_ERROR,  
           ACE_TEXT (  "INS_Manager: Could not open event %d [%s] type\n" ),  
           index2,  s_name.c_str(   ) ),  -1 );
           }
           this->event_array_[this->event_number_]->action(   )->instance(  this );
           this->event_number_ = index2;
           }
          
           return 0;
          };
          
          /*----------------------------------------------------------------------------*/
          int
     969  OSM_Instance_Base::close(  void )
          {
           if (  OSM_CfgManager::instance(   )->debug_mode(   ) )
           {
           ACE_DEBUG(  (  LM_DEBUG,  ACE_TEXT(  
           "INS_Base - close(   )\n" ) ) );
           }
           this->disconnect(  1 ); // Force = yes.
           return this->destroy_events(   );
          
          }
          
          /*----------------------------------------------------------------------------*/
          int
     983  OSM_Instance_Base::connect(  void )
          {
           // noop connect.
           return 0;
          }
          /*----------------------------------------------------------------------------*/
          int
     990  OSM_Instance_Base::disconnect(  const int force )
          {
           // noop disconnect.
           return 0;
          }
          /*----------------------------------------------------------------------------*/
          OSM_AG_InsManager*
     997   OSM_Instance_Base::ins_manager(   )
          {
           return this->ins_manager_;
          }
          
          /*----------------------------------------------------------------------------*/
          int
    1004  OSM_Instance_Base::parse_event_cmdline (  const ACE_TCHAR* cmdline,  
           int &value,  
           int &mode,  
           int &warn,  
           int &alar,  
           int &silent )
          {
           int opt_t=0;
           int opt_c=0;
           int opt_w=0;
           int opt_a=0;
           int opt_s=0;
          
           ACE_ARGV cmdline_args(  cmdline );
          
           ACE_Get_Opt get_opt (  cmdline_args.argc(   ),   cmdline_args.argv(   ),   ACE_TEXT (  "t:c:w:a:s" ),   0 );
          
           mode = -1;
           warn = alar = silent = 0;
          
           for (  int c; (  c = get_opt (   ) ) != -1;  )
           {
           switch (  c )
           {
           case 't':
           // Value for the period in seconds.
           value = ACE_OS::atoi(  get_opt.opt_arg (   ) );
           opt_t++;
           break;
           case 's':
           // Silent Mode
           silent = 1;
           opt_s++;
           break;
           case 'a':
           // Warning limit.
           alar = ACE_OS::atoi(  get_opt.opt_arg (   ) );
           opt_a++;
           break;
           case 'w':
           // Warning limit.
           warn = ACE_OS::atoi(  get_opt.opt_arg (   ) );
           opt_w++;
           break;
           case 'c':
           // Compare mode.
           mode = ACE_OS::atoi(  get_opt.opt_arg (   ) );
           opt_c++;
           break;
           default:
           break;
           return -1;
           }
           }
           if (  1 != opt_t )
           {
           return -1;
           }
          
           if (  mode > -1 )
           {
           if (  (  1 != opt_w )||(  1 != opt_a ) )
           {
           return -1;
           }
           }
          
           if (  (  OSM_Event::OSM_COMPARE_GREATER != mode ) && (  OSM_Event::OSM_COMPARE_LESS != mode )&& (  -1 != mode ) )
           {
           mode = -1;
           }
          
           return 0;
          }
          /*----------------------------------------------------------------------------*/
          int
    1080  OSM_Instance_Base::check_conn_info(  const ACE_TCHAR* conn_info )
          {
           // noop check.
           return 0;
          }
          /*----------------------------------------------------------------------------*/
          
          /*----------------------------------------------------------------------------*/
          /* OSM_ACT_ExecuteProcess Implementation */
          /*----------------------------------------------------------------------------*/
          int
    1091  OSM_ACT_ExecuteProcess::execute (  const ACE_TCHAR* cmd_line ,  const int cmd_len,  
           const int timeout,  
    1093   ACE_TCHAR* val_text,  
           int& val_len,  
           int & value  )
          {
          // // Uncomment this if you want to trace this function.
          // if (  OSM_CfgManager::instance(   )->debug_mode(   ) )
          // {
          // ACE_DEBUG(  (  LM_DEBUG,  
          // ACE_TEXT(  "(  %P|%T ) OSM_Action: execute(   ) [%s] TimeOut: %d\n" ),  
          // cmd_line,  timeout ) );
          // }
          
           value = -1;
          
           // Use your own command line checker method. See below.
           if (  0 == this->cmd_checked_ )
           {
           if (  -1 == this->check_cmd_line(  cmd_line,  cmd_len ) )
           {
           ACE_ERROR(  (  LM_ERROR,  
           ACE_TEXT(  "(  %P|%T ) OSM_Action : Bad command line [%s]\n" ),  
           cmd_line ) );
           ACE_OS::sprintf(  val_text,  "Bad command line" );
           val_len = ACE_OS::strlen(  val_text );
           return -1;
           }
           this->cmd_checked_ = 1;
           }
           // We could also check the command line parameters for our event into the cfg file.
           // EVENT = -t timeout [-c 0,  1 -w warn -a alarm -s(  ilent )]
          // if (  OSM_CfgManager::instance(   )->debug_mode(   ) )
          // {
          // ACE_DEBUG(  (  LM_DEBUG,  
          // ACE_TEXT(  "(  %P|%T ) OSM_Action: Config Parameters are [%s]\n" ),  
          // this->ev_parameters(   ) ) );
          // }
          
           // Do whatever you must do to get the value and its text.
           if (  0 > this->process_.execute(  cmd_line,   "",  "",  value ,  0,  val_text,  val_len ) )
           {
           ACE_ERROR (  (  LM_ERROR,  ACE_TEXT (  
           "ACT_ExecuteProcess - execute(   ) Failed command: [%s] exit code: %d.\n" ),  
           cmd_line,  
           value ) );
           }
          
           val_len=ACE_OS::strlen(  val_text );
          
           return 0;
          }
          /*----------------------------------------------------------------------------*/
          int
    1145  OSM_ACT_ExecuteProcess::check_cmd_line(  const ACE_TCHAR* cmd_line,  
           const int cmd_len )
          {
          // Uncomment this if you want to trace this function (  and run with "-d" )
          // if (  OSM_CfgManager::instance(   )->debug_mode(   ) )
          // {
          // ACE_DEBUG(  (  LM_DEBUG,  
          // ACE_TEXT(  "(  %P|%T ) OSM_Action: check_cmd_line(   ) [%s] %d\n" ),  
          // cmd_line,  cmd_len ) );
          // }
          
           return 0;
          }
          
          /*----------------------------------------------------------------------------*/
          /* OSM_ACT_IP4Interfaces Implementation */
          /*----------------------------------------------------------------------------*/
    1162  int OSM_ACT_IP4Interfaces::execute (  const ACE_TCHAR* cmd_line,  const int cmd_len,  
    1163   const int timeout ,  ACE_TCHAR* val_text ,  
           int& val_len ,  int& value  )
          {
           //Uncomment this if you want to trace this function.
           //if (  OSM_CfgManager::instance(   )->debug_mode(   ) )
           //{
           // ACE_DEBUG(  (  LM_DEBUG,  
           // ACE_TEXT(  "(  %P|%T ) OSM_Action: execute(   ) [%s] TimeOut: %d\n" ),  
           // cmd_line,  timeout ) );
           //}
          
           // Use your own command line checker method. See below.
          // if (  -1 == this->check_cmd_line(  cmd_line,  cmd_len ) )
          // {
          // ACE_ERROR(  (  LM_ERROR,  
          // ACE_TEXT(  "(  %P|%T ) OSM_Action : Bad command line [%s]\n" ),  
          // cmd_line ) );
          // return -1;
          // }
          
           // We could also check the command line parameters for our event into the cfg file.
           // EVENT = -t timeout [-c 0,  1 -w warn -a alarm -s(  ilent )]
           // if (  OSM_CfgManager::instance(   )->debug_mode(   ) )
           // {
           // ACE_DEBUG(  (  LM_DEBUG,  
           // ACE_TEXT(  "(  %P|%T ) OSM_Action: Config Parameters are [%s]\n" ),  
           // this->ev_parameters(   ) ) );
           // }
           int ret = ACE::get_ip_interfaces(  this->num_if_,   this->addr_array_ );
          
           if (  0 != ret )
           {
           ACE_ERROR(  (  LM_ERROR,  ACE_TEXT(  "(  %P|%T ) OSM_Action : could not get_ip_interfaces(   )\n" ) ) );
           value = -1;
           return -1;
           }
          
           value = 0;
           for (  size_t i=0; i < this->num_if_ ;i++ )
           {
           if (  AF_INET == this->addr_array_[i].get_type(   ) )
           {
           value++;
           }
           }
           if (  this->num_if_ )
           {
           delete [] this->addr_array_;
           this->addr_array_ = 0;
           }
           this->num_if_ = 0;
          
           ACE_OS::sprintf(  val_text,  "" );
           val_len=0;
           return 0;
          }
          /*----------------------------------------------------------------------------*/
          // Don't need this.
          //int OSM_ACT_IP4Interfaces::check_cmd_line(  const ACE_TCHAR* cmd_line,  
          // const int cmd_len )
          //{
          //}
          /*----------------------------------------------------------------------------*/
          /* OSM_ACT_IP6Interfaces Implementation */
          /*----------------------------------------------------------------------------*/
    1228  int OSM_ACT_IP6Interfaces::execute (  const ACE_TCHAR* cmd_line,  const int cmd_len,