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

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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2