00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00035 #include "OW_config.h"
00036 #include "OW_CppInstanceProviderIFC.hpp"
00037 #include "OW_CppSimpleAssociatorProviderIFC.hpp"
00038 #include "OW_CIMClass.hpp"
00039 #include "OW_CIMInstance.hpp"
00040 #include "OW_CIMException.hpp"
00041 #include "OW_CIMValue.hpp"
00042 #include "OW_CIMProperty.hpp"
00043 #include "OW_CIMObjectPath.hpp"
00044 #include "OW_ConfigOpts.hpp"
00045 #include "OW_ConfigFile.hpp"
00046 #include "OW_ConfigException.hpp"
00047 #include "OW_Format.hpp"
00048 #include "OW_TempFileStream.hpp"
00049 #include "OW_FileSystem.hpp"
00050 #include <fstream>
00051 #include <sys/types.h>
00052 #include <sys/stat.h>
00053 #include <unistd.h>
00054
00055
00056 namespace OW_NAMESPACE
00057 {
00058
00059 class OpenWBEM_ConfigSettingDataInstProv : public virtual CppInstanceProviderIFC
00060 #ifndef OW_DISABLE_ASSOCIATION_TRAVERSAL
00061 , public virtual CppSimpleAssociatorProviderIFC
00062 #endif
00063 {
00064 public:
00065
00066 void initialize(const ProviderEnvironmentIFCRef& env)
00067 {
00068 loadConfigMap(env);
00069 }
00070
00072 virtual ~OpenWBEM_ConfigSettingDataInstProv()
00073 {
00074 }
00075
00077 virtual void enumInstanceNames(
00078 const ProviderEnvironmentIFCRef& env,
00079 const String& ns,
00080 const String& className,
00081 CIMObjectPathResultHandlerIFC& result,
00082 const CIMClass& cimClass )
00083 {
00084 (void)cimClass;
00085 env->getLogger()->logDebug("In OpenWBEM_ConfigSettingDataInstProv::enumInstanceNames");
00086
00087 if (mapNeedsLoad(getConfigFile(env)))
00088 {
00089 loadConfigMap(env);
00090 }
00091
00092 CIMObjectPath newCop(className, ns);
00093
00094
00095 for (ConfigItemsMap::const_iterator iter = m_configItems.begin();
00096 iter != m_configItems.end(); ++iter)
00097 {
00098 String id = makeID(iter->first);
00099 newCop.setKeyValue("InstanceID", CIMValue(id));
00100 result.handle(newCop);
00101 }
00102
00103 }
00104
00105
00107 virtual CIMInstance getInstance(
00108 const ProviderEnvironmentIFCRef& env,
00109 const String& ns,
00110 const CIMObjectPath& instanceName,
00111 WBEMFlags::ELocalOnlyFlag localOnly,
00112 WBEMFlags::EIncludeQualifiersFlag includeQualifiers,
00113 WBEMFlags::EIncludeClassOriginFlag includeClassOrigin,
00114 const StringArray* propertyList,
00115 const CIMClass& cimClass )
00116 {
00117 (void)ns;
00118 env->getLogger()->logDebug("In OpenWBEM_ConfigSettingDataInstProv::getInstance");
00119
00120 if (mapNeedsLoad(getConfigFile(env)))
00121 {
00122 loadConfigMap(env);
00123 }
00124
00125 CIMInstance newInst = cimClass.newInstance();
00126 newInst.updatePropertyValues(instanceName.getKeys());
00127
00128 String id;
00129 CIMValue cv = instanceName.getKeyValue("InstanceID");
00130 if (!cv || cv.getType() != CIMDataType::STRING || cv.isArray())
00131 {
00132 OW_THROWCIM(CIMException::INVALID_PARAMETER);
00133 }
00134 cv.get(id);
00135
00136 StringArray sa = id.tokenize(":");
00137 if (sa.size() != 3)
00138 {
00139 OW_THROWCIM(CIMException::INVALID_PARAMETER);
00140 }
00141
00142 String& configName = sa[2];
00143
00144 ConfigItemsMap::const_iterator iter = m_configItems.find(configName);
00145 if (iter == m_configItems.end())
00146 {
00147 OW_THROWCIM(CIMException::NOT_FOUND);
00148 }
00149
00150 const ConfigData& cd = iter->second;
00151
00152 newInst.setProperty("Value", CIMValue(cd.Value));
00153 newInst.setProperty("CurrentEffectiveValue", CIMValue(cd.CurrentEffectiveValue));
00154
00155 newInst.setProperty("ElementName", CIMValue(configName));
00156 newInst.setProperty("Caption", CIMValue(cd.Caption));
00157 newInst.setProperty("Description", CIMValue(cd.Description));
00158
00159 return newInst.clone(localOnly,includeQualifiers,includeClassOrigin,propertyList);
00160 }
00161
00163 virtual CIMObjectPath createInstance(
00164 const ProviderEnvironmentIFCRef& env,
00165 const String& ns,
00166 const CIMInstance& cimInstance )
00167 {
00168 (void)env;
00169 (void)ns;
00170 (void)cimInstance;
00171 OW_THROWCIMMSG(CIMException::FAILED, "Provider does not support createInstance");
00172 }
00173
00175 virtual void modifyInstance(
00176 const ProviderEnvironmentIFCRef& env,
00177 const String& ns,
00178 const CIMInstance& modifiedInstance,
00179 const CIMInstance& previousInstance,
00180 WBEMFlags::EIncludeQualifiersFlag includeQualifiers,
00181 const StringArray* propertyList,
00182 const CIMClass& theClass)
00183 {
00184 (void)ns;
00185 (void)includeQualifiers;
00186 (void)theClass;
00187 env->getLogger()->logDebug("In OpenWBEM_ConfigSettingDataInstProv::modifyInstance");
00188
00189 if (propertyList)
00190 {
00191 if (propertyList->size() == 0)
00192 {
00193 return;
00194 }
00195 if (propertyList->size() > 1
00196 || !(*propertyList)[0].equalsIgnoreCase("value"))
00197 {
00198 OW_THROWCIMMSG(CIMException::INVALID_PARAMETER,
00199 "Only the \"Value\" parameter can be modified");
00200 }
00201 }
00202
00203 String oldvalue;
00204 CIMValue cv = previousInstance.getPropertyValue("Value");
00205 if (!cv || cv.getType() != CIMDataType::STRING || cv.isArray())
00206 {
00207 OW_THROWCIMMSG(CIMException::INVALID_PARAMETER,
00208 "Bad or Missing \"Value\" property");
00209 }
00210 cv.get(oldvalue);
00211
00212 String newvalue;
00213
00214 cv = modifiedInstance.getPropertyValue("Value");
00215 if (!cv || cv.getType() != CIMDataType::STRING || cv.isArray())
00216 {
00217 OW_THROWCIMMSG(CIMException::INVALID_PARAMETER,
00218 "Bad or Missing \"Value\" property");
00219 }
00220 cv.get(newvalue);
00221
00222 if (oldvalue == newvalue)
00223 {
00224
00225 return;
00226 }
00227
00228 String configfile = getConfigFile(env);
00229
00230 std::ifstream file(configfile.c_str());
00231 if (!file)
00232 {
00233 OW_THROWCIMMSG(CIMException::FAILED, Format("Unable to read config"
00234 " file: %1", configfile).c_str());
00235 }
00236
00237 cv = modifiedInstance.getPropertyValue("InstanceID");
00238 if (!cv || cv.getType() != CIMDataType::STRING || cv.isArray())
00239 {
00240 OW_THROWCIM(CIMException::INVALID_PARAMETER);
00241 }
00242 String id;
00243 cv.get(id);
00244
00245 StringArray sa = id.tokenize(":");
00246 if (sa.size() != 3)
00247 {
00248 OW_THROWCIM(CIMException::INVALID_PARAMETER);
00249 }
00250
00251 String configName = sa[2];
00252
00253
00254 TempFileStream tfs;
00255
00256 String line;
00257 bool foundItem = false;
00258 while (file)
00259 {
00260 line = String::getLine(file);
00261 String tline = line;
00262 if (!tline.empty() && tline[0] == ';')
00263 {
00264 do
00265 {
00266 tline = tline.substring(1);
00267 } while (!tline.empty() && tline[0] == ';');
00268 }
00269 size_t idx = tline.indexOf('=');
00270 if (idx != String::npos)
00271 {
00272 String item = tline.substring(0, idx).trim();
00273 if (item == configName)
00274 {
00275 if (foundItem)
00276 {
00277
00278
00279 continue;
00280 }
00281 line = configName + " = " + newvalue;
00282 foundItem = true;
00283 }
00284 }
00285 tfs << line << "\n";
00286 }
00287 if (!foundItem)
00288 {
00289 tfs << "\n" << configName << " = " << newvalue << "\n";
00290 }
00291 file.close();
00292 tfs.rewind();
00293
00294
00295
00296 String bkpfilename = configfile + ".bkp";
00297 std::ofstream bkpfile(bkpfilename.c_str());
00298 if (!bkpfile)
00299 {
00300 OW_THROWCIMMSG(CIMException::FAILED, Format("Error opening %1 for writing",
00301 bkpfilename).c_str());
00302 }
00303 std::ifstream ifile(configfile.c_str());
00304 if (!ifile)
00305 {
00306 OW_THROWCIMMSG(CIMException::FAILED, Format("Error opening %1 for reading",
00307 ifile).c_str());
00308 }
00309 bkpfile << ifile.rdbuf();
00310 bkpfile.close();
00311 ifile.close();
00312
00313 std::ofstream ofile(configfile.c_str());
00314 if (!ofile)
00315 {
00316 OW_THROWCIMMSG(CIMException::FAILED, Format("Error opening %1 for writing",
00317 ofile).c_str());
00318 }
00319 ofile << tfs.rdbuf();
00320 ofile.close();
00321
00322
00323 }
00324
00326 virtual void deleteInstance(
00327 const ProviderEnvironmentIFCRef& env,
00328 const String& ns,
00329 const CIMObjectPath& cop)
00330 {
00331 (void)env;
00332 (void)ns;
00333 (void)cop;
00334 OW_THROWCIMMSG(CIMException::FAILED, "Provider does not support deleteInstance");
00335 }
00336
00338 virtual void getInstanceProviderInfo(InstanceProviderInfo &info)
00339 {
00340 info.addInstrumentedClass("OpenWBEM_ConfigSettingData");
00341 }
00342
00343 #ifndef OW_DISABLE_ASSOCIATION_TRAVERSAL
00344
00345 virtual void doReferences(const ProviderEnvironmentIFCRef &env,
00346 CIMInstanceResultHandlerIFC &result,
00347 const String &ns,
00348 const CIMObjectPath &objectName,
00349 const CIMClass &assocClass,
00350 const String &resultClass,
00351 const String &role,
00352 const String &resultRole)
00353 {
00354 CIMInstance newInst = assocClass.newInstance();
00355 String lcname = objectName.getClassName();
00356 lcname.toLowerCase();
00357 String lrole = role;
00358 lrole.toLowerCase();
00359 String lresultRole = resultRole;
00360 lresultRole.toLowerCase();
00361 if (lcname == "openwbem_objectmanager")
00362 {
00363 if ((!lrole.empty() && lrole != "managedelement")
00364 || (!lresultRole.empty() && lresultRole != "settingdata"))
00365 {
00366 OW_THROWCIMMSG(CIMException::INVALID_PARAMETER,
00367 "Bad Role or ResultRole");
00368 }
00369 lrole = "ManagedElement";
00370 lresultRole = "SettingData";
00371
00372 newInst.setProperty(lrole, CIMValue(objectName));
00373 CIMObjectPath settingCOP("OpenWBEM_ConfigSettingData", ns);
00374
00375 for (ConfigItemsMap::const_iterator iter = m_configItems.begin();
00376 iter != m_configItems.end(); ++iter)
00377 {
00378 settingCOP.setKeyValue("InstanceID",
00379 CIMValue(makeID(iter->first)));
00380 newInst.setProperty(lresultRole, CIMValue(settingCOP));
00381 result.handle(newInst);
00382 }
00383 }
00384 else if (lcname == "openwbem_configsettingdata")
00385 {
00386 if ((!lrole.empty() && lrole != "settingdata")
00387 || (!lresultRole.empty() && lresultRole != "managedelement"))
00388 {
00389 OW_THROWCIMMSG(CIMException::INVALID_PARAMETER,
00390 "Bad Role or ResultRole");
00391 }
00392 lrole = "SettingData";
00393 lresultRole = "ManagedElement";
00394
00395 CIMObjectPathArray cpa = env->getCIMOMHandle()->enumInstanceNamesA(ns, "OpenWBEM_ObjectManager");
00396 if (cpa.size() != 1)
00397 {
00398 OW_THROWCIMMSG(CIMException::FAILED,
00399 "Unable to retrieve a single instance of OpenWBEM_ObjectManager");
00400 }
00401 newInst.setProperty(lrole, CIMValue(objectName));
00402 newInst.setProperty(lresultRole, CIMValue(cpa[0]));
00403 result.handle(newInst);
00404 }
00405 }
00406
00408 virtual void getAssociatorProviderInfo(AssociatorProviderInfo &info)
00409 {
00410 info.addInstrumentedClass("OpenWBEM_ObjectManagerConfigSettingData");
00411 }
00412 #endif // #ifndef OW_DISABLE_ASSOCIATION_TRAVERSAL
00413
00414 private:
00415 struct ConfigData
00416 {
00417 String Value;
00418 String CurrentEffectiveValue;
00419 String Caption;
00420 String Description;
00421
00422
00423 };
00424
00425 typedef SortedVectorMap<String, ConfigData> ConfigItemsMap;
00426
00427 SortedVectorMap<String, ConfigData> m_configItems;
00429
00430 time_t m_fileMTime;
00432 String makeID(const String& confName)
00433 {
00434 String rval = "OpenWBEM:ConfigItem:";
00435 rval += confName;
00436 return rval;
00437 }
00439 bool mapNeedsLoad(const String& filename)
00440 {
00441 struct stat st;
00442
00443 if (stat(filename.c_str(), &st) != 0)
00444 {
00445 OW_THROWCIMMSG(CIMException::FAILED, Format("Cannot stat %1: %2",
00446 filename, strerror(errno)).c_str());
00447 }
00448
00449 if (st.st_mtime != m_fileMTime)
00450 {
00451 return true;
00452 }
00453 return false;
00454 }
00455
00457 String getConfigFile(const ProviderEnvironmentIFCRef& env)
00458 {
00459 String filename = env->getConfigItem("owcimomd.config_file");
00460
00461 if (filename.empty())
00462 {
00463 OW_THROWCIMMSG(CIMException::FAILED, "Cannot determine config file");
00464 }
00465
00466 return filename;
00467 }
00468
00470 void loadConfigMap(const ProviderEnvironmentIFCRef& env)
00471 {
00472 String filename = getConfigFile(env);
00473 m_configItems.clear();
00474
00475 struct stat st;
00476 if (stat(filename.c_str(), &st) != 0)
00477 {
00478 OW_THROWCIMMSG(CIMException::FAILED, Format("Cannot stat %1: %2",
00479 filename, strerror(errno)).c_str());
00480 }
00481
00482 m_fileMTime = st.st_mtime;
00483
00484 std::ifstream file(filename.c_str());
00485 if (!file)
00486 {
00487 OW_THROWCIMMSG(CIMException::FAILED, Format("Unable to read config"
00488 " file: %1", filename).c_str());
00489 }
00490
00491 String line;
00492 int lineNum = 0;
00493 while (file)
00494 {
00495 lineNum++;
00496 line = String::getLine(file);
00497 if (!line.empty())
00498 {
00499
00500 if (line[0] == '#' || line[0] == ';')
00501 {
00502 continue;
00503 }
00504 size_t idx = line.indexOf('=');
00505 if (idx != String::npos)
00506 {
00507 if (idx + 1 < line.length())
00508 {
00509 String itemValue = line.substring(idx + 1).trim();
00510 if (!itemValue.empty())
00511 {
00512 String item = line.substring(0, idx).trim();
00513 ConfigItemsMap::iterator it = m_configItems.find(item);
00514 if (it == m_configItems.end())
00515 {
00516 ConfigData cd;
00517 cd.Value = itemValue;
00518 cd.CurrentEffectiveValue = env->getConfigItem(item);
00519 m_configItems.insert(std::make_pair(item, cd));
00520 }
00521 }
00522 }
00523 }
00524 else
00525 {
00526 OW_THROWCIMMSG(CIMException::FAILED, Format("Error in config file:"
00527 " %1 at line %2.\n Line is %3", filename, lineNum,
00528 line).c_str());
00529 }
00530 }
00531 }
00532 file.close();
00533
00534 for(const ConfigOpts::NameAndDefault* niter = &ConfigOpts::g_defaults[0];
00535 niter != ConfigOpts::g_defaultsEnd; ++niter)
00536 {
00537 String curValue = env->getConfigItem(niter->name, String(niter->defaultValue));
00538 ConfigItemsMap::iterator it = m_configItems.find(niter->name);
00539 if (it == m_configItems.end())
00540 {
00541 ConfigData cd;
00542 cd.CurrentEffectiveValue = curValue;
00543 m_configItems.insert(std::make_pair(niter->name, cd));
00544 }
00545 else
00546 {
00547 it->second.CurrentEffectiveValue = curValue;
00548 }
00549 }
00550
00551 }
00552
00553
00554 };
00555
00556
00557 }
00558
00559
00560
00561
00562 OW_PROVIDERFACTORY(OpenWBEM::OpenWBEM_ConfigSettingDataInstProv, owprovinstOpenWBEM_ConfigSettingData)
00563
00564
00565
00566
00567