void TeaSafe::renameEntry(std::string const &src, std::string const &dst) { StateLock lock(m_stateMutex); auto srcPath(src); char ch = *src.rbegin(); // ignore trailing slash if (ch == '/') { std::string(src.begin(), src.end() - 1).swap(srcPath); } auto dstPath(dst); char chDst = *dst.rbegin(); // ignore trailing slash if (chDst == '/') { std::string(dst.begin(), dst.end() - 1).swap(dstPath); } // throw if source parent doesn't exist auto parentSrc(doGetParentCompoundFolder(srcPath)); if (!parentSrc) { throw TeaSafeException(TeaSafeError::NotFound); } // throw if destination parent doesn't exist auto parentDst(doGetParentCompoundFolder(dstPath)); if (!parentSrc) { throw TeaSafeException(TeaSafeError::NotFound); } // throw if destination already exists throwIfAlreadyExists(dstPath); // throw if source doesn't exist auto const filename(boost::filesystem::path(srcPath).filename().string()); auto childInfo(parentSrc->getEntryInfo(filename)); if (!childInfo) { throw TeaSafeException(TeaSafeError::NotFound); } // do moving / renaming // (i) Remove original entry metadata entry // (ii) Add new metadata entry with new file name parentSrc->putMetaDataOutOfUse(filename); auto dstFilename(boost::filesystem::path(dstPath).filename().string()); parentDst->writeNewMetaDataForEntry(dstFilename, childInfo->type(), childInfo->firstFileBlock()); }
void CoreFS::renameEntry(std::string const &src, std::string const &dst) { StateLock lock(m_stateMutex); auto srcPath(src); char ch = *src.rbegin(); // ignore trailing slash if (ch == '/') { std::string(src.begin(), src.end() - 1).swap(srcPath); } auto dstPath(dst); char chDst = *dst.rbegin(); // ignore trailing slash if (chDst == '/') { std::string(dst.begin(), dst.end() - 1).swap(dstPath); } // throw if source parent doesn't exist auto parentSrc(doGetParentCompoundFolder(srcPath)); if (!parentSrc) { throw KnoxCryptException(KnoxCryptError::NotFound); } // throw if destination parent doesn't exist auto parentDst(doGetParentCompoundFolder(dstPath)); if (!parentSrc) { throw KnoxCryptException(KnoxCryptError::NotFound); } // throw if destination already exists throwIfAlreadyExists(dstPath); // throw if source doesn't exist auto const srcPathBoost = ::boost::filesystem::path(srcPath); auto const filename(srcPathBoost.filename().string()); auto childInfo(parentSrc->getEntryInfo(filename)); if (!childInfo) { throw KnoxCryptException(KnoxCryptError::NotFound); } // do moving / renaming // (i) Remove original entry metadata entry // (ii) Add new metadata entry with new file name // NOTE: As an optimization, if entry is to be moved to // same parent folder, don't bother invalidating parent metadata, // just update the name. auto const dstPathBoost = ::boost::filesystem::path(dstPath); auto const destPathParent(dstPathBoost.parent_path()); auto const srcPathParent(srcPathBoost.parent_path()); auto dstFilename(dstPathBoost.filename().string()); if(destPathParent == srcPathParent) { parentSrc->updateMetaDataWithNewFilename(filename, dstFilename); } else { parentSrc->putMetaDataOutOfUse(filename); parentDst->writeNewMetaDataForEntry(dstFilename, childInfo->type(), childInfo->firstFileBlock()); } // Need to remove parent entry from cache this->removeFolderFromCache(srcPathParent); // Also need to remove src from cache if folder if(childInfo->type() == EntryType::FolderType) { this->removeFolderFromCache(srcPath); } // need to also walk over children?? // need to also check if this now f***s up the cached file resetCachedFile(srcPathBoost); }