1 karl 1.20 //%2006////////////////////////////////////////////////////////////////////////
|
2 mike 1.2 //
|
3 karl 1.17 // 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.13 // IBM Corp.; EMC Corporation, The Open Group.
|
7 karl 1.17 // 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.18 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
10 // EMC Corporation; VERITAS Software Corporation; The Open Group.
|
11 karl 1.20 // 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.6 //
|
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 <fstream>
|
36 kumpf 1.12 #include <errno.h>
|
37 mike 1.2 #include <Pegasus/Common/FileSystem.h>
38 #include <Pegasus/Common/HashTable.h>
|
39 kumpf 1.5 #include <Pegasus/Common/Tracer.h>
|
40 mike 1.2 #include "ConfigFileHandler.h"
|
41 kumpf 1.3 #include "ConfigManager.h"
|
42 david 1.10 #if defined(PEGASUS_OS_OS400)
43 #include "OS400ConvertChar.h"
44 #endif
|
45 mike 1.2
46
47 PEGASUS_USING_STD;
48
49 PEGASUS_NAMESPACE_BEGIN
50
51 ////////////////////////////////////////////////////////////////////////////////
52 //
53 // ConfigFileHandler Class
54 //
55 ////////////////////////////////////////////////////////////////////////////////
56
57
58 ////////////////////////////////////////////////////////////////////////////////
|
59 kumpf 1.21 // ConfigTable
|
60 mike 1.2 ////////////////////////////////////////////////////////////////////////////////
61
62 typedef HashTable<String, String, EqualFunc<String>, HashFunc<String> > Table;
63
64 struct ConfigTable
65 {
66 Table table;
67 };
68
69
|
70 kumpf 1.21 /**
|
71 mike 1.2 Constructor.
72 */
|
73 kumpf 1.21 ConfigFileHandler::ConfigFileHandler(
74 const String& currentFile,
|
75 mike 1.2 const String& plannedFile,
76 const Boolean offLine)
77 : _offLine(offLine)
78 {
|
79 kumpf 1.3 String cFile;
80 String pFile;
|
81 mike 1.2
|
82 kumpf 1.3 //
83 // Set the current and planned config files
84 //
85 cFile = ConfigManager::getHomedPath(currentFile);
86
87 pFile = ConfigManager::getHomedPath(plannedFile);
|
88 mike 1.2
89 //
90 // Initialize instance variables.
91 //
|
92 kumpf 1.21
|
93 mike 1.2 _currentFileExist = true;
94 _plannedFileExist = true;
95
96
|
97 a.arora 1.16 _currentConfFile.reset(new ConfigFile(cFile));
98 _plannedConfFile.reset(new ConfigFile(pFile));
|
99 mike 1.2
100 _currentConfig = new ConfigTable;
101 _plannedConfig = new ConfigTable;
102
103 //
104 // check whether the planned file exists or not
105 //
106 if (!FileSystem::exists(pFile))
107 {
108 _plannedFileExist = false;
109 return;
110 }
111
112 //
113 // check whether the file is readable or not
114 //
115 if (!FileSystem::canRead(pFile))
116 {
117 throw FileNotReadable(pFile);
118 }
119
120 mike 1.2 //
121 // check whether the current file exists or not
122 //
123 if (!FileSystem::exists(cFile))
124 {
125 _currentFileExist = false;
126 //
127 // Current file need not exist.
128 // try creating one so that planned file contents
129 // can be copied over.
130 //
|
131 david 1.10 #if defined(PEGASUS_OS_OS400)
|
132 kumpf 1.21 ofstream ofs(cFile.getCString(), PEGASUS_STD(_CCSID_T(1208)));
|
133 david 1.10 #else
|
134 david 1.15 ofstream ofs(cFile.getCString());
|
135 david 1.10 #endif
|
136 mike 1.2 if (!ofs)
137 {
|
138 kumpf 1.12 // unable to create file
139 PEG_TRACE_STRING(TRC_CONFIG, Tracer::LEVEL4,
|
140 kumpf 1.21 "Failed to create config file: " + cFile + ", " +
141 strerror(errno));
|
142 mike 1.2 throw NoSuchFile(cFile);
143 }
144 ofs.close();
145 }
146
147 //
148 // check whether the file is readable or not
149 //
150 if (!FileSystem::canRead(cFile))
151 {
152 throw FileNotReadable(cFile);
153 }
154
155 }
156
|
157 kumpf 1.21 /**
158 Destructor.
|
159 mike 1.2 */
|
160 kumpf 1.21 ConfigFileHandler::~ConfigFileHandler()
|
161 mike 1.2 {
162 //
163 // delete tables
164 //
165 delete _currentConfig;
166 delete _plannedConfig;
167 }
168
|
169 kumpf 1.21 /**
170 Overwrites config properties in the current config file with the
171 the config properties from the planned config file.
|
172 mike 1.2
173 The content of the current config file will be copied in to a
|
174 kumpf 1.21 backup (.bak) file before copying planned file contents over the
|
175 mike 1.2 current file.
176 */
177 void ConfigFileHandler::copyPlannedFileOverCurrentFile()
178 {
179 if (_plannedFileExist)
180 {
181 _currentConfFile->replace(_plannedConfFile->getFileName());
|
182 kumpf 1.7 _currentFileExist = true;
|
183 mike 1.2 }
184 else if (_currentFileExist)
185 {
186 //
187 // Remove the current file
188 //
189 FileSystem::removeFileNoCase(_currentConfFile->getFileName());
190 }
191 }
192
193
|
194 kumpf 1.21 /**
|
195 mike 1.2 Load the config properties from the config files.
196 */
|
197 kumpf 1.21 void ConfigFileHandler::loadAllConfigProperties()
|
198 mike 1.2 {
199 loadCurrentConfigProperties();
200
201 loadPlannedConfigProperties();
202 }
203
204
|
205 kumpf 1.21 /**
|
206 mike 1.2 Load the config properties from the current config file.
207 */
|
208 kumpf 1.21 void ConfigFileHandler::loadCurrentConfigProperties()
|
209 mike 1.2 {
210 if (_currentFileExist)
211 {
212 _currentConfFile->load(_currentConfig);
213 }
214 }
215
216
|
217 kumpf 1.21 /**
|
218 mike 1.2 Load the config properties from the planned config file.
219 */
|
220 kumpf 1.21 void ConfigFileHandler::loadPlannedConfigProperties()
|
221 mike 1.2 {
222 if (_plannedFileExist)
223 {
224 _plannedConfFile->load(_plannedConfig);
225 }
226 }
227
228
|
229 kumpf 1.21 /**
230 Update the specified property name and value in the current
231 config file.
|
232 mike 1.2 */
|
233 kumpf 1.21 Boolean ConfigFileHandler::updateCurrentValue(
234 const CIMName& name,
|
235 kumpf 1.4 const String& value,
236 Boolean unset)
|
237 mike 1.2 {
238 // Remove the old property name and value from the table
|
239 kumpf 1.9 if (_currentConfig->table.contains(name.getString()))
|
240 mike 1.2 {
|
241 kumpf 1.9 if (!_currentConfig->table.remove(name.getString()))
|
242 mike 1.2 {
243 return false;
244 }
245 }
246
|
247 kumpf 1.4 if (!unset)
|
248 mike 1.2 {
249 // Store the new property name and value in to the table
|
250 kumpf 1.9 if (!_currentConfig->table.insert(name.getString(), value))
|
251 mike 1.2 {
252 return false;
253 }
254 }
255
256 try
257 {
258 // Store the new property in current config file.
259 _currentConfFile->save(_currentConfig);
260 }
261 catch (CannotRenameFile& e)
262 {
263 //
264 // Back up creation failed
|
265 kumpf 1.5 // FUTURE: Log this message in a log file.
|
266 mike 1.2 //
|
267 kumpf 1.5 PEG_TRACE_STRING(TRC_CONFIG, Tracer::LEVEL3,
|
268 kumpf 1.21 "Backup configuration file creation failed: " +
|
269 kumpf 1.14 e.getMessage() + ", " + strerror(errno));
|
270 mike 1.2
271 return false;
272 }
|
273 kumpf 1.14 catch (CannotOpenFile& cof)
274 {
275 PEG_TRACE_STRING(TRC_CONFIG, Tracer::LEVEL3,
|
276 kumpf 1.21 "Setting permissions on current configuration file failed: " +
|
277 kumpf 1.14 cof.getMessage() + ", " + strerror(errno));
278
279 return false;
280 }
281
|
282 mike 1.2 //
283 // The current config file would now been created,
284 // so set the flag to true.
285 //
286 _currentFileExist = true;
287
288 return true;
289 }
290
291
|
292 kumpf 1.21 /**
293 Update the specified property name and value in the planned
294 config file.
|
295 mike 1.2 */
|
296 kumpf 1.21 Boolean ConfigFileHandler::updatePlannedValue(
297 const CIMName& name,
|
298 kumpf 1.4 const String& value,
299 Boolean unset)
|
300 mike 1.2 {
301 //
302 // Remove the old property name and value from the table
303 //
|
304 kumpf 1.9 if (_plannedConfig->table.contains(name.getString()))
|
305 mike 1.2 {
|
306 kumpf 1.9 if (!_plannedConfig->table.remove(name.getString()))
|
307 mike 1.2 {
308 return false;
309 }
310 }
311
|
312 kumpf 1.4 if (!unset)
|
313 mike 1.2 {
314 //
315 // Store the new property name and value in to the table
316 //
|
317 kumpf 1.9 if (!_plannedConfig->table.insert(name.getString(), value))
|
318 mike 1.2 {
319 return false;
320 }
321 }
322
323 try
324 {
325 //
326 // Planned file need not exist for off line
327 // configuration setting update.
328 //
329 if (_offLine)
330 {
331 String pFile = _plannedConfFile->getFileName();
332
|
333 david 1.10 #if defined(PEGASUS_OS_OS400)
|
334 kumpf 1.21 ofstream ofs(pFile.getCString(), PEGASUS_STD(_CCSID_T(1208)));
|
335 david 1.10 #else
|
336 david 1.15 ofstream ofs(pFile.getCString());
|
337 david 1.10 #endif
|
338 mike 1.2 if (!ofs)
339 {
|
340 kumpf 1.12 PEG_TRACE_STRING(TRC_CONFIG, Tracer::LEVEL4,
|
341 kumpf 1.21 "Failed to create config file: " + pFile + ", " +
342 strerror(errno));
|
343 mike 1.2 throw NoSuchFile(pFile);
344 }
345 ofs.close();
346 }
347
348 //
349 // Store the new property in planned config file.
350 //
351 _plannedConfFile->save(_plannedConfig);
352
353 }
354 catch (CannotRenameFile& e)
355 {
356 //
357 // Back up creation failed
|
358 kumpf 1.5 // FUTURE: Log this message in a log file.
|
359 mike 1.2 //
|
360 kumpf 1.5 PEG_TRACE_STRING(TRC_CONFIG, Tracer::LEVEL3,
|
361 kumpf 1.21 "Backup configuration file creation failed: " +
362 e.getMessage() + ", " + strerror(errno));
|
363 mike 1.2
364 return false;
365 }
|
366 kumpf 1.14 catch (CannotOpenFile& cof)
367 {
368 PEG_TRACE_STRING(TRC_CONFIG, Tracer::LEVEL3,
|
369 kumpf 1.21 "Setting permissions on planned configuration file failed: " +
370 cof.getMessage() + ", " + strerror(errno));
|
371 kumpf 1.14
372 return false;
373 }
374
|
375 mike 1.2 //
376 // The planned config file would now been created,
377 // so set the flag to true.
378 //
379 _plannedFileExist = true;
380
381 return true;
382 }
383
384
|
385 kumpf 1.21 /**
386 Get the current property value for the specified property name.
|
387 mike 1.2 */
|
388 kumpf 1.21 Boolean ConfigFileHandler::getCurrentValue(
389 const CIMName& name,
390 String& value) const
|
391 mike 1.2 {
392 if (_currentFileExist)
393 {
|
394 kumpf 1.9 return _currentConfig->table.lookup(name.getString(), value);
|
395 mike 1.2 }
396
|
397 kumpf 1.4 return false;
|
398 mike 1.2 }
399
400
|
401 kumpf 1.21 /**
402 Get the planned property value for the specified property name.
|
403 mike 1.2 */
|
404 kumpf 1.21 Boolean ConfigFileHandler::getPlannedValue(
405 const CIMName& name,
406 String& value) const
|
407 mike 1.2 {
408 if (_plannedFileExist)
409 {
|
410 kumpf 1.9 return _plannedConfig->table.lookup(name.getString(), value);
|
411 mike 1.2 }
412
|
413 kumpf 1.4 return false;
|
414 mike 1.2 }
415
416
|
417 kumpf 1.21 /**
|
418 mike 1.2 Get all current property names.
419 */
|
420 kumpf 1.21 void ConfigFileHandler::getAllCurrentPropertyNames(
421 Array<CIMName>& propertyNames)
|
422 mike 1.2 {
423 propertyNames.clear();
424
425 if (_currentFileExist)
426 {
427 for (Table::Iterator i = _currentConfig->table.start(); i; i++)
428 {
429 propertyNames.append(i.key());
430 }
431 }
432 }
433
434
|
435 kumpf 1.21 /**
|
436 mike 1.2 Get all current property names and values.
437 */
|
438 kumpf 1.21 void ConfigFileHandler::getAllCurrentProperties(
439 Array<CIMName>& propertyNames,
|
440 mike 1.2 Array<String>& propertyValues)
441 {
442 propertyNames.clear();
443 propertyValues.clear();
444
445 if (_currentFileExist)
446 {
447 for (Table::Iterator i = _currentConfig->table.start(); i; i++)
448 {
449 propertyNames.append(i.key());
450 propertyValues.append(i.value());
451 }
452 }
453 }
454
455
|
456 kumpf 1.21 /**
|
457 mike 1.2 Get all planned property names and values.
458 */
|
459 kumpf 1.21 void ConfigFileHandler::getAllPlannedPropertyNames(
|
460 kumpf 1.9 Array<CIMName>& propertyNames)
|
461 mike 1.2 {
462 propertyNames.clear();
463
464 if (_plannedFileExist)
465 {
466 for (Table::Iterator i = _plannedConfig->table.start(); i; i++)
467 {
468 propertyNames.append(i.key());
469 }
470 }
471 }
472
473
|
474 kumpf 1.21 /**
|
475 mike 1.2 Get all planned config property names and values.
476 */
|
477 kumpf 1.21 void ConfigFileHandler::getAllPlannedProperties(
478 Array<CIMName>& propertyNames,
|
479 mike 1.2 Array<String>& propertyValues)
480 {
481 propertyNames.clear();
482 propertyValues.clear();
483
484 if (_plannedFileExist)
485 {
486 for (Table::Iterator i = _plannedConfig->table.start(); i; i++)
487 {
488 propertyNames.append(i.key());
489 propertyValues.append(i.value());
490 }
491 }
492 }
493
494 PEGASUS_NAMESPACE_END
|