00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "Locator_Options.h"
00012 #include "ace/Arg_Shifter.h"
00013 #include "ace/Log_Msg.h"
00014 #include "ace/OS_NS_strings.h"
00015
00016 ACE_RCSID (ImplRepo_Service,
00017 Options,
00018 "Locator_Options.cpp,v 1.9 2006/01/04 16:10:11 giovannd Exp")
00019
00020
00021 #if defined (ACE_WIN32)
00022 static const HKEY SERVICE_REG_ROOT = HKEY_LOCAL_MACHINE;
00023
00024 static const ACE_TCHAR *SERVICE_REG_PATH =
00025 ACE_TEXT ("SYSTEM\\CurrentControlSet\\Services\\TAOImR\\Parameters");
00026 #endif
00027
00028 static const int DEFAULT_PING_INTERVAL = 10;
00029 static const int DEFAULT_START_TIMEOUT = 60;
00030
00031 Options::Options ()
00032 : repo_mode_ (REPO_NONE)
00033 , erase_repo_ (false)
00034 , debug_ (1)
00035 , multicast_ (false)
00036 , service_ (false)
00037 , ping_interval_(DEFAULT_PING_INTERVAL)
00038 , startup_timeout_(DEFAULT_START_TIMEOUT)
00039 , readonly_ (false)
00040 , service_command_(SC_NONE)
00041 {
00042 }
00043
00044 int
00045 Options::parse_args (int &argc, char *argv[])
00046 {
00047 ACE_Arg_Shifter shifter (argc, argv);
00048
00049 while (shifter.is_anything_left ())
00050 {
00051 if (ACE_OS::strcasecmp (shifter.get_current (),
00052 ACE_TEXT ("-c")) == 0)
00053 {
00054 shifter.consume_arg ();
00055
00056 if (!shifter.is_anything_left () || shifter.get_current ()[0] == '-')
00057 {
00058 ACE_ERROR ((LM_ERROR, "Error: -c option needs a command\n"));
00059 this->print_usage ();
00060 return -1;
00061 }
00062
00063 if (ACE_OS::strcasecmp (shifter.get_current (),
00064 ACE_TEXT ("install")) == 0)
00065 {
00066 this->service_command_ = SC_INSTALL;
00067 }
00068 else if (ACE_OS::strcasecmp (shifter.get_current (),
00069 ACE_TEXT ("remove")) == 0)
00070 {
00071 this->service_command_ = SC_REMOVE;
00072 }
00073 else
00074 {
00075 ACE_ERROR((LM_ERROR, "Error: Unknown service command : %s\n", shifter.get_current()));
00076 this->print_usage ();
00077 return -1;
00078 }
00079 }
00080 else if (ACE_OS::strcasecmp (shifter.get_current (),
00081 ACE_TEXT ("-d")) == 0)
00082 {
00083 shifter.consume_arg ();
00084
00085 if (!shifter.is_anything_left () || shifter.get_current ()[0] == '-')
00086 {
00087 ACE_ERROR ((LM_ERROR, "Error: -d option needs a debuglevel\n"));
00088 this->print_usage ();
00089 return -1;
00090 }
00091
00092 this->debug_ = ACE_OS::atoi (shifter.get_current ());
00093 }
00094 else if (ACE_OS::strcasecmp (shifter.get_current (),
00095 ACE_TEXT ("-m")) == 0)
00096 {
00097 this->multicast_ = true;
00098 }
00099 else if (ACE_OS::strcasecmp (shifter.get_current (),
00100 ACE_TEXT ("-o")) == 0)
00101 {
00102 shifter.consume_arg ();
00103
00104 if (!shifter.is_anything_left () || shifter.get_current ()[0] == '-')
00105 {
00106 ACE_ERROR ((LM_ERROR, "Error: -o option needs a filename\n"));
00107 this->print_usage ();
00108 return -1;
00109 }
00110 this->ior_output_file_ = shifter.get_current();
00111 }
00112 else if (ACE_OS::strcasecmp (shifter.get_current (),
00113 ACE_TEXT ("-s")) == 0)
00114 {
00115
00116 this->service_ = true;
00117 }
00118 else if ((ACE_OS::strcasecmp (shifter.get_current (),
00119 ACE_TEXT ("-?")) == 0)
00120 || (ACE_OS::strcasecmp (shifter.get_current (),
00121 ACE_TEXT ("-h")) == 0))
00122 {
00123 this->print_usage ();
00124 return 1;
00125 }
00126 else if (ACE_OS::strcasecmp (shifter.get_current (),
00127 ACE_TEXT ("-l")) == 0)
00128 {
00129 this->readonly_ = true;
00130 }
00131 else if (ACE_OS::strcasecmp (shifter.get_current (),
00132 ACE_TEXT ("-p")) == 0)
00133 {
00134 shifter.consume_arg ();
00135
00136 if (!shifter.is_anything_left () || shifter.get_current ()[0] == '-')
00137 {
00138 ACE_ERROR ((LM_ERROR, "Error: -p option needs a filename\n"));
00139 this->print_usage ();
00140 return -1;
00141 }
00142
00143 this->persist_file_name_ = shifter.get_current ();
00144 this->repo_mode_ = REPO_HEAP_FILE;
00145 }
00146 else if (ACE_OS::strcasecmp (shifter.get_current (),
00147 ACE_TEXT ("-r")) == 0)
00148 {
00149 this->repo_mode_ = REPO_REGISTRY;
00150 }
00151 else if (ACE_OS::strcasecmp (shifter.get_current (),
00152 ACE_TEXT ("-x")) == 0)
00153 {
00154 shifter.consume_arg ();
00155
00156 if (!shifter.is_anything_left () || shifter.get_current ()[0] == '-')
00157 {
00158 ACE_ERROR ((LM_ERROR, "Error: -x option needs a filename\n"));
00159 this->print_usage ();
00160 return -1;
00161 }
00162
00163 this->persist_file_name_ = shifter.get_current ();
00164 this->repo_mode_ = REPO_XML_FILE;
00165 }
00166 else if (ACE_OS::strcasecmp (shifter.get_current (),
00167 ACE_TEXT ("-e")) == 0)
00168 {
00169 this->erase_repo_ = true;
00170 }
00171 else if (ACE_OS::strcasecmp (shifter.get_current (),
00172 ACE_TEXT ("-t")) == 0)
00173 {
00174 shifter.consume_arg ();
00175
00176 if (!shifter.is_anything_left () || shifter.get_current ()[0] == '-')
00177 {
00178 ACE_ERROR ((LM_ERROR, "Error: -t option needs a value\n"));
00179 this->print_usage ();
00180 return -1;
00181 }
00182 this->startup_timeout_ =
00183 ACE_Time_Value (ACE_OS::atoi (shifter.get_current ()));
00184 }
00185 else if (ACE_OS::strcasecmp (shifter.get_current (),
00186 ACE_TEXT ("-v")) == 0)
00187 {
00188 shifter.consume_arg ();
00189
00190 if (!shifter.is_anything_left () || shifter.get_current ()[0] == '-')
00191 {
00192 ACE_ERROR ((LM_ERROR, "Error: -v option needs a value\n"));
00193 this->print_usage ();
00194 return -1;
00195 }
00196 this->ping_interval_ =
00197 ACE_Time_Value (0, 1000 * ACE_OS::atoi (shifter.get_current ()));
00198 }
00199 else
00200 {
00201 shifter.ignore_arg ();
00202 continue;
00203 }
00204
00205 shifter.consume_arg ();
00206 }
00207
00208 return 0;
00209 }
00210
00211 int
00212 Options::init (int argc, char *argv[])
00213 {
00214
00215
00216 int result = this->parse_args (argc, argv);
00217 if (result != 0)
00218 {
00219 return result;
00220 }
00221
00222 for (int i = 0; i < argc; ++i)
00223 {
00224 this->cmdline_ += ACE_CString (argv[i]) + ACE_CString (" ");
00225 }
00226 return 0;
00227 }
00228
00229 int
00230 Options::init_from_registry (void)
00231 {
00232 this->load_registry_options ();
00233 return 0;
00234 }
00235
00236
00237 void
00238 Options::print_usage (void) const
00239 {
00240 ACE_ERROR ((LM_ERROR,
00241 "Usage:\n"
00242 "\n"
00243 "ImR_Locator [-c cmd] [-d 0|1|2] [-m] [-o file]\n"
00244 " [-r|-p file|-x file] [-s] [-t secs] [-v secs]\n"
00245 " -c command Runs nt service commands ('install' or 'remove')\n"
00246 " -d level Sets the debug level (default 1)\n"
00247 " -l Lock the database\n"
00248 " -m Turn on multicast\n"
00249 " -o file Outputs the ImR's IOR to a file\n"
00250 " -p file Use file for storing/loading settings\n"
00251 " -x file Use XML file for storing/loading setting\n"
00252 " -r Use the registry for storing/loading settings\n"
00253 " -t secs Server startup timeout.(Default=60s)\n"
00254 " -v msecs Server verification interval.(Default=10s)\n"
00255 ));
00256 }
00257
00258 int
00259 Options::save_registry_options ()
00260 {
00261 #if defined (ACE_WIN32)
00262 HKEY key = 0;
00263
00264 LONG err = ACE_TEXT_RegCreateKeyEx (SERVICE_REG_ROOT,
00265 SERVICE_REG_PATH,
00266 0,
00267 "",
00268 REG_OPTION_NON_VOLATILE,
00269 KEY_ALL_ACCESS,
00270 NULL,
00271 &key,
00272 NULL
00273 );
00274 if (err != ERROR_SUCCESS)
00275 {
00276 return -1;
00277 }
00278 err = ACE_TEXT_RegSetValueEx (key, "ORBInitOptions", 0, REG_SZ,
00279 (LPBYTE) this->cmdline_.c_str (), this->cmdline_.length () + 1);
00280 ACE_ASSERT (err == ERROR_SUCCESS);
00281
00282 err = ACE_TEXT_RegSetValueEx (key, "IORFile", 0, REG_SZ,
00283 (LPBYTE) ior_output_file_.c_str (), ior_output_file_.length () + 1);
00284 ACE_ASSERT (err == ERROR_SUCCESS);
00285
00286 err = ACE_TEXT_RegSetValueEx (key, "DebugLevel", 0, REG_DWORD,
00287 (LPBYTE) &debug_ , sizeof (debug_));
00288 ACE_ASSERT(err == ERROR_SUCCESS);
00289
00290 err = ACE_TEXT_RegSetValueEx (key, "PersistFile", 0, REG_SZ,
00291 (LPBYTE) this->persist_file_name_.c_str (), this->persist_file_name_.length () + 1);
00292 ACE_ASSERT (err == ERROR_SUCCESS);
00293
00294 DWORD tmp = this->ping_interval_.msec ();
00295 err = ACE_TEXT_RegSetValueEx (key, "PingInterval", 0, REG_DWORD,
00296 (LPBYTE) &tmp, sizeof (DWORD));
00297 ACE_ASSERT (err == ERROR_SUCCESS);
00298
00299 tmp = this->readonly_ ? 1 : 0;
00300 err = ACE_TEXT_RegSetValueEx (key, "Lock", 0, REG_DWORD,
00301 (LPBYTE) &tmp, sizeof (DWORD));
00302 ACE_ASSERT (err == ERROR_SUCCESS);
00303
00304 tmp = this->repo_mode_;
00305 err = ACE_TEXT_RegSetValueEx (key, "PersistType", 0, REG_DWORD,
00306 (LPBYTE) &tmp, sizeof (DWORD));
00307 ACE_ASSERT (err == ERROR_SUCCESS);
00308
00309 tmp = this->startup_timeout_.sec();
00310 err = ACE_TEXT_RegSetValueEx (key, "Timeout", 0, REG_DWORD,
00311 (LPBYTE) &tmp, sizeof (DWORD));
00312 ACE_ASSERT (err == ERROR_SUCCESS);
00313
00314 tmp = multicast_ ? 1 : 0;
00315 err = ACE_TEXT_RegSetValueEx (key, "Multicast", 0, REG_DWORD,
00316 (LPBYTE) &tmp, sizeof (DWORD));
00317 ACE_ASSERT (err == ERROR_SUCCESS);
00318
00319 err = ::RegCloseKey (key);
00320 ACE_ASSERT (err == ERROR_SUCCESS);
00321 #endif
00322 return 0;
00323 }
00324
00325 int
00326 Options::load_registry_options ()
00327 {
00328 #if defined (ACE_WIN32)
00329 HKEY key = 0;
00330
00331 LONG err = ACE_TEXT_RegOpenKeyEx (SERVICE_REG_ROOT,
00332 SERVICE_REG_PATH,
00333 0,
00334 KEY_READ,
00335 &key
00336 );
00337 if (err != ERROR_SUCCESS)
00338 {
00339
00340 return 0;
00341 }
00342 ACE_TCHAR tmpstr[4096];
00343 DWORD sz = sizeof (tmpstr);
00344 DWORD type = 0;
00345 err = ACE_TEXT_RegQueryValueEx (key, "ORBInitOptions", 0, &type,
00346 (LPBYTE) tmpstr, &sz);
00347 if (err == ERROR_SUCCESS)
00348 {
00349 ACE_ASSERT (type == REG_SZ);
00350 tmpstr[sz - 1] = '\0';
00351 this->cmdline_ = tmpstr;
00352 }
00353
00354 sz = sizeof(tmpstr);
00355 err = ACE_TEXT_RegQueryValueEx (key, "IORFile", 0, &type,
00356 (LPBYTE) tmpstr, &sz);
00357 if (err == ERROR_SUCCESS)
00358 {
00359 ACE_ASSERT (type == REG_SZ);
00360 tmpstr[sz - 1] = '\0';
00361 this->ior_output_file_ = tmpstr;
00362 }
00363
00364 sz = sizeof(debug_);
00365 err = ACE_TEXT_RegQueryValueEx (key, "DebugLevel", 0, &type,
00366 (LPBYTE) &this->debug_ , &sz);
00367 if (err == ERROR_SUCCESS)
00368 {
00369 ACE_ASSERT (type == REG_DWORD);
00370 }
00371
00372 DWORD tmp = 0;
00373 sz = sizeof(tmp);
00374 err = ACE_TEXT_RegQueryValueEx (key, "PingInterval", 0, &type,
00375 (LPBYTE) &tmp, &sz);
00376 if (err == ERROR_SUCCESS)
00377 {
00378 ACE_ASSERT (type == REG_DWORD);
00379 ping_interval_.msec (tmp);
00380 }
00381
00382 tmp = 0;
00383 sz = sizeof(tmp);
00384 err = ACE_TEXT_RegQueryValueEx (key, "Lock", 0, &type,
00385 (LPBYTE) &tmp, &sz);
00386 if (err == ERROR_SUCCESS)
00387 {
00388 ACE_ASSERT (type == REG_DWORD);
00389 readonly_ = tmp != 0;
00390 }
00391
00392 sz = sizeof(this->repo_mode_);
00393 err = ACE_TEXT_RegQueryValueEx (key, "PersistType", 0, &type,
00394 (LPBYTE) &this->repo_mode_, &sz);
00395 if (err == ERROR_SUCCESS)
00396 {
00397 ACE_ASSERT (type == REG_DWORD);
00398 }
00399
00400 tmp = 0;
00401 sz = sizeof(tmp);
00402 err = ACE_TEXT_RegQueryValueEx (key, "Timeout", 0, &type,
00403 (LPBYTE) &tmp, &sz);
00404 if (err == ERROR_SUCCESS)
00405 {
00406 ACE_ASSERT (type == REG_DWORD);
00407 this->startup_timeout_.sec (tmp);
00408 }
00409
00410 tmp = 0;
00411 sz = sizeof(tmp);
00412 err = ACE_TEXT_RegQueryValueEx (key, "Multicast", 0, &type,
00413 (LPBYTE) &tmp, &sz);
00414 if (err == ERROR_SUCCESS)
00415 {
00416 ACE_ASSERT (type == REG_DWORD);
00417 this->multicast_ = tmp != 0;
00418 }
00419
00420 sz = sizeof(tmpstr);
00421 err = ACE_TEXT_RegQueryValueEx (key, "PersistFile", 0, &type,
00422 (LPBYTE) tmpstr, &sz);
00423 if (err == ERROR_SUCCESS)
00424 {
00425 ACE_ASSERT (type == REG_SZ);
00426 tmpstr[sz - 1] = '\0';
00427 this->persist_file_name_ = tmpstr;
00428 }
00429
00430 err = ::RegCloseKey (key);
00431 ACE_ASSERT (err == ERROR_SUCCESS);
00432 #endif
00433 return 0;
00434 }
00435
00436 bool
00437 Options::service (void) const
00438 {
00439 return this->service_;
00440 }
00441
00442 unsigned int
00443 Options::debug (void) const
00444 {
00445 return this->debug_;
00446 }
00447
00448 const ACE_CString&
00449 Options::ior_filename (void) const
00450 {
00451 return this->ior_output_file_;
00452 }
00453
00454 bool
00455 Options::multicast (void) const
00456 {
00457 return this->multicast_;
00458 }
00459
00460 Options::SERVICE_COMMAND
00461 Options::service_command(void) const
00462 {
00463 return this->service_command_;
00464 }
00465
00466 const char*
00467 Options::cmdline(void) const {
00468 return this->cmdline_.c_str ();
00469 }
00470
00471 const ACE_CString&
00472 Options::persist_file_name(void) const {
00473 return this->persist_file_name_;
00474 }
00475
00476 ACE_Time_Value
00477 Options::startup_timeout (void) const
00478 {
00479 return this->startup_timeout_;
00480 }
00481
00482 ACE_Time_Value
00483 Options::ping_interval (void) const
00484 {
00485 return this->ping_interval_;
00486 }
00487
00488 Options::RepoMode
00489 Options::repository_mode (void) const
00490 {
00491 return this->repo_mode_;
00492 }
00493
00494 bool
00495 Options::repository_erase (void) const
00496 {
00497 return this->erase_repo_;
00498 }
00499
00500 bool
00501 Options::readonly (void) const
00502 {
00503 return this->readonly_;
00504 }
00505