Explorar o código

Move non-csync-dependent parts of FileSystem to src/common

This keep the csync-dependent parts in src/libsync, slitting the namespace
over two files.
This will allow moving SyncJournalDB to src/common as well.
Jocelyn Turcotte %!s(int64=8) %!d(string=hai) anos
pai
achega
4c2e078eac

+ 1 - 0
src/common/common.cmake

@@ -2,5 +2,6 @@
 # Essentially they could be in the same directory but are separate to
 # help keep track of the different code licenses.
 set(common_SOURCES
+    ${CMAKE_CURRENT_LIST_DIR}/filesystembase.cpp
     ${CMAKE_CURRENT_LIST_DIR}/utility.cpp
 )

+ 488 - 0
src/common/filesystembase.cpp

@@ -0,0 +1,488 @@
+/*
+ * Copyright (C) by Daniel Molkentin <danimo@owncloud.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "filesystembase.h"
+
+#include <QDateTime>
+#include <QFile>
+#include <QCryptographicHash>
+
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#ifdef ZLIB_FOUND
+#include <zlib.h>
+#endif
+
+#ifdef Q_OS_WIN
+#include <windows.h>
+#include <windef.h>
+#include <winbase.h>
+#include <fcntl.h>
+#include <io.h>
+#endif
+
+namespace OCC {
+
+Q_LOGGING_CATEGORY(lcFileSystem, "sync.filesystem", QtInfoMsg)
+
+QString FileSystem::longWinPath(const QString &inpath)
+{
+#ifdef Q_OS_WIN
+    return pathtoUNC(inpath);
+#else
+    return inpath;
+#endif
+}
+
+void FileSystem::setFileHidden(const QString &filename, bool hidden)
+{
+#ifdef _WIN32
+    QString fName = longWinPath(filename);
+    DWORD dwAttrs;
+
+    dwAttrs = GetFileAttributesW((wchar_t *)fName.utf16());
+
+    if (dwAttrs != INVALID_FILE_ATTRIBUTES) {
+        if (hidden && !(dwAttrs & FILE_ATTRIBUTE_HIDDEN)) {
+            SetFileAttributesW((wchar_t *)fName.utf16(), dwAttrs | FILE_ATTRIBUTE_HIDDEN);
+        } else if (!hidden && (dwAttrs & FILE_ATTRIBUTE_HIDDEN)) {
+            SetFileAttributesW((wchar_t *)fName.utf16(), dwAttrs & ~FILE_ATTRIBUTE_HIDDEN);
+        }
+    }
+#else
+    Q_UNUSED(filename);
+    Q_UNUSED(hidden);
+#endif
+}
+
+static QFile::Permissions getDefaultWritePermissions()
+{
+    QFile::Permissions result = QFile::WriteUser;
+#ifndef Q_OS_WIN
+    mode_t mask = umask(0);
+    umask(mask);
+    if (!(mask & S_IWGRP)) {
+        result |= QFile::WriteGroup;
+    }
+    if (!(mask & S_IWOTH)) {
+        result |= QFile::WriteOther;
+    }
+#endif
+    return result;
+}
+
+void FileSystem::setFileReadOnly(const QString &filename, bool readonly)
+{
+    QFile file(filename);
+    QFile::Permissions permissions = file.permissions();
+
+    QFile::Permissions allWritePermissions =
+        QFile::WriteUser | QFile::WriteGroup | QFile::WriteOther | QFile::WriteOwner;
+    static QFile::Permissions defaultWritePermissions = getDefaultWritePermissions();
+
+    permissions &= ~allWritePermissions;
+    if (!readonly) {
+        permissions |= defaultWritePermissions;
+    }
+    file.setPermissions(permissions);
+}
+
+void FileSystem::setFolderMinimumPermissions(const QString &filename)
+{
+#ifdef Q_OS_MAC
+    QFile::Permissions perm = QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner;
+    QFile file(filename);
+    file.setPermissions(perm);
+#else
+    Q_UNUSED(filename);
+#endif
+}
+
+
+void FileSystem::setFileReadOnlyWeak(const QString &filename, bool readonly)
+{
+    QFile file(filename);
+    QFile::Permissions permissions = file.permissions();
+
+    if (!readonly && (permissions & QFile::WriteOwner)) {
+        return; // already writable enough
+    }
+
+    setFileReadOnly(filename, readonly);
+}
+
+bool FileSystem::rename(const QString &originFileName,
+    const QString &destinationFileName,
+    QString *errorString)
+{
+    bool success = false;
+    QString error;
+#ifdef Q_OS_WIN
+    QString orig = longWinPath(originFileName);
+    QString dest = longWinPath(destinationFileName);
+
+    if (isLnkFile(originFileName) || isLnkFile(destinationFileName)) {
+        success = MoveFileEx((wchar_t *)orig.utf16(),
+            (wchar_t *)dest.utf16(),
+            MOVEFILE_COPY_ALLOWED | MOVEFILE_WRITE_THROUGH);
+        if (!success) {
+            wchar_t *string = 0;
+            FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
+                NULL, ::GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+                (LPWSTR)&string, 0, NULL);
+
+            error = QString::fromWCharArray(string);
+            LocalFree((HLOCAL)string);
+        }
+    } else
+#endif
+    {
+        QFile orig(originFileName);
+        success = orig.rename(destinationFileName);
+        if (!success) {
+            error = orig.errorString();
+        }
+    }
+
+    if (!success) {
+        qCWarning(lcFileSystem) << "Error renaming file" << originFileName
+                                << "to" << destinationFileName
+                                << "failed: " << error;
+        if (errorString) {
+            *errorString = error;
+        }
+    }
+    return success;
+}
+
+bool FileSystem::uncheckedRenameReplace(const QString &originFileName,
+    const QString &destinationFileName,
+    QString *errorString)
+{
+#ifndef Q_OS_WIN
+    bool success;
+    QFile orig(originFileName);
+    // We want a rename that also overwites.  QFile::rename does not overwite.
+    // Qt 5.1 has QSaveFile::renameOverwrite we could use.
+    // ### FIXME
+    success = true;
+    bool destExists = fileExists(destinationFileName);
+    if (destExists && !QFile::remove(destinationFileName)) {
+        *errorString = orig.errorString();
+        qCWarning(lcFileSystem) << "Target file could not be removed.";
+        success = false;
+    }
+    if (success) {
+        success = orig.rename(destinationFileName);
+    }
+    if (!success) {
+        *errorString = orig.errorString();
+        qCWarning(lcFileSystem) << "Renaming temp file to final failed: " << *errorString;
+        return false;
+    }
+
+#else //Q_OS_WIN
+    // You can not overwrite a read-only file on windows.
+    if (!QFileInfo(destinationFileName).isWritable()) {
+        setFileReadOnly(destinationFileName, false);
+    }
+
+    BOOL ok;
+    QString orig = longWinPath(originFileName);
+    QString dest = longWinPath(destinationFileName);
+
+    ok = MoveFileEx((wchar_t *)orig.utf16(),
+        (wchar_t *)dest.utf16(),
+        MOVEFILE_REPLACE_EXISTING + MOVEFILE_COPY_ALLOWED + MOVEFILE_WRITE_THROUGH);
+    if (!ok) {
+        wchar_t *string = 0;
+        FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
+            NULL, ::GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+            (LPWSTR)&string, 0, NULL);
+
+        *errorString = QString::fromWCharArray(string);
+        qCWarning(lcFileSystem) << "Renaming temp file to final failed: " << *errorString;
+        LocalFree((HLOCAL)string);
+        return false;
+    }
+#endif
+    return true;
+}
+
+bool FileSystem::openAndSeekFileSharedRead(QFile *file, QString *errorOrNull, qint64 seek)
+{
+    QString errorDummy;
+    // avoid many if (errorOrNull) later.
+    QString &error = errorOrNull ? *errorOrNull : errorDummy;
+    error.clear();
+
+#ifdef Q_OS_WIN
+    //
+    // The following code is adapted from Qt's QFSFileEnginePrivate::nativeOpen()
+    // by including the FILE_SHARE_DELETE share mode.
+    //
+
+    // Enable full sharing.
+    DWORD shareMode = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
+
+    int accessRights = GENERIC_READ;
+    DWORD creationDisp = OPEN_EXISTING;
+
+    // Create the file handle.
+    SECURITY_ATTRIBUTES securityAtts = { sizeof(SECURITY_ATTRIBUTES), NULL, FALSE };
+    QString fName = longWinPath(file->fileName());
+
+    HANDLE fileHandle = CreateFileW(
+        (const wchar_t *)fName.utf16(),
+        accessRights,
+        shareMode,
+        &securityAtts,
+        creationDisp,
+        FILE_ATTRIBUTE_NORMAL,
+        NULL);
+
+    // Bail out on error.
+    if (fileHandle == INVALID_HANDLE_VALUE) {
+        error = qt_error_string();
+        return false;
+    }
+
+    // Convert the HANDLE to an fd and pass it to QFile's foreign-open
+    // function. The fd owns the handle, so when QFile later closes
+    // the fd the handle will be closed too.
+    int fd = _open_osfhandle((intptr_t)fileHandle, _O_RDONLY);
+    if (fd == -1) {
+        error = "could not make fd from handle";
+        return false;
+    }
+    if (!file->open(fd, QIODevice::ReadOnly, QFile::AutoCloseHandle)) {
+        error = file->errorString();
+        return false;
+    }
+
+    // Seek to the right spot
+    LARGE_INTEGER *li = reinterpret_cast<LARGE_INTEGER *>(&seek);
+    DWORD newFilePointer = SetFilePointer(fileHandle, li->LowPart, &li->HighPart, FILE_BEGIN);
+    if (newFilePointer == 0xFFFFFFFF && GetLastError() != NO_ERROR) {
+        error = qt_error_string();
+        return false;
+    }
+
+    return true;
+#else
+    if (!file->open(QFile::ReadOnly)) {
+        error = file->errorString();
+        return false;
+    }
+    if (!file->seek(seek)) {
+        error = file->errorString();
+        return false;
+    }
+    return true;
+#endif
+}
+
+#ifdef Q_OS_WIN
+static bool fileExistsWin(const QString &filename)
+{
+    WIN32_FIND_DATA FindFileData;
+    HANDLE hFind;
+    QString fName = FileSystem::longWinPath(filename);
+
+    hFind = FindFirstFileW((wchar_t *)fName.utf16(), &FindFileData);
+    if (hFind == INVALID_HANDLE_VALUE) {
+        return false;
+    }
+    FindClose(hFind);
+    return true;
+}
+#endif
+
+bool FileSystem::fileExists(const QString &filename, const QFileInfo &fileInfo)
+{
+#ifdef Q_OS_WIN
+    if (isLnkFile(filename)) {
+        // Use a native check.
+        return fileExistsWin(filename);
+    }
+#endif
+    bool re = fileInfo.exists();
+    // if the filename is different from the filename in fileInfo, the fileInfo is
+    // not valid. There needs to be one initialised here. Otherwise the incoming
+    // fileInfo is re-used.
+    if (fileInfo.filePath() != filename) {
+        QFileInfo myFI(filename);
+        re = myFI.exists();
+    }
+    return re;
+}
+
+#ifdef Q_OS_WIN
+QString FileSystem::fileSystemForPath(const QString &path)
+{
+    // See also QStorageInfo (Qt >=5.4) and GetVolumeInformationByHandleW (>= Vista)
+    QString drive = path.left(2);
+    if (!drive.endsWith(":"))
+        return QString();
+    drive.append('\\');
+
+    const size_t fileSystemBufferSize = 4096;
+    TCHAR fileSystemBuffer[fileSystemBufferSize];
+
+    if (!GetVolumeInformationW(
+            reinterpret_cast<LPCWSTR>(drive.utf16()),
+            NULL, 0,
+            NULL, NULL, NULL,
+            fileSystemBuffer, fileSystemBufferSize)) {
+        return QString();
+    }
+    return QString::fromUtf16(reinterpret_cast<const ushort *>(fileSystemBuffer));
+}
+#endif
+
+#define BUFSIZE qint64(500 * 1024) // 500 KiB
+
+static QByteArray readToCrypto(const QString &filename, QCryptographicHash::Algorithm algo)
+{
+    QFile file(filename);
+    const qint64 bufSize = qMin(BUFSIZE, file.size() + 1);
+    QByteArray buf(bufSize, Qt::Uninitialized);
+    QByteArray arr;
+    QCryptographicHash crypto(algo);
+
+    if (file.open(QIODevice::ReadOnly)) {
+        qint64 size;
+        while (!file.atEnd()) {
+            size = file.read(buf.data(), bufSize);
+            if (size > 0) {
+                crypto.addData(buf.data(), size);
+            }
+        }
+        arr = crypto.result().toHex();
+    }
+    return arr;
+}
+
+QByteArray FileSystem::calcMd5(const QString &filename)
+{
+    return readToCrypto(filename, QCryptographicHash::Md5);
+}
+
+QByteArray FileSystem::calcSha1(const QString &filename)
+{
+    return readToCrypto(filename, QCryptographicHash::Sha1);
+}
+
+#ifdef ZLIB_FOUND
+QByteArray FileSystem::calcAdler32(const QString &filename)
+{
+    QFile file(filename);
+    const qint64 bufSize = qMin(BUFSIZE, file.size() + 1);
+    QByteArray buf(bufSize, Qt::Uninitialized);
+
+    unsigned int adler = adler32(0L, Z_NULL, 0);
+    if (file.open(QIODevice::ReadOnly)) {
+        qint64 size;
+        while (!file.atEnd()) {
+            size = file.read(buf.data(), bufSize);
+            if (size > 0)
+                adler = adler32(adler, (const Bytef *)buf.data(), size);
+        }
+    }
+
+    return QByteArray::number(adler, 16);
+}
+#endif
+
+QString FileSystem::makeConflictFileName(const QString &fn, const QDateTime &dt)
+{
+    QString conflictFileName(fn);
+    // Add _conflict-XXXX  before the extension.
+    int dotLocation = conflictFileName.lastIndexOf('.');
+    // If no extension, add it at the end  (take care of cases like foo/.hidden or foo.bar/file)
+    if (dotLocation <= conflictFileName.lastIndexOf('/') + 1) {
+        dotLocation = conflictFileName.size();
+    }
+    QString timeString = dt.toString("yyyyMMdd-hhmmss");
+
+    // Additional marker
+    QByteArray conflictFileUserName = qgetenv("CSYNC_CONFLICT_FILE_USERNAME");
+    if (conflictFileUserName.isEmpty())
+        conflictFileName.insert(dotLocation, "_conflict-" + timeString);
+    else
+        conflictFileName.insert(dotLocation, "_conflict_" + QString::fromUtf8(conflictFileUserName) + "-" + timeString);
+
+    return conflictFileName;
+}
+
+bool FileSystem::remove(const QString &fileName, QString *errorString)
+{
+#ifdef Q_OS_WIN
+    // You cannot delete a read-only file on windows, but we want to
+    // allow that.
+    if (!QFileInfo(fileName).isWritable()) {
+        setFileReadOnly(fileName, false);
+    }
+#endif
+    QFile f(fileName);
+    if (!f.remove()) {
+        if (errorString) {
+            *errorString = f.errorString();
+        }
+        return false;
+    }
+    return true;
+}
+
+bool FileSystem::isFileLocked(const QString &fileName)
+{
+#ifdef Q_OS_WIN
+    const wchar_t *wuri = reinterpret_cast<const wchar_t *>(fileName.utf16());
+    // Check if file exists
+    DWORD attr = GetFileAttributesW(wuri);
+    if (attr != INVALID_FILE_ATTRIBUTES) {
+        // Try to open the file with as much access as possible..
+        HANDLE win_h = CreateFileW(
+            wuri,
+            GENERIC_READ | GENERIC_WRITE,
+            FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+            NULL, OPEN_EXISTING,
+            FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS,
+            NULL);
+
+        if (win_h == INVALID_HANDLE_VALUE) {
+            /* could not be opened, so locked? */
+            /* 32 == ERROR_SHARING_VIOLATION */
+            return true;
+        } else {
+            CloseHandle(win_h);
+        }
+    }
+#else
+    Q_UNUSED(fileName);
+#endif
+    return false;
+}
+
+bool FileSystem::isLnkFile(const QString &filename)
+{
+    return filename.endsWith(".lnk");
+}
+
+} // namespace OCC

+ 189 - 0
src/common/filesystembase.h

@@ -0,0 +1,189 @@
+/*
+ * Copyright (C) by Olivier Goffart <ogoffart@owncloud.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#pragma once
+
+#include "config.h"
+
+#include <QString>
+#include <ctime>
+#include <QFileInfo>
+#include <QLoggingCategory>
+
+#include <ocsynclib.h>
+
+class QFile;
+
+namespace OCC {
+
+OCSYNC_EXPORT Q_DECLARE_LOGGING_CATEGORY(lcFileSystem)
+
+/**
+ *  \addtogroup libsync
+ *  @{
+ */
+
+/**
+ * @brief This file contains file system helper
+ */
+namespace FileSystem {
+
+    /**
+     * @brief Mark the file as hidden  (only has effects on windows)
+     */
+    void OCSYNC_EXPORT setFileHidden(const QString &filename, bool hidden);
+
+    /**
+     * @brief Marks the file as read-only.
+     *
+     * On linux this either revokes all 'w' permissions or restores permissions
+     * according to the umask.
+     */
+    void OCSYNC_EXPORT setFileReadOnly(const QString &filename, bool readonly);
+
+    /**
+     * @brief Marks the file as read-only.
+     *
+     * It's like setFileReadOnly(), but weaker: if readonly is false and the user
+     * already has write permissions, no change to the permissions is made.
+     *
+     * This means that it will preserve explicitly set rw-r--r-- permissions even
+     * when the umask is 0002. (setFileReadOnly() would adjust to rw-rw-r--)
+     */
+    void OCSYNC_EXPORT setFileReadOnlyWeak(const QString &filename, bool readonly);
+
+    /**
+     * @brief Try to set permissions so that other users on the local machine can not
+     * go into the folder.
+     */
+    void OCSYNC_EXPORT setFolderMinimumPermissions(const QString &filename);
+
+    /** convert a "normal" windows path into a path that can be 32k chars long. */
+    QString OCSYNC_EXPORT longWinPath(const QString &inpath);
+
+    /**
+     * @brief Checks whether a file exists.
+     *
+     * Use this over QFileInfo::exists() and QFile::exists() to avoid bugs with lnk
+     * files, see above.
+     */
+    bool OCSYNC_EXPORT fileExists(const QString &filename, const QFileInfo & = QFileInfo());
+
+    /**
+     * @brief Rename the file \a originFileName to \a destinationFileName.
+     *
+     * It behaves as QFile::rename() but handles .lnk files correctly on Windows.
+     */
+    bool OCSYNC_EXPORT rename(const QString &originFileName,
+        const QString &destinationFileName,
+        QString *errorString = NULL);
+
+    /**
+     * Rename the file \a originFileName to \a destinationFileName, and
+     * overwrite the destination if it already exists - without extra checks.
+     */
+    bool OCSYNC_EXPORT uncheckedRenameReplace(const QString &originFileName,
+        const QString &destinationFileName,
+        QString *errorString);
+
+    /**
+     * Removes a file.
+     *
+     * Equivalent to QFile::remove(), except on Windows, where it will also
+     * successfully remove read-only files.
+     */
+    bool OCSYNC_EXPORT remove(const QString &fileName, QString *errorString = 0);
+
+    /**
+     * Replacement for QFile::open(ReadOnly) followed by a seek().
+     * This version sets a more permissive sharing mode on Windows.
+     *
+     * Warning: The resulting file may have an empty fileName and be unsuitable for use
+     * with QFileInfo! Calling seek() on the QFile with >32bit signed values will fail!
+     */
+    bool OCSYNC_EXPORT openAndSeekFileSharedRead(QFile *file, QString *error, qint64 seek);
+
+#ifdef Q_OS_WIN
+    /**
+     * Returns the file system used at the given path.
+     */
+    QString fileSystemForPath(const QString &path);
+#endif
+
+    QByteArray OCSYNC_EXPORT calcMd5(const QString &fileName);
+    QByteArray OCSYNC_EXPORT calcSha1(const QString &fileName);
+#ifdef ZLIB_FOUND
+    QByteArray OCSYNC_EXPORT calcAdler32(const QString &fileName);
+#endif
+
+    /**
+     * Returns a file name based on \a fn that's suitable for a conflict.
+     */
+    QString OCSYNC_EXPORT makeConflictFileName(const QString &fn, const QDateTime &dt);
+
+    /**
+     * Returns true when a file is locked. (Windows only)
+     */
+    bool OCSYNC_EXPORT isFileLocked(const QString &fileName);
+
+    bool OCSYNC_EXPORT isLnkFile(const QString &filename);
+
+    /*
+     * This function takes a path and converts it to a UNC representation of the
+     * string. That means that it prepends a \\?\ (unless already UNC) and converts
+     * all slashes to backslashes.
+     *
+     * Note the following:
+     *  - The string must be absolute.
+     *  - it needs to contain a drive character to be a valid UNC
+     *  - A conversion is only done if the path len is larger than 245. Otherwise
+     *    the windows API functions work with the normal "unixoid" representation too.
+     */
+    template<typename S>
+    S pathtoUNC(const S &str)
+    {
+        int len = 0;
+        S longStr;
+
+        len = str.length();
+        longStr.reserve(len+4);
+
+        // prepend \\?\ and convert '/' => '\' to support long names
+        if( str[0] == '/' || str[0] == '\\' ) {
+            // Don't prepend if already UNC
+            if( !(len > 1 && (str[1] == '/' || str[1] == '\\')) ) {
+                longStr.append("\\\\?");
+            }
+        } else {
+            longStr.append("\\\\?\\"); // prepend string by this four magic chars.
+        }
+        longStr += str;
+
+        /* replace all occurences of / with the windows native \ */
+        
+        for (auto it = longStr.begin(); it != longStr.end(); ++it) {
+            if(*it == '/') {
+                *it = '\\';
+            }
+        }
+        return longStr;
+    }
+}
+
+/** @} */
+}

+ 5 - 0
src/csync/CMakeLists.txt

@@ -128,6 +128,11 @@ generate_export_header( ${CSYNC_LIBRARY}
 target_link_libraries(${CSYNC_LIBRARY} ${CSYNC_LINK_LIBRARIES})
 #target_link_libraries(${CSYNC_LIBRARY}_static ${CSYNC_LINK_LIBRARIES})
 
+if(ZLIB_FOUND)
+  target_link_libraries(${CSYNC_LIBRARY} ${ZLIB_LIBRARIES})
+  include_directories(${ZLIB_INCLUDE_DIRS})
+endif(ZLIB_FOUND)
+
 find_package(Qt5Core REQUIRED)
 qt5_use_modules(${CSYNC_LIBRARY} Core)
 

+ 0 - 60
src/csync/std/c_path.c

@@ -390,63 +390,3 @@ int c_parse_uri(const char *uri,
 
   return -1;
 }
-
-
-/*
- * This function takes a path and converts it to a UNC representation of the
- * string. That means that it prepends a \\?\ (unless already UNC) and converts
- * all slashes to backslashes.
- *
- * Note the following:
- *  - The string must be absolute.
- *  - it needs to contain a drive character to be a valid UNC
- *  - A conversion is only done if the path len is larger than 245. Otherwise
- *    the windows API functions work with the normal "unixoid" representation too.
- *
- *  This function allocates memory that must be freed by the caller.
- */
- const char *c_path_to_UNC(const char *str)
- {
-     int len = 0;
-     char *longStr = NULL;
-
-     len = strlen(str);
-     longStr = c_malloc(len+5);
-     *longStr = '\0';
-
-     // prepend \\?\ and convert '/' => '\' to support long names
-     if( str[0] == '/' || str[0] == '\\' ) {
-         // Don't prepend if already UNC
-         if( !(len > 1 && (str[1] == '/' || str[1] == '\\')) ) {
-            strcpy( longStr, "\\\\?");
-         }
-     } else {
-         strcpy( longStr, "\\\\?\\"); // prepend string by this four magic chars.
-     }
-     strncat( longStr, str, len );
-
-     /* replace all occurences of / with the windows native \ */
-     char *c = longStr;
-     for (; *c; ++c) {
-         if(*c == '/') {
-             *c = '\\';
-         }
-     }
-     return longStr;
- }
-
- mbchar_t* c_utf8_path_to_locale(const char *str)
- {
-     if( str == NULL ) {
-         return NULL;
-     } else {
- #ifdef _WIN32
-         const char *unc_str = c_path_to_UNC(str);
-         mbchar_t *dst = c_utf8_string_to_locale(unc_str);
-         SAFE_FREE(unc_str);
-         return dst;
- #else
-         return c_utf8_string_to_locale(str);
- #endif
-     }
- }

+ 0 - 28
src/csync/std/c_path.h

@@ -112,34 +112,6 @@ typedef struct
     char * extension;
 } C_PATHINFO;
 
-/**
- * @brief c_path_to_UNC converts a unixoid path to UNC format.
- *
- * It converts the '/' to '\' and prepends \\?\ to the path.
- *
- * A proper windows path has to have a drive letter, otherwise it is not
- * valid UNC.
- *
- * @param str The path to convert
- *
- * @return a pointer to the converted string. Caller has to free it.
- */
-const char *c_path_to_UNC(const char *str);
-
-/**
- * @brief c_utf8_path_to_locale converts a unixoid path to the locale aware format
- *
- * On windows, it converts to UNC and multibyte.
- * On Mac, it converts to the correct utf8 using iconv.
- * On Linux, it returns utf8
- *
- * @param str The path to convert
- *
- * @return a pointer to the converted string. Caller has to free it using the
- *         function c_free_locale_string.
- */
-mbchar_t* c_utf8_path_to_locale(const char *str);
-
 /**
  * }@
  */

+ 16 - 0
src/csync/std/c_utf8.cpp

@@ -37,6 +37,7 @@
 
 #include "c_alloc.h"
 #include "c_string.h"
+#include "common/filesystembase.h"
 
 /* Convert a locale String to UTF8 */
 QByteArray c_utf8_from_locale(const mbchar_t *wstr)
@@ -99,4 +100,19 @@ mbchar_t* c_utf8_string_to_locale(const char *str)
 #endif
 }
 
+ mbchar_t* c_utf8_path_to_locale(const char *str)
+ {
+     if( str == NULL ) {
+         return NULL;
+     } else {
+ #ifdef _WIN32
+         QByteArray unc_str = OCC::FileSystem::pathtoUNC(QByteArray::fromRawData(str, strlen(str)));
+         mbchar_t *dst = c_utf8_string_to_locale(unc_str);
+         return dst;
+ #else
+         return c_utf8_string_to_locale(str);
+ #endif
+     }
+ }
+
 }

+ 14 - 0
src/csync/std/c_utf8.h

@@ -91,6 +91,20 @@ extern "C" {
  */
 mbchar_t* c_utf8_string_to_locale(const char *wstr);
 
+/**
+ * @brief c_utf8_path_to_locale converts a unixoid path to the locale aware format
+ *
+ * On windows, it converts to UNC and multibyte.
+ * On Mac, it converts to the correct utf8 using iconv.
+ * On Linux, it returns utf8
+ *
+ * @param str The path to convert
+ *
+ * @return a pointer to the converted string. Caller has to free it using the
+ *         function c_free_locale_string.
+ */
+mbchar_t* c_utf8_path_to_locale(const char *str);
+
 /**
  * @brief Free buffer malloced by c_utf8_to_locale().
  *

+ 0 - 5
src/libsync/CMakeLists.txt

@@ -115,11 +115,6 @@ if(INOTIFY_FOUND)
     link_directories(${INOTIFY_LIBRARY_DIR})
 endif()
 
-if(ZLIB_FOUND)
-    list(APPEND libsync_LINK_TARGETS ${ZLIB_LIBRARIES})
-    include_directories(${ZLIB_INCLUDE_DIRS})
-endif(ZLIB_FOUND)
-
 add_library(${synclib_NAME} SHARED ${libsync_SRCS} ${syncMoc})
 GENERATE_EXPORT_HEADER( ${synclib_NAME}
 	BASE_NAME ${synclib_NAME}

+ 0 - 487
src/libsync/filesystem.cpp

@@ -17,21 +17,6 @@
 #include "common/utility.h"
 #include <QFile>
 #include <QFileInfo>
-#include <QLoggingCategory>
-#include <QCoreApplication>
-#include <QCryptographicHash>
-
-#ifdef ZLIB_FOUND
-#include <zlib.h>
-#endif
-
-#ifdef Q_OS_WIN
-#include <windows.h>
-#include <windef.h>
-#include <winbase.h>
-#include <fcntl.h>
-#include <io.h>
-#endif
 
 // We use some internals of csync:
 extern "C" int c_utimes(const char *, const struct timeval *);
@@ -44,20 +29,6 @@ extern "C" int c_utimes(const char *, const struct timeval *);
 
 namespace OCC {
 
-Q_LOGGING_CATEGORY(lcFileSystem, "sync.filesystem", QtInfoMsg)
-
-QString FileSystem::longWinPath(const QString &inpath)
-{
-#ifdef Q_OS_WIN
-    const char *unc_str = c_path_to_UNC(inpath.toUtf8());
-    QString path = QString::fromUtf8(unc_str);
-    free((void*)unc_str);
-    return path;
-#else
-    return inpath;
-#endif
-}
-
 bool FileSystem::fileEquals(const QString &fn1, const QString &fn2)
 {
     // compare two files with given filename and return true if they have the same content
@@ -91,83 +62,6 @@ bool FileSystem::fileEquals(const QString &fn1, const QString &fn2)
     return false;
 }
 
-void FileSystem::setFileHidden(const QString &filename, bool hidden)
-{
-#ifdef _WIN32
-    QString fName = longWinPath(filename);
-    DWORD dwAttrs;
-
-    dwAttrs = GetFileAttributesW((wchar_t *)fName.utf16());
-
-    if (dwAttrs != INVALID_FILE_ATTRIBUTES) {
-        if (hidden && !(dwAttrs & FILE_ATTRIBUTE_HIDDEN)) {
-            SetFileAttributesW((wchar_t *)fName.utf16(), dwAttrs | FILE_ATTRIBUTE_HIDDEN);
-        } else if (!hidden && (dwAttrs & FILE_ATTRIBUTE_HIDDEN)) {
-            SetFileAttributesW((wchar_t *)fName.utf16(), dwAttrs & ~FILE_ATTRIBUTE_HIDDEN);
-        }
-    }
-#else
-    Q_UNUSED(filename);
-    Q_UNUSED(hidden);
-#endif
-}
-
-static QFile::Permissions getDefaultWritePermissions()
-{
-    QFile::Permissions result = QFile::WriteUser;
-#ifndef Q_OS_WIN
-    mode_t mask = umask(0);
-    umask(mask);
-    if (!(mask & S_IWGRP)) {
-        result |= QFile::WriteGroup;
-    }
-    if (!(mask & S_IWOTH)) {
-        result |= QFile::WriteOther;
-    }
-#endif
-    return result;
-}
-
-void FileSystem::setFileReadOnly(const QString &filename, bool readonly)
-{
-    QFile file(filename);
-    QFile::Permissions permissions = file.permissions();
-
-    QFile::Permissions allWritePermissions =
-        QFile::WriteUser | QFile::WriteGroup | QFile::WriteOther | QFile::WriteOwner;
-    static QFile::Permissions defaultWritePermissions = getDefaultWritePermissions();
-
-    permissions &= ~allWritePermissions;
-    if (!readonly) {
-        permissions |= defaultWritePermissions;
-    }
-    file.setPermissions(permissions);
-}
-
-void FileSystem::setFolderMinimumPermissions(const QString &filename)
-{
-#ifdef Q_OS_MAC
-    QFile::Permissions perm = QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner;
-    QFile file(filename);
-    file.setPermissions(perm);
-#else
-    Q_UNUSED(filename);
-#endif
-}
-
-
-void FileSystem::setFileReadOnlyWeak(const QString &filename, bool readonly)
-{
-    QFile file(filename);
-    QFile::Permissions permissions = file.permissions();
-
-    if (!readonly && (permissions & QFile::WriteOwner)) {
-        return; // already writable enough
-    }
-
-    setFileReadOnly(filename, readonly);
-}
-
 time_t FileSystem::getModTime(const QString &filename)
 {
     csync_file_stat_t stat;
@@ -197,57 +91,6 @@ bool FileSystem::setModTime(const QString &filename, time_t modTime)
     return true;
 }
 
-#ifdef Q_OS_WIN
-static bool isLnkFile(const QString &filename)
-{
-    return filename.endsWith(".lnk");
-}
-#endif
-
-bool FileSystem::rename(const QString &originFileName,
-    const QString &destinationFileName,
-    QString *errorString)
-{
-    bool success = false;
-    QString error;
-#ifdef Q_OS_WIN
-    QString orig = longWinPath(originFileName);
-    QString dest = longWinPath(destinationFileName);
-
-    if (isLnkFile(originFileName) || isLnkFile(destinationFileName)) {
-        success = MoveFileEx((wchar_t *)orig.utf16(),
-            (wchar_t *)dest.utf16(),
-            MOVEFILE_COPY_ALLOWED | MOVEFILE_WRITE_THROUGH);
-        if (!success) {
-            wchar_t *string = 0;
-            FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
-                NULL, ::GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
-                (LPWSTR)&string, 0, NULL);
-
-            error = QString::fromWCharArray(string);
-            LocalFree((HLOCAL)string);
-        }
-    } else
-#endif
-    {
-        QFile orig(originFileName);
-        success = orig.rename(destinationFileName);
-        if (!success) {
-            error = orig.errorString();
-        }
-    }
-
-    if (!success) {
-        qCWarning(lcFileSystem) << "Error renaming file" << originFileName
-                                << "to" << destinationFileName
-                                << "failed: " << error;
-        if (errorString) {
-            *errorString = error;
-        }
-    }
-    return success;
-}
-
 bool FileSystem::fileChanged(const QString &fileName,
     qint64 previousSize,
     time_t previousMtime)
@@ -271,151 +114,6 @@ bool FileSystem::verifyFileUnchanged(const QString &fileName,
     return true;
 }
 
-bool FileSystem::renameReplace(const QString &originFileName,
-    const QString &destinationFileName,
-    qint64 destinationSize,
-    time_t destinationMtime,
-    QString *errorString)
-{
-    if (fileExists(destinationFileName)
-        && fileChanged(destinationFileName, destinationSize, destinationMtime)) {
-        if (errorString) {
-            *errorString = qApp->translate("FileSystem",
-                "The destination file has an unexpected size or modification time");
-        }
-        return false;
-    }
-
-    return uncheckedRenameReplace(originFileName, destinationFileName, errorString);
-}
-
-bool FileSystem::uncheckedRenameReplace(const QString &originFileName,
-    const QString &destinationFileName,
-    QString *errorString)
-{
-#ifndef Q_OS_WIN
-    bool success;
-    QFile orig(originFileName);
-    // We want a rename that also overwites.  QFile::rename does not overwite.
-    // Qt 5.1 has QSaveFile::renameOverwrite we could use.
-    // ### FIXME
-    success = true;
-    bool destExists = fileExists(destinationFileName);
-    if (destExists && !QFile::remove(destinationFileName)) {
-        *errorString = orig.errorString();
-        qCWarning(lcFileSystem) << "Target file could not be removed.";
-        success = false;
-    }
-    if (success) {
-        success = orig.rename(destinationFileName);
-    }
-    if (!success) {
-        *errorString = orig.errorString();
-        qCWarning(lcFileSystem) << "Renaming temp file to final failed: " << *errorString;
-        return false;
-    }
-
-#else //Q_OS_WIN
-    // You can not overwrite a read-only file on windows.
-    if (!QFileInfo(destinationFileName).isWritable()) {
-        setFileReadOnly(destinationFileName, false);
-    }
-
-    BOOL ok;
-    QString orig = longWinPath(originFileName);
-    QString dest = longWinPath(destinationFileName);
-
-    ok = MoveFileEx((wchar_t *)orig.utf16(),
-        (wchar_t *)dest.utf16(),
-        MOVEFILE_REPLACE_EXISTING + MOVEFILE_COPY_ALLOWED + MOVEFILE_WRITE_THROUGH);
-    if (!ok) {
-        wchar_t *string = 0;
-        FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
-            NULL, ::GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
-            (LPWSTR)&string, 0, NULL);
-
-        *errorString = QString::fromWCharArray(string);
-        qCWarning(lcFileSystem) << "Renaming temp file to final failed: " << *errorString;
-        LocalFree((HLOCAL)string);
-        return false;
-    }
-#endif
-    return true;
-}
-
-bool FileSystem::openAndSeekFileSharedRead(QFile *file, QString *errorOrNull, qint64 seek)
-{
-    QString errorDummy;
-    // avoid many if (errorOrNull) later.
-    QString &error = errorOrNull ? *errorOrNull : errorDummy;
-    error.clear();
-
-#ifdef Q_OS_WIN
-    //
-    // The following code is adapted from Qt's QFSFileEnginePrivate::nativeOpen()
-    // by including the FILE_SHARE_DELETE share mode.
-    //
-
-    // Enable full sharing.
-    DWORD shareMode = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
-
-    int accessRights = GENERIC_READ;
-    DWORD creationDisp = OPEN_EXISTING;
-
-    // Create the file handle.
-    SECURITY_ATTRIBUTES securityAtts = { sizeof(SECURITY_ATTRIBUTES), NULL, FALSE };
-    QString fName = longWinPath(file->fileName());
-
-    HANDLE fileHandle = CreateFileW(
-        (const wchar_t *)fName.utf16(),
-        accessRights,
-        shareMode,
-        &securityAtts,
-        creationDisp,
-        FILE_ATTRIBUTE_NORMAL,
-        NULL);
-
-    // Bail out on error.
-    if (fileHandle == INVALID_HANDLE_VALUE) {
-        error = qt_error_string();
-        return false;
-    }
-
-    // Convert the HANDLE to an fd and pass it to QFile's foreign-open
-    // function. The fd owns the handle, so when QFile later closes
-    // the fd the handle will be closed too.
-    int fd = _open_osfhandle((intptr_t)fileHandle, _O_RDONLY);
-    if (fd == -1) {
-        error = "could not make fd from handle";
-        return false;
-    }
-    if (!file->open(fd, QIODevice::ReadOnly, QFile::AutoCloseHandle)) {
-        error = file->errorString();
-        return false;
-    }
-
-    // Seek to the right spot
-    LARGE_INTEGER *li = reinterpret_cast<LARGE_INTEGER *>(&seek);
-    DWORD newFilePointer = SetFilePointer(fileHandle, li->LowPart, &li->HighPart, FILE_BEGIN);
-    if (newFilePointer == 0xFFFFFFFF && GetLastError() != NO_ERROR) {
-        error = qt_error_string();
-        return false;
-    }
-
-    return true;
-#else
-    if (!file->open(QFile::ReadOnly)) {
-        error = file->errorString();
-        return false;
-    }
-    if (!file->seek(seek)) {
-        error = file->errorString();
-        return false;
-    }
-    return true;
-#endif
-}
-
 #ifdef Q_OS_WIN
 static qint64 getSizeWithCsync(const QString &filename)
 {
@@ -441,190 +139,5 @@ qint64 FileSystem::getSize(const QString &filename)
     return QFileInfo(filename).size();
 }
 
-#ifdef Q_OS_WIN
-static bool fileExistsWin(const QString &filename)
-{
-    WIN32_FIND_DATA FindFileData;
-    HANDLE hFind;
-    QString fName = FileSystem::longWinPath(filename);
-
-    hFind = FindFirstFileW((wchar_t *)fName.utf16(), &FindFileData);
-    if (hFind == INVALID_HANDLE_VALUE) {
-        return false;
-    }
-    FindClose(hFind);
-    return true;
-}
-#endif
-
-bool FileSystem::fileExists(const QString &filename, const QFileInfo &fileInfo)
-{
-#ifdef Q_OS_WIN
-    if (isLnkFile(filename)) {
-        // Use a native check.
-        return fileExistsWin(filename);
-    }
-#endif
-    bool re = fileInfo.exists();
-    // if the filename is different from the filename in fileInfo, the fileInfo is
-    // not valid. There needs to be one initialised here. Otherwise the incoming
-    // fileInfo is re-used.
-    if (fileInfo.filePath() != filename) {
-        QFileInfo myFI(filename);
-        re = myFI.exists();
-    }
-    return re;
-}
-
-#ifdef Q_OS_WIN
-QString FileSystem::fileSystemForPath(const QString &path)
-{
-    // See also QStorageInfo (Qt >=5.4) and GetVolumeInformationByHandleW (>= Vista)
-    QString drive = path.left(2);
-    if (!drive.endsWith(":"))
-        return QString();
-    drive.append('\\');
-
-    const size_t fileSystemBufferSize = 4096;
-    TCHAR fileSystemBuffer[fileSystemBufferSize];
-
-    if (!GetVolumeInformationW(
-            reinterpret_cast<LPCWSTR>(drive.utf16()),
-            NULL, 0,
-            NULL, NULL, NULL,
-            fileSystemBuffer, fileSystemBufferSize)) {
-        return QString();
-    }
-    return QString::fromUtf16(reinterpret_cast<const ushort *>(fileSystemBuffer));
-}
-#endif
-
-#define BUFSIZE qint64(500 * 1024) // 500 KiB
-
-static QByteArray readToCrypto(const QString &filename, QCryptographicHash::Algorithm algo)
-{
-    QFile file(filename);
-    const qint64 bufSize = qMin(BUFSIZE, file.size() + 1);
-    QByteArray buf(bufSize, Qt::Uninitialized);
-    QByteArray arr;
-    QCryptographicHash crypto(algo);
-
-    if (file.open(QIODevice::ReadOnly)) {
-        qint64 size;
-        while (!file.atEnd()) {
-            size = file.read(buf.data(), bufSize);
-            if (size > 0) {
-                crypto.addData(buf.data(), size);
-            }
-        }
-        arr = crypto.result().toHex();
-    }
-    return arr;
-}
-
-QByteArray FileSystem::calcMd5(const QString &filename)
-{
-    return readToCrypto(filename, QCryptographicHash::Md5);
-}
-
-QByteArray FileSystem::calcSha1(const QString &filename)
-{
-    return readToCrypto(filename, QCryptographicHash::Sha1);
-}
-
-#ifdef ZLIB_FOUND
-QByteArray FileSystem::calcAdler32(const QString &filename)
-{
-    QFile file(filename);
-    const qint64 bufSize = qMin(BUFSIZE, file.size() + 1);
-    QByteArray buf(bufSize, Qt::Uninitialized);
-
-    unsigned int adler = adler32(0L, Z_NULL, 0);
-    if (file.open(QIODevice::ReadOnly)) {
-        qint64 size;
-        while (!file.atEnd()) {
-            size = file.read(buf.data(), bufSize);
-            if (size > 0)
-                adler = adler32(adler, (const Bytef *)buf.data(), size);
-        }
-    }
-
-    return QByteArray::number(adler, 16);
-}
-#endif
-
-QString FileSystem::makeConflictFileName(const QString &fn, const QDateTime &dt)
-{
-    QString conflictFileName(fn);
-    // Add _conflict-XXXX  before the extension.
-    int dotLocation = conflictFileName.lastIndexOf('.');
-    // If no extension, add it at the end  (take care of cases like foo/.hidden or foo.bar/file)
-    if (dotLocation <= conflictFileName.lastIndexOf('/') + 1) {
-        dotLocation = conflictFileName.size();
-    }
-    QString timeString = dt.toString("yyyyMMdd-hhmmss");
-
-    // Additional marker
-    QByteArray conflictFileUserName = qgetenv("CSYNC_CONFLICT_FILE_USERNAME");
-    if (conflictFileUserName.isEmpty())
-        conflictFileName.insert(dotLocation, "_conflict-" + timeString);
-    else
-        conflictFileName.insert(dotLocation, "_conflict_" + QString::fromUtf8(conflictFileUserName) + "-" + timeString);
-
-    return conflictFileName;
-}
-
-bool FileSystem::remove(const QString &fileName, QString *errorString)
-{
-#ifdef Q_OS_WIN
-    // You cannot delete a read-only file on windows, but we want to
-    // allow that.
-    if (!QFileInfo(fileName).isWritable()) {
-        setFileReadOnly(fileName, false);
-    }
-#endif
-    QFile f(fileName);
-    if (!f.remove()) {
-        if (errorString) {
-            *errorString = f.errorString();
-        }
-        return false;
-    }
-    return true;
-}
-
-bool FileSystem::isFileLocked(const QString &fileName)
-{
-#ifdef Q_OS_WIN
-    mbchar_t *wuri = c_utf8_path_to_locale(fileName.toUtf8());
-
-    // Check if file exists
-    DWORD attr = GetFileAttributesW(wuri);
-    if (attr != INVALID_FILE_ATTRIBUTES) {
-        // Try to open the file with as much access as possible..
-        HANDLE win_h = CreateFileW(
-            wuri,
-            GENERIC_READ | GENERIC_WRITE,
-            FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
-            NULL, OPEN_EXISTING,
-            FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS,
-            NULL);
-
-        c_free_locale_string(wuri);
-        if (win_h == INVALID_HANDLE_VALUE) {
-            /* could not be opened, so locked? */
-            /* 32 == ERROR_SHARING_VIOLATION */
-            return true;
-        } else {
-            CloseHandle(win_h);
-        }
-    } else {
-        c_free_locale_string(wuri);
-    }
-#else
-    Q_UNUSED(fileName);
-#endif
-    return false;
-}
 
 } // namespace OCC

+ 2 - 118
src/libsync/filesystem.h

@@ -18,13 +18,12 @@
 
 #include <QString>
 #include <ctime>
-#include <QCryptographicHash>
-#include <QFileInfo>
 
 #include <owncloudlib.h>
+// Chain in the base include and extend the namespace
+#include "common/filesystembase.h"
 
 class QFile;
-class QFileInfo;
 
 namespace OCC {
 
@@ -43,39 +42,6 @@ namespace FileSystem {
  */
     bool fileEquals(const QString &fn1, const QString &fn2);
 
-    /**
- * @brief Mark the file as hidden  (only has effects on windows)
- */
-    void OWNCLOUDSYNC_EXPORT setFileHidden(const QString &filename, bool hidden);
-
-    /**
- * @brief Marks the file as read-only.
- *
- * On linux this either revokes all 'w' permissions or restores permissions
- * according to the umask.
- */
-    void OWNCLOUDSYNC_EXPORT setFileReadOnly(const QString &filename, bool readonly);
-
-    /**
- * @brief Marks the file as read-only.
- *
- * It's like setFileReadOnly(), but weaker: if readonly is false and the user
- * already has write permissions, no change to the permissions is made.
- *
- * This means that it will preserve explicitly set rw-r--r-- permissions even
- * when the umask is 0002. (setFileReadOnly() would adjust to rw-rw-r--)
- */
-    void OWNCLOUDSYNC_EXPORT setFileReadOnlyWeak(const QString &filename, bool readonly);
-
-    /**
- * @brief Try to set permissions so that other users on the local machine can not
- * go into the folder.
- */
-    void OWNCLOUDSYNC_EXPORT setFolderMinimumPermissions(const QString &filename);
-
-    /** convert a "normal" windows path into a path that can be 32k chars long. */
-    QString OWNCLOUDSYNC_EXPORT longWinPath(const QString &inpath);
-
     /**
  * @brief Get the mtime for a filepath
  *
@@ -94,23 +60,6 @@ namespace FileSystem {
  */
     qint64 OWNCLOUDSYNC_EXPORT getSize(const QString &filename);
 
-    /**
- * @brief Checks whether a file exists.
- *
- * Use this over QFileInfo::exists() and QFile::exists() to avoid bugs with lnk
- * files, see above.
- */
-    bool OWNCLOUDSYNC_EXPORT fileExists(const QString &filename, const QFileInfo & = QFileInfo());
-
-    /**
- * @brief Rename the file \a originFileName to \a destinationFileName.
- *
- * It behaves as QFile::rename() but handles .lnk files correctly on Windows.
- */
-    bool OWNCLOUDSYNC_EXPORT rename(const QString &originFileName,
-        const QString &destinationFileName,
-        QString *errorString = NULL);
-
     /**
  * @brief Check if \a fileName has changed given previous size and mtime
  *
@@ -128,71 +77,6 @@ namespace FileSystem {
     bool verifyFileUnchanged(const QString &fileName,
         qint64 previousSize,
         time_t previousMtime);
-
-    /**
- * @brief renames a file, overriding the target if it exists
- *
- * Rename the file \a originFileName to \a destinationFileName, and
- * overwrite the destination if it already exists - as long as the
- * destination file has the expected \a destinationSize and
- * \a destinationMtime.
- *
- * If the destination file does not exist, the given size and mtime are
- * ignored.
- */
-    bool renameReplace(const QString &originFileName,
-        const QString &destinationFileName,
-        qint64 destinationSize,
-        time_t destinationMtime,
-        QString *errorString);
-
-    /**
- * Rename the file \a originFileName to \a destinationFileName, and
- * overwrite the destination if it already exists - without extra checks.
- */
-    bool uncheckedRenameReplace(const QString &originFileName,
-        const QString &destinationFileName,
-        QString *errorString);
-
-    /**
- * Removes a file.
- *
- * Equivalent to QFile::remove(), except on Windows, where it will also
- * successfully remove read-only files.
- */
-    bool OWNCLOUDSYNC_EXPORT remove(const QString &fileName, QString *errorString = 0);
-
-    /**
- * Replacement for QFile::open(ReadOnly) followed by a seek().
- * This version sets a more permissive sharing mode on Windows.
- *
- * Warning: The resulting file may have an empty fileName and be unsuitable for use
- * with QFileInfo! Calling seek() on the QFile with >32bit signed values will fail!
- */
-    bool openAndSeekFileSharedRead(QFile *file, QString *error, qint64 seek);
-
-#ifdef Q_OS_WIN
-    /**
- * Returns the file system used at the given path.
- */
-    QString fileSystemForPath(const QString &path);
-#endif
-
-    QByteArray OWNCLOUDSYNC_EXPORT calcMd5(const QString &fileName);
-    QByteArray OWNCLOUDSYNC_EXPORT calcSha1(const QString &fileName);
-#ifdef ZLIB_FOUND
-    QByteArray OWNCLOUDSYNC_EXPORT calcAdler32(const QString &fileName);
-#endif
-
-    /**
- * Returns a file name based on \a fn that's suitable for a conflict.
- */
-    QString OWNCLOUDSYNC_EXPORT makeConflictFileName(const QString &fn, const QDateTime &dt);
-
-    /**
- * Returns true when a file is locked. (Windows only)
- */
-    bool OWNCLOUDSYNC_EXPORT isFileLocked(const QString &fileName);
 }
 
 /** @} */

+ 1 - 0
src/libsync/syncjournaldb.cpp

@@ -12,6 +12,7 @@
  * for more details.
  */
 
+#include <QCryptographicHash>
 #include <QFile>
 #include <QLoggingCategory>
 #include <QStringList>

+ 8 - 12
test/csync/encoding_tests/check_encoding.cpp

@@ -21,6 +21,8 @@
 #include "c_string.h"
 #include "c_path.h"
 #include "c_utf8.h"
+#include "common/filesystembase.h"
+#include "torture.h"
 
 #ifdef _WIN32
 #include <string.h>
@@ -116,41 +118,36 @@ static void check_long_win_path(void **state)
     {
         const char *path = "C://DATA/FILES/MUSIC/MY_MUSIC.mp3"; // check a short path
         const char *exp_path = "\\\\?\\C:\\\\DATA\\FILES\\MUSIC\\MY_MUSIC.mp3";
-        const char *new_short = c_path_to_UNC(path);
+        QByteArray new_short = OCC::FileSystem::pathtoUNC(QByteArray::fromRawData(path, strlen(path)));
         assert_string_equal(new_short, exp_path);
-        SAFE_FREE(new_short);
     }
 
     {
         const char *path = "\\\\foo\\bar/MY_MUSIC.mp3";
         const char *exp_path = "\\\\foo\\bar\\MY_MUSIC.mp3";
-        const char *new_short = c_path_to_UNC(path);
+        QByteArray new_short = OCC::FileSystem::pathtoUNC(QByteArray::fromRawData(path, strlen(path)));
         assert_string_equal(new_short, exp_path);
-        SAFE_FREE(new_short);
     }
 
     {
         const char *path = "//foo\\bar/MY_MUSIC.mp3";
         const char *exp_path = "\\\\foo\\bar\\MY_MUSIC.mp3";
-        const char *new_short = c_path_to_UNC(path);
+        QByteArray new_short = OCC::FileSystem::pathtoUNC(QByteArray::fromRawData(path, strlen(path)));
         assert_string_equal(new_short, exp_path);
-        SAFE_FREE(new_short);
     }
 
     {
         const char *path = "\\foo\\bar";
         const char *exp_path = "\\\\?\\foo\\bar";
-        const char *new_short = c_path_to_UNC(path);
+        QByteArray new_short = OCC::FileSystem::pathtoUNC(QByteArray::fromRawData(path, strlen(path)));
         assert_string_equal(new_short, exp_path);
-        SAFE_FREE(new_short);
     }
 
     {
         const char *path = "/foo/bar";
         const char *exp_path = "\\\\?\\foo\\bar";
-        const char *new_short = c_path_to_UNC(path);
+        QByteArray new_short = OCC::FileSystem::pathtoUNC(QByteArray::fromRawData(path, strlen(path)));
         assert_string_equal(new_short, exp_path);
-        SAFE_FREE(new_short);
     }
 
     const char *longPath = "D://alonglonglonglong/blonglonglonglong/clonglonglonglong/dlonglonglonglong/"
@@ -162,14 +159,13 @@ static void check_long_win_path(void **state)
             "jlonglonglonglong\\klonglonglonglong\\llonglonglonglong\\mlonglonglonglong\\nlonglonglonglong\\"
             "olonglonglonglong\\file.txt";
 
-    const char *new_long = c_path_to_UNC(longPath);
+    QByteArray new_long = OCC::FileSystem::pathtoUNC(QByteArray::fromRawData(longPath, strlen(longPath)));
     // printf( "XXXXXXXXXXXX %s %d\n", new_long, mem_reserved);
 
     assert_string_equal(new_long, longPathConv);
 
     // printf( "YYYYYYYYYYYY %ld\n", strlen(new_long));
     assert_int_equal( strlen(new_long), 286);
-    SAFE_FREE(new_long);
 }
 
 int torture_run_tests(void)