in source/code/scxsystemlib/common/scxostypeinfo.cpp [305:600]
void SCXOSTypeInfo::Init() // private
{
m_osVersion = L"";
m_osName = L"Unknown";
assert(m_unameIsValid);
#if defined(hpux) || defined(sun)
if (m_unameIsValid)
{
m_osName = StrFromUTF8(m_unameInfo.sysname);
m_osVersion = StrFromUTF8(m_unameInfo.release);
}
#if defined(hpux)
m_osAlias = L"HPUX";
m_osManufacturer = L"Hewlett-Packard Company";
#elif defined(sun)
m_osAlias = L"Solaris";
m_osManufacturer = L"Oracle Corporation";
#endif
#elif defined(aix)
if (m_unameIsValid)
{
m_osName = StrFromUTF8(m_unameInfo.sysname);
// To get "5.3" we must read "5" and "3" from different fields.
string ver(m_unameInfo.version);
ver.append(".");
ver.append(m_unameInfo.release);
m_osVersion = StrFromUTF8(ver);
}
m_osAlias = L"AIX";
m_osManufacturer = L"International Business Machines Corporation";
#elif defined(linux)
vector<wstring> lines;
SCXStream::NLFs nlfs;
#if defined(PF_DISTRO_SUSE)
static const string relFileName = "/etc/SuSE-release";
wifstream relfile(relFileName.c_str());
wstring version(L"");
wstring patchlevel(L"");
SCXStream::ReadAllLines(relfile, lines, nlfs);
if (!lines.empty()) {
m_osName = ExtractOSName(lines[0]);
}
// Set the Linux Caption (get first line of the /etc/SuSE-release file)
m_linuxDistroCaption = lines[0];
if (0 == m_linuxDistroCaption.length())
{
// Fallback - should not normally happen
m_linuxDistroCaption = L"SuSE";
}
// File contains one or more lines looking like this:
// SUSE Linux Enterprise Server 10 (i586)
// VERSION = 10
// PATCHLEVEL = 1
for (size_t i = 0; i<lines.size(); i++)
{
if (StrIsPrefix(StrTrim(lines[i]), L"VERSION", true))
{
wstring::size_type n = lines[i].find_first_of(L"=");
if (n != wstring::npos)
{
version = StrTrim(lines[i].substr(n+1));
}
}
else if (StrIsPrefix(StrTrim(lines[i]), L"PATCHLEVEL", true))
{
wstring::size_type n = lines[i].find_first_of(L"=");
if (n != wstring::npos)
{
patchlevel = StrTrim(lines[i].substr(n+1));
}
}
}
if (version.length() > 0)
{
m_osVersion = version;
if (patchlevel.length() > 0)
{
m_osVersion = version.append(L".").append(patchlevel);
}
}
if (std::wstring::npos != m_osName.find(L"Desktop"))
{
m_osAlias = L"SLED";
}
else
{ // Assume server.
m_osAlias = L"SLES";
}
m_osManufacturer = L"SUSE GmbH";
#elif defined(PF_DISTRO_REDHAT)
static const string relFileName = "/etc/redhat-release";
wifstream relfile(relFileName.c_str());
SCXStream::ReadAllLines(relfile, lines, nlfs);
if (!lines.empty()) {
m_osName = ExtractOSName(lines[0]);
}
// Set the Linux Caption (get first line of the /etc/redhat-release file)
m_linuxDistroCaption = lines[0];
if (0 == m_linuxDistroCaption.length())
{
// Fallback - should not normally happen
m_linuxDistroCaption = L"Red Hat";
}
// File should contain one line that looks like this:
// Red Hat Enterprise Linux Server release 5.1 (Tikanga)
if (lines.size() > 0)
{
wstring::size_type n = lines[0].find_first_of(L"0123456789");
if (n != wstring::npos)
{
wstring::size_type n2 = lines[0].substr(n).find_first_of(L" \t\n\t");
m_osVersion = StrTrim(lines[0].substr(n,n2));
}
}
if ((std::wstring::npos != m_osName.find(L"Client")) // RHED5
|| (std::wstring::npos != m_osName.find(L"Desktop"))) // RHED4
{
m_osAlias = L"RHED";
}
else
{ // Assume server.
m_osAlias = L"RHEL";
}
m_osManufacturer = L"Red Hat, Inc.";
#elif defined(PF_DISTRO_ULINUX)
// The release file is created at agent start time by init.d startup script
// This is done to insure that we can write to the appropriate directory at
// the time (since, at agent run-time, we may not have root privileges).
//
// If we CAN create the file here (if we're running as root), then we'll
// do so here. But in the normal case, this shouldn't be necessary. Only
// in "weird" cases (i.e. starting omiserver by hand, for example).
// Create the release file by running GetLinuxOS.sh script
// (if we have root privileges)
try
{
if ( !SCXFile::Exists(m_deps->getReleasePath()) &&
SCXFile::Exists(m_deps->getScriptPath()) &&
m_deps->isReleasePathWritable() )
{
std::istringstream in;
std::ostringstream out;
std::ostringstream err;
int ret = SCXCoreLib::SCXProcess::Run(m_deps->getScriptPath().c_str(), in, out, err, 10000);
if ( ret || out.str().length() || err.str().length() )
{
wostringstream sout;
sout << L"Unexpected errors running script: " << m_deps->getScriptPath().c_str()
<< L", return code: " << ret
<< L", stdout: " << StrFromUTF8(out.str())
<< L", stderr: " << StrFromUTF8(err.str());
SCX_LOGERROR(m_log, sout.str() );
}
}
}
catch(SCXCoreLib::SCXInterruptedProcessException &e)
{
wstring msg;
msg = L"Timeout running script \"" + m_deps->getScriptPath() +
L"\", " + e.Where() + L'.';
SCX_LOGERROR(m_log, msg );
};
// Look in release file for O/S information
string sFile = StrToUTF8(m_deps->getReleasePath());
wifstream fin(sFile.c_str());
SCXStream::ReadAllLines(fin, lines, nlfs);
if (!lines.empty())
{
ExtractToken(L"OSName", lines, m_osName);
ExtractToken(L"OSVersion", lines, m_osVersion);
ExtractToken(L"OSFullName", lines, m_linuxDistroCaption);
ExtractToken(L"OSAlias", lines, m_osAlias);
ExtractToken(L"OSManufacturer", lines, m_osManufacturer);
}
else
{
m_osAlias = L"Universal";
}
// Behavior for m_osCompatName (method GetOSName) should be as follows:
// PostInstall scripts will first look for SCX-RELEASE file (only on universal kits)
// If found, add "ORIGINAL_KIT_TYPE=Universal" to scxconfig.conf file,
// else add "ORIGINAL_KIT_TYPE=!Universal" to scxconfig.conf file.
// After that is set up, the SCX-RELEASE file is created.
//
// A RHEL system should of OSAlias of "RHEL, SLES system should have "SuSE" (in scx-release)
//
// We need to mimic return values for RHEL and SLES on universal kits that did not
// have a universal kit installed previously, but only for RHEL and SLES kits. In
// all other cases, continue to return "Linux Distribution".
wstring configFilename(m_deps->getConfigPath());
SCXConfigFile configFile(configFilename);
try
{
configFile.LoadConfig();
}
catch(SCXFilePathNotFoundException &e)
{
// Something's whacky with postinstall, so we can't follow algorithm
static SCXCoreLib::LogSuppressor suppressor(SCXCoreLib::eError, SCXCoreLib::eTrace);
wstring logMessage(L"Unable to load configuration file " + configFilename);
SCX_LOG(m_log, suppressor.GetSeverity(logMessage), logMessage);
m_osCompatName = L"Unknown Linux Distribution";
}
if ( m_osCompatName.empty() )
{
wstring kitType;
if ( configFile.GetValue(L"ORIGINAL_KIT_TYPE", kitType) )
{
if ( L"!Universal" == kitType )
{
if ( L"RHEL" == m_osAlias )
{
m_osCompatName = L"Red Hat Distribution";
}
else if ( L"SLES" == m_osAlias )
{
m_osCompatName = L"SuSE Distribution";
}
}
}
if ( m_osCompatName.empty() )
{
m_osCompatName = L"Linux Distribution";
}
}
#else
#error "Linux Platform not supported";
#endif
#elif defined(macos)
m_osAlias = L"MacOS";
m_osManufacturer = L"Apple Inc.";
if (m_unameIsValid)
{
// MacOS is called "Darwin" in uname info, so we hard-code here
m_osName = L"Mac OS";
// This value we could read dynamically from the xml file
// /System/Library/CoreServices/SystemVersion.plist, but that
// file may be named differently based on client/server, and
// reading the plist file would require framework stuff.
//
// Rather than using the plist, we'll use Gestalt, which is an
// API designed to figure out versions of anything and everything.
// Note that use of Gestalt requires the use of framework stuff
// as well, so the Makefiles for MacOS are modified for that.
SInt32 major, minor, bugfix;
if (0 != Gestalt(gestaltSystemVersionMajor, &major)
|| 0 != Gestalt(gestaltSystemVersionMinor, &minor)
|| 0 != Gestalt(gestaltSystemVersionBugFix, &bugfix))
{
throw SCXCoreLib::SCXErrnoException(L"Gestalt", errno, SCXSRCLOCATION);
}
wostringstream sout;
sout << major << L"." << minor << L"." << bugfix;
m_osVersion = sout.str();
}
#else
#error "Platform not supported"
#endif
}