void SCXOSTypeInfo::Init()

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
    }