2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 #include <dpl/assert.h>
22 #include <dpl/ace/ConfigurationManager.h>
27 const string currentXMLSchema("bondixml.xsd");
30 ConfigurationManager * ConfigurationManager::instance = NULL;
32 string ConfigurationManager::getCurrentPolicyFile(void) const
34 return currentPolicyFile;
37 string ConfigurationManager::getFullPathToCurrentPolicyFile(void) const
39 if (*(storagePath.rbegin()) == '/') {
40 return storagePath + currentPolicyFile;
42 return storagePath + "/" + currentPolicyFile;
45 string ConfigurationManager::getStoragePath(void) const
50 string ConfigurationManager::getFullPathToCurrentPolicyXMLSchema() const
52 if (*(storagePath.rbegin()) == '/')
54 return storagePath + currentXMLSchema;
56 return storagePath + "/" + currentXMLSchema;
59 int ConfigurationManager::parse(const string &configFileName)
61 configFile = configFileName;
62 int error = PARSER_SUCCESS;
65 reader = xmlNewTextReaderFilename(configFile.c_str());
68 LogError("Parser does not exist");
73 if (xmlTextReaderSetParserProp(reader, XML_PARSER_VALIDATE, 1)) {
74 LogError("Error while setting parser validating.");
76 Assert(false && "Cannot make XML parser validating");
80 if (xmlTextReaderSetParserProp(reader, XML_PARSER_DEFAULTATTRS, 1)) {
81 LogError("Error while attribute defaulting.");
83 Assert(false && "XML Parser cannot default xml attributes");
88 while (1 == (ret = xmlTextReaderRead(reader))) {
90 if (xmlTextReaderIsValid(reader) == 0) {
92 "Parser error while reading file " << configFile <<
93 ". File is not valid.");
95 Assert(false && "Configuration Manager error");
100 LogError("There were some errors while parsing XML file.");
104 if (reader != NULL) {
105 xmlFreeTextReader(reader);
110 void ConfigurationManager::extractFileAttributes()
112 xmlChar *active = xmlTextReaderGetAttribute(reader, ATTR_ACTIVE_POLICY);
115 if (active && active[0] == 't') {
122 void ConfigurationManager::startNodeHandler(void)
124 xmlChar *name = xmlTextReaderName(reader);
127 extractFileAttributes();
135 void ConfigurationManager::endNodeHandler(void)
137 xmlChar *name = xmlTextReaderName(reader);
140 policyFiles.push_back(currentText);
142 currentPolicyFile = currentText;
148 storagePath = currentText;
157 void ConfigurationManager::textNodeHandler(void)
159 xmlChar *text = xmlTextReaderValue(reader);
160 currentText = reinterpret_cast<const char*>(text);
164 void ConfigurationManager::processNode(void)
166 xmlReaderTypes type =
167 static_cast<xmlReaderTypes>(xmlTextReaderNodeType(reader));
169 case XML_READER_TYPE_ELEMENT: startNodeHandler();
171 case XML_READER_TYPE_END_ELEMENT: endNodeHandler();
173 case XML_READER_TYPE_TEXT: textNodeHandler();
180 int ConfigurationManager::addPolicyFile(const string & sourcePath)
182 FILE * sourceFd = NULL, *destFd = NULL;
183 int flag = CM_OPERATION_SUCCESS;
187 string newFilePath(getStoragePath());
188 newFilePath.append("/");
190 if (sourcePath.empty()) {
191 LogError("Filename empty");
192 flag = CM_GENERAL_ERROR;
196 fileName = extractFilename(sourcePath);
197 newFilePath.append(fileName);
199 LogDebug("Adding new file " << newFilePath);
200 if (checkIfFileExistst(newFilePath)) {
201 LogError("Destination file already exists");
202 flag = CM_FILE_EXISTS;
206 sourceFd = fopen(sourcePath.c_str(), "r");
207 if (sourceFd == NULL) {
208 LogError("Source file opening failed");
209 flag = CM_GENERAL_ERROR;
213 destFd = fopen(newFilePath.c_str(), "w");
214 if (destFd == NULL) {
215 LogError("Destination file creation failed");
216 flag = CM_GENERAL_ERROR;
220 if (0 > (sourceLength = getFileSize(sourcePath))) {
221 LogError("getFileSize error");
222 flag = CM_GENERAL_ERROR;
226 if (!copyFile(sourceFd, destFd, sourceLength)) {
227 //Copying failed, we have to remove corrupted file
228 flag = CM_GENERAL_ERROR;
229 if (removePolicyFile(newFilePath) != CM_OPERATION_SUCCESS) {
230 flag = CM_REMOVE_ERROR;
234 policyFiles.push_back(fileName);
236 if (saveConfig() != CM_OPERATION_SUCCESS) {
237 LogError("Error while saving policy file");
238 //TODO HOW TO ROLLBACK save config?
253 int ConfigurationManager::removePolicyFile(const string& file)
255 LogDebug("Trying to remove policy " << file);
256 int errorFlag = CM_OPERATION_SUCCESS;
257 string fileName = extractFilename(file);
258 string filePath(CONFIGURATION_MGR_TEST_POLICY_STORAGE);
260 if (fileName == currentPolicyFile) {
261 errorFlag = CM_REMOVE_CURRENT;
262 LogError("Cannot remove current policy");
266 filePath.append("/").append(fileName);
268 if (remove(filePath.c_str()) != 0) {
269 if (checkIfFileExistst(filePath)) {
270 errorFlag = CM_REMOVE_ERROR;
271 LogError("Cannot delete file" << filePath);
274 LogError("Cannot delete file" << filePath << " the file doesn't exist");
275 errorFlag = CM_REMOVE_NOT_EXISTING;
277 errorFlag = CM_OPERATION_SUCCESS;
279 //If remove was successful or unsuccessful but file doesn't exists then it
280 //should be removed from the list of available policies
281 policyFiles.remove(fileName);
287 string ConfigurationManager::extractFilename(const string & sourcePath) const
289 //begining of filename without path
290 size_t filenamePos = sourcePath.rfind('/');
293 if (filenamePos == string::npos) {
296 tmp = sourcePath.substr(filenamePos + 1);
298 LogDebug("Extracted filename " << tmp);
302 int ConfigurationManager::getFileSize(const string & path) const
304 //get source file size
305 struct stat sourceStat;
307 if (stat(path.c_str(), &sourceStat) == -1) {
308 LogError("Reading file properties failed");
311 sourceLength = sourceStat.st_size;
316 bool ConfigurationManager::copyFile(FILE * sourceDesc,
317 FILE * destinationDesc,
321 char *buffer = static_cast<char *>(malloc(lenght));
328 while ((rv = fread(buffer, sizeof (char), lenght, sourceDesc)) > 0) {
330 if (!feof(sourceDesc)) {
331 LogError("Error while reading file ");
337 rv = fwrite(buffer, sizeof (char), lenght, destinationDesc);
339 LogError("Write file failed ");
348 bool ConfigurationManager::checkIfFileExistst(const string & newFilePath) const
352 if (stat(newFilePath.c_str(), &stats) == 0) {
358 int ConfigurationManager::changeCurrentPolicyFile(const std::string & fileName)
360 int result = CM_OPERATION_SUCCESS;
361 string oldPolicyFile = currentPolicyFile;
363 string filePath(getStoragePath() + "/");
364 filePath += fileName;
366 if (!checkIfFileExistst(filePath)) {
367 //Policy file doesn't exist
368 result = CM_GENERAL_ERROR;
369 LogError("Error: policy file " << filePath << " doesn't exist");
372 if (result == CM_OPERATION_SUCCESS) {
373 //Adding file to storage succeeded
374 currentPolicyFile = extractFilename(filePath);
375 //Try to save the configuration file
376 result = saveConfig();
378 if (result != CM_OPERATION_SUCCESS) {
380 currentPolicyFile = oldPolicyFile;
381 LogError("Error while saving policy file");
382 //TODO HOW TO ROLLBACK save config?
389 int ConfigurationManager::saveConfig()
391 std::ofstream output(configFile.c_str());
392 int errorFlag = CM_OPERATION_SUCCESS;
394 output << "<?xml version=\"1.0\" ?>" << std::endl;
396 "<!DOCTYPE manager-settings SYSTEM \"" ACE_CONFIGURATION_DTD "\">" <<
398 output << "<manager-settings>" << std::endl;
399 output << " <storage-path>" << storagePath << "</storage-path>" <<
401 output << " <policy-files>" << std::endl;
402 for (list<string>::const_iterator it = policyFiles.begin();
403 it != policyFiles.end();
405 output << "\t<file ";
406 if (*it == currentPolicyFile) {
407 output << "active=\"true\"";
409 output << ">" << *it << "</file>" << std::endl;
411 output << " </policy-files>\n";
412 output << " </manager-settings>";
415 //TODO should we add 'eof' here?
416 if (output.bad() || output.fail()) {
417 //There were some errors while writing to file
418 errorFlag = CM_GENERAL_ERROR;