mirror of
https://github.com/chylex/Nextcloud-Desktop.git
synced 2025-05-12 05:34:09 +02:00
Excludes: Refactor for pending improvements
Make ExcludedFiles something that is instantiated outside of the CSYNC context and then given to it as a hook. ExcludedFiles still lives in csync_exclude and the internal workings haven't been touched.
This commit is contained in:
parent
dd91f4a86e
commit
7ab127ad53
@ -534,7 +534,7 @@ restart_sync:
|
||||
engine.excludedFiles().addExcludeFilePath(systemExcludeFile);
|
||||
}
|
||||
|
||||
if (!engine.excludedFiles().reloadExcludes()) {
|
||||
if (!engine.excludedFiles().reloadExcludeFiles()) {
|
||||
qFatal("Cannot load system exclude list or list supplied via --exclude");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
@ -77,7 +77,7 @@ int csync_update(CSYNC *ctx) {
|
||||
|
||||
csync_memstat_check();
|
||||
|
||||
if (!ctx->excludes) {
|
||||
if (!ctx->exclude_traversal_fn) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_INFO, "No exclude file loaded or defined!");
|
||||
}
|
||||
|
||||
|
@ -40,6 +40,7 @@
|
||||
#include "common/utility.h"
|
||||
|
||||
#include <QString>
|
||||
#include <QFileInfo>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <io.h>
|
||||
@ -53,21 +54,6 @@
|
||||
#ifndef WITH_TESTING
|
||||
static
|
||||
#endif
|
||||
int _csync_exclude_add(c_strlist_t **inList, const char *string) {
|
||||
size_t i = 0;
|
||||
|
||||
// We never want duplicates, so check whether the string is already
|
||||
// in the list first.
|
||||
if (*inList) {
|
||||
for (i = 0; i < (*inList)->count; ++i) {
|
||||
char *pattern = (*inList)->vector[i];
|
||||
if (c_streq(pattern, string)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return c_strlist_add_grow(inList, string);
|
||||
}
|
||||
|
||||
/** Expands C-like escape sequences.
|
||||
*
|
||||
@ -109,7 +95,8 @@ static const char *csync_exclude_expand_escapes(const char * input)
|
||||
return out;
|
||||
}
|
||||
|
||||
int csync_exclude_load(const char *fname, c_strlist_t **list) {
|
||||
/** Loads patterns from a file and adds them to excludes */
|
||||
int csync_exclude_load(const char *fname, QList<QByteArray> *excludes) {
|
||||
int fd = -1;
|
||||
int i = 0;
|
||||
int rc = -1;
|
||||
@ -162,14 +149,9 @@ int csync_exclude_load(const char *fname, c_strlist_t **list) {
|
||||
buf[i] = '\0';
|
||||
if (*entry != '#') {
|
||||
const char *unescaped = csync_exclude_expand_escapes(entry);
|
||||
rc = _csync_exclude_add(list, unescaped);
|
||||
if( rc == 0 ) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "Adding entry: %s", unescaped);
|
||||
}
|
||||
excludes->append(unescaped);
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "Adding entry: %s", unescaped);
|
||||
SAFE_FREE(unescaped);
|
||||
if (rc < 0) {
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
entry = buf + i + 1;
|
||||
@ -193,6 +175,11 @@ static const char *win_reserved_words_4[] = {
|
||||
};
|
||||
static const char *win_reserved_words_n[] = { "CLOCK$", "$Recycle.Bin" };
|
||||
|
||||
/**
|
||||
* @brief Checks if filename is considered reserved by Windows
|
||||
* @param file_name filename
|
||||
* @return true if file is reserved, false otherwise
|
||||
*/
|
||||
bool csync_is_windows_reserved_word(const char *filename)
|
||||
{
|
||||
size_t len_filename = strlen(filename);
|
||||
@ -233,7 +220,8 @@ bool csync_is_windows_reserved_word(const char *filename)
|
||||
return false;
|
||||
}
|
||||
|
||||
static CSYNC_EXCLUDE_TYPE _csync_excluded_common(c_strlist_t *excludes, const char *path, int filetype, bool check_leading_dirs) {
|
||||
static CSYNC_EXCLUDE_TYPE _csync_excluded_common(const QList<QByteArray> &excludes, const char *path, int filetype, bool check_leading_dirs)
|
||||
{
|
||||
size_t i = 0;
|
||||
const char *bname = NULL;
|
||||
size_t blen = 0;
|
||||
@ -335,7 +323,7 @@ static CSYNC_EXCLUDE_TYPE _csync_excluded_common(c_strlist_t *excludes, const ch
|
||||
}
|
||||
}
|
||||
|
||||
if( ! excludes ) {
|
||||
if (excludes.isEmpty()) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
@ -367,9 +355,16 @@ static CSYNC_EXCLUDE_TYPE _csync_excluded_common(c_strlist_t *excludes, const ch
|
||||
}
|
||||
|
||||
/* Loop over all exclude patterns and evaluate the given path */
|
||||
for (i = 0; match == CSYNC_NOT_EXCLUDED && i < excludes->count; i++) {
|
||||
for (const auto &exclude : excludes) {
|
||||
if (match != CSYNC_NOT_EXCLUDED)
|
||||
break;
|
||||
|
||||
bool match_dirs_only = false;
|
||||
char *pattern = excludes->vector[i];
|
||||
|
||||
// If the pattern ends with a slash, *it will be temporarily modified
|
||||
// inside this function* and then reverted. This is left over from
|
||||
// old code and will be removed.
|
||||
char *pattern = const_cast<char *>(exclude.data());
|
||||
|
||||
type = CSYNC_FILE_EXCLUDE_LIST;
|
||||
if (!pattern[0]) { /* empty pattern */
|
||||
@ -434,70 +429,103 @@ static CSYNC_EXCLUDE_TYPE _csync_excluded_common(c_strlist_t *excludes, const ch
|
||||
return match;
|
||||
}
|
||||
|
||||
/* Only for bnames (not paths) */
|
||||
static QString convertToBnameRegexpSyntax(QString exclude)
|
||||
|
||||
using namespace OCC;
|
||||
|
||||
ExcludedFiles::ExcludedFiles()
|
||||
{
|
||||
QString s = QRegularExpression::escape(exclude).replace("\\*", ".*").replace("\\?", ".");
|
||||
return s;
|
||||
}
|
||||
|
||||
void csync_exclude_traversal_prepare(CSYNC *ctx)
|
||||
ExcludedFiles::~ExcludedFiles()
|
||||
{
|
||||
ctx->parsed_traversal_excludes.prepare(ctx->excludes);
|
||||
}
|
||||
|
||||
void csync_s::TraversalExcludes::prepare(c_strlist_t *excludes)
|
||||
void ExcludedFiles::addExcludeFilePath(const QString &path)
|
||||
{
|
||||
c_strlist_destroy(list_patterns_fnmatch);
|
||||
list_patterns_fnmatch = nullptr;
|
||||
_excludeFiles.insert(path);
|
||||
}
|
||||
|
||||
// Start out with regexes that would match nothing
|
||||
QString exclude_only = "a^";
|
||||
QString exclude_and_remove = "a^";
|
||||
void ExcludedFiles::addManualExclude(const QByteArray &expr)
|
||||
{
|
||||
_manualExcludes.append(expr);
|
||||
_allExcludes.append(expr);
|
||||
_nonRegexExcludes.append(expr);
|
||||
}
|
||||
|
||||
size_t exclude_count = excludes ? excludes->count : 0;
|
||||
for (unsigned int i = 0; i < exclude_count; i++) {
|
||||
char *exclude = excludes->vector[i];
|
||||
QString *builderToUse = & exclude_only;
|
||||
if (exclude[0] == '\n') continue; // empty line
|
||||
if (exclude[0] == '\r') continue; // empty line
|
||||
void ExcludedFiles::clearManualExcludes()
|
||||
{
|
||||
_manualExcludes.clear();
|
||||
reloadExcludeFiles();
|
||||
}
|
||||
|
||||
/* If an exclude entry contains some fnmatch-ish characters, we use the C-style codepath without QRegularEpression */
|
||||
if (strchr(exclude, '/') || strchr(exclude, '[') || strchr(exclude, '{') || strchr(exclude, '\\')) {
|
||||
_csync_exclude_add(&list_patterns_fnmatch, exclude);
|
||||
continue;
|
||||
}
|
||||
bool ExcludedFiles::reloadExcludeFiles()
|
||||
{
|
||||
_allExcludes.clear();
|
||||
_regex = QRegularExpression();
|
||||
|
||||
/* Those will attempt to use QRegularExpression */
|
||||
if (exclude[0] == ']'){
|
||||
exclude++;
|
||||
builderToUse = &exclude_and_remove;
|
||||
}
|
||||
if (builderToUse->size() > 0) {
|
||||
builderToUse->append("|");
|
||||
}
|
||||
builderToUse->append(convertToBnameRegexpSyntax(exclude));
|
||||
bool success = true;
|
||||
foreach (const QString &file, _excludeFiles) {
|
||||
if (csync_exclude_load(file.toUtf8(), &_allExcludes) < 0)
|
||||
success = false;
|
||||
}
|
||||
|
||||
QString pattern = "^(" + exclude_only + ")$|^(" + exclude_and_remove + ")$";
|
||||
regexp_exclude.setPattern(pattern);
|
||||
QRegularExpression::PatternOptions patternOptions = QRegularExpression::OptimizeOnFirstUsageOption;
|
||||
if (OCC::Utility::fsCasePreserving())
|
||||
patternOptions |= QRegularExpression::CaseInsensitiveOption;
|
||||
regexp_exclude.setPatternOptions(patternOptions);
|
||||
regexp_exclude.optimize();
|
||||
_allExcludes.append(_manualExcludes);
|
||||
|
||||
prepare();
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
CSYNC_EXCLUDE_TYPE csync_excluded_traversal(CSYNC *ctx, const char *path, int filetype) {
|
||||
bool ExcludedFiles::isExcluded(
|
||||
const QString &filePath,
|
||||
const QString &basePath,
|
||||
bool excludeHidden) const
|
||||
{
|
||||
if (!filePath.startsWith(basePath, Utility::fsCasePreserving() ? Qt::CaseInsensitive : Qt::CaseSensitive)) {
|
||||
// Mark paths we're not responsible for as excluded...
|
||||
return true;
|
||||
}
|
||||
|
||||
if (excludeHidden) {
|
||||
QString path = filePath;
|
||||
// Check all path subcomponents, but to *not* check the base path:
|
||||
// We do want to be able to sync with a hidden folder as the target.
|
||||
while (path.size() > basePath.size()) {
|
||||
QFileInfo fi(path);
|
||||
if (fi.isHidden() || fi.fileName().startsWith(QLatin1Char('.'))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Get the parent path
|
||||
path = fi.absolutePath();
|
||||
}
|
||||
}
|
||||
|
||||
QFileInfo fi(filePath);
|
||||
csync_ftw_type_e type = CSYNC_FTW_TYPE_FILE;
|
||||
if (fi.isDir()) {
|
||||
type = CSYNC_FTW_TYPE_DIR;
|
||||
}
|
||||
|
||||
QString relativePath = filePath.mid(basePath.size());
|
||||
if (relativePath.endsWith(QLatin1Char('/'))) {
|
||||
relativePath.chop(1);
|
||||
}
|
||||
|
||||
return fullPatternMatch(relativePath.toUtf8(), type) != CSYNC_NOT_EXCLUDED;
|
||||
}
|
||||
|
||||
CSYNC_EXCLUDE_TYPE ExcludedFiles::traversalPatternMatch(const char *path, int filetype) const
|
||||
{
|
||||
CSYNC_EXCLUDE_TYPE match = CSYNC_NOT_EXCLUDED;
|
||||
|
||||
/* Check only static patterns and only with the reduced list which is empty usually */
|
||||
match = _csync_excluded_common(ctx->parsed_traversal_excludes.list_patterns_fnmatch, path, filetype, false);
|
||||
match = _csync_excluded_common(_nonRegexExcludes, path, filetype, false);
|
||||
if (match != CSYNC_NOT_EXCLUDED) {
|
||||
return match;
|
||||
}
|
||||
|
||||
if (ctx->excludes) {
|
||||
if (!_allExcludes.isEmpty()) {
|
||||
/* Now check with our optimized regexps */
|
||||
const char *bname = NULL;
|
||||
/* split up the path */
|
||||
@ -508,7 +536,7 @@ CSYNC_EXCLUDE_TYPE csync_excluded_traversal(CSYNC *ctx, const char *path, int fi
|
||||
bname = path;
|
||||
}
|
||||
QString p = QString::fromUtf8(bname);
|
||||
auto m = ctx->parsed_traversal_excludes.regexp_exclude.match(p);
|
||||
auto m = _regex.match(p);
|
||||
if (m.hasMatch()) {
|
||||
if (!m.captured(1).isEmpty()) {
|
||||
match = CSYNC_FILE_EXCLUDE_LIST;
|
||||
@ -520,7 +548,62 @@ CSYNC_EXCLUDE_TYPE csync_excluded_traversal(CSYNC *ctx, const char *path, int fi
|
||||
return match;
|
||||
}
|
||||
|
||||
CSYNC_EXCLUDE_TYPE csync_excluded_no_ctx(c_strlist_t *excludes, const char *path, int filetype) {
|
||||
return _csync_excluded_common(excludes, path, filetype, true);
|
||||
CSYNC_EXCLUDE_TYPE ExcludedFiles::fullPatternMatch(const char *path, int filetype) const
|
||||
{
|
||||
return _csync_excluded_common(_allExcludes, path, filetype, true);
|
||||
}
|
||||
|
||||
auto ExcludedFiles::csyncTraversalMatchFun() const
|
||||
-> std::function<CSYNC_EXCLUDE_TYPE(const char *path, int filetype)>
|
||||
{
|
||||
return [this](const char *path, int filetype) { return this->traversalPatternMatch(path, filetype); };
|
||||
}
|
||||
|
||||
/* Only for bnames (not paths) */
|
||||
static QString convertToBnameRegexpSyntax(QString exclude)
|
||||
{
|
||||
QString s = QRegularExpression::escape(exclude).replace("\\*", ".*").replace("\\?", ".");
|
||||
return s;
|
||||
}
|
||||
|
||||
void ExcludedFiles::prepare()
|
||||
{
|
||||
_nonRegexExcludes.clear();
|
||||
|
||||
// Start out with regexes that would match nothing
|
||||
QString exclude_only = "a^";
|
||||
QString exclude_and_remove = "a^";
|
||||
|
||||
for (auto exclude : _allExcludes) {
|
||||
QString *builderToUse = &exclude_only;
|
||||
if (exclude[0] == '\n')
|
||||
continue; // empty line
|
||||
if (exclude[0] == '\r')
|
||||
continue; // empty line
|
||||
|
||||
/* If an exclude entry contains some fnmatch-ish characters, we use the C-style codepath without QRegularEpression */
|
||||
if (strchr(exclude, '/') || strchr(exclude, '[') || strchr(exclude, '{') || strchr(exclude, '\\')) {
|
||||
_nonRegexExcludes.append(exclude);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Those will attempt to use QRegularExpression */
|
||||
if (exclude[0] == ']') {
|
||||
exclude = exclude.mid(1);
|
||||
builderToUse = &exclude_and_remove;
|
||||
}
|
||||
if (builderToUse->size() > 0) {
|
||||
builderToUse->append("|");
|
||||
}
|
||||
builderToUse->append(convertToBnameRegexpSyntax(QString::fromUtf8(exclude)));
|
||||
}
|
||||
|
||||
QString pattern = "^(" + exclude_only + ")$|^(" + exclude_and_remove + ")$";
|
||||
_regex.setPattern(pattern);
|
||||
QRegularExpression::PatternOptions patternOptions = QRegularExpression::OptimizeOnFirstUsageOption;
|
||||
if (OCC::Utility::fsCasePreserving())
|
||||
patternOptions |= QRegularExpression::CaseInsensitiveOption;
|
||||
_regex.setPatternOptions(patternOptions);
|
||||
_regex.optimize();
|
||||
}
|
||||
|
||||
|
@ -23,6 +23,13 @@
|
||||
|
||||
#include "ocsynclib.h"
|
||||
|
||||
#include "csync.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QSet>
|
||||
#include <QString>
|
||||
#include <QRegularExpression>
|
||||
|
||||
enum csync_exclude_type_e {
|
||||
CSYNC_NOT_EXCLUDED = 0,
|
||||
CSYNC_FILE_SILENTLY_EXCLUDED,
|
||||
@ -38,63 +45,127 @@ enum csync_exclude_type_e {
|
||||
};
|
||||
typedef enum csync_exclude_type_e CSYNC_EXCLUDE_TYPE;
|
||||
|
||||
#ifdef WITH_TESTING
|
||||
int OCSYNC_EXPORT _csync_exclude_add(c_strlist_t **inList, const char *string);
|
||||
/**
|
||||
* Manages file/directory exclusion.
|
||||
*
|
||||
* Most commonly exclude patterns are loaded from files. See
|
||||
* addExcludeFilePath() and reloadExcludeFiles().
|
||||
*
|
||||
* Excluded files are primarily relevant for sync runs, and for
|
||||
* file watcher filtering.
|
||||
*
|
||||
* Excluded files and ignored files are the same thing. But the
|
||||
* selective sync blacklist functionality is a different thing
|
||||
* entirely.
|
||||
*/
|
||||
class OCSYNC_EXPORT ExcludedFiles : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ExcludedFiles();
|
||||
~ExcludedFiles();
|
||||
|
||||
/**
|
||||
* Adds a new path to a file containing exclude patterns.
|
||||
*
|
||||
* Does not load the file. Use reloadExcludeFiles() afterwards.
|
||||
*/
|
||||
void addExcludeFilePath(const QString &path);
|
||||
|
||||
/**
|
||||
* Checks whether a file or directory should be excluded.
|
||||
*
|
||||
* @param filePath the absolute path to the file
|
||||
* @param basePath folder path from which to apply exclude rules, ends with a /
|
||||
*/
|
||||
bool isExcluded(
|
||||
const QString &filePath,
|
||||
const QString &basePath,
|
||||
bool excludeHidden) const;
|
||||
|
||||
/**
|
||||
* Adds an exclude pattern.
|
||||
*
|
||||
* Primarily used in tests. Patterns added this way are preserved when
|
||||
* reloadExcludeFiles() is called.
|
||||
*/
|
||||
void addManualExclude(const QByteArray &expr);
|
||||
|
||||
/**
|
||||
* Removes all manually added exclude patterns.
|
||||
*
|
||||
* Primarily used in tests.
|
||||
*/
|
||||
void clearManualExcludes();
|
||||
|
||||
/**
|
||||
* Generate a hook for traversal exclude pattern matching
|
||||
* that csync can use.
|
||||
*
|
||||
* Careful: The function will only be valid for as long as this
|
||||
* ExcludedFiles instance stays alive.
|
||||
*/
|
||||
auto csyncTraversalMatchFun() const
|
||||
-> std::function<CSYNC_EXCLUDE_TYPE(const char *path, int filetype)>;
|
||||
|
||||
public slots:
|
||||
/**
|
||||
* Reloads the exclude patterns from the registered paths.
|
||||
*/
|
||||
bool reloadExcludeFiles();
|
||||
|
||||
#ifdef CSYNC_TEST
|
||||
public:
|
||||
#else
|
||||
private:
|
||||
#endif
|
||||
/**
|
||||
* @brief Match the exclude pattern against the full path.
|
||||
*
|
||||
* @param Path is folder-relative, should not start with a /.
|
||||
*
|
||||
* Note that this only matches patterns. It does not check whether the file
|
||||
* or directory pointed to is hidden (or whether it even exists).
|
||||
*/
|
||||
CSYNC_EXCLUDE_TYPE fullPatternMatch(const char *path, int filetype) const;
|
||||
|
||||
/**
|
||||
* @brief Load exclude list
|
||||
*
|
||||
* @param ctx The context of the synchronizer.
|
||||
* @param fname The filename to load.
|
||||
*
|
||||
* @return 0 on success, -1 if an error occurred with errno set.
|
||||
*/
|
||||
int OCSYNC_EXPORT csync_exclude_load(const char *fname, c_strlist_t **list);
|
||||
/**
|
||||
* @brief Check if the given path should be excluded in a traversal situation.
|
||||
*
|
||||
* It does only part of the work that full() does because it's assumed
|
||||
* that all leading directories have been run through traversal()
|
||||
* before. This can be significantly faster.
|
||||
*
|
||||
* That means for 'foo/bar/file' only ('foo/bar/file', 'file') is checked
|
||||
* against the exclude patterns.
|
||||
*
|
||||
* @param Path is folder-relative, should not start with a /.
|
||||
*
|
||||
* Note that this only matches patterns. It does not check whether the file
|
||||
* or directory pointed to is hidden (or whether it even exists).
|
||||
*/
|
||||
CSYNC_EXCLUDE_TYPE traversalPatternMatch(const char *path, int filetype) const;
|
||||
|
||||
/**
|
||||
* @brief When all list loads and list are done
|
||||
*
|
||||
* Used to initialize internal data structures that build upon the loaded excludes.
|
||||
*
|
||||
* @param ctx
|
||||
*/
|
||||
void OCSYNC_EXPORT csync_exclude_traversal_prepare(CSYNC *ctx);
|
||||
/**
|
||||
* Generate an optimized _regex for many of the patterns. The remaining
|
||||
* patterns are put into _nonRegexExcludes.
|
||||
*/
|
||||
void prepare();
|
||||
|
||||
/**
|
||||
* @brief Check if the given path should be excluded in a traversal situation.
|
||||
*
|
||||
* It does only part of the work that csync_excluded does because it's assumed
|
||||
* that all leading directories have been run through csync_excluded_traversal()
|
||||
* before. This can be significantly faster.
|
||||
*
|
||||
* That means for '/foo/bar/file' only ('/foo/bar/file', 'file') is checked
|
||||
* against the exclude patterns.
|
||||
*
|
||||
* @param ctx The synchronizer context.
|
||||
* @param path The patch to check.
|
||||
*
|
||||
* @return 2 if excluded and needs cleanup, 1 if excluded, 0 if not.
|
||||
*/
|
||||
CSYNC_EXCLUDE_TYPE OCSYNC_EXPORT csync_excluded_traversal(CSYNC *ctx, const char *path, int filetype);
|
||||
/// Files to load excludes from
|
||||
QSet<QString> _excludeFiles;
|
||||
|
||||
/// Exclude patterns added with addManualExclude()
|
||||
QList<QByteArray> _manualExcludes;
|
||||
|
||||
/// List of all active exclude patterns
|
||||
QList<QByteArray> _allExcludes;
|
||||
|
||||
/// see prepare()
|
||||
QList<QByteArray> _nonRegexExcludes;
|
||||
|
||||
/// see prepare()
|
||||
QRegularExpression _regex;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Checks all path components if the whole path should be excluded
|
||||
*
|
||||
* @param excludes
|
||||
* @param path
|
||||
* @param filetype
|
||||
* @return
|
||||
*/
|
||||
CSYNC_EXCLUDE_TYPE OCSYNC_EXPORT csync_excluded_no_ctx(c_strlist_t *excludes, const char *path, int filetype);
|
||||
#endif /* _CSYNC_EXCLUDE_H */
|
||||
|
||||
/**
|
||||
* @brief Checks if filename is considered reserved by Windows
|
||||
* @param file_name filename
|
||||
* @return true if file is reserved, false otherwise
|
||||
*/
|
||||
bool csync_is_windows_reserved_word(const char *file_name);
|
||||
|
||||
|
||||
/* vim: set ft=c.doxygen ts=8 sw=2 et cindent: */
|
||||
|
@ -39,6 +39,7 @@
|
||||
#include <sqlite3.h>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <functional>
|
||||
|
||||
#include "common/syncjournaldb.h"
|
||||
#include "config_csync.h"
|
||||
@ -46,11 +47,9 @@
|
||||
#include "std/c_private.h"
|
||||
#include "csync.h"
|
||||
#include "csync_misc.h"
|
||||
|
||||
#include "csync_exclude.h"
|
||||
#include "csync_macros.h"
|
||||
|
||||
#include <QRegularExpression>
|
||||
|
||||
/**
|
||||
* How deep to scan directories.
|
||||
*/
|
||||
@ -148,17 +147,13 @@ struct OCSYNC_EXPORT csync_s {
|
||||
|
||||
OCC::SyncJournalDb *statedb;
|
||||
|
||||
c_strlist_t *excludes = nullptr; /* list of individual patterns collected from all exclude files */
|
||||
struct TraversalExcludes {
|
||||
~TraversalExcludes() {
|
||||
c_strlist_destroy(list_patterns_fnmatch);
|
||||
}
|
||||
void prepare(c_strlist_t *excludes);
|
||||
|
||||
QRegularExpression regexp_exclude;
|
||||
c_strlist_t *list_patterns_fnmatch = nullptr;
|
||||
|
||||
} parsed_traversal_excludes;
|
||||
/**
|
||||
* Function used to determine whether an item is excluded
|
||||
* during the update phase.
|
||||
*
|
||||
* See ExcludedFiles in csync_exclude.
|
||||
*/
|
||||
std::function<CSYNC_EXCLUDE_TYPE(const char *path, int filetype)> exclude_traversal_fn;
|
||||
|
||||
struct {
|
||||
std::unordered_map<ByteArrayRef, QByteArray, ByteArrayRefHash> folder_renamed_to; // map from->to
|
||||
|
@ -109,7 +109,7 @@ static bool _csync_mtime_equal(time_t a, time_t b)
|
||||
*/
|
||||
static int _csync_detect_update(CSYNC *ctx, std::unique_ptr<csync_file_stat_t> fs) {
|
||||
OCC::SyncJournalFileRecord base;
|
||||
CSYNC_EXCLUDE_TYPE excluded;
|
||||
CSYNC_EXCLUDE_TYPE excluded = CSYNC_NOT_EXCLUDED;
|
||||
|
||||
if (fs == NULL) {
|
||||
errno = EINVAL;
|
||||
@ -120,8 +120,9 @@ static int _csync_detect_update(CSYNC *ctx, std::unique_ptr<csync_file_stat_t> f
|
||||
if (fs->type == CSYNC_FTW_TYPE_SKIP) {
|
||||
excluded =CSYNC_FILE_EXCLUDE_STAT_FAILED;
|
||||
} else {
|
||||
/* Check if file is excluded */
|
||||
excluded = csync_excluded_traversal(ctx, fs->path, fs->type);
|
||||
/* Check if file is excluded */
|
||||
if (ctx->exclude_traversal_fn)
|
||||
excluded = ctx->exclude_traversal_fn(fs->path, fs->type);
|
||||
}
|
||||
|
||||
if( excluded == CSYNC_NOT_EXCLUDED ) {
|
||||
@ -498,7 +499,9 @@ static bool fill_tree_from_db(CSYNC *ctx, const char *uri)
|
||||
/* Check for exclusion from the tree.
|
||||
* Note that this is only a safety net in case the ignore list changes
|
||||
* without a full remote discovery being triggered. */
|
||||
CSYNC_EXCLUDE_TYPE excluded = csync_excluded_traversal(ctx, st->path, st->type);
|
||||
CSYNC_EXCLUDE_TYPE excluded = CSYNC_NOT_EXCLUDED;
|
||||
if (ctx->exclude_traversal_fn)
|
||||
excluded = ctx->exclude_traversal_fn(st->path, st->type);
|
||||
if (excluded != CSYNC_NOT_EXCLUDED) {
|
||||
qDebug(lcUpdate, "%s excluded (%d)", st->path.constData(), excluded);
|
||||
|
||||
|
@ -35,7 +35,6 @@
|
||||
#include "accountmanager.h"
|
||||
#include "creds/abstractcredentials.h"
|
||||
#include "updater/ocupdater.h"
|
||||
#include "excludedfiles.h"
|
||||
#include "owncloudsetupwizard.h"
|
||||
#include "version.h"
|
||||
|
||||
@ -140,14 +139,6 @@ Application::Application(int &argc, char **argv)
|
||||
setupLogging();
|
||||
setupTranslations();
|
||||
|
||||
// Setup global excludes
|
||||
qCInfo(lcApplication) << "Loading global exclude list";
|
||||
ConfigFile cfg;
|
||||
ExcludedFiles &excludes = ExcludedFiles::instance();
|
||||
excludes.addExcludeFilePath(cfg.excludeFile(ConfigFile::SystemScope));
|
||||
excludes.addExcludeFilePath(cfg.excludeFile(ConfigFile::UserScope));
|
||||
excludes.reloadExcludes();
|
||||
|
||||
_folderManager.reset(new FolderMan);
|
||||
|
||||
connect(this, &SharedTools::QtSingleApplication::messageReceived, this, &Application::slotParseMessage);
|
||||
@ -175,6 +166,7 @@ Application::Application(int &argc, char **argv)
|
||||
|
||||
setQuitOnLastWindowClosed(false);
|
||||
|
||||
ConfigFile cfg;
|
||||
_theme->setSystrayUseMonoIcons(cfg.monoIcons());
|
||||
connect(_theme, &Theme::systrayUseMonoIconsChanged, this, &Application::slotUseMonoIconsChanged);
|
||||
|
||||
|
@ -30,7 +30,6 @@
|
||||
#include "socketapi.h"
|
||||
#include "theme.h"
|
||||
#include "filesystem.h"
|
||||
#include "excludedfiles.h"
|
||||
|
||||
#include "creds/abstractcredentials.h"
|
||||
|
||||
@ -79,7 +78,8 @@ Folder::Folder(const FolderDefinition &definition,
|
||||
// pass the setting if hidden files are to be ignored, will be read in csync_update
|
||||
_engine->setIgnoreHiddenFiles(_definition.ignoreHiddenFiles);
|
||||
|
||||
if (!setIgnoredFiles())
|
||||
ConfigFile::setupDefaultExcludeFilePaths(_engine->excludedFiles());
|
||||
if (!reloadExcludes())
|
||||
qCWarning(lcFolder, "Could not read system exclude file");
|
||||
|
||||
connect(_accountState.data(), &AccountState::isConnectedChanged, this, &Folder::canSyncChanged);
|
||||
@ -595,24 +595,9 @@ void Folder::wipe()
|
||||
FolderMan::instance()->socketApi()->slotRegisterPath(alias());
|
||||
}
|
||||
|
||||
bool Folder::setIgnoredFiles()
|
||||
bool Folder::reloadExcludes()
|
||||
{
|
||||
// Note: Doing this on each sync run and on Folder construction is
|
||||
// unnecessary, because _engine->excludedFiles() persists between
|
||||
// sync runs. This is not a big problem because ExcludedFiles maintains
|
||||
// a QSet of files to load.
|
||||
ConfigFile cfg;
|
||||
QString systemList = cfg.excludeFile(ConfigFile::SystemScope);
|
||||
qCInfo(lcFolder) << "Adding system ignore list to csync:" << systemList;
|
||||
_engine->excludedFiles().addExcludeFilePath(systemList);
|
||||
|
||||
QString userList = cfg.excludeFile(ConfigFile::UserScope);
|
||||
if (QFile::exists(userList)) {
|
||||
qCInfo(lcFolder) << "Adding user defined ignore list to csync:" << userList;
|
||||
_engine->excludedFiles().addExcludeFilePath(userList);
|
||||
}
|
||||
|
||||
return _engine->excludedFiles().reloadExcludes();
|
||||
return _engine->excludedFiles().reloadExcludeFiles();
|
||||
}
|
||||
|
||||
void Folder::setProxyDirty(bool value)
|
||||
@ -647,7 +632,7 @@ void Folder::startSync(const QStringList &pathList)
|
||||
|
||||
_fileLog->start(path());
|
||||
|
||||
if (!setIgnoredFiles()) {
|
||||
if (!reloadExcludes()) {
|
||||
slotSyncError(tr("Could not read system exclude file"));
|
||||
QMetaObject::invokeMethod(this, "slotSyncFinished", Qt::QueuedConnection, Q_ARG(bool, false));
|
||||
return;
|
||||
|
@ -323,7 +323,7 @@ private slots:
|
||||
void slotNextSyncFullLocalDiscovery();
|
||||
|
||||
private:
|
||||
bool setIgnoredFiles();
|
||||
bool reloadExcludes();
|
||||
|
||||
void showSyncResultPopup();
|
||||
|
||||
|
@ -32,7 +32,6 @@
|
||||
#include "folderwatcher_linux.h"
|
||||
#endif
|
||||
|
||||
#include "excludedfiles.h"
|
||||
#include "folder.h"
|
||||
|
||||
namespace OCC {
|
||||
|
@ -17,7 +17,6 @@
|
||||
#include "ignorelisteditor.h"
|
||||
#include "folderman.h"
|
||||
#include "ui_ignorelisteditor.h"
|
||||
#include "excludedfiles.h"
|
||||
|
||||
#include <QFile>
|
||||
#include <QDir>
|
||||
@ -135,8 +134,6 @@ void IgnoreListEditor::slotUpdateLocalIgnoreList()
|
||||
folder->journalDb()->forceRemoteDiscoveryNextSync();
|
||||
folderMan->scheduleFolder(folder);
|
||||
}
|
||||
|
||||
ExcludedFiles::instance().reloadExcludes();
|
||||
}
|
||||
|
||||
void IgnoreListEditor::slotAddPattern()
|
||||
|
@ -14,7 +14,6 @@
|
||||
#include "selectivesyncdialog.h"
|
||||
#include "folder.h"
|
||||
#include "account.h"
|
||||
#include "excludedfiles.h"
|
||||
#include "networkjobs.h"
|
||||
#include "theme.h"
|
||||
#include "folderman.h"
|
||||
@ -95,6 +94,9 @@ SelectiveSyncWidget::SelectiveSyncWidget(AccountPtr account, QWidget *parent)
|
||||
_folderTree->header()->setStretchLastSection(true);
|
||||
_folderTree->headerItem()->setText(0, tr("Name"));
|
||||
_folderTree->headerItem()->setText(1, tr("Size"));
|
||||
|
||||
ConfigFile::setupDefaultExcludeFilePaths(_excludedFiles);
|
||||
_excludedFiles.reloadExcludeFiles();
|
||||
}
|
||||
|
||||
QSize SelectiveSyncWidget::sizeHint() const
|
||||
@ -204,7 +206,7 @@ void SelectiveSyncWidget::slotUpdateDirectories(QStringList list)
|
||||
QMutableListIterator<QString> it(list);
|
||||
while (it.hasNext()) {
|
||||
it.next();
|
||||
if (ExcludedFiles::instance().isExcluded(it.value(), pathToRemove, FolderMan::instance()->ignoreHiddenFiles()))
|
||||
if (_excludedFiles.isExcluded(it.value(), pathToRemove, FolderMan::instance()->ignoreHiddenFiles()))
|
||||
it.remove();
|
||||
}
|
||||
|
||||
|
@ -17,6 +17,8 @@
|
||||
#include <QTreeWidget>
|
||||
#include "accountfwd.h"
|
||||
|
||||
#include "csync_exclude.h"
|
||||
|
||||
class QTreeWidgetItem;
|
||||
class QTreeWidget;
|
||||
class QNetworkReply;
|
||||
@ -72,6 +74,10 @@ private:
|
||||
QLabel *_loading;
|
||||
|
||||
QTreeWidget *_folderTree;
|
||||
|
||||
// During account setup we want to filter out excluded folders from the
|
||||
// view without having a Folder.SyncEngine.ExcludedFiles instance.
|
||||
ExcludedFiles _excludedFiles;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -56,7 +56,6 @@ set(libsync_SRCS
|
||||
syncfilestatustracker.cpp
|
||||
syncresult.cpp
|
||||
theme.cpp
|
||||
excludedfiles.cpp
|
||||
creds/dummycredentials.cpp
|
||||
creds/abstractcredentials.cpp
|
||||
creds/credentialscommon.cpp
|
||||
|
@ -21,6 +21,8 @@
|
||||
|
||||
#include "creds/abstractcredentials.h"
|
||||
|
||||
#include "csync_exclude.h"
|
||||
|
||||
#ifndef TOKEN_AUTH_ONLY
|
||||
#include <QWidget>
|
||||
#include <QHeaderView>
|
||||
@ -748,4 +750,17 @@ std::unique_ptr<QSettings> ConfigFile::settingsWithGroup(const QString &group, Q
|
||||
return settings;
|
||||
}
|
||||
|
||||
void ConfigFile::setupDefaultExcludeFilePaths(ExcludedFiles &excludedFiles)
|
||||
{
|
||||
ConfigFile cfg;
|
||||
QString systemList = cfg.excludeFile(ConfigFile::SystemScope);
|
||||
qCInfo(lcConfigFile) << "Adding system ignore list to csync:" << systemList;
|
||||
excludedFiles.addExcludeFilePath(systemList);
|
||||
|
||||
QString userList = cfg.excludeFile(ConfigFile::UserScope);
|
||||
if (QFile::exists(userList)) {
|
||||
qCInfo(lcConfigFile) << "Adding user defined ignore list to csync:" << userList;
|
||||
excludedFiles.addExcludeFilePath(userList);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -24,6 +24,7 @@
|
||||
|
||||
class QWidget;
|
||||
class QHeaderView;
|
||||
class ExcludedFiles;
|
||||
|
||||
namespace OCC {
|
||||
|
||||
@ -153,6 +154,9 @@ public:
|
||||
with the given parent. If no parent is specified, the caller must destroy the settings */
|
||||
static std::unique_ptr<QSettings> settingsWithGroup(const QString &group, QObject *parent = 0);
|
||||
|
||||
/// Add the system and user exclude file path to the ExcludedFiles instance.
|
||||
static void setupDefaultExcludeFilePaths(ExcludedFiles &excludedFiles);
|
||||
|
||||
protected:
|
||||
QVariant getPolicySetting(const QString &policy, const QVariant &defaultValue = QVariant()) const;
|
||||
void storeData(const QString &group, const QString &key, const QVariant &value);
|
||||
|
@ -698,8 +698,6 @@ void DiscoveryJob::start()
|
||||
_csync_ctx->callbacks.remote_closedir_hook = remote_vio_closedir_hook;
|
||||
_csync_ctx->callbacks.vio_userdata = this;
|
||||
|
||||
csync_exclude_traversal_prepare(_csync_ctx); // Converts the flat exclude list to optimized regexps
|
||||
|
||||
csync_set_log_callback(_log_callback);
|
||||
csync_set_log_level(_log_level);
|
||||
_lastUpdateProgressCallbackCall.invalidate();
|
||||
|
@ -1,107 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) by Christian Kamm <mail@ckamm.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "excludedfiles.h"
|
||||
#include "common/utility.h"
|
||||
|
||||
#include <QFileInfo>
|
||||
|
||||
#include "std/c_string.h"
|
||||
#include "csync.h"
|
||||
#include "csync_exclude.h"
|
||||
|
||||
using namespace OCC;
|
||||
|
||||
ExcludedFiles::ExcludedFiles(c_strlist_t **excludesPtr)
|
||||
: _excludesPtr(excludesPtr)
|
||||
{
|
||||
}
|
||||
|
||||
ExcludedFiles::~ExcludedFiles()
|
||||
{
|
||||
c_strlist_destroy(*_excludesPtr);
|
||||
}
|
||||
|
||||
ExcludedFiles &ExcludedFiles::instance()
|
||||
{
|
||||
static c_strlist_t *globalExcludes;
|
||||
static ExcludedFiles inst(&globalExcludes);
|
||||
return inst;
|
||||
}
|
||||
|
||||
void ExcludedFiles::addExcludeFilePath(const QString &path)
|
||||
{
|
||||
_excludeFiles.insert(path);
|
||||
}
|
||||
|
||||
#ifdef WITH_TESTING
|
||||
void ExcludedFiles::addExcludeExpr(const QString &expr)
|
||||
{
|
||||
_csync_exclude_add(_excludesPtr, expr.toLatin1().constData());
|
||||
}
|
||||
#endif
|
||||
|
||||
bool ExcludedFiles::reloadExcludes()
|
||||
{
|
||||
c_strlist_destroy(*_excludesPtr);
|
||||
*_excludesPtr = NULL;
|
||||
|
||||
bool success = true;
|
||||
foreach (const QString &file, _excludeFiles) {
|
||||
if (csync_exclude_load(file.toUtf8(), _excludesPtr) < 0)
|
||||
success = false;
|
||||
}
|
||||
// The csync_exclude_traversal_prepare is called implicitely at sync start.
|
||||
return success;
|
||||
}
|
||||
|
||||
bool ExcludedFiles::isExcluded(
|
||||
const QString &filePath,
|
||||
const QString &basePath,
|
||||
bool excludeHidden) const
|
||||
{
|
||||
if (!filePath.startsWith(basePath, Utility::fsCasePreserving() ? Qt::CaseInsensitive : Qt::CaseSensitive)) {
|
||||
// Mark paths we're not responsible for as excluded...
|
||||
return true;
|
||||
}
|
||||
|
||||
if (excludeHidden) {
|
||||
QString path = filePath;
|
||||
// Check all path subcomponents, but to *not* check the base path:
|
||||
// We do want to be able to sync with a hidden folder as the target.
|
||||
while (path.size() > basePath.size()) {
|
||||
QFileInfo fi(path);
|
||||
if (fi.isHidden() || fi.fileName().startsWith(QLatin1Char('.'))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Get the parent path
|
||||
path = fi.absolutePath();
|
||||
}
|
||||
}
|
||||
|
||||
QFileInfo fi(filePath);
|
||||
csync_ftw_type_e type = CSYNC_FTW_TYPE_FILE;
|
||||
if (fi.isDir()) {
|
||||
type = CSYNC_FTW_TYPE_DIR;
|
||||
}
|
||||
|
||||
QString relativePath = filePath.mid(basePath.size());
|
||||
if (relativePath.endsWith(QLatin1Char('/'))) {
|
||||
relativePath.chop(1);
|
||||
}
|
||||
|
||||
return csync_excluded_no_ctx(*_excludesPtr, relativePath.toUtf8(), type) != CSYNC_NOT_EXCLUDED;
|
||||
}
|
@ -1,76 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) by Christian Kamm <mail@ckamm.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "owncloudlib.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QSet>
|
||||
#include <QString>
|
||||
|
||||
#include "std/c_string.h"
|
||||
#include "csync.h"
|
||||
#include "csync_exclude.h" // for CSYNC_EXCLUDE_TYPE
|
||||
|
||||
namespace OCC {
|
||||
|
||||
/**
|
||||
* Manages the global system and user exclude lists.
|
||||
*/
|
||||
class OWNCLOUDSYNC_EXPORT ExcludedFiles : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
static ExcludedFiles &instance();
|
||||
|
||||
ExcludedFiles(c_strlist_t **excludesPtr);
|
||||
~ExcludedFiles();
|
||||
|
||||
/**
|
||||
* Adds a new path to a file containing exclude patterns.
|
||||
*
|
||||
* Does not load the file. Use reloadExcludes() afterwards.
|
||||
*/
|
||||
void addExcludeFilePath(const QString &path);
|
||||
|
||||
/**
|
||||
* Checks whether a file or directory should be excluded.
|
||||
*
|
||||
* @param filePath the absolute path to the file
|
||||
* @param basePath folder path from which to apply exclude rules
|
||||
*/
|
||||
bool isExcluded(
|
||||
const QString &filePath,
|
||||
const QString &basePath,
|
||||
bool excludeHidden) const;
|
||||
|
||||
#ifdef WITH_TESTING
|
||||
void addExcludeExpr(const QString &expr);
|
||||
#endif
|
||||
|
||||
public slots:
|
||||
/**
|
||||
* Reloads the exclude patterns from the registered paths.
|
||||
*/
|
||||
bool reloadExcludes();
|
||||
|
||||
private:
|
||||
// This is a pointer to the csync exclude list, its is owned by this class
|
||||
// but the pointer can be in a csync_context so that it can itself also query the list.
|
||||
c_strlist_t **_excludesPtr;
|
||||
QSet<QString> _excludeFiles;
|
||||
};
|
||||
|
||||
} // namespace OCC
|
@ -89,7 +89,9 @@ SyncEngine::SyncEngine(AccountPtr account, const QString &localPath,
|
||||
|
||||
_csync_ctx.reset(new CSYNC(localPath.toUtf8().data(), journal));
|
||||
|
||||
_excludedFiles.reset(new ExcludedFiles(&_csync_ctx->excludes));
|
||||
_excludedFiles.reset(new ExcludedFiles);
|
||||
_csync_ctx->exclude_traversal_fn = _excludedFiles->csyncTraversalMatchFun();
|
||||
|
||||
_syncFileStatusTracker.reset(new SyncFileStatusTracker(this));
|
||||
|
||||
_clearTouchedFilesTimer.setSingleShot(true);
|
||||
|
@ -32,7 +32,6 @@
|
||||
// when do we go away with this private/public separation?
|
||||
#include <csync_private.h>
|
||||
|
||||
#include "excludedfiles.h"
|
||||
#include "syncfileitem.h"
|
||||
#include "progressdispatcher.h"
|
||||
#include "common/utility.h"
|
||||
|
@ -29,10 +29,14 @@
|
||||
|
||||
#define EXCLUDE_LIST_FILE SOURCEDIR"/../../sync-exclude.lst"
|
||||
|
||||
ExcludedFiles *excludedFiles = nullptr;
|
||||
|
||||
static int setup(void **state) {
|
||||
CSYNC *csync;
|
||||
|
||||
csync = new CSYNC("/tmp/check_csync1", new OCC::SyncJournalDb(""));
|
||||
excludedFiles = new ExcludedFiles;
|
||||
csync->exclude_traversal_fn = excludedFiles->csyncTraversalMatchFun();
|
||||
|
||||
*state = csync;
|
||||
return 0;
|
||||
@ -40,26 +44,22 @@ static int setup(void **state) {
|
||||
|
||||
static int setup_init(void **state) {
|
||||
CSYNC *csync;
|
||||
int rc;
|
||||
|
||||
csync = new CSYNC("/tmp/check_csync1", new OCC::SyncJournalDb(""));
|
||||
excludedFiles = new ExcludedFiles;
|
||||
csync->exclude_traversal_fn = excludedFiles->csyncTraversalMatchFun();
|
||||
|
||||
rc = csync_exclude_load(EXCLUDE_LIST_FILE, &(csync->excludes));
|
||||
assert_int_equal(rc, 0);
|
||||
excludedFiles->addExcludeFilePath(EXCLUDE_LIST_FILE);
|
||||
assert_true(excludedFiles->reloadExcludeFiles());
|
||||
|
||||
/* and add some unicode stuff */
|
||||
rc = _csync_exclude_add(&(csync->excludes), "*.💩");
|
||||
assert_int_equal(rc, 0);
|
||||
rc = _csync_exclude_add(&(csync->excludes), "пятницы.*");
|
||||
assert_int_equal(rc, 0);
|
||||
rc = _csync_exclude_add(&(csync->excludes), "*/*.out");
|
||||
assert_int_equal(rc, 0);
|
||||
rc = _csync_exclude_add(&(csync->excludes), "latex*/*.run.xml");
|
||||
assert_int_equal(rc, 0);
|
||||
rc = _csync_exclude_add(&(csync->excludes), "latex/*/*.tex.tmp");
|
||||
assert_int_equal(rc, 0);
|
||||
excludedFiles->addManualExclude("*.💩"); // is this source file utf8 encoded?
|
||||
excludedFiles->addManualExclude("пятницы.*");
|
||||
excludedFiles->addManualExclude("*/*.out");
|
||||
excludedFiles->addManualExclude("latex*/*.run.xml");
|
||||
excludedFiles->addManualExclude("latex/*/*.tex.tmp");
|
||||
|
||||
csync_exclude_traversal_prepare(csync);
|
||||
assert_true(excludedFiles->reloadExcludeFiles());
|
||||
|
||||
*state = csync;
|
||||
return 0;
|
||||
@ -72,6 +72,7 @@ static int teardown(void **state) {
|
||||
auto statedb = csync->statedb;
|
||||
delete csync;
|
||||
delete statedb;
|
||||
delete excludedFiles;
|
||||
|
||||
rc = system("rm -rf /tmp/check_csync1");
|
||||
assert_int_equal(rc, 0);
|
||||
@ -79,450 +80,313 @@ static int teardown(void **state) {
|
||||
assert_int_equal(rc, 0);
|
||||
|
||||
*state = NULL;
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void check_csync_exclude_add(void **state)
|
||||
int check_file_full(const char *path)
|
||||
{
|
||||
CSYNC *csync = (CSYNC*)*state;
|
||||
_csync_exclude_add(&(csync->excludes), "/tmp/check_csync1/*");
|
||||
assert_string_equal(csync->excludes->vector[0], "/tmp/check_csync1/*");
|
||||
return excludedFiles->fullPatternMatch(path, CSYNC_FTW_TYPE_FILE);
|
||||
}
|
||||
|
||||
static void check_csync_exclude_load(void **state)
|
||||
int check_dir_full(const char *path)
|
||||
{
|
||||
CSYNC *csync = (CSYNC*)*state;
|
||||
int rc;
|
||||
|
||||
rc = csync_exclude_load(EXCLUDE_LIST_FILE, &(csync->excludes) );
|
||||
assert_int_equal(rc, 0);
|
||||
|
||||
assert_string_equal(csync->excludes->vector[0], "*~");
|
||||
assert_int_not_equal(csync->excludes->count, 0);
|
||||
|
||||
assert_true(csync->parsed_traversal_excludes.regexp_exclude.pattern().isEmpty());
|
||||
csync_exclude_traversal_prepare(csync); /* parse into regular expression */
|
||||
assert_false(csync->parsed_traversal_excludes.regexp_exclude.pattern().isEmpty());
|
||||
return excludedFiles->fullPatternMatch(path, CSYNC_FTW_TYPE_DIR);
|
||||
}
|
||||
|
||||
static void check_csync_excluded(void **state)
|
||||
int check_file_traversal(const char *path)
|
||||
{
|
||||
CSYNC *csync = (CSYNC*)*state;
|
||||
int rc;
|
||||
return excludedFiles->traversalPatternMatch(path, CSYNC_FTW_TYPE_FILE);
|
||||
}
|
||||
|
||||
rc = csync_excluded_no_ctx(csync->excludes, "", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_NOT_EXCLUDED);
|
||||
rc = csync_excluded_no_ctx(csync->excludes, "/", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_NOT_EXCLUDED);
|
||||
int check_dir_traversal(const char *path)
|
||||
{
|
||||
return excludedFiles->traversalPatternMatch(path, CSYNC_FTW_TYPE_DIR);
|
||||
}
|
||||
|
||||
rc = csync_excluded_no_ctx(csync->excludes, "A", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_NOT_EXCLUDED);
|
||||
static void check_csync_exclude_add(void **)
|
||||
{
|
||||
excludedFiles->addManualExclude("/tmp/check_csync1/*");
|
||||
assert_int_equal(check_file_full("/tmp/check_csync1/foo"), CSYNC_FILE_EXCLUDE_LIST);
|
||||
assert_int_equal(check_file_full("/tmp/check_csync2/foo"), CSYNC_NOT_EXCLUDED);
|
||||
assert_true(excludedFiles->_allExcludes.contains("/tmp/check_csync1/*"));
|
||||
|
||||
rc = csync_excluded_no_ctx(csync->excludes, "krawel_krawel", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_NOT_EXCLUDED);
|
||||
rc = csync_excluded_no_ctx(csync->excludes, ".kde/share/config/kwin.eventsrc", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_NOT_EXCLUDED);
|
||||
rc = csync_excluded_no_ctx(csync->excludes, ".directory/cache-maximegalon/cache1.txt", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST);
|
||||
rc = csync_excluded_no_ctx(csync->excludes, "mozilla/.directory", CSYNC_FTW_TYPE_DIR);
|
||||
assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST);
|
||||
excludedFiles->prepare();
|
||||
assert_true(excludedFiles->_nonRegexExcludes.contains("/tmp/check_csync1/*"));
|
||||
assert_false(excludedFiles->_regex.pattern().contains("csync1"));
|
||||
|
||||
excludedFiles->addManualExclude("foo");
|
||||
excludedFiles->prepare();
|
||||
assert_true(excludedFiles->_nonRegexExcludes.size() == 1);
|
||||
assert_true(excludedFiles->_regex.pattern().contains("foo"));
|
||||
}
|
||||
|
||||
static void check_csync_excluded(void **)
|
||||
{
|
||||
assert_int_equal(check_file_full(""), CSYNC_NOT_EXCLUDED);
|
||||
assert_int_equal(check_file_full("/"), CSYNC_NOT_EXCLUDED);
|
||||
assert_int_equal(check_file_full("A"), CSYNC_NOT_EXCLUDED);
|
||||
assert_int_equal(check_file_full("krawel_krawel"), CSYNC_NOT_EXCLUDED);
|
||||
assert_int_equal(check_file_full(".kde/share/config/kwin.eventsrc"), CSYNC_NOT_EXCLUDED);
|
||||
assert_int_equal(check_file_full(".directory/cache-maximegalon/cache1.txt"), CSYNC_FILE_EXCLUDE_LIST);
|
||||
assert_int_equal(check_dir_full("mozilla/.directory"), CSYNC_FILE_EXCLUDE_LIST);
|
||||
|
||||
/*
|
||||
* Test for patterns in subdirs. '.beagle' is defined as a pattern and has
|
||||
* to be found in top dir as well as in directories underneath.
|
||||
*/
|
||||
rc = csync_excluded_no_ctx(csync->excludes, ".apdisk", CSYNC_FTW_TYPE_DIR);
|
||||
assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST);
|
||||
rc = csync_excluded_no_ctx(csync->excludes, "foo/.apdisk", CSYNC_FTW_TYPE_DIR);
|
||||
assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST);
|
||||
rc = csync_excluded_no_ctx(csync->excludes, "foo/bar/.apdisk", CSYNC_FTW_TYPE_DIR);
|
||||
assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST);
|
||||
assert_int_equal(check_dir_full(".apdisk"), CSYNC_FILE_EXCLUDE_LIST);
|
||||
assert_int_equal(check_dir_full("foo/.apdisk"), CSYNC_FILE_EXCLUDE_LIST);
|
||||
assert_int_equal(check_dir_full("foo/bar/.apdisk"), CSYNC_FILE_EXCLUDE_LIST);
|
||||
|
||||
rc = csync_excluded_no_ctx(csync->excludes, ".java", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_NOT_EXCLUDED);
|
||||
assert_int_equal(check_file_full(".java"), CSYNC_NOT_EXCLUDED);
|
||||
|
||||
/* Files in the ignored dir .java will also be ignored. */
|
||||
rc = csync_excluded_no_ctx(csync->excludes, ".apdisk/totally_amazing.jar", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST);
|
||||
assert_int_equal(check_file_full(".apdisk/totally_amazing.jar"), CSYNC_FILE_EXCLUDE_LIST);
|
||||
|
||||
/* and also in subdirs */
|
||||
rc = csync_excluded_no_ctx(csync->excludes, "projects/.apdisk/totally_amazing.jar", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST);
|
||||
assert_int_equal(check_file_full("projects/.apdisk/totally_amazing.jar"), CSYNC_FILE_EXCLUDE_LIST);
|
||||
|
||||
/* csync-journal is ignored in general silently. */
|
||||
rc = csync_excluded_no_ctx(csync->excludes, ".csync_journal.db", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_FILE_SILENTLY_EXCLUDED);
|
||||
rc = csync_excluded_no_ctx(csync->excludes, ".csync_journal.db.ctmp", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_FILE_SILENTLY_EXCLUDED);
|
||||
rc = csync_excluded_no_ctx(csync->excludes, "subdir/.csync_journal.db", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_FILE_SILENTLY_EXCLUDED);
|
||||
|
||||
/* also the new form of the database name */
|
||||
rc = csync_excluded_no_ctx(csync->excludes, "._sync_5bdd60bdfcfa.db", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_FILE_SILENTLY_EXCLUDED);
|
||||
rc = csync_excluded_no_ctx(csync->excludes, "._sync_5bdd60bdfcfa.db.ctmp", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_FILE_SILENTLY_EXCLUDED);
|
||||
rc = csync_excluded_no_ctx(csync->excludes, "._sync_5bdd60bdfcfa.db-shm", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_FILE_SILENTLY_EXCLUDED);
|
||||
rc = csync_excluded_no_ctx(csync->excludes, "subdir/._sync_5bdd60bdfcfa.db", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_FILE_SILENTLY_EXCLUDED);
|
||||
assert_int_equal(check_file_full(".csync_journal.db"), CSYNC_FILE_SILENTLY_EXCLUDED);
|
||||
assert_int_equal(check_file_full(".csync_journal.db.ctmp"), CSYNC_FILE_SILENTLY_EXCLUDED);
|
||||
assert_int_equal(check_file_full("subdir/.csync_journal.db"), CSYNC_FILE_SILENTLY_EXCLUDED);
|
||||
|
||||
rc = csync_excluded_no_ctx(csync->excludes, ".sync_5bdd60bdfcfa.db", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_FILE_SILENTLY_EXCLUDED);
|
||||
rc = csync_excluded_no_ctx(csync->excludes, ".sync_5bdd60bdfcfa.db.ctmp", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_FILE_SILENTLY_EXCLUDED);
|
||||
rc = csync_excluded_no_ctx(csync->excludes, ".sync_5bdd60bdfcfa.db-shm", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_FILE_SILENTLY_EXCLUDED);
|
||||
rc = csync_excluded_no_ctx(csync->excludes, "subdir/.sync_5bdd60bdfcfa.db", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_FILE_SILENTLY_EXCLUDED);
|
||||
/* also the new form of the database name */
|
||||
assert_int_equal(check_file_full("._sync_5bdd60bdfcfa.db"), CSYNC_FILE_SILENTLY_EXCLUDED);
|
||||
assert_int_equal(check_file_full("._sync_5bdd60bdfcfa.db.ctmp"), CSYNC_FILE_SILENTLY_EXCLUDED);
|
||||
assert_int_equal(check_file_full("._sync_5bdd60bdfcfa.db-shm"), CSYNC_FILE_SILENTLY_EXCLUDED);
|
||||
assert_int_equal(check_file_full("subdir/._sync_5bdd60bdfcfa.db"), CSYNC_FILE_SILENTLY_EXCLUDED);
|
||||
|
||||
assert_int_equal(check_file_full(".sync_5bdd60bdfcfa.db"), CSYNC_FILE_SILENTLY_EXCLUDED);
|
||||
assert_int_equal(check_file_full(".sync_5bdd60bdfcfa.db.ctmp"), CSYNC_FILE_SILENTLY_EXCLUDED);
|
||||
assert_int_equal(check_file_full(".sync_5bdd60bdfcfa.db-shm"), CSYNC_FILE_SILENTLY_EXCLUDED);
|
||||
assert_int_equal(check_file_full("subdir/.sync_5bdd60bdfcfa.db"), CSYNC_FILE_SILENTLY_EXCLUDED);
|
||||
|
||||
|
||||
/* pattern ]*.directory - ignore and remove */
|
||||
rc = csync_excluded_no_ctx(csync->excludes, "my.~directory", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_FILE_EXCLUDE_AND_REMOVE);
|
||||
|
||||
rc = csync_excluded_no_ctx(csync->excludes, "/a_folder/my.~directory", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_FILE_EXCLUDE_AND_REMOVE);
|
||||
assert_int_equal(check_file_full("my.~directory"), CSYNC_FILE_EXCLUDE_AND_REMOVE);
|
||||
assert_int_equal(check_file_full("/a_folder/my.~directory"), CSYNC_FILE_EXCLUDE_AND_REMOVE);
|
||||
|
||||
/* Not excluded because the pattern .netscape/cache requires directory. */
|
||||
rc = csync_excluded_no_ctx(csync->excludes, ".netscape/cache", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_NOT_EXCLUDED);
|
||||
assert_int_equal(check_file_full(".netscape/cache"), CSYNC_NOT_EXCLUDED);
|
||||
|
||||
/* Not excluded */
|
||||
rc = csync_excluded_no_ctx(csync->excludes, "unicode/中文.hé", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_NOT_EXCLUDED);
|
||||
assert_int_equal(check_file_full("unicode/中文.hé"), CSYNC_NOT_EXCLUDED);
|
||||
/* excluded */
|
||||
rc = csync_excluded_no_ctx(csync->excludes, "unicode/пятницы.txt", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST);
|
||||
rc = csync_excluded_no_ctx(csync->excludes, "unicode/中文.💩", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST);
|
||||
assert_int_equal(check_file_full("unicode/пятницы.txt"), CSYNC_FILE_EXCLUDE_LIST);
|
||||
assert_int_equal(check_file_full("unicode/中文.💩"), CSYNC_FILE_EXCLUDE_LIST);
|
||||
|
||||
/* path wildcards */
|
||||
rc = csync_excluded_no_ctx(csync->excludes, "foobar/my_manuscript.out", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST);
|
||||
assert_int_equal(check_file_full("foobar/my_manuscript.out"), CSYNC_FILE_EXCLUDE_LIST);
|
||||
assert_int_equal(check_file_full("latex_tmp/my_manuscript.run.xml"), CSYNC_FILE_EXCLUDE_LIST);
|
||||
|
||||
rc = csync_excluded_no_ctx(csync->excludes, "latex_tmp/my_manuscript.run.xml", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST);
|
||||
assert_int_equal(check_file_full("word_tmp/my_manuscript.run.xml"), CSYNC_NOT_EXCLUDED);
|
||||
|
||||
rc = csync_excluded_no_ctx(csync->excludes, "word_tmp/my_manuscript.run.xml", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_NOT_EXCLUDED);
|
||||
assert_int_equal(check_file_full("latex/my_manuscript.tex.tmp"), CSYNC_NOT_EXCLUDED);
|
||||
|
||||
rc = csync_excluded_no_ctx(csync->excludes, "latex/my_manuscript.tex.tmp", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_NOT_EXCLUDED);
|
||||
|
||||
rc = csync_excluded_no_ctx(csync->excludes, "latex/songbook/my_manuscript.tex.tmp", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST);
|
||||
assert_int_equal(check_file_full("latex/songbook/my_manuscript.tex.tmp"), CSYNC_FILE_EXCLUDE_LIST);
|
||||
|
||||
#ifdef _WIN32
|
||||
rc = csync_excluded_no_ctx(csync->excludes, "file_trailing_space ", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_FILE_EXCLUDE_TRAILING_SPACE);
|
||||
assert_int_equal(exclude_check_file("file_trailing_space "), CSYNC_FILE_EXCLUDE_TRAILING_SPACE);
|
||||
|
||||
rc = csync_excluded_no_ctx(csync->excludes, "file_trailing_dot.", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_FILE_EXCLUDE_INVALID_CHAR);
|
||||
|
||||
rc = csync_excluded_no_ctx(csync->excludes, "AUX", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_FILE_EXCLUDE_INVALID_CHAR);
|
||||
|
||||
rc = csync_excluded_no_ctx(csync->excludes, "file_invalid_char<", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_FILE_EXCLUDE_INVALID_CHAR);
|
||||
assert_int_equal(exclude_check_file("file_trailing_dot."), CSYNC_FILE_EXCLUDE_INVALID_CHAR);
|
||||
assert_int_equal(exclude_check_file("AUX"), CSYNC_FILE_EXCLUDE_INVALID_CHAR);
|
||||
assert_int_equal(exclude_check_file("file_invalid_char<"), CSYNC_FILE_EXCLUDE_INVALID_CHAR);
|
||||
#endif
|
||||
|
||||
/* ? character */
|
||||
_csync_exclude_add( &(csync->excludes), "bond00?" );
|
||||
csync_exclude_traversal_prepare(csync);
|
||||
rc = csync_excluded_no_ctx(csync->excludes, "bond00", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_NOT_EXCLUDED);
|
||||
rc = csync_excluded_no_ctx(csync->excludes, "bond007", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST);
|
||||
rc = csync_excluded_no_ctx(csync->excludes, "bond0071", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_NOT_EXCLUDED);
|
||||
excludedFiles->addManualExclude("bond00?");
|
||||
excludedFiles->reloadExcludeFiles();
|
||||
assert_int_equal(check_file_full("bond00"), CSYNC_NOT_EXCLUDED);
|
||||
assert_int_equal(check_file_full("bond007"), CSYNC_FILE_EXCLUDE_LIST);
|
||||
assert_int_equal(check_file_full("bond0071"), CSYNC_NOT_EXCLUDED);
|
||||
|
||||
#ifndef _WIN32
|
||||
/* brackets */
|
||||
_csync_exclude_add( &(csync->excludes), "a [bc] d" );
|
||||
csync_exclude_traversal_prepare(csync);
|
||||
rc = csync_excluded_no_ctx(csync->excludes, "a d d", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_NOT_EXCLUDED);
|
||||
rc = csync_excluded_no_ctx(csync->excludes, "a d", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_NOT_EXCLUDED);
|
||||
rc = csync_excluded_no_ctx(csync->excludes, "a b d", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST);
|
||||
rc = csync_excluded_no_ctx(csync->excludes, "a c d", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST);
|
||||
excludedFiles->addManualExclude("a [bc] d");
|
||||
excludedFiles->reloadExcludeFiles();
|
||||
assert_int_equal(check_file_full("a d d"), CSYNC_NOT_EXCLUDED);
|
||||
assert_int_equal(check_file_full("a d"), CSYNC_NOT_EXCLUDED);
|
||||
assert_int_equal(check_file_full("a b d"), CSYNC_FILE_EXCLUDE_LIST);
|
||||
assert_int_equal(check_file_full("a c d"), CSYNC_FILE_EXCLUDE_LIST);
|
||||
#endif
|
||||
|
||||
/* escapes */
|
||||
_csync_exclude_add( &(csync->excludes), "\\a \\* \\?" );
|
||||
csync_exclude_traversal_prepare(csync);
|
||||
rc = csync_excluded_no_ctx(csync->excludes, "\\a \\* \\?", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_NOT_EXCLUDED);
|
||||
rc = csync_excluded_no_ctx(csync->excludes, "a b c", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_NOT_EXCLUDED);
|
||||
rc = csync_excluded_no_ctx(csync->excludes, "a * ?", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST);
|
||||
excludedFiles->addManualExclude("\\a \\* \\?");
|
||||
excludedFiles->reloadExcludeFiles();
|
||||
assert_int_equal(check_file_full("\\a \\* \\?"), CSYNC_NOT_EXCLUDED);
|
||||
assert_int_equal(check_file_full("a b c"), CSYNC_NOT_EXCLUDED);
|
||||
assert_int_equal(check_file_full("a * ?"), CSYNC_FILE_EXCLUDE_LIST);
|
||||
}
|
||||
|
||||
static void check_csync_excluded_traversal(void **state)
|
||||
static void check_csync_excluded_traversal(void **)
|
||||
{
|
||||
CSYNC *csync = (CSYNC*)*state;
|
||||
int rc;
|
||||
assert_int_equal(check_file_traversal(""), CSYNC_NOT_EXCLUDED);
|
||||
assert_int_equal(check_file_traversal("/"), CSYNC_NOT_EXCLUDED);
|
||||
|
||||
rc = csync_excluded_traversal(csync, "", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_NOT_EXCLUDED);
|
||||
rc = csync_excluded_traversal(csync, "/", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_NOT_EXCLUDED);
|
||||
assert_int_equal(check_file_traversal("A"), CSYNC_NOT_EXCLUDED);
|
||||
|
||||
rc = csync_excluded_traversal(csync, "A", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_NOT_EXCLUDED);
|
||||
|
||||
rc = csync_excluded_traversal(csync, "krawel_krawel", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_NOT_EXCLUDED);
|
||||
rc = csync_excluded_traversal(csync, ".kde/share/config/kwin.eventsrc", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_NOT_EXCLUDED);
|
||||
rc = csync_excluded_traversal(csync, "mozilla/.directory", CSYNC_FTW_TYPE_DIR);
|
||||
assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST);
|
||||
assert_int_equal(check_file_traversal("krawel_krawel"), CSYNC_NOT_EXCLUDED);
|
||||
assert_int_equal(check_file_traversal(".kde/share/config/kwin.eventsrc"), CSYNC_NOT_EXCLUDED);
|
||||
assert_int_equal(check_dir_traversal("mozilla/.directory"), CSYNC_FILE_EXCLUDE_LIST);
|
||||
|
||||
/*
|
||||
* Test for patterns in subdirs. '.beagle' is defined as a pattern and has
|
||||
* to be found in top dir as well as in directories underneath.
|
||||
*/
|
||||
rc = csync_excluded_traversal(csync, ".apdisk", CSYNC_FTW_TYPE_DIR);
|
||||
assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST);
|
||||
rc = csync_excluded_traversal(csync, "foo/.apdisk", CSYNC_FTW_TYPE_DIR);
|
||||
assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST);
|
||||
rc = csync_excluded_traversal(csync, "foo/bar/.apdisk", CSYNC_FTW_TYPE_DIR);
|
||||
assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST);
|
||||
assert_int_equal(check_dir_traversal(".apdisk"), CSYNC_FILE_EXCLUDE_LIST);
|
||||
assert_int_equal(check_dir_traversal("foo/.apdisk"), CSYNC_FILE_EXCLUDE_LIST);
|
||||
assert_int_equal(check_dir_traversal("foo/bar/.apdisk"), CSYNC_FILE_EXCLUDE_LIST);
|
||||
|
||||
rc = csync_excluded_traversal(csync, ".java", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_NOT_EXCLUDED);
|
||||
assert_int_equal(check_file_traversal(".java"), CSYNC_NOT_EXCLUDED);
|
||||
|
||||
/* csync-journal is ignored in general silently. */
|
||||
rc = csync_excluded_traversal(csync, ".csync_journal.db", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_FILE_SILENTLY_EXCLUDED);
|
||||
rc = csync_excluded_traversal(csync, ".csync_journal.db.ctmp", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_FILE_SILENTLY_EXCLUDED);
|
||||
rc = csync_excluded_traversal(csync, "subdir/.csync_journal.db", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_FILE_SILENTLY_EXCLUDED);
|
||||
rc = csync_excluded_traversal(csync, "/two/subdir/.csync_journal.db", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_FILE_SILENTLY_EXCLUDED);
|
||||
assert_int_equal(check_file_traversal(".csync_journal.db"), CSYNC_FILE_SILENTLY_EXCLUDED);
|
||||
assert_int_equal(check_file_traversal(".csync_journal.db.ctmp"), CSYNC_FILE_SILENTLY_EXCLUDED);
|
||||
assert_int_equal(check_file_traversal("subdir/.csync_journal.db"), CSYNC_FILE_SILENTLY_EXCLUDED);
|
||||
assert_int_equal(check_file_traversal("/two/subdir/.csync_journal.db"), CSYNC_FILE_SILENTLY_EXCLUDED);
|
||||
|
||||
/* also the new form of the database name */
|
||||
rc = csync_excluded_traversal(csync, "._sync_5bdd60bdfcfa.db", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_FILE_SILENTLY_EXCLUDED);
|
||||
rc = csync_excluded_traversal(csync, "._sync_5bdd60bdfcfa.db.ctmp", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_FILE_SILENTLY_EXCLUDED);
|
||||
rc = csync_excluded_traversal(csync, "._sync_5bdd60bdfcfa.db-shm", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_FILE_SILENTLY_EXCLUDED);
|
||||
rc = csync_excluded_traversal(csync, "subdir/._sync_5bdd60bdfcfa.db", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_FILE_SILENTLY_EXCLUDED);
|
||||
assert_int_equal(check_file_traversal("._sync_5bdd60bdfcfa.db"), CSYNC_FILE_SILENTLY_EXCLUDED);
|
||||
assert_int_equal(check_file_traversal("._sync_5bdd60bdfcfa.db.ctmp"), CSYNC_FILE_SILENTLY_EXCLUDED);
|
||||
assert_int_equal(check_file_traversal("._sync_5bdd60bdfcfa.db-shm"), CSYNC_FILE_SILENTLY_EXCLUDED);
|
||||
assert_int_equal(check_file_traversal("subdir/._sync_5bdd60bdfcfa.db"), CSYNC_FILE_SILENTLY_EXCLUDED);
|
||||
|
||||
rc = csync_excluded_traversal(csync, ".sync_5bdd60bdfcfa.db", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_FILE_SILENTLY_EXCLUDED);
|
||||
rc = csync_excluded_traversal(csync, ".sync_5bdd60bdfcfa.db.ctmp", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_FILE_SILENTLY_EXCLUDED);
|
||||
rc = csync_excluded_traversal(csync, ".sync_5bdd60bdfcfa.db-shm", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_FILE_SILENTLY_EXCLUDED);
|
||||
rc = csync_excluded_traversal(csync, "subdir/.sync_5bdd60bdfcfa.db", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_FILE_SILENTLY_EXCLUDED);
|
||||
assert_int_equal(check_file_traversal(".sync_5bdd60bdfcfa.db"), CSYNC_FILE_SILENTLY_EXCLUDED);
|
||||
assert_int_equal(check_file_traversal(".sync_5bdd60bdfcfa.db.ctmp"), CSYNC_FILE_SILENTLY_EXCLUDED);
|
||||
assert_int_equal(check_file_traversal(".sync_5bdd60bdfcfa.db-shm"), CSYNC_FILE_SILENTLY_EXCLUDED);
|
||||
assert_int_equal(check_file_traversal("subdir/.sync_5bdd60bdfcfa.db"), CSYNC_FILE_SILENTLY_EXCLUDED);
|
||||
|
||||
|
||||
/* pattern ]*.directory - ignore and remove */
|
||||
rc = csync_excluded_traversal(csync, "my.~directory", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_FILE_EXCLUDE_AND_REMOVE);
|
||||
|
||||
rc = csync_excluded_traversal(csync, "/a_folder/my.~directory", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_FILE_EXCLUDE_AND_REMOVE);
|
||||
assert_int_equal(check_file_traversal("my.~directory"), CSYNC_FILE_EXCLUDE_AND_REMOVE);
|
||||
assert_int_equal(check_file_traversal("/a_folder/my.~directory"), CSYNC_FILE_EXCLUDE_AND_REMOVE);
|
||||
|
||||
/* Not excluded because the pattern .netscape/cache requires directory. */
|
||||
rc = csync_excluded_traversal(csync, ".netscape/cache", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_NOT_EXCLUDED);
|
||||
assert_int_equal(check_file_traversal(".netscape/cache"), CSYNC_NOT_EXCLUDED);
|
||||
|
||||
/* Not excluded */
|
||||
rc = csync_excluded_traversal(csync, "unicode/中文.hé", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_NOT_EXCLUDED);
|
||||
assert_int_equal(check_file_traversal("unicode/中文.hé"), CSYNC_NOT_EXCLUDED);
|
||||
/* excluded */
|
||||
rc = csync_excluded_traversal(csync, "unicode/пятницы.txt", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST);
|
||||
rc = csync_excluded_traversal(csync, "unicode/中文.💩", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST);
|
||||
assert_int_equal(check_file_traversal("unicode/пятницы.txt"), CSYNC_FILE_EXCLUDE_LIST);
|
||||
assert_int_equal(check_file_traversal("unicode/中文.💩"), CSYNC_FILE_EXCLUDE_LIST);
|
||||
|
||||
/* path wildcards */
|
||||
rc = csync_excluded_traversal(csync, "foobar/my_manuscript.out", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST);
|
||||
|
||||
rc = csync_excluded_traversal(csync, "latex_tmp/my_manuscript.run.xml", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST);
|
||||
|
||||
rc = csync_excluded_traversal(csync, "word_tmp/my_manuscript.run.xml", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_NOT_EXCLUDED);
|
||||
|
||||
rc = csync_excluded_traversal(csync, "latex/my_manuscript.tex.tmp", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_NOT_EXCLUDED);
|
||||
|
||||
rc = csync_excluded_traversal(csync, "latex/songbook/my_manuscript.tex.tmp", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST);
|
||||
assert_int_equal(check_file_traversal("foobar/my_manuscript.out"), CSYNC_FILE_EXCLUDE_LIST);
|
||||
assert_int_equal(check_file_traversal("latex_tmp/my_manuscript.run.xml"), CSYNC_FILE_EXCLUDE_LIST);
|
||||
assert_int_equal(check_file_traversal("word_tmp/my_manuscript.run.xml"), CSYNC_NOT_EXCLUDED);
|
||||
assert_int_equal(check_file_traversal("latex/my_manuscript.tex.tmp"), CSYNC_NOT_EXCLUDED);
|
||||
assert_int_equal(check_file_traversal("latex/songbook/my_manuscript.tex.tmp"), CSYNC_FILE_EXCLUDE_LIST);
|
||||
|
||||
#ifdef _WIN32
|
||||
rc = csync_excluded_traversal(csync, "file_trailing_space ", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_FILE_EXCLUDE_TRAILING_SPACE);
|
||||
|
||||
rc = csync_excluded_traversal(csync, "file_trailing_dot.", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_FILE_EXCLUDE_INVALID_CHAR);
|
||||
|
||||
rc = csync_excluded_traversal(csync, "AUX", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_FILE_EXCLUDE_INVALID_CHAR);
|
||||
|
||||
rc = csync_excluded_traversal(csync, "file_invalid_char<", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_FILE_EXCLUDE_INVALID_CHAR);
|
||||
assert_int_equal(check_file_traversal("file_trailing_space "), CSYNC_FILE_EXCLUDE_TRAILING_SPACE);
|
||||
assert_int_equal(check_file_traversal("file_trailing_dot."), CSYNC_FILE_EXCLUDE_INVALID_CHAR);
|
||||
assert_int_equal(check_file_traversal("AUX"), CSYNC_FILE_EXCLUDE_INVALID_CHAR);
|
||||
assert_int_equal(check_file_traversal("file_invalid_char<"), CSYNC_FILE_EXCLUDE_INVALID_CHAR);
|
||||
#endif
|
||||
|
||||
|
||||
/* From here the actual traversal tests */
|
||||
|
||||
_csync_exclude_add( &(csync->excludes), "/exclude" );
|
||||
csync_exclude_traversal_prepare(csync);
|
||||
excludedFiles->addManualExclude("/exclude");
|
||||
excludedFiles->reloadExcludeFiles();
|
||||
|
||||
/* Check toplevel dir, the pattern only works for toplevel dir. */
|
||||
rc = csync_excluded_traversal(csync, "/exclude", CSYNC_FTW_TYPE_DIR);
|
||||
assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST);
|
||||
|
||||
rc = csync_excluded_traversal(csync, "/foo/exclude", CSYNC_FTW_TYPE_DIR);
|
||||
assert_int_equal(rc, CSYNC_NOT_EXCLUDED);
|
||||
assert_int_equal(check_dir_traversal("/exclude"), CSYNC_FILE_EXCLUDE_LIST);
|
||||
assert_int_equal(check_dir_traversal("/foo/exclude"), CSYNC_NOT_EXCLUDED);
|
||||
|
||||
/* check for a file called exclude. Must still work */
|
||||
rc = csync_excluded_traversal(csync, "/exclude", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST);
|
||||
|
||||
rc = csync_excluded_traversal(csync, "/foo/exclude", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_NOT_EXCLUDED);
|
||||
assert_int_equal(check_file_traversal("/exclude"), CSYNC_FILE_EXCLUDE_LIST);
|
||||
assert_int_equal(check_file_traversal("/foo/exclude"), CSYNC_NOT_EXCLUDED);
|
||||
|
||||
/* Add an exclude for directories only: excl/ */
|
||||
_csync_exclude_add( &(csync->excludes), "excl/" );
|
||||
csync_exclude_traversal_prepare(csync);
|
||||
rc = csync_excluded_traversal(csync, "/excl", CSYNC_FTW_TYPE_DIR);
|
||||
assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST);
|
||||
excludedFiles->addManualExclude("excl/");
|
||||
excludedFiles->reloadExcludeFiles();
|
||||
assert_int_equal(check_dir_traversal("/excl"), CSYNC_FILE_EXCLUDE_LIST);
|
||||
assert_int_equal(check_dir_traversal("meep/excl"), CSYNC_FILE_EXCLUDE_LIST);
|
||||
|
||||
rc = csync_excluded_traversal(csync, "meep/excl", CSYNC_FTW_TYPE_DIR);
|
||||
assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST);
|
||||
// because leading dirs aren't checked!
|
||||
assert_int_equal(check_file_traversal("meep/excl/file"), CSYNC_NOT_EXCLUDED);
|
||||
assert_int_equal(check_file_traversal("/excl"), CSYNC_NOT_EXCLUDED);
|
||||
|
||||
rc = csync_excluded_traversal(csync, "meep/excl/file", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_NOT_EXCLUDED); // because leading dirs aren't checked!
|
||||
excludedFiles->addManualExclude("/excludepath/withsubdir");
|
||||
excludedFiles->reloadExcludeFiles();
|
||||
|
||||
rc = csync_excluded_traversal(csync, "/excl", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_NOT_EXCLUDED);
|
||||
assert_int_equal(check_dir_traversal("/excludepath/withsubdir"), CSYNC_FILE_EXCLUDE_LIST);
|
||||
assert_int_equal(check_file_traversal("/excludepath/withsubdir"), CSYNC_FILE_EXCLUDE_LIST);
|
||||
assert_int_equal(check_dir_traversal("/excludepath/withsubdir2"), CSYNC_NOT_EXCLUDED);
|
||||
|
||||
_csync_exclude_add(&csync->excludes, "/excludepath/withsubdir");
|
||||
csync_exclude_traversal_prepare(csync);
|
||||
|
||||
rc = csync_excluded_traversal(csync, "/excludepath/withsubdir", CSYNC_FTW_TYPE_DIR);
|
||||
assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST);
|
||||
|
||||
rc = csync_excluded_traversal(csync, "/excludepath/withsubdir", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST);
|
||||
|
||||
rc = csync_excluded_traversal(csync, "/excludepath/withsubdir2", CSYNC_FTW_TYPE_DIR);
|
||||
assert_int_equal(rc, CSYNC_NOT_EXCLUDED);
|
||||
|
||||
rc = csync_excluded_traversal(csync, "/excludepath/withsubdir/foo", CSYNC_FTW_TYPE_DIR);
|
||||
assert_int_equal(rc, CSYNC_NOT_EXCLUDED); // because leading dirs aren't checked!
|
||||
// because leading dirs aren't checked!
|
||||
assert_int_equal(check_dir_traversal("/excludepath/withsubdir/foo"), CSYNC_NOT_EXCLUDED);
|
||||
|
||||
/* Check ending of pattern */
|
||||
rc = csync_excluded_traversal(csync, "/exclude", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST);
|
||||
rc = csync_excluded_traversal(csync, "/excludeX", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_NOT_EXCLUDED);
|
||||
rc = csync_excluded_traversal(csync, "exclude", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_NOT_EXCLUDED);
|
||||
assert_int_equal(check_file_traversal("/exclude"), CSYNC_FILE_EXCLUDE_LIST);
|
||||
assert_int_equal(check_file_traversal("/excludeX"), CSYNC_NOT_EXCLUDED);
|
||||
assert_int_equal(check_file_traversal("exclude"), CSYNC_NOT_EXCLUDED);
|
||||
|
||||
_csync_exclude_add( &(csync->excludes), "exclude" );
|
||||
csync_exclude_traversal_prepare(csync);
|
||||
rc = csync_excluded_traversal(csync, "exclude", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST);
|
||||
excludedFiles->addManualExclude("exclude");
|
||||
excludedFiles->reloadExcludeFiles();
|
||||
assert_int_equal(check_file_traversal("exclude"), CSYNC_FILE_EXCLUDE_LIST);
|
||||
|
||||
/* ? character */
|
||||
_csync_exclude_add( &(csync->excludes), "bond00?" );
|
||||
csync_exclude_traversal_prepare(csync);
|
||||
rc = csync_excluded_traversal(csync, "bond00", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_NOT_EXCLUDED);
|
||||
rc = csync_excluded_traversal(csync, "bond007", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST);
|
||||
rc = csync_excluded_traversal(csync, "bond0071", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_NOT_EXCLUDED);
|
||||
excludedFiles->addManualExclude("bond00?");
|
||||
excludedFiles->reloadExcludeFiles();
|
||||
assert_int_equal(check_file_traversal("bond00"), CSYNC_NOT_EXCLUDED);
|
||||
assert_int_equal(check_file_traversal("bond007"), CSYNC_FILE_EXCLUDE_LIST);
|
||||
assert_int_equal(check_file_traversal("bond0071"), CSYNC_NOT_EXCLUDED);
|
||||
|
||||
#ifndef _WIN32
|
||||
/* brackets */
|
||||
_csync_exclude_add( &(csync->excludes), "a [bc] d" );
|
||||
csync_exclude_traversal_prepare(csync);
|
||||
rc = csync_excluded_traversal(csync, "a d d", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_NOT_EXCLUDED);
|
||||
rc = csync_excluded_traversal(csync, "a d", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_NOT_EXCLUDED);
|
||||
rc = csync_excluded_traversal(csync, "a b d", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST);
|
||||
rc = csync_excluded_traversal(csync, "a c d", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST);
|
||||
excludedFiles->addManualExclude("a [bc] d");
|
||||
excludedFiles->reloadExcludeFiles();
|
||||
assert_int_equal(check_file_traversal("a d d"), CSYNC_NOT_EXCLUDED);
|
||||
assert_int_equal(check_file_traversal("a d"), CSYNC_NOT_EXCLUDED);
|
||||
assert_int_equal(check_file_traversal("a b d"), CSYNC_FILE_EXCLUDE_LIST);
|
||||
assert_int_equal(check_file_traversal("a c d"), CSYNC_FILE_EXCLUDE_LIST);
|
||||
#endif
|
||||
|
||||
/* escapes */
|
||||
_csync_exclude_add( &(csync->excludes), "\\a \\* \\?" );
|
||||
csync_exclude_traversal_prepare(csync);
|
||||
rc = csync_excluded_traversal(csync, "\\a \\* \\?", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_NOT_EXCLUDED);
|
||||
rc = csync_excluded_traversal(csync, "a b c", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_NOT_EXCLUDED);
|
||||
rc = csync_excluded_traversal(csync, "a * ?", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST);
|
||||
excludedFiles->addManualExclude("\\a \\* \\?");
|
||||
excludedFiles->reloadExcludeFiles();
|
||||
assert_int_equal(check_file_traversal("\\a \\* \\?"), CSYNC_NOT_EXCLUDED);
|
||||
assert_int_equal(check_file_traversal("a b c"), CSYNC_NOT_EXCLUDED);
|
||||
assert_int_equal(check_file_traversal("a * ?"), CSYNC_FILE_EXCLUDE_LIST);
|
||||
}
|
||||
|
||||
static void check_csync_pathes(void **state)
|
||||
static void check_csync_pathes(void **)
|
||||
{
|
||||
CSYNC *csync = (CSYNC*)*state;
|
||||
int rc;
|
||||
|
||||
_csync_exclude_add( &(csync->excludes), "/exclude" );
|
||||
excludedFiles->addManualExclude("/exclude");
|
||||
excludedFiles->reloadExcludeFiles();
|
||||
|
||||
/* Check toplevel dir, the pattern only works for toplevel dir. */
|
||||
rc = csync_excluded_no_ctx(csync->excludes, "/exclude", CSYNC_FTW_TYPE_DIR);
|
||||
assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST);
|
||||
assert_int_equal(check_dir_full("/exclude"), CSYNC_FILE_EXCLUDE_LIST);
|
||||
|
||||
rc = csync_excluded_no_ctx(csync->excludes, "/foo/exclude", CSYNC_FTW_TYPE_DIR);
|
||||
assert_int_equal(rc, CSYNC_NOT_EXCLUDED);
|
||||
assert_int_equal(check_dir_full("/foo/exclude"), CSYNC_NOT_EXCLUDED);
|
||||
|
||||
/* check for a file called exclude. Must still work */
|
||||
rc = csync_excluded_no_ctx(csync->excludes, "/exclude", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST);
|
||||
assert_int_equal(check_file_full("/exclude"), CSYNC_FILE_EXCLUDE_LIST);
|
||||
|
||||
rc = csync_excluded_no_ctx(csync->excludes, "/foo/exclude", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_NOT_EXCLUDED);
|
||||
assert_int_equal(check_file_full("/foo/exclude"), CSYNC_NOT_EXCLUDED);
|
||||
|
||||
/* Add an exclude for directories only: excl/ */
|
||||
_csync_exclude_add( &(csync->excludes), "excl/" );
|
||||
rc = csync_excluded_no_ctx(csync->excludes, "/excl", CSYNC_FTW_TYPE_DIR);
|
||||
assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST);
|
||||
excludedFiles->addManualExclude("excl/");
|
||||
excludedFiles->reloadExcludeFiles();
|
||||
assert_int_equal(check_dir_full("/excl"), CSYNC_FILE_EXCLUDE_LIST);
|
||||
assert_int_equal(check_dir_full("meep/excl"), CSYNC_FILE_EXCLUDE_LIST);
|
||||
assert_int_equal(check_file_full("meep/excl/file"), CSYNC_FILE_EXCLUDE_LIST);
|
||||
|
||||
rc = csync_excluded_no_ctx(csync->excludes, "meep/excl", CSYNC_FTW_TYPE_DIR);
|
||||
assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST);
|
||||
assert_int_equal(check_file_full("/excl"), CSYNC_NOT_EXCLUDED);
|
||||
|
||||
rc = csync_excluded_no_ctx(csync->excludes, "meep/excl/file", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST);
|
||||
excludedFiles->addManualExclude("/excludepath/withsubdir");
|
||||
excludedFiles->reloadExcludeFiles();
|
||||
|
||||
rc = csync_excluded_no_ctx(csync->excludes, "/excl", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_NOT_EXCLUDED);
|
||||
assert_int_equal(check_dir_full("/excludepath/withsubdir"), CSYNC_FILE_EXCLUDE_LIST);
|
||||
assert_int_equal(check_file_full("/excludepath/withsubdir"), CSYNC_FILE_EXCLUDE_LIST);
|
||||
|
||||
_csync_exclude_add(&csync->excludes, "/excludepath/withsubdir");
|
||||
assert_int_equal(check_dir_full("/excludepath/withsubdir2"), CSYNC_NOT_EXCLUDED);
|
||||
|
||||
rc = csync_excluded_no_ctx(csync->excludes, "/excludepath/withsubdir", CSYNC_FTW_TYPE_DIR);
|
||||
assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST);
|
||||
|
||||
rc = csync_excluded_no_ctx(csync->excludes, "/excludepath/withsubdir", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST);
|
||||
|
||||
rc = csync_excluded_no_ctx(csync->excludes, "/excludepath/withsubdir2", CSYNC_FTW_TYPE_DIR);
|
||||
assert_int_equal(rc, CSYNC_NOT_EXCLUDED);
|
||||
|
||||
rc = csync_excluded_no_ctx(csync->excludes, "/excludepath/withsubdir/foo", CSYNC_FTW_TYPE_DIR);
|
||||
assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST);
|
||||
assert_int_equal(check_dir_full("/excludepath/withsubdir/foo"), CSYNC_FILE_EXCLUDE_LIST);
|
||||
}
|
||||
|
||||
static void check_csync_is_windows_reserved_word(void **) {
|
||||
@ -560,10 +424,8 @@ static void check_csync_is_windows_reserved_word(void **) {
|
||||
}
|
||||
|
||||
/* QT_ENABLE_REGEXP_JIT=0 to get slower results :-) */
|
||||
static void check_csync_excluded_performance(void **state)
|
||||
static void check_csync_excluded_performance(void **)
|
||||
{
|
||||
CSYNC *csync = (CSYNC*)*state;
|
||||
|
||||
const int N = 10000;
|
||||
int totalRc = 0;
|
||||
int i = 0;
|
||||
@ -574,8 +436,8 @@ static void check_csync_excluded_performance(void **state)
|
||||
gettimeofday(&before, 0);
|
||||
|
||||
for (i = 0; i < N; ++i) {
|
||||
totalRc += csync_excluded_no_ctx(csync->excludes, "/this/is/quite/a/long/path/with/many/components", CSYNC_FTW_TYPE_DIR);
|
||||
totalRc += csync_excluded_no_ctx(csync->excludes, "/1/2/3/4/5/6/7/8/9/10/11/12/13/14/15/16/17/18/19/20/21/22/23/24/25/26/27/29", CSYNC_FTW_TYPE_FILE);
|
||||
totalRc += check_dir_full("/this/is/quite/a/long/path/with/many/components");
|
||||
totalRc += check_file_full("/1/2/3/4/5/6/7/8/9/10/11/12/13/14/15/16/17/18/19/20/21/22/23/24/25/26/27/29");
|
||||
}
|
||||
assert_int_equal(totalRc, CSYNC_NOT_EXCLUDED); // mainly to avoid optimization
|
||||
|
||||
@ -592,8 +454,8 @@ static void check_csync_excluded_performance(void **state)
|
||||
gettimeofday(&before, 0);
|
||||
|
||||
for (i = 0; i < N; ++i) {
|
||||
totalRc += csync_excluded_traversal(csync, "/this/is/quite/a/long/path/with/many/components", CSYNC_FTW_TYPE_DIR);
|
||||
totalRc += csync_excluded_traversal(csync, "/1/2/3/4/5/6/7/8/9/10/11/12/13/14/15/16/17/18/19/20/21/22/23/24/25/26/27/29", CSYNC_FTW_TYPE_FILE);
|
||||
totalRc += check_dir_traversal("/this/is/quite/a/long/path/with/many/components");
|
||||
totalRc += check_file_traversal("/1/2/3/4/5/6/7/8/9/10/11/12/13/14/15/16/17/18/19/20/21/22/23/24/25/26/27/29");
|
||||
}
|
||||
assert_int_equal(totalRc, CSYNC_NOT_EXCLUDED); // mainly to avoid optimization
|
||||
|
||||
@ -629,7 +491,6 @@ int torture_run_tests(void)
|
||||
{
|
||||
const struct CMUnitTest tests[] = {
|
||||
cmocka_unit_test_setup_teardown(check_csync_exclude_add, setup, teardown),
|
||||
cmocka_unit_test_setup_teardown(check_csync_exclude_load, setup, teardown),
|
||||
cmocka_unit_test_setup_teardown(check_csync_excluded, setup_init, teardown),
|
||||
cmocka_unit_test_setup_teardown(check_csync_excluded_traversal, setup_init, teardown),
|
||||
cmocka_unit_test_setup_teardown(check_csync_pathes, setup_init, teardown),
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
#include <QtTest>
|
||||
|
||||
#include "excludedfiles.h"
|
||||
#include "csync_exclude.h"
|
||||
|
||||
using namespace OCC;
|
||||
|
||||
@ -20,7 +20,7 @@ class TestExcludedFiles: public QObject
|
||||
private slots:
|
||||
void testFun()
|
||||
{
|
||||
auto & excluded = ExcludedFiles::instance();
|
||||
ExcludedFiles excluded;
|
||||
bool excludeHidden = true;
|
||||
bool keepHidden = false;
|
||||
|
||||
@ -30,7 +30,7 @@ private slots:
|
||||
QVERIFY(excluded.isExcluded("/a/.b", "/a", excludeHidden));
|
||||
|
||||
excluded.addExcludeFilePath(EXCLUDE_LIST_FILE);
|
||||
excluded.reloadExcludes();
|
||||
excluded.reloadExcludeFiles();
|
||||
|
||||
QVERIFY(!excluded.isExcluded("/a/b", "/a", keepHidden));
|
||||
QVERIFY(excluded.isExcluded("/a/b~", "/a", keepHidden));
|
||||
|
@ -212,8 +212,8 @@ private slots:
|
||||
|
||||
void warningStatusForExcludedFile() {
|
||||
FakeFolder fakeFolder{FileInfo::A12_B12_C12_S12()};
|
||||
fakeFolder.syncEngine().excludedFiles().addExcludeExpr("A/a1");
|
||||
fakeFolder.syncEngine().excludedFiles().addExcludeExpr("B");
|
||||
fakeFolder.syncEngine().excludedFiles().addManualExclude("A/a1");
|
||||
fakeFolder.syncEngine().excludedFiles().addManualExclude("B");
|
||||
fakeFolder.localModifier().appendByte("A/a1");
|
||||
fakeFolder.localModifier().appendByte("B/b1");
|
||||
StatusPushSpy statusSpy(fakeFolder.syncEngine());
|
||||
@ -239,7 +239,7 @@ private slots:
|
||||
statusSpy.clear();
|
||||
|
||||
// Clears the exclude expr above
|
||||
fakeFolder.syncEngine().excludedFiles().reloadExcludes();
|
||||
fakeFolder.syncEngine().excludedFiles().clearManualExcludes();
|
||||
fakeFolder.scheduleSync();
|
||||
fakeFolder.execUntilBeforePropagation();
|
||||
QCOMPARE(statusSpy.statusOf(""), SyncFileStatus(SyncFileStatus::StatusSync));
|
||||
@ -262,7 +262,7 @@ private slots:
|
||||
|
||||
void warningStatusForExcludedFile_CasePreserving() {
|
||||
FakeFolder fakeFolder{FileInfo::A12_B12_C12_S12()};
|
||||
fakeFolder.syncEngine().excludedFiles().addExcludeExpr("B");
|
||||
fakeFolder.syncEngine().excludedFiles().addManualExclude("B");
|
||||
fakeFolder.serverErrorPaths().append("A/a1");
|
||||
fakeFolder.localModifier().appendByte("A/a1");
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user