mirror of
https://github.com/chylex/Nextcloud-Desktop.git
synced 2025-05-23 11:34:06 +02:00
174 lines
4.5 KiB
C++
174 lines
4.5 KiB
C++
/*
|
|
* libcsync -- a library to sync a directory with another
|
|
*
|
|
* Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
|
|
* Copyright (c) 2013- by Klaas Freitag <freitag@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 <cerrno>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <fcntl.h>
|
|
#include <dirent.h>
|
|
#include <cstdio>
|
|
|
|
#include <memory>
|
|
|
|
#include "c_private.h"
|
|
#include "c_lib.h"
|
|
#include "csync.h"
|
|
|
|
#include "vio/csync_vio_local.h"
|
|
#include "common/vfs.h"
|
|
|
|
#include <QtCore/QLoggingCategory>
|
|
#include <QtCore/QFile>
|
|
|
|
Q_LOGGING_CATEGORY(lcCSyncVIOLocal, "nextcloud.sync.csync.vio_local", QtInfoMsg)
|
|
|
|
/*
|
|
* directory functions
|
|
*/
|
|
|
|
struct csync_vio_handle_t {
|
|
DIR *dh;
|
|
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 QString &name) {
|
|
QScopedPointer<csync_vio_handle_t> handle(new csync_vio_handle_t{});
|
|
|
|
auto dirname = QFile::encodeName(name);
|
|
|
|
handle->dh = _topendir(dirname.constData());
|
|
if (!handle->dh) {
|
|
return nullptr;
|
|
}
|
|
|
|
handle->path = dirname;
|
|
return handle.take();
|
|
}
|
|
|
|
int csync_vio_local_closedir(csync_vio_handle_t *dhandle) {
|
|
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 *handle, OCC::Vfs *vfs) {
|
|
|
|
struct _tdirent *dirent = nullptr;
|
|
std::unique_ptr<csync_file_stat_t> file_stat;
|
|
|
|
do {
|
|
dirent = _treaddir(handle->dh);
|
|
if (!dirent)
|
|
return {};
|
|
} while (qstrcmp(dirent->d_name, ".") == 0 || qstrcmp(dirent->d_name, "..") == 0);
|
|
|
|
file_stat = std::make_unique<csync_file_stat_t>();
|
|
file_stat->path = QFile::decodeName(dirent->d_name).toUtf8();
|
|
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;
|
|
}
|
|
|
|
/* Check for availability of d_type, see manpage. */
|
|
#if defined(_DIRENT_HAVE_D_TYPE) || defined(__APPLE__)
|
|
switch (dirent->d_type) {
|
|
case DT_FIFO:
|
|
case DT_SOCK:
|
|
case DT_CHR:
|
|
case DT_BLK:
|
|
break;
|
|
case DT_DIR:
|
|
case DT_REG:
|
|
if (dirent->d_type == DT_DIR) {
|
|
file_stat->type = ItemTypeDirectory;
|
|
} else {
|
|
file_stat->type = ItemTypeFile;
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
#endif
|
|
|
|
if (file_stat->path.isNull())
|
|
return file_stat;
|
|
|
|
if (_csync_vio_local_stat_mb(fullPath.constData(), file_stat.get()) < 0) {
|
|
// Will get excluded by _csync_detect_update.
|
|
file_stat->type = ItemTypeSkip;
|
|
}
|
|
|
|
// Override type for virtual files if desired
|
|
if (vfs) {
|
|
// Directly modifies file_stat->type.
|
|
// We can ignore the return value since we're done here anyway.
|
|
vfs->statTypeVirtualFile(file_stat.get(), nullptr);
|
|
}
|
|
|
|
return file_stat;
|
|
}
|
|
|
|
|
|
int csync_vio_local_stat(const QString &uri, csync_file_stat_t *buf)
|
|
{
|
|
return _csync_vio_local_stat_mb(QFile::encodeName(uri).constData(), buf);
|
|
}
|
|
|
|
static int _csync_vio_local_stat_mb(const mbchar_t *wuri, csync_file_stat_t *buf)
|
|
{
|
|
csync_stat_t sb;
|
|
|
|
if (_tstat(wuri, &sb) < 0) {
|
|
return -1;
|
|
}
|
|
|
|
switch (sb.st_mode & S_IFMT) {
|
|
case S_IFDIR:
|
|
buf->type = ItemTypeDirectory;
|
|
break;
|
|
case S_IFREG:
|
|
buf->type = ItemTypeFile;
|
|
break;
|
|
case S_IFLNK:
|
|
case S_IFSOCK:
|
|
buf->type = ItemTypeSoftLink;
|
|
break;
|
|
default:
|
|
buf->type = ItemTypeSkip;
|
|
break;
|
|
}
|
|
|
|
#ifdef __APPLE__
|
|
if (sb.st_flags & UF_HIDDEN) {
|
|
buf->is_hidden = true;
|
|
}
|
|
#endif
|
|
|
|
buf->inode = sb.st_ino;
|
|
buf->modtime = sb.st_mtime;
|
|
buf->size = sb.st_size;
|
|
return 0;
|
|
}
|