*/
ReLeafFile* ReCryptFileSystem::buildFile(const ReFileMetaData& metadata)
{
- return new ReCryptLeafFile(metadata, fullName(metadata.m_node), m_logger2);
+ return new ReCryptLeafFile(metadata, fullName(metadata.m_node),
+ *this, m_logger2);
}
QString ReCryptFileSystem::canonicalPathOf(const QString& path)
* entries are deleted from the buffer. block.length() < MAX_ENTRY_SIZE
*/
void ReCryptDirectory::splitBlock(bool isLast, QByteArray& block){
- const FileEntry_t* src = reinterpret_cast<const FileEntry_t*>
- (block.constData());
ReFileMetaData file;
TRACE("splitBlock:\n");
IF_TRACE(int ix = 0);
/**
* Constructor.
*
- * @param meta the file infos
- * @param directory the assoziated directory
+ * @param metadata the file infos
+ * @param fullName the filename with path
+ * @param directory the assoziated directory
+ * @param logger the logger
+ *
*/
-ReCryptFile::ReCryptFile(const ReFileMetaData& meta, ReCryptDirectory& directory) :
- m_metaData(meta),
+ReCryptLeafFile::ReCryptLeafFile(const ReFileMetaData& metadata,
+ const QString& fullName, ReCryptDirectory& directory, ReLogger* logger) :
+ ReLeafFile(metadata, fullName, logger),
m_fullHostedName((directory.parentFS()->host().directory()
- + directory.parentFS()->buildHostedNode(meta.m_id)).toUtf8()),
+ + directory.parentFS()->buildHostedNode(metadata.m_id)).toUtf8()),
m_fileHeader(),
m_dataSum(0x7b644ac5d1187d25L, 0x6b85115d6064365bL),
m_sumOfEncrypted(0x7b644ac5d1187d25L, 0x6b85115d6064365bL),
/**
* Destructor.
*/
-ReCryptFile::~ReCryptFile()
+ReCryptLeafFile::~ReCryptLeafFile()
{
close();
}
* @return EC_SUCCESS: success<br>
* x
*/
-ReFileSystem::ErrorCode ReCryptFile::open(bool writeable)
+ReFileSystem::ErrorCode ReCryptLeafFile::open(bool writeable)
{
ReFileSystem::ErrorCode rc = ReFileSystem::EC_SUCCESS;
close();
* @param data data to write
* @return EC_SUCCESS: success
*/
-ReFileSystem::ErrorCode ReCryptFile::writeBlock(const QByteArray& data){
+ReFileSystem::ErrorCode ReCryptLeafFile::writeBlock(const QByteArray& data){
ReFileSystem::ErrorCode rc = ReFileSystem::EC_SUCCESS;
if (m_fp != NULL && fwrite(data.constData(), data.length(), 1, m_fp)
!= size_t(data.length())){
* @param data
* @return
*/
-ReFileSystem::ErrorCode ReCryptFile::write(const QByteArray& data)
+ReFileSystem::ErrorCode ReCryptLeafFile::write(const QByteArray& data)
{
ReFileSystem::ErrorCode rc = ReFileSystem::EC_SUCCESS;
m_dataSum.updateBlock(data);
* @param length the 64 bit length
* @return the dynamic length
*/
-uint32_t ReCryptFile::dynamicLength(int64_t length) {
+uint32_t ReCryptLeafFile::dynamicLength(int64_t length) {
while (length > 0xFFFFffffL)
length >>= 1;
return uint64_t(length);
*
* @return EC_SUCCESS: success
*/
-ReFileSystem::ErrorCode ReCryptFile::close()
+ReFileSystem::ErrorCode ReCryptLeafFile::close()
{
ReFileSystem::ErrorCode rc = ReFileSystem::EC_SUCCESS;
if (m_fp != NULL){
QByteArray& target = m_directory.fileBuffer();
int blockSize = m_directory.blockSize();
bool doFlush = m_dataSize > 0 && m_dataSize <= blockSize;
- m_metaData.m_size = m_dataSize;
+ m_meta.m_size = m_dataSize;
QByteArray checkSum = m_dataSum.digest();
// Add the data checksum at the end of the data block:
}
/**
- * Constructor.
+ * Reads data from the current position into a buffer.
*
- * @param metaData metadata of the file
- * @param fullName filename with path
- * @param logger the logger
- */
-ReCryptLeafFile::ReCryptLeafFile(const ReFileMetaData& metaData,
- const QString& fullName, ReLogger* logger) :
- ReLeafFile(metaData, fullName, logger)
-{
-
-}
-
-/**
- * Destructor.
+ * @param maxSize number of bytes to read
+ * @param buffer OUT: content of the file
+ * @return EC_SUCCESS or error code
*/
-ReCryptLeafFile::~ReCryptLeafFile()
-{
-
-}
-
-ReFileSystem::ErrorCode ReCryptLeafFile::open(bool writeable)
-{
- ReFileSystem::ErrorCode rc = ReFileSystem::EC_SUCCESS;
- return rc;
-}
-
-ReFileSystem::ErrorCode ReCryptLeafFile::close()
-{
- ReFileSystem::ErrorCode rc = ReFileSystem::EC_SUCCESS;
- return rc;
-}
-
ReFileSystem::ErrorCode ReCryptLeafFile::read(int size, QByteArray& buffer)
{
ReFileSystem::ErrorCode rc = ReFileSystem::EC_SUCCESS;
- return rc;
-}
-ReFileSystem::ErrorCode ReCryptLeafFile::write(const QByteArray& buffer)
-{
- ReFileSystem::ErrorCode rc = ReFileSystem::EC_SUCCESS;
return rc;
}
+
#define RECRYPTFILESYSTEM_HPP
class ReCryptFileSystem;
-
class ReCryptDirectory;
+
/**
* Administrates an encrypted file for reading / writing.
+ *
+ * A leaf file could not be a directory.
*/
-class ReCryptFile {
+class ReCryptLeafFile : public ReLeafFile{
public:
- ReCryptFile(const ReFileMetaData& metaData, ReCryptDirectory& directory);
- ~ReCryptFile();
+ ReCryptLeafFile(const ReFileMetaData& metaData, const QString& fullName,
+ ReCryptDirectory& directory, ReLogger* logger);
+ virtual ~ReCryptLeafFile();
public:
- ReFileSystem::ErrorCode open(bool writeable);
- ReFileSystem::ErrorCode write(const QByteArray& data);
- ReFileSystem::ErrorCode close();
+ virtual ReFileSystem::ErrorCode open(bool writeable);
+ virtual ReFileSystem::ErrorCode close();
+ virtual ReFileSystem::ErrorCode read(int size, QByteArray& buffer);
+ virtual ReFileSystem::ErrorCode write(const QByteArray& buffer);
public:
static uint32_t dynamicLength(int64_t length);
protected:
ReFileSystem::ErrorCode writeBlock(const QByteArray& data);
private:
- ReFileMetaData m_metaData;
QByteArray m_fullHostedName;
QByteArray m_fileHeader;
/// checksum of the unencrypted data
int m_maxFileId;
};
-/**
- * An abstract base class for leafs of the tree spanned by a filesystem.
- *
- * A leaf file could not be a directory.
- */
-class ReCryptLeafFile : public ReLeafFile{
-public:
- ReCryptLeafFile(const ReFileMetaData& metaData, const QString& fullName,
- ReLogger* logger);
- virtual ~ReCryptLeafFile();
-public:
- virtual ReFileSystem::ErrorCode open(bool writeable);
- virtual ReFileSystem::ErrorCode close();
- virtual ReFileSystem::ErrorCode read(int size, QByteArray& buffer);
- virtual ReFileSystem::ErrorCode write(const QByteArray& buffer);
-};
-
/**
* A filesystem with encrypted filenames and file content.
*
void ReFileSystem::setWriteable(bool writeable) {
m_writeable = writeable;
}
+
+/**
+ * Synchronizes recursivly the instances with another filesystem.
+ *
+ * The newer files in the source directory will be copied and files
+ * which does not exist in the target.
+ *
+ * @param fileMatcher only files matched by this will be processed
+ * @param dirMatcher only subdirectories matched by this will be processed
+ * @param verboseLevel defines the logging output (to stdout)
+ * @param source the source filesystem
+ */
+void ReFileSystem::synchronize(ReIncludeExcludeMatcher& fileMatcher,
+ ReIncludeExcludeMatcher& dirMatcher, VerboseLevel verboseLevel,
+ ReFileSystem& source)
+{
+ ReFileMetaDataList sourceList;
+ ReFileMetaData metaTarget;
+ QByteArray dir;
+ if (verboseLevel > V_SILENT)
+ dir = directory().toUtf8();
+ if (source.listInfos(fileMatcher, sourceList, LO_FILES) > 0){
+ QString sourceDir = source.directory();
+ QString targetDir = directory();
+ ReFileMetaDataList::iterator it;
+ for (it = sourceList.begin(); it != sourceList.end(); ++it){
+ bool alreadyExists = exists(it->m_node, &metaTarget);
+ if (! alreadyExists
+ // precision of 2 seconds:
+ || it->m_modified.currentMSecsSinceEpoch() - 2*1000
+ > metaTarget.m_modified.currentMSecsSinceEpoch()){
+ if (verboseLevel > V_SILENT)
+ printf("%c%s%s\n", alreadyExists ? '<' : '+',
+ dir.constData(), it->m_node.toUtf8().constData());
+ copy(*it, source);
+ } else if (verboseLevel > V_IMPORTANT){
+ printf("%c%s%s\n",
+ it->m_modified == metaTarget.m_modified ? '=' : '>',
+ dir.constData(), it->m_node.toUtf8().constData());
+ }
+ }
+ }
+ if (source.listInfos(dirMatcher, sourceList, LO_ONLY_DIRS_WITH_NAMEFILTER) > 0){
+ QString sourceDir = source.directory();
+ QString targetDir = directory();
+ ReFileMetaDataList::const_iterator it;
+ for (it = sourceList.cbegin(); it != sourceList.cend(); ++it){
+ bool alreadyExists = exists(it->m_node, &metaTarget);
+ if (! alreadyExists && S_ISDIR(metaTarget.m_mode)){
+ if (verboseLevel > V_SILENT)
+ printf("-%s%s\n", dir.constData(),
+ it->m_node.toUtf8().constData());
+ remove(metaTarget);
+ alreadyExists = exists(it->m_node, &metaTarget);
+ }
+ if (! alreadyExists){
+ if (verboseLevel > V_SILENT)
+ printf("&%s%s\n", dir.constData(),
+ it->m_node.toUtf8().constData());
+ if (makeDir(it->m_node) != EC_SUCCESS)
+ continue;
+ }
+ if (source.setDirectory(it->m_node) == EC_SUCCESS
+ && setDirectory(it->m_node) == EC_SUCCESS)
+ synchronize(fileMatcher, dirMatcher, verboseLevel, source);
+ source.setDirectory(sourceDir);
+ setDirectory(targetDir);
+ }
+ }
+}
/**
* Sets the size of the internal buffer for copy operations.
*
LO_DIRS = 2,
LO_ALL = 3,
LO_NAME_FILTER_FOR_DIRS = 4,
+ LO_ONLY_DIRS_WITH_NAMEFILTER = 6,
LO_ALL_AND_NAME_FILTER_FOR_DIRS = 7,
};
EC_INVALID_STATE,
EC_ALREADY_EXISTS,
};
+ enum VerboseLevel {
+ V_SILENT,
+ V_IMPORTANT,
+ V_VERBOSE,
+ V_DEBUG
+ };
public:
ReFileSystem(const QString& name, ReLogger* logger);
void setBlocksize(int blocksize);
void setOsPermissions(const ReOSPermissions& osPermissions);
void setWriteable(bool writeable);
+ void synchronize(ReIncludeExcludeMatcher& fileMatcher,
+ ReIncludeExcludeMatcher& dirMatcher,
+ VerboseLevel verboseLevel,
+ ReFileSystem& source);
bool writeable() const;
public:
static ReFileSystem* buildFromUrl(const QString& url);