⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 locator_options.cpp

📁 这是广泛使用的通信开源项目,对于大容量,高并发的通讯要求完全能够胜任,他广泛可用于网络游戏医学图像网关的高qos要求.更详细的内容可阅读相应的材料
💻 CPP
字号:
//=============================================================================
/**
 *  @file    Locator_Options.cpp
 *
 *  Locator_Options.cpp,v 1.2 2003/11/12 22:58:08 michel_j Exp
 *
 *  @author Darrell Brunsch <brunsch@cs.wustl.edu>
 */
//=============================================================================

#include "Locator_Options.h"
#include "Locator_NT_Service.h"
#include "tao/Strategies/advanced_resource.h"
#include "ace/Arg_Shifter.h"
#include "ace/ARGV.h"
#include "ace/OS_NS_strings.h"
#include "ace/Mutex.h"

ACE_RCSID (ImplRepo_Service,
           Options,
           "Locator_Options.cpp,v 1.2 2003/11/12 22:58:08 michel_j Exp")


#if defined (ACE_WIN32)
static const HKEY SERVICE_REG_ROOT = HKEY_LOCAL_MACHINE;
// This string must agree with the one used in Locator_NT_Service.h
static const ACE_TCHAR *SERVICE_REG_PATH =
  ACE_TEXT ("SYSTEM\\CurrentControlSet\\Services\\TAOIMRLocator\\Parameters");
#endif /* ACE_WIN32 */

/**
 * Default Constructor.  Assigns default values to all the member variables.
 */
Options::Options ()
  : debug_ (1)
  , multicast_ (false)
  , service_ (false)
  , service_command_(SC_NONE)
{
}

/**
 * parse_args uses an ACE_Arg_Shifter to grab all the options that are
 * specific to the ImR.
 *
 * @retval  0 Success
 * @retval -1 Error parsing args
 * @retval  1 Success but we should exit.
 */
int
Options::parse_args (int &argc, char *argv[])
{
  ACE_Arg_Shifter shifter (argc, argv);

  while (shifter.is_anything_left ())
    {
      if (ACE_OS::strcasecmp (shifter.get_current (),
                              ACE_TEXT ("-c")) == 0)
        {
          shifter.consume_arg ();

          if (!shifter.is_anything_left () || shifter.get_current ()[0] == '-')
            {
              ACE_ERROR ((LM_ERROR, "Error: -c option needs a command\n"));
              this->print_usage ();
              return -1;
            }

          if (ACE_OS::strcasecmp (shifter.get_current (),
                                   ACE_TEXT ("install")) == 0) 
          {
            this->service_command_ = SC_INSTALL;
          }
          else if (ACE_OS::strcasecmp (shifter.get_current (),
                                   ACE_TEXT ("remove")) == 0) 
          {
            this->service_command_ = SC_REMOVE;
          }
          else
          {
            ACE_ERROR((LM_ERROR, "Error: Unknown service command : %s\n", shifter.get_current()));
            this->print_usage ();
            return -1;
          } 
        }
      else if (ACE_OS::strcasecmp (shifter.get_current (),
                                   ACE_TEXT ("-d")) == 0)
        {
          shifter.consume_arg ();

          if (!shifter.is_anything_left () || shifter.get_current ()[0] == '-')
            {
              ACE_ERROR ((LM_ERROR, "Error: -d option needs a debuglevel\n"));
              this->print_usage ();
              return -1;
            }

          this->debug_ = ACE_OS::atoi (shifter.get_current ());
        }
      else if (ACE_OS::strcasecmp (shifter.get_current (),
                                   ACE_TEXT ("-m")) == 0)
        {
          this->multicast_ = true;
        }
      else if (ACE_OS::strcasecmp (shifter.get_current (),
                                   ACE_TEXT ("-o")) == 0)
        {
          shifter.consume_arg ();

          if (!shifter.is_anything_left () || shifter.get_current ()[0] == '-')
            {
              ACE_ERROR ((LM_ERROR, "Error: -o option needs a filename\n"));
              this->print_usage ();
              return -1;
            }
          this->ior_output_file_ = shifter.get_current();
        }
      else if (ACE_OS::strcasecmp (shifter.get_current (),
                                   ACE_TEXT ("-s")) == 0)
        {
          // Run as a service
          this->service_ = true;
        }
      else if ((ACE_OS::strcasecmp (shifter.get_current (),
                                    ACE_TEXT ("-?")) == 0)
               || (ACE_OS::strcasecmp (shifter.get_current (),
                                       ACE_TEXT ("-h")) == 0))
        {
          this->print_usage ();
          return 1;
        }
      else
        {
          shifter.ignore_arg ();
          continue;
        }

      shifter.consume_arg ();
    }

  return 0;
}

/**
 * @retval  0 Success
 * @retval -1 Error parsing args
 * @retval  1 Success but we should exit.
 */
int
Options::init (int argc, char *argv[])
{
  int result = this->parse_args (argc, argv);
  if (result != 0) {
    return result;
  }

  ACE_ARGV orb_args;   // Save the leftovers to a ACE_ARGV class
  ACE_CString cmdline; // We'll save this in the registry when installing.
  for (int i = 1; i < argc; ++i)
    {
      cmdline += ACE_CString(argv[i]) + ACE_CString(" ");
      if (orb_args.add (argv[i]) == -1)
        {
          ACE_ERROR ((LM_ERROR, "Error: Could not save argument"));
          return -1;
        }
    }

  result = run_service_command(cmdline);
  
  if (result != 0) 
    return result;

  char* argv_tmp = 0;

  // Load from the registry. This may replace the args.
  if (this->load_registry_options(argv_tmp, orb_args) != 0)
    return -1;

  ACE_Auto_Array_Ptr<char> argv_deleter(argv_tmp);

  int orb_argc = orb_args.argc ();
  // Now initialize the orb and pass it the leftover arguments
  ACE_TRY_NEW_ENV
    {
      this->orb_ = CORBA::ORB_init (orb_argc,
                                    orb_args.argv (),
                                    0
                                    ACE_ENV_ARG_PARAMETER);
      ACE_TRY_CHECK;
    }
  ACE_CATCHANY
    {
      ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,
                           "Caught exception \n");
      ACE_ERROR ((LM_ERROR, "Error: Cannot initialize ORB\n"));
      return -1;
    }
  ACE_ENDTRY;

  // Indicates successful parsing of command line.
  return 0;
}


/**
 * Just print out the usage message to STDERR
 */
void
Options::print_usage (void) const
{
  ACE_ERROR ((LM_ERROR,
              "Usage:\n"
              "\n"
              "ImR_Locator [-c cmd] [-d 0|1|2] [-m] [-o file] [-s]\n"
              "\n"
              "  -c command  Runs nt service commands ('install' or 'remove')\n"
              "  -d level    Sets the debug level (default 1)\n"
              "  -m          Turn on multicast\n"
              "  -o file     Outputs the ImR's IOR to a file\n"
              "  -s          Runs as a service (NT Only)\n")
             );
}


/**
 * Executes the various commands that are useful for a NT service.  Right
 * now these include 'install' and 'remove'.  Others, such as 'start' and
 * 'stop' can be added, but the 'net' program in Windows already handles
 * these commands.
 *
 * @todo Finish implementing Options::run_service_command
 * @todo Update to unicode
 */
int
Options::run_service_command (const ACE_CString& cmdline)
{
  if (this->service_command_ == SC_NONE) 
    return 0;
#if defined (ACE_WIN32)
  SERVICE::instance ()->name (IMR_LOCATOR_SERVICE_NAME, IMR_LOCATOR_DISPLAY_NAME);

  if (this->service_command_ == SC_INSTALL)
    {
      char pathname[_MAX_PATH * 2 + 3];  // +3 for the ' -s' at the end

      if (ACE_TEXT_GetModuleFileName(NULL, pathname, _MAX_PATH * 2) == 0)
        {
          ACE_ERROR ((LM_ERROR, "Error: Could not get module file name.\n"));
          return -1;
        }

      // Append the command used for running the implrepo as
      ACE_OS::strcat (pathname, ACE_TEXT (" -s"));

      int ret =  SERVICE::instance ()->insert (SERVICE_DEMAND_START,
                                           SERVICE_ERROR_NORMAL,
                                           pathname
                                           );
      if (ret != -1) {
        if (debug() > 0) {
          ACE_DEBUG ((LM_DEBUG, "ImR Locator: Service installed.\n"));
        }
        this->save_registry_options(cmdline);
      } else {
        ACE_ERROR((LM_ERROR, "Error: Failed to install service.\n"));
      }
      if (ret == 0) 
        return 1;
    }
  else if (this->service_command_ == SC_REMOVE)
    {
      int ret = SERVICE::instance ()->remove ();
      if (debug() > 0) {
        ACE_DEBUG ((LM_DEBUG, "ImR Locator: Service removed.\n"));
      }
      if (ret == 0) 
        return 1; // If successfull, then we don't want to continue.
    }

  return -1;

#else /* ACE_WIN32 */
  ACE_UNUSED_ARG (cmdline);
  ACE_ERROR ((LM_ERROR, "Service not supported on this platform"));

  return -1;
#endif /* ACE_WIN32 */
}

int 
Options::save_registry_options(const ACE_CString& cmdline) 
{
#if defined (ACE_WIN32)
  HKEY key = 0;
  // Create or open the parameters key
  LONG err = ACE_TEXT_RegCreateKeyEx (SERVICE_REG_ROOT,
                             SERVICE_REG_PATH,
                             0,
                             "", // class
                             REG_OPTION_NON_VOLATILE,
                             KEY_ALL_ACCESS,
                             NULL,
                             &key,
                             NULL
                             );
  if (err != ERROR_SUCCESS) {
    return -1;
  }
  err = ACE_TEXT_RegSetValueEx(key, "ORBInitOptions", 0, REG_SZ, 
    (LPBYTE) cmdline.c_str(), cmdline.length() + 1);
  ACE_ASSERT(err == ERROR_SUCCESS);

  err = ACE_TEXT_RegSetValueEx(key, "IORFile", 0, REG_SZ, 
    (LPBYTE) ior_output_file_.c_str(), ior_output_file_.length() + 1);
  ACE_ASSERT(err == ERROR_SUCCESS);

  err = ACE_TEXT_RegSetValueEx(key, "DebugLevel", 0, REG_DWORD, 
    (LPBYTE) &debug_ , sizeof(debug_));
  ACE_ASSERT(err == ERROR_SUCCESS);

  DWORD tmp = multicast_ ? 1 : 0;
  err = ACE_TEXT_RegSetValueEx(key, "Multicast", 0, REG_DWORD, 
    (LPBYTE) &tmp, sizeof(DWORD));
  ACE_ASSERT(err == ERROR_SUCCESS);

  err = ::RegCloseKey(key);
  ACE_ASSERT(err == ERROR_SUCCESS);
#else
  ACE_UNUSED_ARG (cmdline);
#endif
  return 0;
}

namespace {
  // This both parses the cmdline by replacing spaces with \0's, and
  // adds each command to the ACE_ARGV. 
  void parse_command_line(char* cmdline, ACE_ARGV& argv) {
    // This tokenizer will replace all spaces with end-of-string
    // characters and will preserve text between "" and '' pairs.
    ACE_Tokenizer parser (cmdline);
    parser.delimiter_replace (' ', '\0');
    parser.preserve_designators ('\"', '\"');
    parser.preserve_designators ('\'', '\'');

    for (char *p = parser.next (); p; p = parser.next ()) {
      argv.add(p);
    }
  }
}
/**
 *  We will only load from the registry if we are a service.
 *  We load each parameter from individual string keys, and then
 *  we have to parse the cmdline property into the orb_options
 *  so that they can be passed to ORB_init()
 */
int
Options::load_registry_options (char*& cmdline, ACE_ARGV& argv)
{
#if defined (ACE_WIN32)
  if (! this->service())
  {
    if (this->debug () > 1)
      ACE_DEBUG ((LM_DEBUG,
      "Locator_Options::load_registry_options: Not running "
      "as a service, will not load data from registry\n"));
    return 0;
  }

  HKEY key = 0;
  // Create or open the parameters key
  LONG err = ACE_TEXT_RegOpenKeyEx (SERVICE_REG_ROOT,
                             SERVICE_REG_PATH,
                             0,
                             KEY_READ,
                             &key
                             );
  if (err != ERROR_SUCCESS) {
    // If there aren't any saved parameters, then that's ok.
    return 0;
  }
  ACE_TCHAR tmpstr[4096];
  DWORD sz = sizeof(tmpstr);
  DWORD type = 0;
  err = ACE_TEXT_RegQueryValueEx(key, "ORBInitOptions", 0, &type, 
    (LPBYTE) tmpstr, &sz);
  if (err == ERROR_SUCCESS) {
    ACE_ASSERT(type == REG_SZ);
    cmdline = new char[sz+1];
    ACE_OS::strncpy(cmdline, tmpstr, sz);
    parse_command_line(cmdline, argv);
  }

  sz = sizeof(tmpstr);
  err = ACE_TEXT_RegQueryValueEx(key, "IORFile", 0, &type, 
    (LPBYTE) tmpstr, &sz);
  if (err == ERROR_SUCCESS) {
    ACE_ASSERT(type == REG_SZ);
    tmpstr[sz] = ACE_TCHAR('\0');
    this->ior_output_file_ = ACE_CString(tmpstr);
  }

  sz = sizeof(debug_);
  err = ACE_TEXT_RegQueryValueEx(key, "DebugLevel", 0, &type, 
    (LPBYTE) &debug_ , &sz);
  if (err == ERROR_SUCCESS) {
    ACE_ASSERT(type == REG_DWORD);
  }

  DWORD tmp = 0;
  err = ACE_TEXT_RegQueryValueEx(key, "Multicast", 0, &type, 
    (LPBYTE) &tmp, &sz);
  if (err == ERROR_SUCCESS) {
    ACE_ASSERT(type == REG_DWORD);
    this->multicast_ = tmp != 0;
  }

  err = ::RegCloseKey(key);
  ACE_ASSERT(err == ERROR_SUCCESS);

  return 0;
#else /* ACE_WIN32 */
  ACE_UNUSED_ARG (cmdline);
  ACE_UNUSED_ARG (argv);
  return 0;
#endif /* ACE_WIN32 */
}

/**
 * Standalone Mode
 *
 * @retval false Run as standalone service
 * @retval true Run as a service (only on NT right now)
 */
bool
Options::service (void) const
{
  return this->service_;
}


/**
 * Debug level for the IR.
 *
 * @retval 0 Quiet
 * @retval 1 Trace messages
 * @retval 2 Detailed messages
 */
unsigned int
Options::debug (void) const
{
  return this->debug_;
}


/**
 * @return The file where the IOR will be stored.
 */
ACE_CString
Options::output_filename (void) const
{
  return this->ior_output_file_;
}

/**
 * @return A pointer to the ORB.
 */
CORBA::ORB_ptr
Options::orb (void) const
{
  return CORBA::ORB::_duplicate (this->orb_.in ());
}

/**
 * @retval false Do not listen for multicast location requests.
 * @retval true Do Listen.
 */
bool
Options::multicast (void) const
{
  return this->multicast_;
}

#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
template class ACE_Singleton <Options, ACE_Null_Mutex>;
#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
#pragma instantiate ACE_Singleton <Options, ACE_Null_Mutex>
#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -