1 //%2005////////////////////////////////////////////////////////////////////////
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.
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:
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 // 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.
28 //==============================================================================
30 // Author: Mike Brasher (mbrasher@bmc.com)
32 // Modified By: Mike Day (mdday@us.ibm.com)
33 // Karl Schopmeyer (k.schopmeyer@opengroup.org)
34 // Nag Boranna (nagaraja_boranna@hp.com)
35 // Jenny Yu (jenny_yu@hp.com)
36 // Sushma Fernandes (sushma_fernandes@hp.com)
37 // Carol Ann Krug Graves, Hewlett-Packard Company
38 // (carolann_graves@hp.com)
39 // Yi Zhou, Hewlett-Packard Company (yi_zhou@hp.com)
40 // Dave Rosckes (rosckes@us.ibm.com)
41 // Humberto Rivero (hurivero@us.ibm.com)
42 // Steve Hills (steve.hills@ncr.com)
43 // Amit K Arora, IBM (amitarora@in.ibm.com) - pep 167
44 // Josephine Eskaline Joyce, IBM (jojustin@in.ibm.com) - Bug#2555
45 // Josephine Eskaline Joyce, IBM (jojustin@in.ibm.com) - Bug#2032
46 // Heather Sterling, IBM (hsterl@us.ibm.com) - PEP#197 CIMListener,
47 // PEP#222 Service Refactoring
48 // Amit K Arora, IBM (amita@in.ibm.com) Bug#3028
49 // David Dillard, VERITAS Software Corp.
50 // (david.dillard@veritas.com)
52 //%/////////////////////////////////////////////////////////////////////////////
55 //////////////////////////////////////////////////////////////////////
57 // Notes on deamon operation (Unix) and service operation (Win 32):
59 // To run pegasus listener as a daemon on Unix platforms:
63 // To NOT run pegasus listener as a daemon on Unix platforms:
65 // cimlistener --nodaemon
67 // The daemon setting has no effect on windows operation.
69 // To shutdown pegasus listener, use the -s option:
73 // To run pegasus listener as an NT service, there are FOUR different possibilities:
75 // To INSTALL the Pegasus service,
77 // cimlistener -install
79 // To REMOVE the Pegasus service,
81 // cimlistener -remove
83 // To START the Pegasus service,
85 // net start cimlistener
89 // To STOP the Pegasus service,
91 // net stop cimlistener
95 // Alternatively, you can use the windows service manager. Pegasus listener shows up
96 // in the service database as "Pegasus CIM Listener"
98 // Mike Day, mdday@us.ibm.com
100 //////////////////////////////////////////////////////////////////////
103 #include <Pegasus/Common/Config.h>
104 #include <Pegasus/Common/Constants.h>
105 #include <Pegasus/Common/PegasusAssert.h>
107 #include <Pegasus/Common/FileSystem.h>
108 #include <Pegasus/Common/Logger.h>
109 #include <Pegasus/Common/System.h>
110 #include <Pegasus/Common/Tracer.h>
111 #include <Pegasus/Common/Thread.h>
112 #include <Pegasus/Common/LanguageParser.h>
113 #include <Pegasus/Common/PegasusVersion.h>
114 #include <Pegasus/DynListener/DynamicListener.h>
115 #include <Pegasus/DynListener/DynamicListenerConfig.h>
116 #include <Service/ServerProcess.h>
118 PEGASUS_USING_PEGASUS;
121 #define PEGASUS_LISTENER_PROCESS_NAME "cimlistener";
123 //Windows service variables are not defined elsewhere in the product
124 //enable ability to override these
125 #ifndef PEGASUS_LISTENER_PRODUCT_NAME
126 #define PEGASUS_LISTENER_PRODUCT_NAME "CIM Listener"
128 #ifndef PEGASUS_LISTENER_SERVICE_NAME
129 #define PEGASUS_LISTENER_SERVICE_NAME "Pegasus CIM Listener"
131 #ifndef PEGASUS_LISTENER_SERVICE_DESCRIPTION
132 #define PEGASUS_LISTENER_SERVICE_DESCRIPTION "Pegasus CIM Listener Service"
135 //The start file is created as soon the child forks and notifies the parent.
136 //This file is used to detect whether the cimserver is running and thus,
137 //it must exist until right before the child process exits.
138 #ifndef LISTENER_START_FILE
139 #define LISTENER_START_FILE "/tmp/cimlistener_start.conf"
141 //The stop file is created to signal the cimserver to shutdown.
142 //We cannot use the earlier file and delete it to "signal shutdown"
143 //because then another cimserver process could be started while we
144 //were still shutting down. This is a workaround for the fact that
145 //signals are not implemented on all platforms. Theoretically,
146 //we should be blocking until the calling process signalled the child
148 #ifndef LISTENER_STOP_FILE
149 #define LISTENER_STOP_FILE "/tmp/cimlistener_stop.conf"
152 class CIMListenerProcess : public ServerProcess
156 CIMListenerProcess(void)
158 cimserver_set_process(this);
161 virtual ~CIMListenerProcess(void)
165 virtual const char* getProductName() const
167 return PEGASUS_LISTENER_PRODUCT_NAME;
170 virtual const char* getExtendedName() const
172 return PEGASUS_LISTENER_SERVICE_NAME;
175 virtual const char* getDescription() const
177 return PEGASUS_LISTENER_SERVICE_DESCRIPTION;
180 //defined in PegasusVersion.h
181 virtual const char* getVersion() const
183 return PEGASUS_PRODUCT_VERSION;
186 virtual const char* getProcessName() const
188 return PEGASUS_LISTENER_PROCESS_NAME;
191 virtual const char* getPIDFileName() const
193 return LISTENER_START_FILE;
196 int cimserver_run(int argc, char** argv, bool shutdownOption);
198 void cimserver_stop(void);
201 AutoPtr<CIMListenerProcess> _cimListenerProcess(new CIMListenerProcess());
202 AutoPtr<DynamicListenerConfig> configManager(DynamicListenerConfig::getInstance());
203 static DynamicListener* _cimListener = 0;
209 static const char COMMAND_NAME [] = "cimlistener";
212 // The constant defining usage string.
214 static const char USAGE [] = "Usage: ";
217 Constants representing the command line options.
219 static const char OPTION_VERSION = 'v';
221 static const char OPTION_HELP = 'h';
223 static const char OPTION_HOME = 'D';
225 static const char OPTION_SHUTDOWN = 's';
227 static const char OPTION_NO_DAEMON [] = "--nodaemon";
229 static const char LONG_HELP [] = "help";
231 static const char LONG_VERSION [] = "version";
233 #if defined(PEGASUS_OS_HPUX)
234 static const char OPTION_BINDVERBOSE = 'X';
237 static const String PROPERTY_TIMEOUT = "shutdownTimeout";
239 static const String DEFAULT_CONFIG_FILE = "cimlistener.conf";
242 /* PrintHelp - This is temporary until we expand the options manager to allow
243 options help to be defined with the OptionRow entries and presented from
246 void PrintHelp(const char* arg0)
248 String usage = String (USAGE);
249 usage.append (COMMAND_NAME);
250 usage.append (" [ [ options ] ]\n");
251 usage.append (" options\n");
252 usage.append (" -v, --version - displays CIM Listener version number\n");
253 usage.append (" -h, --help - prints this help message\n");
254 usage.append (" -s - shuts down CIM Listener\n");
255 usage.append (" -D [home] - sets pegasus home directory\n");
256 #if defined(PEGASUS_OS_TYPE_WINDOWS)
257 usage.append (" -install [name] - installs pegasus as a Windows Service\n");
258 usage.append (" [name] is optional and overrides the\n");
259 usage.append (" default CIM Listener Service Name\n");
260 usage.append (" -remove [name] - removes pegasus as a Windows Service\n");
261 usage.append (" [name] is optional and overrides the\n");
262 usage.append (" default CIM Listener Service Name\n");
263 usage.append (" -start [name] - starts pegasus as a Windows Service\n");
264 usage.append (" [name] is optional and overrides the\n");
265 usage.append (" default CIM Listener Service Name\n");
266 usage.append (" -stop [name] - stops pegasus as a Windows Service\n");
267 usage.append (" [name] is optional and overrides the\n");
268 usage.append (" default CIM Listener Service Name\n\n");
270 #if !defined(PEGASUS_OS_TYPE_WINDOWS)
271 usage.append (" --nodaemon - do NOT run as a daemon\n");
275 cout << _cimListenerProcess->getProductName() << " " << _cimListenerProcess->getVersion() << endl;
278 //ATTN: Add menu items to Server bundle for listener
279 /*#if defined(PEGASUS_OS_TYPE_WINDOWS)
280 MessageLoaderParms parms("src.Server.cimserver.MENU.WINDOWS", usage);
281 #elif defined(PEGASUS_OS_USE_RELEASE_DIRS)
282 MessageLoaderParms parms("src.Server.cimserver.MENU.HPUXLINUXIA64GNU", usage);
284 MessageLoaderParms parms("src.Server.cimserver.MENU.STANDARD", usage);
286 cout << MessageLoader::getMessage(parms) << endl;
293 // Dummy function for the Thread object associated with the initial thread.
294 // Since the initial thread is used to process CIM requests, this is
295 // needed to localize the exceptions thrown during CIM request processing.
296 // Note: This function should never be called!
298 PEGASUS_THREAD_RETURN PEGASUS_THREAD_CDECL dummyThreadFunc(void *parm)
300 return((PEGASUS_THREAD_RETURN)0);
306 /////////////////////////////////////////////////////////////////////////
308 //////////////////////////////////////////////////////////////////////////
309 int main(int argc, char** argv)
311 String pegasusHome = String::EMPTY;
312 Boolean shutdownOption = false;
315 // Set Message loading to process locale
316 MessageLoader::_useProcessLocale = true;
320 #if defined(PEGASUS_OS_AIX) && defined(PEGASUS_HAS_MESSAGES)
321 setlocale(LC_ALL, "");
324 #ifdef PEGASUS_OS_OS400
326 VFYPTRS_INCDCL; // VFYPTRS local variables
329 #pragma exception_handler (qsyvp_excp_hndlr,qsyvp_excp_comm_area,\
331 for( int arg_index = 1; arg_index < argc; arg_index++ ){
332 VFYPTRS(VERIFY_SPP_NULL(argv[arg_index]));
334 #pragma disable_handler
336 // Convert the args to ASCII
337 for(Uint32 i = 0;i< argc;++i)
342 // Initialize Pegasus home to the shipped OS/400 directory.
343 pegasusHome = OS400_DEFAULT_PEGASUS_HOME;
347 #ifndef PEGASUS_OS_TYPE_WINDOWS
349 // Get environment variables:
351 #ifdef PEGASUS_OS_OS400
353 const char* tmp = getenv("PEGASUS_HOME");
355 char home[256] = {0};
356 if (tmp && strlen(tmp) < 256)
363 #if defined(PEGASUS_OS_AIX) && defined(PEGASUS_USE_RELEASE_DIRS)
364 pegasusHome = AIX_RELEASE_PEGASUS_HOME;
365 #elif !defined(PEGASUS_USE_RELEASE_DIRS)
366 const char* tmp = getenv("PEGASUS_HOME");
375 FileSystem::translateSlashes(pegasusHome);
379 char exeDir[MAX_PATH];
380 HMODULE hExe = GetModuleHandle(NULL);
381 GetModuleFileName(hExe, exeDir, sizeof(exeDir));
382 *strrchr(exeDir, '\\') = '\0';
383 pegasusHome = String(exeDir);
387 // Get help, version, and shutdown options
389 for (int i = 1; i < argc; )
391 const char* arg = argv[i];
392 if(String::equal(arg,"--help"))
397 else if(String::equal(arg,"--version"))
399 cout << _cimListenerProcess->getVersion() << endl;
403 else if (*arg == '-')
406 const char* option = arg + 1;
409 // Check to see if user asked for the version (-v option):
411 if (*option == OPTION_VERSION &&
414 cout << _cimListenerProcess->getVersion() << endl;
418 // Check to see if user asked for help (-h option):
420 else if (*option == OPTION_HELP &&
421 (strlen(option) == 1))
426 #if !defined(PEGASUS_USE_RELEASE_DIRS)
427 else if (*option == OPTION_HOME &&
428 (strlen(option) == 1))
432 pegasusHome.assign(argv[i + 1]);
437 //cout << "Missing argument for option -" << option << endl;
439 MessageLoaderParms parms("src.Server.cimserver.MISSING_ARGUMENT",
440 "Missing argument for option -$0",
442 cout << MessageLoader::getMessage(parms) << endl;
446 memmove(&argv[i], &argv[i + 2], (argc-i-1) * sizeof(char*));
450 #if defined(PEGASUS_OS_HPUX)
452 // Check to see if user asked for the version (-X option):
454 if (*option == OPTION_BINDVERBOSE &&
455 (strlen(option) == 1))
457 System::bindVerbose = true;
459 //cout << "Unsupported debug option, BIND_VERBOSE, enabled."
461 MessageLoaderParms parms("src.Server.cimserver.UNSUPPORTED_DEBUG_OPTION",
462 "Unsupported debug option, BIND_VERBOSE, enabled.");
463 cout << MessageLoader::getMessage(parms) << endl;
464 // remove the option from the command line
465 memmove(&argv[i], &argv[i + 1], (argc-i) * sizeof(char*));
470 // Check to see if user asked for shutdown (-s option):
472 else if (*option == OPTION_SHUTDOWN &&
473 (strlen(option) == 1))
476 // Check to see if shutdown has already been specified:
481 //cout << "Duplicate shutdown option specified." << endl;
482 MessageLoaderParms parms("DynListener.cimlistener.DUPLICATE_SHUTDOWN_OPTION",
483 "Duplicate shutdown option specified.");
485 cout << MessageLoader::getMessage(parms) << endl;
489 shutdownOption = true;
491 // remove the option from the command line
492 memmove(&argv[i], &argv[i + 1], (argc-i) * sizeof(char*));
503 // Set the value for pegasusHome property
505 DynamicListenerConfig::setListenerHome(pegasusHome);
508 // Do the plaform specific run
511 return _cimListenerProcess->platform_run( argc, argv, shutdownOption );
514 void CIMListenerProcess::cimserver_stop()
516 _cimListener->stop();
520 // The main, common, running code
522 // NOTE: Do NOT call exit(). Use return(), otherwise some platforms
523 // will fail to shutdown properly/cleanly.
525 // TODO: Current change minimal for platform "service" shutdown bug fixes.
526 // Perhpas further extract out common stuff and put into main(), put
527 // daemon stuff into platform specific platform_run(), etc.
528 // Note: make sure to not put error handling stuff that platform
529 // specific runs may need to deal with bettter (instead of exit(), etc).
532 int CIMListenerProcess::cimserver_run( int argc, char** argv, Boolean shutdownOption )
534 String logsDirectory = String::EMPTY;
535 String homeDir = configManager->getListenerHome();
538 // Get an instance of the Config Manager.
540 //configManager = DynamicListenerConfig::getInstance();
543 // Check to see if we should Pegasus as a daemon
545 Boolean daemonOption;
546 #if defined(PEGASUS_OS_TYPE_WINDOWS)
547 daemonOption = false;
550 for (int i=1; i < argc; i++)
552 if (strcmp(argv[i], OPTION_NO_DAEMON) == 0)
554 daemonOption = false;
560 #ifdef PEGASUS_OS_OS400
561 // In a special startup case for IBM OS400, when the server is
562 // automatically started when the machine starts up the config
563 // file cannot be read because of access restrictions for the
564 // user starting the server. In this case, we need to skip
565 // reading the config options and therefore any use of the config
566 // manager also. To make this determinations we will check to see
567 // if the daemon flag is set to true. If so, then there will be a
568 // series of checks to bracket all the calls to the configManager
569 // which would otherwise fail. All this will only be done for
572 Boolean os400StartupOption = daemonOption ? true : false;
576 // Get options (from command line and from configuration file); this
577 // removes corresponding options and their arguments from the command
582 #ifdef PEGASUS_OS_OS400
583 if (os400StartupOption == false)
585 String configFilePath = homeDir + "/" + DEFAULT_CONFIG_FILE;
586 FileSystem::translateSlashes(configFilePath);
587 configManager->initOptions(configFilePath);
591 Logger::put_l(Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE,
592 "src.Server.cimserver.SERVER_NOT_STARTED",
593 "cimserver not started: $0", e.getMessage());
595 #if !defined(PEGASUS_OS_OS400)
596 MessageLoaderParms parms("DynListener.cimlistener.LISTENER_NOT_STARTED",
597 "CIM Listener not started: $0", e.getMessage());
599 PEGASUS_STD(cerr) << argv[0] << ": " << MessageLoader::getMessage(parms)
600 << PEGASUS_STD(endl);
607 // Set the home directory, msg sub-dir, into the MessageLoader.
608 // This will be the default directory where the resource bundles
610 String msgHome = homeDir + "/msg";
611 FileSystem::translateSlashes(msgHome);
612 MessageLoader::setPegasusMsgHome(msgHome);
615 // Check to see if we need to shutdown CIMOM
620 //Uncomment the following line when signals are implemented on all platforms.
621 //The workaround is to use a file.
624 #if defined(PEGASUS_OS_HPUX) || defined(PEGASUS_OS_LINUX) || defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM) \
625 || defined(PEGASUS_OS_AIX) || defined(PEGASUS_OS_SOLARIS) \
626 || defined(PEGASUS_OS_VMS)
628 // Check to see if the CIM Listener is running. No need to stop if not running.
629 if(_cimListenerProcess->isCIMServerRunning())
631 // remove the old file if it exists
632 System::removeFile(LISTENER_STOP_FILE);
635 FILE *pid_file = fopen(LISTENER_STOP_FILE, "w");
639 // save the pid in the file
640 fprintf(pid_file, "%ld\n", _cimListenerProcess->get_server_pid());
644 printf("CIM Listener may not be running.\n");
649 #ifdef PEGASUS_OS_OS400
651 //Logger::put(Logger::ERROR_LOG, System::CIMSERVER, Logger::INFORMATION,
652 //"CIM Server stopped.");
653 Logger::put_l(Logger::ERROR_LOG, System::CIMSERVER, Logger::INFORMATION,
654 "src.Server.cimserver.SERVER_STOPPED",
655 "CIM Server stopped.");
659 //cout << "CIM Server stopped." << endl;
660 MessageLoaderParms parms("DynListener.cimlistener.LISTENER_STOPPED",
661 "CIM Listener stopped.");
662 cout << MessageLoader::getMessage(parms) << endl;
667 //get config options. note that the paths will be converted to homedPaths in the lookup calls.
669 Boolean httpsConnection;
670 String sslKeyFilePath;
671 String sslCertificateFilePath;
673 String consumerConfigDir;
674 Boolean enableConsumerUnload;
675 Uint32 consumerIdleTimeout;
676 Uint32 shutdownTimeout;
679 String traceComponents;
681 #ifdef PEGASUS_OS_OS400
682 if (os400StartupOption)
684 //set fixed values for OS400
686 httpsConnection = false;
688 sslCertificateFilePath = "";
690 consumerConfigDir = "";
691 enableConsumerUnload = false;
692 consumerIdleTimeout = 0;
693 shutdownTimeout = 10;
694 traceFile = "cimlistener.trc";
696 traceComponents = "LISTENER";
702 configManager->lookupIntegerValue("listenerPort", listenerPort);
703 httpsConnection = configManager->isTrue("enableHttpsListenerConnection");
704 configManager->lookupValue("sslKeyFilePath", sslKeyFilePath);
705 configManager->lookupValue("sslCertificateFilePath", sslCertificateFilePath);
706 configManager->lookupValue("consumerDir", consumerDir);
707 configManager->lookupValue("consumerConfigDir", consumerConfigDir);
708 enableConsumerUnload = configManager->isTrue("enableConsumerUnload");
709 configManager->lookupIntegerValue("consumerIdleTimeout", consumerIdleTimeout);
710 configManager->lookupIntegerValue("consumerIdleTimeout", consumerIdleTimeout);
711 configManager->lookupIntegerValue("shutdownTimeout", shutdownTimeout);
712 configManager->lookupValue("traceFilePath", traceFile);
713 configManager->lookupIntegerValue("traceLevel", traceLevel);
714 configManager->lookupValue("traceComponents", traceComponents);
716 } catch (Exception& ex)
718 MessageLoaderParms parms("src.Server.cimserver.INVALID_CONFIG_OPTION",
719 "Invalid configuration option: $0",
721 cout << MessageLoader::getMessage(parms) << endl;
724 #ifdef PEGASUS_OS_OS400
728 //Check listener port validity
729 //ATTN: Do we need this?
730 /*CString portString = listenerPort.getCString();
732 Uint32 port = strtol(portString, &end, 10);
733 if(!(end != 0 && *end == '\0'))
735 PEGASUS_STD(cerr) << "Bad HTTP/HTTPS Port Value" << PEGASUS_STD(endl);
739 //Configure trace options
742 Uint32 traceLevelArg = 0;
746 case 1: traceLevelArg = Tracer::LEVEL1; break;
747 case 2: traceLevelArg = Tracer::LEVEL2; break;
748 case 3: traceLevelArg = Tracer::LEVEL3; break;
749 case 4: traceLevelArg = Tracer::LEVEL4; break;
753 Tracer::setTraceFile((const char*)traceFile.getCString());
754 Tracer::setTraceComponents(traceComponents);
755 Tracer::setTraceLevel(traceLevelArg);
757 #if defined(PEGASUS_DEBUG)
758 // Put out startup up message.
759 cout << _cimListenerProcess->getProductName() << " " << _cimListenerProcess->getVersion() << endl;
761 //cout << "Built " << __DATE__ << " " << __TIME__ << endl;
762 //cout <<"Starting..."
763 MessageLoaderParms parms("DynListener.cimlistener.STARTUP_MESSAGE",
764 "CIM Listener built $0 $1\nCIM Listener starting...",
770 // reset message loading to NON-process locale
771 MessageLoader::_useProcessLocale = false;
774 // Get the parent's PID before forking
775 _cimListenerProcess->set_parent_pid(System::getPID());
777 // do we need to run as a daemon ?
780 if(-1 == _cimListenerProcess->cimserver_fork())
781 #ifndef PEGASUS_OS_OS400
798 // Now we are after the fork...
799 // Create a dummy Thread object that can be used to store the
800 // AcceptLanguages object for CIM requests that are serviced
801 // by this thread (initial thread of server). Need to do this
802 // because this thread is not in a ThreadPool, but is used
803 // to service CIM requests.
804 // The run function for the dummy Thread should never be called,
805 Thread *dummyInitialThread = new Thread(dummyThreadFunc, NULL, false);
806 Thread::setCurrent(dummyInitialThread);
807 AcceptLanguages default_al;
809 default_al = LanguageParser::getDefaultAcceptLanguages();
810 Thread::setLanguages(new AcceptLanguages(default_al));
811 }catch(InvalidAcceptLanguageHeader& e){
812 Logger::put_l(Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE,
813 "src.Server.cimserver.FAILED_TO_SET_PROCESS_LOCALE",
814 "Could not convert the system process locale into a valid AcceptLanguage format.");
815 Logger::put(Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE,
821 #ifdef PEGASUS_OS_OS400
822 // Special server initialization code for OS/400.
823 if (_cimListenerProcess->cimserver_initialize() != 0)
825 // do some logging here!
827 //Logger::put(Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE,
828 //"CIM Server failed to initialize");
829 Logger::put_l(Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE,
830 "src.Server.cimserver.SERVER_FAILED_TO_INITIALIZE",
831 "CIM Server failed to initialize");
837 #if defined(PEGASUS_OS_HPUX) || defined(PEGASUS_PLATFORM_LINUX_GENERIC_GNU) \
838 || defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM) || defined(PEGASUS_OS_AIX) \
839 || defined(PEGASUS_OS_SOLARIS) || defined (PEGASUS_OS_VMS)
840 umask(S_IWGRP|S_IWOTH);
843 // check if CIMServer is already running
844 // if CIMServer is already running, print message and
845 // notify parent process (if there is a parent process) to terminate
847 if(_cimListenerProcess->isCIMServerRunning())
850 //cout << "Unable to start CIMServer." << endl;
851 //cout << "CIMServer is already running." << endl;
852 MessageLoaderParms parms("DynListener.cimlistener.UNABLE_TO_START_LISTENER_ALREADY_RUNNING",
853 "Unable to start CIM Listener.\nCIM Listener is already running.");
854 PEGASUS_STD(cerr) << MessageLoader::getMessage(parms) << PEGASUS_STD(endl);
857 // notify parent process (if there is a parent process) to terminate
860 _cimListenerProcess->notify_parent(1);
867 // try loop to bind the address, and run the server
870 //ATTN: Need to handle SSL cases
873 _cimListener = new DynamicListener(listenerPort,
876 enableConsumerUnload,
880 _cimListener->start();
882 Logger::put_l(Logger::STANDARD_LOG, System::CIMSERVER, Logger::INFORMATION,
883 "src.Server.cimserver.LISTENING_ON_PORT",
884 "Listening on port $0.", listenerPort);
888 #if defined(PEGASUS_DEBUG)
889 //Log startup options
890 printf("Starting CIMListener with the following options\n");
891 printf("\tlistenerPort %d\n", listenerPort);
892 printf("\thttpsConnection %d\n", httpsConnection);
893 printf("\tsslKeyFilePath %s\n", (const char*)sslKeyFilePath.getCString());
894 printf("\tsslCertificateFilePath %s\n", (const char*)sslCertificateFilePath.getCString());
895 printf("\tconsumerDir %s\n", (const char*)consumerDir.getCString());
896 printf("\tconsumerConfigDir %s\n", (const char*)consumerConfigDir.getCString());
897 printf("\tenableConsumerUnload %d\n", enableConsumerUnload);
898 printf("\tconsumerIdleTimeout %d\n", consumerIdleTimeout);
899 printf("\tshutdownTimeout %d\n", shutdownTimeout);
900 printf("\ttraceFilePath %s\n", (const char*)traceFile.getCString());
901 printf("\ttraceLevel %d\n", traceLevel);
902 printf("\ttraceComponents %s\n", (const char*)traceComponents.getCString());
903 printf("\tMessage home is %s\n", (const char*)msgHome.getCString());
906 // notify parent process (if there is a parent process) to terminate
907 // so user knows that there is cimserver ready to serve CIM requests.
909 _cimListenerProcess->notify_parent(0);
913 #if defined(PEGASUS_OS_HPUX) || defined(PEGASUS_OS_LINUX) || defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM) \
914 || defined(PEGASUS_OS_AIX) || defined(PEGASUS_OS_SOLARIS) \
915 || defined(PEGASUS_OS_VMS)
917 // create a file to indicate that the cimserver has started and
918 // save the process id of the cimserver process in the file
920 // remove the old file if it exists
921 System::removeFile(_cimListenerProcess->getPIDFileName());
924 FILE *pid_file = fopen(_cimListenerProcess->getPIDFileName(), "w");
928 // save the pid in the file
929 fprintf(pid_file, "%ld\n", _cimListenerProcess->get_server_pid());
934 //#if defined(PEGASUS_DEBUG)
935 cout << "Started. " << endl;
938 // Put server started message to the logger
939 Logger::put_l(Logger::STANDARD_LOG, System::CIMSERVER,
941 "src.Server.cimserver.STARTED_VERSION",
942 "Started $0 version $1.",
943 _cimListenerProcess->getProductName(), _cimListenerProcess->getVersion());
945 #if !defined(PEGASUS_OS_TYPE_WINDOWS)
947 #if defined(PEGASUS_DEBUG)
948 printf("Blocking until shutdown signal\n");
952 if (FileSystem::exists(LISTENER_STOP_FILE))
960 #if defined(PEGASUS_DEBUG)
961 printf("Received signal to shutdown\n");
963 FileSystem::removeFile(LISTENER_STOP_FILE);
964 _cimListener->stop();
967 //Uncomment this block of code when signals are implemented on all platforms.
968 //Temporary workaround is to use a file, as specified above.
969 //wait until signalled to terminate
970 /*int sig = _cimListenerProcess->cimserver_wait();
971 printf("Returned from sigwait %d\n", sig);
975 printf("Graceful shutdown\n");
976 _cimListener->stop();
980 //ATTN: Implement cimserver_wait for windows so we don't have to loop here
981 //The listener is stopped in the cimserver_stop method by the service control manager
984 if (!_cimListener->isAlive())
993 #if defined(PEGASUS_DEBUG)
994 PEGASUS_STD(cout) << "Stopped\n";
998 // normal termination
1001 // Put server shutdown message to the logger
1002 Logger::put_l(Logger::STANDARD_LOG, System::CIMSERVER,
1003 Logger::INFORMATION, "src.Server.cimserver.STOPPED",
1004 "$0 stopped.", _cimListenerProcess->getProductName());
1006 #if defined(PEGASUS_OS_HPUX) || defined(PEGASUS_PLATFORM_LINUX_GENERIC_GNU) \
1007 || defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM) || defined(PEGASUS_OS_AIX) \
1008 || defined(PEGASUS_OS_SOLARIS) || defined(PEGASUS_OS_VMS)
1010 // close the file created at startup time to indicate that the
1011 // cimserver has terminated normally.
1013 FileSystem::removeFile(_cimListenerProcess->getPIDFileName());
1020 //Logger::put(Logger::STANDARD_LOG, System::CIMSERVER, Logger::WARNING,
1021 //"Error: $0", e.getMessage());
1022 Logger::put_l(Logger::STANDARD_LOG, System::CIMSERVER, Logger::WARNING,
1023 "src.Server.cimserver.ERROR",
1024 "Error: $0", e.getMessage());
1026 #ifndef PEGASUS_OS_OS400
1028 //PEGASUS_STD(cerr) << "Error: " << e.getMessage() << PEGASUS_STD(endl);
1029 MessageLoaderParms parms("DynListener.cimlistener.ERROR",
1030 "CIM Listener error: $0");
1031 PEGASUS_STD(cerr) << MessageLoader::getMessage(parms) << PEGASUS_STD(endl);
1036 // notify parent process (if there is a parent process) to terminate
1039 _cimListenerProcess->notify_parent(1);
1043 delete _cimListener;
1052 delete _cimListener;
1056 #if defined(PEGASUS_DEBUG)
1057 printf("Exiting child process\n");