(file) Return to ConfigFile.cpp CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Pegasus / Config

File: [Pegasus] / pegasus / src / Pegasus / Config / ConfigFile.cpp (download)
Revision: 1.29, Fri Jul 27 17:42:43 2007 UTC (16 years, 11 months ago) by kumpf
Branch: MAIN
CVS Tags: TASK-PEP328_SOLARIS_IX86_CC_PORT-root, TASK-PEP328_SOLARIS_IX86_CC_PORT-branch, TASK-PEP305_VXWORKS-root, TASK-PEP305_VXWORKS-branch-pre-solaris-port, TASK-PEP305_VXWORKS-branch-post-solaris-port, TASK-PEP305_VXWORKS-branch-beta2, TASK-PEP305_VXWORKS-branch, TASK-PEP305_VXWORKS-2008-10-23, TASK-BUG7146_SqlRepositoryPrototype-root, TASK-BUG7146_SqlRepositoryPrototype-merged_out_to_branch, TASK-BUG7146_SqlRepositoryPrototype-merged_out_from_trunk, TASK-BUG7146_SqlRepositoryPrototype-merged_in_to_trunk, TASK-BUG7146_SqlRepositoryPrototype-merged_in_from_branch, TASK-BUG7146_SqlRepositoryPrototype-branch, RELEASE_2_8_0_BETA, RELEASE_2_8_0-FC, RELEASE_2_7_1-RC1, RELEASE_2_7_1, RELEASE_2_7_0-RC1, RELEASE_2_7_0-BETA, RELEASE_2_7_0, RELEASE_2_7-root
Branch point for: TASK-PEP328_SOLARIS_IX86_CC_PORT-branch-v2, RELEASE_2_7-branch
Changes since 1.28: +7 -7 lines
BUG#: 6702
TITLE: Config file header text needs clean-up
DESCRIPTION: Reword the header text with better terminology.

//%2006////////////////////////////////////////////////////////////////////////
//
// 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.
// 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
// 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.
//
//==============================================================================
//
//%/////////////////////////////////////////////////////////////////////////////


#include <cctype>
#include <fstream>
#include <Pegasus/Common/FileSystem.h>
#include <Pegasus/Common/HashTable.h>
#include <Pegasus/Common/Tracer.h>
#include <Pegasus/Common/Executor.h>

#include "ConfigExceptions.h"
#include "ConfigFile.h"

PEGASUS_USING_STD;

PEGASUS_NAMESPACE_BEGIN


////////////////////////////////////////////////////////////////////////////////
//
//  ConfigFile Class
//
////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////
// ConfigTable
////////////////////////////////////////////////////////////////////////////////

typedef HashTable<String, String, EqualFunc<String>, HashFunc<String> > Table;

struct ConfigTable
{
    Table table;
};


/*
    Config file header information
*/
static const char* ConfigHeader [] = {
    "########################################################################",
    "##                                                                    ##",
    "##                  CIM Server configuration file                     ##",
    "##                                                                    ##",
    "########################################################################",
    "",
    "########################################################################",
    "#                                                                      #",
    "# The configuration in this file is loaded by the CIM Server at        #",
    "# start-up.  This file is updated by the CIM Server when the           #",
    "# configuration changes.                                               #",
    "#                                                                      #",
    "# Do not edit this file directly.  Instead, use the cimconfig command  #",
    "# to update the CIM Server configuration.                              #",
    "#                                                                      #",
    "########################################################################",
    ""
};

static const int HEADER_SIZE = sizeof(ConfigHeader) / sizeof(ConfigHeader[0]);


/**
    Constructor.
*/
ConfigFile::ConfigFile (const String& fileName)
{
    _configFile = fileName;

    _configBackupFile = fileName + ".bak";
}

/**
    Destructor.
*/
ConfigFile::~ConfigFile ()
{
}


/**
    Get the name of the configuration file.
*/
String ConfigFile::getFileName () const
{
    return _configFile;
}


/**
    Load the properties from the config file.
*/
void ConfigFile::load(ConfigTable* confTable)
{
    String line;

    //
    // Delete the backup configuration file
    //

    if (FileSystem::exists(_configBackupFile))
    {
        Executor::removeFile(_configBackupFile.getCString());
    }

    //
    // Open the config file
    //
    ifstream ifs(_configFile.getCString());

    if (!ifs)
    {
        return;
    }

    //
    // Read each line of the file
    //
    for (Uint32 lineNumber = 1; GetLine(ifs, line); lineNumber++)
    {
        // Get the property name and value

        //
        // Skip leading whitespace
        //
        const Char16* p = line.getChar16Data();

        while (*p && isspace(*p))
        {
            p++;
        }

        if (!*p)
        {
            continue;
        }

        //
        // Skip comment lines
        //
        if (*p == '#')
        {
            continue;
        }

        //
        // Get the property name
        //
        String name;

        if (!(isalpha(*p) || *p == '_'))
        {
            ifs.close();
            throw ConfigFileSyntaxError(_configFile, lineNumber);
        }

        name.append(*p++);

        while (isalnum(*p) || *p == '_')
        {
            name.append(*p++);
        }

        //
        // Skip whitespace after property name
        //
        while (*p && isspace(*p))
        {
            p++;
        }

        //
        // Expect an equal sign
        //
        if (*p != '=')
        {
            ifs.close();
            throw ConfigFileSyntaxError(_configFile, lineNumber);
        }

        p++;

        //
        // Skip whitespace after equal sign
        //
        while (*p && isspace(*p))
        {
            p++;
        }

        //
        // Get the value
        //
        String value;

        while (*p)
        {
            value.append(*p++);
        }

        //
        // Store the property name and value in the table
        //
        if (!confTable->table.insert(name, value))
        {
            //
            // Duplicate property, ignore the new property value.
            // FUTURE: Log this message in a log file.
            //
            PEG_TRACE_STRING(TRC_CONFIG, Tracer::LEVEL3,
                "Duplicate property '" + name + "', value '" + value +
                    "' is ignored.");
        }
    }

    ifs.close();
}


/**
    Save the properties to the config file.
*/
void ConfigFile::save(ConfigTable* confTable)
{
    //
    // Delete the backup configuration file
    //
    if (FileSystem::exists(_configBackupFile))
    {
        Executor::removeFile(_configBackupFile.getCString());
    }

    //
    // Rename the configuration file as a backup file
    //

    if (FileSystem::exists(_configFile))
    {
        if (Executor::renameFile(
            _configFile.getCString(), _configBackupFile.getCString()) != 0)
        {
            throw CannotRenameFile(_configFile);
        }
    }

    //
    // Open the config file for writing
    //

    FILE* ofs = Executor::openFile(_configFile.getCString(), 'w');

    if (!ofs)
    {
        throw CannotOpenFile(_configFile);
    }

    //
    // Write config file header information
    //

    for (int index = 0; index < HEADER_SIZE; index++)
    {
        fputs(ConfigHeader[index], ofs);
        fputc('\n', ofs);
    }

    //
    // Save config properties and values to the file
    //

    for (Table::Iterator i = confTable->table.start(); i; i++)
    {
        CString key = i.key().getCString();
        CString value = i.value().getCString();
        fprintf(ofs, "%s=%s\n", (const char*)key, (const char*)value);
    }

    fclose(ofs);

#if !defined(PEGASUS_OS_TYPE_WINDOWS)
    // Note:  The Executor process sets the permissions to 0644 when it
    // opens the config file for writing.
    if (Executor::detectExecutor() != 0)
    {
        //
        // Set permissions on the config file to 0644
        //
        if (!FileSystem::changeFilePermissions(
                _configFile,
                (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)))    // set 0644
        {
            throw CannotOpenFile(_configFile);
        }
    }
#endif
}


/**
    Replace the properties in the config file with the properties from
    the given file.
*/
void ConfigFile::replace (const String& fileName)
{
    //
    // Open the given config file for reading
    //

    FILE* ifs = fopen(fileName.getCString(), "rb");

    if (!ifs)
    {
        throw CannotOpenFile(fileName);
    }

    //
    // Delete the backup configuration file
    //

    if (FileSystem::exists(_configBackupFile))
    {
        Executor::removeFile(_configBackupFile.getCString());
    }

    //
    // Rename the existing config file as a backup file
    //

    if (FileSystem::exists(_configFile))
    {
        if (Executor::renameFile(
            _configFile.getCString(), _configBackupFile.getCString()) != 0)
        {
            fclose(ifs);
            throw CannotRenameFile(_configFile);
        }
    }

    //
    // Open the existing config file for writing
    //

    FILE* ofs = Executor::openFile(_configFile.getCString(), 'w');

    if (!ofs)
    {
        fclose(ifs);
        throw CannotOpenFile(_configFile);
    }

    //
    // Read each line of the new file and write to the config file.
    //

    char buffer[4096];

    while ((fgets(buffer, sizeof(buffer), ifs)) != NULL)
        fputs(buffer, ofs);

    //
    // Close the file handles
    //

    fclose(ifs);
    fclose(ofs);

#if !defined(PEGASUS_ENABLE_PRIVILEGE_SEPARATION)
# if !defined(PEGASUS_OS_TYPE_WINDOWS)
    //
    // Set permissions on the config file to 0644
    //
    if (!FileSystem::changeFilePermissions(_configFile,
        (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)))    // set 0644
    {
        throw CannotOpenFile(_configFile);
    }
# endif
#endif /* PEGASUS_ENABLE_PRIVILEGE_SEPARATION */
}

PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2