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

  1 karl  1.23 //%2006////////////////////////////////////////////////////////////////////////
  2 mike  1.2  //
  3 karl  1.20 // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
  4            // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
  5            // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
  6 karl  1.12 // IBM Corp.; EMC Corporation, The Open Group.
  7 karl  1.20 // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
  8            // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
  9 karl  1.21 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
 10            // EMC Corporation; VERITAS Software Corporation; The Open Group.
 11 karl  1.23 // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
 12            // EMC Corporation; Symantec Corporation; The Open Group.
 13 mike  1.2  //
 14            // Permission is hereby granted, free of charge, to any person obtaining a copy
 15            // of this software and associated documentation files (the "Software"), to
 16            // deal in the Software without restriction, including without limitation the
 17            // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 18            // sell copies of the Software, and to permit persons to whom the Software is
 19            // furnished to do so, subject to the following conditions:
 20 kumpf 1.4  // 
 21 mike  1.2  // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
 22            // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
 23            // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
 24            // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 25            // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 26            // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 27            // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 28            // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 29            //
 30            //==============================================================================
 31            //
 32            //%/////////////////////////////////////////////////////////////////////////////
 33            
 34            
 35            #include <cctype>
 36            #include <fstream>
 37            #include <Pegasus/Common/FileSystem.h>
 38            #include <Pegasus/Common/HashTable.h>
 39 kumpf 1.3  #include <Pegasus/Common/Tracer.h>
 40 kumpf 1.26 #include <Pegasus/Common/Executor.h>
 41 mike  1.2  
 42            #include "ConfigExceptions.h"
 43            #include "ConfigFile.h"
 44 david 1.8  #if  defined(PEGASUS_OS_OS400)
 45            #include "OS400ConvertChar.h"
 46            #endif
 47 mike  1.2  
 48            
 49            PEGASUS_USING_STD;
 50            
 51            PEGASUS_NAMESPACE_BEGIN
 52            
 53            
 54            ////////////////////////////////////////////////////////////////////////////////
 55            //
 56            //  ConfigFile Class
 57            //
 58            ////////////////////////////////////////////////////////////////////////////////
 59            
 60            
 61            ////////////////////////////////////////////////////////////////////////////////
 62 kumpf 1.24 // ConfigTable
 63 mike  1.2  ////////////////////////////////////////////////////////////////////////////////
 64            
 65            typedef HashTable<String, String, EqualFunc<String>, HashFunc<String> > Table;
 66            
 67            struct ConfigTable
 68            {
 69                Table table;
 70            };
 71            
 72            
 73            /*
 74                Config file header information
 75            */
 76            static const char* ConfigHeader [] = {
 77                "########################################################################",
 78                "##                                                                    ##",
 79                "##                  CIM Server configuration file                     ##",
 80                "##                                                                    ##",
 81                "########################################################################",
 82 kumpf 1.24     " ",
 83 mike  1.2      "########################################################################",
 84                "#                                                                      #",
 85                "# This is the configuration file for the CIMOM. The configuration      #",
 86                "# properties in this file are loaded in to CIMOM at startup.           #",
 87                "# CIMOM updates this file with the changes in the configurations.      #",
 88                "#                                                                      #",
 89                "# It is recommended that user do not edit this file, instead use       #",
 90                "# CIMConfigCommand to make any changes to the CIMOM configurations.    #",
 91                "#                                                                      #",
 92                "########################################################################",
 93                " "
 94            };
 95            
 96            static const int HEADER_SIZE = sizeof(ConfigHeader) / sizeof(ConfigHeader[0]);
 97            
 98            
 99 kumpf 1.24 /**
100                Constructor.
101 mike  1.2  */
102            ConfigFile::ConfigFile (const String& fileName)
103            {
104                _configFile = fileName;
105            
106                _configBackupFile = fileName + ".bak";
107            }
108            
109 kumpf 1.24 /**
110                Destructor.
111 mike  1.2  */
112            ConfigFile::~ConfigFile ()
113            {
114            }
115            
116            
117 kumpf 1.24 /**
118 mike  1.2      Get the name of the configuration file.
119            */
120 vijay.eli 1.22 String ConfigFile::getFileName () const
121 mike      1.2  {
122 kumpf     1.24     return _configFile;
123 mike      1.2  }
124                
125                
126 kumpf     1.24 /**
127 mike      1.2      Load the properties from the config file.
128                */
129 kumpf     1.24 void ConfigFile::load(ConfigTable* confTable)
130 mike      1.2  {
131                    String line;
132                
133                    //
134                    // Delete the backup configuration file
135                    //
136 kumpf     1.26 
137 mike      1.2      if (FileSystem::exists(_configBackupFile))
138                    {
139 kumpf     1.26         Executor::removeFile(_configBackupFile.getCString());
140 mike      1.2      }
141                
142                    //
143                    // Open the config file
144                    //
145 kumpf     1.26 
146 david     1.8  #if defined(PEGASUS_OS_OS400)
147 david     1.18     ifstream ifs(_configFile.getCString(), PEGASUS_STD(_CCSID_T(1208)));
148 david     1.8  #else
149 david     1.18     ifstream ifs(_configFile.getCString());
150 david     1.8  #endif
151 kumpf     1.26 
152 mike      1.2      if (!ifs)
153                    {
154                        return;
155                    }
156                
157                    //
158                    // Read each line of the file
159                    //
160                    for (Uint32 lineNumber = 1; GetLine(ifs, line); lineNumber++)
161                    {
162                        // Get the property name and value
163                
164                        //
165                        // Skip leading whitespace
166                        //
167 kumpf     1.7          const Char16* p = line.getChar16Data();
168 mike      1.2  
169                        while (*p && isspace(*p))
170                        {
171                            p++;
172                        }
173                
174                        if (!*p)
175                        {
176                            continue;
177                        }
178                
179                        //
180                        // Skip comment lines
181                        //
182                        if (*p == '#')
183                        {
184                            continue;
185                        }
186                
187                        //
188                        // Get the property name
189 mike      1.2          //
190 kumpf     1.25         String name;
191 mike      1.2  
192                        if (!(isalpha(*p) || *p == '_'))
193                        {
194                            ifs.close();
195                            throw ConfigFileSyntaxError(_configFile, lineNumber);
196                        }
197                
198 kumpf     1.5          name.append(*p++);
199 mike      1.2  
200                        while (isalnum(*p) || *p == '_')
201                        {
202 kumpf     1.5              name.append(*p++);
203 mike      1.2          }
204                
205                        //
206                        // Skip whitespace after property name
207                        //
208                        while (*p && isspace(*p))
209                        {
210                            p++;
211                        }
212                
213                        //
214                        // Expect an equal sign
215                        //
216                        if (*p != '=')
217                        {
218                            ifs.close();
219                            throw ConfigFileSyntaxError(_configFile, lineNumber);
220                        }
221                
222                        p++;
223                
224 mike      1.2          //
225                        // Skip whitespace after equal sign
226                        //
227                        while (*p && isspace(*p))
228                        {
229                            p++;
230                        }
231                
232                        //
233                        // Get the value
234                        //
235 kumpf     1.25         String value;
236 mike      1.2  
237                        while (*p)
238                        {
239 kumpf     1.5              value.append(*p++);
240 mike      1.2          }
241                
242                        //
243                        // Store the property name and value in the table
244                        //
245                        if (!confTable->table.insert(name, value))
246                        {
247                            //
248                            // Duplicate property, ignore the new property value.
249 kumpf     1.3              // FUTURE: Log this message in a log file.
250 mike      1.2              //
251 kumpf     1.3              PEG_TRACE_STRING(TRC_CONFIG, Tracer::LEVEL3,
252 kumpf     1.24                 "Duplicate property '" + name + "', value '" + value +
253                                    "' is ignored.");
254 mike      1.2          }
255                    }
256                
257                    ifs.close();
258                }
259                
260                
261 kumpf     1.24 /**
262 mike      1.2      Save the properties to the config file.
263                */
264 kumpf     1.24 void ConfigFile::save(ConfigTable* confTable)
265 mike      1.2  {
266                    //
267                    // Delete the backup configuration file
268                    //
269                    if (FileSystem::exists(_configBackupFile))
270                    {
271 kumpf     1.26         Executor::removeFile(_configBackupFile.getCString());
272 mike      1.2      }
273                
274                    //
275                    // Rename the configuration file as a backup file
276                    //
277 kumpf     1.26 
278 mike      1.2      if (FileSystem::exists(_configFile))
279                    {
280 kumpf     1.26         if (Executor::renameFile(
281                            _configFile.getCString(), _configBackupFile.getCString()) != 0)
282 mike      1.2          {
283                            throw CannotRenameFile(_configFile);
284                        }
285                    }
286                
287                    //
288                    // Open the config file for writing
289                    //
290                
291 kumpf     1.26     FILE* ofs = Executor::openFile(_configFile.getCString(), 'w');
292                
293                    if (!ofs)
294 kumpf     1.13     {
295                        throw CannotOpenFile(_configFile);
296                    }
297                
298                    //
299 mike      1.2      // Write config file header information
300                    //
301 kumpf     1.26 
302 mike      1.2      for (int index = 0; index < HEADER_SIZE; index++)
303                    {
304 kumpf     1.26         fputs(ConfigHeader[index], ofs);
305                        fputc('\n', ofs);
306 mike      1.2      }
307                
308                    //
309                    // Save config properties and values to the file
310                    //
311 kumpf     1.26 
312 mike      1.2      for (Table::Iterator i = confTable->table.start(); i; i++)
313                    {
314 kumpf     1.26         CString key = i.key().getCString();
315                        CString value = i.value().getCString();
316                        fprintf(ofs, "%s=%s\n", (const char*)key, (const char*)value);
317 mike      1.2      }
318                
319 kumpf     1.26     fclose(ofs);
320                
321                #if !defined(PEGASUS_ENABLE_PRIVILEGE_SEPARATION)
322                    // Note:  The Executor process sets the permissions to 0644 whenever it
323                    // opens a file for writing.
324                # if !defined(PEGASUS_OS_TYPE_WINDOWS)
325                    //
326                    // Set permissions on the config file to 0644
327                    //
328                    if (!FileSystem::changeFilePermissions(_configFile,
329                        (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)))    // set 0644
330                    {
331                        throw CannotOpenFile(_configFile);
332                    }
333                # endif
334                #endif /* PEGASUS_ENABLE_PRIVILEGE_SEPARATION */
335 mike      1.2  }
336                
337                
338 kumpf     1.24 /**
339 mike      1.2      Replace the properties in the config file with the properties from
340                    the given file.
341                */
342                void ConfigFile::replace (const String& fileName)
343                {
344                    //
345                    // Open the given config file for reading
346                    //
347 kumpf     1.26 
348                    FILE* ifs = fopen(fileName.getCString(), "rb");
349                
350                    if (!ifs)
351                    {
352                        throw CannotOpenFile(fileName);
353                    }
354 mike      1.2  
355                    //
356                    // Delete the backup configuration file
357                    //
358 kumpf     1.26 
359 mike      1.2      if (FileSystem::exists(_configBackupFile))
360                    {
361 kumpf     1.26         Executor::removeFile(_configBackupFile.getCString());
362 mike      1.2      }
363                
364                    //
365                    // Rename the existing config file as a backup file
366                    //
367 kumpf     1.26 
368 mike      1.2      if (FileSystem::exists(_configFile))
369                    {
370 kumpf     1.26         if (Executor::renameFile(
371                            _configFile.getCString(), _configBackupFile.getCString()) != 0)
372 mike      1.2          {
373 kumpf     1.26             fclose(ifs);
374 mike      1.2              throw CannotRenameFile(_configFile);
375                        }
376                    }
377                
378                    //
379                    // Open the existing config file for writing
380                    //
381 kumpf     1.13 
382 kumpf     1.26     FILE* ofs = Executor::openFile(_configFile.getCString(), 'w');
383                
384                    if (!ofs)
385 kumpf     1.14     {
386 kumpf     1.26         fclose(ifs);
387 kumpf     1.14         throw CannotOpenFile(_configFile);
388                    }
389 mike      1.2  
390                    //
391                    // Read each line of the new file and write to the config file.
392                    //
393 kumpf     1.26 
394                    char buffer[4096];
395                
396                    while ((fgets(buffer, sizeof(buffer), ifs)) != NULL)
397                        fputs(buffer, ofs);
398 mike      1.2  
399 kumpf     1.24     //
400 mike      1.2      // Close the file handles
401                    //
402 kumpf     1.26 
403                    fclose(ifs);
404                    fclose(ofs);
405                
406                #if !defined(PEGASUS_ENABLE_PRIVILEGE_SEPARATION)
407                # if !defined(PEGASUS_OS_TYPE_WINDOWS)
408                    //
409                    // Set permissions on the config file to 0644
410                    //
411                    if (!FileSystem::changeFilePermissions(_configFile,
412                        (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)))    // set 0644
413                    {
414                        throw CannotOpenFile(_configFile);
415                    }
416                # endif
417                #endif /* PEGASUS_ENABLE_PRIVILEGE_SEPARATION */
418 mike      1.2  }
419                
420                PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2