(file) Return to cimserver_windows.cpp CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Server

  1 mike  1.7 //%/////////////////////////////////////////////////////////////////////////////
  2           //
  3 kumpf 1.16 // Copyright (c) 2000, 2001, 2002 BMC Software, Hewlett-Packard Company, IBM,
  4            // The Open Group, Tivoli Systems
  5 mike  1.7  //
  6            // Permission is hereby granted, free of charge, to any person obtaining a copy
  7 kumpf 1.16 // of this software and associated documentation files (the "Software"), to
  8            // deal in the Software without restriction, including without limitation the
  9            // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 10 mike  1.7  // sell copies of the Software, and to permit persons to whom the Software is
 11            // furnished to do so, subject to the following conditions:
 12            // 
 13 kumpf 1.16 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
 14 mike  1.7  // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
 15            // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
 16 kumpf 1.16 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 17            // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 18            // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 19 mike  1.7  // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 20            // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 21            //
 22            //==============================================================================
 23            //
 24            // Author: Mike Day (mdday@us.ibm.com)
 25            //
 26 mary  1.11 // Modified By: Mary Hinton (m.hinton@verizon.net)
 27 kumpf 1.12 //              Sushma Fernandes (sushma_fernandes@hp.com)
 28 tony  1.22 //              Yi Zhou, Hewlett-Packard Company (yi_zhou@hp.com)
 29            //              Tony Fiorentino (fiorentino_tony@emc.com)
 30 kumpf 1.23 //              Roger Kumpf, Hewlett-Packard Company (roger_kumpf@hp.com)
 31 s.hills 1.33 //              Steve Hills (steve.hills@ncr.com)
 32 mike    1.7  //
 33              //%/////////////////////////////////////////////////////////////////////////////
 34              
 35              #include <windows.h>
 36              #include <process.h>    /* _beginthread, _endthread */
 37              #include <tchar.h>
 38              #include <direct.h>
 39 humberto 1.30 #include <Pegasus/Common/MessageLoader.h> //l10n
 40 chuck    1.31 #include <Pegasus/Common/Thread.h>  // l10n
 41 mike     1.7  
 42 tony     1.22 #include "service.cpp"
 43 mike     1.7  
 44               PEGASUS_USING_PEGASUS;
 45               PEGASUS_USING_STD;
 46               
 47 tony     1.22 //-------------------------------------------------------------------------
 48               // DEFINES
 49               //-------------------------------------------------------------------------
 50               #define PEGASUS_SERVICE_NAME "cimserver"
 51               #define PEGASUS_DISPLAY_NAME "Pegasus CIM Object Manager"
 52               #define PEGASUS_DESCRIPTION  "Pegasus CIM Object Manager Service"
 53               
 54               //-------------------------------------------------------------------------
 55               // GLOBALS
 56               //-------------------------------------------------------------------------
 57 s.hills  1.33 static Mutex _cimserverLock;
 58               static CIMServer* _cimserver = 0;
 59               static bool _shutdown = false;
 60 tony     1.22 static Service pegasus_service(PEGASUS_SERVICE_NAME);
 61 s.hills  1.33 static HANDLE pegasus_service_event = NULL;
 62 tony     1.26 static LPCSTR g_cimservice_key  = TEXT("SYSTEM\\CurrentControlSet\\Services\\%s");
 63 tony     1.22 static LPCSTR g_cimservice_home = TEXT("home");
 64               
 65 s.hills  1.33 //  Constants representing the command line options.
 66               static const char OPTION_INSTALL[] = "install";
 67               static const char OPTION_REMOVE[]  = "remove";
 68               static const char OPTION_START[]   = "start";
 69               static const char OPTION_STOP[]    = "stop";
 70               
 71 tony     1.22 //-------------------------------------------------------------------------
 72               // PROTOTYPES
 73               //-------------------------------------------------------------------------
 74               int cimserver_windows_main(int flag, int argc, char **argv);
 75               static bool _getRegInfo(const char *lpchKeyword, char *lpchRetValue);
 76               static bool _setRegInfo(const char *lpchKeyword, const char *lpchValue);
 77               void setHome(String & home);
 78               
 79               //-------------------------------------------------------------------------
 80               // NO-OPs for windows platform
 81               //-------------------------------------------------------------------------
 82               int cimserver_fork(void) { return(0); }
 83               int cimserver_kill(void) { return(0); }
 84 s.hills  1.33 void notify_parent(int id) { return; }
 85 tony     1.22 
 86 chuck    1.31 //-------------------------------------------------------------------------
 87 s.hills  1.33 // Helper for platform specific handling
 88               //-------------------------------------------------------------------------
 89               
 90               void cimserver_set( CIMServer* s )
 91               {
 92               	auto_mutex am( &_cimserverLock );
 93               	_cimserver = s;
 94               	if( _cimserver && _shutdown )
 95               		_cimserver->shutdownSignal();
 96               }
 97 tony     1.22 
 98 s.hills  1.33 void signal_shutdown()
 99               {
100               	auto_mutex am( &_cimserverLock );
101               	_shutdown = true;
102               	if( _cimserver )
103               		_cimserver->shutdownSignal();
104 tony     1.22 }
105 mary     1.13 
106 s.hills  1.33 //-------------------------------------------------------------------------
107               // Run main server asynchronously
108               //-------------------------------------------------------------------------
109               static unsigned __stdcall cimserver_windows_thread( void* parm )
110               {
111               	int argc = 0;
112               	int rc = cimserver_run( argc, 0, false );
113               	SetEvent(pegasus_service_event);
114               	_endthreadex( rc );
115               	return rc;
116               }
117 mike     1.7  
118 tony     1.22 //-------------------------------------------------------------------------
119               //  Windows NT Service Control Code 
120               //-------------------------------------------------------------------------
121 kumpf    1.14 
122 tony     1.22 //-------------------------------------------------------------------------
123 s.hills  1.33 // START/STOP handler 
124 tony     1.22 //-------------------------------------------------------------------------
125 s.hills  1.33 int cimserver_windows_main(int flag, int argc, char *argv[])
126 tony     1.22 {
127 s.hills  1.33 	switch( flag )
128               	{
129               	case Service::STARTUP_FLAG:
130               	{
131               		//
132               		// Start up main run in a separate thread and wait for it to finish.
133               		//
134               
135               		unsigned threadid = 0;
136               		HANDLE hThread = (HANDLE)_beginthreadex( NULL, 0, cimserver_windows_thread, NULL, 0, &threadid );
137               		if( hThread == NULL )
138               			return 1;
139               
140               		WaitForSingleObject( pegasus_service_event, INFINITE );
141               
142               		//
143               		// Shutdown the cimserver.
144               		//
145               
146               		signal_shutdown();
147               
148 s.hills  1.33 		//
149               		// Make sure we upate the SCM that our stop is pending.
150               		// Wait for the main run thread to exit.
151               		//
152               
153               		DWORD dwCheckPoint = 1; // service code should have already started at 0
154 mike     1.7  
155 s.hills  1.33 		while( WaitForSingleObject( hThread, 3000 ) == WAIT_TIMEOUT )
156               		{
157               			pegasus_service.report_status( 
158               				SERVICE_STOP_PENDING, NO_ERROR, dwCheckPoint++, 5000 );
159               		}
160 mike     1.7  
161 s.hills  1.33 		CloseHandle( hThread );
162 mike     1.8  
163 s.hills  1.33 		break;
164               	}
165               	case Service::SHUTDOWN_FLAG:
166               		SetEvent(pegasus_service_event);
167               		break;
168 mike     1.8  
169 s.hills  1.33 	default:
170               		break;
171               	}
172 mike     1.7  
173 s.hills  1.33 	return 0;
174 mike     1.7  }
175               
176 tony     1.22 //-------------------------------------------------------------------------
177 s.hills  1.33 // IS RUNNING?
178 tony     1.22 //-------------------------------------------------------------------------
179 s.hills  1.33 
180               static const char* _ALREADY_RUNNING_NAME = "PegasusCIMServer";
181               
182               class AlreadyRunning
183 tony     1.22 {
184 s.hills  1.33 public:
185               	AlreadyRunning(): alreadyRunning( true ), event( NULL )
186               	{
187               	}
188               	~AlreadyRunning()
189               	{
190               		if( event != NULL )
191               			CloseHandle( event );
192               	}
193               
194               	void Init()
195               	{
196               		if( event == NULL )
197               		{
198               			event = CreateEvent( NULL, TRUE, TRUE, _ALREADY_RUNNING_NAME );
199               			if( event != NULL && GetLastError() != ERROR_ALREADY_EXISTS )
200               				alreadyRunning = false;
201               		}
202               	}
203               
204               	bool IsAlreadyRunning()
205 s.hills  1.33 	{
206               		return alreadyRunning;
207               	}
208               
209               	bool alreadyRunning;
210               	HANDLE event;
211               };
212               
213               AlreadyRunning _alreadyRunning;
214 mike     1.7  
215               
216 tony     1.22 Boolean isCIMServerRunning(void)
217               {
218 s.hills  1.33 	//Service::State state;
219               	//pegasus_service.GetState(&state);
220               	//return (state == Service::SERVICE_STATE_RUNNING) ? true : false;
221               
222               	// We do it this way so this will work when run as a 
223               	// console process and a Windows service.
224               	AlreadyRunning ar;
225               	ar.Init();
226               	return ar.IsAlreadyRunning();
227 tony     1.22 }
228 mike     1.7  
229 tony     1.22 //-------------------------------------------------------------------------
230               // INSTALL
231               //-------------------------------------------------------------------------
232 tony     1.26 bool cimserver_install_nt_service(char *service_name)
233 mike     1.7  {
234 tony     1.22   Service::ReturnCode status = Service::SERVICE_RETURN_SUCCESS;
235 tony     1.26   char filename[_MAX_PATH] = {0};
236                 char displayname[_MAX_PATH] = {0};
237               
238                 // If service name is specified, override default
239                 if (service_name == NULL)
240                   {
241                     strcpy(displayname, PEGASUS_DISPLAY_NAME);
242                   }
243                 else
244                   {
245                     pegasus_service.SetServiceName(service_name);
246                     sprintf(displayname, "%s - %s", PEGASUS_DISPLAY_NAME, service_name);
247                   }
248 tony     1.22 
249                 GetModuleFileName(NULL, filename, sizeof(filename));
250 tony     1.26   status = pegasus_service.Install(displayname, PEGASUS_DESCRIPTION, filename);
251 mike     1.7  
252 tony     1.22   // Upon success, set home in registry
253                 if (status == Service::SERVICE_RETURN_SUCCESS)
254 mike     1.7      {
255 tony     1.22       char pegasus_homepath[_MAX_PATH];
256                     System::extract_file_path(filename, pegasus_homepath);
257                     pegasus_homepath[strlen(pegasus_homepath)-1] = '\0';
258                     strcpy(filename, pegasus_homepath);
259                     System::extract_file_path(filename, pegasus_homepath);
260                     pegasus_homepath[strlen(pegasus_homepath)-1] = '\0';
261                     _setRegInfo(g_cimservice_home, pegasus_homepath);
262 mike     1.7      }
263 tony     1.22 
264                 return (status == Service::SERVICE_RETURN_SUCCESS) ? true : false;
265               }
266               
267               //-------------------------------------------------------------------------
268               // REMOVE
269               //-------------------------------------------------------------------------
270 tony     1.26 bool cimserver_remove_nt_service(char *service_name) 
271 tony     1.22 {
272                 Service::ReturnCode status = Service::SERVICE_RETURN_SUCCESS;
273               
274 tony     1.26   // If service name is specified, override default
275                 if (service_name != NULL)
276                   {
277                     pegasus_service.SetServiceName(service_name);
278                   }
279               
280 tony     1.22   status = pegasus_service.Remove();
281               
282                 return (status == Service::SERVICE_RETURN_SUCCESS) ? true : false;
283 mike     1.7  }
284               
285 tony     1.22 //-------------------------------------------------------------------------
286               // START
287               //-------------------------------------------------------------------------
288 tony     1.26 bool cimserver_start_nt_service(char *service_name) 
289 tony     1.22 {
290                 Service::ReturnCode status = Service::SERVICE_RETURN_SUCCESS;
291               
292 tony     1.26   // If service name is specified, override default
293                 if (service_name != NULL)
294                   {
295                     pegasus_service.SetServiceName(service_name);
296                   }
297               
298 tony     1.22   status = pegasus_service.Start(5);
299               
300                 return (status == Service::SERVICE_RETURN_SUCCESS) ? true : false;
301               }
302 mike     1.7  
303 tony     1.22 //-------------------------------------------------------------------------
304               // STOP
305               //-------------------------------------------------------------------------
306 tony     1.26 bool cimserver_stop_nt_service(char *service_name) 
307 mike     1.7  {
308 tony     1.22   Service::ReturnCode status = Service::SERVICE_RETURN_SUCCESS;
309 mike     1.7  
310 tony     1.26   // If service name is specified, override default
311                 if (service_name != NULL)
312                   {
313                     pegasus_service.SetServiceName(service_name);
314                   }
315               
316 tony     1.22   status = pegasus_service.Stop(5);
317               
318                 return (status == Service::SERVICE_RETURN_SUCCESS) ? true : false;
319               }
320 mike     1.7  
321 tony     1.22 //-------------------------------------------------------------------------
322               // HELPER Utilities
323               //-------------------------------------------------------------------------
324               static bool _getRegInfo(const char *lpchKeyword, char *lpchRetValue)
325               {
326                 HKEY   hKey;
327                 DWORD  dw                   = _MAX_PATH;
328 tony     1.26   char   subKey[_MAX_PATH]    = {0};
329                 
330                 sprintf(subKey, g_cimservice_key, pegasus_service.GetServiceName());
331 mike     1.7  
332 tony     1.22   if ((RegOpenKeyEx(HKEY_LOCAL_MACHINE,
333 tony     1.26                     subKey, 
334 tony     1.22                     0,
335                                   KEY_READ, 
336                                   &hKey)) != ERROR_SUCCESS)
337 mike     1.7      {
338 tony     1.22       return false;
339 mike     1.7      }
340               
341 tony     1.22   if ((RegQueryValueEx(hKey, 
342                                      lpchKeyword, 
343                                      NULL, 
344                                      NULL, 
345                                      (LPBYTE)lpchRetValue,
346                                      &dw)) != ERROR_SUCCESS)
347 mike     1.7      {
348 tony     1.22       RegCloseKey(hKey);
349                     return false;
350 mike     1.7      }
351               
352 tony     1.22   RegCloseKey(hKey);
353               
354                 return true;
355 mike     1.7  }
356               
357 tony     1.22 static bool _setRegInfo(const char *lpchKeyword, const char *lpchValue)
358 mike     1.7  {
359 tony     1.22   HKEY   hKey;
360                 DWORD  dw                   = _MAX_PATH;
361                 char   home_key[_MAX_PATH]  = {0};
362 tony     1.26   char   subKey[_MAX_PATH]    = {0};
363 tony     1.22 
364                 if (lpchKeyword == NULL || lpchValue == NULL)
365                   return false;
366               
367 tony     1.26   sprintf(subKey, g_cimservice_key, pegasus_service.GetServiceName());
368               
369                 if ((RegCreateKeyEx (HKEY_LOCAL_MACHINE,
370                                     subKey,
371 tony     1.22                       0,
372                                     NULL,
373                                     0,
374                                     KEY_ALL_ACCESS,
375                                     NULL,
376                                     &hKey,
377                                     NULL) != ERROR_SUCCESS))
378                   {
379                     return false;
380                   }
381               
382                 if ((RegSetValueEx(hKey, 
383                                    lpchKeyword, 
384                                    0, 
385                                    REG_SZ, 
386                                    (CONST BYTE *)lpchValue,
387                                    (DWORD)(strlen(lpchValue)+1))) != ERROR_SUCCESS)
388               	{
389               	  RegCloseKey(hKey);
390               	  return false;
391               	}
392 mike     1.7  
393 tony     1.22   RegCloseKey(hKey);
394               
395                 return true;
396 mike     1.7  }
397               
398 tony     1.22 void setHome(String & home)
399 mike     1.7  {
400 tony     1.22   // Determine the absolute path to the running program
401 tony     1.27   char exe_pathname[_MAX_PATH] = {0};
402                 char home_pathname[_MAX_PATH] = {0};
403 tony     1.22   GetModuleFileName(NULL, exe_pathname, sizeof(exe_pathname));
404               
405                 // Pegasus home search rules:
406                 // - look in registry (if set)
407                 // - if not found, look in PEGASUS_HOME (if set)
408                 // - if not found, use exe directory minus one level
409               
410 tony     1.27   bool found_reg = _getRegInfo("home", home_pathname);
411                 if (found_reg == true)
412 tony     1.22     {
413 tony     1.27       // Make sure home matches
414                     String current_home(home_pathname);
415                     String current_exe(exe_pathname);
416                     current_home.toLower();
417                     current_exe.toLower();
418               
419                     Uint32 pos = current_exe.find(current_home);
420                     if (pos != PEG_NOT_FOUND)
421                       {
422                         home = home_pathname;
423                       }
424                     else
425                       {
426                         found_reg = false;
427                       }
428 tony     1.22     }
429 tony     1.27   if (found_reg == false)
430 tony     1.22     {
431                     const char* tmp = getenv("PEGASUS_HOME");
432                     if (tmp)
433                       {
434                         home = tmp;
435                       }
436                     else
437                       {
438                         // ASSUMPTION: At a minimum, the cimserver program is running
439                         // from a "bin" directory
440                         home = FileSystem::extractFilePath(exe_pathname);
441                         home.remove(home.size()-1, 1);
442                         home = FileSystem::extractFilePath(home);
443                         home.remove(home.size()-1, 1);
444                       }
445 mike     1.7      }
446               }
447               
448 s.hills  1.33 //
449               // Our console control handler
450               //
451               
452               static BOOL WINAPI ControlHandler( DWORD dwCtrlType )
453               {
454               	switch( dwCtrlType )
455               	{
456               	case CTRL_BREAK_EVENT:  // use Ctrl+C or Ctrl+Break to simulate
457               	case CTRL_C_EVENT:      // SERVICE_CONTROL_STOP in debug mode
458               	{
459               		signal_shutdown();
460               		return TRUE;
461               	}
462               	}
463               	return FALSE;
464               }
465               
466               //
467               // Platform specific run
468               //
469 mike     1.7  
470 s.hills  1.33 int platform_run( int argc, char** argv, Boolean shutdownOption )
471               {
472               	//
473               	// Check for my command line options
474               	//
475 tony     1.22 
476 s.hills  1.33 	for( int i = 1; i < argc; )
477               	{
478               		const char* arg = argv[i];
479               
480               		// Check for -option
481               		if (*arg == '-')
482               		{
483               			// Get the option
484               			const char* option = arg + 1;
485               
486               			if (strcmp(option, OPTION_INSTALL) == 0)
487               			{
488               				//
489               				// Install as a NT service
490               				//
491               				char *opt_arg = NULL;
492               				if (i+1 < argc)
493               				{
494               					opt_arg = argv[i+1];
495               
496               				}
497 s.hills  1.33 				if(cimserver_install_nt_service(opt_arg))
498               				{
499               					//l10n
500               					//cout << "\nPegasus installed as NT Service";
501               					MessageLoaderParms parms(
502               						"src.Server.cimserver.INSTALLED_NT_SERVICE",
503               						"\nPegasus installed as NT Service");
504               					cout << MessageLoader::getMessage(parms) << endl;
505               					exit(0);
506               				}
507               				else
508               				{
509               					exit(0);
510               				}
511               			}
512               			else if (strcmp(option, OPTION_REMOVE) == 0)
513               			{
514               				//
515               				// Remove Pegasus as an NT service
516               				//
517               				char *opt_arg = NULL;
518 s.hills  1.33 				if (i+1 < argc)
519               				{
520               					opt_arg = argv[i+1];                    
521               				}
522               				if(cimserver_remove_nt_service(opt_arg))
523               				{
524               					//l10n
525               					//cout << "\nPegasus removed as NT Service";
526               					MessageLoaderParms parms(
527               						"src.Server.cimserver.REMOVED_NT_SERVICE",
528               						"\nPegasus removed as NT Service");
529               					cout << MessageLoader::getMessage(parms) << endl;
530               					exit(0);
531               				}
532               				else
533               				{
534               					exit(0);
535               				}
536               
537               			}
538               			else if (strcmp(option, OPTION_START) == 0)
539 s.hills  1.33 			{
540               				//
541               				// Start as a NT service
542               				//
543               				char *opt_arg = NULL;
544               				if (i+1 < argc)
545               				{
546               					opt_arg = argv[i+1];                    
547               				}
548               				if(cimserver_start_nt_service(opt_arg))
549               				{
550               					//l10n
551               					//cout << "\nPegasus started as NT Service";
552               					MessageLoaderParms parms(
553               						"src.Server.cimserver.STARTED_NT_SERVICE",
554               						"\nPegasus started as NT Service");
555               					cout << MessageLoader::getMessage(parms) << endl;
556               					exit(0);
557               				}
558               				else
559               				{
560 s.hills  1.33 					exit(0);
561               				}
562               			}
563               			else if (strcmp(option, OPTION_STOP) == 0)
564               			{
565               				//
566               				// Stop as a NT service
567               				//
568               				char *opt_arg = NULL;
569               				if (i+1 < argc)
570               				{
571               					opt_arg = argv[i+1];                    
572               				}
573               				if(cimserver_stop_nt_service(opt_arg))
574               				{
575               					//l10n
576               					//cout << "\nPegasus stopped as NT Service";
577               					MessageLoaderParms parms(
578               						"src.Server.cimserver.STOPPED_NT_SERVICE",
579               						"\nPegasus stopped as NT Service");
580               					cout << MessageLoader::getMessage(parms) << endl;
581 s.hills  1.33 					exit(0);
582               				}
583               				else
584               				{
585               					exit(0);
586               				}
587               			}
588               			else
589               				i++;
590               		}
591               		else
592               			i++;
593               	}
594               
595               	//
596               	// Signal ourself as running
597               	//
598               
599               	if( !shutdownOption )
600               		_alreadyRunning.Init();
601               
602 s.hills  1.33 	//
603               	// Check if already running
604               	//
605               	// Hmm, when starting as a service, should we do this here (before
606               	// starting the control dispatcher)?  If we do then the SCM reports
607               	// a dumb message to the user.  If we don't, and it in the serviceProc 
608               	// then the service will start up then die silently.
609               	//
610               
611               	if( !shutdownOption && _alreadyRunning.IsAlreadyRunning() )
612               	{
613               		MessageLoaderParms parms(
614               			"src.Server.cimserver.UNABLE_TO_START_SERVER_ALREADY_RUNNING",
615               			"Unable to start CIMServer.\nCIMServer is already running." );
616               		Logger::put(
617               			Logger::ERROR_LOG, "CIMServer", Logger::SEVERE,
618               			MessageLoader::getMessage(parms) );
619               		PEGASUS_STD(cerr) << MessageLoader::getMessage(parms) << PEGASUS_STD(endl);
620               		return 1;
621               	}
622               
623 s.hills  1.33 	//
624               	// Check if running from a console window. If so then just run
625               	// as a console process.
626               	//
627               
628               	char console_title[ _MAX_PATH ] = {0};
629               	if( GetConsoleTitle( console_title, _MAX_PATH ) > 0 )
630               	{
631               		SetConsoleCtrlHandler( ControlHandler, TRUE );
632               
633               		return cimserver_run( argc, argv, shutdownOption );
634               	}
635               
636               	//
637               	// Run as a service
638               	//
639               
640               	pegasus_service_event = CreateEvent( NULL, FALSE, FALSE, NULL );
641               
642               	Service::ReturnCode status;
643               	status = pegasus_service.Run( cimserver_windows_main );
644 s.hills  1.33 
645               	if( status != Service::SERVICE_RETURN_SUCCESS )
646               	{
647               		// todo: put into localized messages when messages unfreezes.
648               		Logger::put_l(
649               			Logger::ERROR_LOG, "CIMServer", Logger::SEVERE,
650               			"src.Server.cimserver_windows.LISTENING_ON_HTTP_PORT",
651               			"Error during service run: code = $0.", status );
652               		return 1;
653               	}
654               
655               	return 0;
656               }

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2