#include "vio/csync_vio_local.h"
#include <QtCore/QLoggingCategory>
+#include <QtCore/QFile>
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<csync_vio_handle_t> 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_file_stat_t> csync_vio_local_readdir(csync_vio_handle_t *dhandle) {
-
- dhandle_t *handle = nullptr;
+std::unique_ptr<csync_file_stat_t> csync_vio_local_readdir(csync_vio_handle_t *handle) {
- handle = (dhandle_t *) dhandle;
- struct _tdirent *dirent = nullptr;
+ struct _tdirent *dirent = NULL;
std::unique_ptr<csync_file_stat_t> file_stat;
do {
file_stat = std::make_unique<csync_file_stat_t>();
file_stat->path = c_utf8_from_locale(dirent->d_name);
- QByteArray fullPath = QByteArray() % const_cast<const char *>(handle->path) % '/' % QByteArray() % const_cast<const char *>(dirent->d_name);
+ QByteArray fullPath = handle->path % '/' % QByteArray() % const_cast<const char *>(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;
#include "c_utf8.h"
#include "csync_util.h"
#include "vio/csync_vio_local.h"
+#include "common/filesystembase.h"
#include <QtCore/QLoggingCategory>
* 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<csync_vio_handle_t> 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<const wchar_t *>(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;
}
}
}
-std::unique_ptr<csync_file_stat_t> csync_vio_local_readdir(csync_vio_handle_t *dhandle) {
+std::unique_ptr<csync_file_stat_t> csync_vio_local_readdir(csync_vio_handle_t *handle) {
- dhandle_t *handle = nullptr;
std::unique_ptr<csync_file_stat_t> file_stat;
DWORD rem;
- handle = (dhandle_t *) dhandle;
-
errno = 0;
// the win32 functions get the first valid entry with the opendir
}
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<csync_file_stat_t>();
file_stat->path = path;
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<const wchar_t *>(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) {
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) {
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
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;