BUG#:5399
[tpot/pegasus/.git] / src / Pegasus / DynListener / Service / cimlistener.cpp
index cedb7db57501a0cffd8157a7196e38dadf5caf24..1db78db46a786799ca022f3b0c6d74d88cf26adc 100644 (file)
@@ -1,4 +1,4 @@
-//%2004////////////////////////////////////////////////////////////////////////
+//%2006////////////////////////////////////////////////////////////////////////
 //
 // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
 // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
@@ -6,6 +6,10 @@
 // IBM Corp.; EMC Corporation, The Open Group.
 // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
 // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
+// Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
+// EMC Corporation; VERITAS Software Corporation; The Open Group.
+// Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
+// EMC Corporation; Symantec Corporation; The Open Group.
 //
 // Permission is hereby granted, free of charge, to any person obtaining a copy
 // of this software and associated documentation files (the "Software"), to
 //
 // Author: Mike Brasher (mbrasher@bmc.com)
 //
-// Modified By: Mike Day (mdday@us.ibm.com) 
-//
-// Modified By: Karl Schopmeyer (k.schopmeyer@opengroup.org)
-//
-// Modified By: Nag Boranna (nagaraja_boranna@hp.com)
-//
-// Modified By: Jenny Yu (jenny_yu@hp.com)
-//
-// Modified By: Sushma Fernandes (sushma_fernandes@hp.com)
+// Modified By: Mike Day (mdday@us.ibm.com)
+//              Karl Schopmeyer (k.schopmeyer@opengroup.org)
+//              Nag Boranna (nagaraja_boranna@hp.com)
+//              Jenny Yu (jenny_yu@hp.com)
+//              Sushma Fernandes (sushma_fernandes@hp.com)
 //              Carol Ann Krug Graves, Hewlett-Packard Company
-//                (carolann_graves@hp.com)
-//      Yi Zhou, Hewlett-Packard Company (yi_zhou@hp.com)
-//
-// Modified By: Dave Rosckes (rosckes@us.ibm.com)
-//
-// Modified By: Humberto Rivero (hurivero@us.ibm.com)
-//
-// Modified By: Steve Hills (steve.hills@ncr.com)
-//
-// Modified By: Amit K Arora, IBM (amitarora@in.ibm.com) - pep 167
-//
-// Modified By: Josephine Eskaline Joyce, IBM (jojustin@in.ibm.com) - Bug#2555
-//
-// Modified By: Josephine Eskaline Joyce, IBM (jojustin@in.ibm.com) - Bug#2032
-//
-// Modified By: Heather Sterling, IBM (hsterl@us.ibm.com) - PEP#197 CIMListener, PEP#222 Service Refactoring
-//
-// Modified By: Amit K Arora, IBM (amita@in.ibm.com) Bug#3028
+//                  (carolann_graves@hp.com)
+//              Yi Zhou, Hewlett-Packard Company (yi_zhou@hp.com)
+//              Dave Rosckes (rosckes@us.ibm.com)
+//              Humberto Rivero (hurivero@us.ibm.com)
+//              Steve Hills (steve.hills@ncr.com)
+//              Amit K Arora, IBM (amitarora@in.ibm.com) - pep 167
+//              Josephine Eskaline Joyce, IBM (jojustin@in.ibm.com) - Bug#2555
+//              Josephine Eskaline Joyce, IBM (jojustin@in.ibm.com) - Bug#2032
+//              Heather Sterling, IBM (hsterl@us.ibm.com) - PEP#197 CIMListener,
+//                      PEP#222 Service Refactoring
+//              Amit K Arora, IBM (amita@in.ibm.com) Bug#3028
+//              David Dillard, VERITAS Software Corp.
+//                  (david.dillard@veritas.com)
 //
 //%/////////////////////////////////////////////////////////////////////////////
 
@@ -63,7 +58,7 @@
 //
 // Notes on deamon operation (Unix) and service operation (Win 32):
 //
-// To run pegasus listener as a daemon on Unix platforms: 
+// To run pegasus listener as a daemon on Unix platforms:
 //
 // cimlistener
 //
 //
 // cimlistener --nodaemon
 //
-// The daemon setting has no effect on windows operation. 
+// The daemon setting has no effect on windows operation.
 //
 // To shutdown pegasus listener, use the -s option:
-// 
-// cimlistener -s 
+//
+// cimlistener -s
 //
 // To run pegasus listener as an NT service, there are FOUR  different possibilities:
 //
-// To INSTALL the Pegasus service, 
+// To INSTALL the Pegasus service,
 //
 // cimlistener -install
 //
-// To REMOVE the Pegasus service, 
+// To REMOVE the Pegasus service,
 //
 // cimlistener -remove
 //
-// To START the Pegasus service, 
+// To START the Pegasus service,
 //
 // net start cimlistener
 // or
 // cimlistener -start
 //
-// To STOP the Pegasus service, 
+// To STOP the Pegasus service,
 //
 // net stop cimlistener
 // or
 // cimlistener -stop
 //
-// Alternatively, you can use the windows service manager. Pegasus listener shows up 
+// Alternatively, you can use the windows service manager. Pegasus listener shows up
 // in the service database as "Pegasus CIM Listener"
 //
 // Mike Day, mdday@us.ibm.com
-// 
+//
 //////////////////////////////////////////////////////////////////////
 
 
 #include <Pegasus/Common/Config.h>
 #include <Pegasus/Common/Constants.h>
-#include <iostream>
-#include <cassert>
+#include <Pegasus/Common/PegasusAssert.h>
 #include <cstdlib>
-#include <fstream>
 #include <Pegasus/Common/FileSystem.h>
 #include <Pegasus/Common/Logger.h>
 #include <Pegasus/Common/System.h>
 #include <Pegasus/Common/Tracer.h>
 #include <Pegasus/Common/Thread.h>
+#include <Pegasus/Common/LanguageParser.h>
 #include <Pegasus/Common/PegasusVersion.h>
+#include <Pegasus/Common/Signal.h>
 #include <Pegasus/DynListener/DynamicListener.h>
 #include <Pegasus/DynListener/DynamicListenerConfig.h>
 #include <Service/ServerProcess.h>
 
+#if defined(PEGASUS_OS_TYPE_UNIX)
+# if defined(PEGASUS_OS_OS400)
+#  include <unistd.cleinc>
+# else
+#  include <unistd.h>
+# endif
+# include <sys/types.h>
+# include <sys/stat.h>
+# include <fcntl.h>
+#endif
+
 PEGASUS_USING_PEGASUS;
 PEGASUS_USING_STD;
 
@@ -184,7 +190,7 @@ public:
     {
         return PEGASUS_LISTENER_SERVICE_DESCRIPTION;
     }
-    
+
     //defined in PegasusVersion.h
     virtual const char* getVersion() const
     {
@@ -201,12 +207,17 @@ public:
         return LISTENER_START_FILE;
     }
 
-    int cimserver_run(int argc, char** argv, bool shutdownOption);
+    int cimserver_run(
+        int argc,
+        char** argv,
+        Boolean shutdownOption,
+        Boolean debugOutputOption);
 
     void cimserver_stop(void);
 };
 
 AutoPtr<CIMListenerProcess> _cimListenerProcess(new CIMListenerProcess());
+AutoPtr<DynamicListenerConfig> configManager(DynamicListenerConfig::getInstance());
 static DynamicListener* _cimListener = 0;
 
 
@@ -237,36 +248,13 @@ static const char   LONG_HELP []  = "help";
 
 static const char   LONG_VERSION []  = "version";
 
-#if defined(PEGASUS_OS_HPUX)
-static const char OPTION_BINDVERBOSE = 'X';
-#endif
+static const char OPTION_DEBUGOUTPUT = 'X';
 
 static const String PROPERTY_TIMEOUT = "shutdownTimeout";
 
 static const String DEFAULT_CONFIG_FILE = "cimlistener.conf";
 
 
-DynamicListenerConfig*    configManager = 0;
-
-
-/** GetOptions function - This function defines the Options Table
-    and sets up the options from that table using the config manager.
-*/
-void GetOptions(
-    DynamicListenerConfig* cm,
-    String configFile)
-{
-    try
-    {
-        cm->initOptions(configFile);
-    }
-    catch (Exception&)
-    {
-        throw;
-    }
-    //ATTN: Catch OptionMgr exceptions
-}
-
 /* PrintHelp - This is temporary until we expand the options manager to allow
    options help to be defined with the OptionRow entries and presented from
    those entries.
@@ -302,7 +290,7 @@ void PrintHelp(const char* arg0)
     cout << endl;
     cout << _cimListenerProcess->getProductName() << " " << _cimListenerProcess->getVersion() << endl;
     cout << endl;
-    
+
 //ATTN: Add menu items to Server bundle for listener
 /*#if defined(PEGASUS_OS_TYPE_WINDOWS)
     MessageLoaderParms parms("src.Server.cimserver.MENU.WINDOWS", usage);
@@ -321,11 +309,11 @@ void PrintHelp(const char* arg0)
 // Dummy function for the Thread object associated with the initial thread.
 // Since the initial thread is used to process CIM requests, this is
 // needed to localize the exceptions thrown during CIM request processing.
-// Note: This function should never be called! 
-// 
+// Note: This function should never be called!
+//
 PEGASUS_THREAD_RETURN PEGASUS_THREAD_CDECL dummyThreadFunc(void *parm)
 {
-   return((PEGASUS_THREAD_RETURN)0);    
+   return((PEGASUS_THREAD_RETURN)0);
 }
 
 
@@ -338,10 +326,11 @@ int main(int argc, char** argv)
 {
     String pegasusHome  = String::EMPTY;
     Boolean shutdownOption = false;
+    Boolean debugOutputOption = false;
 
 //l10n
 // Set Message loading to process locale
-MessageLoader::_useProcessLocale = true; 
+MessageLoader::_useProcessLocale = true;
 //l10n
 
 //l10n
@@ -404,8 +393,12 @@ setlocale(LC_ALL, "");
 #else
 
   // windows only
-  //setHome(pegasusHome);
-  pegasusHome = _cimListenerProcess->getHome();
+       char exeDir[MAX_PATH];
+       HMODULE hExe = GetModuleHandle(NULL);
+       GetModuleFileName(hExe, exeDir, sizeof(exeDir));
+       *strrchr(exeDir, '\\') = '\0';
+       pegasusHome = String(exeDir);
+
 #endif
 
         // Get help, version, and shutdown options
@@ -471,25 +464,27 @@ setlocale(LC_ALL, "");
                     argc -= 2;
                 }
 #endif
-#if defined(PEGASUS_OS_HPUX)
                 //
-                // Check to see if user asked for the version (-X option):
+                // Check to see if user asked for debug output (-X option):
                 //
-                if (*option == OPTION_BINDVERBOSE &&
+                else if (*option == OPTION_DEBUGOUTPUT &&
                         (strlen(option) == 1))
                 {
-            System::bindVerbose = true;
-                    //l10n
-                    //cout << "Unsupported debug option, BIND_VERBOSE, enabled." 
-                         //<< endl;
-                    MessageLoaderParms parms("src.Server.cimserver.UNSUPPORTED_DEBUG_OPTION",
-                                         "Unsupported debug option, BIND_VERBOSE, enabled.");
+                    MessageLoaderParms parms(
+                        "src.Server.cimserver.UNSUPPORTED_DEBUG_OPTION",
+                        "Unsupported debug output option is enabled.");
                     cout << MessageLoader::getMessage(parms) << endl;
+
+                    debugOutputOption = true;
+
+#if defined(PEGASUS_OS_HPUX)
+                    System::bindVerbose = true;
+#endif
+
                     // remove the option from the command line
                     memmove(&argv[i], &argv[i + 1], (argc-i) * sizeof(char*));
-                    argc--;   
+                    argc--;
                 }
-#endif
                 //
                 // Check to see if user asked for shutdown (-s option):
                 //
@@ -505,16 +500,16 @@ setlocale(LC_ALL, "");
                         //cout << "Duplicate shutdown option specified." << endl;
                         MessageLoaderParms parms("DynListener.cimlistener.DUPLICATE_SHUTDOWN_OPTION",
                                                  "Duplicate shutdown option specified.");
-                       
+
                         cout << MessageLoader::getMessage(parms) << endl;
                         exit(0);
                     }
 
                     shutdownOption = true;
+
                     // remove the option from the command line
                     memmove(&argv[i], &argv[i + 1], (argc-i) * sizeof(char*));
-                    argc--;   
+                    argc--;
                 }
                 else
                     i++;
@@ -532,7 +527,8 @@ setlocale(LC_ALL, "");
     // Do the plaform specific run
     //
 
-    return _cimListenerProcess->platform_run( argc, argv, shutdownOption );
+    return _cimListenerProcess->platform_run(
+        argc, argv, shutdownOption, debugOutputOption);
 }
 
 void CIMListenerProcess::cimserver_stop()
@@ -543,24 +539,29 @@ void CIMListenerProcess::cimserver_stop()
 //
 // The main, common, running code
 //
-// NOTE: Do NOT call exit().  Use return(), otherwise some platforms 
+// NOTE: Do NOT call exit().  Use return(), otherwise some platforms
 // will fail to shutdown properly/cleanly.
 //
-// TODO: Current change minimal for platform "service" shutdown bug fixes.  
-// Perhpas further extract out common stuff and put into main(), put 
-// daemon stuff into platform specific platform_run(), etc.  
-// Note: make sure to not put error handling stuff that platform 
+// TODO: Current change minimal for platform "service" shutdown bug fixes.
+// Perhpas further extract out common stuff and put into main(), put
+// daemon stuff into platform specific platform_run(), etc.
+// Note: make sure to not put error handling stuff that platform
 // specific runs may need to deal with bettter (instead of exit(), etc).
 //
 
-int CIMListenerProcess::cimserver_run( int argc, char** argv, Boolean shutdownOption )
+int CIMListenerProcess::cimserver_run(
+    int argc,
+    char** argv,
+    Boolean shutdownOption,
+    Boolean debugOutputOption)
 {
     String logsDirectory = String::EMPTY;
+       String homeDir = configManager->getListenerHome();
 
     //
     // Get an instance of the Config Manager.
     //
-    configManager = DynamicListenerConfig::getInstance();
+    //configManager = DynamicListenerConfig::getInstance();
 
     //
     // Check to see if we should Pegasus as a daemon
@@ -579,7 +580,7 @@ int CIMListenerProcess::cimserver_run( int argc, char** argv, Boolean shutdownOp
         }
     }
 #endif
-  
+
 #ifdef PEGASUS_OS_OS400
     // In a special startup case for IBM OS400, when the server is
     // automatically started when the machine starts up the config
@@ -593,7 +594,7 @@ int CIMListenerProcess::cimserver_run( int argc, char** argv, Boolean shutdownOp
     // IBM OS400.
 
     Boolean os400StartupOption = daemonOption ? true : false;
-#endif    
+#endif
 
     //
     // Get options (from command line and from configuration file); this
@@ -604,8 +605,10 @@ int CIMListenerProcess::cimserver_run( int argc, char** argv, Boolean shutdownOp
     {
 #ifdef PEGASUS_OS_OS400
     if (os400StartupOption == false)
-#endif   
-        GetOptions(configManager, DEFAULT_CONFIG_FILE);
+#endif
+               String configFilePath = homeDir + "/" + DEFAULT_CONFIG_FILE;
+               FileSystem::translateSlashes(configFilePath);
+        configManager->initOptions(configFilePath);
     }
     catch (Exception& e)
     {
@@ -624,51 +627,79 @@ int CIMListenerProcess::cimserver_run( int argc, char** argv, Boolean shutdownOp
         return(1);
     }
 
-
 // l10n
     // Set the home directory, msg sub-dir, into the MessageLoader.
-    // This will be the default directory where the resource bundles 
-    // are found.    
-/*  MessageLoader::setPegasusMsgHome(ConfigManager::getHomedPath(
-        ConfigManager::getInstance()->getCurrentValue("messageDir")));      
-*/
-
+    // This will be the default directory where the resource bundles
+    // are found.
+       String msgHome = homeDir + "/msg";
+       FileSystem::translateSlashes(msgHome);
+       MessageLoader::setPegasusMsgHome(msgHome);
 
     //
-    // Check to see if we need to shutdown CIMOM 
+    // Check to see if we need to shutdown CIMOM
     //
     if (shutdownOption)
     {
         //gracefully exit
         //Uncomment the following line when signals are implemented on all platforms.
         //The workaround is to use a file.
-        //cimserver_kill(1);
+#ifdef PEGASUS_HAS_SIGNALS
+        FILE *pid_file;
+        pid_t pid = 0;
+
+        // open the file containing the CIMServer process ID
+        pid_file = fopen(getPIDFileName(), "r");
+        if (!pid_file) 
+        {
+            return (-1);
+        }
 
+        // get the pid from the file
+        fscanf(pid_file, "%d\n", &pid);
+
+        fclose(pid_file);
+
+        if (pid == 0)
+        {
+           System::removeFile(getPIDFileName());
+           return (-1);
+        }
+
+        kill(pid, PEGASUS_SIGTERM);
+        //cimserver_kill(1);
+#else
 #if defined(PEGASUS_OS_HPUX) || defined(PEGASUS_OS_LINUX) || defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM) \
-    || defined(PEGASUS_OS_AIX) || defined(PEGASUS_PLATFORM_SOLARIS_SPARC_CC) \
+    || defined(PEGASUS_OS_AIX) || defined(PEGASUS_OS_SOLARIS) \
     || defined(PEGASUS_OS_VMS)
-        //
-        // create a file to indicate that the cimserver has started and
-        // save the process id of the cimserver process in the file
-        //
-        // remove the old file if it exists
-        System::removeFile(LISTENER_STOP_FILE);
-
-        // open the file
-        FILE *pid_file = fopen(LISTENER_STOP_FILE, "w");
 
-        if (pid_file)
+        // Check to see if the CIM Listener is running. No need to stop if not running.
+        if(_cimListenerProcess->isCIMServerRunning())
         {
-            // save the pid in the file
-            fprintf(pid_file, "%ld\n", _cimListenerProcess->get_server_pid());
-            fclose(pid_file);
+            // remove the old file if it exists
+            System::removeFile(LISTENER_STOP_FILE);
+
+            // open the file
+            FILE *pid_file = fopen(LISTENER_STOP_FILE, "w");
+
+            if (pid_file)
+            {
+                // save the pid in the file
+                fprintf(pid_file, "%ld\n", _cimListenerProcess->get_server_pid());
+                fclose(pid_file);
+            }
+        } else {
+            printf("CIM Listener may not be running.\n");
+            return(0);
         }
 #endif
 
+#endif //PEGASUS_HAS_SIGNALS
+
+
 #ifdef PEGASUS_OS_OS400
     //l10n
     //Logger::put(Logger::ERROR_LOG, System::CIMSERVER, Logger::INFORMATION,
-        //"CIM Server stopped.");  
+        //"CIM Server stopped.");
     Logger::put_l(Logger::ERROR_LOG, System::CIMSERVER, Logger::INFORMATION,
         "src.Server.cimserver.SERVER_STOPPED",
         "CIM Server stopped.");
@@ -683,9 +714,7 @@ int CIMListenerProcess::cimserver_run( int argc, char** argv, Boolean shutdownOp
 #endif
     }
 
-    //
-    //Get options from the config
-    //
+       //get config options.  note that the paths will be converted to homedPaths in the lookup calls.
     Uint32 listenerPort;
     Boolean httpsConnection;
     String sslKeyFilePath;
@@ -718,6 +747,8 @@ int CIMListenerProcess::cimserver_run( int argc, char** argv, Boolean shutdownOp
     } else
     {
 #endif
+       try
+    {
     configManager->lookupIntegerValue("listenerPort", listenerPort);
     httpsConnection = configManager->isTrue("enableHttpsListenerConnection");
     configManager->lookupValue("sslKeyFilePath", sslKeyFilePath);
@@ -726,12 +757,20 @@ int CIMListenerProcess::cimserver_run( int argc, char** argv, Boolean shutdownOp
     configManager->lookupValue("consumerConfigDir", consumerConfigDir);
     enableConsumerUnload = configManager->isTrue("enableConsumerUnload");
     configManager->lookupIntegerValue("consumerIdleTimeout", consumerIdleTimeout);
-    configManager->lookupValue("traceFilePath", traceFile);
     configManager->lookupIntegerValue("consumerIdleTimeout", consumerIdleTimeout);
     configManager->lookupIntegerValue("shutdownTimeout", shutdownTimeout);
     configManager->lookupValue("traceFilePath", traceFile);
     configManager->lookupIntegerValue("traceLevel", traceLevel);
     configManager->lookupValue("traceComponents", traceComponents);
+
+       } catch (Exception& ex)
+       {
+               MessageLoaderParms parms("src.Server.cimserver.INVALID_CONFIG_OPTION",
+                                                                "Invalid configuration option: $0",
+                                                                ex.getMessage());
+               cout << MessageLoader::getMessage(parms) << endl;
+               exit(0);
+       }
 #ifdef PEGASUS_OS_OS400
     }
 #endif
@@ -750,7 +789,7 @@ int CIMListenerProcess::cimserver_run( int argc, char** argv, Boolean shutdownOp
     //Configure trace options
     if (traceLevel > 0)
     {
-        Uint32 traceLevelArg;
+        Uint32 traceLevelArg = 0;
 
         switch (traceLevel)
         {
@@ -758,8 +797,7 @@ int CIMListenerProcess::cimserver_run( int argc, char** argv, Boolean shutdownOp
         case 2: traceLevelArg = Tracer::LEVEL2; break;
         case 3: traceLevelArg = Tracer::LEVEL3; break;
         case 4: traceLevelArg = Tracer::LEVEL4; break;
-        default: printf("Invalid trace level\n");
-            return 0;
+        default: break;
         }
 
         Tracer::setTraceFile((const char*)traceFile.getCString());
@@ -780,7 +818,7 @@ int CIMListenerProcess::cimserver_run( int argc, char** argv, Boolean shutdownOp
 
 //l10n
 // reset message loading to NON-process locale
-MessageLoader::_useProcessLocale = false; 
+MessageLoader::_useProcessLocale = false;
 //l10n
 
     // Get the parent's PID before forking
@@ -803,32 +841,32 @@ MessageLoader::_useProcessLocale = false;
         return(0);
     }
 #endif
-    
+
     }
 
 // l10n
     // Now we are after the fork...
     // Create a dummy Thread object that can be used to store the
-    // AcceptLanguages object for CIM requests that are serviced
+    // AcceptLanguageList object for CIM requests that are serviced
     // by this thread (initial thread of server).  Need to do this
     // because this thread is not in a ThreadPool, but is used
     // to service CIM requests.
     // The run function for the dummy Thread should never be called,
     Thread *dummyInitialThread = new Thread(dummyThreadFunc, NULL, false);
-    Thread::setCurrent(dummyInitialThread); 
-    AcceptLanguages default_al;
+    Thread::setCurrent(dummyInitialThread);
+    AcceptLanguageList default_al;
     try{
-         default_al = AcceptLanguages::getDefaultAcceptLanguages();   
-         Thread::setLanguages(new AcceptLanguages(default_al));
+         default_al = LanguageParser::getDefaultAcceptLanguages();
+         Thread::setLanguages(new AcceptLanguageList(default_al));
     }catch(InvalidAcceptLanguageHeader& e){
           Logger::put_l(Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE,
                   "src.Server.cimserver.FAILED_TO_SET_PROCESS_LOCALE",
-                  "Could not convert the system process locale into a valid AcceptLanguage format.");  
+                  "Could not convert the system process locale into a valid AcceptLanguage format.");
           Logger::put(Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE,
-                             e.getMessage()); 
+                             e.getMessage());
     }
-    
-    
+
+
 
 #ifdef PEGASUS_OS_OS400
     // Special server initialization code for OS/400.
@@ -837,23 +875,23 @@ MessageLoader::_useProcessLocale = false;
     // do some logging here!
     //l10n
     //Logger::put(Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE,
-            //"CIM Server failed to initialize"); 
+            //"CIM Server failed to initialize");
     Logger::put_l(Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE,
                   "src.Server.cimserver.SERVER_FAILED_TO_INITIALIZE",
-                  "CIM Server failed to initialize");  
+                  "CIM Server failed to initialize");
     return(-1);
-    } 
+    }
 #endif
 
 
 #if defined(PEGASUS_OS_HPUX) || defined(PEGASUS_PLATFORM_LINUX_GENERIC_GNU) \
 || defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM) || defined(PEGASUS_OS_AIX) \
-|| defined(PEGASUS_PLATFORM_SOLARIS_SPARC_CC) || defined (PEGASUS_OS_VMS)
+|| defined(PEGASUS_OS_SOLARIS) || defined (PEGASUS_OS_VMS)
     umask(S_IWGRP|S_IWOTH);
 
     //
     // check if CIMServer is already running
-    // if CIMServer is already running, print message and 
+    // if CIMServer is already running, print message and
     // notify parent process (if there is a parent process) to terminate
     //
     if(_cimListenerProcess->isCIMServerRunning())
@@ -873,7 +911,7 @@ MessageLoader::_useProcessLocale = false;
 
         return(1);
     }
-     
+
 #endif
 
     // try loop to bind the address, and run the server
@@ -887,7 +925,7 @@ MessageLoader::_useProcessLocale = false;
                                            consumerConfigDir,
                                            enableConsumerUnload,
                                            consumerIdleTimeout,
-                                           shutdownTimeout); 
+                                           shutdownTimeout);
 
         _cimListener->start();
 
@@ -895,10 +933,9 @@ MessageLoader::_useProcessLocale = false;
                 "src.Server.cimserver.LISTENING_ON_PORT",
                 "Listening on port $0.", listenerPort);
 
-        
+
 
 #if defined(PEGASUS_DEBUG)
-        //ATTN: Use MessageLoaderParms
         //Log startup options
         printf("Starting CIMListener with the following options\n");
         printf("\tlistenerPort %d\n", listenerPort);
@@ -913,9 +950,10 @@ MessageLoader::_useProcessLocale = false;
         printf("\ttraceFilePath %s\n", (const char*)traceFile.getCString());
         printf("\ttraceLevel %d\n", traceLevel);
         printf("\ttraceComponents %s\n", (const char*)traceComponents.getCString());
+               printf("\tMessage home is %s\n", (const char*)msgHome.getCString());
 #endif
 
-    // notify parent process (if there is a parent process) to terminate 
+    // notify parent process (if there is a parent process) to terminate
         // so user knows that there is cimserver ready to serve CIM requests.
     if (daemonOption)
         _cimListenerProcess->notify_parent(0);
@@ -923,7 +961,7 @@ MessageLoader::_useProcessLocale = false;
     time_t last = 0;
 
 #if defined(PEGASUS_OS_HPUX) || defined(PEGASUS_OS_LINUX) || defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM) \
-    || defined(PEGASUS_OS_AIX) || defined(PEGASUS_PLATFORM_SOLARIS_SPARC_CC) \
+    || defined(PEGASUS_OS_AIX) || defined(PEGASUS_OS_SOLARIS) \
     || defined(PEGASUS_OS_VMS)
         //
         // create a file to indicate that the cimserver has started and
@@ -946,7 +984,7 @@ MessageLoader::_useProcessLocale = false;
 //#if defined(PEGASUS_DEBUG)
     cout << "Started. " << endl;
 //#endif
-    
+
         // Put server started message to the logger
         Logger::put_l(Logger::STANDARD_LOG, System::CIMSERVER,
             Logger::INFORMATION,
@@ -954,36 +992,58 @@ MessageLoader::_useProcessLocale = false;
             "Started $0 version $1.",
             _cimListenerProcess->getProductName(), _cimListenerProcess->getVersion());
 
+#if defined(PEGASUS_OS_TYPE_UNIX)
+        if (daemonOption && !debugOutputOption)
+        {
+            // Direct standard input, output, and error to /dev/null,
+            // since we are running as a daemon.
+            close(0);
+            open("/dev/null", O_RDONLY);
+            close(1);
+            open("/dev/null", O_RDWR);
+            close(2);
+            open("/dev/null", O_RDWR);
+        }
+#endif
+
 #if !defined(PEGASUS_OS_TYPE_WINDOWS)
 
+// if signals are defined, do not use old file creation mechanism
+#ifndef PEGASUS_HAS_SIGNALS
+#if defined(PEGASUS_DEBUG)
         printf("Blocking until shutdown signal\n");
+#endif
         while (true)
         {
             if (FileSystem::exists(LISTENER_STOP_FILE))
             {
                 break;
-            } 
+            }
 
             pegasus_sleep(500);
         }
 
+#if defined(PEGASUS_DEBUG)
         printf("Received signal to shutdown\n");
+#endif
         FileSystem::removeFile(LISTENER_STOP_FILE);
         _cimListener->stop();
-        
+#else // defined(PEGASUS_HAS_SIGNALS)
 
-        //Uncomment this block of code when signals are implemented on all platforms.
         //Temporary workaround is to use a file, as specified above.
         //wait until signalled to terminate
-        /*int sig = _cimListenerProcess->cimserver_wait();
+        int sig = _cimListenerProcess->cimserver_wait();
+#if defined(PEGASUS_DEBUG)
         printf("Returned from sigwait %d\n", sig);
-
-        if (sig == SIGUSR1)
+#endif
+        if ((sig == PEGASUS_SIGTERM) || (sig == PEGASUS_SIGHUP))
         {
+#if defined(PEGASUS_DEBUG)
             printf("Graceful shutdown\n");
+#endif            
             _cimListener->stop();
         }
-        */
+#endif
 #else
         //ATTN: Implement cimserver_wait for windows so we don't have to loop here
         //The listener is stopped in the cimserver_stop method by the service control manager
@@ -998,7 +1058,9 @@ MessageLoader::_useProcessLocale = false;
         }
 #endif
 
+#if defined(PEGASUS_DEBUG)
     PEGASUS_STD(cout) << "Stopped\n";
+#endif
 
         //
         // normal termination
@@ -1011,9 +1073,9 @@ MessageLoader::_useProcessLocale = false;
 
 #if defined(PEGASUS_OS_HPUX) || defined(PEGASUS_PLATFORM_LINUX_GENERIC_GNU) \
 || defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM) || defined(PEGASUS_OS_AIX) \
-|| defined(PEGASUS_PLATFORM_SOLARIS_SPARC_CC) || defined(PEGASUS_OS_VMS)
+|| defined(PEGASUS_OS_SOLARIS) || defined(PEGASUS_OS_VMS)
         //
-        // close the file created at startup time to indicate that the 
+        // close the file created at startup time to indicate that the
         // cimserver has terminated normally.
         //
         FileSystem::removeFile(_cimListenerProcess->getPIDFileName());
@@ -1024,10 +1086,10 @@ MessageLoader::_useProcessLocale = false;
 
     //l10n
     //Logger::put(Logger::STANDARD_LOG, System::CIMSERVER, Logger::WARNING,
-            //"Error: $0", e.getMessage()); 
+            //"Error: $0", e.getMessage());
     Logger::put_l(Logger::STANDARD_LOG, System::CIMSERVER, Logger::WARNING,
             "src.Server.cimserver.ERROR",
-            "Error: $0", e.getMessage());  
+            "Error: $0", e.getMessage());
 
 #ifndef PEGASUS_OS_OS400
     //l10n
@@ -1059,7 +1121,9 @@ MessageLoader::_useProcessLocale = false;
         _cimListener = 0;
     }
 
+#if defined(PEGASUS_DEBUG)
     printf("Exiting child process\n");
+#endif
 
     return 0;
 }