BUG#: 4173
authorjim.wunderlich <jim.wunderlich>
Fri, 21 Oct 2005 21:24:13 +0000 (21:24 +0000)
committerjim.wunderlich <jim.wunderlich>
Fri, 21 Oct 2005 21:24:13 +0000 (21:24 +0000)
TITLE: ManagedSystem_stub.cpp  causes poststarttests to fail on Solaris

DESCRIPTION: Implemented OperatingSystem_Solaris.cpp and the test
             OSTestClient_Solaris.cpp.

src/Providers/ManagedSystem/OperatingSystem/OperatingSystem.cpp
src/Providers/ManagedSystem/OperatingSystem/OperatingSystem_Solaris.cpp [new file with mode: 0644]
src/Providers/ManagedSystem/OperatingSystem/tests/OSTestClient/OSTestClient.cpp
src/Providers/ManagedSystem/OperatingSystem/tests/OSTestClient/OSTestClient_Solaris.cpp [new file with mode: 0644]

index 9be7a9b9394e17084ae6ba6b61549a4ea990ca8d..15d43cfe66940f367fba7e731c29765960e851b6 100644 (file)
@@ -33,6 +33,7 @@
 // Modified By:  Susan Campbell, Hewlett-Packard Company <scampbell@hp.com>
 //               k. v. le   <ikhanh@us.ibm.com>
 //              Sean Keenan, Hewlett-Packard Company (sean.keenan@hp.com)
+//              Jim Wunderlich (Jim_Wunderlich@prodigy.net)
 //
 //%/////////////////////////////////////////////////////////////////////////////
 #include "OperatingSystem.h"
@@ -49,6 +50,8 @@
 #include "OperatingSystem_DARWIN.cpp"
 #elif defined (PEGASUS_OS_VMS)
 # include "OperatingSystem_Vms.cpp"
+#elif defined (PEGASUS_OS_SOLARIS)
+# include "OperatingSystem_Solaris.cpp" 
 #else
 # include "OperatingSystem_Stub.cpp"
 #endif
diff --git a/src/Providers/ManagedSystem/OperatingSystem/OperatingSystem_Solaris.cpp b/src/Providers/ManagedSystem/OperatingSystem/OperatingSystem_Solaris.cpp
new file mode 100644 (file)
index 0000000..71c8cfe
--- /dev/null
@@ -0,0 +1,684 @@
+//%2005////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
+// Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
+// Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
+// 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.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+// 
+// THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
+// ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
+// "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
+// LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//==============================================================================
+//
+// Author: Jim Wunderlich <Jim_Wunderlich@prodigy.net>
+//
+// Modified By: 
+//
+///////////////////////////////////////////////////////////////////////////////
+
+
+#include <Pegasus/Common/Config.h>
+#include <Pegasus/Common/System.h>
+#include <Pegasus/Common/Logger.h>
+#include "OperatingSystemProvider.h"
+
+#include <iostream>
+#include <set>
+#include <sys/utsname.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <unistd.h>
+#include <time.h>
+#include <utmpx.h>
+#include <regex.h>
+#include <dirent.h>
+
+PEGASUS_USING_STD;
+
+#define OSP_DEBUG(X) // Logger::put(Logger::DEBUG_LOG, "Solaris OSProvider",Logger::INFORMATION, "$0", X)
+
+OperatingSystem::OperatingSystem(void)
+{
+}
+
+OperatingSystem::~OperatingSystem(void)
+{
+}
+
+
+/**
+   getName method of the Solaris implementation for the OS Provider
+
+   Calls uname() to get the operating system name.
+
+  */
+Boolean OperatingSystem::getName(String& osName)
+{
+    struct utsname  unameInfo;
+
+    // Call uname and check for any errors. 
+    if (uname(&unameInfo) < 0)
+    {
+       return false;
+    }
+
+    osName.assign(unameInfo.sysname);
+
+    return true;
+
+}
+
+/**
+   getUtilGetHostName method for the Solaris implementation of the OS Provider
+
+   Gets the name of the host system from gethostname and gethostbyname.
+
+  */
+
+static Boolean getUtilGetHostName(String& csName)
+{
+     char    hostName[PEGASUS_MAXHOSTNAMELEN + 1];
+     struct  hostent *he;
+
+     if (gethostname(hostName, sizeof(hostName)) != 0)
+     {
+         return false;
+     }
+     hostName[sizeof(hostName)-1] = 0;
+
+     // Now get the official hostname.  If this call fails then return
+     // the value from gethostname().
+
+     he=gethostbyname(hostName);
+     if (he)
+     {
+         strncpy(hostName, he->h_name, sizeof(hostName)-1);
+     }
+
+     csName.assign(hostName);
+
+     return true;
+}
+
+Boolean OperatingSystem::getCSName(String& csName)
+{
+    return getUtilGetHostName(csName);
+}
+
+/**
+   getCaption method for Solaris implementation of OS Provider
+
+   Uses uname system call and extracts information for the Caption.
+  */
+Boolean OperatingSystem::getCaption(String& caption)
+{
+
+   struct utsname     unameInfo;
+
+   // Call uname and check for any errors.
+   if (uname(&unameInfo) < 0)
+   {
+       return false;
+   }
+
+   // append in caption the information available from uname system call.
+   //     system name, release, version, machine and nodename.
+   caption.assign(unameInfo.sysname);
+   caption.append(" ");
+   caption.append(unameInfo.release);
+   // caption.append(" ");
+   // caption.append(unameInfo.version);
+   // caption.append(" ");
+   // caption.append(unameInfo.machine);
+   // caption.append(" ");
+   // caption.append(unameInfo.nodename);
+
+   return true;
+}
+
+Boolean OperatingSystem::getDescription(String& description)
+{
+
+   description.assign("This instance reflects the Operating System"
+        " on which the CIMOM is executing (as distinguished from instances"
+        " of other installed operating systems that could be run).");
+
+   return true;
+}
+
+/**
+   getInstallDate method for Solaris implementation of OS provider
+
+  */
+Boolean OperatingSystem::getInstallDate(CIMDateTime& installDate)
+{
+// ATTN: Need to determine how to get this on SunOS
+
+   return false;
+}
+
+/**
+   getStatus method for Solaris implementation of OS provider
+
+    */
+Boolean OperatingSystem::getStatus(String& status)
+{
+
+// ATTN: Need to determine how to get this on SunOS
+
+   status.assign("Unknown");
+
+   return true;
+}
+
+/**
+   getVersion method for Solaris implementation of OS provider
+
+   Uses uname system call and extracts the release and version
+   information (separated by a space).
+
+   Returns FALSE if uname call results in errors.
+   */
+Boolean OperatingSystem::getVersion(String& osVersion)
+{
+
+    struct utsname  unameInfo;
+
+    // Call uname and check for any errors. 
+
+    if (uname(&unameInfo) < 0)
+    {
+       return false;
+    }
+
+    osVersion.assign(unameInfo.release);
+
+   return true;
+
+}
+
+Boolean OperatingSystem::getOSType(Uint16& osType)
+{
+    // SunOS is the OS component of the packaged
+    // system called Solaris so return SunOS
+    // osType = Solaris;
+    osType = SunOS;
+    return true;
+}
+
+Boolean OperatingSystem::getOtherTypeDescription(String& otherTypeDescription)
+{
+
+    struct utsname  unameInfo;
+    char version[sizeof(unameInfo.release) + sizeof(unameInfo.version)];
+
+    // Call uname and check for any errors.
+
+    if (uname(&unameInfo) < 0)
+    {
+       return false;
+    }
+
+    sprintf(version, "%s %s", unameInfo.release, unameInfo.version);
+    otherTypeDescription.assign(version);
+
+    return true;
+}
+
+
+/**
+   getLastBootUpTime method for Solaris implementation of OS Provider
+
+   gets information from /proc/uptime file
+  */
+
+Boolean OperatingSystem::getLastBootUpTime(CIMDateTime& lastBootUpTime)
+{
+// ATTN: need to determine how to get this on SunOS
+
+return false;
+}
+
+/**
+   getLocalDateTime method for Solaris implementation of OS Provider
+
+   Currently calls time to get local time, should be changed to use
+   the CIMOM date time and be consistent across all time properties
+   (e.g., LastBootUpTime + SystemUpTime = LocalDateTime)
+  */
+
+Boolean OperatingSystem::getLocalDateTime(CIMDateTime& localDateTime)
+{
+   // Get the date and time from the system. 
+   localDateTime = CIMDateTime::getCurrentDateTime();
+   return true;
+}
+
+/**
+   getCurrentTimeZone method for Solaris implementation of OS Provider
+
+   Gets information from gettimeofday call and ensures sign follows
+   CIM standard.
+
+  */
+
+Boolean OperatingSystem::getCurrentTimeZone(Sint16& currentTimeZone)
+{
+    time_t systemTime;
+    struct tm tmval;
+
+    // Get the time from the system. 
+    systemTime = time(0);
+    localtime_r(&systemTime, &tmval);
+    currentTimeZone = - (Sint16) (timezone / 60);
+    if ((tmval.tm_isdst > 0) && daylight)
+    {
+        // ATTN: It is unclear how to determine the DST offset.  Assume 1 hour.
+        currentTimeZone += 60;
+    }
+
+    return true;
+}
+
+/**
+   getNumberOfLicensedUsers method for Solaris implementation of OS Provider 
+
+   Always returns 0 for unlimited
+  */
+Boolean OperatingSystem::getNumberOfLicensedUsers(Uint32& numberOfLicensedUsers)
+{
+// ATTN: need todetrmine how to get this on SunOS
+
+   // According to the MOF, if it's unlimited, use zero
+   numberOfLicensedUsers = 0;
+   return true;
+}
+
+/**
+   getNumberOfUsers method for Solaris implementation of OS Provider
+
+   Goes through the utents, counting the number of type USER_PROCESS
+  */
+
+Boolean OperatingSystem::getNumberOfUsers(Uint32& numberOfUsers)
+{
+    struct utmpx * utmpp;
+
+    numberOfUsers = 0;
+
+    while ((utmpp = getutxent()) != NULL)
+    {
+        if (utmpp->ut_type == USER_PROCESS)
+        {
+            numberOfUsers++;
+        }
+    }
+
+    endutxent();
+
+    return true;
+}
+
+/**
+   getNumberOfProcesses method for Solaris implementation of OS Provider
+
+   Counts the number of sub-directories of /proc that are of the format
+   to represent processes.
+  */
+Boolean OperatingSystem::getNumberOfProcesses(Uint32& numberOfProcesses)
+{
+// ATTN: ned to determine how to get this on SunOS
+
+   Uint32 count;
+   DIR *procdir;
+   struct dirent entry, *result;
+   regex_t process_pattern_compiled;
+   const char process_pattern[] = "^[1-9][0-9]*$";
+
+   count = 0;
+   if ((procdir = opendir("/proc")))
+   {
+      if (regcomp(&process_pattern_compiled, process_pattern, 0) == 0)
+      {
+         while (readdir_r(procdir, &entry, &result) == 0 && result != NULL)
+         {
+#if defined (PEGASUS_PLATFORM_LINUX_GENERIC_GNU) && !defined(PEGASUS_OS_LSB)
+            if (entry.d_type != DT_DIR)
+               continue;
+#endif
+            if (regexec(&process_pattern_compiled, entry.d_name,
+                        0, NULL, 0) == 0)
+               count++;
+         }
+         regfree(&process_pattern_compiled);
+      }
+      closedir(procdir);
+   }
+
+   numberOfProcesses = count;
+   return true;
+}
+
+/**
+   getMaxNumberOfProcesses method for Solaris implementation of OS Provider
+
+   gets information from /proc/sys/kernel/threads-max
+  */
+
+Boolean OperatingSystem::getMaxNumberOfProcesses(Uint32& mMaxProcesses)
+{
+// ATTN: Need to determine how to get this on Solaris
+
+  return false;
+}
+
+/**
+   getTotalSwapSpaceSize method for Soalris implementation of OS Provider
+
+  */
+Boolean OperatingSystem::getTotalSwapSpaceSize(Uint64& mTotalSwapSpaceSize)
+{
+// ATTN: Need to determine ow to get this on SunOS
+
+  return false;
+}
+
+/** _totalVM method for Solaris implementation of OS Provider
+
+    Calculates TotalVirtualMemory as the sum of totalSwap
+    and totalMem.
+*/
+Uint64 OperatingSystem::_totalVM()
+{
+  Uint64 total;
+  Uint64 tmp;
+
+  total = 0;
+  if( getTotalSwapSpaceSize(tmp) )
+  {
+    total += tmp;
+  }
+  if( getTotalVisibleMemorySize(tmp))
+  {
+    total += tmp;
+  }
+  return total;
+}
+
+/**
+   getTotalVirtualMemorySize method for Soalris implementation of OS Provider
+
+   Gets information from SwapTotal in /proc/meminfo
+  */
+Boolean OperatingSystem::getTotalVirtualMemorySize(Uint64& total)
+{
+    total = _totalVM();
+    if (total) return true;
+    else return false;   // possible that we had trouble with file
+}
+
+/**
+   getFreeVirtualMemorySize method for Solaris implementation of OS Provider
+
+   Gets information from SwapFree in /proc/meminfo
+  */
+Boolean OperatingSystem::getFreeVirtualMemory(Uint64& freeVirtualMemory)
+{
+// ATTN: Need to determine how to get this on SunOS
+
+  return false;
+}
+
+/**
+   getFreePhysicalMemory method for Solaris implementation of OS Provider
+
+   Gets information from MemFree in /proc/meminfo
+  */
+Boolean OperatingSystem::getFreePhysicalMemory(Uint64& total)
+{
+// ATTN: Need to determine how to get thison SunOS
+
+  return false;
+}
+
+/**
+   getTotalVisibleMemorySize method for Solaris implementation of OS Provider
+
+   Was returning FreePhysical - correct? diabled it.
+  */
+Boolean OperatingSystem::getTotalVisibleMemorySize(Uint64& memory)
+{
+// ATTN: Need to determin how to get this on SunOS
+
+  return false;
+}
+
+/**
+   getSizeStoredInPagingFiles method for Solaris implementation of OS Provider
+
+   Was returning TotalSwap - correct? diabled it.
+  */
+Boolean OperatingSystem::getSizeStoredInPagingFiles(Uint64& total)
+{
+    return false;
+}
+
+/**
+   getFreeSpaceInPagingFiles method for Solaris implementation of OS Provider
+
+   Was returning TotalVirtualMemory - correct? diabled it.
+  */
+Boolean OperatingSystem::getFreeSpaceInPagingFiles(
+                                              Uint64& freeSpaceInPagingFiles)
+{
+    return false;
+}
+/**
+   getMaxProcessMemorySize method for Solaris implementation of OS Provider
+
+   Gets information from /proc/sys/vm/overcommit_memoryt or returns
+   TotalVirtualMemory
+   */
+Boolean OperatingSystem::getMaxProcessMemorySize(Uint64& maxProcessMemorySize)
+{
+// ATTN: Need to determine how to get this for SunOS
+
+  return false;
+}
+
+ /**
+   getDistributed method for Solaris implementation of OS Provider
+
+   Always sets the distributed boolean to FALSE
+  */
+Boolean OperatingSystem::getDistributed(Boolean& distributed)
+{
+    distributed = false;
+    return true;
+}
+
+/**
+   getMaxProcsPerUser method for Solaris implementation of OS Provider
+
+   Retrieves the _SC_CHILD_MAX value from sysconf.
+  */
+Boolean OperatingSystem::getMaxProcsPerUser (Uint32& maxProcsPerUser)
+{
+// ATTN: Need to determine how to get this on SunOS
+
+    return false;
+}
+
+/**
+   getSystemUpTime method for Solaris implementation of OS Provider
+
+   Gets information from /proc/uptime (already in seconds).
+  */
+Boolean OperatingSystem::getSystemUpTime(Uint64& mUpTime)
+{
+// ATTN: Need to determine how to get this on SunOS
+
+   return false;
+}
+
+/**
+   getOperatingSystemCapability handles a Pegasus extension of the DMTF defined
+   CIM_Operating System. This attribute is defined as a string either "64 bit"
+   or "32 bit". On the Solaris side we will determine that by measuring 
+   the number
+   of bytes allocated for pointers because this implementation will change
+   based on the underlying processor architecture. 32-bit 64-bit... 128-bit
+  */
+
+Boolean OperatingSystem::getOperatingSystemCapability(String& scapability)
+{
+    char capability[80];
+    void *ptr;
+    int ptr_bits;
+
+    ptr_bits = 8*sizeof(ptr);
+
+    sprintf (capability, "%d bit", ptr_bits);
+
+    scapability.assign(capability);
+    return true;
+}
+
+/**
+   _reboot method for Solaris implementation of OS Provider
+
+   Finds executable in /sbin, /usr/bin, or /usr/local/sbin and invokes.
+
+   Invokes as via system system call, so have full checking of user's
+   authorization (already authenticated by CIMOM)
+
+   Don't we want to do some additional cleanup before actually
+   invoking the reboot command?  For example, we know the CIMOM is up
+   and running.  Perhaps set the OS state to 'Stopping' and do a
+   graceful shutdown of the CIMOM (at least)?
+
+   */
+Uint32 OperatingSystem::_reboot()
+{
+/*
+******************************************************
+ATTN: At the time of implementation the Provider Manager will not call 
+this function. The code is defined out becasue it is not clear that all
+users would want this supportted. If it were to be supported then at a 
+minimum the user must be athenticated or the code should run switch and 
+run on behalf of the caller rather than as the CIMOM and then let the
+system validate the users credentials and permissions to determine if
+the calling user has the authority to invoke a shutdown or a reboot.  
+******************************************************
+*/
+
+   return false;
+
+#ifdef NOTDEF
+   const char *reboot[] = { "reboot", NULL };
+   const char *paths[] = { "/sbin", "/usr/sbin", "/usr/local/sbin", NULL };
+   struct stat sbuf;
+   String fname;
+   CString p;
+   Uint32 result;
+
+   result = 1;
+   for (int ii = 0; paths[ii] != NULL; ii++)
+   {
+      for (int jj = 0; reboot[jj]; jj++)
+      {
+         fname = paths[ii];
+         fname.append("/");
+         fname.append(reboot[jj]);
+         p = fname.getCString();
+         if (stat(p, &sbuf) == 0 && (sbuf.st_mode & S_IXUSR))
+         {
+            result = 2;
+            if (system(p) == 0)
+               result = 0;
+
+            return result;
+         }
+      }
+   }
+   return result;
+#endif // NOTDEF
+}
+/**
+   _shutdown method for Solaris implementation of OS Provider
+
+   Finds executable in /sbin, /usr/bin, or /usr/local/sbin and invokes.
+
+   Don't we want to add some more cleanup - especially since we know
+   the CIMOM is running - this could cause things to be set into a
+   'Stopping' state while the OS cleans up before actually invoking
+   the poweroff command.
+   */
+Uint32 OperatingSystem::_shutdown()
+{
+/*
+******************************************************
+ATTN: At the time of implementation the Provider Manager will not call 
+this function. The code is defined out becasue it is not clear that all
+users would want this supportted. If it were to be supported then at a 
+minimum the user must be athenticated or the code should run switch and 
+run on behalf of the caller rather than as the CIMOM and then let the
+system validate the users credentials and permissions to determine if
+the calling user has the authority to invoke a shutdown or a reboot.  
+******************************************************
+*/
+
+   return false;
+#ifdef NOTDEF
+   const char *poweroff[] = { "poweroff", NULL };
+   const char *paths[] = { "/sbin", "/usr/sbin", "/usr/local/sbin", NULL };
+   struct stat sbuf;
+   String fname;
+   CString p;
+   Uint32 result;
+
+   result = 1;
+   for (int ii = 0; paths[ii] != NULL; ii++)
+   {
+      for (int jj = 0; poweroff[jj]; jj++)
+      {
+         fname = paths[ii];
+         fname.append("/");
+         fname.append(poweroff[jj]);
+         p = fname.getCString();
+         if (stat(p, &sbuf) == 0 && (sbuf.st_mode & S_IXUSR))
+         {
+            result = 2;
+            if (system(p) == 0)
+               result = 0;
+
+            return result;
+         }
+      }
+   }
+   return result;
+#endif //NOTDEF
+}
+
index b7c371307b927b6adcc5a128a34347a4edf71c6c..ebebabfaf580582c2063a45ceaa2741d0913edcd 100644 (file)
 // include the appropriate OS-specific file for checking results
 #if defined (PEGASUS_PLATFORM_HPUX_ACC)
 # include "OSTestClient_HPUX.cpp"
-#else
-# if defined (PEGASUS_OS_VMS)
+#elif defined (PEGASUS_OS_VMS)
 #  include "OSTestClient_VMS.cpp"
+#elif defined (PEGASUS_OS_SOLARIS)
+#  include "OSTestClient_Solaris.cpp"
 # else
 #  include "OSTestClient_Stub.cpp"
-# endif
 #endif
 
 PEGASUS_USING_PEGASUS;
diff --git a/src/Providers/ManagedSystem/OperatingSystem/tests/OSTestClient/OSTestClient_Solaris.cpp b/src/Providers/ManagedSystem/OperatingSystem/tests/OSTestClient/OSTestClient_Solaris.cpp
new file mode 100644 (file)
index 0000000..b070557
--- /dev/null
@@ -0,0 +1,675 @@
+//%2005////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
+// Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
+// Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
+// 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.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+// 
+// THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
+// ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
+// "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
+// LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//==============================================================================
+//
+// Author: Jim Wunderlich (Jim_Wunderlich@prodigy.net)
+//
+// Modified By:  
+//
+//%/////////////////////////////////////////////////////////////////////////////
+
+
+// This file has the OS-specific routines that will be called to get
+// a validation of the CIM information vs. the current test system
+
+#include "OSTestClient.h"
+#include <sys/param.h>      // for MAXHOSTNAMELEN
+#include <sys/utsname.h>    // for uname
+#include <unistd.h>         // for gethostname
+#include <sys/socket.h>     // for gethostbyname
+#include <netinet/in.h>     // for gethostbyname
+#include <netdb.h>          // for gethostbyname
+#include <utmpx.h>          // for utxent calls
+
+/**
+   goodCSCreationClassName method for the OS Provider Test Client
+
+   Checks the specified value against the expected value and
+   returns TRUE if the same, else FALSE
+ */
+Boolean OSTestClient::goodCSCreationClassName(const String &cs_ccn, 
+                                              Boolean verbose)
+{
+   if (verbose)
+      cout<<"Checking " <<cs_ccn<< " against CIM_UnitaryComputerSystem"<<endl;
+   return (String::equalNoCase(cs_ccn, "CIM_UnitaryComputerSystem"));
+}
+
+/*
+   GoodCSName method for the OS Provider Test Client
+
+   Checks the specified value against the expected value and
+   returns TRUE if the same, else FALSE
+ */
+Boolean OSTestClient::goodCSName(const String &csname, Boolean verbose)
+{
+   struct hostent *he;
+   char hostName[PEGASUS_MAXHOSTNAMELEN + 1];
+
+   if (verbose)
+      cout<<"Checking " <<csname<< " against hostname" <<endl;
+
+   // try and get fully qualified hostname, else just system name
+   if (gethostname(hostName, sizeof(hostName)) != 0)
+   {
+      return false;  // if can't get data to validate, fail
+   }
+   hostName[sizeof(hostName)-1] = 0;
+
+   if (he = gethostbyname(hostName))
+   {
+      strncpy(hostName, he->h_name, sizeof(hostName)-1);
+   }
+
+   if (verbose)
+       cout << " Host name should be " << hostName << endl;
+
+   return (String::equalNoCase(csname, hostName));
+}
+
+/*
+   GoodCreationClassName method for the OS Provider Test Client
+
+   Checks the specified value against the expected value and
+   returns TRUE if the same, else FALSE
+ */
+Boolean OSTestClient::goodCreationClassName(const String &ccn, 
+                                            Boolean verbose)
+{
+   if (verbose)
+      cout<<"Checking " << ccn << " against CIM_OperatingSystem"<<endl;
+   return (String::equalNoCase(ccn, "CIM_OperatingSystem"));
+}
+
+/*
+   GoodName method for the OS Provider Test Client
+
+   Checks the specified value against the expected value and
+   returns TRUE if the same, else FALSE
+ */
+Boolean OSTestClient::goodName(const String &name, Boolean verbose)
+{
+    struct utsname  unameInfo;
+   
+    if (verbose)
+      cout<<"Checking " << name << " against OS name"<<endl;
+
+    // Call uname and check for any errors.
+    if (uname(&unameInfo) < 0)
+    {
+       return false;  // if can't get data to validate, fail
+    }
+
+    if (verbose)
+      cout<<" OS name should be " << unameInfo.sysname << endl;
+   
+    return (String::equalNoCase(name, unameInfo.sysname));   
+}
+
+/* GoodCaption method for the OS Provider Test Client 
+
+   Checks the specified value against the expected value 
+   and returns TRUE if the same, else FALSE 
+ */
+Boolean OSTestClient::goodCaption(const String &cap, 
+                                  Boolean verbose)
+{
+
+   struct utsname     unameInfo;
+   String _cap;
+
+   if (verbose)
+       cout<<"Checking Caption " << cap << endl;
+
+   // Call uname and check for any errors.
+   if (uname(&unameInfo) < 0)
+   {
+       return false;
+   }
+
+   // append in _cap the system name and release.
+   _cap.assign(unameInfo.sysname);
+   _cap.append(" ");
+   _cap.append(unameInfo.release);
+
+  if (verbose)
+       cout<<" Should be  " << _cap << endl;
+
+   return (String::equalNoCase(cap,_cap)); 
+}
+
+/*
+   GoodDescription method for the OS Provider Test Client
+
+   Checks the specified value against the expected value and
+   returns TRUE if the same, else FALSE
+ */
+Boolean OSTestClient::goodDescription(const String &desc, 
+                                      Boolean verbose)
+{
+   // has check against standard description
+   if (verbose)
+      cout<<"Checking Description " << desc << endl;
+   return (String::equalNoCase(desc,
+     "This instance reflects the Operating System on which the "
+     "CIMOM is executing (as distinguished from instances of "
+     "other installed operating systems that could be run)."));
+}
+
+/*
+   GoodInstallDate method for the OS Provider Test Client
+
+   Checks the specified value against the expected value and
+   returns TRUE if the same, else FALSE
+ */
+Boolean OSTestClient::goodInstallDate(const CIMDateTime &idate,
+                                      Boolean verbose)
+{
+   if (verbose)
+      cout<<"Checking InstallDate " << idate.toString() << endl;
+   return false;  // not implemented for SunOS, fail if there
+}
+
+/*
+   GoodStatus method for the OS Provider Test Client
+
+   Checks the specified value against the expected value and
+   returns TRUE if the same, else FALSE
+ */
+Boolean OSTestClient::goodStatus(const String &stat, 
+                                 Boolean verbose)
+{
+   if (verbose)
+      cout<<"Checking Status " << stat << " against Unknown" << endl;
+
+   // for now, SunOS provider always returns Unknown
+   return (String::equalNoCase(stat, "Unknown"));
+}
+
+/*
+   GoodOSType method for the OS Provider Test Client
+
+   Checks the specified value against the expected value and
+   returns TRUE if the same, else FALSE
+ */
+Boolean OSTestClient::goodOSType(const Uint16 &ostype,
+                                 Boolean verbose)
+{
+   if (verbose)
+      cout<<"Checking OSType " << ostype << " against SunOS=30" << endl;
+   return (ostype == 30);  
+}
+
+Boolean OSTestClient::goodOtherTypeDescription(const String &otdesc,
+                                               Boolean verbose)
+{
+   if (verbose)
+      cout<<"Checking OtherTypeDescription " << otdesc << endl;
+
+
+
+   struct utsname     unameInfo;
+   String otdesc_expected;
+
+   // Call uname and check for any errors.
+   if (uname(&unameInfo) < 0)
+   {
+       return false;
+   }
+
+   // append in _cap the system name and release.
+   otdesc_expected.assign(unameInfo.release);
+   otdesc_expected.append(" ");
+   otdesc_expected.append(unameInfo.version);
+
+  if (verbose)
+       cout<<" Should be  " << otdesc_expected << endl;
+
+   return (String::equalNoCase(otdesc, otdesc_expected));
+
+}
+
+Boolean OSTestClient::goodVersion(const String &version, Boolean verbose)
+{
+   struct utsname  unameInfo;
+
+   if (verbose)
+     cout<<"Checking Version " << version << endl;
+
+   // Call uname and check for any errors.
+   if (uname(&unameInfo) < 0)
+   {
+      return false;
+   }
+
+   if (verbose)
+     cout<<" Should be  " << unameInfo.release << endl;
+
+   return (String::equalNoCase(version,unameInfo.release));
+}
+
+
+/**
+   goodLastBootUpTime method for SunOS implementation of OS Provider
+
+   Gets information from pstat call.  Internally in UTC (Universal
+   Time Code) which must be converted to localtime for CIM
+  */                
+Boolean OSTestClient::goodLastBootUpTime(const CIMDateTime &btime,
+                                        Boolean verbose)
+{
+   if (verbose)
+      cout<<"Checking LastBootUpTime " << btime.toString() << endl;
+   cout<<"- No check written for LastBootUpTime " << endl;
+   return true;
+
+}
+
+/**
+   goodLocalDateTime method of SunOS OS Provider Test Client
+
+   Uses the CIMOM getCurrentDateTime function and checks that the
+   current time from the instance is within one hour of that time.
+  */
+Boolean OSTestClient::goodLocalDateTime(const CIMDateTime &ltime,
+                                       Boolean verbose)
+{
+   if (verbose)
+      cout<<"Checking LocalDateTime " << ltime.toString() << endl;
+
+   CIMDateTime currentDT = CIMDateTime::getCurrentDateTime();
+
+   Sint64 raw_delta;
+   try
+   {
+       raw_delta = CIMDateTime::getDifference(ltime, currentDT);
+   }
+   catch(DateTimeOutOfRangeException &e)
+   {
+       cout << "Error : " << e.getMessage() << endl;
+       exit;
+   }
+   Uint64 delta = labs(raw_delta);
+   
+   if (verbose) {
+      cout<<" Should be close to " << currentDT.toString() << endl;
+      printf( " Delta should be within 360 seconds, is %lld\n",delta);
+      fflush(stdout);
+   }
+   // arbitrary choice of expecting them to be within 360 seconds
+   return (delta < 360000000);   
+}
+
+/**
+   goodCurrentTimeZone method of SunOS OS Provider Test Client 
+
+   Expect the timezone now to be identical to that returned.
+  */
+Boolean OSTestClient::goodCurrentTimeZone(const Sint16 &tz, Boolean verbose)
+{
+   if (verbose)
+      cout<<"Checking CurrentTimeZone " << tz << endl;
+  
+   CIMDateTime currentDT = CIMDateTime::getCurrentDateTime();
+   String ds = currentDT.toString();  // want timezone
+
+   // cheat here since we know the position of the timezone info
+   // subtracting '0' gets us the number from the ASCII, while 
+   // the multiplies do our shifts and we use the sign appropriately
+   Sint32 calctz = ((ds[22]-'0') * 100 +
+                    (ds[23]-'0') * 10 +
+                    (ds[24]-'0')) *
+                    (ds[21]=='-'?-1:1);
+
+   if (verbose) 
+      cout << " Should be " << calctz << endl;
+   
+   return (tz == calctz);
+}
+
+/**
+   goodNumberOfLicensedUsers method for SunOS implementation of OS provider
+
+   Calls uname and checks the version string (to get user license
+   information.  This version field doesn't currently distinguish
+   between 128, 256, and unlimited user licensed (all = U).
+   Need to determine how to differentiate and fix this, for now return
+   0 (which is unlimited).  Don't know if uname -l has same limitation.
+  */       
+Boolean OSTestClient::goodNumberOfLicensedUsers(const Uint32 &nlusers,
+                                               Boolean verbose)
+{
+    Uint32 numberOfLicensedUsers=0;
+
+    if (verbose)
+      cout<<"Checking NumberOfLicensedUsers " << nlusers << endl;
+   
+    if (verbose)
+      cout<<" Should be " << numberOfLicensedUsers << endl;
+
+   return (nlusers == numberOfLicensedUsers);   
+}
+
+/**
+   goodNumberOfUsers method for SunOS implementation of OS Provider
+
+   Goes through the utents, counting the number of type USER_PROCESS
+   Works in isolated test env without new users logging in
+  */      
+Boolean OSTestClient::goodNumberOfUsers(const Uint32 &nusers,
+                                       Boolean verbose)
+{
+   struct utmpx * utmpp;
+   Uint32 numberOfUsers;
+
+   if (verbose)
+      cout<<"Checking NumberOfUsers " << nusers << endl;
+
+   numberOfUsers = 0;
+
+// ATTN-SLC-P3-17-Apr-02: optimization? parse uptime instead?
+
+   while ((utmpp = getutxent()) != NULL)
+   {
+       if (utmpp->ut_type == USER_PROCESS)
+       {
+           numberOfUsers++;
+       }
+   }
+
+   endutxent();  
+   if (verbose)
+      cout << " Should be " << numberOfUsers << endl;
+
+// works in isolated test env without new users logging in
+   return (nusers == numberOfUsers);   
+}
+
+/**
+   goodNumberOfProcesses method for SunOS implementation of OS Provider
+
+   Gets number of active processes from pstat.
+  */         
+Boolean OSTestClient::goodNumberOfProcesses(const Uint32 &nprocs,
+                                           Boolean verbose)
+{
+   if (verbose)
+      cout<<"Checking NumberOfProcesses " << nprocs << endl;
+   cout<<"- No check written for NumberOfProcesses " << endl;
+   return true;
+}
+
+/**
+   goodMaxNumberOfProcesses method for SunOS implementation of OS Provider
+
+   Gets maximum number of processes from pstat.
+  */             
+Boolean OSTestClient::goodMaxNumberOfProcesses(const Uint32 &maxprocs,
+                                              Boolean verbose)
+{
+   if (verbose)
+      cout<<"Checking MaxNumberOfProcs " << maxprocs << endl;
+   cout<<"- No check written for MaxNumberOfProcesses " << endl;
+   return true;
+
+}
+
+/**
+   _totalVM method for SunOS implementation of OS Provider
+
+   Gets information from swapinfo -q command (already in KB).
+   Invoked for TotalVirtualMemory as well as TotalSwapSpaceSize.
+   Would be more efficient to get this only once.
+  */ 
+static Uint64 _totalVM()
+{
+    char               mline[80];
+    FILE             * mswapInfo;
+    Uint32             swapSize;
+
+    // Initialize the return parameter in case swapinfo is not available.
+    swapSize = 0;
+
+    // Use a pipe to invoke swapinfo.
+    if ((mswapInfo = popen("/usr/sbin/swapinfo -q 2>/dev/null", "r")) != NULL)
+    {
+        // Now extract the total swap space size from the swapinfo output.
+        while (fgets(mline, 80, mswapInfo))
+        {
+           sscanf(mline, "%d", &swapSize);
+        }  // end while
+
+        (void)pclose (mswapInfo);
+    }
+    return Uint64(swapSize);
+}
+/**
+   goodTotalSwapSpaceSize method for SunOS implementation of OS Provider
+
+   Gets information from swapinfo -q command (techically not swap
+   space, it's paging).   No formal paging files, report as swap.
+
+  */     
+Boolean OSTestClient::goodTotalSwapSpaceSize(const Uint64 &totalswap,
+                                            Boolean verbose)
+{
+   Uint64 mTotalSwapSpaceSize = 0;
+
+   if (verbose) 
+   {
+      printf("Checking TotalSwapSpaceSize %lld\n", totalswap);
+      fflush(stdout);
+   }
+
+   mTotalSwapSpaceSize = _totalVM();
+   if (mTotalSwapSpaceSize == 0)
+      return false;
+
+   if (verbose)
+   {
+      printf(" Should be %lld\n", mTotalSwapSpaceSize);
+      fflush(stdout);
+   }
+   return (totalswap == mTotalSwapSpaceSize);
+}
+
+/**
+   getTotalVirtualMemorySize method for SunOS implementation of OS Provider
+
+   Gets information from swapinfo -q command (techically not swap
+   space, it's paging).  Same as the information returned for
+   TotalSwapSpace.
+
+  */    
+Boolean OSTestClient::goodTotalVirtualMemorySize(const Uint64 &totalvmem,
+                                                Boolean verbose)
+{
+   if (verbose)
+      cout<<"Checking TotalVirtualMemorySize "<<Uint32(totalvmem)<<endl;
+  
+   Uint64 totalVMem = _totalVM();
+
+   if (verbose)
+      cout<<" Should be " << Uint32(totalVMem) << endl;
+   return (totalvmem == totalVMem);  // will return false if totalVMem=0   
+}
+
+/**
+   goodFreeVirtualMemorySize method for SunOS implementation of OS Provider
+
+   Gets information from swapinfo -at command (the Free column)
+  */  
+Boolean OSTestClient::goodFreeVirtualMemory(const Uint64 &freevmem,
+                                           Boolean verbose)
+{
+   char               mline[80];
+   FILE             * mswapInfo;
+   Uint32             swapAvailable;
+   Uint32             swapUsed;
+   Uint32             swapFree;  
+   
+   if (verbose)
+      cout<<"Checking FreeVirtualMemory "<< Uint32(freevmem) << endl;
+
+   swapFree = 0;
+
+   // Use a pipe to invoke swapinfo.
+   if ((mswapInfo = popen("/usr/sbin/swapinfo -at 2>/dev/null", "r")) != NULL)
+   {
+      // Now extract the total swap space size from the swapinfo output
+      while (fgets(mline, 80, mswapInfo))
+      {
+          sscanf(mline, "total %u %u %u", &swapAvailable,
+                &swapUsed, &swapFree);
+      }  // end while
+
+      (void)pclose (mswapInfo);
+   }
+   if (verbose)
+      cout<<" Should be close to " << swapFree << endl;
+
+   Sint64 raw_delta = freevmem - Uint64(swapFree);
+   Uint64 delta = labs(raw_delta);
+
+   if (verbose)
+   {
+      printf (" Delta should be within 65536, is %lld\n", delta); 
+      fflush(stdout);
+   }
+
+   // arbitrary choice of valid delta - typically ran within 
+   // 2048, but with many client connections, went as high as 
+   // 36,000+.  Thus chose 2^16 = 65536 (still helps weed out
+   // garbage values).
+   return (delta < 65536 );   
+}
+
+/**
+   goodFreePhysicalMemory method for SunOS implementation of
+   OS Provider Test Client. 
+
+  */     
+Boolean OSTestClient::goodFreePhysicalMemory(const Uint64 &freepmem,
+                                            Boolean verbose)
+{
+   if (verbose)
+      cout<<"Checking FreePhysicalMemory " << endl;
+   cout<<"- No check written for FreePhysicalMemory" << endl;
+   return true;
+}
+
+/**
+   goodTotalVisibleMemorySize method for SunOS implementation of 
+   OS Provider Test Client.
+
+   Gets information from pstat (pst.physical_memory adjusted for
+   the page size.
+   */
+Boolean OSTestClient::goodTotalVisibleMemorySize(const Uint64 &totalvmem,
+                                                Boolean verbose)
+{
+   if (verbose)
+      cout<<"Checking TotalVisibleMemorySize " << endl;
+   cout<<"- No check written for TotalVisibleMemorySize" << endl;
+   return true;
+}
+
+Boolean OSTestClient::goodSizeStoredInPagingFiles(const Uint64 &pgsize,
+                                                 Boolean verbose)
+{
+   if (verbose)
+      cout<<"Checking SizeStoredInPagingFiles " << endl;
+   cout<<"- No check written for SizeStoredInPagingFiles" << endl;
+   return true;
+}
+
+Boolean OSTestClient::goodFreeSpaceInPagingFiles(const Uint64 &freepg,
+                                                Boolean verbose)
+{
+   if (verbose)
+      cout<<"Checking FreeSpaceInPagingFiles " << endl;
+   cout<<"- No check written for FreeSpaceInPagingFiles" << endl;
+   return true;
+}
+
+
+/**
+   goodMaxProcessMemorySize method for Solaris implementation of OS Provider
+
+   */   
+Boolean OSTestClient::goodMaxProcessMemorySize(const Uint64 &maxpmem,
+                                              Boolean verbose)
+{
+   if (verbose)
+      cout<<"Checking MaxProcessMemSize " << endl;
+   cout<<"- No check written for MaxProcessMemSize " << endl;
+   return true;
+}
+
+Boolean OSTestClient::goodDistributed(const Boolean &distr,
+                                     Boolean verbose)
+{
+   if (verbose)
+      cout<<"Checking Distributed against FALSE" << endl;
+   return (distr == false);  // Solaris always false   
+}
+
+/**
+   goodMaxProcessesPerUser method for Solaris implementation of OS Provider
+
+  */
+Boolean OSTestClient::goodMaxProcessesPerUser (const Uint32& umaxproc,
+                                              Boolean verbose)
+{
+   if (verbose)
+      cout<<"Checking MaxProcsPerUser " << umaxproc << endl;
+   cout<<"- No check written for MaxProcsPerUser " << endl;
+   return true;
+}
+
+Boolean OSTestClient::goodOSCapability(const String &cap, Boolean verbose)
+{
+   if (verbose)
+      cout<<"Checking OSCapability " << cap << endl;
+   cout<<"- No check written for OSCapability " << endl;
+   return true;
+}
+
+/**
+   goodSystemUpTime method of Solaris OS Provider Test Client
+
+  */
+Boolean OSTestClient::goodSystemUpTime(const Uint64 &uptime, Boolean verbose)
+{
+   if (verbose)
+      cout<<"Checking SystemUpTime " << endl;
+   cout<<"- No check written for SystemUpTime " << endl;
+   return true;
+}
+