From: Olivier Goffart Date: Tue, 6 Nov 2018 14:44:22 +0000 (+0100) Subject: csync_vio_locale: use QString for the path in opendir X-Git-Tag: archive/raspbian/3.16.7-1_deb13u1+rpi1~1^2~12^2~21^2~468^2~419 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=5e05b61d2f4940571381fcbff33cfd130aa25dc2;p=nextcloud-desktop.git csync_vio_locale: use QString for the path in opendir So we don't have to convert to utf8 and back again --- diff --git a/src/csync/vio/csync_vio_local.h b/src/csync/vio/csync_vio_local.h index 734f60211..97ac34d63 100644 --- a/src/csync/vio/csync_vio_local.h +++ b/src/csync/vio/csync_vio_local.h @@ -23,7 +23,7 @@ struct csync_vio_handle_t; -csync_vio_handle_t OCSYNC_EXPORT *csync_vio_local_opendir(const char *name); +csync_vio_handle_t OCSYNC_EXPORT *csync_vio_local_opendir(const QString &name); int OCSYNC_EXPORT csync_vio_local_closedir(csync_vio_handle_t *dhandle); std::unique_ptr OCSYNC_EXPORT csync_vio_local_readdir(csync_vio_handle_t *dhandle); diff --git a/src/csync/vio/csync_vio_local_unix.cpp b/src/csync/vio/csync_vio_local_unix.cpp index c13b0fab7..ea6f925df 100644 --- a/src/csync/vio/csync_vio_local_unix.cpp +++ b/src/csync/vio/csync_vio_local_unix.cpp @@ -37,6 +37,7 @@ #include "vio/csync_vio_local.h" #include +#include Q_LOGGING_CATEGORY(lcCSyncVIOLocal, "nextcloud.sync.csync.vio_local", QtInfoMsg) @@ -44,58 +45,37 @@ Q_LOGGING_CATEGORY(lcCSyncVIOLocal, "nextcloud.sync.csync.vio_local", QtInfoMsg) * directory functions */ -struct dhandle_t { +struct csync_vio_handle_t { DIR *dh; - char *path; + QByteArray path; }; static int _csync_vio_local_stat_mb(const mbchar_t *wuri, csync_file_stat_t *buf); -csync_vio_handle_t *csync_vio_local_opendir(const char *name) { - dhandle_t *handle = nullptr; - mbchar_t *dirname = nullptr; +csync_vio_handle_t *csync_vio_local_opendir(const QString &name) { + QScopedPointer handle(new csync_vio_handle_t{}); - handle = (dhandle_t*)c_malloc(sizeof(dhandle_t)); + auto dirname = QFile::encodeName(name); - dirname = c_utf8_path_to_locale(name); - - handle->dh = _topendir( dirname ); - if (!handle->dh) { - c_free_locale_string(dirname); - SAFE_FREE(handle); - return nullptr; - } - - handle->path = c_strdup(name); - c_free_locale_string(dirname); + handle->dh = _topendir( dirname ); + if (!handle->dh) { + return nullptr; + } - return (csync_vio_handle_t *) handle; + handle->path = dirname; + return handle.take(); } int csync_vio_local_closedir(csync_vio_handle_t *dhandle) { - dhandle_t *handle = nullptr; - int rc = -1; - - if (!dhandle) { - errno = EBADF; - return -1; - } - - handle = (dhandle_t *) dhandle; - rc = _tclosedir(handle->dh); - - SAFE_FREE(handle->path); - SAFE_FREE(handle); - - return rc; + Q_ASSERT(dhandle); + auto rc = _tclosedir(dhandle->dh); + delete dhandle; + return rc; } -std::unique_ptr csync_vio_local_readdir(csync_vio_handle_t *dhandle) { - - dhandle_t *handle = nullptr; +std::unique_ptr csync_vio_local_readdir(csync_vio_handle_t *handle) { - handle = (dhandle_t *) dhandle; - struct _tdirent *dirent = nullptr; + struct _tdirent *dirent = NULL; std::unique_ptr file_stat; do { @@ -106,7 +86,7 @@ std::unique_ptr csync_vio_local_readdir(csync_vio_handle_t *d file_stat = std::make_unique(); file_stat->path = c_utf8_from_locale(dirent->d_name); - QByteArray fullPath = QByteArray() % const_cast(handle->path) % '/' % QByteArray() % const_cast(dirent->d_name); + QByteArray fullPath = handle->path % '/' % QByteArray() % const_cast(dirent->d_name); if (file_stat->path.isNull()) { file_stat->original_path = fullPath; qCWarning(lcCSyncVIOLocal) << "Invalid characters in file/directory name, please rename:" << dirent->d_name << handle->path; diff --git a/src/csync/vio/csync_vio_local_win.cpp b/src/csync/vio/csync_vio_local_win.cpp index 3a58be31c..7eeab6827 100644 --- a/src/csync/vio/csync_vio_local_win.cpp +++ b/src/csync/vio/csync_vio_local_win.cpp @@ -34,6 +34,7 @@ #include "c_utf8.h" #include "csync_util.h" #include "vio/csync_vio_local.h" +#include "common/filesystembase.h" #include @@ -43,81 +44,54 @@ Q_LOGGING_CATEGORY(lcCSyncVIOLocal, "nextcloud.sync.csync.vio_local", QtInfoMsg) * directory functions */ -struct dhandle_t { +struct csync_vio_handle_t { WIN32_FIND_DATA ffd; HANDLE hFind; int firstFind; - mbchar_t *path; // Always ends with '\' + QString path; // Always ends with '\' }; static int _csync_vio_local_stat_mb(const mbchar_t *uri, csync_file_stat_t *buf); -csync_vio_handle_t *csync_vio_local_opendir(const char *name) { - dhandle_t *handle = nullptr; - mbchar_t *dirname = nullptr; +csync_vio_handle_t *csync_vio_local_opendir(const QString &name) { - handle = (dhandle_t*)c_malloc(sizeof(dhandle_t)); + QScopedPointer handle(new csync_vio_handle_t{}); - // the file wildcard has to be attached - size_t len_name = strlen(name); - if( len_name ) { - char *h = nullptr; + // the file wildcard has to be attached + QString dirname = OCC::FileSystem::longWinPath(name + QLatin1String("/*")); - // alloc an enough large buffer to take the name + '/*' + the closing zero. - h = (char*)c_malloc(len_name+3); - strncpy( h, name, 1+len_name); - strncat(h, "/*", 2); + handle->hFind = FindFirstFile(reinterpret_cast(dirname.utf16()), &(handle->ffd)); - dirname = c_utf8_path_to_locale(h); - SAFE_FREE(h); - } - - if( dirname ) { - handle->hFind = FindFirstFile(dirname, &(handle->ffd)); - } - - if (!dirname || handle->hFind == INVALID_HANDLE_VALUE) { - c_free_locale_string(dirname); - int retcode = GetLastError(); - if( retcode == ERROR_FILE_NOT_FOUND ) { - errno = ENOENT; - } else { - errno = EACCES; - } - SAFE_FREE(handle); - return nullptr; - } - - handle->firstFind = 1; // Set a flag that there first fileinfo is available. + if (handle->hFind == INVALID_HANDLE_VALUE) { + int retcode = GetLastError(); + if( retcode == ERROR_FILE_NOT_FOUND ) { + errno = ENOENT; + } else { + errno = EACCES; + } + return nullptr; + } - dirname[std::wcslen(dirname) - 1] = L'\0'; // remove the * - handle->path = dirname; + handle->firstFind = 1; // Set a flag that there first fileinfo is available. - return (csync_vio_handle_t *) handle; + dirname.chop(1); // remove the * + handle->path = std::move(dirname); + return handle.take(); } int csync_vio_local_closedir(csync_vio_handle_t *dhandle) { - dhandle_t *handle = nullptr; - int rc = -1; + Q_ASSERT(dhandle); + int rc = -1; - if (!dhandle) { - errno = EBADF; - return -1; - } - - handle = (dhandle_t *) dhandle; - // FindClose returns non-zero on success - if( FindClose(handle->hFind) != 0 ) { - rc = 0; - } else { - // error case, set errno - errno = EBADF; - } - - c_free_locale_string(handle->path); - SAFE_FREE(handle); - - return rc; + // FindClose returns non-zero on success + if( FindClose(dhandle->hFind) != 0 ) { + rc = 0; + } else { + // error case, set errno + errno = EBADF; + } + delete dhandle; + return rc; } @@ -139,14 +113,11 @@ static time_t FileTimeToUnixTime(FILETIME *filetime, DWORD *remainder) } } -std::unique_ptr csync_vio_local_readdir(csync_vio_handle_t *dhandle) { +std::unique_ptr csync_vio_local_readdir(csync_vio_handle_t *handle) { - dhandle_t *handle = nullptr; std::unique_ptr file_stat; DWORD rem; - handle = (dhandle_t *) dhandle; - errno = 0; // the win32 functions get the first valid entry with the opendir @@ -166,7 +137,7 @@ std::unique_ptr csync_vio_local_readdir(csync_vio_handle_t *d } auto path = c_utf8_from_locale(handle->ffd.cFileName); if (path == "." || path == "..") - return csync_vio_local_readdir(dhandle); + return csync_vio_local_readdir(handle); file_stat = std::make_unique(); file_stat->path = path; @@ -201,8 +172,8 @@ std::unique_ptr csync_vio_local_readdir(csync_vio_handle_t *d file_stat->modtime = FileTimeToUnixTime(&handle->ffd.ftLastWriteTime, &rem); std::wstring fullPath; - fullPath.reserve(std::wcslen(handle->path) + std::wcslen(handle->ffd.cFileName)); - fullPath += handle->path; // path always ends with '\', by construction + fullPath.reserve(handle->path.size() + std::wcslen(handle->ffd.cFileName)); + fullPath += reinterpret_cast(handle->path.utf16()); // path always ends with '\', by construction fullPath += handle->ffd.cFileName; if (_csync_vio_local_stat_mb(fullPath.data(), file_stat.get()) < 0) { diff --git a/src/libsync/discovery.cpp b/src/libsync/discovery.cpp index 79560e785..a0949c330 100644 --- a/src/libsync/discovery.cpp +++ b/src/libsync/discovery.cpp @@ -1220,13 +1220,13 @@ DiscoverySingleDirectoryJob *ProcessDirectoryJob::startAsyncServerQuery() bool ProcessDirectoryJob::runLocalQuery() { - QByteArray localPath = (_discoveryData->_localDir + _currentFolder._local).toUtf8(); + QString localPath = _discoveryData->_localDir + _currentFolder._local; if (localPath.endsWith('/')) // Happens if _currentFolder._local.isEmpty() localPath.chop(1); auto dh = csync_vio_local_opendir(localPath); if (!dh) { - qCInfo(lcDisco) << "Error while opening directory" << (_discoveryData->_localDir + _currentFolder._local) << errno; - QString errorString = tr("Error while opening directory %1").arg(_discoveryData->_localDir + _currentFolder._local); + qCInfo(lcDisco) << "Error while opening directory" << (localPath) << errno; + QString errorString = tr("Error while opening directory %1").arg(localPath); if (errno == EACCES) { errorString = tr("Directory not accessible on client, permission denied"); if (_dirItem) { @@ -1236,7 +1236,7 @@ bool ProcessDirectoryJob::runLocalQuery() return false; } } else if (errno == ENOENT) { - errorString = tr("Directory not found: %1").arg(_discoveryData->_localDir + _currentFolder._local); + errorString = tr("Directory not found: %1").arg(localPath); } else if (errno == ENOTDIR) { // Not a directory.. // Just consider it is empty @@ -1276,7 +1276,7 @@ bool ProcessDirectoryJob::runLocalQuery() if (errno != 0) { // Note: Windows vio converts any error into EACCES qCWarning(lcDisco) << "readdir failed for file in " << _currentFolder._local << " - errno: " << errno; - emit _discoveryData->fatalError(tr("Error while reading directory %1").arg(_discoveryData->_localDir + _currentFolder._local)); + emit _discoveryData->fatalError(tr("Error while reading directory %1").arg(localPath)); return false; } return true;