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,  
    1229   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 )
           {
           value = -1;
           ACE_ERROR(  (  LM_ERROR,  ACE_TEXT(  "(  %P|%T ) OSM_Action : could not get_ip_interfaces(   )\n" ) ) );
           return -1;
           }
          
           value = 0;
           for (  size_t i=0; i < this->num_if_ ;i++ )
           {
           if (  AF_INET6 == 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_ScanLog Implementation */
          /*----------------------------------------------------------------------------*/
          int
    1296  OSM_ACT_ScanLog::execute (  const ACE_TCHAR* cmd_line ,  const int cmd_len ,  
    1297   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 ) );
          // }
          
           value = -1;
          
           // Use your own command line checker method. See below.
           if (  0 == this->cmd_line_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_line_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.
           ACE_stat f_stat;
           if (  ACE_OS::stat(  this->log_file_,  &f_stat ) )
           {
           ACE_ERROR(  (  LM_ERROR,  
           ACE_TEXT(  "(  %P|%T ) OSM_ACT_ScanLog : Cannot stat file [%s]\n" ),  
           this->log_file_ ) );
           ACE_OS::sprintf(  val_text,  "Cannot stat file [%s]",  this->log_file_ );
           val_len = ACE_OS::strlen(  val_text );
           return -1;
           }
          
           if (  f_stat.st_size < this->last_size_ )
           {
           this->last_size_ = 0;
           }
          
           if (  f_stat.st_size == this->last_size_ )
           {
           value=0;
           val_text[0] = 0;
           val_len = ACE_OS::strlen(  val_text );
           return 0;
           }
          
           this->fd_ = ACE_OS::fopen(  this->log_file_,  ACE_LIB_TEXT(  "r" ) );
           if (  0 == this->fd_ )
           {
           ACE_ERROR(  (  LM_ERROR,  
           ACE_TEXT(  "(  %P|%T ) OSM_ACT_ScanLog : Cannot open file [%s]\n" ),  
           this->log_file_ ) );
           ACE_OS::sprintf(  val_text,  "Cannot open file [%s]",  this->log_file_ );
           val_len = ACE_OS::strlen(  val_text );
           return -1;
           }
          
           this->auxbuf_[0] = 0;
           ACE_OS::fseek(  this->fd_,   this->last_size_,   SEEK_SET );
          
           value=0;
           char* p=0;
           while (  ACE_OS::fgets(  this->auxbuf_,  OSM_SCANLOG_BUFSIZ,   this->fd_ ) )
           {
           for (  int i=0; i < OSM_SCANLOG_BUFSIZ; i++ )
           {
           if (  (  0x0D == this->auxbuf_[i] ) || (  0x0A == this->auxbuf_[i] ) )
           {
           this->auxbuf_[i] = 0;
           break;
           }
           }
           p = ACE_OS::strstr(  this->auxbuf_,   this->string_ );
           if (  p )
           {
           value =1 ;
           ACE_OS::sprintf(  val_text,  "%s[%s] -> [%s]",  this->log_file_,  this->string_,   p );
           break;
           }
          
           this->auxbuf_[0] = 0;
           }
           this->last_size_ = f_stat.st_size;
          
           val_len=ACE_OS::strlen(  val_text );
          
           if (  0 != ACE_OS::fclose(  this->fd_ ) )
           {
           ACE_ERROR(  (  LM_ERROR,  
           ACE_TEXT(  "(  %P|%T ) OSM_ACT_ScanLog : Cannot close file [%s]\n" ),  
           this->log_file_ ) );
           }
          
           return 0;
          }
          /*----------------------------------------------------------------------------*/
          int
    1409  OSM_ACT_ScanLog::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 ) );
           //}
          
           // Check the Command Line.
           if (  this->cmd_line_checked_ )
           {
           return 0;
           }
          
           // Check the Command Line.
           int opt_l=0;
           int opt_s=0;
          
           ACE_ARGV cmd_args(  cmd_line );
           ACE_Get_Opt get_opt (  cmd_args.argc(   ),   cmd_args.argv(   ),   ACE_TEXT (  "l:s:" ),   0 );
          
           ACE_TCHAR aux[BUFSIZ+1];
           int len;
          
           for (  int c; (  c = get_opt (   ) ) != -1;  )
           {
           switch (  c )
           {
           case 'l':
           // LogFile full path
           ACE_OS::strcpy(  aux,  get_opt.opt_arg (   ) );
           len = ACE_OS::strlen(  aux );
           if (  (  len > BUFSIZ ) || (  len < 2 ) ) return -1;
           aux[len]='\0';
           ACE_OS::strcpy(  this->log_file_,  aux );
           opt_l++;
           break;
           case 's':
           // String to search
           ACE_OS::strcpy(  aux,  get_opt.opt_arg (   ) );
           len = ACE_OS::strlen(  aux );
           if (  (  len > BUFSIZ ) ) return -1;
           aux[len]='\0';
           ACE_OS::strcpy(  this->string_,  aux );
           opt_s++;
           break;
           default:
           break;
           }
           }
          
           if (  (  1 != opt_l ) || (  1!=opt_s ) ) // Logfile name and string to search are mandatory.
           {
           return -1;
           }
          
           this->cmd_line_checked_ = 1;
          
           return 0;
          }
          

ag/osm_ag_insmanager.h

       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.h
          * @brief Definition file for the main classes to build an Osmius agent and instance and event manager.
          * Osmius - Peopleware.
          *
          * @author Jose Luis Marina <joseluis.marina@peopleware.es>
          * @date 24-MAY-2006
          */
          // -----------------------------------------------------------------------------
          #ifndef _OSM_AG_INSMANAGER_H_
          #define _OSM_AG_INSMANAGER_H_
          
          //#if !defined (  ACE_LACKS_PRAGMA_ONCE )
          //# pragma once
          //#endif /* ACE_LACKS_PRAGMA_ONCE */
          
          //#include <ace/Event_Handler.h>
          //#include <ace/Reactor.h>
          //#include <ace/Configuration.h>
          
          #include "osm_ag_msgmanager.h"
          #include "../cm/osm_message.h"
          
          // Forwarded declaration.
      49  class OSM_Instance_Base;
          
          /**
           * @class OSM_Action_Base
           *
           * @brief Defines Base class to all action classes like execute query,   execute shell,   etc...
           *
           * We must derive from this class when creating a new action. An action is every
           * thing an event must execute to retrieve its own value. An action could be the
           * execution of an SQL query to Oracle or MySql,   or the execution of a command
           * under Solaris,   HP-UX,   AIX,   Linux or Windows boxes.
           *
           */
      62  class OSM_Action_Base
          {
          public:
           enum
           {
           OSM_MAX_ACTION_NAME_LEN = 8
           };
           /// Default Constructor
      70   OSM_Action_Base(   ) {};
          
           /// Destructor
      73   virtual ~OSM_Action_Base(   ) {};
          
           /// Returns 1 if the name of the action is equal to the name in the parameter.
      76   int is_name(  const ACE_TCHAR* nm )
           {
           if (  0 == ACE_OS::strncmp(  this->name_,  nm,  ACE_OS::strlen(  this->name_ ) ) )
           {
           return 1;
           }
          
           return 0;
           };
          
           /**
           * Executes the action using the command line and returns the associated text
           * and value.
           * @param cmd_line Input - Command line used to execute this action.
           * @param cmd_len Input - Command line length.
           * @param timeout Input - Wait timeout seconds before aborting execution.
           * @param val_text Output - Text of the resulting action.
           * @param val_len Output - Text length.
           * @param value Output - Final value of the action.
           * @retval -1 in case of error. 0 for success.
           */
      97   virtual int execute(  const ACE_TCHAR* cmd_line,  const int cmd_len ,  
      98   const int timeout ,  ACE_TCHAR* val_text,  
           int& val_len ,   int& value  ) = 0;
          
           /**
           * Checks the command line. You should overwrite this method to handle issues
           * like semantic and sintactic checking or security stuff.
           * E.g. You could return error if your SQL string contains the words UPDATE,  
           * DELETE or INSERT.
           * @param cmd_line Input - Command line used to execute this action.
           * @param cmd_len Input - Command line length.
           * @retval -1 in case of error. 0 for success.
           */
     110   virtual int check_cmd_line(  const ACE_TCHAR* cmd_line,  const int cmd_len ) {return 0;};
          
           /**
           * Sets the name of the action.
           * @param nm Input - Name.
           */
     116   void set_name(  const ACE_TCHAR* nm )
           {
           ACE_OS::strncpy(  name_,  nm,  OSM_MAX_ACTION_NAME_LEN );
           name_[OSM_MAX_ACTION_NAME_LEN]=0;
           };
          
           /**
           * Sets the instance.
           * @param ins Input - Instance pointer.
           */
     126   void instance(  OSM_Instance_Base* ins )
           {
           this->osm_instance_=ins;
           };
          
           /**
           * Return a pointer to the instance.
           */
     134   const OSM_Instance_Base* instance(  void ) const
           {
           return this->osm_instance_;
           };
          
           /**
           * Sets the parameters used in our Event config file.
           * @param param Input - Parameters (  command line like ).
           */
     143   void ev_parameters(  const ACE_TCHAR* param )
           {
           ACE_OS::strncpy(  ev_parameters_,  param,  BUFSIZ );
           ev_parameters_[BUFSIZ]=0;
           };
          
           /**
           * Return pointer to parameters.
           */
     152   const ACE_TCHAR* ev_parameters(  void ) const
           {
           return this->ev_parameters_;
           };
          
           /**
           * Return pointer to my name.
           */
     160   const ACE_TCHAR* name(  void ) const
           {
           return this->name_;
           };
          
          private:
           /// Parameter Key os name. Must be unique.
     167   ACE_TCHAR name_[OSM_MAX_ACTION_NAME_LEN + 1];
          
           /// We must know who our instance is to manage connection to different
           /// kind of instances (  ftp,   oracle,   mysql,   temperature sensor,  ... ) and
           /// specific data structures. We'll make it easy ; )
     172   OSM_Instance_Base* osm_instance_;
          
           /// Parameters located on the config file of our Event.
           /// We can choose to parse them and use or ignore them
     176   ACE_TCHAR ev_parameters_[BUFSIZ+1];
          
          };
          
          // Forwarded declaration.
     181  class OSM_AG_InsManager;
          
          /**
           * @class OSM_Event
           *
           * @brief Event class to monitor a certain event into an Osmius Instance.
           *
           * This class derives from ACE_Event_Handler so we can register timers with
           * the chosen Reactor implementation. It has implemented the handle_time_out(   )
           * hook method,   and this method in turn will call its associated action
           * execute(   ) method.
           * In the open(   ) method we'll register with the reactor,   keep our timed_id info,  
           * and check every thing. In close(   ) we'll cancel future timers,   deregister our-
           * selves with the Reactor and perform cleaning activities.
           */
     196  class OSM_Event : public ACE_Event_Handler
          {
          public:
          
          /// Compare types. 0-Greater Than 1-Less than
          enum OSM_TYP_COMPARE
          {
           OSM_COMPARE_GREATER=0,  
           OSM_COMPARE_LESS =1
          };
           /// Constructor.
     207   OSM_Event (  ACE_Reactor *r= ACE_Reactor::instance(   ) ):
           last_value_(  -1 ) ,   timer_id_(  -1 ),   interval_(  -1 ),  
           initial_delay_(  5 ),  
           compare_mode_(  -1 ),  warn_limit_(  -1 ),   crit_limit_(  -1 ) ,  
           silent_mode_(  0 ),   last_alarm_type_(  -1 )
           {this->reactor(  r );};
          
           /// Hook method called when object is signaled by timers.
     215   virtual int handle_timeout (  const ACE_Time_Value &tv,  
           const void * );
           /**
           * Initializes the Event parameters. An event is basically an action plus
           * a command line.
           * @param name Input - Event Name.
           * @param instance Input - This event creator instance.
           * @param interval Input - The reactor timer interval seconds.
           * @param i_delay Input - The reactor timer interval seconds.
           * @param timeout Input - Timeout for the action.
           * @param mode Input - Compare mode.
           * @param warn Input - Warning Limit
           * @param alar Input - Critical Alarm Limit
           * @param silent Input - Silent mode 0-Off 1-On
           * @param ev_params Input - Complete command line parameters in config file.
           * @retval -1 in case of error. 0 for success.
           */
     232   int open(  const ACE_TCHAR* name ,   OSM_Instance_Base* instance,  
           const int interval ,   const int i_delay,  
           const int timeout ,  
           const int mode=0 ,  
           const int warn=0 ,  
           const int alar=0 ,  
           const int silent=0 ,  
     239   const ACE_TCHAR* ev_params=0 );
          
           /**
           * Cleaning activities:
           * Cancel future timer calls.
           * Deregister the timer from the ACE Reactor framework.
           * Delete our action.
           * @retval -1 in case of error. 0 for success.
           */
     248   int close(  void );
          
           /// Returns 1 if the name of the action is equal to the name in the parameter.
     251   int is_code(  const ACE_TCHAR* nm )
           {
           if (  0 == ACE_OS::strncmp(  this->typ_event_,  nm,  ACE_OS::strlen(  this->typ_event_ ) ) )
           {
           return 1;
           }
          
           return 0;
           };
          
           /// Return a pointer to local typ_event.
     262   const ACE_TCHAR* typ_event(  void )
           {
           return this->typ_event_;
           };
          
           /// Return a pointer to command line char string.
     268   const ACE_TCHAR* cmd_line(  void )
           {
           return this->cmd_line_;
           };
           /// Sets the command line
     273   void cmd_line(  const ACE_TCHAR* cmd_line,  const int len )
           {
           int i;
           if (  len > BUFSIZ )
           {
           i = BUFSIZ;
           }
           else
           {
           i = len;
           }
           ACE_OS::strncpy(  cmd_line_,  cmd_line,  i );
           cmd_line_[i]=0;
           };
          
           /// Returns a pointer to the local action.
     289   OSM_Action_Base* action(  void )
           {
           return this->action_;
           }
          
           /// Set the action to be executed when this Event is called.
     295   void action(  OSM_Action_Base* action )
           {
           this->action_ = action;
           }
          
          private:
           /// Event Unique Code
     302   ACE_TCHAR typ_event_ [OSM_Message::CODLEN + 1];
           /// Command Line used to call action_->execute(  ... )
     304   ACE_TCHAR cmd_line_ [BUFSIZ+1];
           /// Value state returned in the last execution.
           // Just in case we need to remember it.
           int last_value_;
           /// When we register a timer with the ACE Reactor framework we get this number
           /// We'll use it to cancel the timer in configuration changes.
           long timer_id_;
           /// Time in seconds this event must be called back and execute an action.
     312   time_t interval_;
           /// Seconds to wait before the first timer expiration.
     314   time_t initial_delay_;
           /// Time in seconds to wait for hte action to complete.
     316   time_t timeout_;
           /// A pointer to our instance.
     318   OSM_Instance_Base* osm_instance_;
          
           /// Comparison Mode 0-greater 1-less
           int compare_mode_;
           /// Limit for warning.
           int warn_limit_;
           /// Limit for critical
           int crit_limit_;
           /// Silent mode 0-No 1-Yes
           /// If Yes we'll send only the message when there are changes of alarm type.
           int silent_mode_;
          
           /// Last Message alarm type.
           int last_alarm_type_;
          
           /// This is our way to execute this event.
     334   OSM_Action_Base* action_;
          
          };
          
          /**
           * @class OSM_Instance_Base
           *
           * @brief Instance class to monitor.It's a collection of event to supervise.
           *
           * This all Instances Base class with common stuff implemented letting us to -
           * using inheritance - only codify our instance type specific job. Reading
           * from the config file we must be able to create all the necessary objects and
           * start monitoring the instance.
           */
     348  class OSM_Instance_Base
          {
          public:
           /// Constructor.
     352   OSM_Instance_Base(   ) : event_number_(  0 ),   connected_(  0 ) {};
          
           /**
           * This procedure creates the array of events reading configuration from the
           * section [OSMIUS_INSTANCES]->[IDN]->[EVENTS] of the ConfigFile.
           * Also register the different events with the Reactor (  timers )
           * @param config_file Input - Configuration file.
           * @param idn_instance Input - Instance ID. Also is the section in the cfg file.
           * @param typ_instance Input - Instance Type.
           * @param con_info Input - Connection Info.
           * @param InsManager Input - Instance Manager pointer
           * @param event_num Output - Return the number of associated events.
           * @retval -1 in case of error. n > 1 for success n=number of events.
           */
     366   int open(  const ACE_TCHAR* config_file ,   const ACE_TCHAR* idn_instance ,  
     367   const ACE_TCHAR* typ_instance ,   const ACE_TCHAR* con_info ,  
     368   OSM_AG_InsManager* InsManager ,   int* event_num );
          
           /**
           * Frees the memory allocated by the local array of events. Previously performs
           * the deregistration of timers within the reactor.
           * @retval -1 in case of error. n > 1 for success n=number of events deregistered.
           */
     375   virtual int close(   );
          
           /**
           * Returns the instance Id or code.
           */
     380   ACE_TCHAR* idn_instance(  void )
           {
           return this->idn_instance_;
           };
          
           /**
           * Returns the instance type.
           */
     388   ACE_TCHAR* typ_instance(  void )
           {
           return this->typ_instance_;
           };
          
           /**
           * Try to connect to whatever kind of instance you are coding.
           * It uses the connection string to perform the connection.
           * When inherite from this class you may add connection structure and new
           * methods.
           * @retval -1 in case of error.0 for success.
           */
     400   virtual int connect(  void );
          
           /**
           * Disconnect from the current instance. Instance connection structure
           * cleaning.
           * @retval -1 in case of error.0 for success.
           */
     407   virtual int disconnect(  const int force=0 );
          
           /// Returns a pointer to the Instance Manager.
     410   OSM_AG_InsManager* ins_manager(   );
          
           /**
           * Checks the connection information.
           * @retval -1 in case of error.0 for success.
           */
     416   virtual int check_conn_info(  const ACE_TCHAR* conn_info );
          
           /// Returns connection state.
     419   int connected(   )
           {
           return this->connected_;
           };
          
           /// Sets connection state.
     425   void connected(  const int connected )
           {
           this->connected_ = connected;
           };
          
          private:
          
           /// Destroy the array of events after call their close(   ) method.
     433   int destroy_events(  void );
          
           /**
           * Create the array of events and call their open(   ) method.
           * @retval -1 in case of error.0 for success.
           */
     439   int create_events(  void );
          
           /// Print out the instance retrieved info and associated events. Debug porpuse.
     442   void print(   );
          
           /**
           * Checks the command line of the event read from the config file.
           * Normally the command line is:
           * -t SECONDS_TO_EXECUTE_THIS_EVENT -c COMPARE_MODE -w WARN_LIMIT -a ALAR_LIMIT -s
           * @param cmdline - command line to parse * -t SECONDS_TO_EXECUTE_THIS_EVENT -c COMPARE_MODE -w WARN_LIMIT -a ALAR_LIMIT -s
           * @param value - number of seconds to execute this event in a periodic way.
           * @param mode - Type of compare mode.
           * @param warn - Warning limit.
           * @param alar - Critical limit
           * @param silent - Silent mode
           * @retval -1 in case of error.0 for success.
           */
     456   int parse_event_cmdline(  const ACE_TCHAR* cmdline,  
           int &value,  
           int &mode,  
           int &warn,  
           int &alar,  
           int &silent );
          
          
           /// Instance unique identification.
     465   ACE_TCHAR idn_instance_ [OSM_Message::CODLEN + 1];
           /// Instance Type.
     467   ACE_TCHAR typ_instance_ [OSM_Message::TYPLEN + 1];
           /// Absolute Path to configuration file
     469   ACE_TCHAR config_file_ [MAXPATHLEN + 1];
           ///
     471   ACE_TCHAR connection_info_ [BUFSIZ];
          
           /// Number of events read from the config fiel and active.
           long event_number_;
          
           /// Array of events to be polled.
     477   OSM_Event** event_array_ ; // Shouldn't it be a container instead?.
          
           /// Pointer to the Instance Manager Service. Used to send messages.
     480   OSM_AG_InsManager* ins_manager_;
          
           /// Connection state.
           int connected_;
          };
          
          /*----------------------------------------------------------------------------*/
          /* OSM_AG_InsManager */
          /*----------------------------------------------------------------------------*/
          /**
           * @class OSM_AG_InsManager
           *
           * @brief Creates instances and events from config_file and start monitoring.
           *
           * With this service read how many instances and events we must monitor. We
           * create all the needed objects and register the events (  inherited from
           * ACE_EVent_Handler ) and all the timers with the Reactor.
           * Instance Manage can re-read the configuration file shutting down and freeing
           * the memory correctly.
           */
     500  class OSM_AG_InsManager
          {
          protected:
           /// Factory that actively connects the OSM_AG_MsgSender.
     504   OSM_Instance_Base** osm_instance_array_;
           /// Number of instances managed by me.
           int osm_instance_number_;
           /// The OSM_AG_MsgManager used to send messages via its put(   ) method.
     508   OSM_AG_MsgManager* msg_manager_;
           /// Complete path to configuration file.
     510   ACE_TCHAR config_file_[MAXPATHLEN+1];
           /// Configuragtion Heap
     512   ACE_Configuration_Heap cfg_;
           /// Used to fetch different section or instances
     514   ACE_Configuration_Section_Key cfg_section_;
          
          private:
           /// Constructor.
     518   OSM_AG_InsManager(  OSM_AG_MsgManager* msg_manager ): osm_instance_number_(  0 )
           { this->msg_manager_ = msg_manager;};
          
           /**
           * Frees allocated memory.
           * @retval -1 in case of error.0 for success.
           */
     525   int destroy_instances(  void );
          
           /**
           * Creates the necessary instance objects.
           * @retval -1 in case of error.0 for success.
           */
     531   int create_instances(  void );
          
           /// Reference to the singleton instance.
           static OSM_AG_InsManager* instance_;
          
          
          public:
           /// Returns singleton.
     539   static OSM_AG_InsManager *instance (  void );
          
           /// Make initial task to run the MSG_Manager Service within Osmius agent.
     542   int init(  int argc,   ACE_TCHAR *argv[] );
           /// Perform the final task to end the MSG_Manager Service.
     544   int fini (   );
          
           /**
           * Reload Configuration: Frees allocated memory,   if any,   and restarts the
           * instances and events registering them with the reactor.
           * @retval -1 in case of error.0 for success.
           */
     551   int reload(   );
          
           /**
           * Used tu send messages wrapped into ACE_Message_Block to whatever site.
           * @retval -1 in case of error.0 for success.
           */
     557   int put(  ACE_Message_Block* mblk,   ACE_Time_Value* tm )
           {
           if (  0 != this->msg_manager_ )
           {
           return this->msg_manager_->put(  mblk,  tm );
           }
           return -1;
           }
          
          };
          
          /**
           * @class OSM_ACT_ExecuteProcess
           *
           * @brief This action can execute a command in the host machine in a portable way.
           *
           *
           */
     575  class OSM_ACT_ExecuteProcess : public OSM_Action_Base
          {
          public:
          
           /// Constructor.
     580   OSM_ACT_ExecuteProcess(   ) : cmd_checked_(  0 ) {};
           /**
           * Executes the action using the command line and returns the associated text
           * and value.
           * @param cmd_line Input - Command line used to execute this action.
           * @param cmd_len Input - Command line length.
           * @param timeout Input - Wait timeout seconds before aborting execution.
           * @param val_text Output - Standard and error output of the process.
           * @param val_len Output - Output length.
           * @param value Output - Exit code.
           * @retval -1 in case of error. 0 for success.
           */
     592   int execute(  const ACE_TCHAR* cmd_line,  const int cmd_len,  
     593   const int timeout,  ACE_TCHAR* val_text,  
           int& val_len,   int &value  );
          
           /**
           * Checks the command line. You should overwrite this method to handle issues
           * like semantic and sintactic checking or security stuff.
           * @param cmd_line Input - Command line used to execute this action.
           * @param cmd_len Input - Command line length.
           * @retval -1 in case of error. 0 for success.
           */
     603   int check_cmd_line(  const ACE_TCHAR* cmd_line,  const int cmd_len );
          
          private:
           int value_;
          
           /// Process structure to execute against local host machine in a portable way.
     609   OSM_Process process_;
          
           /// To keep if we've already checked the command line.
           int cmd_checked_;
          
          };
          
          /**
           * @class OSM_ACT_IP4Interfaces
           *
           * @brief Retrieves number of active IP4 interfaces
           *
           */
     622  class OSM_ACT_IP4Interfaces : public OSM_Action_Base
          {
          public:
           /// Constructor.
     626   OSM_ACT_IP4Interfaces(   ): num_if_(  0 )
           {
           };
          
           /**
           * Executes the action using the command line and returns the associated text
           * and value.
           * @param cmd_line Input - Command line used to execute this action.
           * @param cmd_len Input - Command line length.
           * @param timeout Input - Wait timeout seconds before aborting execution.
           * @param val_text Output - Text of the resulting action.
           * @param val_len Output - Text length.
           * @param value Output - Uptime seconds.
           * @retval -1 in case of error. 0 for success.
           */
     641   int execute(  const ACE_TCHAR* cmd_line,  const int cmd_len ,  
     642   const int timeout ,  ACE_TCHAR* val_text,  
           int& val_len ,   int& value  );
          
           /**
           * Checks the command line.
           * @param cmd_line Input - Command line used to execute this action.
           * @param cmd_len Input - Command line length.
           * @retval -1 in case of error. 0 for success.
           */
           //int check_cmd_line(  const ACE_TCHAR* cmd_line,  const int cmd_len );
          
          private:
     654   size_t num_if_;
     655   ACE_INET_Addr* addr_array_;
          
          };
          /**
           * @class OSM_ACT_IP6Interfaces
           *
           * @brief Retrieves number of active IP6 interfaces
           *
           */
     664  class OSM_ACT_IP6Interfaces : public OSM_Action_Base
          {
          public:
           /// Constructor.
     668   OSM_ACT_IP6Interfaces(   ): num_if_(  0 )
           {
           };
          
           /**
           * Executes the action using the command line and returns the associated text
           * and value.
           * @param cmd_line Input - Command line used to execute this action.
           * @param cmd_len Input - Command line length.
           * @param timeout Input - Wait timeout seconds before aborting execution.
           * @param val_text Output - Text of the resulting action.
           * @param val_len Output - Text length.
           * @param value Output - Uptime seconds.
           * @retval -1 in case of error. 0 for success.
           */
     683   int execute(  const ACE_TCHAR* cmd_line,  const int cmd_len ,  
     684   const int timeout ,  ACE_TCHAR* val_text,  
           int& val_len ,   int& value  );
          
           /**
           * Checks the command line.
           * @param cmd_line Input - Command line used to execute this action.
           * @param cmd_len Input - Command line length.
           * @retval -1 in case of error. 0 for success.
           */
           //int check_cmd_line(  const ACE_TCHAR* cmd_line,  const int cmd_len );
          
          private:
     696   size_t num_if_;
     697   ACE_INET_Addr* addr_array_;
          
          };
          
          /**
           * @class OSM_ACT_ScanLog
           *
           * @brief Search if a string has been written in a log file.
           *
           */
     707  class OSM_ACT_ScanLog : public OSM_Action_Base
          {
          public:
           enum
           {
           OSM_SCANLOG_BUFSIZ = 8*1024
           };
          
           /// Constructor.
     716   OSM_ACT_ScanLog(   ): cmd_line_checked_(  0 ),   last_size_(  0 )
           {
           log_file_ [0] = 0;
           string_ [0] = 0;
           };
          
           /**
           * Executes the action using the command line and returns the associated text
           * and value.
           * @param cmd_line Input - Command line used to execute this action.
           * @param cmd_len Input - Command line length.
           * @param timeout Input - Wait timeout seconds before aborting execution.
           * @param val_text Output - Text of the resulting action.
           * @param val_len Output - Text length.
           * @param value Output - Uptime seconds.
           * @retval -1 in case of error. 0 for success.
           */
     733   int execute(  const ACE_TCHAR* cmd_line,  const int cmd_len ,  
     734   const int timeout ,  ACE_TCHAR* val_text,  
           int& val_len ,   int& value  );
          
           /**
           * Checks the command line.
           * @param cmd_line Input - Command line used to execute this action.
           * @param cmd_len Input - Command line length.
           * @retval -1 in case of error. 0 for success.
           */
     743   int check_cmd_line(  const ACE_TCHAR* cmd_line,  const int cmd_len );
          
          private:
           int cmd_line_checked_;
           long last_size_;
     748   FILE* fd_;
     749   ACE_TCHAR log_file_[BUFSIZ+1];
     750   ACE_TCHAR string_[BUFSIZ+1];
     751   ACE_TCHAR auxbuf_[OSM_SCANLOG_BUFSIZ+1];
          };
          
          #endif /* _OSM_AG_INSMANAGER_H_ */

ag/osm_ag_msgmanager.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_msgmanager.cpp
          * @brief Implementation file for the MSG_MANAGER service of Osmius Agents.
          *
          * @author Jose Luis Marina <joseluis.marina@peopleware.es>
          * @date 15-JUN-2006
          */
          // -----------------------------------------------------------------------------
          
          // These are standard includes for any program
          #include "osm_ag_msgmanager.h"
          #include "../cm/osm_message.h"
          
          #if defined (  ACE_WIN32 )
          #include <ace/OS.h>
          #endif /* (  ACE_WIN32 ) */
          
          //#include "../cm/osm_cfgmanager.h"
          //#include <ace/OS.h>
          
          //#include <ace/Log_Msg.h>
          
          // Specific module includes.
          #include <ace/Get_Opt.h>
          #include <ace/Signal.h>
          
          /*----------------------------------------------------------------------------*/
          /* OSM_AG_MsgSender Implementation */
          /*----------------------------------------------------------------------------*/
          int
      54  OSM_AG_MsgSender::open (  void *connector )
          {
           ACE_TCHAR aux_str[BUFSIZ+1]="N";
          
           this->mode_= -1;
           // Lets see if we have a command to send messages.
           if (  -1 == OSM_CfgManager::instance(   )->get_value_str(  "SNDCMD",  aux_str,  BUFSIZ ) )
           {
           ACE_OS::strcpy(  aux_str,  "N" );
           }
          
           if (  (  1 == ACE_OS::strlen(  aux_str ) )&&(  'N' == aux_str[0] ) )
           {
           this->mode_ = OSM_SNDMODE_NET;
           ACE_OS::strcpy(  this->command_,  "" );
           }
           else
           {
           ACE_OS::strcpy(  this->command_,  aux_str );
          
           #ifdef ACE_WIN32
           if (  ACE_DIRECTORY_SEPARATOR_CHAR_A != this->command_[2] )
           {
           ACE_ERROR (  (  LM_ERROR,  
           ACE_TEXT (  "AG_MsgSender - open(   ) Command [%s] needs to be an absolute path\n" ),  
           this->command_ ) );
           return -1;
           }
           #else
           if (  ACE_DIRECTORY_SEPARATOR_CHAR_A != this->command_[0] )
           {
           ACE_ERROR (  (  LM_ERROR,  
           ACE_TEXT (  "AG_MsgSender - open(   ) Command [%s] needs to be an absolute path\n" ),  
           this->command_ ) );
           return -1;
           }
           #endif
          
           if (  connector )
           {
           this->mode_ = OSM_SNDMODE_BOZ;
           }
           else
           {
           this->mode_ = OSM_SNDMODE_CMD;
           }
           }
          
           if (  0 == connector && (  (  OSM_SNDMODE_BOZ == this->mode_ )||(  OSM_SNDMODE_NET == this->mode_ ) ) )
           {
           ACE_ERROR (  (  LM_ERROR,  ACE_TEXT (  "AG_MsgSender - open(   ) Bad Connector\n" ) ) );
           return -1;
           }
          
           if (  connector )
           {
           // Assign the connector.
           connector_ = static_cast<OSM_AG_MsgConnector *> (  connector );
          
           // Try to set the maximum buffer size for the sockect,  
           int bufsiz = ACE_DEFAULT_MAX_SOCKET_BUFSIZ;
           peer (   ).set_option (  SOL_SOCKET,   SO_SNDBUF,  &bufsiz,   sizeof bufsiz );
          
           // Register with the singleton reactor for incomming data in the socket.
           // If we receive data it seems the server has disconnect from us.
           // We will handle this situation in handle_input(   ).
           if (  reactor (   )->register_handler
           (  this,   ACE_Event_Handler::READ_MASK ) == -1 )
           {
           ACE_ERROR (  (  LM_ERROR,  ACE_TEXT (  
           "AG_MsgSender - open(   ) Could Not register with the Reactor\n" ) ) );
           return -1;
           }
           }
          
          #if defined(  OSM_NO_THREADS )
           return 0;
          #endif // OSM_NO_THREADS
          
           int i_qsize=0;
           // Get the max queue size parameter for the Message Sender (  in kbytes ).
           if (  -1 == OSM_CfgManager::instance(   )->get_value_int(  "MSGQSI",  &i_qsize ) )
           {
           ACE_ERROR (  (  LM_ERROR,  
           ACE_TEXT (  "AG_MsgSender - Could not get MSGQSI. Using 16.\n" ) ) );
           i_qsize = 16 * 1024;
           }
           else
           {
           i_qsize = i_qsize * 1024;
           }
           // Get the timeout parameter for network operations.
           if (  -1 == OSM_CfgManager::instance(   )->get_value_int(  "TIMOUT",  &this->i_timeout_ ) )
           {
           ACE_ERROR (  (  LM_ERROR,  
           ACE_TEXT(  "AG_MsgSender - svc(   ) Could not get TIMOUT\n" ) ) );
           this->i_timeout_ = 120;
           }
           // Get the time buffer parameter to wait until send messages.
           if (  -1 == OSM_CfgManager::instance(   )->get_value_int(  "TIMBUF",  &this->i_timbuf_ ) )
           {
           ACE_ERROR (  (  LM_ERROR,  
           ACE_TEXT(  "AG_MsgSender - svc(   ) Could not get TIMBUF\n" ) ) );
           this->i_timbuf_ = 20;
           }
           if (  this->i_timbuf_ < 0 ) this->i_timbuf_ = 0;
          
           // Lets see if the queue is active. If it is we activate our selves (  svc(   ) ).
           if (  ACE_Message_Queue_Base::ACTIVATED == msg_queue (   )->activate (   ) )
           {
           msg_queue (   )->high_water_mark (  i_qsize );
           return activate (  THR_NEW_LWP | THR_DETACHED ); //(  THR_SCOPE_SYSTEM );
           }
          
          
           ACE_DEBUG (  (  LM_DEBUG,  ACE_TEXT(  
           "AG_MsgSender - Queue not activated. Service already executing?\n" ) ) );
           return 0;
          }
          /*----------------------------------------------------------------------------*/
          int
     175  OSM_AG_MsgSender::put(  ACE_Message_Block *mblk,  ACE_Time_Value *tm )
          {
           // We can choose to process the message or to differ it into the message
           // queue,   and process them into the svc(   ) method. We chose the last option.
           int retval;
           // Statistics
           if (  OSM_CfgManager::instance(   )->debug_mode(   ) )
           {
           ACE_Thread_Mutex mutex;
           ACE_Guard <ACE_Thread_Mutex> guard (  mutex );
           OSM_CfgManager::instance(   )->counter(  OSM_STAT_EVENTS,  
           OSM_CfgManager::instance(   )->counter(  OSM_STAT_EVENTS ) + 1 );
           }
          
          // ------------------------------------------------------------------------------------
          #if defined(  OSM_NO_THREADS )
           if (  (  0 == mblk->size (   ) ) )
           {
           mblk->release (   );
           ACE_Reactor::instance (   )->end_reactor_event_loop (   );
           return 0;
           }
           retval=1;
           this->send(  &mblk,  (  size_t& )retval );
           return 0;
          #endif // OSM_NO_THREADS
          // ------------------------------------------------------------------------------------
          
           while (  (  retval = putq (  mblk,   tm ) ) == -1 )
           {
           if (  msg_queue (   )->state (   ) != ACE_Message_Queue_Base::PULSED )
           break;
           }
           return retval;
          }
          
          /*----------------------------------------------------------------------------*/
          int
     213  OSM_AG_MsgSender::handle_input(  ACE_HANDLE h )
          {
           ACE_DEBUG (  (  LM_DEBUG,  ACE_TEXT(  
           "AG_MsgSender - handle_input(   ) called.It seems the Master Agent is down.\n" ) ) );
           peer (   ).close (   );
           reactor (   )->remove_handler
           (  h,   ACE_Event_Handler::READ_MASK
           | ACE_Event_Handler::DONT_CALL );
           msg_queue (   )->pulse (   );
           return 0;
          }
          
          /*----------------------------------------------------------------------------*/
     226  int OSM_AG_MsgSender::handle_close (  ACE_HANDLE handle,   ACE_Reactor_Mask mask )
          {
           if (  OSM_CfgManager::instance(   )->debug_mode(   ) )
           {
           ACE_DEBUG(  (  LM_DEBUG,  
           ACE_TEXT(  "(  %P|%T ) AG_Sender: handle_close(   ) called.\n" ) ) );
           }
          
           ACE_OS::closesocket (  handle );
          
           this->peer(   ).close(   );
          
           PARENT::handle_close (  handle,   mask );
          
           return 0;
          }
          
          /*----------------------------------------------------------------------------*/
          int
     245  OSM_AG_MsgSender::svc(   )
          {
           ACE_Message_Block *chunk[ACE_IOV_MAX];
           size_t message_index = 0;
           ACE_Time_Value time_of_last_send (  ACE_OS::gettimeofday (   ) );
           ACE_Time_Value timeout;
          
           // Lets avoid interruptions while working on this.
           ACE_Sig_Action no_sigpipe (  (  ACE_SignalHandler ) SIG_IGN );
           ACE_Sig_Action original_action;
           no_sigpipe.register_action (  SIGPIPE,   &original_action );
          
           // ---------------------------------------------------------------------------
           // Read for ever.
           // ---------------------------------------------------------------------------
           for (  ;; )
           {
           if (  message_index == 0 )
           {
           timeout = ACE_OS::gettimeofday (   );
           timeout += this->i_timeout_;
           }
           ACE_Message_Block *mblk = 0;
           ACE_OS::last_error(  0 );
           // -------------------------------
           // Read messages from the queue. |
           // -------------------------------
           if (  getq (  mblk,   &timeout ) == -1 )
           {
           if (  ACE_OS::last_error(   ) == ESHUTDOWN )
           {
           if (  this->connector_->reconnect (   ) == -1 ) break;
           continue;
           }
           else if (  ACE_OS::last_error(   ) != EWOULDBLOCK ) break;
           else if (  message_index == 0 ) continue;
           }
           else // Read one message.
           {
           // If someone has send a MB_STOP message we must quit.
           if (   (  0 == mblk->size (   ) )
           && (  mblk->msg_type (   ) == ACE_Message_Block::MB_STOP ) )
           {
           mblk->release (   );
           break;
           }
           // else... put the message into the bulk vector.
           chunk[message_index] = mblk;
           ++message_index;
           }
           // If chuck[] array is full or we've reached the timeout -> send messages.
           if (  message_index >= ACE_IOV_MAX ||
           (  ACE_OS::gettimeofday (   ) - time_of_last_send
           >= ACE_Time_Value(  this->i_timbuf_ ) ) || !this->i_timbuf_ )
           {
           if (  send (  chunk,   message_index ) == -1 ) break; // Sent failed.
           time_of_last_send = ACE_OS::gettimeofday (   );
           }
           }
          
           // Send the last messages. We are shutting down.
           if (  message_index > 0 ) send (  chunk,   message_index );
           // Restore interruptions.
           no_sigpipe.restore_action (  SIGPIPE,   original_action );
          
           if (  OSM_CfgManager::instance(   )->debug_mode(   ) )
           {
           ACE_ERROR (  (  LM_ERROR,  ACE_TEXT (  
           "AG_MsgSender - svc(   ) exit MB_STOP Received or reconnect failed\n" ) ) );
           }
           // We must shutdown the complete process.
          // ACE_Message_Block *shutdown_message = 0;
          // ACE_NEW_RETURN
          // (  shutdown_message,  
          // ACE_Message_Block (  0,   ACE_Message_Block::MB_STOP ),   -1 );
          // this->put (  shutdown_message );
          
           // AKI REVISAR O BORRAR SI TODO VA BIEN
           //-> ACE_Reactor::instance (   )->end_reactor_event_loop (   );
          
           return -1;
          }
          
          /*----------------------------------------------------------------------------*/
          int
     330  OSM_AG_MsgSender::send(  ACE_Message_Block *chunk[],   size_t &count )
          {
           iovec iov[ACE_IOV_MAX];
           size_t iov_size;
           int result = 0;
           OSM_Message* osm_msg=0;
           int exit_code=0;
           int output_len=BUFSIZ;
          
           // Statistics
           if (  OSM_CfgManager::instance(   )->debug_mode(   ) )
           {
           OSM_CfgManager::instance(   )->counter(  OSM_STAT_MSGSND,  
           OSM_CfgManager::instance(   )->counter(  OSM_STAT_MSGSND ) + count );
           }
          
           for (  iov_size = 0; iov_size < count; ++iov_size )
           {
           osm_msg= (  OSM_Message* ) chunk[iov_size]->rd_ptr(   );
           iov[iov_size].iov_base = (  char * )&osm_msg->net_message_;
           // This lenght(   ) mut be set using rd_ptr(   ) and wr_ptr(   )!!
           iov[iov_size].iov_len = chunk[iov_size]->length(   );
           // Only for debug porpuses.
           // osm_msg->print(   );
          
           if (  (  OSM_SNDMODE_CMD == this->mode_ )||(  OSM_SNDMODE_BOZ == this->mode_ ) )
           {
           // The parameters always are in the same order:
           // 1 - typ_agent
           // 2 - typ_instance
           // 3 - idn_instance
           // 4 - typ_event
           // 5 - typ_alarm
           // 6 - dti_inievent
           // 7 - dti_finevent
           // 8 - num_value
           // 9 - "txt_message"
           ACE_OS::sprintf(  this->exec_command_,  "%s %s %s %s %s %s %s %s %s \"%s\"",  
           this->command_ ,  
           osm_msg->typ_agent(   ) ,  
           osm_msg->typ_instance(   ) ,  
           osm_msg->idn_instance(   ) ,  
           osm_msg->typ_event(   ) ,  
           osm_msg->typ_alarm(   ) ,  
           osm_msg->dti_inievent(   ) ,  
           osm_msg->dti_finevent(   ) ,  
           osm_msg->num_value(   ) ,  
           osm_msg->txt_message(   ) );
           // We're using timeout = 0 after several probes on HP-UX...
           // We don't need to store the output of the command so we assign 0 to output_len.
           // Comment out next line to store the command output.
           output_len = 0;
           if (  0 > this->process_.execute(  this->exec_command_,   "",  "",  exit_code ,  0,  this->output_,  output_len ) )
           {
           ACE_ERROR (  (  LM_ERROR,  ACE_TEXT (  
           "AG_MsgSender - send(   ) Could not execute command: [%s] exit code: %d.\n" ),  
           this->exec_command_,  
           exit_code ) );
           }
           }
           }
          
           if (  (  OSM_SNDMODE_NET == this->mode_ )||(  OSM_SNDMODE_BOZ == this->mode_ ) )
           {
           while (  -1 == peer(   ).sendv_n(  iov,   iov_size ) )
           {
           // Send failed so we'll try to reconnect and send again.
           if (  this->connector_->reconnect (   ) == -1 )
           {
           ACE_ERROR (  (  LM_ERROR,  ACE_TEXT (  
           "AG_MsgSender - send(   ) Could not reconnect to server.\n" ) ) );
           result = -1;
           break;
           }
           }
           }
          
           while (  iov_size > 0 ) {
           delete chunk[--iov_size]->rd_ptr(   ); // Delete OSM_Message.
           chunk[iov_size]->release (   ); chunk[iov_size] = 0; // Delete ACE_Msg_Block.
           }
          
           count = iov_size;
          
           return result;
          }
          
          /*----------------------------------------------------------------------------*/
          /* OSM_AG_MsgConnector Implementation */
          /*----------------------------------------------------------------------------*/
          /*----------------------------------------------------------------------------*/
          /* If we want to use SSL use implement theese methods.*/
          int
     423  OSM_AG_MsgConnector::open (  ACE_Reactor *r,   int flags )
          {
           if (  PARENT::open (  r,   flags ) != 0 ) return -1;
           // SSL stuff...
           return 0;
          }
          
          /*----------------------------------------------------------------------------*/
          int
     432  OSM_AG_MsgConnector::connect_svc_handler
     433   (  OSM_AG_MsgSender *&svc_handler,  
     434   const ACE_SOCK_Connector::PEER_ADDR &remote_addr,  
     435   ACE_Time_Value *timeout,  
     436   const ACE_SOCK_Connector::PEER_ADDR &local_addr,  
           int reuse_addr,   int flags,   int perms )
          {
           if (  PARENT::connect_svc_handler
           (  svc_handler,   remote_addr,   timeout,  
           local_addr,   reuse_addr,   flags,   perms ) == -1 ) return -1;
           remote_addr_ = remote_addr;
           return 0;
          }
          
          /*----------------------------------------------------------------------------*/
          int
     448  OSM_AG_MsgConnector::connect_svc_handler
     449   (  OSM_AG_MsgSender *&svc_handler,  
     450   OSM_AG_MsgSender *&sh_copy,  
     451   const ACE_SOCK_Connector::PEER_ADDR &remote_addr,  
     452   ACE_Time_Value *timeout,  
     453   const ACE_SOCK_Connector::PEER_ADDR &local_addr,  
           int reuse_addr,   int flags,   int perms )
          {
           sh_copy = svc_handler;
           return this->connect_svc_handler (  svc_handler,   remote_addr,   timeout,  
           local_addr,   reuse_addr,   flags,   perms );
          }
          
          /*----------------------------------------------------------------------------*/
          int
     463  OSM_AG_MsgConnector::reconnect (   )
          {
           // Get the number of retries.
           int i_reconn_tries;
           if (  -1 == OSM_CfgManager::instance(   )->get_value_int(  "RECONN",  &i_reconn_tries ) )
           {
           ACE_ERROR (  (  LM_ERROR,  ACE_TEXT (  
           "MsgConnector - Could not get RECONN parameter\n" ) ) );
           i_reconn_tries = 4;
           }
           if (  OSM_CfgManager::instance(   )->debug_mode(   ) )
           {
           ACE_DEBUG(  (  LM_DEBUG,  
           ACE_TEXT (  "(  %P|%T ) MSG_Connector: reconnect(   ) to Master. Trying %d times\n" ),  
           i_reconn_tries ) );
           }
           ACE_Time_Value timeout (  1 );
           int i;
           for (  i = 0; i < i_reconn_tries ; ++i )
           {
           // Statistics
           if (  OSM_CfgManager::instance(   )->debug_mode(   ) )
           {
           OSM_CfgManager::instance(   )->counter(  OSM_STAT_RECONN,  
           OSM_CfgManager::instance(   )->counter(  OSM_STAT_RECONN ) + 1 );
           }
          
           ACE_Synch_Options options (  ACE_Synch_Options::USE_TIMEOUT,  timeout );
           if (  i > 0 ) ACE_OS::sleep (  timeout );
           if (  connect (  svc_handler_,   remote_addr_,   options ) == 0 )
           {
           break;
           }
           timeout *= 2;
           }
           if (  i == i_reconn_tries )
           {
           ACE_ERROR (  (  LM_ERROR,  
           ACE_TEXT(  "(  %P|%T ) MSG_Connector: reconnect(   ) failed after %d retries\n" ),  
           i_reconn_tries ) );
           return -1;
           }
          
           return 0;
          }
          
          /*----------------------------------------------------------------------------*/
          /* OSM_AG_MsgManager Implementation */
          /*----------------------------------------------------------------------------*/
          // Static initialization.
          OSM_AG_MsgManager *OSM_AG_MsgManager::instance_ = 0;
          
          /*----------------------------------------------------------------------------*/
     516  OSM_AG_MsgManager* OSM_AG_MsgManager::instance (  void )
          {
           if (  0 == OSM_AG_MsgManager::instance_ )
           ACE_NEW_RETURN (  OSM_AG_MsgManager::instance_,   OSM_AG_MsgManager,   0 );
           return OSM_AG_MsgManager::instance_;
          }
          
          /*----------------------------------------------------------------------------*/
          int
     525  OSM_AG_MsgManager::init (  int argc,   ACE_TCHAR *argv[] )
          {
           u_short master_port = 1970;
           ACE_TCHAR cmd[MAXPATHLEN+1]="";
          
           int opt_m=0;
           int opt_C=0;
          
           ACE_Get_Opt get_opt (  argc,   argv,   ACE_TEXT (  "m:C:" ),   0 );
           get_opt.long_option (  ACE_TEXT (  "master_port" ),   'm',  
           ACE_Get_Opt::ARG_REQUIRED );
           get_opt.long_option (  ACE_TEXT (  "send_command" ),   'C',  
           ACE_Get_Opt::ARG_REQUIRED );
          
           for (  int c; (  c = get_opt (   ) ) != -1; )
           {
           switch (  c )
           {
           case 'm':
           master_port = static_cast<u_short> (  ACE_OS::atoi (  get_opt.opt_arg (   ) ) );
           opt_m++;
           break;
           case 'C':
           ACE_OS::strcpy(  cmd,  get_opt.opt_arg (   ) );
           opt_C++;
           break;
           }
           }
          
           if (  (  opt_m !=1 )||(  opt_C !=1 )||(  !opt_m )&&(  !opt_C ) )
           {
           if (  !master_port )
           {
           ACE_ERROR(  (  LM_ERROR,  ACE_TEXT (  
           "MSG_Manager - PORTMA or SNDCMD needed.\n\tQuitting...\n" ) ) );
           return -1;
           }
           }
          
           if (  master_port )
           {
           //En windows parece que no funciona
           //ACE_INET_Addr master_addr (  master_port );
          
           // Command Manager Accept and Sent Commands
           ACE_TCHAR szmaster[2*MAXHOSTNAMELEN+1];
           ACE_OS::sprintf(  szmaster,  "127.0.0.1:%d",  master_port );
           ACE_INET_Addr master_addr (  szmaster );
          
           if (  OSM_CfgManager::instance(   )->debug_mode(   ) )
           {
           ACE_DEBUG (  (  LM_DEBUG,  ACE_TEXT (  
           "(  %P|%T ) MSG_Manager - init_work(   ) Sending Messages to Port: %d Connecting\n" ),  
           master_port ) );
           }
          
           ACE_OS::last_error(  0 );
           OSM_AG_MsgSender *m_sender = &this->msg_sender_;
           if (  -1 == this->connector_.connect (  m_sender,   master_addr ) )
           {
           ACE_ERROR(  (  LM_ERROR,  ACE_TEXT (  
           "MSG_Manager - Could not initialize.\n\tQuitting...\n" ),  
           master_port ) );
           this->connector_.close (   );
           return -1; // If the master is not there we don't even start.
           }
           }
           if (  ACE_OS::strlen(  cmd ) > 2 )
           {
           if (  OSM_CfgManager::instance(   )->debug_mode(   ) )
           {
           ACE_DEBUG (  (  LM_DEBUG,  ACE_TEXT (  
           "(  %P|%T ) MSG_Manager - init_work(   ) Sending Command is: [%s]\n" ),  
           cmd ) );
           }
           FILE* pf = ACE_OS::fopen(  cmd,  ACE_LIB_TEXT(  "r" ) );
           if (  0 == pf )
           {
           ACE_ERROR(  (  LM_ERROR,  ACE_TEXT (  
           "MSG_Manager - Could not read open [%s].\n\tQuitting...\n" ),  
           cmd ) );
           return -1;
           }
           ACE_OS::fclose(  pf );
           if (  !master_port )
           {
           if (  -1 == this->msg_sender_.open(  0 ) )
           {
           return -1;
           }
           }
           }
           else
           {
           if (  !master_port )
           {
           ACE_ERROR(  (  LM_ERROR,  ACE_TEXT (  
           "MSG_Manager - PORTMA Needed.\n\tQuitting...\n" ) ) );
           return -1;
           }
           }
          
           return 0;
          }
          
          /*----------------------------------------------------------------------------*/
     631  int OSM_AG_MsgManager::fini (   )
          {
           if (  OSM_CfgManager::instance(   )->debug_mode(   ) )
           {
           ACE_DEBUG(  (  LM_DEBUG,  
           ACE_TEXT (  "MSG_Manager - fini(   ) Ending MSG_Manager Service.\n" ) ) );
           }
          
           ACE_Message_Block *shutdown_message = 0;
           ACE_NEW_RETURN
           (  shutdown_message,  
           ACE_Message_Block (  0,   ACE_Message_Block::MB_STOP ),   -1 );
          
           this->put (  shutdown_message );
           this->msg_sender(   )->wait(   );
           this->connector_.close (   );
           return this->msg_sender(   )->close(   );
          
          }
          /*----------------------------------------------------------------------------*/

ag/osm_ag_msgmanager.h

          // -*- 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_msgmanager.h
          * @brief Interface and definition file for the Agent MSG_MANAGER service.
          * Osmius - Peopleware.
          *
          * @author Jose Luis Marina <joseluis.marina@peopleware.es>
          * @date 07-APR-2006
          */
          // -----------------------------------------------------------------------------
          #ifndef _OSM_AG_MSGMANAGER_H_
          #define _OSM_AG_MSGMANAGER_H_
          
          #include "../cm/osm_cfgmanager.h"
          // include appropriate socket and address includes
          //#include <ace/SOCK_Stream.h>
          //#include <ace/INET_Addr.h>
          
          // Specific includes.
          #include <ace/Svc_Handler.h>
          #include <ace/SOCK_Connector.h>
          #include <ace/Connector.h>
          
          
          // -----------------------------------------------------------------------------
          // Explicit template instantiations. OBSOLETE.
          // -----------------------------------------------------------------------------
          //#if defined (  ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION )
          #if defined (  OSM_NO_THREADS )
      52  template class ACE_Svc_Handler<ACE_SOCK_STREAM,  ACE_NULL_SYNCH>; // NO_THREADS ACE_MT_SYNCH o ACE_NULL_SYNCH
          #endif // OSM_NO_THREADS
          #if !defined (  OSM_NO_THREADS )
      55  template class ACE_Svc_Handler<ACE_SOCK_STREAM,  ACE_MT_SYNCH>; // NO_THREADS ACE_MT_SYNCH o ACE_NULL_SYNCH
          #endif // !OSM_NO_THREADS
          //#elif defined (  ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA )
          //#if defined (  OSM_NO_THREADS )
          //#pragma instantiate ACE_Svc_Handler<ACE_SOCK_STREAM,  ACE_NULL_SYNCH>; // NO_THREADS ACE_MT_SYNCH o ACE_NULL_SYNCH
          //#endif //!OSM_NO_THREADS
          //#if !defined (  OSM_NO_THREADS )
          //#pragma instantiate ACE_Svc_Handler<ACE_SOCK_STREAM,  ACE_MT_SYNCH>; // NO_THREADS ACE_MT_SYNCH o ACE_NULL_SYNCH
          //#endif //!OSM_NO_THREADS
          //#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */
          
          // -----------------------------------------------------------------------------
          /// Indexes for the statistical values. See osm_master_agent.h
          // -----------------------------------------------------------------------------
          enum
          {
           /// Number of sended messages.
           OSM_STAT_MSGSND = 0,  
           /// Number of reconnections.
           OSM_STAT_RECONN = 1,  
           /// Events processed
           OSM_STAT_EVENTS = 2
          };
          /*----------------------------------------------------------------------------*/
          // Forwarded declarations.
      80  class OSM_AG_MsgConnector;
          /*----------------------------------------------------------------------------*/
          /* OSM_AG_MsgSender */
          /*----------------------------------------------------------------------------*/
          /**
           * @class OSM_AG_MsgSender
           *
           * @brief Send message to the master agent in bulk groups.
           *
           * We use the put(   ) method to access this class and send the Blk to the local
           * queue. The svc(   ) method will run its own thread to send messages in the
           * queue to the server through the Connector.
           * Implements the active service part in the Connector Pattern.
           *
           */
           #if defined (  OSM_NO_THREADS )
          class ACE_Svc_Export OSM_AG_MsgSender
           : public ACE_Svc_Handler<ACE_SOCK_STREAM,   ACE_NULL_SYNCH> // NO_THREADS ACE_NULL_SYNCH o ACE_MT_SYNCH
          #endif
           #if !defined (  OSM_NO_THREADS )
          class OSM_AG_MsgSender
           : public ACE_Svc_Handler<ACE_SOCK_STREAM,   ACE_MT_SYNCH> // NO_THREADS ACE_NULL_SYNCH o ACE_MT_SYNCH
          #endif
          {
          public:
          
           enum
           {
           /// Sending mode: Over the NET.
           OSM_SNDMODE_NET = 0,  
           /// Sending mode: Execute a command.
           OSM_SNDMODE_CMD = 1,  
           /// Sending mode: Both net and command.
           OSM_SNDMODE_BOZ = 2
           };
          
          #if defined (  OSM_NO_THREADS )
          /// typedef PARENT
          typedef ACE_Svc_Handler<ACE_SOCK_STREAM,   ACE_NULL_SYNCH> PARENT;
          #endif
           #if !defined (  OSM_NO_THREADS )
          /// typedef PARENT
          typedef ACE_Svc_Handler<ACE_SOCK_STREAM,   ACE_MT_SYNCH> PARENT;
          #endif
          
           /**
           * This is the initialization hook method. It will receive the connector,   and
           * after initialization tasks will activate the object (  run svc(   ) method ).
           * @retval -1 in case of error.
           */
           virtual int open(  void* conn );
          
           /**
           * This is the entry point into the class to process messages.
           * Basically it puts the mblk in the local queue.
           */
           virtual int put(  ACE_Message_Block* mblk,   ACE_Time_Value* = 0 );
          
           /**
           * handle_close(   ) will be called when a client agent quits.
           * So lets close the socket
           */
           virtual int handle_close (  ACE_HANDLE h= ACE_INVALID_HANDLE,  
           ACE_Reactor_Mask mask = 0 );
          
          protected:
           /**
           * Timeout for queue and networking operations
           */
           int i_timeout_;
          
           /**
           * Time buffer for messages.
           */
           int i_timbuf_;
          
           /**
           * Connector used to send messages to the server.
           */
           OSM_AG_MsgConnector *connector_;
          
           /**
           * Processor used to execute command if supplied.
           */
           OSM_Process process_;
           /**
           * Sender Mode
           */
           int mode_;
          
           /**
           * Command to execute when "sending" messages.
           */
           ACE_TCHAR command_[MAXPATHLEN+1];
          
           /**
           * Character string to hold the execute command
           */
           ACE_TCHAR exec_command_[BUFSIZ+1];
          
           /**
           * Character string to hold the output of the command
           */
           ACE_TCHAR output_[BUFSIZ+1];
          
           /**
           * Will be called when the server disconnects.
           */
           virtual int handle_input(  ACE_HANDLE h );
          
           /**
           * Active object main(   )
           * Waits "for ever" for messages in the queue and sends them to the master
           * agent.
           * Internally uses two parameters to send the buffer: The maximum number of
           * messages in the buffer,   and a number of seconds since the last sent.
           * These to parameters are: ACE_IOV_MAX and TIMBUF (  this is in cfg file ).
           */
           virtual int svc(   );
          
           /**
           * Sends the messages in bulk operations.
           */
           virtual int send (  ACE_Message_Block *chunk[],   size_t &count );
          
          };
          
          /*----------------------------------------------------------------------------*/
          /* OSM_AG_MsgConnector */
          /*----------------------------------------------------------------------------*/
          /**
           * @class OSM_AG_MsgConnector
           *
           * @brief Active connection to connect and keep the stream with the server.
           *
           * This is a "classical" ACE connector. We've added (  copying from ACE code )
           */
          class OSM_AG_MsgConnector
           : public ACE_Connector<OSM_AG_MsgSender,   ACE_SOCK_CONNECTOR>
          {
          public:
           /// To make fast reference to the upper class.
           typedef ACE_Connector<OSM_AG_MsgSender,   ACE_SOCK_CONNECTOR>
           PARENT;
          
           /// Constructor. Initialize the sender object.
           OSM_AG_MsgConnector (  OSM_AG_MsgSender* handler = 0 )
           : svc_handler_ (  handler ) {};
          
           // /**
           // * Open method. Call the base class open(   ).
           // * @retval -1 in case of error.
           // */
           virtual int open (  ACE_Reactor *r = ACE_Reactor::instance (   ),   int flags = 0 );
          
           /**
           * Try to reconnect "RECONN" times using 2(  n ) exponential intervals.
           * @retval -1 in case of error.
           */
           int reconnect (   );
          
          protected:
           // /**
           // * Create and authenticate the connection. Hook method.
           // * @retval -1 in case of error.
           // */
           virtual int connect_svc_handler
           (  OSM_AG_MsgSender *&svc_handler,  
           const ACE_SOCK_Connector::PEER_ADDR &remote_addr,  
           ACE_Time_Value *timeout,  
           const ACE_SOCK_Connector::PEER_ADDR &local_addr,  
           int reuse_addr,   int flags,   int perms );
          
           /**
           * Create and authenticate the connection. Hook method.
           * @retval -1 in case of error.
           */
           virtual int connect_svc_handler
           (  OSM_AG_MsgSender *&svc_handler,  
           OSM_AG_MsgSender *&sh_copy,  
           const ACE_SOCK_Connector::PEER_ADDR &remote_addr,  
           ACE_Time_Value *timeout,  
           const ACE_SOCK_Connector::PEER_ADDR &local_addr,  
           int reuse_addr,   int flags,   int perms );
          
           /// Message sending Service.
           OSM_AG_MsgSender *svc_handler_;
          
           /// Master Agent address (  Local Port ) receiving messages.
           ACE_INET_Addr remote_addr_;
          
          };
          
          /*----------------------------------------------------------------------------*/
          /* OSM_AG_MsgManager */
          /*----------------------------------------------------------------------------*/
          /**
           * @class OSM_AG_MsgManager
           *
           * @brief Receives,   validates message events from agents and send them to master
           *
           * With this service we receive messages from events via our put(   ) method.
           * We store those messages into a Message Queue so the code to execute those
           * events don't need to wait too much time and could continue doing their job.
           * We send the messages in the queue to the master in bulk clusters of messages
           * to improve performance using several threads (  This could be with a
           * configurable parameter ).
           * To do this we use a Connector using a message sender class.
           * Implements a singleton.
           */
          class OSM_AG_MsgManager
          {
          protected:
           /// Factory that actively connects the OSM_AG_MsgSender.
           OSM_AG_MsgConnector connector_;
          
           /// The OSM_AG_MsgSender connected by OSM_AG_MsgConnector.
           OSM_AG_MsgSender msg_sender_;
          
          public:
          
           /// Returns singleton.
           static OSM_AG_MsgManager *instance (  void );
          
           /// Make initial task to run the MSG_Manager Service within Osmius agent.
           int init(  int argc,   ACE_TCHAR *argv[] );
           /// Perform the final task to end the MSG_Manager Service.
           int fini (   );
          
           /// Just pass the call to Msg_Sender put(   ).
           int put(  ACE_Message_Block* mblk,   ACE_Time_Value* tm=0 )
           {
           return this->msg_sender_.put(  mblk,  tm );
           }
          
           /// Return a pointer to the local MSG_Sender.
           OSM_AG_MsgSender* msg_sender(  void )
           {
           return &this->msg_sender_;
           }
          
          private:
           /// Constructor.
           OSM_AG_MsgManager(   )
           : connector_(  &msg_sender_ ) {};
           /// Reference to the singleton instance.
           static OSM_AG_MsgManager* instance_;
          
          };
          
          /*----------------------------------------------------------------------------*/
          #endif /* _OSM_AG_MSGMANAGER_H_*/

ag/osm_agent_basic.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_agent_basic.cpp
          * @brief Basic Agent main program and functions. Use it to build your own agent.
          *
          * @author Jose Luis Marina <joseluis.marina@peopleware.es>
          * @date 18-MAY-2006
          */
          // -----------------------------------------------------------------------------
          // Specific module includes.
          #include "osm_agent_basic.h"
          #include "osm_ag_insmanager.h"
          #include "../cm/osm_reactor.h"
          
          // ACE includes
          //#include <ace/OS.h>
          //#include <ace/Log_Msg.h> // Logging,   trace and debug facility.
          //#include <ace/Version.h> // Always in main to retrieve ACE version.
          
          // Especific ACE includes.
          #include <ace/Get_Opt.h>
          #include <ace/ARGV.h>
          
          // -----------------------------------------------------------------------------
          // Implementation of MAIN program classes
          // -----------------------------------------------------------------------------
          
          // Static initialization.
          OSM_AG_Main *OSM_AG_Main::instance_=0;
          /*----------------------------------------------------------------------------*/
      53  OSM_AG_Main::OSM_AG_Main(  void )
          {
           ACE_OS::strcpy(  PROGRAM_NAME_,  "OSMIUS_AGENT" );
          }
          /*----------------------------------------------------------------------------*/
          OSM_AG_Main*
      59  OSM_AG_Main::instance (  void )
          {
           if (  OSM_AG_Main::instance_ == 0 )
           ACE_NEW_RETURN (  OSM_AG_Main::instance_,   OSM_AG_Main,   0 );
          
           return OSM_AG_Main::instance_;
          }
          
          /*----------------------------------------------------------------------------*/
      68  void OSM_AG_Main::print_usage(  void )
          {
           ACE_DEBUG (  (  LM_DEBUG,  
           ACE_TEXT (  "%s - Osmius %d.%d\n"
           "osmius_agent -c config_file -m master_code -p master_port [-d] [-h]\n\n"
           "\t-c complete path to config file\n"
           "\t-m Master Agent code CHAR[%d]\n"
           "\t-p Master Agent connection port \n"
           "\t-d Debug mode. More messages printed to log file\n"
           "\t-h Print this info\n"
           "\n"
           "Osmius and its code is copyright of Peopleware S.L. Spain.\n"
           "\n"
           "Osmius is Open Source Software under GPL.\n"
           "Osmius is based on ACE C++ frameworks\n"
           "\tACE version is ACE %s\n"
           "More in http://www.osmius.net\n" ),  
           PROGRAM_NAME_ ,  
           OSM_MAX_VERSION,  
           OSM_MIN_VERSION,  
           OSM_Message::CODLEN,  
           ACE_VERSION ) ) ;
          }
          
          /*----------------------------------------------------------------------------*/
      93  int OSM_AG_Main::parse_cmd_line(  int argc,   ACE_TCHAR *argv[] )
          {
           int opt_c=0;
           int opt_p=0;
           int opt_m=0;
          
           ACE_TCHAR aux_char[BUFSIZ]="";
           size_t aux_len;
           ACE_Get_Opt get_opt (  argc,   argv,   ACE_TEXT (  "c:dhp:m:" ),   0 );
          
           OSM_CfgManager::instance(   )->debug_mode(  0 );
          
           for (  int c; (  c = get_opt (   ) ) != -1;  )
           {
           switch (  c )
           {
           case 'c':
           // Config File
           if (  -1 == this->set_config_file(  get_opt.opt_arg (   ) ) )
           return -1;
           opt_c++;
           break;
          // case 'a':
          // // Agent Code is obsolete!!
          // ACE_OS::strcpy(  aux_char,  get_opt.opt_arg (   ) );
          // aux_len = ACE_OS::strlen(  aux_char );
          // if (  aux_len != OSM_Message::CODLEN ) return -1;
          // this->idn_agent(  aux_char,   aux_len );
          // opt_a++;
          // break;
           case 'p':
           // Master Agent Port!!
           ACE_OS::strcpy(  aux_char,  get_opt.opt_arg (   ) );
           this->prt_master_ = ACE_OS::atoi(  aux_char );
           // The port could be 0 if we have SNDCMD !!!!
           opt_p++;
           break;
           case 'm':
           // Master Code!!
           ACE_OS::strcpy(  aux_char,  get_opt.opt_arg (   ) );
           aux_len = ACE_OS::strlen(  aux_char );
           if (  aux_len != OSM_Message::CODLEN ) return -1;
           this->idn_master(  aux_char,   aux_len );
           opt_m++;
           break;
           case 'd':
           OSM_CfgManager::instance(   )->debug_mode(  1 );
           break;
           default:
           return -1;
           }
           }
           if (  (  1 == opt_c )&&(  1 == opt_p )&&(  1 == opt_m ) )
           {
           return 0;
           }
           else
           {
           return -1;
           }
          }
          /*----------------------------------------------------------------------------*/
          int
     156  OSM_AG_Main::set_config_file(  ACE_TCHAR* file )
          {
           register int len;
           len = ACE_OS::strlen(  file );
           if (  (  len < 1 )||(  len > MAXPATHLEN ) ) return -1;
           ACE_OS::strncpy(  this->config_file_,  file,  len );
           this->config_file_[len] = '\0';
           return 0;
          }
          
          /*----------------------------------------------------------------------------*/
          void
     168  OSM_AG_Main::typ_agent (  const ACE_TCHAR *data,   const size_t len )
          {
           ACE_OS::strncpy(  this->typ_agent_,  data,  OSM_Message::CODLEN );
           this->typ_agent_[OSM_Message::CODLEN]='\0';
          };
          
          /*----------------------------------------------------------------------------*/
          const ACE_TCHAR *
     176  OSM_AG_Main::typ_agent(  void ) const
          {
           return this->typ_agent_;
          };
          
          /*----------------------------------------------------------------------------*/
          void
     183  OSM_AG_Main::idn_master (  const ACE_TCHAR *data,   const size_t len )
          {
           ACE_OS::strncpy(  this->idn_master_,  data,  OSM_Message::CODLEN );
           this->idn_master_[OSM_Message::CODLEN]='\0';
          };
          
          /*----------------------------------------------------------------------------*/
          const ACE_TCHAR *
     191  OSM_AG_Main::idn_master(  void ) const
          {
           return this->idn_master_;
          };
          
          /*----------------------------------------------------------------------------*/
          int
     198  OSM_AG_Main::prepare_msg_manager(  ACE_TCHAR* cmd_line,  int len )
          {
           ACE_TCHAR send_cmd[MAXPATHLEN+1]="";
          
           ACE_OS::sprintf(  cmd_line,  ACE_TEXT(  "-m %d" ),  this->prt_master_ );
          
           // We don't need this parameter. We use it only if exists.
           OSM_CfgManager::instance(   )->get_value_str(  "SNDCMD",  
           send_cmd,  
           MAXPATHLEN );
          
           if (  (  int )(  ACE_OS::strlen(  send_cmd ) +15 ) > len )
           {
           return -1;
           }
          
          
           if (  ACE_OS::strlen(  send_cmd ) > 2 )
           {
           ACE_OS::strcat(  cmd_line,  " -C " );
           ACE_OS::strcat(  cmd_line,  send_cmd );
           }
          
           return 0;
          };
          
          /*----------------------------------------------------------------------------*/
          int
     226  OSM_AG_Main::prepare_ins_manager(  ACE_TCHAR* cmd_line,  int len )
          {
           if (  0 == ACE_OS::strlen(  this->config_file_ ) )
           {
           return -1;
           }
          
           if (  (  int )(  ACE_OS::strlen(  this->config_file_ ) +3 ) > len )
           {
           return -1;
           }
          
           ACE_OS::sprintf(  cmd_line,  ACE_TEXT(  "-c %s" ),  this->config_file_ );
          
           return 0;
          };
          /*----------------------------------------------------------------------------*/
          int
     244  OSM_AG_Main::init_work(  int argc,   ACE_TCHAR *argv[] )
          {
           ACE_TCHAR* env_s;
          
           env_s = ACE_OS::getenv(  "OSM_ROOT" );
           if (  env_s == 0 )
           {
           ACE_ERROR_RETURN(  (  LM_ERROR,  
           ACE_TEXT(  "OSM_AG_Main: Env variable OSM_ROOT not defined!!\n" ) ),  
           -1 );
           }
          
           if (  ACE_LOG_MSG->open (  argv[0],  ACE_Log_Msg::STDERR,  ACE_TEXT(  PROGRAM_NAME_ ) ) == -1 )
           {
          
           ACE_ERROR (  (  LM_ERROR,  ACE_TEXT (  "OSM_AG_Main: Cannot open logger\n" ) ) );
           }
          
           // ---------------------------------------------------------------------------
           // Parse Command Line
           // ---------------------------------------------------------------------------
           if (  -1 == parse_cmd_line(  argc,  argv ) )
           {
           print_usage(   );
           return -1;
           }
          
           if (  -1 == parse_config_file(  this->config_file_ ) )
           {
           ACE_ERROR_RETURN(  (  LM_ERROR,  
           ACE_TEXT(  "OSM_AG_Main: Bad or missing parameter. Check the configuration file:\n"
           "\t[%s]\n\n" ),  this->config_file_ ),  -1 );
           }
           // ---------------------------------------------------------------------------
           // Add cfg parameters not in config file.
           // ---------------------------------------------------------------------------
           if (  0 !=
           OSM_CfgManager::instance(   )->add_value_str(  "OSROOT",  env_s )
          // + OSM_CfgManager::instance(   )->add_value_str(  "CODAGT",  this->typ_agent(   ) )
           + OSM_CfgManager::instance(   )->add_value_str(  "CODMST",  this->idn_master(   ) )
           //+ OSM_CfgManager::instance(   )->add_value_int(  "TPREAC",  0 )
           + OSM_CfgManager::instance(   )->add_value_int(  "TIMBUF",  0 )
           + OSM_CfgManager::instance(   )->add_value_int(  "RECVRY",  1 )
           + OSM_CfgManager::instance(   )->add_value_int(  "MSGQSI",  16 )
           + OSM_CfgManager::instance(   )->add_value_str(  "OSMKEY",  "OSMIUS_KEY" )
            )
           {
           ACE_ERROR_RETURN(  (  LM_ERROR,  
           ACE_TEXT(  "OSM_AG_Main: Adding Config parameters\n" ) ),  
           -1 );
           }
          
           return 0;
          }
          
          /*----------------------------------------------------------------------------*/
     300  int OSM_AG_Main::parse_config_file(  ACE_TCHAR* config_file )
          {
           // ---------------------------------------------------------------------------
           // Array of configuration elements.
           // OSMIUS_CONFIGURE
           // ---------------------------------------------------------------------------
           const int num_cfg_elements=3; /** IMPORTANT **/
           OSM_CfgElement CfgArray [num_cfg_elements];
           //CfgArray[0].set_data (  "PORTMA",  OSM_CFG_NUMBER );// Master Agent port. AKI ->> Should be by command line??
           CfgArray[0].set_data (  "PORTCM",  OSM_CFG_NUMBER );// Port to receive commands.
           CfgArray[1].set_data (  "TIMOUT",  OSM_CFG_NUMBER );// Timeout retry
           CfgArray[2].set_data (  "RECONN",  OSM_CFG_NUMBER );// Number of retries to connect server.
           //CfgArray[4].set_data (  "OSMKEY",  OSM_CFG_STRING );// Osmius Code.
           //CfgArray[5].set_data (  "TPREAC",  OSM_CFG_NUMBER );// Use Thread Pool Reactor Implementacion?
           //CfgArray[6].set_data (  "TIMBUF",  OSM_CFG_NUMBER );// Time buffer to wait for sending messages.
           //CfgArray[7].set_data (  "RECVRY",  OSM_CFG_NUMBER );// Try to recover.
           // ---------------------------------------------------------------------------
           // Check if all these parameters are in the configuration file
           // with the right type.
           // ---------------------------------------------------------------------------
           if (  0 != OSM_CfgManager::instance(   )->open(  
           config_file_,  PROGRAM_NAME_,  CfgArray,  num_cfg_elements,  OSM_STAT_NUM ) )
           {
           return -1;
           }
          
           return 0;
          }
          
          /*----------------------------------------------------------------------------*/
     330  int OSM_AG_Main::exit_work(  void )
          {
           int result = 0;
          
           // Shutdown INS_Manager
           if (  -1 == OSM_AG_InsManager::instance(   )->fini(   ) )
           {
           ACE_ERROR(  (  LM_ERROR,  "OSM_AG_Main: exit_work(   )- INS_Manager::fini(   ) Failed\n" ) );
           result = -1;
           }
          
           // Shutdown MSG_Manager
           if (  -1 == OSM_AG_MsgManager::instance(   )->fini(   ) )
           {
           ACE_ERROR(  (  LM_ERROR,  "OSM_AG_Main: exit_work(   )- MSG_Manager::fini(   ) Failed\n" ) );
           result = -1;
           }
           if (  OSM_CfgManager::instance(   )->debug_mode(   ) )
           {
           ACE_DEBUG(  (  LM_DEBUG,  ACE_TEXT(  "(  %P|%T ) OSM_AG_Main: exit_work(   )\n" ) ) );
           ACE_DEBUG(  (  LM_DEBUG,  ACE_TEXT(  "\tProcessed Events.......: %d\n" ),  
           OSM_CfgManager::instance(   )->counter(  OSM_STAT_EVENTS ) ) );
           ACE_DEBUG(  (  LM_DEBUG,  ACE_TEXT(  "\tSended Messages........: %d\n" ),  
           OSM_CfgManager::instance(   )->counter(  OSM_STAT_MSGSND ) ) );
           ACE_DEBUG(  (  LM_DEBUG,  ACE_TEXT(  "\tReconnections..........: %d\n" ),  
           OSM_CfgManager::instance(   )->counter(  OSM_STAT_RECONN ) ) );
           }
           OSM_CfgManager::instance(   )->close(   );
          
           return result;
          }
          
          //------------------------------------------------------------------------------
          // Preparing Reactor and signal to quit gracefully!!
          //------------------------------------------------------------------------------
          // 1.- Convert OSM_Reactor into singleton -> OSM_REACTOR_S
          typedef ACE_Singleton <OSM_Reactor,  ACE_Thread_Mutex> OSM_REACTOR_S;
          
          // 2.- Derive from OSM_SignalHandler_Base a new class and add MsgManager END
     369  class OSM_EndSignal : public OSM_SignalHandler_Base
          {
          public:
          // /// Default constructor.
          // OSM_EndSignal (  int signum = SIGINT ): OSM_SignalHandler_Base (  signum )
          // {
          // };
          
           /// Hook method called when object is signaled by OS.
     378   int handle_signal (  int signum,  siginfo_t * si= 0,  ucontext_t * uc= 0 )
           {
           OSM_SignalHandler_Base::handle_signal(  signum,  si,  uc );
          
           ACE_OS::sleep(  1 );
          
           // Shutdown every thing in a thread loop doing things
           // In this case we must shut down the MSG_Manager
           if (  -1 == OSM_AG_MsgManager::instance(   )->fini(   ) )
           {
           ACE_ERROR(  (  LM_ERROR,  "OSM_AG_Main: exit_work(   )- MSG_Manager::fini(   ) Failed\n" ) );
           }
          
           return -1; // And deregister the signal
           };
          };
          
          // #############################################################################
          // MAIN
          // #############################################################################
          int
     399  ACE_TMAIN (  int argc,   ACE_TCHAR *argv[] )
          {
           // Open OSM_REACTOR_S (  dinamyc memory )
           if (  -1==OSM_REACTOR_S::instance(   )->open(   ) )
           {
           ACE_DEBUG(  (  LM_DEBUG,  
           ACE_TEXT(  "(  %P|%T ) OSM_Main: Couldn't open reactor...\n" ) ) );
           return 1;
           }
          
           if (  -1==OSM_AG_Main::instance(   )->init_work(  argc,  argv ) )
           {
           return 1;
           }
          
           // ---------------------------------------------------------------------------
           // Reactor
           // ---------------------------------------------------------------------------
           int num_reactor_threads = 1; // Default in Agent : Without Threads!!
           if (  -1 == OSM_CfgManager::instance(   )->get_value_int(  "TPREAC",  &num_reactor_threads ) )
           {
           // Default number of Threads (  >1 : Thread_Pool <=1 : Default Reactor.
           num_reactor_threads = 1;
           }
           ACE_OS::last_error(  0 );
          
           if (  -1 == OSM_REACTOR_S::instance(   )->create_reactor(  num_reactor_threads ) )
           {
           ACE_DEBUG(  (  LM_DEBUG,  
           ACE_TEXT(  "(  %P|%T ) OSM_Main: Couldn't create reactor...\n" ) ) );
           return 10;
           }
          
           // ---------------------------------------------------------------------------
           // Prepare signals. Quit if SIGINT is triggered.
           // ---------------------------------------------------------------------------
           OSM_EndSignal signal_handler;
          
           // ---------------------------------------------------------------------------
           // Spawn the Message Manager.
           // ---------------------------------------------------------------------------
           if (  OSM_CfgManager::instance(   )->debug_mode(   ) )
           {
           ACE_DEBUG(  (  LM_DEBUG,  
           ACE_TEXT(  "(  %P|%T ) OSM_Main: MSG_Manager Starting...\n" ) ) );
           }
          
           ACE_OS::last_error(  0 );
          
           ACE_TCHAR cmd_line[BUFSIZ]="";
           // Get the command line for the Message Manager.
           if (   -1 == OSM_AG_Main::instance(   )->prepare_msg_manager(  cmd_line,  BUFSIZ ) )
           {
           ACE_ERROR(  (  LM_ERROR,  
           ACE_TEXT(  "OSM_Main: Could not prepare MSG_Manager. last_error:%d\n" ),  
           ACE_OS::last_error(   ) ) );
           OSM_AG_Main::instance(   )->exit_work(   );
           return 4;
           }
          
           if (  OSM_CfgManager::instance(   )->debug_mode(   ) )
           {
           ACE_DEBUG(  (  LM_DEBUG,  
           ACE_TEXT(  "(  %P|%T ) OSM_Main: MSG_Manager cmd_line is [%s]\n" ),  cmd_line ) );
           }
          
           ACE_ARGV cmd_line_args(  cmd_line );
           // Pass the command line to the Msg_Manager main function: init(   )
           if (  -1 == OSM_AG_MsgManager::instance(   )->init(  cmd_line_args.argc(   ),  
           cmd_line_args.argv(   ) ) )
           {
           ACE_ERROR(  (  LM_ERROR,  
           ACE_TEXT(  "OSM_AG_Main: Failed to initialize MSG_Manager.\n" ) ) );
           OSM_AG_Main::instance(   )->exit_work(   );
           return 5;
           }
           // So we have the MSG_Manager service connected to the local master agent
           // and waiting for message to be inserted into its MSG_Sender Queue,   and
           // send them to the master through its Connector.
           if (  OSM_CfgManager::instance(   )->debug_mode(   ) )
           {
           ACE_DEBUG(  (  LM_DEBUG,  
           ACE_TEXT(  "(  %P|%T ) OSM_AG_Main: MSG_Manager Up and Runnig OK!!\n" ) ) );
           }
          
           // ---------------------------------------------------------------------------
           // Spawn the Instance and Event Manager.
           // ---------------------------------------------------------------------------
           if (  OSM_CfgManager::instance(   )->debug_mode(   ) )
           {
           ACE_DEBUG(  (  LM_DEBUG,  
           ACE_TEXT(  "(  %P|%T ) OSM_AG_Main: INS_Manager Starting...\n" ) ) );
           }
          
           if (   -1 == OSM_AG_Main::instance(   )->prepare_ins_manager(  cmd_line,  BUFSIZ ) )
           {
           ACE_ERROR(  (  LM_ERROR,  
           ACE_TEXT(  "OSM_AG_Main: Could not prepare INS_Manager. last_error:%d\n" ),  
           ACE_OS::last_error(   ) ) );
           OSM_AG_Main::instance(   )->exit_work(   );
           return 14;
           }
          
           if (  OSM_CfgManager::instance(   )->debug_mode(   ) )
           {
           ACE_DEBUG(  (  LM_DEBUG,  
           ACE_TEXT(  "(  %P|%T ) OSM_AG_Main: INS_Manager cmd_line is [%s]\n" ),  cmd_line ) );
           }
          
           ACE_ARGV ins_cmd_line_args(  cmd_line );
           if (  -1 == OSM_AG_InsManager::instance(   )->init(  ins_cmd_line_args.argc(   ),  
           ins_cmd_line_args.argv(   ) ) )
           {
           ACE_ERROR(  (  LM_ERROR,  
           ACE_TEXT(  "OSM_AG_Main: Failed to initialize INS_Manager. Argv:[%s] %d\n" ),  
           cmd_line,  ins_cmd_line_args.argc(   ) ) );
           OSM_AG_Main::instance(   )->exit_work(   );
           return 15;
           }
          
           if (  OSM_CfgManager::instance(   )->debug_mode(   ) )
           {
           ACE_DEBUG(  (  LM_DEBUG,  
           ACE_TEXT(  "(  %P|%T ) OSM_AG_Main: INS_Manager Up and Runnig OK!!\n" ) ) );
           }
          
           // ---------------------------------------------------------------------------
           // Spawn the Command Manager.
           // ---------------------------------------------------------------------------
          
          
           // ---------------------------------------------------------------------------
           // Run the event loop.
           // ---------------------------------------------------------------------------
           if (  OSM_CfgManager::instance(   )->debug_mode(   ) )
           {
           ACE_DEBUG(  (  LM_DEBUG,  
           "(  %P|%T ) OSM_AG_Main: Run reactor event loop in %d threads(   )\n",  
           OSM_REACTOR_S::instance(   )->num_threads(   ) ) );
           }
          
           OSM_REACTOR_S::instance(   )->run_reactor(   );
          
           // ---------------------------------------------------------------------------
           // Bye!!
           // ---------------------------------------------------------------------------
           OSM_AG_Main::instance(   )->exit_work(   );
           return 0;
          }

ag/osm_agent_basic.h

       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_agent_basic.h
          * @brief Basic agent for the Osmius infraestructure. Use it to build your own agent.
          *
          * @author Jose Luis Marina <joseluis.marina@peopleware.es>
          * @date 18-MAY-2006
          */
          // -----------------------------------------------------------------------------
          #ifndef _OSM_AGENT_BASIC_H_
          #define _OSM_AGENT_BASIC_H_
          
          #include "../cm/osm_message.h"
          
          #include <ace/Acceptor.h>
          #include <ace/SOCK_Acceptor.h>
          
          
          
          // -----------------------------------------------------------------------------
          // Counters for statistical use.
          // -----------------------------------------------------------------------------
          enum
          {
           /// Number of statistics
           OSM_STAT_NUM = 3
          };
          
          /**
           * @class OSM_AG_Main
           *
           * @brief Manages Osmius Basic Agent init and exit tasks.
           *
           * It is in charge of the initial actions such as validate command options,  
           * validate config files open log-files and other common resources and to spawn
           * the other services within the process.
           * Also it must do all the end-of-process tasks.
           */
      61  class OSM_AG_Main
          {
          public:
          enum
           {
           OSM_MAX_VERSION = 8,  
           OSM_MIN_VERSION = 07,  
           MAX_THREADS_TPREACTOR = 8
           };
          
           /// Returns Singleton.
      72   static OSM_AG_Main* instance (  void );
          
           /// Exit tasks like closing files and sockets,   free resources.
      75   ~OSM_AG_Main(  void );
          
           /**
           * Make all the initial tasks like check the command line,   env variables,  
           * check config file,   add config information,   starts services,   and open
           * common resources.
           * @retval -1 in case of error(   ).
           */
      83   int init_work (  int argc,   ACE_TCHAR *argv[] );
          
           /**
           * Make all the final tasks like free resources,   end services,   close handles
           * and store statistical information.
           * @retval -1 in case of error.
           */
      90   int exit_work(  void );
           /**
           * Sets config_file private info.
           * @retval -1 in case of error.
           */
      95   int set_config_file(  ACE_TCHAR* file );
          
           /**
           * Prepares the creation and spawn of the MSG_MANAGER service.
           * returns the command line needed by init(   ) to start the service.
           * @retval -1 in case of error(   ).
           */
     102   int prepare_msg_manager(  ACE_TCHAR* cmd_line,  const int len );
          
           /**
           * Prepares the creation and spawn of the INS_MANAGER service.
           * returns the command line needed by init(   ) to start the service.
           * @retval -1 in case of error(   ).
           */
     109   int prepare_ins_manager(  ACE_TCHAR* cmd_line,  const int len );
          
           /**
           * Sets agent code.
           * @retval -1 in case of error.
           */
     115   void typ_agent(  const ACE_TCHAR* data,  const size_t len );
          
           /**
           * Gets master agent code.
           * @retval -1 in case of error.
           */
     121   const ACE_TCHAR* typ_agent(  void ) const;
          
           /**
           * Sets master agent code.
           * @retval -1 in case of error.
           */
     127   void idn_master(  const ACE_TCHAR* data,  const size_t len );
          
           /**
           * Gets master agent code.
           * @retval -1 in case of error.
           */
     133   const ACE_TCHAR* idn_master(  void ) const;
          
          private:
           /// The constructor is private to ensure singleton.
     137   OSM_AG_Main(  void );
           /// Prints usage and command line options.
     139   void print_usage(  void );
           /**
           * Parses command line.
           * @retval -1 in case of error(   ).
           */
     144   int parse_cmd_line(  int argc,   ACE_TCHAR *argv[] );
          
           /**
           * Parses config file using an Array of OSM_CfgElement
           * @retval -1 in case of error(   ).
           */
     150   int parse_config_file(  ACE_TCHAR *cfg_file );
          
           static OSM_AG_Main* instance_;
     153   ACE_TCHAR config_file_ [MAXPATHLEN+1];
     154   ACE_TCHAR PROGRAM_NAME_[MAXPATHLEN+1];
     155   ACE_TCHAR idn_master_ [OSM_Message::CODLEN + 1];
     156   ACE_TCHAR typ_agent_ [OSM_Message::CODLEN + 1]; // Actually this is the Instance Type.
           int prt_master_; // Port where the master agent is listening for message events.
          };
          
          #endif // _OSM_AGENT_BASIC_H_

agents/ag_hpux/osm_ag_hpux.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_hpux.cpp
          * @brief Implementation file for the HP-UX monitoring agent.
          * Osmius - Peopleware.
          *
          * @author Manuel Fraga Castro <joseluis.marina [-at-] peopleware.es>
          * @date 22-AUG-2006.
          */
          // -----------------------------------------------------------------------------
          // These are standard includes for any program
          #include <ace/OS.h>
          #include <ace/Log_Msg.h>
          
          // Specific module includes.
          #include <ace/Time_Value.h>
          
          #include "../../cm/osm_cfgmanager.h"
          
          /*******************************************************************************
           * OSMIUS_HINT 04:
           * Include at least our declaration file and other files needed in the
           * implementation.
           ******************************************************************************/
          #include "osm_ag_hpux.h"
          
          /*----------------------------------------------------------------------------*/
          /* Create Functions Implementation */
          /*----------------------------------------------------------------------------*/
          
          /*******************************************************************************
           * OSMIUS_HINT 05:
           * We have to implement the function used in
           * OSM_AG_InsManager::create_instances(   ) to return new objects of our new
           * instance class.
           ******************************************************************************/
           /**
           * 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 Input - This funtion will make a new over this pointer.
           * @retval -1 in case of error. 0 for success.
           */
      67  int CREATE_OSMIUS_INSTANCE(  const ACE_TCHAR* instance_name,  
           const ACE_TCHAR* instance_type,  
           const ACE_TCHAR* conn_info ,  
           OSM_Instance_Base* &instance )
          {
           // ---------------------------------------------------------------------------
           // Check instance_name.
           // ---------------------------------------------------------------------------
          
           // ---------------------------------------------------------------------------
           // Check instance_type.
           // ---------------------------------------------------------------------------
           // Choose a name(  s ) for the types of instance your agent is about to monitor.
           if (  0 != ACE_OS::strncmp(  instance_type,  ACE_TEXT(  INS_TYPE_01 ),  OSM_Message::TYPLEN ) )
           {
           ACE_ERROR(  (  LM_ERROR,  
           ACE_TEXT(  "CREATE_OSMIUS_INSTANCE: Bad Instance Type [%s]\n" ),  
           instance_type ) );
          
           return -1;
           }
          
           // ---------------------------------------------------------------------------
           // Check conn_info
           // ---------------------------------------------------------------------------
           // We don't have an operational connect nor disconnect functions so we don't
           // have to check this info...
          
           // ---------------------------------------------------------------------------
           // Create the new object.
           // ---------------------------------------------------------------------------
           // We only have this HP-UX instance type: create it and return.
           ACE_NEW_RETURN(  instance,   OSM_Instance_Hpux,   -1 );
          
           return 0;
          }
          
          /*******************************************************************************
           * OSMIUS_HINT 05:
           * We have to implement the function used in
           * OSM_Instance_Base::create_events(   ) to return new objects of our new events
           * with the appropriate new action.
           ******************************************************************************/
          /**
           * 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 ev_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.
           */
     119  int CREATE_OSMIUS_EVENT(  const ACE_TCHAR* event_name ,  
           const ACE_TCHAR* instance_type,  
           const ACE_TCHAR* ev_parameters,  
           int seconds ,  
           OSM_Event* &event )
          {
           // Put here the minimum number of seconds needed by these events to complete.
           // The interval between executions must be greater than this minimum.
           // You can do this with a different value for each event if you want...
           const int min_seconds = 4;
           ACE_TCHAR user_param1 [BUFSIZ+1]="";
           ACE_TCHAR cmd_query [BUFSIZ+1]="";
          
           // ---------------------------------------------------------------------------
           // Check instance_type.
           // ---------------------------------------------------------------------------
           if (  0 != ACE_OS::strncmp(  instance_type,  INS_TYPE_01,  OSM_Message::TYPLEN ) )
           {
           ACE_ERROR(  (  LM_ERROR,  
           ACE_TEXT(  "CREATE_OSMIUS_EVENT: Unknown Instance Type [%s]\n" ),  
           instance_type ) );
           return -1;
           }
           // ---------------------------------------------------------------------------
           // Check if the number of seconds is appropiate with this event.
           // ---------------------------------------------------------------------------
           if (  min_seconds > seconds )
           {
           ACE_ERROR(  (  LM_ERROR,  
           ACE_TEXT(  "CREATE_OSMIUS_EVENT: Interval %d is too low for this event.Must be greater than:%d\n" ),  
           seconds,  min_seconds ) );
           return -1;
           }
          
           OSM_Action_Base* p_action;
           p_action = 0;
           // ---------------------------------------------------------------------------
           // Check event_name and create the event and associated action.
           // ---------------------------------------------------------------------------
          
           // ################### Percentage CPU System Usage ######################
           if (  0 == ACE_OS::strncmp(  event_name,  "HPCPUSYS",  OSM_Message::CODLEN ) )
           {
           ACE_NEW_NORETURN(  event,   OSM_Event );
           if (  0 == event )
           {
           ACE_ERROR(  (  LM_ERROR,  
           ACE_TEXT(  "CREATE_OSMIUS_EVENT: Coul not create new Event\n" ) ) );
           return -1;
           }
           ACE_NEW_NORETURN(  p_action,  OSM_ACT_HpuxCpuSys );
          
           if (  0 == p_action )
           {
           ACE_ERROR(  (  LM_ERROR,  
           ACE_TEXT(  "CREATE_OSMIUS_EVENT: Coul not create new Action - OSM_ACT_HpuxCpuSys\n" ) ) );
           delete event;
           event = 0;
           return -1;
           }
           event->action(  p_action );
           event->cmd_line(  "",  0 );
          
           return 0;
           }
           // ################### Percentage CPU Users Usage ######################
           if (  0 == ACE_OS::strncmp(  event_name,  "HPCPUUSR",  OSM_Message::CODLEN ) )
           {
           ACE_NEW_NORETURN(  event,   OSM_Event );
           if (  0 == event )
           {
           ACE_ERROR(  (  LM_ERROR,  
           ACE_TEXT(  "CREATE_OSMIUS_EVENT: Coul not create new Event\n" ) ) );
           return -1;
           }
           ACE_NEW_NORETURN(  p_action,  OSM_ACT_HpuxCpuUser );
          
           if (  0 == p_action )
           {
           ACE_ERROR(  (  LM_ERROR,  
           ACE_TEXT(  "CREATE_OSMIUS_EVENT: Coul not create new Action - OSM_ACT_HpuxCpuUser\n" ) ) );
           delete event;
           event = 0;
           return -1;
           }
           event->action(  p_action );
           event->cmd_line(  "",  0 );
          
           return 0;
           }
           // ################### Percentage Total CPU Usage ######################
           if (  0 == ACE_OS::strncmp(  event_name,  "HPCPUTOT",  OSM_Message::CODLEN ) )
           {
           ACE_NEW_NORETURN(  event,   OSM_Event );
           if (  0 == event )
           {
           ACE_ERROR(  (  LM_ERROR,  
           ACE_TEXT(  "CREATE_OSMIUS_EVENT: Coul not create new Event\n" ) ) );
           return -1;
           }
           ACE_NEW_NORETURN(  p_action,  OSM_ACT_HpuxCpuTotal );
          
           if (  0 == p_action )
           {
           ACE_ERROR(  (  LM_ERROR,  
           ACE_TEXT(  "CREATE_OSMIUS_EVENT: Coul not create new Action - OSM_ACT_HpuxCpuTotal\n" ) ) );
           delete event;
           event = 0;
           return -1;
           }
           event->action(  p_action );
           event->cmd_line(  "",  0 );
          
           return 0;
           }
           // ############################# NULL Event ##################################
           p_action = 0;
           if (  0 == ACE_OS::strncmp(  event_name,  "NULLEVNT",  OSM_Message::CODLEN ) )
           {
           ACE_NEW_NORETURN(  event,   OSM_Event );
           if (  0 == event )
           {
           ACE_ERROR(  (  LM_ERROR,  
           ACE_TEXT(  "CREATE_OSMIUS_EVENT: Coul not create new Event\n" ) ) );
           return -1;
           }
           ACE_NEW_NORETURN(  p_action,   OSM_ACT_HpuxNull );
          
           if (  0 == p_action )
           {
           ACE_ERROR(  (  LM_ERROR,  
           ACE_TEXT(  "CREATE_OSMIUS_EVENT: Coul not create new Action - OSM_ACT_HpuxNull\n" ) ) );
           delete event;
           event = 0;
           return -1;
           }
           event->action(  p_action );
           event->cmd_line(  "NULL",  4 );
          
           return 0;
           }
          
           // ############################# Active IP4 Interfaces ######################
           if (  0 == ACE_OS::strncmp(  event_name,  "HPIP4INT",  OSM_Message::CODLEN ) )
           {
           ACE_NEW_NORETURN(  event,   OSM_Event );
           if (  0 == event )
           {
           ACE_ERROR(  (  LM_ERROR,  
           ACE_TEXT(  "CREATE_OSMIUS_EVENT: Coul not create new Event\n" ) ) );
           return -1;
           }
           ACE_NEW_NORETURN(  p_action,  OSM_ACT_IP4Interfaces );
          
           if (  0 == p_action )
           {
           ACE_ERROR(  (  LM_ERROR,  
           ACE_TEXT(  "CREATE_OSMIUS_EVENT: Coul not create new Action - OSM_ACT_IP4Interfaces\n" ) ) );
           delete event;
           event = 0;
           return -1;
           }
           event->action(  p_action );
           event->cmd_line(  "NULL",  4 );
          
           return 0;
           }
           // ############################# Active IP6 Interfaces ######################
           if (  0 == ACE_OS::strncmp(  event_name,  "HPIP6INT",  OSM_Message::CODLEN ) )
           {
           ACE_NEW_NORETURN(  event,   OSM_Event );
           if (  0 == event )
           {
           ACE_ERROR(  (  LM_ERROR,  
           ACE_TEXT(  "CREATE_OSMIUS_EVENT: Coul not create new Event\n" ) ) );
           return -1;
           }
           ACE_NEW_NORETURN(  p_action,  OSM_ACT_IP6Interfaces );
          
           if (  0 == p_action )
           {
           ACE_ERROR(  (  LM_ERROR,  
           ACE_TEXT(  "CREATE_OSMIUS_EVENT: Coul not create new Action - OSM_ACT_IP6Interfaces\n" ) ) );
           delete event;
           event = 0;
           return -1;
           }
           event->action(  p_action );
           event->cmd_line(  "NULL",  4 );
          
           return 0;
           }
          
          // ################### Number of total running processes ######################
           if (  0 == ACE_OS::strncmp(  event_name,  "HPNUMPRC",  OSM_Message::CODLEN ) )
           {
           ACE_NEW_NORETURN(  event,   OSM_Event );
           if (  0 == event )
           {
           ACE_ERROR(  (  LM_ERROR,  
           ACE_TEXT(  "CREATE_OSMIUS_EVENT: Coul not create new Event\n" ) ) );
           return -1;
           }
           ACE_NEW_NORETURN(  p_action,  OSM_ACT_HpuxTotalProc );
          
           if (  0 == p_action )
           {
           ACE_ERROR(  (  LM_ERROR,  
           ACE_TEXT(  "CREATE_OSMIUS_EVENT: Coul not create new Action - OSM_ACT_HpuxTotalProc\n" ) ) );
           delete event;
           event = 0;
           return -1;
           }
           event->action(  p_action );
           event->cmd_line(  "",  0 );
          
           return 0;
           }
          
          // ####################### MB of Free Memory ##########################
           if (  0 == ACE_OS::strncmp(  event_name,  "HPFREMEM",  OSM_Message::CODLEN ) )
           {
           ACE_NEW_NORETURN(  event,   OSM_Event );
           if (  0 == event )
           {
           ACE_ERROR(  (  LM_ERROR,  
           ACE_TEXT(  "CREATE_OSMIUS_EVENT: Coul not create new Event\n" ) ) );
           return -1;
           }
           ACE_NEW_NORETURN(  p_action,  OSM_ACT_HpuxFreeMem );
          
           if (  0 == p_action )
           {
           ACE_ERROR(  (  LM_ERROR,  
           ACE_TEXT(  "CREATE_OSMIUS_EVENT: Coul not create new Action - OSM_ACT_HpuxFreeMem\n" ) ) );
           delete event;
           event = 0;
           return -1;
           }
           event->action(  p_action );
           event->cmd_line(  "",  0 );
          
           return 0;
           }
          
          // ################### HP-UX uptime in seconds ######################
           if (  0 == ACE_OS::strncmp(  event_name,  "HPUPTIME",  OSM_Message::CODLEN ) )
           {
           ACE_NEW_NORETURN(  event,   OSM_Event );
           if (  0 == event )
           {
           ACE_ERROR(  (  LM_ERROR,  
           ACE_TEXT(  "CREATE_OSMIUS_EVENT: Coul not create new Event\n" ) ) );
           return -1;
           }
           ACE_NEW_NORETURN(  p_action,  OSM_ACT_HpuxUpTime );
          
           if (  0 == p_action )
           {
           ACE_ERROR(  (  LM_ERROR,  
           ACE_TEXT(  "CREATE_OSMIUS_EVENT: Coul not create new Action - OSM_ACT_HpuxUpTime\n" ) ) );
           delete event;
           event = 0;
           return -1;
           }
           event->action(  p_action );
           event->cmd_line(  "",  0 );
          
           return 0;
           }
          
          // ############################# Process Down ######################
           if (  0 == ACE_OS::strncmp(  event_name,  "HPPRCDWN",  OSM_Message::CODLEN ) )
           {
           ACE_NEW_NORETURN(  event,   OSM_Event );
           if (  0 == event )
           {
           ACE_ERROR(  (  LM_ERROR,  
           ACE_TEXT(  "CREATE_OSMIUS_EVENT: Coul not create new Event\n" ) ) );
           return -1;
           }
           ACE_NEW_NORETURN(  p_action,  OSM_ACT_HpuxProcessDown );
          
           if (  0 == p_action )
           {
           ACE_ERROR(  (  LM_ERROR,  
           ACE_TEXT(  "CREATE_OSMIUS_EVENT: Coul not create new Action - OSM_ACT_HpuxProcessDown\n" ) ) );
           delete event;
           event = 0;
           return -1;
           }
           event->action(  p_action );
           event->cmd_line(  "",  0 );
          
           if (  ACE_OS::strlen(  ev_parameters ) )
           {
           OSM_CfgManager::instance(   )->get_param (  ev_parameters,   'L',  user_param1,  BUFSIZ );
           }
          
           if (  ACE_OS::strlen(  user_param1 ) < 3 )
           {
           ACE_ERROR(  (  LM_ERROR,  
           ACE_TEXT(  "CREATE_OSMIUS_EVENT: Could not create new Action - OSM_ACT_HpuxProcessDown\n"
           " Could not find -L parameters. List of processes.\n" ) ) );
           delete p_action;
           p_action = 0;
           delete event;
           event = 0;
           return -1;
           }
          
           ACE_TCHAR procs[BUFSIZ];
           ACE_OS::sprintf(  procs,  "-p %s",  user_param1 );
          
           event->cmd_line(  procs,  ACE_OS::strlen(  procs ) );
          
           return 0;
           }
          
          // ################### HP-UX number of cpus in the system ######################
           if (  0 == ACE_OS::strncmp(  event_name,  "HPNUMCPU",  OSM_Message::CODLEN ) )
           {
           ACE_NEW_NORETURN(  event,   OSM_Event );
           if (  0 == event )
           {
           ACE_ERROR(  (  LM_ERROR,  
           ACE_TEXT(  "CREATE_OSMIUS_EVENT: Coul not create new Event HPNUMCPU\n" ) ) );
           return -1;
           }
           ACE_NEW_NORETURN(  p_action,  OSM_ACT_HpuxNumCpu );
          
           if (  0 == p_action )
           {
           ACE_ERROR(  (  LM_ERROR,  
           ACE_TEXT(  "CREATE_OSMIUS_EVENT: Coul not create new Action - OSM_ACT_HpuxNumCpu\n" ) ) );
           delete event;
           event = 0;
           return -1;
           }
           event->action(  p_action );
           event->cmd_line(  "",  0 );
          
           return 0;
           }
          
          // ################### HP-UX used memory percentage ######################
           if (  0 == ACE_OS::strncmp(  event_name,  "HPPRCMEM",  OSM_Message::CODLEN ) )
           {
           ACE_NEW_NORETURN(  event,   OSM_Event );
           if (  0 == event )
           {
           ACE_ERROR(  (  LM_ERROR,  
           ACE_TEXT(  "CREATE_OSMIUS_EVENT: Coul not create new Event HPPRCMEM\n" ) ) );
           return -1;
           }
           ACE_NEW_NORETURN(  p_action,  OSM_ACT_HpuxPrcMem );
          
           if (  0 == p_action )
           {
           ACE_ERROR(  (  LM_ERROR,  
           ACE_TEXT(  "CREATE_OSMIUS_EVENT: Coul not create new Action - OSM_ACT_HpuxPrcMem\n" ) ) );
           delete event;
           event = 0;
           return -1;
           }
           event->action(  p_action );
           event->cmd_line(  "",  0 );
          
           return 0;
           }
          
          // ##################### HP-UX percentage of Used FileSystem ##################
           if (  0 == ACE_OS::strncmp(  event_name,  "HPPRCHFS",  OSM_Message::CODLEN ) )
           {
           ACE_NEW_NORETURN(  event,   OSM_Event );
           if (  0 == event )
           {
           ACE_ERROR(  (  LM_ERROR,  
           ACE_TEXT(  "CREATE_OSMIUS_EVENT: Coul not create new Event\n" ) ) );
           return -1;
           }
           ACE_NEW_NORETURN(  p_action,  OSM_ACT_HpuxFSUsed );
          
           if (  0 == p_action )
           {
           ACE_ERROR(  (  LM_ERROR,  
           ACE_TEXT(  "CREATE_OSMIUS_EVENT: Coul not create new Action - OSM_ACT_HpuxFSUsed\n" ) ) );
           delete event;
           event = 0;
           return -1;
           }
           event->action(  p_action );
           event->cmd_line(  "",  0 );
          
           if (  ACE_OS::strlen(  ev_parameters ) )
           {
           OSM_CfgManager::instance(   )->get_param (  ev_parameters,   'L',  user_param1,  BUFSIZ );
           }
          
           if (  ACE_OS::strlen(  user_param1 ) < 1 )
           {
           ACE_ERROR(  (  LM_ERROR,  
           ACE_TEXT(  "CREATE_OSMIUS_EVENT: Coul not create new Action - OSM_ACT_HpuxFSUsed\n"
           " Could not find -L parameters. List of filesystems.\n" ) ) );
           delete p_action;
           p_action = 0;
           delete event;
           event = 0;
           return -1;
           }
          
           ACE_TCHAR procs[BUFSIZ];
           ACE_OS::sprintf(  procs,  "-p %s",  user_param1 );
          
           event->cmd_line(  procs,  ACE_OS::strlen(  procs ) );
          
           return 0;
           }
          
          // ################### HP-UX percentage of used swap ######################
           if (  0 == ACE_OS::strncmp(  event_name,  "HPPRCSWP",  OSM_Message::CODLEN ) )
           {
           ACE_NEW_NORETURN(  event,   OSM_Event );
           if (  0 == event )
           {
           ACE_ERROR(  (  LM_ERROR,  
           ACE_TEXT(  "CREATE_OSMIUS_EVENT: Coul not create new Event HPPRCSWP\n" ) ) );
           return -1;
           }
           ACE_NEW_NORETURN(  p_action,  OSM_ACT_HpuxPrcSwp );
          
           if (  0 == p_action )
           {
           ACE_ERROR(  (  LM_ERROR,  
           ACE_TEXT(  "CREATE_OSMIUS_EVENT: Coul not create new Action - OSM_ACT_HpuxPrcSwp\n" ) ) );
           delete event;
           event = 0;
           return -1;
           }
           event->action(  p_action );
           event->cmd_line(  "",  0 );
          
           return 0;
           }
          
           // ############################# Logfile Scan ######################
           if (  0 == ACE_OS::strncmp(  event_name,  "HPLOG0",  OSM_Message::CODLEN-2 ) )
           {
           ACE_TCHAR auxbuf[BUFSIZ];
           ACE_NEW_NORETURN(  event,   OSM_Event );
           if (  0 == event )
           {
           ACE_ERROR(  (  LM_ERROR,  
           ACE_TEXT(  "CREATE_OSMIUS_EVENT: Coul not create new Event - HPLOG0\n" ) ) );
           return -1;
           }
           ACE_NEW_NORETURN(  p_action,  OSM_ACT_ScanLog );
          
           if (  0 == p_action )
           {
           ACE_ERROR(  (  LM_ERROR,  
           ACE_TEXT(  "CREATE_OSMIUS_EVENT: Coul not create new Action - OSM_ACT_ScanLog\n" ) ) );
           delete event;
           event = 0;
           return -1;
           }
           event->action(  p_action );
           event->cmd_line(  "",  0 );
          
           // Get the full logfile path -L "/logdir/logfile.log".
           user_param1[0] = '\0';
           if (  ACE_OS::strlen(  ev_parameters ) )
           {
           OSM_CfgManager::instance(   )->get_param (  ev_parameters,   'L',  user_param1,  BUFSIZ );
           }
           if (  !ACE_OS::strlen(  user_param1 ) )
           {
           ACE_ERROR(  (  LM_ERROR,  
           ACE_TEXT(  "CREATE_OSMIUS_EVENT: Coul not create new Action - OSM_ACT_ScanLog\n"
           " Could not find -L parameter. Logfile full path.\n" ) ) );
           delete p_action;
           p_action = 0;
           delete event;
           event = 0;
           return -1;
           }
           else
           {
           ACE_OS::sprintf(  cmd_query,  "-l %s",  user_param1 );
           }
           // Get the string to search within the logfile.
           if (  ACE_OS::strlen(  ev_parameters ) )
           {
           OSM_CfgManager::instance(   )->get_param (  ev_parameters,   'S',  user_param1,  BUFSIZ );
           }
          
           if (  !ACE_OS::strlen(  user_param1 ) )
           {
           ACE_ERROR(  (  LM_ERROR,  
           ACE_TEXT(  "CREATE_OSMIUS_EVENT: Coul not create new Action - OSM_ACT_ScanLog\n"
           " Could not find -S parameter. String to search.\n" ) ) );
           delete p_action;
           p_action = 0;
           delete event;
           event = 0;
           return -1;
           }
           else
           {
           ACE_OS::sprintf(  auxbuf,  " -s %s",  user_param1 );
           ACE_OS::strcat(  cmd_query,  auxbuf );
           }
          
           event->cmd_line(  cmd_query,  ACE_OS::strlen(  cmd_query ) );
           return 0;
           }
          
           // We have an unknown Event name. don't know what to do.
           ACE_ERROR(  (  LM_ERROR,  
           ACE_TEXT(  "CREATE_OSMIUS_EVENT: Bad Event Name [%s]\n" ),  
           event_name ) );
          
           return -1;
          
          }
          /*----------------------------------------------------------------------------*/
          /* OSM_ACT_HpuxNull Implementation */
          /*----------------------------------------------------------------------------*/
     647  int OSM_ACT_HpuxNull::execute (  const ACE_TCHAR* cmd_line,  const int cmd_len ,  
     648   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(   ) ) );
           // }
          
           // You can use the pointer to "our" instance (  this->osm_instance_ ) to access
           // instance data. In this example we don't use it.
          
           // Do whatever you must do to get the value and its text.
           ACE_OS::strcpy(  val_text,  "NULL Event Text" );
           val_len=15;
           value = value_++;
          
           return 0;
          }
          /*----------------------------------------------------------------------------*/
     687  int OSM_ACT_HpuxNull::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 ) );
           //}
          
           // Check the Command Line.
          
           return 0;
          }
          
          /*----------------------------------------------------------------------------*/
          /* OSM_ACT_HpuxCpuSys Implementation */
          /*----------------------------------------------------------------------------*/
     706  int OSM_ACT_HpuxCpuSys::execute (  const ACE_TCHAR* cmd_line,  const int cmd_len,  
     707   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(   ) ) );
           // }
          
           ACE_TCHAR command[BUFSIZ+1]="";
          
           ACE_OS::sprintf(  command,  "ksh -c \"vmstat 2 2 | tail -1 | awk '{ print $17 }'\"" );
           value = 0;
          
           if (  -1 == OSM_ACT_ExecuteProcess::execute(  command,  ACE_OS::strlen(  command ),  
           timeout ,  val_text ,  
           val_len ,  value ) )
           {
           return -1;
           }
          
           value = ACE_OS::atoi(  val_text );
          
           if (  value < 0 )
           {
           value = -1;
           ACE_OS::sprintf(  val_text,  "command [%s] failed!!",  command );
           val_len = ACE_OS::strlen(  val_text );
           return -1;
           }
          
           val_text[0] = '\0';
           val_len = 0;
          
           return 0;
          }
          
          /*----------------------------------------------------------------------------*/
          /* OSM_ACT_HpuxCpuUser Implementation */
          /*----------------------------------------------------------------------------*/
     767  int OSM_ACT_HpuxCpuUser::execute (  const ACE_TCHAR* cmd_line,  const int cmd_len,  
     768   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(   ) ) );
           // }
          
           ACE_TCHAR command[BUFSIZ+1]="";
          
           ACE_OS::sprintf(  command,  "ksh -c \"vmstat 2 2 | tail -1 | awk '{ print $16 }'\"" );
           value = 0;
          
           if (  -1 == OSM_ACT_ExecuteProcess::execute(  command,  ACE_OS::strlen(  command ),  
           timeout ,  val_text ,  
           val_len ,  value ) )
           {
           return -1;
           }
          
           value = ACE_OS::atoi(  val_text );
          
           if (  value < 0 )
           {
           value = -1;
           ACE_OS::sprintf(  val_text,  "command [%s] failed!!",  command );
           val_len = ACE_OS::strlen(  val_text );
           return -1;
           }
          
           val_text[0] = '\0';
           val_len = 0;
          
           return 0;
          }
          
          /*----------------------------------------------------------------------------*/
          /* OSM_ACT_HpuxCpuTotal Implementation */
          /*----------------------------------------------------------------------------*/
     828  int OSM_ACT_HpuxCpuTotal::execute (  const ACE_TCHAR* cmd_line,  const int cmd_len,  
     829   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(   ) ) );
           // }
          
           ACE_TCHAR command[BUFSIZ+1]="";
          
           ACE_OS::sprintf(  command,  "ksh -c \"vmstat | tail -1 | awk '{ print $18 }'\"" );
           value = 0;
          
           if (  -1 == OSM_ACT_ExecuteProcess::execute(  command,  ACE_OS::strlen(  command ),  
           timeout ,  val_text ,  
           val_len ,  value ) )
           {
           return -1;
           }
          
           value = ACE_OS::atoi(  val_text );
          //This is to convert idle use percentage in non-idle
           value = 100 - value;
          
           if (  value < 0 )
           {
           value = -1;
           ACE_OS::sprintf(  val_text,  "command [%s] failed!!",  command );
           val_len = ACE_OS::strlen(  val_text );
           return -1;
           }
          
           val_text[0] = '\0';
           val_len = 0;
          
           return 0;
          }
          
          /*----------------------------------------------------------------------------*/
          /* OSM_ACT_HpuxTotalProc Implementation */
          /*----------------------------------------------------------------------------*/
     891  int OSM_ACT_HpuxTotalProc::execute (  const ACE_TCHAR* cmd_line,  const int cmd_len,  
     892   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(   ) ) );
           // }
          
           ACE_TCHAR command[BUFSIZ+1]="";
          
           ACE_OS::sprintf(  command,  "ksh -c \"ps -e | wc -l\"" );
           value = 0;
          
           if (  -1 == OSM_ACT_ExecuteProcess::execute(  command,  ACE_OS::strlen(  command ),  
           timeout ,  val_text ,  
           val_len ,  value ) )
           {
           return -1;
           }
          
           value = ACE_OS::atoi(  val_text );
          
           if (  value < 0 )
           {
           value = -1;
           ACE_OS::sprintf(  val_text,  "command [%s] failed!!",  command );
           val_len = ACE_OS::strlen(  val_text );
           return -1;
           }
          
           val_text[0] = '\0';
           val_len = 0;
          
           return 0;
          }
          
          /*----------------------------------------------------------------------------*/
          /* OSM_ACT_HpuxFreeMem Implementation */
          /*----------------------------------------------------------------------------*/
     952  int OSM_ACT_HpuxFreeMem::execute (  const ACE_TCHAR* cmd_line,  const int cmd_len,  
     953   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(   ) ) );
           // }
          
           ACE_TCHAR command[BUFSIZ+1]="";
          
           ACE_OS::sprintf(  command,  "ksh -c \"vmstat | tail -1 | awk '{print (  $5*4 )/1024}'\"" );
           value = 0;
          
           if (  -1 == OSM_ACT_ExecuteProcess::execute(  command,  ACE_OS::strlen(  command ),  
           timeout ,  val_text ,  
           val_len ,  value ) )
           {
           return -1;
           }
          
           value = ACE_OS::atoi(  val_text );
          
           if (  value < 0 )
           {
           value = -1;
           ACE_OS::sprintf(  val_text,  "command [%s] failed!!",  command );
           val_len = ACE_OS::strlen(  val_text );
           return -1;
           }
          
           val_text[0] = '\0';
           val_len = 0;
          
           return 0;
          }
          
          /*----------------------------------------------------------------------------*/
          /* OSM_ACT_HpuxUpTime Implementation */
          /*----------------------------------------------------------------------------*/
    1013  int OSM_ACT_HpuxUpTime::execute(  const ACE_TCHAR* cmd_line,  const int cmd_len ,  
    1014   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(   ) ) );
           // }
          
           // Lets do important things .....
           // Get uptime value in seconds in HP-UX.
           struct pst_static pst;
           pstat_getstatic (   &pst,   sizeof (   pst  ),   (  size_t ) 1,   0  );
           // {
           // ACE_ERROR(  (  LM_ERROR,  ACE_TEXT(  "(  %P|%t ) OSM_Action : could not obtain HP-UX uptime\n" ) ) );
           // value = -1;
           // return -1;
           // }
           this->uptime_ = (  time(  NULL ) - pst.boot_time  );
           value = this-> uptime_;
          
           int days = value / 86400;
           int hours = (  value/3600 ) - (  days * 24 );
           int mins = (  value/60 ) - (  (  days * 1440 ) + (  hours * 60 ) );
          
           OSM_Instance_Hpux* p = (  OSM_Instance_Hpux* ) this->instance(   );
          
           ACE_OS::sprintf(  val_text,  "Days[%d] Hours[%d] Mins[%d] [%s]",  
           days ,  
           hours ,  
           mins ,  
           p->hostname(   ) );
           val_len=ACE_OS::strlen(  val_text );
          
           //ACE_OS::sprintf(  val_text,  "Uptime:[%d]",  
           // this->uptime_ );
           //val_len=ACE_OS::strlen(  val_text );
          
           return 0;
          }
          /*----------------------------------------------------------------------------*/
          //int OSM_ACT_HpuxUpTime::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 ) );
          // //}
          //
          // // Check the Command Line.
          //
          // return 0;
          //}
          
          /*----------------------------------------------------------------------------*/
          /* OSM_ACT_HpuxProcessDown Implementation */
          /*----------------------------------------------------------------------------*/
    1094  int OSM_ACT_HpuxProcessDown::execute (  const ACE_TCHAR* cmd_line,  const int cmd_len,  
    1095