diff --git a/CMakeLists.txt b/CMakeLists.txt --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -161,8 +161,7 @@ endif() add_subdirectory( thumbnail ) add_subdirectory( docfilter ) -if (libssh_FOUND AND HAVE_UTIME_H) - # does not compile on Windows: kio_sftp.cpp(28): fatal error C1083: Cannot open include file: 'utime.h': No such file or directory +if (libssh_FOUND) add_subdirectory(sftp) endif () add_subdirectory(settings) diff --git a/sftp/CMakeLists.txt b/sftp/CMakeLists.txt --- a/sftp/CMakeLists.txt +++ b/sftp/CMakeLists.txt @@ -1,7 +1,9 @@ add_definitions(-DTRANSLATION_DOMAIN=\"kio5_sftp\") include_directories(${LIBSSH_INCLUDE_DIR}) - +if(WIN32) +include_directories(${QT_MKSPECS_DIR}/default) # for SYMLINKS +endif() set(kio_sftp_SRCS kio_sftp.cpp) ecm_qt_declare_logging_category(kio_sftp_SRCS diff --git a/sftp/kio_sftp.cpp b/sftp/kio_sftp.cpp --- a/sftp/kio_sftp.cpp +++ b/sftp/kio_sftp.cpp @@ -26,22 +26,30 @@ #include "kio_sftp_trace_debug.h" #include #include -#include #include #include #include #include #include #include +#include #include #include #include #include #include +#ifdef Q_OS_WIN +#include // for permissions +using namespace std::experimental::filesystem; +#include +#else +#include +#endif + #define KIO_SFTP_SPECIAL_TIMEOUT 30 // How big should each data packet be? Definitely not bigger than 64kb or @@ -379,7 +387,11 @@ if (isBrokenLink) { // It is a link pointing to nowhere fileType = S_IFMT - 1; +#ifdef Q_OS_WIN + access = static_cast(perms::owner_all | perms::group_all | perms::others_all); +#else access = S_IRWXU | S_IRWXG | S_IRWXO; +#endif size = 0LL; } else { switch (sb->type) { @@ -390,7 +402,12 @@ fileType = S_IFDIR; break; case SSH_FILEXFER_TYPE_SYMLINK: +#ifdef Q_OS_WIN + // TODO Check if this works for other OSes too. + fileType = QT_STAT_LNK; +#else fileType = S_IFLNK; +#endif break; case SSH_FILEXFER_TYPE_SPECIAL: case SSH_FILEXFER_TYPE_UNKNOWN: @@ -1751,7 +1768,11 @@ mode_t initialMode; if (permissions != -1) { +#ifdef Q_OS_WIN + initialMode = permissions | static_cast(perms::owner_write | perms::owner_read); +#else initialMode = permissions | S_IWUSR | S_IRUSR; +#endif } else { initialMode = 0644; } @@ -1923,10 +1944,10 @@ // check if destination is ok ... QT_STATBUF buff; - const bool bDestExists = (QT_STAT(QFile::encodeName(sCopyFile), &buff) != -1); - + QFileInfo copyFile(sCopyFile); + const bool bDestExists = copyFile.exists(); if(bDestExists) { - if(S_ISDIR(buff.st_mode)) { + if(copyFile.isDir()) { errorCode = ERR_IS_DIRECTORY; return sftpProtocol::ClientError; } @@ -1939,12 +1960,13 @@ bool bResume = false; const QString sPart = sCopyFile + QLatin1String(".part"); // do we have a ".part" file? - const bool bPartExists = (QT_STAT(QFile::encodeName(sPart), &buff) != -1); + QFileInfo partFile(sPart); + const bool bPartExists = partFile.exists(); const bool bMarkPartial = config()->readEntry("MarkPartial", true); const QString dest = (bMarkPartial ? sPart : sCopyFile); if (bMarkPartial && bPartExists && buff.st_size > 0) { - if (S_ISDIR(buff.st_mode)) { + if(partFile.isDir()) { errorCode = ERR_DIR_ALREADY_EXIST; return sftpProtocol::ClientError; // client side error } @@ -1958,7 +1980,11 @@ // otherwise we can be in for a surprise on NFS. mode_t initialMode; if (permissions != -1) +#ifdef Q_OS_WIN + initialMode = permissions | static_cast(perms::owner_write); +#else initialMode = permissions | S_IWUSR; +#endif else initialMode = 0666; @@ -2015,10 +2041,18 @@ if (!mtimeStr.isEmpty()) { QDateTime dt = QDateTime::fromString(mtimeStr, Qt::ISODate); if (dt.isValid()) { - struct utimbuf utbuf; - utbuf.actime = buff.st_atime; // access time, unchanged - utbuf.modtime = dt.toTime_t(); // modification time - utime(QFile::encodeName(sCopyFile), &utbuf); + QFile receivedFile(sCopyFile); + if (receivedFile.exists()) { + if (!receivedFile.open(QIODevice::ReadWrite | QIODevice::Text)) { + QString error_msg = receivedFile.errorString(); + qCDebug(KIO_SFTP_LOG) << QStringLiteral("Couldn't update modified time : ") << error_msg; + } + else { + receivedFile.setFileTime(QDateTime::fromTime_t(buff.st_atime), + QFileDevice::FileTime(QFileDevice::FileAccessTime)); + receivedFile.setFileTime(dt, QFileDevice::FileTime(QFileDevice::FileModificationTime)); + } + } } } @@ -2031,10 +2065,10 @@ // check if source is ok ... QT_STATBUF buff; - bool bSrcExists = (QT_STAT(QFile::encodeName(sCopyFile), &buff) != -1); - + QFileInfo copyFile(sCopyFile); + bool bSrcExists = copyFile.exists(); if (bSrcExists) { - if (S_ISDIR(buff.st_mode)) { + if(copyFile.isDir()) { errorCode = ERR_IS_DIRECTORY; return sftpProtocol::ClientError; } @@ -2210,7 +2244,11 @@ if (isBrokenLink) { // It is a link pointing to nowhere fileType = S_IFMT - 1; +#ifdef Q_OS_WIN + access = static_cast(perms::owner_all | perms::group_all | perms::others_all); +#else access = S_IRWXU | S_IRWXG | S_IRWXO; +#endif size = 0LL; } else { switch (dirent->type) { @@ -2221,7 +2259,11 @@ fileType = S_IFDIR; break; case SSH_FILEXFER_TYPE_SYMLINK: +#ifdef Q_OS_WIN + fileType = QT_STAT_LNK; +#else fileType = S_IFLNK; +#endif break; case SSH_FILEXFER_TYPE_SPECIAL: case SSH_FILEXFER_TYPE_UNKNOWN: