bool Ini_UpdaterLists::saveRollbackInfo(const FileVector &rollbackList) { STRING section_name = SS_KEY_RollbackTree; long k = 0; STRING rollbackFileAndPath; if(!getProductFolder(m_useCurrentFolder, rollbackFileAndPath, pLog)) { TRACE_MESSAGE("Unable to save rollback information, because failed to get product folder"); return false; } rollbackFileAndPath += UPDATER_LISTS_FILENEME; TRACE_MESSAGE2("Saving rollback list to '%s'", rollbackFileAndPath.to_string().c_str()); removeRollbackSection(); // for output saved entries in rows and save space in trace file std::string savedEntries; unsigned long logLineSplitIndex = 0; for(FileVector::const_iterator iter = rollbackList.begin(); iter != rollbackList.end(); ++iter) { if(iter->m_rollbackChange == STRING(SS_KEY_RecentStatusAdded) || iter->m_rollbackChange == STRING(SS_KEY_RecentStatusModified) || iter->m_rollbackChange == STRING(SS_KEY_RecentStatusDeleted)) { STRING newSectionName; const long order_number = k++; makeNewSectionName(order_number, iter->m_filename, newSectionName); if(!saveRollbackListEntry(rollbackFileAndPath.c_str(), section_name.c_str(), order_number, newSectionName, *iter)) { TRACE_MESSAGE2("Unable to save rollback information for file entry '%s'", (iter->m_localPath + iter->m_filename).to_string().c_str()); return false; } // append comma before all items, but the very first one if(logLineSplitIndex++) savedEntries += ", "; // split line each 3 elements, but not before last element if(iter + 1 != rollbackList.end()) { if(!(logLineSplitIndex % 3)) savedEntries += "\n\t"; } savedEntries += (iter->m_localPath + iter->m_filename).to_string(); } } TRACE_MESSAGE3("Rollback information saved successfully to %s, entries: %s", rollbackFileAndPath.to_string().c_str(), savedEntries.c_str()); return true; }
void File::remove(bool bRecursive) { if (bRecursive && !isLink() && isDirectory()) { FileVector files; list(files, false); for (FileVector::iterator it = files.begin(); it != files.end(); ++it) { it->remove(true); } } FileImpl::remove(m_sPath); }
KLUPD::CoreError KLUPD::UpdateInfo::parse(const Path &path, FileInfo &fileInfo, const ChangeStateCheck &changeStateCheck, const FileVector &localFilesToCheckAgainst, const bool suppressSuccessLogMessages) { // index is already parsed, files already attached if(fileAlreadyParsed(fileInfo)) return CORE_NO_ERROR; const Path fullFileName = path + fileInfo.m_filename; if(!suppressSuccessLogMessages) TRACE_MESSAGE2("Parsing XML index file '%S'", fullFileName.toWideChar()); std::vector<unsigned char> buffer; const CoreError readFileResult = LocalFile(fullFileName, pLog).read(buffer); if(!KLUPD::isSuccess(readFileResult)) { TRACE_MESSAGE3("Failed to read XML index file '%S', result '%S'", fullFileName.toWideChar(), KLUPD::toString(readFileResult).toWideChar()); return readFileResult; } if(buffer.empty()) { TRACE_MESSAGE3("Index XML file '%S' is corrupted, file size is %d", fullFileName.toWideChar(), buffer.size()); return CORE_UPDATE_DESCRIPTION_DAMAGED; } // a file list obtained from XML FileVector fileList; IndexFileXMLParser xmler(fileInfo.m_filename.m_value, fileList, m_signature6Checker, fileInfo.m_relativeURLPath, m_retranslationMode, m_callbacks, pLog); XmlReader xmlReader(reinterpret_cast<const char *>(&buffer[0]), buffer.size()); if(!xmler.parseXMLRecursively(xmlReader, 0) || fileList.empty()) { TRACE_MESSAGE3("\tXML file parse error '%S', file number found %d", fullFileName.toWideChar(), fileList.size()); return CORE_UPDATE_DESCRIPTION_DAMAGED; } m_parsedIndexCache.push_back(fileInfo); xmler.GetUpdateDate(fileInfo.m_strUpdateDate); xmler.GetBlackDate(fileInfo.m_strBlackDate); // save variables to write into settings storage std::vector<UpdatedSettings> updatedSettings = xmler.updatedSettings(); m_updatedSettings.insert(m_updatedSettings.end(), updatedSettings.begin(), updatedSettings.end()); // copy to match list only those items which suits download criteria for(FileVector::iterator fileIter = fileList.begin(); fileIter != fileList.end(); ++fileIter) { // check download filters criteria should be performed NoCaseString reasonNotMatch; if(!matchesSettings(reasonNotMatch, *fileIter)) { if(!suppressSuccessLogMessages) { TRACE_MESSAGE3("\tFile filtered, download criteria does not matches: '%S', %S", reasonNotMatch.toWideChar(), fileIter->toString().toWideChar()); } continue; } // check download mandatory criteria reasonNotMatch.erase(); if(!isEntryRequired(reasonNotMatch, *fileIter, m_filterFlags)) { if(!suppressSuccessLogMessages) { TRACE_MESSAGE3("\tFile filtered, mandatory criteria does not matches: '%S', %S", reasonNotMatch.toWideChar(), fileIter->toString().toWideChar()); } continue; } // setup transaction folders fileIter->m_transactionInformation.m_currentLocation = m_callbacks.productFolder(*fileIter, m_retranslationMode); fileIter->m_transactionInformation.m_newLocation = m_callbacks.temporaryFolder(*fileIter); NoCaseString statusExplanations; fileIter->m_transactionInformation.m_changeStatus = getFileStatusAgainstLocal(*fileIter, changeStateCheck, localFilesToCheckAgainst, statusExplanations); // insert file with filtering duplicates bool fileDuplicate = false; // insert black list into the beginning of list, because it should be checked before downloading other bases if(fileIter->m_type == FileInfo::blackList) m_matchFileList.insertNewInTheBeginOfListOrUpdateTheSame(*fileIter, *fileIter, fileDuplicate, m_retranslationMode); else m_matchFileList.insertNewOrUpdateTheSame(*fileIter, *fileIter, fileDuplicate, m_retranslationMode); if(!suppressSuccessLogMessages) { // to avoid empty brackets output to trace if(!statusExplanations.empty()) statusExplanations = NoCaseString(L"(") + statusExplanations + L")"; if(fileDuplicate) { TRACE_MESSAGE3("\tDuplicate file information updated: %S %S", fileIter->toString().toWideChar(), statusExplanations.toWideChar()); } else { TRACE_MESSAGE3("\tFile matches download criteria: %S %S", fileIter->toString().toWideChar(), statusExplanations.toWideChar()); } } } return CORE_NO_ERROR; }